Upgrade to gdb version 4.11
This commit is contained in:
parent
e6e5bff5d5
commit
1b943a732e
|
@ -0,0 +1,24 @@
|
|||
# $Id: Makefile,v 1.1 1994/01/28 12:37:29 pk Exp $
|
||||
|
||||
LIB= bfd
|
||||
NOPROFILE=
|
||||
NOPIC=
|
||||
|
||||
CFLAGS+= -I$(.CURDIR)/arch/$(MACHINE_ARCH) -I$(.CURDIR) \
|
||||
-I$(.CURDIR)/../include
|
||||
.PATH: $(.CURDIR)/arch/$(MACHINE_ARCH)
|
||||
|
||||
SRCS= archive.c archures.c bfd.c cache.c coffgen.c core.c ctor.c \
|
||||
format.c init.c libbfd.c opncls.c reloc.c seclet.c section.c \
|
||||
syms.c targets.c ecoff.c elf.c srec.c aout32.c \
|
||||
stab-syms.c trad-core.c
|
||||
|
||||
.include "arch/$(MACHINE_ARCH)/Makefile.inc"
|
||||
|
||||
targets.o archures.o: $(.CURDIR)/$(.TARGET:S/.o$/.c/)
|
||||
$(CC) $(CFLAGS) $(VECTORS) -c -o $(.TARGET) $(.IMPSRC)
|
||||
|
||||
|
||||
install:
|
||||
|
||||
.include <bsd.lib.mk>
|
|
@ -0,0 +1,432 @@
|
|||
/* Define a target vector and some small routines for a variant of a.out.
|
||||
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: aout-target.h,v 1.1 1994/01/28 12:37:31 pk Exp $
|
||||
*/
|
||||
|
||||
#include "aout/aout64.h"
|
||||
#include "aout/stab_gnu.h"
|
||||
#include "aout/ar.h"
|
||||
/*#include "libaout.h"*/
|
||||
|
||||
extern CONST struct reloc_howto_struct * NAME(aout,reloc_type_lookup) ();
|
||||
|
||||
/* Set parameters about this a.out file that are machine-dependent.
|
||||
This routine is called from some_aout_object_p just before it returns. */
|
||||
#ifndef MY_callback
|
||||
static bfd_target *
|
||||
DEFUN(MY(callback),(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
struct internal_exec *execp = exec_hdr (abfd);
|
||||
|
||||
/* Calculate the file positions of the parts of a newly read aout header */
|
||||
obj_textsec (abfd)->_raw_size = N_TXTSIZE(*execp);
|
||||
|
||||
/* The virtual memory addresses of the sections */
|
||||
obj_textsec (abfd)->vma = N_TXTADDR(*execp);
|
||||
obj_datasec (abfd)->vma = N_DATADDR(*execp);
|
||||
obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
|
||||
|
||||
/* The file offsets of the sections */
|
||||
obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
|
||||
obj_datasec (abfd)->filepos = N_DATOFF (*execp);
|
||||
|
||||
/* The file offsets of the relocation info */
|
||||
obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
|
||||
obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
|
||||
|
||||
/* The file offsets of the string table and symbol table. */
|
||||
obj_sym_filepos (abfd) = N_SYMOFF (*execp);
|
||||
obj_str_filepos (abfd) = N_STROFF (*execp);
|
||||
|
||||
/* Determine the architecture and machine type of the object file. */
|
||||
#ifdef SET_ARCH_MACH
|
||||
SET_ARCH_MACH(abfd, *execp);
|
||||
#else
|
||||
bfd_default_set_arch_mach(abfd, DEFAULT_ARCH, 0);
|
||||
#endif
|
||||
|
||||
/* Don't set sizes now -- can't be sure until we know arch & mach.
|
||||
Sizes get set in set_sizes callback, later. */
|
||||
#if 0
|
||||
adata(abfd).page_size = PAGE_SIZE;
|
||||
#ifdef SEGMENT_SIZE
|
||||
adata(abfd).segment_size = SEGMENT_SIZE;
|
||||
#else
|
||||
adata(abfd).segment_size = PAGE_SIZE;
|
||||
#endif
|
||||
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
|
||||
#endif
|
||||
|
||||
return abfd->xvec;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MY_object_p
|
||||
/* Finish up the reading of an a.out file header */
|
||||
|
||||
static bfd_target *
|
||||
DEFUN(MY(object_p),(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
struct external_exec exec_bytes; /* Raw exec header from file */
|
||||
struct internal_exec exec; /* Cleaned-up exec header */
|
||||
bfd_target *target;
|
||||
|
||||
if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
|
||||
!= EXEC_BYTES_SIZE) {
|
||||
bfd_error = wrong_format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NO_SWAP_MAGIC
|
||||
memcpy (&exec.a_info, exec_bytes.e_info, sizeof(exec.a_info));
|
||||
#else
|
||||
exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
|
||||
#endif /* NO_SWAP_MAGIC */
|
||||
|
||||
if (N_BADMAG (exec)) return 0;
|
||||
#ifdef MACHTYPE_OK
|
||||
if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
|
||||
#endif
|
||||
|
||||
NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
|
||||
target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
|
||||
|
||||
#ifdef ENTRY_CAN_BE_ZERO
|
||||
/* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
|
||||
* means that it isn't obvious if EXEC_P should be set.
|
||||
* All of the following must be true for an executable:
|
||||
* There must be no relocations, the bfd can be neither an
|
||||
* archive nor an archive element, and the file must be executable. */
|
||||
|
||||
if (exec.a_trsize + exec.a_drsize == 0
|
||||
&& bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL)
|
||||
{
|
||||
struct stat buf;
|
||||
#ifndef S_IXUSR
|
||||
#define S_IXUSR 0100 /* Execute by owner. */
|
||||
#endif
|
||||
if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
|
||||
abfd->flags |= EXEC_P;
|
||||
}
|
||||
#endif /* ENTRY_CAN_BE_ZERO */
|
||||
|
||||
return target;
|
||||
}
|
||||
#define MY_object_p MY(object_p)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MY_mkobject
|
||||
static boolean
|
||||
DEFUN(MY(mkobject),(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
if (NAME(aout,mkobject)(abfd) == false)
|
||||
return false;
|
||||
#if 0 /* Sizes get set in set_sizes callback, later, after we know
|
||||
the architecture and machine. */
|
||||
adata(abfd).page_size = PAGE_SIZE;
|
||||
#ifdef SEGMENT_SIZE
|
||||
adata(abfd).segment_size = SEGMENT_SIZE;
|
||||
#else
|
||||
adata(abfd).segment_size = PAGE_SIZE;
|
||||
#endif
|
||||
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#define MY_mkobject MY(mkobject)
|
||||
#endif
|
||||
|
||||
/* Write an object file.
|
||||
Section contents have already been written. We write the
|
||||
file header, symbols, and relocation. */
|
||||
|
||||
#ifndef MY_write_object_contents
|
||||
static boolean
|
||||
DEFUN(MY(write_object_contents),(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
struct external_exec exec_bytes;
|
||||
struct internal_exec *execp = exec_hdr (abfd);
|
||||
|
||||
#if CHOOSE_RELOC_SIZE
|
||||
CHOOSE_RELOC_SIZE(abfd);
|
||||
#else
|
||||
obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
|
||||
#endif
|
||||
|
||||
WRITE_HEADERS(abfd, execp);
|
||||
|
||||
return true;
|
||||
}
|
||||
#define MY_write_object_contents MY(write_object_contents)
|
||||
#endif
|
||||
|
||||
#ifndef MY_set_sizes
|
||||
static boolean
|
||||
DEFUN(MY(set_sizes),(abfd), bfd *abfd)
|
||||
{
|
||||
adata(abfd).page_size = PAGE_SIZE;
|
||||
#ifdef SEGMENT_SIZE
|
||||
adata(abfd).segment_size = SEGMENT_SIZE;
|
||||
#else
|
||||
adata(abfd).segment_size = PAGE_SIZE;
|
||||
#endif
|
||||
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
|
||||
return true;
|
||||
}
|
||||
#define MY_set_sizes MY(set_sizes)
|
||||
#endif
|
||||
|
||||
#ifndef MY_backend_data
|
||||
static CONST struct aout_backend_data MY(backend_data) = {
|
||||
0, /* zmagic contiguous */
|
||||
0, /* text incl header */
|
||||
0, /* text vma? */
|
||||
MY_set_sizes,
|
||||
0, /* exec header is counted */
|
||||
};
|
||||
#define MY_backend_data &MY(backend_data)
|
||||
#endif
|
||||
|
||||
/* We assume BFD generic archive files. */
|
||||
#ifndef MY_openr_next_archived_file
|
||||
#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#endif
|
||||
#ifndef MY_generic_stat_arch_elt
|
||||
#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#endif
|
||||
#ifndef MY_slurp_armap
|
||||
#define MY_slurp_armap bfd_slurp_bsd_armap
|
||||
#endif
|
||||
#ifndef MY_slurp_extended_name_table
|
||||
#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table
|
||||
#endif
|
||||
#ifndef MY_write_armap
|
||||
#define MY_write_armap bsd_write_armap
|
||||
#endif
|
||||
#ifndef MY_truncate_arname
|
||||
#define MY_truncate_arname bfd_bsd_truncate_arname
|
||||
#endif
|
||||
|
||||
/* No core file defined here -- configure in trad-core.c separately. */
|
||||
#ifndef MY_core_file_failing_command
|
||||
#define MY_core_file_failing_command _bfd_dummy_core_file_failing_command
|
||||
#endif
|
||||
#ifndef MY_core_file_failing_signal
|
||||
#define MY_core_file_failing_signal _bfd_dummy_core_file_failing_signal
|
||||
#endif
|
||||
#ifndef MY_core_file_matches_executable_p
|
||||
#define MY_core_file_matches_executable_p \
|
||||
_bfd_dummy_core_file_matches_executable_p
|
||||
#endif
|
||||
#ifndef MY_core_file_p
|
||||
#define MY_core_file_p _bfd_dummy_target
|
||||
#endif
|
||||
|
||||
#ifndef MY_bfd_debug_info_start
|
||||
#define MY_bfd_debug_info_start bfd_void
|
||||
#endif
|
||||
#ifndef MY_bfd_debug_info_end
|
||||
#define MY_bfd_debug_info_end bfd_void
|
||||
#endif
|
||||
#ifndef MY_bfd_debug_info_accumulate
|
||||
#define MY_bfd_debug_info_accumulate \
|
||||
(void (*) PARAMS ((bfd*, struct sec *))) bfd_void
|
||||
#endif
|
||||
|
||||
#ifndef MY_core_file_failing_command
|
||||
#define MY_core_file_failing_command NAME(aout,core_file_failing_command)
|
||||
#endif
|
||||
#ifndef MY_core_file_failing_signal
|
||||
#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal)
|
||||
#endif
|
||||
#ifndef MY_core_file_matches_executable_p
|
||||
#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p)
|
||||
#endif
|
||||
#ifndef MY_slurp_armap
|
||||
#define MY_slurp_armap NAME(aout,slurp_armap)
|
||||
#endif
|
||||
#ifndef MY_slurp_extended_name_table
|
||||
#define MY_slurp_extended_name_table NAME(aout,slurp_extended_name_table)
|
||||
#endif
|
||||
#ifndef MY_truncate_arname
|
||||
#define MY_truncate_arname NAME(aout,truncate_arname)
|
||||
#endif
|
||||
#ifndef MY_write_armap
|
||||
#define MY_write_armap NAME(aout,write_armap)
|
||||
#endif
|
||||
#ifndef MY_close_and_cleanup
|
||||
#define MY_close_and_cleanup NAME(aout,close_and_cleanup)
|
||||
#endif
|
||||
#ifndef MY_set_section_contents
|
||||
#define MY_set_section_contents NAME(aout,set_section_contents)
|
||||
#endif
|
||||
#ifndef MY_get_section_contents
|
||||
#define MY_get_section_contents NAME(aout,get_section_contents)
|
||||
#endif
|
||||
#ifndef MY_new_section_hook
|
||||
#define MY_new_section_hook NAME(aout,new_section_hook)
|
||||
#endif
|
||||
#ifndef MY_get_symtab_upper_bound
|
||||
#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound)
|
||||
#endif
|
||||
#ifndef MY_get_symtab
|
||||
#define MY_get_symtab NAME(aout,get_symtab)
|
||||
#endif
|
||||
#ifndef MY_get_reloc_upper_bound
|
||||
#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound)
|
||||
#endif
|
||||
#ifndef MY_canonicalize_reloc
|
||||
#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc)
|
||||
#endif
|
||||
#ifndef MY_make_empty_symbol
|
||||
#define MY_make_empty_symbol NAME(aout,make_empty_symbol)
|
||||
#endif
|
||||
#ifndef MY_print_symbol
|
||||
#define MY_print_symbol NAME(aout,print_symbol)
|
||||
#endif
|
||||
#ifndef MY_get_symbol_info
|
||||
#define MY_get_symbol_info NAME(aout,get_symbol_info)
|
||||
#endif
|
||||
#ifndef MY_get_lineno
|
||||
#define MY_get_lineno NAME(aout,get_lineno)
|
||||
#endif
|
||||
#ifndef MY_set_arch_mach
|
||||
#define MY_set_arch_mach NAME(aout,set_arch_mach)
|
||||
#endif
|
||||
#ifndef MY_openr_next_archived_file
|
||||
#define MY_openr_next_archived_file NAME(aout,openr_next_archived_file)
|
||||
#endif
|
||||
#ifndef MY_find_nearest_line
|
||||
#define MY_find_nearest_line NAME(aout,find_nearest_line)
|
||||
#endif
|
||||
#ifndef MY_generic_stat_arch_elt
|
||||
#define MY_generic_stat_arch_elt NAME(aout,generic_stat_arch_elt)
|
||||
#endif
|
||||
#ifndef MY_sizeof_headers
|
||||
#define MY_sizeof_headers NAME(aout,sizeof_headers)
|
||||
#endif
|
||||
#ifndef MY_bfd_debug_info_start
|
||||
#define MY_bfd_debug_info_start NAME(aout,bfd_debug_info_start)
|
||||
#endif
|
||||
#ifndef MY_bfd_debug_info_end
|
||||
#define MY_bfd_debug_info_end NAME(aout,bfd_debug_info_end)
|
||||
#endif
|
||||
#ifndef MY_bfd_debug_info_accumulat
|
||||
#define MY_bfd_debug_info_accumulat NAME(aout,bfd_debug_info_accumulat)
|
||||
#endif
|
||||
#ifndef MY_reloc_howto_type_lookup
|
||||
#define MY_reloc_howto_type_lookup NAME(aout,reloc_type_lookup)
|
||||
#endif
|
||||
#ifndef MY_make_debug_symbol
|
||||
#define MY_make_debug_symbol 0
|
||||
#endif
|
||||
|
||||
/* Aout symbols normally have leading underscores */
|
||||
#ifndef MY_symbol_leading_char
|
||||
#define MY_symbol_leading_char '_'
|
||||
#endif
|
||||
|
||||
/* Aout archives normally use spaces for padding */
|
||||
#ifndef AR_PAD_CHAR
|
||||
#define AR_PAD_CHAR ' '
|
||||
#endif
|
||||
|
||||
#ifndef MY_BFD_TARGET
|
||||
bfd_target MY(vec) =
|
||||
{
|
||||
TARGETNAME, /* name */
|
||||
bfd_target_aout_flavour,
|
||||
#ifdef TARGET_IS_BIG_ENDIAN_P
|
||||
true, /* target byte order (big) */
|
||||
true, /* target headers byte order (big) */
|
||||
#else
|
||||
false, /* target byte order (little) */
|
||||
false, /* target headers byte order (little) */
|
||||
#endif
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
|
||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
MY_symbol_leading_char,
|
||||
AR_PAD_CHAR, /* ar_pad_char */
|
||||
15, /* ar_max_namelen */
|
||||
3, /* minimum alignment */
|
||||
#ifdef TARGET_IS_BIG_ENDIAN_P
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
|
||||
#else
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
|
||||
#endif
|
||||
{_bfd_dummy_target, MY_object_p, /* bfd_check_format */
|
||||
bfd_generic_archive_p, MY_core_file_p},
|
||||
{bfd_false, MY_mkobject, /* bfd_set_format */
|
||||
_bfd_generic_mkarchive, bfd_false},
|
||||
{bfd_false, MY_write_object_contents, /* bfd_write_contents */
|
||||
_bfd_write_archive_contents, bfd_false},
|
||||
|
||||
MY_core_file_failing_command,
|
||||
MY_core_file_failing_signal,
|
||||
MY_core_file_matches_executable_p,
|
||||
MY_slurp_armap,
|
||||
MY_slurp_extended_name_table,
|
||||
MY_truncate_arname,
|
||||
MY_write_armap,
|
||||
MY_close_and_cleanup,
|
||||
MY_set_section_contents,
|
||||
MY_get_section_contents,
|
||||
MY_new_section_hook,
|
||||
MY_get_symtab_upper_bound,
|
||||
MY_get_symtab,
|
||||
MY_get_reloc_upper_bound,
|
||||
MY_canonicalize_reloc,
|
||||
MY_make_empty_symbol,
|
||||
MY_print_symbol,
|
||||
MY_get_symbol_info,
|
||||
MY_get_lineno,
|
||||
MY_set_arch_mach,
|
||||
MY_openr_next_archived_file,
|
||||
MY_find_nearest_line,
|
||||
MY_generic_stat_arch_elt,
|
||||
MY_sizeof_headers,
|
||||
MY_bfd_debug_info_start,
|
||||
MY_bfd_debug_info_end,
|
||||
MY_bfd_debug_info_accumulate,
|
||||
bfd_generic_get_relocated_section_contents,
|
||||
bfd_generic_relax_section,
|
||||
bfd_generic_seclet_link,
|
||||
MY_reloc_howto_type_lookup,
|
||||
MY_make_debug_symbol,
|
||||
(PTR) MY_backend_data,
|
||||
};
|
||||
#endif /* MY_BFD_TARGET */
|
|
@ -0,0 +1,26 @@
|
|||
/* BFD back-end for 32-bit a.out files.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: aout32.c,v 1.1 1994/01/28 12:37:32 pk Exp $
|
||||
*/
|
||||
|
||||
#define ARCH_SIZE 32
|
||||
|
||||
#include "aoutx.h"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
|||
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:17 pk Exp $
|
||||
|
||||
SRCS+= netbsd386.c cpu-i386.c
|
||||
|
||||
CFLAGS+= -DTRAD_CORE
|
||||
|
||||
VECTORS= -DDEFAULT_VECTOR=netbsd_386_vec \
|
||||
-DSELECT_ARCHITECTURES=bfd_i386_arch \
|
||||
-DSELECT_VECS='&netbsd_386_vec'
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* BFD support for the Intel 386 architecture.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: cpu-i386.c,v 1.1 1994/01/28 12:38:19 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
static bfd_arch_info_type arch_info_struct =
|
||||
{
|
||||
32, /* 32 bits in a word */
|
||||
32, /* 32 bits in an address */
|
||||
8, /* 8 bits in a byte */
|
||||
bfd_arch_i386,
|
||||
0, /* only 1 machine */
|
||||
"i386",
|
||||
"i386",
|
||||
3,
|
||||
true, /* the one and only */
|
||||
bfd_default_compatible,
|
||||
bfd_default_scan ,
|
||||
0,
|
||||
};
|
||||
|
||||
void DEFUN_VOID(bfd_i386_arch)
|
||||
{
|
||||
bfd_arch_linkin(&arch_info_struct);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* BFD back-end for NetBSD/386 a.out-ish binaries.
|
||||
Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: netbsd386.c,v 1.1 1994/01/28 12:38:20 pk Exp $
|
||||
*/
|
||||
|
||||
#define BYTES_IN_WORD 4
|
||||
#define ARCH 32
|
||||
#undef TARGET_IS_BIG_ENDIAN_P
|
||||
#undef HOST_BIG_ENDIAN_P
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define SEGMENT_SIZE PAGE_SIZE
|
||||
#define __LDPGSZ 4096
|
||||
|
||||
#define DEFAULT_ARCH bfd_arch_i386
|
||||
#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN)
|
||||
|
||||
#define MY(OP) CAT(netbsd_386_,OP)
|
||||
/* This needs to start with a.out so GDB knows it is an a.out variant. */
|
||||
#define TARGETNAME "a.out-netbsd-386"
|
||||
|
||||
#include "netbsd.h"
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:21 pk Exp $ */
|
||||
#ifndef hosts_i386bsd_H
|
||||
/* Intel 386 running any BSD Unix */
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#ifndef O_ACCMODE
|
||||
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
||||
#endif
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
#define HOST_PAGE_SIZE NBPG
|
||||
#define HOST_MACHINE_ARCH bfd_arch_i386
|
||||
#define HOST_TEXT_START_ADDR USRTEXT
|
||||
|
||||
/* Jolitz suggested defining HOST_STACK_END_ADDR to
|
||||
(u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on
|
||||
both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */
|
||||
|
||||
#if defined(__bsdi__) || defined(__NetBSD__)
|
||||
/* This seems to be the right thing for BSDI. */
|
||||
#define HOST_STACK_END_ADDR USRSTACK
|
||||
#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
|
||||
#else
|
||||
/* This seems to be the right thing for 386BSD release 0.1. */
|
||||
#define HOST_STACK_END_ADDR (USRSTACK - MAXSSIZ)
|
||||
#endif
|
||||
|
||||
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
|
||||
((core_bfd)->tdata.trad_core_data->u.u_sig)
|
||||
#define u_comm u_kproc.kp_proc.p_comm
|
||||
|
||||
#include "fopen-same.h"
|
||||
|
||||
#define hosts_i386bsd_H
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:23 pk Exp $
|
||||
|
||||
SRCS+= netbsdm68k.c cpu-m68k.c
|
||||
|
||||
CFLAGS+= -DTRAD_CORE
|
||||
|
||||
VECTORS= -DDEFAULT_VECTOR=netbsd_m68k_vec \
|
||||
-DSELECT_ARCHITECTURES=bfd_m68k_arch \
|
||||
-DSELECT_VECS='&netbsd_m68k_vec'
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* BFD library support routines for architectures.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Hacked by Steve Chamberlain of Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: cpu-m68k.c,v 1.1 1994/01/28 12:38:24 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
int bfd_default_scan_num_mach();
|
||||
|
||||
|
||||
#define N(name, print,d) \
|
||||
{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, 0, }
|
||||
|
||||
static bfd_arch_info_type arch_info_struct[] =
|
||||
{
|
||||
N(68000,"m68k:68000",false),
|
||||
N(68008,"m68k:68008",false),
|
||||
N(68010,"m68k:68010",false),
|
||||
N(68020,"m68k:68020",true), /* the word m68k will match this too */
|
||||
N(68030,"m68k:68030",false),
|
||||
N(68040,"m68k:68040",false),
|
||||
N(68070,"m68k:68070",false),
|
||||
{ 0 },
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
void DEFUN_VOID(bfd_m68k_arch)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; arch_info_struct[i].bits_per_word; i++)
|
||||
{
|
||||
bfd_arch_linkin(&arch_info_struct[i]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* BFD back-end for NetBSD/m68k a.out-ish binaries.
|
||||
Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: netbsdm68k.c,v 1.1 1994/01/28 12:38:25 pk Exp $
|
||||
*/
|
||||
|
||||
#define BYTES_IN_WORD 4
|
||||
#define ARCH 32
|
||||
#define HOST_BIG_ENDIAN_P
|
||||
#define TARGET_BIG_ENDIAN_P
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define SEGMENT_SIZE PAGE_SIZE
|
||||
#define __LDPGSZ 4096
|
||||
|
||||
#define DEFAULT_ARCH bfd_arch_m68k
|
||||
#define MACHTYPE_OK(mtype) ((mtype) == M_HP300 || (mtype) == M_M68K_NETBSD || (mtype) == M_UNKNOWN)
|
||||
|
||||
#define MY(OP) CAT(netbsd_m68k_,OP)
|
||||
/* This needs to start with a.out so GDB knows it is an a.out variant. */
|
||||
#define TARGETNAME "a.out-netbsd-m68k"
|
||||
|
||||
#include "netbsd.h"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:26 pk Exp $ */
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <machine/param.h> /* BSD 4.4 alpha or better */
|
||||
|
||||
#ifndef O_ACCMODE
|
||||
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
||||
#endif
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
#define NO_CORE_COMMAND /* Core files don't have command name */
|
||||
|
||||
|
||||
#define HOST_PAGE_SIZE NBPG
|
||||
#define HOST_SEGMENT_SIZE NBPG /* Data seg start addr rounds to NBPG */
|
||||
#define HOST_MACHINE_ARCH bfd_arch_m68k
|
||||
/* #define HOST_MACHINE_MACHINE */
|
||||
|
||||
#define HOST_TEXT_START_ADDR 0
|
||||
#define HOST_STACK_END_ADDR 0xfff00000
|
||||
|
||||
#include "fopen-same.h"
|
|
@ -0,0 +1,11 @@
|
|||
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:28 pk Exp $
|
||||
|
||||
SRCS+= netbsd_sparc.c cpu-sparc.c
|
||||
|
||||
CFLAGS+= -DTRAD_CORE
|
||||
|
||||
VECTORS= -DDEFAULT_VECTOR=netbsd_sparc_vec \
|
||||
-DSELECT_ARCHITECTURES=bfd_sparc_arch \
|
||||
-DSELECT_VECS='&netbsd_sparc_vec'
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* BFD support for the SPARC architecture.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: cpu-sparc.c,v 1.1 1994/01/28 12:38:29 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
static bfd_arch_info_type arch_info_struct =
|
||||
{
|
||||
32, /* 32 bits in a word */
|
||||
32, /* 32 bits in an address */
|
||||
8, /* 8 bits in a byte */
|
||||
bfd_arch_sparc,
|
||||
0, /* only 1 machine */
|
||||
"sparc",
|
||||
"sparc",
|
||||
3,
|
||||
true, /* the one and only */
|
||||
bfd_default_compatible,
|
||||
bfd_default_scan ,
|
||||
0,
|
||||
};
|
||||
|
||||
void DEFUN_VOID(bfd_sparc_arch)
|
||||
{
|
||||
bfd_arch_linkin(&arch_info_struct);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/* $Id: netbsd_sparc.c,v 1.1 1994/01/28 12:38:30 pk Exp $ */
|
||||
|
||||
#define TARGET_IS_BIG_ENDIAN_P
|
||||
#define HOST_BIG_ENDIAN_P
|
||||
#define BYTES_IN_WORD 4
|
||||
#define ARCH 32
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define SEGMENT_SIZE PAGE_SIZE
|
||||
#define __LDPGSZ 8192
|
||||
#define MID_SPARC 138
|
||||
#define DEFAULT_ARCH bfd_arch_sparc
|
||||
|
||||
#define MACHTYPE_OK(mtype) ((mtype) == MID_SPARC || (mtype) == M_UNKNOWN)
|
||||
|
||||
#define MY(OP) CAT(netbsd_sparc_,OP)
|
||||
/* This needs to start with a.out so GDB knows it is an a.out variant. */
|
||||
#define TARGETNAME "a.out-netbsd-sparc"
|
||||
|
||||
#include "netbsd.h"
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:31 pk Exp $ */
|
||||
|
||||
#ifndef hosts_sparc_H
|
||||
#define hosts_sparc_H
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#ifndef O_ACCMODE
|
||||
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
||||
#endif
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
#include "fopen-same.h"
|
||||
|
||||
|
||||
#define HOST_PAGE_SIZE NBPG
|
||||
#define HOST_MACHINE_ARCH bfd_arch_sparc
|
||||
#define HOST_TEXT_START_ADDR USRTEXT
|
||||
|
||||
#define HOST_STACK_END_ADDR USRSTACK
|
||||
#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
|
||||
|
||||
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
|
||||
((core_bfd)->tdata.trad_core_data->u.u_sig)
|
||||
#define u_comm u_kproc.kp_proc.p_comm
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,734 @@
|
|||
/* BFD library support routines for architectures.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
|
||||
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: archures.c,v 1.1 1994/01/28 12:37:37 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
SECTION
|
||||
Architectures
|
||||
|
||||
BFD's idea of an architecture is implimented in
|
||||
<<archures.c>>. BFD keeps one atom in a BFD describing the
|
||||
architecture of the data attached to the BFD; a pointer to a
|
||||
<<bfd_arch_info_type>>.
|
||||
|
||||
Pointers to structures can be requested independently of a bfd
|
||||
so that an architecture's information can be interrogated
|
||||
without access to an open bfd.
|
||||
|
||||
The arch information is provided by each architecture package.
|
||||
The set of default architectures is selected by the #define
|
||||
<<SELECT_ARCHITECTURES>>. This is normally set up in the
|
||||
<<config/target.mt>> file of your choice. If the name is not
|
||||
defined, then all the architectures supported are included.
|
||||
|
||||
When BFD starts up, all the architectures are called with an
|
||||
initialize method. It is up to the architecture back end to
|
||||
insert as many items into the list of architectures as it wants to;
|
||||
generally this would be one for each machine and one for the
|
||||
default case (an item with a machine field of 0).
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
SUBSECTION
|
||||
bfd_architecture
|
||||
|
||||
DESCRIPTION
|
||||
This enum gives the object file's CPU architecture, in a
|
||||
global sense --- i.e., what processor family does it belong to?
|
||||
There is another field, which indicates what processor within
|
||||
the family is in use. The machine gives a number which
|
||||
distingushes different versions of the architecture,
|
||||
containing for example 2 and 3 for Intel i960 KA and i960 KB,
|
||||
and 68020 and 68030 for Motorola 68020 and 68030.
|
||||
|
||||
.enum bfd_architecture
|
||||
.{
|
||||
. bfd_arch_unknown, {* File arch not known *}
|
||||
. bfd_arch_obscure, {* Arch known, not one of these *}
|
||||
. bfd_arch_m68k, {* Motorola 68xxx *}
|
||||
. bfd_arch_vax, {* DEC Vax *}
|
||||
. bfd_arch_i960, {* Intel 960 *}
|
||||
. {* The order of the following is important.
|
||||
. lower number indicates a machine type that
|
||||
. only accepts a subset of the instructions
|
||||
. available to machines with higher numbers.
|
||||
. The exception is the "ca", which is
|
||||
. incompatible with all other machines except
|
||||
. "core". *}
|
||||
.
|
||||
.#define bfd_mach_i960_core 1
|
||||
.#define bfd_mach_i960_ka_sa 2
|
||||
.#define bfd_mach_i960_kb_sb 3
|
||||
.#define bfd_mach_i960_mc 4
|
||||
.#define bfd_mach_i960_xa 5
|
||||
.#define bfd_mach_i960_ca 6
|
||||
.
|
||||
. bfd_arch_a29k, {* AMD 29000 *}
|
||||
. bfd_arch_sparc, {* SPARC *}
|
||||
. bfd_arch_mips, {* MIPS Rxxxx *}
|
||||
. bfd_arch_i386, {* Intel 386 *}
|
||||
. bfd_arch_we32k, {* AT&T WE32xxx *}
|
||||
. bfd_arch_tahoe, {* CCI/Harris Tahoe *}
|
||||
. bfd_arch_i860, {* Intel 860 *}
|
||||
. bfd_arch_romp, {* IBM ROMP PC/RT *}
|
||||
. bfd_arch_alliant, {* Alliant *}
|
||||
. bfd_arch_convex, {* Convex *}
|
||||
. bfd_arch_m88k, {* Motorola 88xxx *}
|
||||
. bfd_arch_pyramid, {* Pyramid Technology *}
|
||||
. bfd_arch_h8300, {* Hitachi H8/300 *}
|
||||
.#define bfd_mach_h8300 1
|
||||
.#define bfd_mach_h8300h 2
|
||||
. bfd_arch_rs6000, {* IBM RS/6000 *}
|
||||
. bfd_arch_hppa, {* HP PA RISC *}
|
||||
. bfd_arch_z8k, {* Zilog Z8000 *}
|
||||
.#define bfd_mach_z8001 1
|
||||
.#define bfd_mach_z8002 2
|
||||
. bfd_arch_h8500, {* Hitachi H8/500 *}
|
||||
. bfd_arch_sh, {* Hitachi SH *}
|
||||
. bfd_arch_alpha, {* Dec Alpha *}
|
||||
. bfd_arch_last
|
||||
. };
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/*
|
||||
|
||||
SUBSECTION
|
||||
bfd_arch_info
|
||||
|
||||
DESCRIPTION
|
||||
This structure contains information on architectures for use
|
||||
within BFD.
|
||||
|
||||
.
|
||||
.typedef struct bfd_arch_info
|
||||
.{
|
||||
. int bits_per_word;
|
||||
. int bits_per_address;
|
||||
. int bits_per_byte;
|
||||
. enum bfd_architecture arch;
|
||||
. long mach;
|
||||
. char *arch_name;
|
||||
. CONST char *printable_name;
|
||||
. unsigned int section_align_power;
|
||||
. {* true if this is the default machine for the architecture *}
|
||||
. boolean the_default;
|
||||
. CONST struct bfd_arch_info * (*compatible)
|
||||
. PARAMS ((CONST struct bfd_arch_info *a,
|
||||
. CONST struct bfd_arch_info *b));
|
||||
.
|
||||
. boolean (*scan) PARAMS ((CONST struct bfd_arch_info *, CONST char *));
|
||||
. {* How to disassemble an instruction, producing a printable
|
||||
. representation on a specified stdio stream. This isn't
|
||||
. defined for most processors at present, because of the size
|
||||
. of the additional tables it would drag in, and because gdb
|
||||
. wants to use a different interface. *}
|
||||
. unsigned int (*disassemble) PARAMS ((bfd_vma addr, CONST char *data,
|
||||
. PTR stream));
|
||||
.
|
||||
. struct bfd_arch_info *next;
|
||||
.} bfd_arch_info_type;
|
||||
*/
|
||||
|
||||
bfd_arch_info_type *bfd_arch_info_list;
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_printable_name
|
||||
|
||||
SYNOPSIS
|
||||
CONST char *bfd_printable_name(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return a printable string representing the architecture and machine
|
||||
from the pointer to the arch info structure
|
||||
|
||||
*/
|
||||
|
||||
CONST char *
|
||||
DEFUN(bfd_printable_name, (abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->printable_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_scan_arch
|
||||
|
||||
SYNOPSIS
|
||||
bfd_arch_info_type *bfd_scan_arch(CONST char *);
|
||||
|
||||
DESCRIPTION
|
||||
This routine is provided with a string and tries to work out
|
||||
if bfd supports any cpu which could be described with the name
|
||||
provided. The routine returns a pointer to an arch_info
|
||||
structure if a machine is found, otherwise NULL.
|
||||
|
||||
*/
|
||||
|
||||
bfd_arch_info_type *
|
||||
DEFUN(bfd_scan_arch,(string),
|
||||
CONST char *string)
|
||||
{
|
||||
struct bfd_arch_info *ap;
|
||||
|
||||
/* Look through all the installed architectures */
|
||||
for (ap = bfd_arch_info_list;
|
||||
ap != (bfd_arch_info_type *)NULL;
|
||||
ap = ap->next) {
|
||||
|
||||
if (ap->scan(ap, string))
|
||||
return ap;
|
||||
}
|
||||
return (bfd_arch_info_type *)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_arch_get_compatible
|
||||
|
||||
SYNOPSIS
|
||||
CONST bfd_arch_info_type *bfd_arch_get_compatible(
|
||||
CONST bfd *abfd,
|
||||
CONST bfd *bbfd);
|
||||
|
||||
DESCRIPTION
|
||||
This routine is used to determine whether two BFDs'
|
||||
architectures and achine types are compatible. It calculates
|
||||
the lowest common denominator between the two architectures
|
||||
and machine types implied by the BFDs and returns a pointer to
|
||||
an arch_info structure describing the compatible machine.
|
||||
*/
|
||||
|
||||
CONST bfd_arch_info_type *
|
||||
DEFUN(bfd_arch_get_compatible,(abfd, bbfd),
|
||||
CONST bfd *abfd AND
|
||||
CONST bfd *bbfd)
|
||||
|
||||
{
|
||||
return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_DEFINITION
|
||||
bfd_default_arch_struct
|
||||
|
||||
DESCRIPTION
|
||||
The <<bfd_default_arch_struct>> is an item of
|
||||
<<bfd_arch_info_type>> which has been initialized to a fairly
|
||||
generic state. A BFD starts life by pointing to this
|
||||
structure, until the correct back end has determined the real
|
||||
architecture of the file.
|
||||
|
||||
.extern bfd_arch_info_type bfd_default_arch_struct;
|
||||
|
||||
*/
|
||||
|
||||
bfd_arch_info_type bfd_default_arch_struct =
|
||||
{
|
||||
32,32,8,bfd_arch_unknown,0,"unknown","unknown",2,true,
|
||||
bfd_default_compatible,
|
||||
bfd_default_scan,
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_arch_info
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_set_arch_info(bfd *, bfd_arch_info_type *);
|
||||
|
||||
*/
|
||||
|
||||
void DEFUN(bfd_set_arch_info,(abfd, arg),
|
||||
bfd *abfd AND
|
||||
bfd_arch_info_type *arg)
|
||||
{
|
||||
abfd->arch_info = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_default_set_arch_mach
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_default_set_arch_mach(bfd *abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach);
|
||||
|
||||
DESCRIPTION
|
||||
Set the architecture and machine type in a bfd. This finds the
|
||||
correct pointer to structure and inserts it into the arch_info
|
||||
pointer.
|
||||
*/
|
||||
|
||||
boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
|
||||
bfd *abfd AND
|
||||
enum bfd_architecture arch AND
|
||||
unsigned long mach)
|
||||
{
|
||||
static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct;
|
||||
boolean found = false;
|
||||
/* run through the table to find the one we want, we keep a little
|
||||
cache to speed things up */
|
||||
if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) {
|
||||
bfd_arch_info_type *ptr;
|
||||
old_ptr = (bfd_arch_info_type *)NULL;
|
||||
for (ptr = bfd_arch_info_list;
|
||||
ptr != (bfd_arch_info_type *)NULL;
|
||||
ptr= ptr->next) {
|
||||
if (ptr->arch == arch &&
|
||||
((ptr->mach == mach) || (ptr->the_default && mach == 0))) {
|
||||
old_ptr = ptr;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found==false) {
|
||||
/*looked for it and it wasn't there, so put in the default */
|
||||
old_ptr = &bfd_default_arch_struct;
|
||||
bfd_error = bad_value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* it was in the cache */
|
||||
found = true;
|
||||
}
|
||||
|
||||
abfd->arch_info = old_ptr;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_arch
|
||||
|
||||
SYNOPSIS
|
||||
enum bfd_architecture bfd_get_arch(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Returns the enumerated type which describes the supplied bfd's
|
||||
architecture
|
||||
|
||||
*/
|
||||
|
||||
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->arch;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_mach
|
||||
|
||||
SYNOPSIS
|
||||
unsigned long bfd_get_mach(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Returns the long type which describes the supplied bfd's
|
||||
machine
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
DEFUN(bfd_get_mach, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->mach;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_arch_bits_per_byte
|
||||
|
||||
SYNOPSIS
|
||||
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Returns the number of bits in one of the architectures bytes
|
||||
|
||||
*/
|
||||
|
||||
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->bits_per_byte;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_arch_bits_per_address
|
||||
|
||||
SYNOPSIS
|
||||
unsigned int bfd_arch_bits_per_address(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Returns the number of bits in one of the architectures addresses
|
||||
*/
|
||||
|
||||
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->bits_per_address;
|
||||
}
|
||||
|
||||
|
||||
extern void bfd_a29k_arch PARAMS ((void));
|
||||
extern void bfd_alpha_arch PARAMS ((void));
|
||||
extern void bfd_h8300_arch PARAMS ((void));
|
||||
extern void bfd_h8500_arch PARAMS ((void));
|
||||
extern void bfd_hppa_arch PARAMS ((void));
|
||||
extern void bfd_i386_arch PARAMS ((void));
|
||||
extern void bfd_i960_arch PARAMS ((void));
|
||||
extern void bfd_m68k_arch PARAMS ((void));
|
||||
extern void bfd_m88k_arch PARAMS ((void));
|
||||
extern void bfd_mips_arch PARAMS ((void));
|
||||
extern void bfd_rs6000_arch PARAMS ((void));
|
||||
extern void bfd_sh_arch PARAMS ((void));
|
||||
extern void bfd_sparc_arch PARAMS ((void));
|
||||
extern void bfd_vax_arch PARAMS ((void));
|
||||
extern void bfd_we32k_arch PARAMS ((void));
|
||||
extern void bfd_z8k_arch PARAMS ((void));
|
||||
|
||||
static void (*archures_init_table[]) PARAMS ((void)) =
|
||||
{
|
||||
#ifdef SELECT_ARCHITECTURES
|
||||
SELECT_ARCHITECTURES,
|
||||
#else
|
||||
bfd_a29k_arch,
|
||||
bfd_alpha_arch,
|
||||
bfd_h8300_arch,
|
||||
bfd_h8500_arch,
|
||||
bfd_hppa_arch,
|
||||
bfd_i386_arch,
|
||||
bfd_i960_arch,
|
||||
bfd_m68k_arch,
|
||||
bfd_m88k_arch,
|
||||
bfd_mips_arch,
|
||||
bfd_rs6000_arch,
|
||||
bfd_sh_arch,
|
||||
bfd_sparc_arch,
|
||||
bfd_vax_arch,
|
||||
bfd_we32k_arch,
|
||||
bfd_z8k_arch,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_arch_init
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_arch_init(void);
|
||||
|
||||
DESCRIPTION
|
||||
This routine initializes the architecture dispatch table by
|
||||
calling all installed architecture packages and getting them
|
||||
to poke around.
|
||||
*/
|
||||
|
||||
void
|
||||
DEFUN_VOID(bfd_arch_init)
|
||||
{
|
||||
void (**ptable) PARAMS ((void));
|
||||
for (ptable = archures_init_table;
|
||||
*ptable ;
|
||||
ptable++)
|
||||
{
|
||||
(*ptable)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_arch_linkin
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_arch_linkin(bfd_arch_info_type *);
|
||||
|
||||
DESCRIPTION
|
||||
Link the provided arch info structure into the list
|
||||
*/
|
||||
|
||||
void DEFUN(bfd_arch_linkin,(ptr),
|
||||
bfd_arch_info_type *ptr)
|
||||
{
|
||||
ptr->next = bfd_arch_info_list;
|
||||
bfd_arch_info_list = ptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_default_compatible
|
||||
|
||||
SYNOPSIS
|
||||
CONST bfd_arch_info_type *bfd_default_compatible
|
||||
(CONST bfd_arch_info_type *a,
|
||||
CONST bfd_arch_info_type *b);
|
||||
|
||||
DESCRIPTION
|
||||
The default function for testing for compatibility.
|
||||
*/
|
||||
|
||||
CONST bfd_arch_info_type *
|
||||
DEFUN(bfd_default_compatible,(a,b),
|
||||
CONST bfd_arch_info_type *a AND
|
||||
CONST bfd_arch_info_type *b)
|
||||
{
|
||||
if(a->arch != b->arch) return NULL;
|
||||
|
||||
if (a->mach > b->mach) {
|
||||
return a;
|
||||
}
|
||||
if (b->mach > a->mach) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_default_scan
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_default_scan(CONST struct bfd_arch_info *, CONST char *);
|
||||
|
||||
DESCRIPTION
|
||||
The default function for working out whether this is an
|
||||
architecture hit and a machine hit.
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_default_scan,(info, string),
|
||||
CONST struct bfd_arch_info *info AND
|
||||
CONST char *string)
|
||||
{
|
||||
CONST char *ptr_src;
|
||||
CONST char *ptr_tst;
|
||||
unsigned long number;
|
||||
enum bfd_architecture arch;
|
||||
/* First test for an exact match */
|
||||
if (strcmp(string, info->printable_name) == 0) return true;
|
||||
|
||||
/* See how much of the supplied string matches with the
|
||||
architecture, eg the string m68k:68020 would match the 68k entry
|
||||
up to the :, then we get left with the machine number */
|
||||
|
||||
for (ptr_src = string,
|
||||
ptr_tst = info->arch_name;
|
||||
*ptr_src && *ptr_tst;
|
||||
ptr_src++,
|
||||
ptr_tst++)
|
||||
{
|
||||
if (*ptr_src != *ptr_tst) break;
|
||||
}
|
||||
|
||||
/* Chewed up as much of the architecture as will match, skip any
|
||||
colons */
|
||||
if (*ptr_src == ':') ptr_src++;
|
||||
|
||||
if (*ptr_src == 0) {
|
||||
/* nothing more, then only keep this one if it is the default
|
||||
machine for this architecture */
|
||||
return info->the_default;
|
||||
}
|
||||
number = 0;
|
||||
while (isdigit(*ptr_src)) {
|
||||
number = number * 10 + *ptr_src - '0';
|
||||
ptr_src++;
|
||||
}
|
||||
|
||||
switch (number)
|
||||
{
|
||||
case 300:
|
||||
arch = bfd_arch_h8300;
|
||||
break;
|
||||
|
||||
case 500:
|
||||
arch = bfd_arch_h8500;
|
||||
break;
|
||||
|
||||
case 68010:
|
||||
case 68020:
|
||||
case 68030:
|
||||
case 68040:
|
||||
case 68332:
|
||||
case 68050:
|
||||
case 68000:
|
||||
arch = bfd_arch_m68k;
|
||||
break;
|
||||
case 386:
|
||||
case 80386:
|
||||
case 486:
|
||||
case 80486:
|
||||
arch = bfd_arch_i386;
|
||||
break;
|
||||
case 29000:
|
||||
arch = bfd_arch_a29k;
|
||||
break;
|
||||
|
||||
case 8000:
|
||||
arch = bfd_arch_z8k;
|
||||
break;
|
||||
|
||||
case 32000:
|
||||
arch = bfd_arch_we32k;
|
||||
break;
|
||||
|
||||
case 860:
|
||||
case 80860:
|
||||
arch = bfd_arch_i860;
|
||||
break;
|
||||
case 960:
|
||||
case 80960:
|
||||
arch = bfd_arch_i960;
|
||||
break;
|
||||
|
||||
case 2000:
|
||||
case 3000:
|
||||
case 4000:
|
||||
case 4400:
|
||||
arch = bfd_arch_mips;
|
||||
break;
|
||||
|
||||
case 6000:
|
||||
arch = bfd_arch_rs6000;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (arch != info->arch)
|
||||
return false;
|
||||
|
||||
if (number != info->mach)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_arch_info
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
bfd_arch_info_type * bfd_get_arch_info(bfd *);
|
||||
|
||||
*/
|
||||
|
||||
bfd_arch_info_type *
|
||||
DEFUN(bfd_get_arch_info,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_lookup_arch
|
||||
|
||||
SYNOPSIS
|
||||
bfd_arch_info_type *bfd_lookup_arch
|
||||
(enum bfd_architecture
|
||||
arch,
|
||||
long machine);
|
||||
|
||||
DESCRIPTION
|
||||
Look for the architecure info struct which matches the
|
||||
arguments given. A machine of 0 will match the
|
||||
machine/architecture structure which marks itself as the
|
||||
default.
|
||||
*/
|
||||
|
||||
bfd_arch_info_type *
|
||||
DEFUN(bfd_lookup_arch,(arch, machine),
|
||||
enum bfd_architecture arch AND
|
||||
long machine)
|
||||
{
|
||||
bfd_arch_info_type *ap;
|
||||
bfd_check_init();
|
||||
for (ap = bfd_arch_info_list;
|
||||
ap != (bfd_arch_info_type *)NULL;
|
||||
ap = ap->next) {
|
||||
if (ap->arch == arch &&
|
||||
((ap->mach == machine)
|
||||
|| (ap->the_default && machine == 0))) {
|
||||
return ap;
|
||||
}
|
||||
}
|
||||
return (bfd_arch_info_type *)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_printable_arch_mach
|
||||
|
||||
SYNOPSIS
|
||||
CONST char * bfd_printable_arch_mach
|
||||
(enum bfd_architecture arch, unsigned long machine);
|
||||
|
||||
DESCRIPTION
|
||||
Return a printable string representing the architecture and
|
||||
machine type.
|
||||
|
||||
NB. The use of this routine is depreciated.
|
||||
*/
|
||||
|
||||
CONST char *
|
||||
DEFUN(bfd_printable_arch_mach,(arch, machine),
|
||||
enum bfd_architecture arch AND
|
||||
unsigned long machine)
|
||||
{
|
||||
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
|
||||
if(ap) return ap->printable_name;
|
||||
return "UNKNOWN!";
|
||||
}
|
|
@ -0,0 +1,736 @@
|
|||
/* Generic BFD library interface and support routines.
|
||||
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: bfd.c,v 1.1 1994/01/28 12:37:38 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
<<typedef bfd>>
|
||||
|
||||
A BFD is has type <<bfd>>; objects of this type are the
|
||||
cornerstone of any application using <<libbfd>>. References
|
||||
though the BFD and to data in the BFD give the entire BFD
|
||||
functionality.
|
||||
|
||||
Here is the struct used to define the type <<bfd>>. This
|
||||
contains the major data about the file, and contains pointers
|
||||
to the rest of the data.
|
||||
|
||||
CODE_FRAGMENT
|
||||
.
|
||||
.struct _bfd
|
||||
.{
|
||||
. {* The filename the application opened the BFD with. *}
|
||||
. CONST char *filename;
|
||||
.
|
||||
. {* A pointer to the target jump table. *}
|
||||
. struct bfd_target *xvec;
|
||||
.
|
||||
. {* To avoid dragging too many header files into every file that
|
||||
. includes `<<bfd.h>>', IOSTREAM has been declared as a "char
|
||||
. *", and MTIME as a "long". Their correct types, to which they
|
||||
. are cast when used, are "FILE *" and "time_t". The iostream
|
||||
. is the result of an fopen on the filename. *}
|
||||
. char *iostream;
|
||||
.
|
||||
. {* Is the file being cached *}
|
||||
.
|
||||
. boolean cacheable;
|
||||
.
|
||||
. {* Marks whether there was a default target specified when the
|
||||
. BFD was opened. This is used to select what matching algorithm
|
||||
. to use to chose the back end. *}
|
||||
.
|
||||
. boolean target_defaulted;
|
||||
.
|
||||
. {* The caching routines use these to maintain a
|
||||
. least-recently-used list of BFDs *}
|
||||
.
|
||||
. struct _bfd *lru_prev, *lru_next;
|
||||
.
|
||||
. {* When a file is closed by the caching routines, BFD retains
|
||||
. state information on the file here:
|
||||
. *}
|
||||
.
|
||||
. file_ptr where;
|
||||
.
|
||||
. {* and here:*}
|
||||
.
|
||||
. boolean opened_once;
|
||||
.
|
||||
. {* Set if we have a locally maintained mtime value, rather than
|
||||
. getting it from the file each time: *}
|
||||
.
|
||||
. boolean mtime_set;
|
||||
.
|
||||
. {* File modified time, if mtime_set is true: *}
|
||||
.
|
||||
. long mtime;
|
||||
.
|
||||
. {* Reserved for an unimplemented file locking extension.*}
|
||||
.
|
||||
. int ifd;
|
||||
.
|
||||
. {* The format which belongs to the BFD.*}
|
||||
.
|
||||
. bfd_format format;
|
||||
.
|
||||
. {* The direction the BFD was opened with*}
|
||||
.
|
||||
. enum bfd_direction {no_direction = 0,
|
||||
. read_direction = 1,
|
||||
. write_direction = 2,
|
||||
. both_direction = 3} direction;
|
||||
.
|
||||
. {* Format_specific flags*}
|
||||
.
|
||||
. flagword flags;
|
||||
.
|
||||
. {* Currently my_archive is tested before adding origin to
|
||||
. anything. I believe that this can become always an add of
|
||||
. origin, with origin set to 0 for non archive files. *}
|
||||
.
|
||||
. file_ptr origin;
|
||||
.
|
||||
. {* Remember when output has begun, to stop strange things
|
||||
. happening. *}
|
||||
. boolean output_has_begun;
|
||||
.
|
||||
. {* Pointer to linked list of sections*}
|
||||
. struct sec *sections;
|
||||
.
|
||||
. {* The number of sections *}
|
||||
. unsigned int section_count;
|
||||
.
|
||||
. {* Stuff only useful for object files:
|
||||
. The start address. *}
|
||||
. bfd_vma start_address;
|
||||
.
|
||||
. {* Used for input and output*}
|
||||
. unsigned int symcount;
|
||||
.
|
||||
. {* Symbol table for output BFD*}
|
||||
. struct symbol_cache_entry **outsymbols;
|
||||
.
|
||||
. {* Pointer to structure which contains architecture information*}
|
||||
. struct bfd_arch_info *arch_info;
|
||||
.
|
||||
. {* Stuff only useful for archives:*}
|
||||
. PTR arelt_data;
|
||||
. struct _bfd *my_archive;
|
||||
. struct _bfd *next;
|
||||
. struct _bfd *archive_head;
|
||||
. boolean has_armap;
|
||||
.
|
||||
. {* Used by the back end to hold private data. *}
|
||||
.
|
||||
. union
|
||||
. {
|
||||
. struct aout_data_struct *aout_data;
|
||||
. struct artdata *aout_ar_data;
|
||||
. struct _oasys_data *oasys_obj_data;
|
||||
. struct _oasys_ar_data *oasys_ar_data;
|
||||
. struct coff_tdata *coff_obj_data;
|
||||
. struct ecoff_tdata *ecoff_obj_data;
|
||||
. struct ieee_data_struct *ieee_data;
|
||||
. struct ieee_ar_data_struct *ieee_ar_data;
|
||||
. struct srec_data_struct *srec_data;
|
||||
. struct tekhex_data_struct *tekhex_data;
|
||||
. struct elf_obj_tdata *elf_obj_data;
|
||||
. struct nlm_obj_tdata *nlm_obj_data;
|
||||
. struct bout_data_struct *bout_data;
|
||||
. struct sun_core_struct *sun_core_data;
|
||||
. struct trad_core_struct *trad_core_data;
|
||||
. struct hppa_data_struct *hppa_data;
|
||||
. struct hpux_core_struct *hpux_core_data;
|
||||
. struct sgi_core_struct *sgi_core_data;
|
||||
. struct lynx_core_struct *lynx_core_data;
|
||||
. struct osf_core_struct *osf_core_data;
|
||||
. PTR any;
|
||||
. } tdata;
|
||||
.
|
||||
. {* Used by the application to hold private data*}
|
||||
. PTR usrdata;
|
||||
.
|
||||
. {* Where all the allocated stuff under this BFD goes *}
|
||||
. struct obstack memory;
|
||||
.
|
||||
. {* Is this really needed in addition to usrdata? *}
|
||||
. asymbol **ld_symbols;
|
||||
.};
|
||||
.
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "coff/internal.h"
|
||||
#include "coff/sym.h"
|
||||
#include "libcoff.h"
|
||||
#include "libecoff.h"
|
||||
#undef obj_symbols
|
||||
#include "libelf.h"
|
||||
|
||||
#undef strerror
|
||||
extern char *strerror();
|
||||
|
||||
/** Error handling
|
||||
o - Most functions return nonzero on success (check doc for
|
||||
precise semantics); 0 or NULL on error.
|
||||
o - Internal errors are documented by the value of bfd_error.
|
||||
If that is system_call_error then check errno.
|
||||
o - The easiest way to report this to the user is to use bfd_perror.
|
||||
*/
|
||||
|
||||
bfd_ec bfd_error = no_error;
|
||||
|
||||
CONST char *CONST bfd_errmsgs[] = {
|
||||
"No error",
|
||||
"System call error",
|
||||
"Invalid target",
|
||||
"File in wrong format",
|
||||
"Invalid operation",
|
||||
"Memory exhausted",
|
||||
"No symbols",
|
||||
"No relocation info",
|
||||
"No more archived files",
|
||||
"Malformed archive",
|
||||
"Symbol not found",
|
||||
"File format not recognized",
|
||||
"File format is ambiguous",
|
||||
"Section has no contents",
|
||||
"Nonrepresentable section on output",
|
||||
"Symbol needs debug section which does not exist",
|
||||
"Bad value",
|
||||
"File truncated",
|
||||
"#<Invalid error code>"
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
DEFUN(bfd_nonrepresentable_section,(abfd, name),
|
||||
CONST bfd * CONST abfd AND
|
||||
CONST char * CONST name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"bfd error writing file %s, format %s can't represent section %s\n",
|
||||
abfd->filename,
|
||||
abfd->xvec->name,
|
||||
name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static
|
||||
void
|
||||
DEFUN(bfd_undefined_symbol,(relent, seclet),
|
||||
CONST arelent *relent AND
|
||||
CONST struct bfd_seclet *seclet)
|
||||
{
|
||||
asymbol *symbol = *(relent->sym_ptr_ptr);
|
||||
fprintf(stderr, "bfd error relocating, symbol %s is undefined\n",
|
||||
symbol->name);
|
||||
exit(1);
|
||||
}
|
||||
/*ARGSUSED*/
|
||||
static
|
||||
void
|
||||
DEFUN(bfd_reloc_value_truncated,(relent, seclet),
|
||||
CONST arelent *relent AND
|
||||
struct bfd_seclet *seclet)
|
||||
{
|
||||
fprintf(stderr, "bfd error relocating, value truncated\n");
|
||||
exit(1);
|
||||
}
|
||||
/*ARGSUSED*/
|
||||
static
|
||||
void
|
||||
DEFUN(bfd_reloc_is_dangerous,(relent, seclet),
|
||||
CONST arelent *relent AND
|
||||
CONST struct bfd_seclet *seclet)
|
||||
{
|
||||
fprintf(stderr, "bfd error relocating, dangerous\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bfd_error_vector_type bfd_error_vector =
|
||||
{
|
||||
bfd_nonrepresentable_section ,
|
||||
bfd_undefined_symbol,
|
||||
bfd_reloc_value_truncated,
|
||||
bfd_reloc_is_dangerous,
|
||||
};
|
||||
|
||||
|
||||
CONST char *
|
||||
bfd_errmsg (error_tag)
|
||||
bfd_ec error_tag;
|
||||
{
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
if (error_tag == system_call_error)
|
||||
return strerror (errno);
|
||||
|
||||
if ((((int)error_tag <(int) no_error) ||
|
||||
((int)error_tag > (int)invalid_error_code)))
|
||||
error_tag = invalid_error_code;/* sanity check */
|
||||
|
||||
return bfd_errmsgs [(int)error_tag];
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN (bfd_default_error_trap, (error_tag),
|
||||
bfd_ec error_tag)
|
||||
{
|
||||
fprintf(stderr, "bfd assert fail (%s)\n", bfd_errmsg(error_tag));
|
||||
}
|
||||
|
||||
void (*bfd_error_trap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
|
||||
void (*bfd_error_nonrepresentabltrap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
|
||||
|
||||
void
|
||||
DEFUN(bfd_perror,(message),
|
||||
CONST char *message)
|
||||
{
|
||||
if (bfd_error == system_call_error)
|
||||
perror((char *)message); /* must be system error then... */
|
||||
else {
|
||||
if (message == NULL || *message == '\0')
|
||||
fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
|
||||
else
|
||||
fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Symbols */
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_reloc_upper_bound
|
||||
|
||||
SYNOPSIS
|
||||
unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
|
||||
|
||||
DESCRIPTION
|
||||
This function return the number of bytes required to store the
|
||||
relocation information associated with section <<sect>>
|
||||
attached to bfd <<abfd>>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
unsigned int
|
||||
DEFUN(bfd_get_reloc_upper_bound,(abfd, asect),
|
||||
bfd *abfd AND
|
||||
sec_ptr asect)
|
||||
{
|
||||
if (abfd->format != bfd_object) {
|
||||
bfd_error = invalid_operation;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_canonicalize_reloc
|
||||
|
||||
SYNOPSIS
|
||||
unsigned int bfd_canonicalize_reloc
|
||||
(bfd *abfd,
|
||||
asection *sec,
|
||||
arelent **loc,
|
||||
asymbol **syms);
|
||||
|
||||
DESCRIPTION
|
||||
This function calls the back end associated with the open
|
||||
<<abfd>> and translates the external form of the relocation
|
||||
information attached to <<sec>> into the internal canonical
|
||||
form. The table is placed into memory at <<loc>>, which has
|
||||
been preallocated, usually by a call to
|
||||
<<bfd_get_reloc_upper_bound>>.
|
||||
|
||||
The <<syms>> table is also needed for horrible internal magic
|
||||
reasons.
|
||||
|
||||
|
||||
*/
|
||||
unsigned int
|
||||
DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols),
|
||||
bfd *abfd AND
|
||||
sec_ptr asect AND
|
||||
arelent **location AND
|
||||
asymbol **symbols)
|
||||
{
|
||||
if (abfd->format != bfd_object) {
|
||||
bfd_error = invalid_operation;
|
||||
return 0;
|
||||
}
|
||||
return BFD_SEND (abfd, _bfd_canonicalize_reloc,
|
||||
(abfd, asect, location, symbols));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_file_flags
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_file_flags(bfd *abfd, flagword flags);
|
||||
|
||||
DESCRIPTION
|
||||
This function attempts to set the flag word in the referenced
|
||||
BFD structure to the value supplied.
|
||||
|
||||
Possible errors are:
|
||||
o wrong_format - The target bfd was not of object format.
|
||||
o invalid_operation - The target bfd was open for reading.
|
||||
o invalid_operation -
|
||||
The flag word contained a bit which was not applicable to the
|
||||
type of file. eg, an attempt was made to set the D_PAGED bit
|
||||
on a bfd format which does not support demand paging
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_set_file_flags (abfd, flags)
|
||||
bfd *abfd;
|
||||
flagword flags;
|
||||
{
|
||||
if (abfd->format != bfd_object) {
|
||||
bfd_error = wrong_format;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bfd_read_p (abfd)) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
bfd_get_file_flags (abfd) = flags;
|
||||
if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_reloc
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_set_reloc
|
||||
(bfd *abfd, asection *sec, arelent **rel, unsigned int count)
|
||||
|
||||
DESCRIPTION
|
||||
This function sets the relocation pointer and count within a
|
||||
section to the supplied values.
|
||||
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bfd_set_reloc (ignore_abfd, asect, location, count)
|
||||
bfd *ignore_abfd;
|
||||
sec_ptr asect;
|
||||
arelent **location;
|
||||
unsigned int count;
|
||||
{
|
||||
asect->orelocation = location;
|
||||
asect->reloc_count = count;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_assert(file, line)
|
||||
char *file;
|
||||
int line;
|
||||
{
|
||||
fprintf(stderr, "bfd assertion fail %s:%d\n",file,line);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_start_address
|
||||
|
||||
DESCRIPTION
|
||||
Marks the entry point of an output BFD.
|
||||
|
||||
RETURNS
|
||||
Returns <<true>> on success, <<false>> otherwise.
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_start_address(bfd *, bfd_vma);
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_set_start_address(abfd, vma)
|
||||
bfd *abfd;
|
||||
bfd_vma vma;
|
||||
{
|
||||
abfd->start_address = vma;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
The bfd_get_mtime function
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_mtime(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
Return file modification time (as read from file system, or
|
||||
from archive header for archive members).
|
||||
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_mtime (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if (abfd->mtime_set)
|
||||
return abfd->mtime;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), &buf))
|
||||
return 0;
|
||||
|
||||
abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
|
||||
return buf.st_mtime;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
The bfd_get_size function
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_size(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
Return file size (as read from file system) for the file
|
||||
associated with a bfd.
|
||||
|
||||
Note that the initial motivation for, and use of, this routine is not
|
||||
so we can get the exact size of the object the bfd applies to, since
|
||||
that might not be generally possible (archive members for example?).
|
||||
Although it would be ideal if someone could eventually modify
|
||||
it so that such results were guaranteed.
|
||||
|
||||
Instead, we want to ask questions like "is this NNN byte sized
|
||||
object I'm about to try read from file offset YYY reasonable?"
|
||||
As as example of where we might want to do this, some object formats
|
||||
use string tables for which the first sizeof(long) bytes of the table
|
||||
contain the size of the table itself, including the size bytes.
|
||||
If an application tries to read what it thinks is one of these
|
||||
string tables, without some way to validate the size, and for
|
||||
some reason the size is wrong (byte swapping error, wrong location
|
||||
for the string table, etc), the only clue is likely to be a read
|
||||
error when it tries to read the table, or a "virtual memory
|
||||
exhausted" error when it tries to allocated 15 bazillon bytes
|
||||
of space for the 15 bazillon byte table it is about to read.
|
||||
This function at least allows us to answer the quesion, "is the
|
||||
size reasonable?".
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_size (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), &buf))
|
||||
return 0;
|
||||
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
The bfd_get_gp_size function
|
||||
|
||||
SYNOPSIS
|
||||
int bfd_get_gp_size(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
Get the maximum size of objects to be optimized using the GP
|
||||
register under MIPS ECOFF. This is typically set by the -G
|
||||
argument to the compiler, assembler or linker.
|
||||
*/
|
||||
|
||||
int
|
||||
bfd_get_gp_size (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
|
||||
return ecoff_data (abfd)->gp_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
The bfd_set_gp_size function
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_set_gp_size(bfd *, int);
|
||||
|
||||
DESCRIPTION
|
||||
Set the maximum size of objects to be optimized using the GP
|
||||
register under ECOFF or MIPS ELF. This is typically set by
|
||||
the -G argument to the compiler, assembler or linker.
|
||||
*/
|
||||
|
||||
void
|
||||
bfd_set_gp_size (abfd, i)
|
||||
bfd *abfd;
|
||||
int i;
|
||||
{
|
||||
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
|
||||
ecoff_data (abfd)->gp_size = i;
|
||||
else if (abfd->xvec->flavour == bfd_target_elf_flavour)
|
||||
elf_gp_size (abfd) = i;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_scan_vma
|
||||
|
||||
DESCRIPTION
|
||||
Converts, like strtoul, a numerical expression as a
|
||||
string into a bfd_vma integer, and returns that integer.
|
||||
(Though without as many bells and whistles as strtoul.)
|
||||
The expression is assumed to be unsigned (i.e. positive).
|
||||
If given a base, it is used as the base for conversion.
|
||||
A base of 0 causes the function to interpret the string
|
||||
in hex if a leading "0x" or "0X" is found, otherwise
|
||||
in octal if a leading zero is found, otherwise in decimal.
|
||||
|
||||
Overflow is not detected.
|
||||
|
||||
SYNOPSIS
|
||||
bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
|
||||
*/
|
||||
|
||||
bfd_vma
|
||||
DEFUN(bfd_scan_vma,(string, end, base),
|
||||
CONST char *string AND
|
||||
CONST char **end AND
|
||||
int base)
|
||||
{
|
||||
bfd_vma value;
|
||||
int digit;
|
||||
|
||||
/* Let the host do it if possible. */
|
||||
if (sizeof(bfd_vma) <= sizeof(unsigned long))
|
||||
return (bfd_vma) strtoul (string, 0, base);
|
||||
|
||||
/* A negative base makes no sense, and we only need to go as high as hex. */
|
||||
if ((base < 0) || (base > 16))
|
||||
return (bfd_vma) 0;
|
||||
|
||||
if (base == 0)
|
||||
{
|
||||
if (string[0] == '0')
|
||||
{
|
||||
if ((string[1] == 'x') || (string[1] == 'X'))
|
||||
base = 16;
|
||||
/* XXX should we also allow "0b" or "0B" to set base to 2? */
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
if ((base == 16) &&
|
||||
(string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
|
||||
string += 2;
|
||||
/* XXX should we also skip over "0b" or "0B" if base is 2? */
|
||||
|
||||
/* Speed could be improved with a table like hex_value[] in gas. */
|
||||
#define HEX_VALUE(c) \
|
||||
(isxdigit(c) ? \
|
||||
(isdigit(c) ? \
|
||||
(c - '0') : \
|
||||
(10 + c - (islower(c) ? 'a' : 'A'))) : \
|
||||
42)
|
||||
|
||||
for (value = 0; (digit = HEX_VALUE(*string)) < base; string++)
|
||||
{
|
||||
value = value * base + digit;
|
||||
}
|
||||
|
||||
if (end)
|
||||
*end = string;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
stuff
|
||||
|
||||
DESCRIPTION
|
||||
stuff which should be documented
|
||||
|
||||
.#define bfd_sizeof_headers(abfd, reloc) \
|
||||
. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
|
||||
.
|
||||
.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
|
||||
. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line))
|
||||
.
|
||||
. {* Do these three do anything useful at all, for any back end? *}
|
||||
.#define bfd_debug_info_start(abfd) \
|
||||
. BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
|
||||
.
|
||||
.#define bfd_debug_info_end(abfd) \
|
||||
. BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
|
||||
.
|
||||
.#define bfd_debug_info_accumulate(abfd, section) \
|
||||
. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
|
||||
.
|
||||
.
|
||||
.#define bfd_stat_arch_elt(abfd, stat) \
|
||||
. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
|
||||
.
|
||||
.#define bfd_set_arch_mach(abfd, arch, mach)\
|
||||
. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
|
||||
.
|
||||
.#define bfd_get_relocated_section_contents(abfd, seclet, data, relocateable) \
|
||||
. BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data, relocateable))
|
||||
.
|
||||
.#define bfd_relax_section(abfd, section, symbols) \
|
||||
. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
|
||||
.
|
||||
.#define bfd_seclet_link(abfd, data, relocateable) \
|
||||
. BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
|
||||
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,314 @@
|
|||
/* BFD library -- caching of file descriptors.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: cache.c,v 1.1 1994/01/28 12:37:42 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
File Caching
|
||||
|
||||
The file caching mechanism is embedded within BFD and allows
|
||||
the application to open as many BFDs as it wants without
|
||||
regard to the underlying operating system's file descriptor
|
||||
limit (often as low as 20 open files). The module in
|
||||
<<cache.c>> maintains a least recently used list of
|
||||
<<BFD_CACHE_MAX_OPEN>> files, and exports the name
|
||||
<<bfd_cache_lookup>> which runs around and makes sure that
|
||||
the required BFD is open. If not, then it chooses a file to
|
||||
close, closes it and opens the one wanted, returning its file
|
||||
handle.
|
||||
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
BFD_CACHE_MAX_OPEN macro
|
||||
|
||||
DESCRIPTION
|
||||
The maximum number of files which the cache will keep open at
|
||||
one time.
|
||||
|
||||
.#define BFD_CACHE_MAX_OPEN 10
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static boolean
|
||||
bfd_cache_delete PARAMS ((bfd *));
|
||||
|
||||
/* Number of bfds on the chain. All such bfds have their file open;
|
||||
if it closed, they get snipd()d from the chain. */
|
||||
|
||||
static int open_files;
|
||||
|
||||
static bfd *cache_sentinel; /* Chain of BFDs with active fds we've
|
||||
opened */
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_last_cache
|
||||
|
||||
SYNOPSIS
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
DESCRIPTION
|
||||
Zero, or a pointer to the topmost BFD on the chain. This is
|
||||
used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
|
||||
determine when it can avoid a function call.
|
||||
*/
|
||||
|
||||
bfd *bfd_last_cache;
|
||||
|
||||
/*
|
||||
* INTERNAL_FUNCTION
|
||||
* bfd_cache_lookup
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Checks to see if the required BFD is the same as the last one
|
||||
* looked up. If so then it can use the iostream in the BFD with
|
||||
* impunity, since it can't have changed since the last lookup,
|
||||
* otherwise it has to perform the complicated lookup function
|
||||
*
|
||||
* .#define bfd_cache_lookup(x) \
|
||||
* . ((x)==bfd_last_cache? \
|
||||
* . (FILE*)(bfd_last_cache->iostream): \
|
||||
* . bfd_cache_lookup_worker(x))
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
DEFUN_VOID(close_one)
|
||||
{
|
||||
bfd *kill = cache_sentinel;
|
||||
if (kill == 0) /* Nothing in the cache */
|
||||
return ;
|
||||
|
||||
/* We can only close files that want to play this game. */
|
||||
while (!kill->cacheable) {
|
||||
kill = kill->lru_prev;
|
||||
if (kill == cache_sentinel) /* Nobody wants to play */
|
||||
return ;
|
||||
}
|
||||
|
||||
kill->where = ftell((FILE *)(kill->iostream));
|
||||
(void) bfd_cache_delete(kill);
|
||||
}
|
||||
|
||||
/* Cuts the BFD abfd out of the chain in the cache */
|
||||
static void
|
||||
DEFUN(snip,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
abfd->lru_prev->lru_next = abfd->lru_next;
|
||||
abfd->lru_next->lru_prev = abfd->lru_prev;
|
||||
if (cache_sentinel == abfd) cache_sentinel = (bfd *)NULL;
|
||||
}
|
||||
|
||||
static boolean
|
||||
DEFUN(bfd_cache_delete,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
boolean ret;
|
||||
|
||||
if (fclose ((FILE *)(abfd->iostream)) == 0)
|
||||
ret = true;
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
bfd_error = system_call_error;
|
||||
}
|
||||
snip (abfd);
|
||||
abfd->iostream = NULL;
|
||||
open_files--;
|
||||
bfd_last_cache = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bfd *
|
||||
DEFUN(insert,(x,y),
|
||||
bfd *x AND
|
||||
bfd *y)
|
||||
{
|
||||
if (y) {
|
||||
x->lru_next = y;
|
||||
x->lru_prev = y->lru_prev;
|
||||
y->lru_prev->lru_next = x;
|
||||
y->lru_prev = x;
|
||||
|
||||
}
|
||||
else {
|
||||
x->lru_prev = x;
|
||||
x->lru_next = x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a BFD by putting it on the cache LRU. */
|
||||
|
||||
void
|
||||
DEFUN(bfd_cache_init,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
if (open_files >= BFD_CACHE_MAX_OPEN)
|
||||
close_one ();
|
||||
cache_sentinel = insert(abfd, cache_sentinel);
|
||||
++open_files;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_cache_close
|
||||
|
||||
DESCRIPTION
|
||||
Remove the BFD from the cache. If the attached file is open,
|
||||
then close it too.
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_cache_close (bfd *);
|
||||
|
||||
RETURNS
|
||||
<<false>> is returned if closing the file fails, <<true>> is
|
||||
returned if all is well.
|
||||
*/
|
||||
boolean
|
||||
DEFUN(bfd_cache_close,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
/* If this file is open then remove from the chain */
|
||||
if (abfd->iostream)
|
||||
{
|
||||
return bfd_cache_delete(abfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_open_file
|
||||
|
||||
DESCRIPTION
|
||||
Call the OS to open a file for this BFD. Returns the FILE *
|
||||
(possibly null) that results from this operation. Sets up the
|
||||
BFD so that future accesses know the file is open. If the FILE
|
||||
* returned is null, then there is won't have been put in the
|
||||
cache, so it won't have to be removed from it.
|
||||
|
||||
SYNOPSIS
|
||||
FILE* bfd_open_file(bfd *);
|
||||
*/
|
||||
|
||||
FILE *
|
||||
DEFUN(bfd_open_file, (abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
abfd->cacheable = true; /* Allow it to be closed later. */
|
||||
|
||||
if(open_files >= BFD_CACHE_MAX_OPEN) {
|
||||
close_one();
|
||||
}
|
||||
|
||||
switch (abfd->direction) {
|
||||
case read_direction:
|
||||
case no_direction:
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RB);
|
||||
break;
|
||||
case both_direction:
|
||||
case write_direction:
|
||||
if (abfd->opened_once == true) {
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RUB);
|
||||
if (!abfd->iostream) {
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WUB);
|
||||
}
|
||||
} else {
|
||||
/*open for creat */
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WB);
|
||||
abfd->opened_once = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (abfd->iostream) {
|
||||
bfd_cache_init (abfd);
|
||||
}
|
||||
|
||||
return (FILE *)(abfd->iostream);
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_cache_lookup_worker
|
||||
|
||||
DESCRIPTION
|
||||
Called when the macro <<bfd_cache_lookup>> fails to find a
|
||||
quick answer. Finds a file descriptor for this BFD. If
|
||||
necessary, it open it. If there are already more than
|
||||
BFD_CACHE_MAX_OPEN files open, it trys to close one first, to
|
||||
avoid running out of file descriptors.
|
||||
|
||||
SYNOPSIS
|
||||
FILE *bfd_cache_lookup_worker(bfd *);
|
||||
|
||||
*/
|
||||
|
||||
FILE *
|
||||
DEFUN(bfd_cache_lookup_worker,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
if (abfd->my_archive)
|
||||
{
|
||||
abfd = abfd->my_archive;
|
||||
}
|
||||
/* Is this file already open .. if so then quick exit */
|
||||
if (abfd->iostream)
|
||||
{
|
||||
if (abfd != cache_sentinel) {
|
||||
/* Place onto head of lru chain */
|
||||
snip (abfd);
|
||||
cache_sentinel = insert(abfd, cache_sentinel);
|
||||
}
|
||||
}
|
||||
/* This is a BFD without a stream -
|
||||
so it must have been closed or never opened.
|
||||
find an empty cache entry and use it. */
|
||||
else
|
||||
{
|
||||
|
||||
if (open_files >= BFD_CACHE_MAX_OPEN)
|
||||
{
|
||||
close_one();
|
||||
}
|
||||
|
||||
BFD_ASSERT(bfd_open_file (abfd) != (FILE *)NULL) ;
|
||||
fseek((FILE *)(abfd->iostream), abfd->where, false);
|
||||
}
|
||||
bfd_last_cache = abfd;
|
||||
return (FILE *)(abfd->iostream);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,109 @@
|
|||
/* Core file generic interface routines for BFD.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: core.c,v 1.1 1994/01/28 12:37:47 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Core files
|
||||
|
||||
DESCRIPTION
|
||||
Buff output this facinating topic
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_core_file_failing_command
|
||||
|
||||
SYNOPSIS
|
||||
CONST char *bfd_core_file_failing_command(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
Returns a read-only string explaining what program was running
|
||||
when it failed and produced the core file being read
|
||||
|
||||
*/
|
||||
|
||||
CONST char *
|
||||
DEFUN(bfd_core_file_failing_command,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
if (abfd->format != bfd_core) {
|
||||
bfd_error = invalid_operation;
|
||||
return NULL;
|
||||
}
|
||||
return BFD_SEND (abfd, _core_file_failing_command, (abfd));
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_core_file_failing_signal
|
||||
|
||||
SYNOPSIS
|
||||
int bfd_core_file_failing_signal(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
Returns the signal number which caused the core dump which
|
||||
generated the file the BFD is attached to.
|
||||
*/
|
||||
|
||||
int
|
||||
bfd_core_file_failing_signal (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if (abfd->format != bfd_core) {
|
||||
bfd_error = invalid_operation;
|
||||
return 0;
|
||||
}
|
||||
return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
core_file_matches_executable_p
|
||||
|
||||
SYNOPSIS
|
||||
boolean core_file_matches_executable_p
|
||||
(bfd *core_bfd, bfd *exec_bfd);
|
||||
|
||||
DESCRIPTION
|
||||
Returns <<true>> if the core file attached to @var{core_bfd}
|
||||
was generated by a run of the executable file attached to
|
||||
@var{exec_bfd}, or else <<false>>.
|
||||
*/
|
||||
boolean
|
||||
core_file_matches_executable_p (core_bfd, exec_bfd)
|
||||
bfd *core_bfd, *exec_bfd;
|
||||
{
|
||||
if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
|
||||
bfd_error = wrong_format;
|
||||
return false;
|
||||
}
|
||||
|
||||
return BFD_SEND (core_bfd, _core_file_matches_executable_p,
|
||||
(core_bfd, exec_bfd));
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/* BFD library support routines for constructors
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
|
||||
Hacked by Steve Chamberlain of Cygnus Support. With some help from
|
||||
Judy Chamberlain too.
|
||||
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: ctor.c,v 1.1 1994/01/28 12:37:49 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Constructors
|
||||
|
||||
Classes in C++ have `constructors' and `destructors'. These
|
||||
are functions which are called automatically by the language
|
||||
whenever data of a class is created or destroyed. Class data
|
||||
which is static data may also be have a type which requires
|
||||
`construction', the contructor must be called before the data
|
||||
can be referenced, so the contructor must be called before the
|
||||
program begins.
|
||||
|
||||
The common solution to this problem is for the compiler to
|
||||
call a magic function as the first statement <<main>>.
|
||||
This magic function, (often called <<__main>>) runs around
|
||||
calling the constructors for all the things needing it.
|
||||
|
||||
With COFF the compile has a bargain with the linker et al.
|
||||
All constructors are given strange names, for example
|
||||
<<__GLOBAL__$I$foo>> might be the label of a contructor for
|
||||
the class @var{foo}. The solution on unfortunate systems
|
||||
(most system V machines) is to perform a partial link on all
|
||||
the <<.o>> files, do an <<nm>> on the result, run <<awk>> or some
|
||||
such over the result looking for strange <<__GLOBAL__$>>
|
||||
symbols, generate a C program from this, compile it and link
|
||||
with the partially linked input. This process is usually
|
||||
called <<collect>>.
|
||||
|
||||
Some versions of <<a.out>> use something called the
|
||||
<<set_vector>> mechanism. The constructor symbols are output
|
||||
from the compiler with a special stab code saying that they
|
||||
are constructors, and the linker can deal with them directly.
|
||||
|
||||
BFD allows applications (ie the linker) to deal with
|
||||
constructor information independently of their external
|
||||
implimentation by providing a set of entry points for the
|
||||
indiviual object back ends to call which maintains a database
|
||||
of the contructor information. The application can
|
||||
interrogate the database to find out what it wants. The
|
||||
construction data essential for the linker to be able to
|
||||
perform its job are:
|
||||
|
||||
o asymbol -
|
||||
The asymbol of the contructor entry point contains all the
|
||||
information necessary to call the function.
|
||||
|
||||
o table id -
|
||||
The type of symbol, i.e., is it a constructor, a destructor or
|
||||
something else someone dreamed up to make our lives difficult.
|
||||
|
||||
This module takes this information and then builds extra
|
||||
sections attached to the bfds which own the entry points. It
|
||||
creates these sections as if they were tables of pointers to
|
||||
the entry points, and builds relocation entries to go with
|
||||
them so that the tables can be relocated along with the data
|
||||
they reference.
|
||||
|
||||
These sections are marked with a special bit
|
||||
(<<SEC_CONSTRUCTOR>>) which the linker notices and do with
|
||||
what it wants.
|
||||
|
||||
*/
|
||||
|
||||
#include <bfd.h>
|
||||
#include <sysdep.h>
|
||||
#include <libbfd.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_constructor_entry
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_constructor_entry(bfd *abfd,
|
||||
asymbol **symbol_ptr_ptr,
|
||||
CONST char*type);
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
This function is called with an a symbol describing the
|
||||
function to be called, an string which descibes the xtor type,
|
||||
e.g., something like "CTOR" or "DTOR" would be fine. And the bfd
|
||||
which owns the function. Its duty is to create a section
|
||||
called "CTOR" or "DTOR" or whatever if the bfd doesn't already
|
||||
have one, and grow a relocation table for the entry points as
|
||||
they accumulate.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
|
||||
bfd *abfd AND
|
||||
asymbol **symbol_ptr_ptr AND
|
||||
CONST char *type)
|
||||
|
||||
{
|
||||
/* Look up the section we're using to store the table in */
|
||||
asection *rel_section = bfd_get_section_by_name (abfd, type);
|
||||
if (rel_section == (asection *)NULL) {
|
||||
rel_section = bfd_make_section (abfd, type);
|
||||
rel_section->flags = SEC_CONSTRUCTOR;
|
||||
rel_section->alignment_power = 2;
|
||||
}
|
||||
|
||||
/* Create a relocation into the section which references the entry
|
||||
point */
|
||||
{
|
||||
arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd,
|
||||
sizeof(arelent_chain));
|
||||
|
||||
/* reloc->relent.section = (asection *)NULL;*/
|
||||
reloc->relent.addend = 0;
|
||||
|
||||
reloc->relent.sym_ptr_ptr = symbol_ptr_ptr;
|
||||
reloc->next = rel_section->constructor_chain;
|
||||
rel_section->constructor_chain = reloc;
|
||||
reloc->relent.address = rel_section->_cooked_size;
|
||||
/* ask the cpu which howto to use */
|
||||
reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR);
|
||||
rel_section->_cooked_size += sizeof(int *);
|
||||
rel_section->reloc_count++;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,251 @@
|
|||
/* ELF executable support for BFD.
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: elf.c,v 1.1 1994/01/28 12:37:52 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
SECTION
|
||||
ELF backends
|
||||
|
||||
BFD support for ELF formats is being worked on.
|
||||
Currently, the best supported back ends are for sparc and i386
|
||||
(running svr4 or Solaris 2).
|
||||
|
||||
Documentation of the internals of the support code still needs
|
||||
to be written. The code is changing quickly enough that we
|
||||
haven't bothered yet.
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#define ARCH_SIZE 0
|
||||
#include "libelf.h"
|
||||
|
||||
/* Standard ELF hash function. Do not change this function; you will
|
||||
cause invalid hash tables to be generated. (Well, you would if this
|
||||
were being used yet.) */
|
||||
unsigned long
|
||||
DEFUN (bfd_elf_hash, (name),
|
||||
CONST unsigned char *name)
|
||||
{
|
||||
unsigned long h = 0;
|
||||
unsigned long g;
|
||||
int ch;
|
||||
|
||||
while ((ch = *name++) != '\0')
|
||||
{
|
||||
h = (h << 4) + ch;
|
||||
if ((g = (h & 0xf0000000)) != 0)
|
||||
{
|
||||
h ^= g >> 24;
|
||||
h &= ~g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Read a specified number of bytes at a specified offset in an ELF
|
||||
file, into a newly allocated buffer, and return a pointer to the
|
||||
buffer. */
|
||||
|
||||
static char *
|
||||
DEFUN (elf_read, (abfd, offset, size),
|
||||
bfd * abfd AND
|
||||
long offset AND
|
||||
int size)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
if ((buf = bfd_alloc (abfd, size)) == NULL)
|
||||
{
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
if (bfd_seek (abfd, offset, SEEK_SET) == -1)
|
||||
{
|
||||
bfd_error = system_call_error;
|
||||
return NULL;
|
||||
}
|
||||
if (bfd_read ((PTR) buf, size, 1, abfd) != size)
|
||||
{
|
||||
bfd_error = system_call_error;
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
boolean
|
||||
DEFUN (elf_mkobject, (abfd), bfd * abfd)
|
||||
{
|
||||
/* this just does initialization */
|
||||
/* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
|
||||
elf_tdata (abfd) = (struct elf_obj_tdata *)
|
||||
bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
|
||||
if (elf_tdata (abfd) == 0)
|
||||
{
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
/* since everything is done at close time, do we need any
|
||||
initialization? */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
DEFUN (elf_get_str_section, (abfd, shindex),
|
||||
bfd * abfd AND
|
||||
unsigned int shindex)
|
||||
{
|
||||
Elf_Internal_Shdr **i_shdrp;
|
||||
char *shstrtab = NULL;
|
||||
unsigned int offset;
|
||||
unsigned int shstrtabsize;
|
||||
|
||||
i_shdrp = elf_elfsections (abfd);
|
||||
if (i_shdrp == 0 || i_shdrp[shindex] == 0)
|
||||
return 0;
|
||||
|
||||
shstrtab = i_shdrp[shindex]->rawdata;
|
||||
if (shstrtab == NULL)
|
||||
{
|
||||
/* No cached one, attempt to read, and cache what we read. */
|
||||
offset = i_shdrp[shindex]->sh_offset;
|
||||
shstrtabsize = i_shdrp[shindex]->sh_size;
|
||||
shstrtab = elf_read (abfd, offset, shstrtabsize);
|
||||
i_shdrp[shindex]->rawdata = (void *) shstrtab;
|
||||
}
|
||||
return shstrtab;
|
||||
}
|
||||
|
||||
char *
|
||||
DEFUN (elf_string_from_elf_section, (abfd, shindex, strindex),
|
||||
bfd * abfd AND
|
||||
unsigned int shindex AND
|
||||
unsigned int strindex)
|
||||
{
|
||||
Elf_Internal_Shdr *hdr;
|
||||
|
||||
if (strindex == 0)
|
||||
return "";
|
||||
|
||||
hdr = elf_elfsections (abfd)[shindex];
|
||||
|
||||
if (!hdr->rawdata
|
||||
&& elf_get_str_section (abfd, shindex) == NULL)
|
||||
return NULL;
|
||||
|
||||
return ((char *) hdr->rawdata) + strindex;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_elf_find_section
|
||||
|
||||
SYNOPSIS
|
||||
struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
|
||||
|
||||
DESCRIPTION
|
||||
Helper functions for GDB to locate the string tables.
|
||||
Since BFD hides string tables from callers, GDB needs to use an
|
||||
internal hook to find them. Sun's .stabstr, in particular,
|
||||
isn't even pointed to by the .stab section, so ordinary
|
||||
mechanisms wouldn't work to find it, even if we had some.
|
||||
*/
|
||||
|
||||
struct elf_internal_shdr *
|
||||
DEFUN (bfd_elf_find_section, (abfd, name),
|
||||
bfd * abfd AND
|
||||
char *name)
|
||||
{
|
||||
Elf_Internal_Shdr **i_shdrp;
|
||||
char *shstrtab;
|
||||
unsigned int max;
|
||||
unsigned int i;
|
||||
|
||||
i_shdrp = elf_elfsections (abfd);
|
||||
if (i_shdrp != NULL)
|
||||
{
|
||||
shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx);
|
||||
if (shstrtab != NULL)
|
||||
{
|
||||
max = elf_elfheader (abfd)->e_shnum;
|
||||
for (i = 1; i < max; i++)
|
||||
if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
|
||||
return i_shdrp[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct bfd_elf_arch_map bfd_elf_arch_map[] = {
|
||||
{ bfd_arch_sparc, EM_SPARC },
|
||||
{ bfd_arch_i386, EM_386 },
|
||||
{ bfd_arch_m68k, EM_68K },
|
||||
{ bfd_arch_m88k, EM_88K },
|
||||
{ bfd_arch_i860, EM_860 },
|
||||
{ bfd_arch_mips, EM_MIPS },
|
||||
{ bfd_arch_hppa, EM_HPPA },
|
||||
};
|
||||
|
||||
const int bfd_elf_arch_map_size = sizeof (bfd_elf_arch_map) / sizeof (bfd_elf_arch_map[0]);
|
||||
|
||||
const char *const bfd_elf_section_type_names[] = {
|
||||
"SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
|
||||
"SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
|
||||
"SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
|
||||
};
|
||||
|
||||
/* ELF relocs are against symbols. If we are producing relocateable
|
||||
output, and the reloc is against an external symbol, and nothing
|
||||
has given us any additional addend, the resulting reloc will also
|
||||
be against the same symbol. In such a case, we don't want to
|
||||
change anything about the way the reloc is handled, since it will
|
||||
all be done at final link time. Rather than put special case code
|
||||
into bfd_perform_relocation, all the reloc types use this howto
|
||||
function. It just short circuits the reloc if producing
|
||||
relocateable output against an external symbol. */
|
||||
|
||||
bfd_reloc_status_type
|
||||
bfd_elf_generic_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
{
|
||||
if (output_bfd != (bfd *) NULL
|
||||
&& (symbol->flags & BSF_SECTION_SYM) == 0
|
||||
&& reloc_entry->addend == 0)
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
return bfd_reloc_continue;
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
/* Generic BFD support for file formats.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: format.c,v 1.1 1994/01/28 12:37:53 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
File Formats
|
||||
|
||||
A format is a BFD concept of high level file contents. The
|
||||
formats supported by BFD are:
|
||||
|
||||
o bfd_object
|
||||
|
||||
The BFD may contain data, symbols, relocations and debug info.
|
||||
|
||||
o bfd_archive
|
||||
|
||||
The BFD contains other BFDs and an optional index.
|
||||
|
||||
o bfd_core
|
||||
|
||||
The BFD contains the result of an executable core dump.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
extern bfd_target *target_vector[];
|
||||
extern bfd_target *default_vector[];
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_check_format
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_check_format(bfd *abfd, bfd_format format);
|
||||
|
||||
DESCRIPTION
|
||||
This routine is supplied a BFD and a format. It attempts to
|
||||
verify if the file attached to the BFD is indeed compatible
|
||||
with the format specified (ie, one of <<bfd_object>>,
|
||||
<<bfd_archive>> or <<bfd_core>>).
|
||||
|
||||
If the BFD has been set to a specific @var{target} before the
|
||||
call, only the named target and format combination will be
|
||||
checked. If the target has not been set, or has been set to
|
||||
<<default>> then all the known target backends will be
|
||||
interrogated to determine a match. If the default target
|
||||
matches, it is used. If not, exactly one target must recognize
|
||||
the file, or an error results.
|
||||
|
||||
The function returns <<true>> on success, otherwise <<false>>
|
||||
with one of the following error codes:
|
||||
|
||||
o invalid_operation -
|
||||
if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
|
||||
<<bfd_core>>.
|
||||
|
||||
o system_call_error -
|
||||
if an error occured during a read - even some file mismatches
|
||||
can cause system_call_errors
|
||||
|
||||
o file_not_recognised -
|
||||
none of the backends recognised the file format
|
||||
|
||||
o file_ambiguously_recognized -
|
||||
more than one backend recognised the file format.
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_check_format,(abfd, format),
|
||||
bfd *abfd AND
|
||||
bfd_format format)
|
||||
{
|
||||
bfd_target **target, *save_targ, *right_targ;
|
||||
int match_count;
|
||||
|
||||
if (!bfd_read_p (abfd) ||
|
||||
((int)(abfd->format) < (int)bfd_unknown) ||
|
||||
((int)(abfd->format) >= (int)bfd_type_end)) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (abfd->format != bfd_unknown)
|
||||
return (abfd->format == format)? true: false;
|
||||
|
||||
|
||||
/* Since the target type was defaulted, check them
|
||||
all in the hope that one will be uniquely recognized. */
|
||||
|
||||
save_targ = abfd->xvec;
|
||||
match_count = 0;
|
||||
right_targ = 0;
|
||||
|
||||
|
||||
/* presume the answer is yes */
|
||||
abfd->format = format;
|
||||
|
||||
/* If the target type was explicitly specified, just check that target. */
|
||||
|
||||
if (!abfd->target_defaulted) {
|
||||
bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */
|
||||
|
||||
right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
|
||||
if (right_targ) {
|
||||
abfd->xvec = right_targ; /* Set the target as returned */
|
||||
return true; /* File position has moved, BTW */
|
||||
}
|
||||
}
|
||||
|
||||
for (target = target_vector; *target != NULL; target++) {
|
||||
bfd_target *temp;
|
||||
|
||||
abfd->xvec = *target; /* Change BFD's target temporarily */
|
||||
bfd_seek (abfd, (file_ptr)0, SEEK_SET);
|
||||
/* If _bfd_check_format neglects to set bfd_error, assume wrong_format.
|
||||
We didn't used to even pay any attention to bfd_error, so I suspect
|
||||
that some _bfd_check_format might have this problem. */
|
||||
bfd_error = wrong_format;
|
||||
temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
|
||||
if (temp) { /* This format checks out as ok! */
|
||||
right_targ = temp;
|
||||
match_count++;
|
||||
/* If this is the default target, accept it, even if other targets
|
||||
might match. People who want those other targets have to set
|
||||
the GNUTARGET variable. */
|
||||
if (temp == default_vector[0])
|
||||
{
|
||||
match_count = 1;
|
||||
break;
|
||||
}
|
||||
#ifdef GNU960
|
||||
/* Big- and little-endian b.out archives look the same, but it doesn't
|
||||
* matter: there is no difference in their headers, and member file byte
|
||||
* orders will (I hope) be handled appropriately by bfd. Ditto for big
|
||||
* and little coff archives. And the 4 coff/b.out object formats are
|
||||
* unambiguous. So accept the first match we find.
|
||||
*/
|
||||
break;
|
||||
#endif
|
||||
} else if (bfd_error != wrong_format) {
|
||||
abfd->xvec = save_targ;
|
||||
abfd->format = bfd_unknown;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_count == 1) {
|
||||
abfd->xvec = right_targ; /* Change BFD's target permanently */
|
||||
return true; /* File position has moved, BTW */
|
||||
}
|
||||
|
||||
abfd->xvec = save_targ; /* Restore original target type */
|
||||
abfd->format = bfd_unknown; /* Restore original format */
|
||||
bfd_error = ((match_count == 0) ? file_not_recognized :
|
||||
file_ambiguously_recognized);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_format
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_format(bfd *, bfd_format);
|
||||
|
||||
DESCRIPTION
|
||||
This function sets the file format of the supplied BFD to the
|
||||
format requested. If the target set in the BFD does not
|
||||
support the format requested, the format is illegal or the BFD
|
||||
is not open for writing than an error occurs.
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_set_format,(abfd, format),
|
||||
bfd *abfd AND
|
||||
bfd_format format)
|
||||
{
|
||||
|
||||
if (bfd_read_p (abfd) ||
|
||||
((int)abfd->format < (int)bfd_unknown) ||
|
||||
((int)abfd->format >= (int)bfd_type_end)) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (abfd->format != bfd_unknown)
|
||||
return (abfd->format == format) ? true:false;
|
||||
|
||||
/* presume the answer is yes */
|
||||
abfd->format = format;
|
||||
|
||||
if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
|
||||
abfd->format = bfd_unknown;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_format_string
|
||||
|
||||
SYNOPSIS
|
||||
CONST char *bfd_format_string(bfd_format);
|
||||
|
||||
DESCRIPTION
|
||||
This function takes one argument, and enumerated type
|
||||
(bfd_format) and returns a pointer to a const string
|
||||
<<invalid>>, <<object>>, <<archive>>, <<core>> or <<unknown>>
|
||||
depending upon the value of the enumeration.
|
||||
*/
|
||||
|
||||
CONST char *
|
||||
DEFUN(bfd_format_string,(format),
|
||||
bfd_format format)
|
||||
{
|
||||
if (((int)format <(int) bfd_unknown)
|
||||
|| ((int)format >=(int) bfd_type_end))
|
||||
return "invalid";
|
||||
|
||||
switch (format) {
|
||||
case bfd_object:
|
||||
return "object"; /* linker/assember/compiler output */
|
||||
case bfd_archive:
|
||||
return "archive"; /* object archive file */
|
||||
case bfd_core:
|
||||
return "core"; /* core dump */
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/* bfd initialization stuff
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain of Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: init.c,v 1.1 1994/01/28 12:37:54 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
extern void DEFUN_VOID (bfd_section_init);
|
||||
|
||||
static boolean initialized = false;
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Initialization
|
||||
|
||||
This is the initialization section
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_init
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_init(void);
|
||||
|
||||
DESCRIPTION
|
||||
This routine must be called before any other bfd function to
|
||||
initialize magical internal data structures.
|
||||
*/
|
||||
|
||||
void DEFUN_VOID(bfd_init)
|
||||
{
|
||||
if (initialized == false) {
|
||||
initialized = true;
|
||||
|
||||
bfd_arch_init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_check_init
|
||||
|
||||
DESCRIPTION
|
||||
This routine is called before any other bfd function using
|
||||
initialized data is used to ensure that the structures have
|
||||
been initialized. Soon this function will go away, and the bfd
|
||||
library will assume that bfd_init has been called.
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_check_init(void);
|
||||
*/
|
||||
|
||||
void DEFUN_VOID(bfd_check_init)
|
||||
{
|
||||
if (initialized == false) {
|
||||
bfd_init();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/* BFD back-end data structures for a.out (and similar) files.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libaout.h,v 1.1 1994/01/28 12:37:55 pk Exp $
|
||||
*/
|
||||
|
||||
/* We try to encapsulate the differences in the various a.out file
|
||||
variants in a few routines, and otherwise share large masses of code.
|
||||
This means we only have to fix bugs in one place, most of the time. */
|
||||
|
||||
/* Parameterize the a.out code based on whether it is being built
|
||||
for a 32-bit architecture or a 64-bit architecture. */
|
||||
#if ARCH_SIZE==64
|
||||
#define GET_WORD bfd_h_get_64
|
||||
#define GET_SWORD bfd_h_get_signed_64
|
||||
#define PUT_WORD bfd_h_put_64
|
||||
#ifndef NAME
|
||||
#define NAME(x,y) CAT3(x,_64_,y)
|
||||
#endif
|
||||
#define JNAME(x) CAT(x,_64)
|
||||
#define BYTES_IN_WORD 8
|
||||
#else /* ARCH_SIZE == 32 */
|
||||
#define GET_WORD bfd_h_get_32
|
||||
#define GET_SWORD bfd_h_get_signed_32
|
||||
#define PUT_WORD bfd_h_put_32
|
||||
#ifndef NAME
|
||||
#define NAME(x,y) CAT3(x,_32_,y)
|
||||
#endif
|
||||
#define JNAME(x) CAT(x,_32)
|
||||
#define BYTES_IN_WORD 4
|
||||
#endif /* ARCH_SIZE==32 */
|
||||
|
||||
/* Declare these types at file level, since they are used in parameter
|
||||
lists, which have wierd scope. */
|
||||
struct external_exec;
|
||||
struct internal_exec;
|
||||
|
||||
/* Back-end information for various a.out targets. */
|
||||
struct aout_backend_data
|
||||
{
|
||||
/* Are ZMAGIC files mapped contiguously? If so, the text section may
|
||||
need more padding, if the segment size (granularity for memory access
|
||||
control) is larger than the page size. */
|
||||
unsigned char zmagic_mapped_contiguous;
|
||||
/* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the
|
||||
text section, which starts immediately after the file header.
|
||||
If not, the text section starts on the next page. */
|
||||
unsigned char text_includes_header;
|
||||
|
||||
/* If the text section VMA isn't specified, and we need an absolute
|
||||
address, use this as the default. If we're producing a relocatable
|
||||
file, zero is always used. */
|
||||
/* ?? Perhaps a callback would be a better choice? Will this do anything
|
||||
reasonable for a format that handles multiple CPUs with different
|
||||
load addresses for each? */
|
||||
bfd_vma default_text_vma;
|
||||
|
||||
/* Callback for setting the page and segment sizes, if they can't be
|
||||
trivially determined from the architecture. */
|
||||
boolean (*set_sizes) PARAMS ((bfd *));
|
||||
|
||||
/* zmagic files only. For go32, the length of the exec header contributes
|
||||
to the size of the text section in the file for alignment purposes but
|
||||
does *not* get counted in the length of the text section. */
|
||||
unsigned char exec_header_not_counted;
|
||||
};
|
||||
#define aout_backend_info(abfd) \
|
||||
((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
|
||||
|
||||
/* This is the layout in memory of a "struct exec" while we process it.
|
||||
All 'lengths' are given as a number of bytes.
|
||||
All 'alignments' are for relinkable files only; an alignment of
|
||||
'n' indicates the corresponding segment must begin at an
|
||||
address that is a multiple of (2**n). */
|
||||
|
||||
struct internal_exec
|
||||
{
|
||||
long a_info; /* Magic number and flags, packed */
|
||||
bfd_vma a_text; /* length of text, in bytes */
|
||||
bfd_vma a_data; /* length of data, in bytes */
|
||||
bfd_vma a_bss; /* length of uninitialized data area in mem */
|
||||
bfd_vma a_syms; /* length of symbol table data in file */
|
||||
bfd_vma a_entry; /* start address */
|
||||
bfd_vma a_trsize; /* length of text's relocation info, in bytes */
|
||||
bfd_vma a_drsize; /* length of data's relocation info, in bytes */
|
||||
/* Added for i960 */
|
||||
bfd_vma a_tload; /* Text runtime load address */
|
||||
bfd_vma a_dload; /* Data runtime load address */
|
||||
unsigned char a_talign; /* Alignment of text segment */
|
||||
unsigned char a_dalign; /* Alignment of data segment */
|
||||
unsigned char a_balign; /* Alignment of bss segment */
|
||||
char a_relaxable; /* Enough info for linker relax */
|
||||
};
|
||||
|
||||
/* Magic number is written
|
||||
< MSB >
|
||||
3130292827262524232221201918171615141312111009080706050403020100
|
||||
< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
|
||||
*/
|
||||
/* Magic number for NetBSD is
|
||||
<MSB >
|
||||
3130292827262524232221201918171615141312111009080706050403020100
|
||||
< FLAGS >< >< MAGIC NUMBER >
|
||||
*/
|
||||
|
||||
enum machine_type {
|
||||
M_UNKNOWN = 0,
|
||||
M_68010 = 1,
|
||||
M_68020 = 2,
|
||||
M_SPARC = 3,
|
||||
/* skip a bunch so we don't run into any of suns numbers */
|
||||
M_386 = 100,
|
||||
M_29K = 101, /* AMD 29000 */
|
||||
M_386_DYNIX = 102, /* Sequent running dynix */
|
||||
M_386_NETBSD = 134, /* NetBSD/386 binary */
|
||||
M_M68K_NETBSD = 135, /* NetBSD/m68k binary */
|
||||
M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
|
||||
M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
|
||||
M_HP200 = 200, /* HP 200 (68010) BSD binary */
|
||||
M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
|
||||
M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */
|
||||
};
|
||||
|
||||
#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
|
||||
|
||||
#ifndef N_MAGIC
|
||||
# define N_MAGIC(exec) ((exec).a_info & 0xffff)
|
||||
#endif
|
||||
|
||||
#ifndef N_MACHTYPE
|
||||
# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
|
||||
#endif
|
||||
|
||||
#ifndef N_FLAGS
|
||||
# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
|
||||
#endif
|
||||
|
||||
#ifndef N_SET_INFO
|
||||
# define N_SET_INFO(exec, magic, type, flags) \
|
||||
((exec).a_info = ((magic) & 0xffff) \
|
||||
| (((int)(type) & 0xff) << 16) \
|
||||
| (((flags) & 0xff) << 24))
|
||||
#endif
|
||||
|
||||
#ifndef N_SET_MAGIC
|
||||
# define N_SET_MAGIC(exec, magic) \
|
||||
((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
|
||||
#endif
|
||||
|
||||
#ifndef N_SET_MACHTYPE
|
||||
# define N_SET_MACHTYPE(exec, machtype) \
|
||||
((exec).a_info = \
|
||||
((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
|
||||
#endif
|
||||
|
||||
#ifndef N_SET_FLAGS
|
||||
# define N_SET_FLAGS(exec, flags) \
|
||||
((exec).a_info = \
|
||||
((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
|
||||
#endif
|
||||
|
||||
typedef struct aout_symbol {
|
||||
asymbol symbol;
|
||||
short desc;
|
||||
char other;
|
||||
unsigned char type;
|
||||
} aout_symbol_type;
|
||||
|
||||
/* The `tdata' struct for all a.out-like object file formats.
|
||||
Various things depend on this struct being around any time an a.out
|
||||
file is being handled. An example is dbxread.c in GDB. */
|
||||
|
||||
struct aoutdata {
|
||||
struct internal_exec *hdr; /* exec file header */
|
||||
aout_symbol_type *symbols; /* symtab for input bfd */
|
||||
|
||||
/* For ease, we do this */
|
||||
asection *textsec;
|
||||
asection *datasec;
|
||||
asection *bsssec;
|
||||
|
||||
/* We remember these offsets so that after check_file_format, we have
|
||||
no dependencies on the particular format of the exec_hdr. */
|
||||
file_ptr sym_filepos;
|
||||
file_ptr str_filepos;
|
||||
|
||||
/* Size of a relocation entry in external form */
|
||||
unsigned reloc_entry_size;
|
||||
|
||||
/* Size of a symbol table entry in external form */
|
||||
unsigned symbol_entry_size;
|
||||
|
||||
/* Page size - needed for alignment of demand paged files. */
|
||||
unsigned long page_size;
|
||||
|
||||
/* Segment size - needed for alignment of demand paged files. */
|
||||
unsigned long segment_size;
|
||||
|
||||
unsigned exec_bytes_size;
|
||||
unsigned vma_adjusted : 1;
|
||||
|
||||
/* used when a bfd supports several highly similar formats */
|
||||
enum {
|
||||
default_format = 0,
|
||||
gnu_encap_format } subformat;
|
||||
|
||||
enum {
|
||||
undecided_magic = 0,
|
||||
z_magic,
|
||||
o_magic,
|
||||
n_magic } magic;
|
||||
};
|
||||
|
||||
struct aout_data_struct {
|
||||
struct aoutdata a;
|
||||
struct internal_exec e;
|
||||
};
|
||||
|
||||
#define adata(bfd) ((bfd)->tdata.aout_data->a)
|
||||
#define exec_hdr(bfd) (adata(bfd).hdr)
|
||||
#define obj_aout_symbols(bfd) (adata(bfd).symbols)
|
||||
#define obj_textsec(bfd) (adata(bfd).textsec)
|
||||
#define obj_datasec(bfd) (adata(bfd).datasec)
|
||||
#define obj_bsssec(bfd) (adata(bfd).bsssec)
|
||||
#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos)
|
||||
#define obj_str_filepos(bfd) (adata(bfd).str_filepos)
|
||||
#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
|
||||
#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
|
||||
#define obj_aout_subformat(bfd) (adata(bfd).subformat)
|
||||
|
||||
/* We take the address of the first element of an asymbol to ensure that the
|
||||
macro is only ever applied to an asymbol */
|
||||
#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd))
|
||||
|
||||
/* Prototype declarations for functions defined in aoutx.h */
|
||||
|
||||
boolean
|
||||
NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section));
|
||||
|
||||
bfd_target *
|
||||
NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd,
|
||||
struct internal_exec *execp,
|
||||
bfd_target * (*callback)(bfd *)));
|
||||
|
||||
boolean
|
||||
NAME(aout,mkobject) PARAMS ((bfd *abfd));
|
||||
|
||||
enum machine_type
|
||||
NAME(aout,machine_type) PARAMS ((enum bfd_architecture arch,
|
||||
unsigned long machine));
|
||||
|
||||
boolean
|
||||
NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch,
|
||||
unsigned long machine));
|
||||
|
||||
boolean
|
||||
NAME(aout,new_section_hook) PARAMS ((bfd *abfd, asection *newsect));
|
||||
|
||||
boolean
|
||||
NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section,
|
||||
PTR location, file_ptr offset, bfd_size_type count));
|
||||
|
||||
asymbol *
|
||||
NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
|
||||
|
||||
boolean
|
||||
NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
|
||||
|
||||
void
|
||||
NAME(aout,write_syms) PARAMS ((bfd *abfd));
|
||||
|
||||
void
|
||||
NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd));
|
||||
|
||||
unsigned int
|
||||
NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd));
|
||||
|
||||
unsigned int
|
||||
NAME(aout,get_symtab) PARAMS ((bfd *abfd, asymbol **location));
|
||||
|
||||
boolean
|
||||
NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect,
|
||||
asymbol **symbols));
|
||||
|
||||
unsigned int
|
||||
NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section,
|
||||
arelent **relptr, asymbol **symbols));
|
||||
|
||||
unsigned int
|
||||
NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect));
|
||||
|
||||
void
|
||||
NAME(aout,reclaim_reloc) PARAMS ((bfd *ignore_abfd, sec_ptr ignore));
|
||||
|
||||
alent *
|
||||
NAME(aout,get_lineno) PARAMS ((bfd *ignore_abfd, asymbol *ignore_symbol));
|
||||
|
||||
void
|
||||
NAME(aout,print_symbol) PARAMS ((bfd *ignore_abfd, PTR file,
|
||||
asymbol *symbol, bfd_print_symbol_type how));
|
||||
|
||||
void
|
||||
NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd,
|
||||
asymbol *symbol, symbol_info *ret));
|
||||
|
||||
boolean
|
||||
NAME(aout,close_and_cleanup) PARAMS ((bfd *abfd));
|
||||
|
||||
boolean
|
||||
NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section,
|
||||
asymbol **symbols, bfd_vma offset, CONST char **filename_ptr,
|
||||
CONST char **functionname_ptr, unsigned int *line_ptr));
|
||||
|
||||
int
|
||||
NAME(aout,sizeof_headers) PARAMS ((bfd *abfd, boolean exec));
|
||||
|
||||
boolean
|
||||
NAME(aout,adjust_sizes_and_vmas) PARAMS ((bfd *abfd,
|
||||
bfd_size_type *text_size, file_ptr *text_end));
|
||||
|
||||
void
|
||||
NAME(aout,swap_exec_header_in) PARAMS ((bfd *abfd,
|
||||
struct external_exec *raw_bytes, struct internal_exec *execp));
|
||||
|
||||
void
|
||||
NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
|
||||
struct internal_exec *execp, struct external_exec *raw_bytes));
|
||||
|
||||
/* Prototypes for functions in stab-syms.c. */
|
||||
|
||||
CONST char *
|
||||
aout_stab_name PARAMS ((int code));
|
||||
|
||||
/* A.out uses the generic versions of these routines... */
|
||||
|
||||
#define aout_32_get_section_contents bfd_generic_get_section_contents
|
||||
#define aout_32_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
|
||||
#define aout_64_get_section_contents bfd_generic_get_section_contents
|
||||
#define aout_64_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
#ifndef NO_WRITE_HEADER_KLUDGE
|
||||
#define NO_WRITE_HEADER_KLUDGE 0
|
||||
#endif
|
||||
|
||||
#ifndef WRITE_HEADERS
|
||||
#define WRITE_HEADERS(abfd, execp) \
|
||||
{ \
|
||||
bfd_size_type text_size; /* dummy vars */ \
|
||||
file_ptr text_end; \
|
||||
if (adata(abfd).magic == undecided_magic) \
|
||||
NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
|
||||
\
|
||||
execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
|
||||
execp->a_entry = bfd_get_start_address (abfd); \
|
||||
\
|
||||
execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
|
||||
obj_reloc_entry_size (abfd)); \
|
||||
execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
|
||||
obj_reloc_entry_size (abfd)); \
|
||||
NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
|
||||
\
|
||||
bfd_seek (abfd, (file_ptr) 0, SEEK_SET); \
|
||||
bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); \
|
||||
/* Now write out reloc info, followed by syms and strings */ \
|
||||
\
|
||||
if (bfd_get_symcount (abfd) != 0) \
|
||||
{ \
|
||||
bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
|
||||
\
|
||||
NAME(aout,write_syms)(abfd); \
|
||||
\
|
||||
bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
|
||||
\
|
||||
if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \
|
||||
bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET); \
|
||||
\
|
||||
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
|
||||
} \
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,853 @@
|
|||
/* Assorted BFD support routines, only used internally.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libbfd.c,v 1.1 1994/01/28 12:37:56 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/*
|
||||
SECTION
|
||||
libbfd
|
||||
|
||||
DESCRIPTION
|
||||
This file contains various routines which are used within BFD.
|
||||
They are not intended for export, but are documented here for
|
||||
completeness.
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(_bfd_dummy_new_section_hook,(ignore, ignore_newsect),
|
||||
bfd *ignore AND
|
||||
asection *ignore_newsect)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_false ,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_true,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PTR
|
||||
DEFUN(bfd_nullvoidptr,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
return (PTR)NULL;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(bfd_0,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DEFUN(bfd_0u,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_void,(ignore),
|
||||
bfd *ignore)
|
||||
{
|
||||
}
|
||||
|
||||
boolean
|
||||
DEFUN(_bfd_dummy_core_file_matches_executable_p,(ignore_core_bfd, ignore_exec_bfd),
|
||||
bfd *ignore_core_bfd AND
|
||||
bfd *ignore_exec_bfd)
|
||||
{
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* of course you can't initialize a function to be the same as another, grr */
|
||||
|
||||
char *
|
||||
DEFUN(_bfd_dummy_core_file_failing_command,(ignore_abfd),
|
||||
bfd *ignore_abfd)
|
||||
{
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(_bfd_dummy_core_file_failing_signal,(ignore_abfd),
|
||||
bfd *ignore_abfd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bfd_target *
|
||||
DEFUN(_bfd_dummy_target,(ignore_abfd),
|
||||
bfd *ignore_abfd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** zalloc -- allocate and clear storage */
|
||||
|
||||
|
||||
#ifndef zalloc
|
||||
char *
|
||||
DEFUN(zalloc,(size),
|
||||
bfd_size_type size)
|
||||
{
|
||||
char *ptr = (char *) malloc ((size_t)size);
|
||||
|
||||
if ((ptr != NULL) && (size != 0))
|
||||
memset(ptr,0, (size_t) size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_xmalloc
|
||||
|
||||
SYNOPSIS
|
||||
PTR bfd_xmalloc( bfd_size_type size);
|
||||
|
||||
DESCRIPTION
|
||||
Like malloc, but exit if no more memory.
|
||||
|
||||
*/
|
||||
|
||||
/** There is major inconsistency in how running out of memory is handled.
|
||||
Some routines return a NULL, and set bfd_error to no_memory.
|
||||
However, obstack routines can't do this ... */
|
||||
|
||||
|
||||
DEFUN(PTR bfd_xmalloc,(size),
|
||||
bfd_size_type size)
|
||||
{
|
||||
static CONST char no_memory_message[] = "Virtual memory exhausted!\n";
|
||||
PTR ptr;
|
||||
if (size == 0) size = 1;
|
||||
ptr = (PTR)malloc((size_t) size);
|
||||
if (!ptr)
|
||||
{
|
||||
write (2, no_memory_message, sizeof(no_memory_message)-1);
|
||||
exit (-1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_xmalloc_by_size_t
|
||||
|
||||
SYNOPSIS
|
||||
PTR bfd_xmalloc_by_size_t ( size_t size);
|
||||
|
||||
DESCRIPTION
|
||||
Like malloc, but exit if no more memory.
|
||||
Uses size_t, so it's suitable for use as obstack_chunk_alloc.
|
||||
*/
|
||||
PTR
|
||||
DEFUN(bfd_xmalloc_by_size_t, (size),
|
||||
size_t size)
|
||||
{
|
||||
return bfd_xmalloc ((bfd_size_type) size);
|
||||
}
|
||||
|
||||
/* Some IO code */
|
||||
|
||||
|
||||
/* Note that archive entries don't have streams; they share their parent's.
|
||||
This allows someone to play with the iostream behind BFD's back.
|
||||
|
||||
Also, note that the origin pointer points to the beginning of a file's
|
||||
contents (0 for non-archive elements). For archive entries this is the
|
||||
first octet in the file, NOT the beginning of the archive header. */
|
||||
|
||||
static
|
||||
int DEFUN(real_read,(where, a,b, file),
|
||||
PTR where AND
|
||||
int a AND
|
||||
int b AND
|
||||
FILE *file)
|
||||
{
|
||||
return fread(where, a,b,file);
|
||||
}
|
||||
bfd_size_type
|
||||
DEFUN(bfd_read,(ptr, size, nitems, abfd),
|
||||
PTR ptr AND
|
||||
bfd_size_type size AND
|
||||
bfd_size_type nitems AND
|
||||
bfd *abfd)
|
||||
{
|
||||
int nread;
|
||||
nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (nread > 0)
|
||||
abfd->where += nread;
|
||||
#endif
|
||||
return nread;
|
||||
}
|
||||
|
||||
bfd_size_type
|
||||
DEFUN(bfd_write,(ptr, size, nitems, abfd),
|
||||
CONST PTR ptr AND
|
||||
bfd_size_type size AND
|
||||
bfd_size_type nitems AND
|
||||
bfd *abfd)
|
||||
{
|
||||
int nwrote = fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (nwrote > 0)
|
||||
abfd->where += nwrote;
|
||||
#endif
|
||||
return nwrote;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_write_bigendian_4byte_int
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
|
||||
|
||||
DESCRIPTION
|
||||
Writes a 4 byte integer to the outputing bfd, in big endian
|
||||
mode regardless of what else is going on. This is useful in
|
||||
archives.
|
||||
|
||||
*/
|
||||
void
|
||||
DEFUN(bfd_write_bigendian_4byte_int,(abfd, i),
|
||||
bfd *abfd AND
|
||||
int i)
|
||||
{
|
||||
bfd_byte buffer[4];
|
||||
bfd_putb32(i, buffer);
|
||||
bfd_write((PTR)buffer, 4, 1, abfd);
|
||||
}
|
||||
|
||||
long
|
||||
DEFUN(bfd_tell,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
file_ptr ptr;
|
||||
|
||||
ptr = ftell (bfd_cache_lookup(abfd));
|
||||
|
||||
if (abfd->my_archive)
|
||||
ptr -= abfd->origin;
|
||||
abfd->where = ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(bfd_flush,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return fflush (bfd_cache_lookup(abfd));
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(bfd_stat,(abfd, statbuf),
|
||||
bfd *abfd AND
|
||||
struct stat *statbuf)
|
||||
{
|
||||
return fstat (fileno(bfd_cache_lookup(abfd)), statbuf);
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(bfd_seek,(abfd, position, direction),
|
||||
bfd * CONST abfd AND
|
||||
CONST file_ptr position AND
|
||||
CONST int direction)
|
||||
{
|
||||
int result;
|
||||
FILE *f;
|
||||
file_ptr file_position;
|
||||
/* For the time being, a BFD may not seek to it's end. The problem
|
||||
is that we don't easily have a way to recognize the end of an
|
||||
element in an archive. */
|
||||
|
||||
BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
|
||||
|
||||
if (direction == SEEK_CUR && position == 0)
|
||||
return 0;
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (abfd->format != bfd_archive && abfd->my_archive == 0)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
/* Explanation for this code: I'm only about 95+% sure that the above
|
||||
conditions are sufficient and that all i/o calls are properly
|
||||
adjusting the `where' field. So this is sort of an `assert'
|
||||
that the `where' field is correct. If we can go a while without
|
||||
tripping the abort, we can probably safely disable this code,
|
||||
so that the real optimizations happen. */
|
||||
file_ptr where_am_i_now;
|
||||
where_am_i_now = ftell (bfd_cache_lookup (abfd));
|
||||
if (abfd->my_archive)
|
||||
where_am_i_now -= abfd->origin;
|
||||
if (where_am_i_now != abfd->where)
|
||||
abort ();
|
||||
#endif
|
||||
if (direction == SEEK_SET && position == abfd->where)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need something smarter to optimize access to archives.
|
||||
Currently, anything inside an archive is read via the file
|
||||
handle for the archive. Which means that a bfd_seek on one
|
||||
component affects the `current position' in the archive, as
|
||||
well as in any other component.
|
||||
|
||||
It might be sufficient to put a spike through the cache
|
||||
abstraction, and look to the archive for the file position,
|
||||
but I think we should try for something cleaner.
|
||||
|
||||
In the meantime, no optimization for archives. */
|
||||
}
|
||||
#endif
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
file_position = position;
|
||||
if (direction == SEEK_SET && abfd->my_archive != NULL)
|
||||
file_position += abfd->origin;
|
||||
|
||||
result = fseek (f, file_position, direction);
|
||||
|
||||
if (result != 0)
|
||||
/* Force redetermination of `where' field. */
|
||||
bfd_tell (abfd);
|
||||
else
|
||||
{
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
/* Adjust `where' field. */
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Make a string table */
|
||||
|
||||
/*>bfd.h<
|
||||
Add string to table pointed to by table, at location starting with free_ptr.
|
||||
resizes the table if necessary (if it's NULL, creates it, ignoring
|
||||
table_length). Updates free_ptr, table, table_length */
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
|
||||
char **table AND
|
||||
char *new_string AND
|
||||
unsigned int *table_length AND
|
||||
char **free_ptr)
|
||||
{
|
||||
size_t string_length = strlen (new_string) + 1; /* include null here */
|
||||
char *base = *table;
|
||||
size_t space_length = *table_length;
|
||||
unsigned int offset = (base ? *free_ptr - base : 0);
|
||||
|
||||
if (base == NULL) {
|
||||
/* Avoid a useless regrow if we can (but of course we still
|
||||
take it next time */
|
||||
space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
|
||||
DEFAULT_STRING_SPACE_SIZE : string_length+1);
|
||||
base = zalloc ((bfd_size_type) space_length);
|
||||
|
||||
if (base == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size_t)(offset + string_length) >= space_length) {
|
||||
/* Make sure we will have enough space */
|
||||
while ((size_t)(offset + string_length) >= space_length)
|
||||
space_length += space_length/2; /* grow by 50% */
|
||||
|
||||
base = (char *) realloc (base, space_length);
|
||||
if (base == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
memcpy (base + offset, new_string, string_length);
|
||||
*table = base;
|
||||
*table_length = space_length;
|
||||
*free_ptr = base + offset + string_length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** The do-it-yourself (byte) sex-change kit */
|
||||
|
||||
/* The middle letter e.g. get<b>short indicates Big or Little endian
|
||||
target machine. It doesn't matter what the byte order of the host
|
||||
machine is; these routines work for either. */
|
||||
|
||||
/* FIXME: Should these take a count argument?
|
||||
Answer (gnu@cygnus.com): No, but perhaps they should be inline
|
||||
functions in swap.h #ifdef __GNUC__.
|
||||
Gprof them later and find out. */
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_put_size
|
||||
FUNCTION
|
||||
bfd_get_size
|
||||
|
||||
DESCRIPTION
|
||||
These macros as used for reading and writing raw data in
|
||||
sections; each access (except for bytes) is vectored through
|
||||
the target format of the BFD and mangled accordingly. The
|
||||
mangling performs any necessary endian translations and
|
||||
removes alignment restrictions. Note that types accepted and
|
||||
returned by these macros are identical so they can be swapped
|
||||
around in macros--for example libaout.h defines GET_WORD to
|
||||
either bfd_get_32 or bfd_get_64.
|
||||
|
||||
In the put routines, val must be a bfd_vma. If we are on a
|
||||
system without prototypes, the caller is responsible for making
|
||||
sure that is true, with a cast if necessary. We don't cast
|
||||
them in the macro definitions because that would prevent lint
|
||||
or gcc -Wall from detecting sins such as passing a pointer.
|
||||
To detect calling these with less than a bfd_vma, use gcc
|
||||
-Wconversion on a host with 64 bit bfd_vma's.
|
||||
|
||||
.
|
||||
.{* Byte swapping macros for user section data. *}
|
||||
.
|
||||
.#define bfd_put_8(abfd, val, ptr) \
|
||||
. (*((unsigned char *)(ptr)) = (unsigned char)val)
|
||||
.#define bfd_put_signed_8 \
|
||||
. bfd_put_8
|
||||
.#define bfd_get_8(abfd, ptr) \
|
||||
. (*(unsigned char *)(ptr))
|
||||
.#define bfd_get_signed_8(abfd, ptr) \
|
||||
. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
|
||||
.
|
||||
.#define bfd_put_16(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
|
||||
.#define bfd_put_signed_16 \
|
||||
. bfd_put_16
|
||||
.#define bfd_get_16(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_getx16, (ptr))
|
||||
.#define bfd_get_signed_16(abfd, ptr) \
|
||||
. BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
|
||||
.
|
||||
.#define bfd_put_32(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
|
||||
.#define bfd_put_signed_32 \
|
||||
. bfd_put_32
|
||||
.#define bfd_get_32(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_getx32, (ptr))
|
||||
.#define bfd_get_signed_32(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
|
||||
.
|
||||
.#define bfd_put_64(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
|
||||
.#define bfd_put_signed_64 \
|
||||
. bfd_put_64
|
||||
.#define bfd_get_64(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_getx64, (ptr))
|
||||
.#define bfd_get_signed_64(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
|
||||
.
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_h_put_size
|
||||
FUNCTION
|
||||
bfd_h_get_size
|
||||
|
||||
DESCRIPTION
|
||||
These macros have the same function as their <<bfd_get_x>>
|
||||
bretherin, except that they are used for removing information
|
||||
for the header records of object files. Believe it or not,
|
||||
some object files keep their header records in big endian
|
||||
order, and their data in little endian order.
|
||||
.
|
||||
.{* Byte swapping macros for file header data. *}
|
||||
.
|
||||
.#define bfd_h_put_8(abfd, val, ptr) \
|
||||
. bfd_put_8 (abfd, val, ptr)
|
||||
.#define bfd_h_put_signed_8(abfd, val, ptr) \
|
||||
. bfd_put_8 (abfd, val, ptr)
|
||||
.#define bfd_h_get_8(abfd, ptr) \
|
||||
. bfd_get_8 (abfd, ptr)
|
||||
.#define bfd_h_get_signed_8(abfd, ptr) \
|
||||
. bfd_get_signed_8 (abfd, ptr)
|
||||
.
|
||||
.#define bfd_h_put_16(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
|
||||
.#define bfd_h_put_signed_16 \
|
||||
. bfd_h_put_16
|
||||
.#define bfd_h_get_16(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx16,(ptr))
|
||||
.#define bfd_h_get_signed_16(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
|
||||
.
|
||||
.#define bfd_h_put_32(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
|
||||
.#define bfd_h_put_signed_32 \
|
||||
. bfd_h_put_32
|
||||
.#define bfd_h_get_32(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx32,(ptr))
|
||||
.#define bfd_h_get_signed_32(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
|
||||
.
|
||||
.#define bfd_h_put_64(abfd, val, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
|
||||
.#define bfd_h_put_signed_64 \
|
||||
. bfd_h_put_64
|
||||
.#define bfd_h_get_64(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx64,(ptr))
|
||||
.#define bfd_h_get_signed_64(abfd, ptr) \
|
||||
. BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
|
||||
.
|
||||
*/
|
||||
|
||||
/* Sign extension to bfd_signed_vma. */
|
||||
#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
|
||||
#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
|
||||
#define EIGHT_GAZILLION (((HOST_64_BIT)0x80000000) << 32)
|
||||
#define COERCE64(x) \
|
||||
(((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
|
||||
|
||||
bfd_vma
|
||||
DEFUN(bfd_getb16,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
return (addr[0] << 8) | addr[1];
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
DEFUN(bfd_getl16,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
return (addr[1] << 8) | addr[0];
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
DEFUN(bfd_getb_signed_16,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
return COERCE16((addr[0] << 8) | addr[1]);
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
DEFUN(bfd_getl_signed_16,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
return COERCE16((addr[1] << 8) | addr[0]);
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_putb16,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
addr[0] = (bfd_byte)(data >> 8);
|
||||
addr[1] = (bfd_byte )data;
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_putl16,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
addr[0] = (bfd_byte )data;
|
||||
addr[1] = (bfd_byte)(data >> 8);
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
bfd_getb32 (addr)
|
||||
register bfd_byte *addr;
|
||||
{
|
||||
return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
|
||||
| addr[2]) << 8 | addr[3];
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
bfd_getl32 (addr)
|
||||
register bfd_byte *addr;
|
||||
{
|
||||
return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
|
||||
| addr[1]) << 8 | addr[0];
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
bfd_getb_signed_32 (addr)
|
||||
register bfd_byte *addr;
|
||||
{
|
||||
return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
|
||||
| addr[2]) << 8 | addr[3]);
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
bfd_getl_signed_32 (addr)
|
||||
register bfd_byte *addr;
|
||||
{
|
||||
return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
|
||||
| addr[1]) << 8 | addr[0]);
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
DEFUN(bfd_getb64,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
#ifdef BFD64
|
||||
bfd_vma low, high;
|
||||
|
||||
high= ((((((((addr[0]) << 8) |
|
||||
addr[1]) << 8) |
|
||||
addr[2]) << 8) |
|
||||
addr[3]) );
|
||||
|
||||
low = (((((((((bfd_vma)addr[4]) << 8) |
|
||||
addr[5]) << 8) |
|
||||
addr[6]) << 8) |
|
||||
addr[7]));
|
||||
|
||||
return high << 32 | low;
|
||||
#else
|
||||
BFD_FAIL();
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
DEFUN(bfd_getl64,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
|
||||
#ifdef BFD64
|
||||
bfd_vma low, high;
|
||||
high= (((((((addr[7] << 8) |
|
||||
addr[6]) << 8) |
|
||||
addr[5]) << 8) |
|
||||
addr[4]));
|
||||
|
||||
low = ((((((((bfd_vma)addr[3] << 8) |
|
||||
addr[2]) << 8) |
|
||||
addr[1]) << 8) |
|
||||
addr[0]) );
|
||||
|
||||
return high << 32 | low;
|
||||
#else
|
||||
BFD_FAIL();
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
DEFUN(bfd_getb_signed_64,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
#ifdef BFD64
|
||||
bfd_vma low, high;
|
||||
|
||||
high= ((((((((addr[0]) << 8) |
|
||||
addr[1]) << 8) |
|
||||
addr[2]) << 8) |
|
||||
addr[3]) );
|
||||
|
||||
low = (((((((((bfd_vma)addr[4]) << 8) |
|
||||
addr[5]) << 8) |
|
||||
addr[6]) << 8) |
|
||||
addr[7]));
|
||||
|
||||
return COERCE64(high << 32 | low);
|
||||
#else
|
||||
BFD_FAIL();
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bfd_signed_vma
|
||||
DEFUN(bfd_getl_signed_64,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
|
||||
#ifdef BFD64
|
||||
bfd_vma low, high;
|
||||
high= (((((((addr[7] << 8) |
|
||||
addr[6]) << 8) |
|
||||
addr[5]) << 8) |
|
||||
addr[4]));
|
||||
|
||||
low = ((((((((bfd_vma)addr[3] << 8) |
|
||||
addr[2]) << 8) |
|
||||
addr[1]) << 8) |
|
||||
addr[0]) );
|
||||
|
||||
return COERCE64(high << 32 | low);
|
||||
#else
|
||||
BFD_FAIL();
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_putb32,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
addr[0] = (bfd_byte)(data >> 24);
|
||||
addr[1] = (bfd_byte)(data >> 16);
|
||||
addr[2] = (bfd_byte)(data >> 8);
|
||||
addr[3] = (bfd_byte)data;
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_putl32,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
addr[0] = (bfd_byte)data;
|
||||
addr[1] = (bfd_byte)(data >> 8);
|
||||
addr[2] = (bfd_byte)(data >> 16);
|
||||
addr[3] = (bfd_byte)(data >> 24);
|
||||
}
|
||||
void
|
||||
DEFUN(bfd_putb64,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
#ifdef BFD64
|
||||
addr[0] = (bfd_byte)(data >> (7*8));
|
||||
addr[1] = (bfd_byte)(data >> (6*8));
|
||||
addr[2] = (bfd_byte)(data >> (5*8));
|
||||
addr[3] = (bfd_byte)(data >> (4*8));
|
||||
addr[4] = (bfd_byte)(data >> (3*8));
|
||||
addr[5] = (bfd_byte)(data >> (2*8));
|
||||
addr[6] = (bfd_byte)(data >> (1*8));
|
||||
addr[7] = (bfd_byte)(data >> (0*8));
|
||||
#else
|
||||
BFD_FAIL();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN(bfd_putl64,(data, addr),
|
||||
bfd_vma data AND
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
#ifdef BFD64
|
||||
addr[7] = (bfd_byte)(data >> (7*8));
|
||||
addr[6] = (bfd_byte)(data >> (6*8));
|
||||
addr[5] = (bfd_byte)(data >> (5*8));
|
||||
addr[4] = (bfd_byte)(data >> (4*8));
|
||||
addr[3] = (bfd_byte)(data >> (3*8));
|
||||
addr[2] = (bfd_byte)(data >> (2*8));
|
||||
addr[1] = (bfd_byte)(data >> (1*8));
|
||||
addr[0] = (bfd_byte)(data >> (0*8));
|
||||
#else
|
||||
BFD_FAIL();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Default implementation */
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type count)
|
||||
{
|
||||
if (count == 0)
|
||||
return true;
|
||||
if ((bfd_size_type)(offset+count) > section->_raw_size
|
||||
|| bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
|
||||
|| bfd_read(location, (bfd_size_type)1, count, abfd) != count)
|
||||
return (false); /* on error */
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* This generic function can only be used in implementations where creating
|
||||
NEW sections is disallowed. It is useful in patching existing sections
|
||||
in read-write files, though. See other set_section_contents functions
|
||||
to see why it doesn't work for new sections. */
|
||||
boolean
|
||||
DEFUN(bfd_generic_set_section_contents, (abfd, section, location, offset, count),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type count)
|
||||
{
|
||||
if (count == 0)
|
||||
return true;
|
||||
if ((bfd_size_type)(offset+count) > bfd_get_section_size_after_reloc(section)
|
||||
|| bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
|
||||
|| bfd_write(location, (bfd_size_type)1, count, abfd) != count)
|
||||
return (false); /* on error */
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_log2
|
||||
|
||||
DESCRIPTION
|
||||
Return the log base 2 of the value supplied, rounded up. eg an
|
||||
arg of 1025 would return 11.
|
||||
|
||||
SYNOPSIS
|
||||
unsigned int bfd_log2(bfd_vma x);
|
||||
*/
|
||||
|
||||
unsigned
|
||||
bfd_log2(x)
|
||||
bfd_vma x;
|
||||
{
|
||||
unsigned result = 0;
|
||||
while ( (bfd_vma)(1<< result) < x)
|
||||
result++;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/* libbfd.h -- Declarations used by bfd library *implementation*.
|
||||
(This include file is not for users of the library.)
|
||||
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libbfd.h,v 1.1 1994/01/28 12:37:57 pk Exp $
|
||||
*/
|
||||
|
||||
|
||||
/* Align an address upward to a boundary, expressed as a number of bytes.
|
||||
E.g. align to an 8-byte boundary with argument of 8. */
|
||||
#define BFD_ALIGN(this, boundary) \
|
||||
((( (this) + ((boundary) -1)) & (~((boundary)-1))))
|
||||
|
||||
/* If you want to read and write large blocks, you might want to do it
|
||||
in quanta of this amount */
|
||||
#define DEFAULT_BUFFERSIZE 8192
|
||||
|
||||
/* Set a tdata field. Can't use the other macros for this, since they
|
||||
do casts, and casting to the left of assignment isn't portable. */
|
||||
#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v))
|
||||
|
||||
/* tdata for an archive. For an input archive, cache
|
||||
needs to be free()'d. For an output archive, symdefs do. */
|
||||
|
||||
struct artdata {
|
||||
file_ptr first_file_filepos;
|
||||
/* Speed up searching the armap */
|
||||
struct ar_cache *cache;
|
||||
bfd *archive_head; /* Only interesting in output routines */
|
||||
carsym *symdefs; /* the symdef entries */
|
||||
symindex symdef_count; /* how many there are */
|
||||
char *extended_names; /* clever intel extension */
|
||||
time_t armap_timestamp; /* Timestamp value written into armap.
|
||||
This is used for BSD archives to check
|
||||
that the timestamp is recent enough
|
||||
for the BSD linker to not complain,
|
||||
just before we finish writing an
|
||||
archive. */
|
||||
file_ptr armap_datepos; /* Position within archive to seek to
|
||||
rewrite the date field. */
|
||||
};
|
||||
|
||||
#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
|
||||
|
||||
/* Goes in bfd's arelt_data slot */
|
||||
struct areltdata {
|
||||
char * arch_header; /* it's actually a string */
|
||||
unsigned int parsed_size; /* octets of filesize not including ar_hdr */
|
||||
char *filename; /* null-terminated */
|
||||
};
|
||||
|
||||
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
|
||||
|
||||
char *zalloc PARAMS ((bfd_size_type size));
|
||||
|
||||
/* These routines allocate and free things on the BFD's obstack. Note
|
||||
that realloc can never occur in place. */
|
||||
|
||||
PTR bfd_alloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t new));
|
||||
void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size));
|
||||
PTR bfd_alloc_finish PARAMS ((bfd *abfd));
|
||||
PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted));
|
||||
|
||||
#define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
|
||||
|
||||
|
||||
bfd_size_type bfd_read PARAMS ((PTR ptr, bfd_size_type size,
|
||||
bfd_size_type nitems, bfd *abfd));
|
||||
bfd_size_type bfd_write PARAMS ((CONST PTR ptr, bfd_size_type size,
|
||||
bfd_size_type nitems, bfd *abfd));
|
||||
int bfd_seek PARAMS ((bfd* CONST abfd, CONST file_ptr fp,
|
||||
CONST int direction));
|
||||
long bfd_tell PARAMS ((bfd *abfd));
|
||||
|
||||
int bfd_flush PARAMS ((bfd *abfd));
|
||||
int bfd_stat PARAMS ((bfd *abfd, struct stat *));
|
||||
|
||||
bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
|
||||
bfd * look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
|
||||
boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
|
||||
struct areltdata * snarf_ar_hdr PARAMS ((bfd *abfd));
|
||||
bfd_target * bfd_generic_archive_p PARAMS ((bfd *abfd));
|
||||
boolean bfd_slurp_armap PARAMS ((bfd *abfd));
|
||||
boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
|
||||
#define bfd_slurp_bsd_armap bfd_slurp_armap
|
||||
#define bfd_slurp_coff_armap bfd_slurp_armap
|
||||
boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
|
||||
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
|
||||
bfd * new_bfd PARAMS (());
|
||||
|
||||
#define DEFAULT_STRING_SPACE_SIZE 0x2000
|
||||
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
|
||||
unsigned int *table_length,
|
||||
char **free_ptr));
|
||||
|
||||
boolean bfd_false PARAMS ((bfd *ignore));
|
||||
boolean bfd_true PARAMS ((bfd *ignore));
|
||||
PTR bfd_nullvoidptr PARAMS ((bfd *ignore));
|
||||
int bfd_0 PARAMS ((bfd *ignore));
|
||||
unsigned int bfd_0u PARAMS ((bfd *ignore));
|
||||
void bfd_void PARAMS ((bfd *ignore));
|
||||
|
||||
bfd * new_bfd_contained_in PARAMS ((bfd *));
|
||||
boolean _bfd_dummy_new_section_hook PARAMS ((bfd *ignore, asection *newsect));
|
||||
char * _bfd_dummy_core_file_failing_command PARAMS ((bfd *abfd));
|
||||
int _bfd_dummy_core_file_failing_signal PARAMS ((bfd *abfd));
|
||||
boolean _bfd_dummy_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
|
||||
bfd *exec_bfd));
|
||||
bfd_target * _bfd_dummy_target PARAMS ((bfd *abfd));
|
||||
|
||||
void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
|
||||
boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
struct orl *map, unsigned int orl_count, int stridx));
|
||||
|
||||
boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
struct orl *map, unsigned int orl_count, int stridx));
|
||||
|
||||
bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
|
||||
bfd *last_file));
|
||||
|
||||
int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
|
||||
boolean bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
|
||||
PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
|
||||
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
|
||||
PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
|
||||
/* Macros to tell if bfds are read or write enabled.
|
||||
|
||||
Note that bfds open for read may be scribbled into if the fd passed
|
||||
to bfd_fdopenr is actually open both for read and write
|
||||
simultaneously. However an output bfd will never be open for
|
||||
read. Therefore sometimes you want to check bfd_read_p or
|
||||
!bfd_read_p, and only sometimes bfd_write_p.
|
||||
*/
|
||||
|
||||
#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction)
|
||||
#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction)
|
||||
|
||||
void bfd_assert PARAMS ((char*,int));
|
||||
|
||||
#define BFD_ASSERT(x) \
|
||||
{ if (!(x)) bfd_assert(__FILE__,__LINE__); }
|
||||
|
||||
#define BFD_FAIL() \
|
||||
{ bfd_assert(__FILE__,__LINE__); }
|
||||
|
||||
FILE * bfd_cache_lookup_worker PARAMS ((bfd *));
|
||||
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
/* Now Steve, what's the story here? */
|
||||
#ifdef lint
|
||||
#define itos(x) "l"
|
||||
#define stoi(x) 1
|
||||
#else
|
||||
#define itos(x) ((char*)(x))
|
||||
#define stoi(x) ((int)(x))
|
||||
#endif
|
||||
|
||||
/* Generic routine for close_and_cleanup is really just bfd_true. */
|
||||
#define bfd_generic_close_and_cleanup bfd_true
|
||||
|
||||
/* And more follows */
|
||||
|
||||
void
|
||||
bfd_check_init PARAMS ((void));
|
||||
|
||||
PTR
|
||||
bfd_xmalloc PARAMS (( bfd_size_type size));
|
||||
|
||||
PTR
|
||||
bfd_xmalloc_by_size_t PARAMS (( size_t size));
|
||||
|
||||
void
|
||||
bfd_write_bigendian_4byte_int PARAMS ((bfd *abfd, int i));
|
||||
|
||||
unsigned int
|
||||
bfd_log2 PARAMS ((bfd_vma x));
|
||||
|
||||
#define BFD_CACHE_MAX_OPEN 10
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
#define bfd_cache_lookup(x) \
|
||||
((x)==bfd_last_cache? \
|
||||
(FILE*)(bfd_last_cache->iostream): \
|
||||
bfd_cache_lookup_worker(x))
|
||||
boolean
|
||||
bfd_cache_close PARAMS ((bfd *));
|
||||
|
||||
FILE*
|
||||
bfd_open_file PARAMS ((bfd *));
|
||||
|
||||
FILE *
|
||||
bfd_cache_lookup_worker PARAMS ((bfd *));
|
||||
|
||||
void
|
||||
bfd_constructor_entry PARAMS ((bfd *abfd,
|
||||
asymbol **symbol_ptr_ptr,
|
||||
CONST char*type));
|
||||
|
||||
CONST struct reloc_howto_struct *
|
||||
bfd_default_reloc_type_lookup
|
||||
PARAMS ((bfd *abfd AND
|
||||
bfd_reloc_code_real_type code));
|
||||
|
||||
boolean
|
||||
bfd_generic_relax_section
|
||||
PARAMS ((bfd *abfd,
|
||||
asection *section,
|
||||
asymbol **symbols));
|
||||
|
||||
bfd_byte *
|
||||
|
||||
bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
|
||||
struct bfd_seclet *seclet,
|
||||
bfd_byte *data,
|
||||
boolean relocateable));
|
||||
|
||||
boolean
|
||||
bfd_generic_seclet_link
|
||||
PARAMS ((bfd *abfd,
|
||||
PTR data,
|
||||
boolean relocateable));
|
||||
|
||||
extern bfd_arch_info_type bfd_default_arch_struct;
|
||||
boolean
|
||||
bfd_default_set_arch_mach PARAMS ((bfd *abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach));
|
||||
|
||||
void
|
||||
bfd_arch_init PARAMS ((void));
|
||||
|
||||
void
|
||||
bfd_arch_linkin PARAMS ((bfd_arch_info_type *));
|
||||
|
||||
CONST bfd_arch_info_type *
|
||||
bfd_default_compatible
|
||||
PARAMS ((CONST bfd_arch_info_type *a,
|
||||
CONST bfd_arch_info_type *b));
|
||||
|
||||
boolean
|
||||
bfd_default_scan PARAMS ((CONST struct bfd_arch_info *, CONST char *));
|
||||
|
||||
struct elf_internal_shdr *
|
||||
bfd_elf_find_section PARAMS ((bfd *abfd, char *name));
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
/* BFD COFF object file private structure.
|
||||
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libcoff.h,v 1.1 1994/01/28 12:37:59 pk Exp $
|
||||
*/
|
||||
|
||||
|
||||
/* Object file tdata; access macros */
|
||||
|
||||
#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
|
||||
#define exec_hdr(bfd) (coff_data(bfd)->hdr)
|
||||
#define obj_symbols(bfd) (coff_data(bfd)->symbols)
|
||||
#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos)
|
||||
|
||||
#define obj_relocbase(bfd) (coff_data(bfd)->relocbase)
|
||||
#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments)
|
||||
#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count)
|
||||
#define obj_convert(bfd) (coff_data(bfd)->conversion_table)
|
||||
#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size)
|
||||
#if CFILE_STUFF
|
||||
#define obj_symbol_slew(bfd) (coff_data(bfd)->symbol_index_slew)
|
||||
#else
|
||||
#define obj_symbol_slew(bfd) 0
|
||||
#endif
|
||||
|
||||
|
||||
/* `Tdata' information kept for COFF files. */
|
||||
|
||||
typedef struct coff_tdata
|
||||
{
|
||||
struct coff_symbol_struct *symbols; /* symtab for input bfd */
|
||||
unsigned int *conversion_table;
|
||||
int conv_table_size;
|
||||
file_ptr sym_filepos;
|
||||
|
||||
long symbol_index_slew; /* used during read to mark whether a
|
||||
C_FILE symbol as been added. */
|
||||
|
||||
struct coff_ptr_struct *raw_syments;
|
||||
struct lineno *raw_linenos;
|
||||
unsigned int raw_syment_count;
|
||||
unsigned short flags;
|
||||
|
||||
/* These are only valid once writing has begun */
|
||||
long int relocbase;
|
||||
|
||||
/* These members communicate important constants about the symbol table
|
||||
to GDB's symbol-reading code. These `constants' unfortunately vary
|
||||
from coff implementation to implementation... */
|
||||
unsigned local_n_btmask;
|
||||
unsigned local_n_btshft;
|
||||
unsigned local_n_tmask;
|
||||
unsigned local_n_tshift;
|
||||
unsigned local_symesz;
|
||||
unsigned local_auxesz;
|
||||
unsigned local_linesz;
|
||||
} coff_data_type;
|
||||
|
||||
/* We take the address of the first element of a asymbol to ensure that the
|
||||
* macro is only ever applied to an asymbol. */
|
||||
#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))
|
||||
|
||||
/* Functions in coffgen.c. */
|
||||
extern bfd_target *coff_object_p PARAMS ((bfd *));
|
||||
extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int));
|
||||
extern unsigned int coff_get_symtab_upper_bound PARAMS ((bfd *));
|
||||
extern unsigned int coff_get_symtab PARAMS ((bfd *, asymbol **));
|
||||
extern int coff_count_linenumbers PARAMS ((bfd *));
|
||||
extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *));
|
||||
extern void coff_renumber_symbols PARAMS ((bfd *));
|
||||
extern void coff_mangle_symbols PARAMS ((bfd *));
|
||||
extern void coff_write_symbols PARAMS ((bfd *));
|
||||
extern void coff_write_linenumbers PARAMS ((bfd *));
|
||||
extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
|
||||
extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
|
||||
extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
|
||||
extern unsigned int coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
|
||||
extern asymbol *coff_make_empty_symbol PARAMS ((bfd *));
|
||||
extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *,
|
||||
bfd_print_symbol_type how));
|
||||
extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *,
|
||||
symbol_info *ret));
|
||||
extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR,
|
||||
unsigned long));
|
||||
extern boolean coff_find_nearest_line PARAMS ((bfd *,
|
||||
asection *,
|
||||
asymbol **,
|
||||
bfd_vma offset,
|
||||
CONST char **filename_ptr,
|
||||
CONST char **functionname_ptr,
|
||||
unsigned int *line_ptr));
|
||||
extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc));
|
||||
extern boolean bfd_coff_reloc16_relax_section PARAMS ((bfd *,
|
||||
asection *,
|
||||
asymbol **));
|
||||
extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
|
||||
PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable));
|
||||
extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
|
||||
struct bfd_seclet *));
|
||||
|
||||
/* And more taken from the source .. */
|
||||
|
||||
typedef struct coff_ptr_struct
|
||||
{
|
||||
|
||||
/* Remembers the offset from the first symbol in the file for
|
||||
this symbol. Generated by coff_renumber_symbols. */
|
||||
unsigned int offset;
|
||||
|
||||
/* Should the tag field of this symbol be renumbered.
|
||||
Created by coff_pointerize_aux. */
|
||||
char fix_tag;
|
||||
|
||||
/* Should the endidx field of this symbol be renumbered.
|
||||
Created by coff_pointerize_aux. */
|
||||
char fix_end;
|
||||
|
||||
/* The container for the symbol structure as read and translated
|
||||
from the file. */
|
||||
|
||||
union {
|
||||
union internal_auxent auxent;
|
||||
struct internal_syment syment;
|
||||
} u;
|
||||
} combined_entry_type;
|
||||
|
||||
|
||||
/* Each canonical asymbol really looks like this: */
|
||||
|
||||
typedef struct coff_symbol_struct
|
||||
{
|
||||
/* The actual symbol which the rest of BFD works with */
|
||||
asymbol symbol;
|
||||
|
||||
/* A pointer to the hidden information for this symbol */
|
||||
combined_entry_type *native;
|
||||
|
||||
/* A pointer to the linenumber information for this symbol */
|
||||
struct lineno_cache_entry *lineno;
|
||||
|
||||
/* Have the line numbers been relocated yet ? */
|
||||
boolean done_lineno;
|
||||
} coff_symbol_type;
|
||||
typedef struct
|
||||
{
|
||||
void (*_bfd_coff_swap_aux_in) PARAMS ((
|
||||
bfd *abfd ,
|
||||
PTR ext,
|
||||
int type,
|
||||
int class ,
|
||||
PTR in));
|
||||
|
||||
void (*_bfd_coff_swap_sym_in) PARAMS ((
|
||||
bfd *abfd ,
|
||||
PTR ext,
|
||||
PTR in));
|
||||
|
||||
void (*_bfd_coff_swap_lineno_in) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR ext,
|
||||
PTR in));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
int type,
|
||||
int class,
|
||||
PTR ext));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
PTR ext));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_lineno_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
PTR ext));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_reloc_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR src,
|
||||
PTR dst));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
PTR out));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
PTR out));
|
||||
|
||||
unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR in,
|
||||
PTR out));
|
||||
|
||||
unsigned int _bfd_filhsz;
|
||||
unsigned int _bfd_aoutsz;
|
||||
unsigned int _bfd_scnhsz;
|
||||
unsigned int _bfd_symesz;
|
||||
unsigned int _bfd_auxesz;
|
||||
unsigned int _bfd_linesz;
|
||||
boolean _bfd_coff_long_filenames;
|
||||
void (*_bfd_coff_swap_filehdr_in) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR ext,
|
||||
PTR in));
|
||||
void (*_bfd_coff_swap_aouthdr_in) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR ext,
|
||||
PTR in));
|
||||
void (*_bfd_coff_swap_scnhdr_in) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR ext,
|
||||
PTR in));
|
||||
boolean (*_bfd_coff_bad_format_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR internal_filehdr));
|
||||
boolean (*_bfd_coff_set_arch_mach_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR internal_filehdr));
|
||||
PTR (*_bfd_coff_mkobject_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR internal_filehdr,
|
||||
PTR internal_aouthdr));
|
||||
flagword (*_bfd_styp_to_sec_flags_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
PTR internal_scnhdr));
|
||||
asection *(*_bfd_make_section_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
char *name));
|
||||
void (*_bfd_set_alignment_hook) PARAMS ((
|
||||
bfd *abfd,
|
||||
asection *sec,
|
||||
PTR internal_scnhdr));
|
||||
boolean (*_bfd_coff_slurp_symbol_table) PARAMS ((
|
||||
bfd *abfd));
|
||||
boolean (*_bfd_coff_symname_in_debug) PARAMS ((
|
||||
bfd *abfd,
|
||||
struct internal_syment *sym));
|
||||
void (*_bfd_coff_reloc16_extra_cases) PARAMS ((
|
||||
bfd *abfd,
|
||||
struct bfd_seclet *seclet,
|
||||
arelent *reloc,
|
||||
bfd_byte *data,
|
||||
unsigned int *src_ptr,
|
||||
unsigned int *dst_ptr));
|
||||
int (*_bfd_coff_reloc16_estimate) PARAMS ((
|
||||
asection *input_section,
|
||||
asymbol **symbols,
|
||||
arelent *r,
|
||||
unsigned int shrink));
|
||||
|
||||
} bfd_coff_backend_data;
|
||||
|
||||
#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)
|
||||
|
||||
#define bfd_coff_swap_aux_in(a,e,t,c,i) \
|
||||
((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,i))
|
||||
|
||||
#define bfd_coff_swap_sym_in(a,e,i) \
|
||||
((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
|
||||
|
||||
#define bfd_coff_swap_lineno_in(a,e,i) \
|
||||
((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))
|
||||
|
||||
#define bfd_coff_swap_reloc_out(abfd, i, o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_lineno_out(abfd, i, o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_aux_out) (abfd, i,t,c, o))
|
||||
|
||||
#define bfd_coff_swap_sym_out(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_filehdr_out(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz)
|
||||
#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz)
|
||||
#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz)
|
||||
#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz)
|
||||
#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
|
||||
#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
|
||||
#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
|
||||
#define bfd_coff_swap_filehdr_in(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_aouthdr_in(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_swap_scnhdr_in(abfd, i,o) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o))
|
||||
|
||||
#define bfd_coff_bad_format_hook(abfd, filehdr) \
|
||||
((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr))
|
||||
|
||||
#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr))
|
||||
#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr))
|
||||
|
||||
#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr)\
|
||||
((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr))
|
||||
|
||||
#define bfd_coff_make_section_hook(abfd, name)\
|
||||
((coff_backend_info (abfd)->_bfd_make_section_hook) (abfd, name))
|
||||
|
||||
#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\
|
||||
((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr))
|
||||
|
||||
#define bfd_coff_slurp_symbol_table(abfd)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd))
|
||||
|
||||
#define bfd_coff_symname_in_debug(abfd, sym)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
|
||||
|
||||
#define bfd_coff_reloc16_extra_cases(abfd, seclet, reloc, data, src_ptr, dst_ptr)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
|
||||
(abfd, seclet, reloc, data, src_ptr, dst_ptr))
|
||||
|
||||
#define bfd_coff_reloc16_estimate(abfd, section, symbols, reloc, shrink)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
|
||||
(section, symbols, reloc, shrink))
|
||||
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
/* BFD ECOFF object file private structure.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libecoff.h,v 1.1 1994/01/28 12:38:00 pk Exp $
|
||||
*/
|
||||
|
||||
/* This is the backend information kept for ECOFF files. This
|
||||
structure is constant for a particular backend. The first element
|
||||
is the COFF backend data structure, so that ECOFF targets can use
|
||||
the generic COFF code. */
|
||||
|
||||
#define ecoff_backend(abfd) \
|
||||
((struct ecoff_backend_data *) (abfd)->xvec->backend_data)
|
||||
|
||||
struct ecoff_backend_data
|
||||
{
|
||||
/* COFF backend information. This must be the first field. */
|
||||
bfd_coff_backend_data coff;
|
||||
/* Supported architecture. */
|
||||
enum bfd_architecture arch;
|
||||
/* Symbol table magic number. */
|
||||
int sym_magic;
|
||||
/* Initial portion of armap string. */
|
||||
const char *armap_start;
|
||||
/* Alignment of debugging information. E.g., 4. */
|
||||
bfd_size_type debug_align;
|
||||
/* The page boundary used to align sections in a demand-paged
|
||||
executable file. E.g., 0x1000. */
|
||||
bfd_vma round;
|
||||
/* Bitsize of constructor entries. */
|
||||
unsigned int constructor_bitsize;
|
||||
/* Reloc to use for constructor entries. */
|
||||
CONST struct reloc_howto_struct *constructor_reloc;
|
||||
/* Sizes of external symbolic information. */
|
||||
bfd_size_type external_hdr_size;
|
||||
bfd_size_type external_dnr_size;
|
||||
bfd_size_type external_pdr_size;
|
||||
bfd_size_type external_sym_size;
|
||||
bfd_size_type external_opt_size;
|
||||
bfd_size_type external_fdr_size;
|
||||
bfd_size_type external_rfd_size;
|
||||
bfd_size_type external_ext_size;
|
||||
/* Functions to swap in external symbolic data. */
|
||||
void (*swap_hdr_in) PARAMS ((bfd *, PTR, HDRR *));
|
||||
void (*swap_dnr_in) PARAMS ((bfd *, PTR, DNR *));
|
||||
void (*swap_pdr_in) PARAMS ((bfd *, PTR, PDR *));
|
||||
void (*swap_sym_in) PARAMS ((bfd *, PTR, SYMR *));
|
||||
void (*swap_opt_in) PARAMS ((bfd *, PTR, OPTR *));
|
||||
void (*swap_fdr_in) PARAMS ((bfd *, PTR, FDR *));
|
||||
void (*swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *));
|
||||
void (*swap_ext_in) PARAMS ((bfd *, PTR, EXTR *));
|
||||
/* Functions to swap out external symbolic data. */
|
||||
void (*swap_hdr_out) PARAMS ((bfd *, const HDRR *, PTR));
|
||||
void (*swap_dnr_out) PARAMS ((bfd *, const DNR *, PTR));
|
||||
void (*swap_pdr_out) PARAMS ((bfd *, const PDR *, PTR));
|
||||
void (*swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR));
|
||||
void (*swap_opt_out) PARAMS ((bfd *, const OPTR *, PTR));
|
||||
void (*swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR));
|
||||
void (*swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR));
|
||||
void (*swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR));
|
||||
/* It so happens that the auxiliary type information has the same
|
||||
type and format for all known ECOFF targets. I don't see any
|
||||
reason that that should change, so at least for now the auxiliary
|
||||
swapping information is not in this table. */
|
||||
/* External reloc size. */
|
||||
bfd_size_type external_reloc_size;
|
||||
/* Reloc swapping functions. */
|
||||
void (*swap_reloc_in) PARAMS ((bfd *, PTR, struct internal_reloc *));
|
||||
void (*swap_reloc_out) PARAMS ((bfd *, const struct internal_reloc *, PTR));
|
||||
/* Backend reloc tweaking. */
|
||||
void (*finish_reloc) PARAMS ((bfd *, struct internal_reloc *, arelent *));
|
||||
};
|
||||
|
||||
/* This is the target specific information kept for ECOFF files. */
|
||||
|
||||
#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data)
|
||||
|
||||
typedef struct ecoff_tdata
|
||||
{
|
||||
/* The reloc file position, set by
|
||||
ecoff_compute_section_file_positions. */
|
||||
file_ptr reloc_filepos;
|
||||
|
||||
/* The symbol table file position, set by ecoff_mkobject_hook. */
|
||||
file_ptr sym_filepos;
|
||||
|
||||
/* The start and end of the text segment. Only valid for an
|
||||
existing file, not for one we are creating. */
|
||||
unsigned long text_start;
|
||||
unsigned long text_end;
|
||||
|
||||
/* The cached gp value. This is used when relocating. */
|
||||
bfd_vma gp;
|
||||
|
||||
/* The maximum size of objects to optimize using gp. This is
|
||||
typically set by the -G option to the compiler, assembler or
|
||||
linker. */
|
||||
int gp_size;
|
||||
|
||||
/* The register masks. When linking, all the masks found in the
|
||||
input files are combined into the masks of the output file.
|
||||
These are not all used for all targets, but that's OK, because
|
||||
the relevant ones are the only ones swapped in and out. */
|
||||
unsigned long gprmask;
|
||||
unsigned long fprmask;
|
||||
unsigned long cprmask[4];
|
||||
|
||||
/* The size of the unswapped ECOFF symbolic information. */
|
||||
bfd_size_type raw_size;
|
||||
|
||||
/* The unswapped ECOFF symbolic information. */
|
||||
PTR raw_syments;
|
||||
|
||||
/* The swapped ECOFF symbolic header. */
|
||||
HDRR symbolic_header;
|
||||
|
||||
/* Pointers to the unswapped symbolic information. */
|
||||
unsigned char *line;
|
||||
PTR external_dnr; /* struct dnr_ext */
|
||||
PTR external_pdr; /* struct pdr_ext */
|
||||
PTR external_sym; /* struct sym_ext */
|
||||
PTR external_opt; /* struct opt_ext */
|
||||
union aux_ext *external_aux;
|
||||
char *ss;
|
||||
char *ssext;
|
||||
PTR external_fdr; /* struct fdr_ext */
|
||||
PTR external_rfd; /* struct rfd_ext */
|
||||
PTR external_ext; /* struct ext_ext */
|
||||
|
||||
/* The swapped FDR information. */
|
||||
FDR *fdr;
|
||||
|
||||
/* The FDR index. This is set for an input BFD to a link so that
|
||||
the external symbols can set their FDR index correctly. */
|
||||
unsigned int ifdbase;
|
||||
|
||||
/* The canonical BFD symbols. */
|
||||
struct ecoff_symbol_struct *canonical_symbols;
|
||||
|
||||
} ecoff_data_type;
|
||||
|
||||
/* Each canonical asymbol really looks like this. */
|
||||
|
||||
typedef struct ecoff_symbol_struct
|
||||
{
|
||||
/* The actual symbol which the rest of BFD works with */
|
||||
asymbol symbol;
|
||||
|
||||
/* The fdr for this symbol. */
|
||||
FDR *fdr;
|
||||
|
||||
/* true if this is a local symbol rather than an external one. */
|
||||
boolean local;
|
||||
|
||||
/* A pointer to the unswapped hidden information for this symbol.
|
||||
This is either a struct sym_ext or a struct ext_ext, depending on
|
||||
the value of the local field above. */
|
||||
PTR native;
|
||||
} ecoff_symbol_type;
|
||||
|
||||
/* We take the address of the first element of a asymbol to ensure that the
|
||||
macro is only ever applied to an asymbol. */
|
||||
#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd)))
|
||||
|
||||
/* This is a hack borrowed from coffcode.h; we need to save the index
|
||||
of an external symbol when we write it out so that can set the
|
||||
symbol index correctly when we write out the relocs. */
|
||||
#define ecoff_get_sym_index(symbol) ((unsigned long) (symbol)->udata)
|
||||
#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata = (PTR) (idx))
|
||||
|
||||
/* Make an ECOFF object. */
|
||||
extern boolean ecoff_mkobject PARAMS ((bfd *));
|
||||
|
||||
/* Read in the ECOFF symbolic debugging information. */
|
||||
extern boolean ecoff_slurp_symbolic_info PARAMS ((bfd *));
|
||||
|
||||
/* Generic ECOFF BFD backend vectors. */
|
||||
extern asymbol *ecoff_make_empty_symbol PARAMS ((bfd *abfd));
|
||||
extern unsigned int ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd));
|
||||
extern unsigned int ecoff_get_symtab PARAMS ((bfd *abfd,
|
||||
asymbol **alocation));
|
||||
extern void ecoff_get_symbol_info PARAMS ((bfd *abfd,
|
||||
asymbol *symbol,
|
||||
symbol_info *ret));
|
||||
extern void ecoff_print_symbol PARAMS ((bfd *abfd, PTR filep,
|
||||
asymbol *symbol,
|
||||
bfd_print_symbol_type how));
|
||||
extern unsigned int ecoff_canonicalize_reloc PARAMS ((bfd *abfd,
|
||||
asection *section,
|
||||
arelent **relptr,
|
||||
asymbol **symbols));
|
||||
extern boolean ecoff_find_nearest_line PARAMS ((bfd *abfd,
|
||||
asection *section,
|
||||
asymbol **symbols,
|
||||
bfd_vma offset,
|
||||
CONST char **filename_ptr,
|
||||
CONST char **fnname_ptr,
|
||||
unsigned int *retline_ptr));
|
||||
extern boolean ecoff_bfd_seclet_link PARAMS ((bfd *abfd, PTR data,
|
||||
boolean relocateable));
|
||||
extern boolean ecoff_set_arch_mach PARAMS ((bfd *abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long machine));
|
||||
extern int ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
|
||||
extern boolean ecoff_set_section_contents PARAMS ((bfd *abfd,
|
||||
asection *section,
|
||||
PTR location,
|
||||
file_ptr offset,
|
||||
bfd_size_type count));
|
||||
extern boolean ecoff_get_section_contents PARAMS ((bfd *abfd,
|
||||
asection *section,
|
||||
PTR location,
|
||||
file_ptr offset,
|
||||
bfd_size_type count));
|
||||
extern boolean ecoff_write_object_contents PARAMS ((bfd *abfd));
|
||||
extern boolean ecoff_slurp_armap PARAMS ((bfd *abfd));
|
||||
extern boolean ecoff_write_armap PARAMS ((bfd *abfd, unsigned int elength,
|
||||
struct orl *map,
|
||||
unsigned int orl_count,
|
||||
int stridx));
|
||||
#define ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table
|
||||
extern bfd_target *ecoff_archive_p PARAMS ((bfd *abfd));
|
||||
#define ecoff_get_lineno \
|
||||
((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
|
||||
#define ecoff_truncate_arname bfd_dont_truncate_arname
|
||||
#define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound
|
||||
#define ecoff_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
#define ecoff_bfd_debug_info_start bfd_void
|
||||
#define ecoff_bfd_debug_info_end bfd_void
|
||||
#define ecoff_bfd_debug_info_accumulate \
|
||||
((void (*) PARAMS ((bfd *, struct sec *))) bfd_void)
|
||||
#define ecoff_bfd_get_relocated_section_contents \
|
||||
bfd_generic_get_relocated_section_contents
|
||||
#define ecoff_bfd_relax_section bfd_generic_relax_section
|
||||
#define ecoff_bfd_make_debug_symbol \
|
||||
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
|
||||
|
||||
/* Hook functions for the generic COFF section reading code. */
|
||||
extern PTR ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
|
||||
extern asection *ecoff_make_section_hook PARAMS ((bfd *abfd, char *name));
|
||||
extern boolean ecoff_new_section_hook PARAMS ((bfd *abfd,
|
||||
asection *section));
|
||||
#define ecoff_set_alignment_hook \
|
||||
((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
|
||||
extern boolean ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
|
||||
extern long ecoff_sec_to_styp_flags PARAMS ((CONST char *name,
|
||||
flagword flags));
|
||||
extern flagword ecoff_styp_to_sec_flags PARAMS ((bfd *abfd, PTR hdr));
|
||||
extern boolean ecoff_slurp_symbol_table PARAMS ((bfd *abfd));
|
|
@ -0,0 +1,252 @@
|
|||
/* BFD back-end data structures for ELF files.
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: libelf.h,v 1.1 1994/01/28 12:38:01 pk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _LIBELF_H_
|
||||
#define _LIBELF_H_ 1
|
||||
|
||||
#include "elf/common.h"
|
||||
#include "elf/internal.h"
|
||||
#include "elf/external.h"
|
||||
|
||||
/* If size isn't specified as 64 or 32, NAME macro should fail. */
|
||||
#ifndef NAME
|
||||
#if ARCH_SIZE==64
|
||||
#define NAME(x,y) CAT4(x,64,_,y)
|
||||
#endif
|
||||
#if ARCH_SIZE==32
|
||||
#define NAME(x,y) CAT4(x,32,_,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NAME
|
||||
#define NAME(x,y) CAT4(x,NOSIZE,_,y)
|
||||
#endif
|
||||
|
||||
#define ElfNAME(X) NAME(Elf,X)
|
||||
#define elfNAME(X) NAME(elf,X)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
asymbol symbol;
|
||||
Elf_Internal_Sym internal_elf_sym;
|
||||
union
|
||||
{
|
||||
unsigned int hppa_arg_reloc;
|
||||
PTR any;
|
||||
}
|
||||
tc_data;
|
||||
} elf_symbol_type;
|
||||
|
||||
struct elf_backend_data
|
||||
{
|
||||
int use_rela_p;
|
||||
int elf_64_p;
|
||||
enum bfd_architecture arch;
|
||||
void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
|
||||
Elf_Internal_Rela *));
|
||||
void (*elf_info_to_howto_rel) PARAMS ((bfd *, arelent *,
|
||||
Elf_Internal_Rel *));
|
||||
bfd_vma maxpagesize;
|
||||
void (*write_relocs) PARAMS ((bfd *, asection *, PTR));
|
||||
|
||||
void (*elf_backend_symbol_processing) PARAMS ((bfd *, asymbol *));
|
||||
boolean (*elf_backend_symbol_table_processing) PARAMS ((bfd *, elf_symbol_type *, int));
|
||||
boolean (*elf_backend_section_processing) PARAMS ((bfd *, Elf32_Internal_Shdr *));
|
||||
boolean (*elf_backend_section_from_shdr) PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
|
||||
boolean (*elf_backend_fake_sections) PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
|
||||
boolean (*elf_backend_section_from_bfd_section) PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));
|
||||
};
|
||||
|
||||
struct elf_sym_extra
|
||||
{
|
||||
int elf_sym_num; /* sym# after locals/globals are reordered */
|
||||
};
|
||||
|
||||
typedef struct elf_sym_extra Elf_Sym_Extra;
|
||||
|
||||
struct bfd_elf_arch_map {
|
||||
enum bfd_architecture bfd_arch;
|
||||
int elf_arch;
|
||||
};
|
||||
|
||||
extern const struct bfd_elf_arch_map bfd_elf_arch_map[];
|
||||
extern const int bfd_elf_arch_map_size;
|
||||
|
||||
struct bfd_elf_section_data {
|
||||
Elf_Internal_Shdr this_hdr;
|
||||
Elf_Internal_Shdr rel_hdr;
|
||||
int this_idx, rel_idx;
|
||||
};
|
||||
#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd)
|
||||
#define shdr_name(abfd,shdr) (elf_shstrtab (abfd)->tab + (shdr)->sh_name)
|
||||
|
||||
#define get_elf_backend_data(abfd) \
|
||||
((struct elf_backend_data *) (abfd)->xvec->backend_data)
|
||||
|
||||
struct strtab
|
||||
{
|
||||
char *tab;
|
||||
int nentries;
|
||||
int length;
|
||||
};
|
||||
|
||||
/* Some private data is stashed away for future use using the tdata pointer
|
||||
in the bfd structure. */
|
||||
|
||||
struct elf_obj_tdata
|
||||
{
|
||||
Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */
|
||||
Elf_Internal_Shdr **elf_sect_ptr;
|
||||
Elf_Internal_Phdr *phdr;
|
||||
struct strtab *strtab_ptr;
|
||||
int num_locals;
|
||||
int num_globals;
|
||||
Elf_Internal_Sym *internal_syms;
|
||||
elf_symbol_type *symbols; /* elf_symbol_type */
|
||||
Elf_Sym_Extra *sym_extra;
|
||||
asymbol **section_syms; /* STT_SECTION symbols for each section */
|
||||
int num_section_syms; /* number of section_syms allocated */
|
||||
Elf_Internal_Shdr symtab_hdr;
|
||||
Elf_Internal_Shdr shstrtab_hdr;
|
||||
Elf_Internal_Shdr strtab_hdr;
|
||||
int symtab_section, shstrtab_section, strtab_section;
|
||||
file_ptr next_file_pos;
|
||||
void *prstatus; /* The raw /proc prstatus structure */
|
||||
void *prpsinfo; /* The raw /proc prpsinfo structure */
|
||||
bfd_vma gp; /* The gp value (MIPS only, for now) */
|
||||
int gp_size; /* The gp size (MIPS only, for now) */
|
||||
};
|
||||
|
||||
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
|
||||
#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
|
||||
#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
|
||||
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr)
|
||||
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
|
||||
#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals)
|
||||
#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals)
|
||||
#define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra)
|
||||
#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms)
|
||||
#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
|
||||
#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
|
||||
#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
|
||||
#define obj_symbols(bfd) (elf_tdata(bfd) -> symbols)
|
||||
#define obj_internal_syms(bfd) (elf_tdata(bfd) -> internal_syms)
|
||||
#define elf_gp(bfd) (elf_tdata(bfd) -> gp)
|
||||
#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size)
|
||||
|
||||
extern char * elf_string_from_elf_section PARAMS ((bfd *, unsigned, unsigned));
|
||||
extern char * elf_get_str_section PARAMS ((bfd *, unsigned));
|
||||
|
||||
#define bfd_elf32_mkobject bfd_elf_mkobject
|
||||
#define bfd_elf64_mkobject bfd_elf_mkobject
|
||||
#define elf_mkobject bfd_elf_mkobject
|
||||
|
||||
extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *));
|
||||
|
||||
extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
|
||||
arelent *,
|
||||
asymbol *,
|
||||
PTR,
|
||||
asection *,
|
||||
bfd *));
|
||||
extern boolean bfd_elf_mkobject PARAMS ((bfd *));
|
||||
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
|
||||
|
||||
extern boolean bfd_elf32_write_object_contents PARAMS ((bfd *));
|
||||
extern boolean bfd_elf64_write_object_contents PARAMS ((bfd *));
|
||||
|
||||
extern bfd_target *bfd_elf32_object_p PARAMS ((bfd *));
|
||||
extern bfd_target *bfd_elf32_core_file_p PARAMS ((bfd *));
|
||||
extern char *bfd_elf32_core_file_failing_command PARAMS ((bfd *));
|
||||
extern int bfd_elf32_core_file_failing_signal PARAMS ((bfd *));
|
||||
extern boolean bfd_elf32_core_file_matches_executable_p PARAMS ((bfd *,
|
||||
bfd *));
|
||||
extern boolean bfd_elf32_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
|
||||
file_ptr,
|
||||
bfd_size_type));
|
||||
|
||||
extern unsigned int bfd_elf32_get_symtab_upper_bound PARAMS ((bfd *));
|
||||
extern unsigned int bfd_elf32_get_symtab PARAMS ((bfd *, asymbol **));
|
||||
extern unsigned int bfd_elf32_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
|
||||
extern unsigned int bfd_elf32_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
|
||||
arelent **,
|
||||
asymbol **));
|
||||
extern asymbol *bfd_elf32_make_empty_symbol PARAMS ((bfd *));
|
||||
extern void bfd_elf32_print_symbol PARAMS ((bfd *, PTR, asymbol *,
|
||||
bfd_print_symbol_type));
|
||||
extern void bfd_elf32_get_symbol_info PARAMS ((bfd *, asymbol *,
|
||||
symbol_info *));
|
||||
extern alent *bfd_elf32_get_lineno PARAMS ((bfd *, asymbol *));
|
||||
extern boolean bfd_elf32_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
|
||||
unsigned long));
|
||||
extern boolean bfd_elf32_find_nearest_line PARAMS ((bfd *, asection *,
|
||||
asymbol **,
|
||||
bfd_vma, CONST char **,
|
||||
CONST char **,
|
||||
unsigned int *));
|
||||
extern int bfd_elf32_sizeof_headers PARAMS ((bfd *, boolean));
|
||||
extern void bfd_elf32__write_relocs PARAMS ((bfd *, asection *, PTR));
|
||||
extern boolean bfd_elf32_new_section_hook PARAMS ((bfd *, asection *));
|
||||
|
||||
/* If the target doesn't have reloc handling written yet: */
|
||||
extern void bfd_elf32_no_info_to_howto PARAMS ((bfd *, arelent *,
|
||||
Elf32_Internal_Rela *));
|
||||
|
||||
extern bfd_target *bfd_elf64_object_p PARAMS ((bfd *));
|
||||
extern bfd_target *bfd_elf64_core_file_p PARAMS ((bfd *));
|
||||
extern char *bfd_elf64_core_file_failing_command PARAMS ((bfd *));
|
||||
extern int bfd_elf64_core_file_failing_signal PARAMS ((bfd *));
|
||||
extern boolean bfd_elf64_core_file_matches_executable_p PARAMS ((bfd *,
|
||||
bfd *));
|
||||
extern boolean bfd_elf64_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
|
||||
file_ptr,
|
||||
bfd_size_type));
|
||||
|
||||
extern unsigned int bfd_elf64_get_symtab_upper_bound PARAMS ((bfd *));
|
||||
extern unsigned int bfd_elf64_get_symtab PARAMS ((bfd *, asymbol **));
|
||||
extern unsigned int bfd_elf64_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
|
||||
extern unsigned int bfd_elf64_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
|
||||
arelent **,
|
||||
asymbol **));
|
||||
extern asymbol *bfd_elf64_make_empty_symbol PARAMS ((bfd *));
|
||||
extern void bfd_elf64_print_symbol PARAMS ((bfd *, PTR, asymbol *,
|
||||
bfd_print_symbol_type));
|
||||
extern void bfd_elf64_get_symbol_info PARAMS ((bfd *, asymbol *,
|
||||
symbol_info *));
|
||||
extern alent *bfd_elf64_get_lineno PARAMS ((bfd *, asymbol *));
|
||||
extern boolean bfd_elf64_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
|
||||
unsigned long));
|
||||
extern boolean bfd_elf64_find_nearest_line PARAMS ((bfd *, asection *,
|
||||
asymbol **,
|
||||
bfd_vma, CONST char **,
|
||||
CONST char **,
|
||||
unsigned int *));
|
||||
extern int bfd_elf64_sizeof_headers PARAMS ((bfd *, boolean));
|
||||
extern void bfd_elf64__write_relocs PARAMS ((bfd *, asection *, PTR));
|
||||
extern boolean bfd_elf64_new_section_hook PARAMS ((bfd *, asection *));
|
||||
|
||||
/* If the target doesn't have reloc handling written yet: */
|
||||
extern void bfd_elf64_no_info_to_howto PARAMS ((bfd *, arelent *,
|
||||
Elf64_Internal_Rela *));
|
||||
|
||||
#endif /* _LIBELF_H_ */
|
|
@ -0,0 +1,55 @@
|
|||
/* $Id: netbsd.h,v 1.1 1994/01/28 12:38:02 pk Exp $ */
|
||||
|
||||
/* ZMAGIC files never have the header in the text. */
|
||||
#define N_HEADER_IN_TEXT(x) 0
|
||||
|
||||
/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */
|
||||
#define TEXT_START_ADDR 0
|
||||
|
||||
#define N_MAGIC(ex) \
|
||||
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : ((ex).a_info))
|
||||
#define N_MACHTYPE(ex) \
|
||||
( (((ex).a_info)&0xffff0000) ? ((ntohl(((ex).a_info))>>16)&0x03ff) : 0 )
|
||||
# define N_FLAGS(ex) \
|
||||
( (((ex).a_info)&0xffff0000) ? ((ntohl(((ex).a_info))>>26)&0x3f) : 0 )
|
||||
#define N_SET_INFO(ex, mag,mid,flag) \
|
||||
( (ex).a_info = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \
|
||||
(((mag)&0xffff)) ) )
|
||||
#define N_SET_MAGIC(exec,magic) \
|
||||
((exec).a_info = (((exec).a_info & ~0xffff) | ((magic) & 0xffff)))
|
||||
#define N_SET_MACHTYPE(exec,machtype) \
|
||||
((exec).a_info = \
|
||||
(((exec).a_info & ~(0x3ff<<16)) | (((machtype)&0xff) << 16)))
|
||||
#define N_SET_FLAGS(exec, flags) \
|
||||
((exec).a_info = ((exec).a_info & 0xffff) | (flags & 0xffff))
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "libaout.h"
|
||||
|
||||
#define N_GETMAGIC(ex) \
|
||||
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : ((ex).a_info))
|
||||
#define N_GETMAGIC2(ex) \
|
||||
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : \
|
||||
(((ex).a_info) | 0x10000) )
|
||||
|
||||
#define N_TXTADDR(ex) (N_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)
|
||||
#define N_TXTOFF(ex) \
|
||||
( N_GETMAGIC2(ex)==ZMAGIC || N_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
|
||||
0 : (N_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : EXEC_BYTES_SIZE ))
|
||||
#define N_ALIGN(ex,x) \
|
||||
(N_MAGIC(ex) == ZMAGIC || N_MAGIC(ex) == QMAGIC ? \
|
||||
((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x))
|
||||
#define N_DATADDR(ex) \
|
||||
(N_GETMAGIC(ex) == OMAGIC ? N_TXTADDR(ex) + (ex).a_text : \
|
||||
(N_TXTADDR(ex) + (ex).a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1))
|
||||
|
||||
/* Data segment offset. */
|
||||
#define N_DATOFF(ex) \
|
||||
N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text)
|
||||
|
||||
#define NO_SWAP_MAGIC /* magic number already in correct endian format */
|
||||
|
||||
#include "aout-target.h"
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
/* opncls.c -- open and close a BFD.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: opncls.c,v 1.1 1994/01/28 12:38:03 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "obstack.h"
|
||||
extern void bfd_cache_init PARAMS ((bfd *));
|
||||
FILE *bfd_open_file PARAMS ((bfd *));
|
||||
|
||||
/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
|
||||
if we do that we can't use fcntl. */
|
||||
|
||||
|
||||
#define obstack_chunk_alloc bfd_xmalloc_by_size_t
|
||||
#define obstack_chunk_free free
|
||||
|
||||
/* Return a new BFD. All BFD's are allocated through this routine. */
|
||||
|
||||
bfd *
|
||||
new_bfd PARAMS ((void))
|
||||
{
|
||||
bfd *nbfd;
|
||||
|
||||
nbfd = (bfd *)zalloc (sizeof (bfd));
|
||||
if (!nbfd)
|
||||
return 0;
|
||||
|
||||
bfd_check_init();
|
||||
obstack_begin((PTR)&nbfd->memory, 128);
|
||||
|
||||
nbfd->arch_info = &bfd_default_arch_struct;
|
||||
|
||||
nbfd->direction = no_direction;
|
||||
nbfd->iostream = NULL;
|
||||
nbfd->where = 0;
|
||||
nbfd->sections = (asection *)NULL;
|
||||
nbfd->format = bfd_unknown;
|
||||
nbfd->my_archive = (bfd *)NULL;
|
||||
nbfd->origin = 0;
|
||||
nbfd->opened_once = false;
|
||||
nbfd->output_has_begun = false;
|
||||
nbfd->section_count = 0;
|
||||
nbfd->usrdata = (PTR)NULL;
|
||||
nbfd->cacheable = false;
|
||||
nbfd->flags = NO_FLAGS;
|
||||
nbfd->mtime_set = false;
|
||||
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/* Allocate a new BFD as a member of archive OBFD. */
|
||||
|
||||
bfd *
|
||||
new_bfd_contained_in (obfd)
|
||||
bfd *obfd;
|
||||
{
|
||||
bfd *nbfd;
|
||||
|
||||
nbfd = new_bfd();
|
||||
nbfd->xvec = obfd->xvec;
|
||||
nbfd->my_archive = obfd;
|
||||
nbfd->direction = read_direction;
|
||||
nbfd->target_defaulted = obfd->target_defaulted;
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Opening and Closing BFDs
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_openr
|
||||
|
||||
SYNOPSIS
|
||||
bfd *bfd_openr(CONST char *filename, CONST char*target);
|
||||
|
||||
DESCRIPTION
|
||||
This function opens the file supplied (using <<fopen>>) with the target
|
||||
supplied, it returns a pointer to the created BFD.
|
||||
|
||||
If NULL is returned then an error has occured. Possible errors
|
||||
are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_openr, (filename, target),
|
||||
CONST char *filename AND
|
||||
CONST char *target)
|
||||
{
|
||||
bfd *nbfd;
|
||||
bfd_target *target_vec;
|
||||
|
||||
nbfd = new_bfd();
|
||||
if (nbfd == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) {
|
||||
bfd_error = invalid_target;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nbfd->filename = filename;
|
||||
nbfd->direction = read_direction;
|
||||
|
||||
if (bfd_open_file (nbfd) == NULL) {
|
||||
bfd_error = system_call_error; /* File didn't exist, or some such */
|
||||
bfd_release(nbfd,0);
|
||||
return NULL;
|
||||
}
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
|
||||
/* Don't try to `optimize' this function:
|
||||
|
||||
o - We lock using stack space so that interrupting the locking
|
||||
won't cause a storage leak.
|
||||
o - We open the file stream last, since we don't want to have to
|
||||
close it if anything goes wrong. Closing the stream means closing
|
||||
the file descriptor too, even though we didn't open it.
|
||||
*/
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_fdopenr
|
||||
|
||||
SYNOPSIS
|
||||
bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
|
||||
|
||||
DESCRIPTION
|
||||
bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen.
|
||||
It opens a BFD on a file already described by the @var{fd}
|
||||
supplied.
|
||||
|
||||
When the file is later bfd_closed, the file descriptor will be closed.
|
||||
|
||||
If the caller desires that this file descriptor be cached by BFD
|
||||
(opened as needed, closed as needed to free descriptors for
|
||||
other opens), with the supplied @var{fd} used as an initial
|
||||
file descriptor (but subject to closure at any time), set
|
||||
bfd->cacheable nonzero in the returned BFD. The default is to
|
||||
assume no cacheing; the file descriptor will remain open until
|
||||
bfd_close, and will not be affected by BFD operations on other
|
||||
files.
|
||||
|
||||
Possible errors are no_memory, invalid_target and system_call
|
||||
error.
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_fdopenr,(filename, target, fd),
|
||||
CONST char *filename AND
|
||||
CONST char *target AND
|
||||
int fd)
|
||||
{
|
||||
bfd *nbfd;
|
||||
bfd_target *target_vec;
|
||||
int fdflags;
|
||||
|
||||
bfd_error = system_call_error;
|
||||
|
||||
#ifdef NO_FCNTL
|
||||
fdflags = O_RDWR; /* Assume full access */
|
||||
#else
|
||||
fdflags = fcntl (fd, F_GETFL, NULL);
|
||||
#endif
|
||||
if (fdflags == -1) return NULL;
|
||||
|
||||
nbfd = new_bfd();
|
||||
|
||||
if (nbfd == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) {
|
||||
bfd_error = invalid_target;
|
||||
return NULL;
|
||||
}
|
||||
#if defined(VMS) || defined(__GO32__)
|
||||
nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
|
||||
#else
|
||||
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
|
||||
switch (fdflags & (O_ACCMODE)) {
|
||||
case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
|
||||
case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
|
||||
case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
|
||||
default: abort ();
|
||||
}
|
||||
#endif
|
||||
if (nbfd->iostream == NULL) {
|
||||
(void) obstack_free (&nbfd->memory, (PTR)0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* OK, put everything where it belongs */
|
||||
|
||||
nbfd->filename = filename;
|
||||
|
||||
/* As a special case we allow a FD open for read/write to
|
||||
be written through, although doing so requires that we end
|
||||
the previous clause with a preposition. */
|
||||
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
|
||||
switch (fdflags & (O_ACCMODE)) {
|
||||
case O_RDONLY: nbfd->direction = read_direction; break;
|
||||
case O_WRONLY: nbfd->direction = write_direction; break;
|
||||
case O_RDWR: nbfd->direction = both_direction; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
bfd_cache_init (nbfd);
|
||||
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/** bfd_openw -- open for writing.
|
||||
Returns a pointer to a freshly-allocated BFD on success, or NULL.
|
||||
|
||||
See comment by bfd_fdopenr before you try to modify this function. */
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_openw
|
||||
|
||||
SYNOPSIS
|
||||
bfd *bfd_openw(CONST char *filename, CONST char *target);
|
||||
|
||||
DESCRIPTION
|
||||
Creates a BFD, associated with file @var{filename}, using the
|
||||
file format @var{target}, and returns a pointer to it.
|
||||
|
||||
Possible errors are system_call_error, no_memory,
|
||||
invalid_target.
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_openw,(filename, target),
|
||||
CONST char *filename AND
|
||||
CONST char *target)
|
||||
{
|
||||
bfd *nbfd;
|
||||
bfd_target *target_vec;
|
||||
|
||||
bfd_error = system_call_error;
|
||||
|
||||
/* nbfd has to point to head of malloc'ed block so that bfd_close may
|
||||
reclaim it correctly. */
|
||||
|
||||
nbfd = new_bfd();
|
||||
if (nbfd == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) return NULL;
|
||||
|
||||
nbfd->filename = filename;
|
||||
nbfd->direction = write_direction;
|
||||
|
||||
if (bfd_open_file (nbfd) == NULL) {
|
||||
bfd_error = system_call_error; /* File not writeable, etc */
|
||||
(void) obstack_free (&nbfd->memory, (PTR)0);
|
||||
return NULL;
|
||||
}
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
FUNCTION
|
||||
bfd_close
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_close(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This function closes a BFD. If the BFD was open for writing,
|
||||
then pending operations are completed and the file written out
|
||||
and closed. If the created file is executable, then
|
||||
<<chmod>> is called to mark it as such.
|
||||
|
||||
All memory attached to the BFD's obstacks is released.
|
||||
|
||||
The file descriptor associated with the BFD is closed (even
|
||||
if it was passed in to BFD by bfd_fdopenr).
|
||||
|
||||
RETURNS
|
||||
<<true>> is returned if all is ok, otherwise <<false>>.
|
||||
*/
|
||||
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_close,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
boolean ret;
|
||||
|
||||
if (!bfd_read_p(abfd))
|
||||
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
|
||||
return false;
|
||||
|
||||
if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
|
||||
|
||||
ret = bfd_cache_close(abfd);
|
||||
|
||||
/* If the file was open for writing and is now executable,
|
||||
make it so */
|
||||
if (ret == true
|
||||
&& abfd->direction == write_direction
|
||||
&& abfd->flags & EXEC_P) {
|
||||
struct stat buf;
|
||||
stat(abfd->filename, &buf);
|
||||
#ifndef S_IXUSR
|
||||
#define S_IXUSR 0100 /* Execute by owner. */
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
#define S_IXGRP 0010 /* Execute by group. */
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
#define S_IXOTH 0001 /* Execute by others. */
|
||||
#endif
|
||||
|
||||
chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
|
||||
}
|
||||
(void) obstack_free (&abfd->memory, (PTR)0);
|
||||
(void) free(abfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_close_all_done
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_close_all_done(bfd *);
|
||||
|
||||
DESCRIPTION
|
||||
This function closes a BFD. It differs from <<bfd_close>>
|
||||
since it does not complete any pending operations. This
|
||||
routine would be used if the application had just used BFD for
|
||||
swapping and didn't want to use any of the writing code.
|
||||
|
||||
If the created file is executable, then <<chmod>> is called
|
||||
to mark it as such.
|
||||
|
||||
All memory attached to the BFD's obstacks is released.
|
||||
|
||||
RETURNS
|
||||
<<true>> is returned if all is ok, otherwise <<false>>.
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_close_all_done,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
boolean ret;
|
||||
|
||||
ret = bfd_cache_close(abfd);
|
||||
|
||||
/* If the file was open for writing and is now executable,
|
||||
make it so */
|
||||
if (ret == true
|
||||
&& abfd->direction == write_direction
|
||||
&& abfd->flags & EXEC_P) {
|
||||
struct stat buf;
|
||||
stat(abfd->filename, &buf);
|
||||
#ifndef S_IXUSR
|
||||
#define S_IXUSR 0100 /* Execute by owner. */
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
#define S_IXGRP 0010 /* Execute by group. */
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
#define S_IXOTH 0001 /* Execute by others. */
|
||||
#endif
|
||||
|
||||
chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
|
||||
}
|
||||
(void) obstack_free (&abfd->memory, (PTR)0);
|
||||
(void) free(abfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_alloc_size
|
||||
|
||||
SYNOPSIS
|
||||
bfd_size_type bfd_alloc_size(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return the number of bytes in the obstacks connected to the
|
||||
supplied BFD.
|
||||
|
||||
*/
|
||||
|
||||
bfd_size_type
|
||||
DEFUN(bfd_alloc_size,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
struct _obstack_chunk *chunk = abfd->memory.chunk;
|
||||
size_t size = 0;
|
||||
while (chunk) {
|
||||
size += chunk->limit - &(chunk->contents[0]);
|
||||
chunk = chunk->prev;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_create
|
||||
|
||||
SYNOPSIS
|
||||
bfd *bfd_create(CONST char *filename, bfd *templ);
|
||||
|
||||
DESCRIPTION
|
||||
This routine creates a new BFD in the manner of
|
||||
<<bfd_openw>>, but without opening a file. The new BFD
|
||||
takes the target from the target used by @var{template}. The
|
||||
format is always set to <<bfd_object>>.
|
||||
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_create,(filename, templ),
|
||||
CONST char *filename AND
|
||||
bfd *templ)
|
||||
{
|
||||
bfd *nbfd = new_bfd();
|
||||
if (nbfd == (bfd *)NULL) {
|
||||
bfd_error = no_memory;
|
||||
return (bfd *)NULL;
|
||||
}
|
||||
nbfd->filename = filename;
|
||||
if(templ) {
|
||||
nbfd->xvec = templ->xvec;
|
||||
}
|
||||
nbfd->direction = no_direction;
|
||||
bfd_set_format(nbfd, bfd_object);
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_alloc_by_size_t
|
||||
|
||||
SYNOPSIS
|
||||
PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
|
||||
|
||||
DESCRIPTION
|
||||
This function allocates a block of memory in the obstack
|
||||
attatched to <<abfd>> and returns a pointer to it.
|
||||
*/
|
||||
|
||||
|
||||
PTR
|
||||
DEFUN(bfd_alloc_by_size_t,(abfd, size),
|
||||
bfd *abfd AND
|
||||
size_t size)
|
||||
{
|
||||
PTR res = obstack_alloc(&(abfd->memory), size);
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
|
||||
bfd *abfd AND
|
||||
PTR ptr AND
|
||||
size_t size)
|
||||
{
|
||||
(void) obstack_grow(&(abfd->memory), ptr, size);
|
||||
}
|
||||
DEFUN(PTR bfd_alloc_finish,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return obstack_finish(&(abfd->memory));
|
||||
}
|
||||
|
||||
DEFUN(PTR bfd_alloc, (abfd, size),
|
||||
bfd *abfd AND
|
||||
size_t size)
|
||||
{
|
||||
return bfd_alloc_by_size_t(abfd, (size_t)size);
|
||||
}
|
||||
|
||||
DEFUN(PTR bfd_zalloc,(abfd, size),
|
||||
bfd *abfd AND
|
||||
size_t size)
|
||||
{
|
||||
PTR res;
|
||||
res = bfd_alloc(abfd, size);
|
||||
memset(res, 0, (size_t)size);
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFUN(PTR bfd_realloc,(abfd, old, size),
|
||||
bfd *abfd AND
|
||||
PTR old AND
|
||||
size_t size)
|
||||
{
|
||||
PTR res = bfd_alloc(abfd, size);
|
||||
memcpy(res, old, (size_t)size);
|
||||
return res;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,188 @@
|
|||
/* seclet.c
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: seclet.c,v 1.1 1994/01/28 12:38:06 pk Exp $
|
||||
*/
|
||||
|
||||
/* This module is part of BFD */
|
||||
|
||||
|
||||
/* The intention is that one day, all the code which uses sections
|
||||
will change and use seclets instead - maybe seglet would have been
|
||||
a better name..
|
||||
|
||||
Anyway, a seclet contains enough info to be able to describe an
|
||||
area of output memory in one go.
|
||||
|
||||
The only description so far catered for is that of the
|
||||
<<bfd_indirect_seclet>>, which is a select which points to a
|
||||
<<section>> and the <<asymbols>> associated with the section, so
|
||||
that relocation can be done when needed.
|
||||
|
||||
One day there will be more types - they will at least migrate from
|
||||
the linker's data structures - also there could be extra stuff,
|
||||
like a bss seclet, which descibes a lump of memory as containing
|
||||
zeros compactly, without the horrible SEC_* flag cruft.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "seclet.h"
|
||||
#include "coff/internal.h"
|
||||
|
||||
/* Create a new seclet and attach it to a section. */
|
||||
|
||||
bfd_seclet_type *
|
||||
DEFUN(bfd_new_seclet,(abfd, section),
|
||||
bfd *abfd AND
|
||||
asection *section)
|
||||
{
|
||||
bfd_seclet_type *n = (bfd_seclet_type *)bfd_alloc(abfd, sizeof(bfd_seclet_type));
|
||||
if (section->seclets_tail != (bfd_seclet_type *)NULL) {
|
||||
section->seclets_tail->next = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
section->seclets_head = n;
|
||||
}
|
||||
section->seclets_tail = n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Given an indirect seclet which points to an input section, relocate
|
||||
the contents of the seclet and put the data in its final
|
||||
destination. */
|
||||
|
||||
static boolean
|
||||
DEFUN(rel,(abfd, seclet, output_section, data, relocateable),
|
||||
bfd *abfd AND
|
||||
bfd_seclet_type *seclet AND
|
||||
asection *output_section AND
|
||||
PTR data AND
|
||||
boolean relocateable)
|
||||
{
|
||||
if ((output_section->flags & SEC_HAS_CONTENTS) != 0
|
||||
&& seclet->size)
|
||||
{
|
||||
data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data,
|
||||
relocateable);
|
||||
if(bfd_set_section_contents(abfd,
|
||||
output_section,
|
||||
data,
|
||||
seclet->offset,
|
||||
seclet->size) == false)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Put the contents of a seclet in its final destination. */
|
||||
|
||||
static boolean
|
||||
DEFUN(seclet_dump_seclet,(abfd, seclet, section, data, relocateable),
|
||||
bfd *abfd AND
|
||||
bfd_seclet_type *seclet AND
|
||||
asection *section AND
|
||||
PTR data AND
|
||||
boolean relocateable)
|
||||
{
|
||||
switch (seclet->type)
|
||||
{
|
||||
case bfd_indirect_seclet:
|
||||
/* The contents of this section come from another one somewhere
|
||||
else */
|
||||
return rel(abfd, seclet, section, data, relocateable);
|
||||
|
||||
case bfd_fill_seclet:
|
||||
/* Fill in the section with us */
|
||||
{
|
||||
char *d = bfd_xmalloc(seclet->size);
|
||||
unsigned int i;
|
||||
for (i =0; i < seclet->size; i+=2) {
|
||||
d[i] = seclet->u.fill.value >> 8;
|
||||
}
|
||||
for (i = 1; i < seclet->size; i+=2) {
|
||||
d[i] = seclet->u.fill.value ;
|
||||
}
|
||||
/* Don't bother to fill in empty sections */
|
||||
if (!(bfd_get_section_flags(abfd, section) & SEC_HAS_CONTENTS))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return bfd_set_section_contents(abfd, section, d, seclet->offset,
|
||||
seclet->size);
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_generic_seclet_link
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_generic_seclet_link
|
||||
(bfd *abfd,
|
||||
PTR data,
|
||||
boolean relocateable);
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
The generic seclet linking routine. The caller should have
|
||||
set up seclets for all the output sections. The DATA argument
|
||||
should point to a memory area large enough to hold the largest
|
||||
section. This function looks through the seclets and moves
|
||||
the contents into the output sections. If RELOCATEABLE is
|
||||
true, the orelocation fields of the output sections must
|
||||
already be initialized.
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_generic_seclet_link,(abfd, data, relocateable),
|
||||
bfd *abfd AND
|
||||
PTR data AND
|
||||
boolean relocateable)
|
||||
{
|
||||
asection *o = abfd->sections;
|
||||
while (o != (asection *)NULL)
|
||||
{
|
||||
bfd_seclet_type *p = o->seclets_head;
|
||||
while (p != (bfd_seclet_type *)NULL)
|
||||
{
|
||||
if (seclet_dump_seclet(abfd, p, o, data, relocateable) == false)
|
||||
return false;
|
||||
p = p ->next;
|
||||
}
|
||||
o = o->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* Definitions of little sections (seclets) for BFD.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
Hacked by Steve Chamberlain of Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: seclet.h,v 1.1 1994/01/28 12:38:07 pk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SECLET_H
|
||||
#define _SECLET_H
|
||||
|
||||
enum bfd_seclet_enum
|
||||
{
|
||||
bfd_indirect_seclet,
|
||||
bfd_fill_seclet
|
||||
};
|
||||
|
||||
struct bfd_seclet
|
||||
{
|
||||
struct bfd_seclet *next;
|
||||
enum bfd_seclet_enum type;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
asection *section;
|
||||
asymbol **symbols;
|
||||
} indirect;
|
||||
struct {
|
||||
int value;
|
||||
} fill;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
typedef struct bfd_seclet bfd_seclet_type;
|
||||
|
||||
bfd_seclet_type *
|
||||
bfd_new_seclet PARAMS ((bfd *, asection *));
|
||||
|
||||
#endif
|
|
@ -0,0 +1,902 @@
|
|||
/* Object file "section" support for the BFD library.
|
||||
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: section.c,v 1.1 1994/01/28 12:38:08 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Sections
|
||||
|
||||
Sections are supported in BFD in <<section.c>>.
|
||||
|
||||
The raw data contained within a BFD is maintained through the
|
||||
section abstraction. A single BFD may have any number of
|
||||
sections, and keeps hold of them by pointing to the first,
|
||||
each one points to the next in the list.
|
||||
|
||||
@menu
|
||||
@* Section Input::
|
||||
@* Section Output::
|
||||
@* typedef asection::
|
||||
@* section prototypes::
|
||||
@end menu
|
||||
|
||||
INODE
|
||||
Section Input, Section Output, Sections, Sections
|
||||
SUBSECTION
|
||||
Section Input
|
||||
|
||||
When a BFD is opened for reading, the section structures are
|
||||
created and attached to the BFD.
|
||||
|
||||
Each section has a name which describes the section in the
|
||||
outside world - for example, <<a.out>> would contain at least
|
||||
three sections, called <<.text>>, <<.data>> and <<.bss>>.
|
||||
|
||||
Names need not be unique; for example a COFF file may have several
|
||||
sections named .data.
|
||||
|
||||
Sometimes a BFD will contain more than the 'natural' number of
|
||||
sections. A back end may attach other sections containing
|
||||
constructor data, or an application may add a section (using
|
||||
bfd_make_section) to the sections attached to an already open
|
||||
BFD. For example, the linker creates a supernumary section
|
||||
<<COMMON>> for each input file's BFD to hold information about
|
||||
common storage.
|
||||
|
||||
The raw data is not necessarily read in at the same time as
|
||||
the section descriptor is created. Some targets may leave the
|
||||
data in place until a <<bfd_get_section_contents>> call is
|
||||
made. Other back ends may read in all the data at once - For
|
||||
example; an S-record file has to be read once to determine the
|
||||
size of the data. An IEEE-695 file doesn't contain raw data in
|
||||
sections, but data and relocation expressions intermixed, so
|
||||
the data area has to be parsed to get out the data and
|
||||
relocations.
|
||||
|
||||
INODE
|
||||
Section Output, typedef asection, Section Input, Sections
|
||||
|
||||
SUBSECTION
|
||||
Section Output
|
||||
|
||||
To write a new object style BFD, the various sections to be
|
||||
written have to be created. They are attached to the BFD in
|
||||
the same way as input sections, data is written to the
|
||||
sections using <<bfd_set_section_contents>>.
|
||||
|
||||
Any program that creates or combines sections (e.g., the assembler
|
||||
and linker) must use the fields <<output_section>> and
|
||||
<<output_offset>> to indicate the file sections to which each
|
||||
section must be written. (If the section is being created from
|
||||
scratch, <<output_section>> should probably point to the section
|
||||
itself, and <<output_offset>> should probably be zero.)
|
||||
|
||||
The data to be written comes from input sections attached to
|
||||
the output sections. The output section structure can be
|
||||
considered a filter for the input section, the output section
|
||||
determines the vma of the output data and the name, but the
|
||||
input section determines the offset into the output section of
|
||||
the data to be written.
|
||||
|
||||
E.g., to create a section "O", starting at 0x100, 0x123 long,
|
||||
containing two subsections, "A" at offset 0x0 (ie at vma
|
||||
0x100) and "B" at offset 0x20 (ie at vma 0x120) the structures
|
||||
would look like:
|
||||
|
||||
| section name "A"
|
||||
| output_offset 0x00
|
||||
| size 0x20
|
||||
| output_section -----------> section name "O"
|
||||
| | vma 0x100
|
||||
| section name "B" | size 0x123
|
||||
| output_offset 0x20 |
|
||||
| size 0x103 |
|
||||
| output_section --------|
|
||||
|
||||
|
||||
SUBSECTION
|
||||
Seglets
|
||||
|
||||
The data within a section is stored in a <<seglet>>. These
|
||||
are much like the fixups in <<gas>>. The seglet abstraction
|
||||
allows the a section to grow and shrink within itself.
|
||||
|
||||
A seglet knows how big it is, and which is the next seglet and
|
||||
where the raw data for it is, and also points to a list of
|
||||
relocations which apply to it.
|
||||
|
||||
The seglet is used by the linker to perform relaxing on final
|
||||
code. The application creates code which is as big as
|
||||
necessary to make it work without relaxing, and the user can
|
||||
select whether to relax. Sometimes relaxing takes a lot of
|
||||
time. The linker runs around the relocations to see if any
|
||||
are attached to data which can be shrunk, if so it does it on
|
||||
a seglet by seglet basis.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
|
||||
/*
|
||||
DOCDD
|
||||
INODE
|
||||
typedef asection, section prototypes, Section Output, Sections
|
||||
SUBSECTION
|
||||
typedef asection
|
||||
|
||||
The shape of a section struct:
|
||||
|
||||
CODE_FRAGMENT
|
||||
.
|
||||
.typedef struct sec
|
||||
.{
|
||||
. {* The name of the section, the name isn't a copy, the pointer is
|
||||
. the same as that passed to bfd_make_section. *}
|
||||
.
|
||||
. CONST char *name;
|
||||
.
|
||||
. {* Which section is it 0.nth *}
|
||||
.
|
||||
. int index;
|
||||
.
|
||||
. {* The next section in the list belonging to the BFD, or NULL. *}
|
||||
.
|
||||
. struct sec *next;
|
||||
.
|
||||
. {* The field flags contains attributes of the section. Some of
|
||||
. flags are read in from the object file, and some are
|
||||
. synthesized from other information. *}
|
||||
.
|
||||
. flagword flags;
|
||||
.
|
||||
.#define SEC_NO_FLAGS 0x000
|
||||
.
|
||||
. {* Tells the OS to allocate space for this section when loaded.
|
||||
. This would clear for a section containing debug information
|
||||
. only. *}
|
||||
.#define SEC_ALLOC 0x001
|
||||
.
|
||||
. {* Tells the OS to load the section from the file when loading.
|
||||
. This would be clear for a .bss section *}
|
||||
.#define SEC_LOAD 0x002
|
||||
.
|
||||
. {* The section contains data still to be relocated, so there will
|
||||
. be some relocation information too. *}
|
||||
.#define SEC_RELOC 0x004
|
||||
.
|
||||
.#if 0 {* Obsolete ? *}
|
||||
.#define SEC_BALIGN 0x008
|
||||
.#endif
|
||||
.
|
||||
. {* A signal to the OS that the section contains read only
|
||||
. data. *}
|
||||
.#define SEC_READONLY 0x010
|
||||
.
|
||||
. {* The section contains code only. *}
|
||||
.#define SEC_CODE 0x020
|
||||
.
|
||||
. {* The section contains data only. *}
|
||||
.#define SEC_DATA 0x040
|
||||
.
|
||||
. {* The section will reside in ROM. *}
|
||||
.#define SEC_ROM 0x080
|
||||
.
|
||||
. {* The section contains constructor information. This section
|
||||
. type is used by the linker to create lists of constructors and
|
||||
. destructors used by <<g++>>. When a back end sees a symbol
|
||||
. which should be used in a constructor list, it creates a new
|
||||
. section for the type of name (eg <<__CTOR_LIST__>>), attaches
|
||||
. the symbol to it and builds a relocation. To build the lists
|
||||
. of constructors, all the linker has to do is catenate all the
|
||||
. sections called <<__CTOR_LIST__>> and relocte the data
|
||||
. contained within - exactly the operations it would peform on
|
||||
. standard data. *}
|
||||
.#define SEC_CONSTRUCTOR 0x100
|
||||
.
|
||||
. {* The section is a constuctor, and should be placed at the
|
||||
. end of the text, data, or bss section(?). *}
|
||||
.#define SEC_CONSTRUCTOR_TEXT 0x1100
|
||||
.#define SEC_CONSTRUCTOR_DATA 0x2100
|
||||
.#define SEC_CONSTRUCTOR_BSS 0x3100
|
||||
.
|
||||
. {* The section has contents - a data section could be
|
||||
. <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>, a debug section could be
|
||||
. <<SEC_HAS_CONTENTS>> *}
|
||||
.#define SEC_HAS_CONTENTS 0x200
|
||||
.
|
||||
. {* An instruction to the linker not to output sections
|
||||
. containing this flag even if they have information which
|
||||
. would normally be written. *}
|
||||
.#define SEC_NEVER_LOAD 0x400
|
||||
.
|
||||
. {* The section is a shared library section. The linker must leave
|
||||
. these completely alone, as the vma and size are used when
|
||||
. the executable is loaded. *}
|
||||
.#define SEC_SHARED_LIBRARY 0x800
|
||||
.
|
||||
. {* The section is a common section (symbols may be defined
|
||||
. multiple times, the value of a symbol is the amount of
|
||||
. space it requires, and the largest symbol value is the one
|
||||
. used). Most targets have exactly one of these (which we
|
||||
. translate to bfd_com_section), but ECOFF has two. *}
|
||||
.#define SEC_IS_COMMON 0x8000
|
||||
.
|
||||
. {* The section contains only debugging information. For
|
||||
. example, this is set for ELF .debug and .stab sections.
|
||||
. strip tests this flag to see if a section can be
|
||||
. discarded. *}
|
||||
.#define SEC_DEBUGGING 0x10000
|
||||
.
|
||||
. {* End of section flags. *}
|
||||
.
|
||||
. {* The virtual memory address of the section - where it will be
|
||||
. at run time. The symbols are relocated against this. The
|
||||
. user_set_vma flag is maintained by bfd; if it's not set, the
|
||||
. backend can assign addresses (for example, in <<a.out>>, where
|
||||
. the default address for <<.data>> is dependent on the specific
|
||||
. target and various flags). *}
|
||||
.
|
||||
. bfd_vma vma;
|
||||
. boolean user_set_vma;
|
||||
.
|
||||
. {* The load address of the section - where it would be in a
|
||||
. rom image, really only used for writing section header
|
||||
. information. *}
|
||||
.
|
||||
. bfd_vma lma;
|
||||
.
|
||||
. {* The size of the section in bytes, as it will be output.
|
||||
. contains a value even if the section has no contents (eg, the
|
||||
. size of <<.bss>>). This will be filled in after relocation *}
|
||||
.
|
||||
. bfd_size_type _cooked_size;
|
||||
.
|
||||
. {* The size on disk of the section in bytes originally. Normally this
|
||||
. value is the same as the size, but if some relaxing has
|
||||
. been done, then this value will be bigger. *}
|
||||
.
|
||||
. bfd_size_type _raw_size;
|
||||
.
|
||||
. {* If this section is going to be output, then this value is the
|
||||
. offset into the output section of the first byte in the input
|
||||
. section. Eg, if this was going to start at the 100th byte in
|
||||
. the output section, this value would be 100. *}
|
||||
.
|
||||
. bfd_vma output_offset;
|
||||
.
|
||||
. {* The output section through which to map on output. *}
|
||||
.
|
||||
. struct sec *output_section;
|
||||
.
|
||||
. {* The alignment requirement of the section, as an exponent - eg
|
||||
. 3 aligns to 2^3 (or 8) *}
|
||||
.
|
||||
. unsigned int alignment_power;
|
||||
.
|
||||
. {* If an input section, a pointer to a vector of relocation
|
||||
. records for the data in this section. *}
|
||||
.
|
||||
. struct reloc_cache_entry *relocation;
|
||||
.
|
||||
. {* If an output section, a pointer to a vector of pointers to
|
||||
. relocation records for the data in this section. *}
|
||||
.
|
||||
. struct reloc_cache_entry **orelocation;
|
||||
.
|
||||
. {* The number of relocation records in one of the above *}
|
||||
.
|
||||
. unsigned reloc_count;
|
||||
.
|
||||
. {* Information below is back end specific - and not always used
|
||||
. or updated. *}
|
||||
.
|
||||
. {* File position of section data *}
|
||||
.
|
||||
. file_ptr filepos;
|
||||
.
|
||||
. {* File position of relocation info *}
|
||||
.
|
||||
. file_ptr rel_filepos;
|
||||
.
|
||||
. {* File position of line data *}
|
||||
.
|
||||
. file_ptr line_filepos;
|
||||
.
|
||||
. {* Pointer to data for applications *}
|
||||
.
|
||||
. PTR userdata;
|
||||
.
|
||||
. struct lang_output_section *otheruserdata;
|
||||
.
|
||||
. {* Attached line number information *}
|
||||
.
|
||||
. alent *lineno;
|
||||
.
|
||||
. {* Number of line number records *}
|
||||
.
|
||||
. unsigned int lineno_count;
|
||||
.
|
||||
. {* When a section is being output, this value changes as more
|
||||
. linenumbers are written out *}
|
||||
.
|
||||
. file_ptr moving_line_filepos;
|
||||
.
|
||||
. {* what the section number is in the target world *}
|
||||
.
|
||||
. int target_index;
|
||||
.
|
||||
. PTR used_by_bfd;
|
||||
.
|
||||
. {* If this is a constructor section then here is a list of the
|
||||
. relocations created to relocate items within it. *}
|
||||
.
|
||||
. struct relent_chain *constructor_chain;
|
||||
.
|
||||
. {* The BFD which owns the section. *}
|
||||
.
|
||||
. bfd *owner;
|
||||
.
|
||||
. boolean reloc_done;
|
||||
. {* A symbol which points at this section only *}
|
||||
. struct symbol_cache_entry *symbol;
|
||||
. struct symbol_cache_entry **symbol_ptr_ptr;
|
||||
.
|
||||
. struct bfd_seclet *seclets_head;
|
||||
. struct bfd_seclet *seclets_tail;
|
||||
.} asection ;
|
||||
.
|
||||
.
|
||||
. {* These sections are global, and are managed by BFD. The application
|
||||
. and target back end are not permitted to change the values in
|
||||
. these sections. *}
|
||||
.#define BFD_ABS_SECTION_NAME "*ABS*"
|
||||
.#define BFD_UND_SECTION_NAME "*UND*"
|
||||
.#define BFD_COM_SECTION_NAME "*COM*"
|
||||
.#define BFD_IND_SECTION_NAME "*IND*"
|
||||
.
|
||||
. {* the absolute section *}
|
||||
.extern asection bfd_abs_section;
|
||||
. {* Pointer to the undefined section *}
|
||||
.extern asection bfd_und_section;
|
||||
. {* Pointer to the common section *}
|
||||
.extern asection bfd_com_section;
|
||||
. {* Pointer to the indirect section *}
|
||||
.extern asection bfd_ind_section;
|
||||
.
|
||||
.extern struct symbol_cache_entry *bfd_abs_symbol;
|
||||
.extern struct symbol_cache_entry *bfd_com_symbol;
|
||||
.extern struct symbol_cache_entry *bfd_und_symbol;
|
||||
.extern struct symbol_cache_entry *bfd_ind_symbol;
|
||||
.#define bfd_get_section_size_before_reloc(section) \
|
||||
. (section->reloc_done ? (abort(),1): (section)->_raw_size)
|
||||
.#define bfd_get_section_size_after_reloc(section) \
|
||||
. ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
|
||||
*/
|
||||
|
||||
/* These symbols are global, not specific to any BFD. Therefore, anything
|
||||
that tries to change them is broken, and should be repaired. */
|
||||
static CONST asymbol global_syms[] = {
|
||||
/* the_bfd, name, value, attr, section [, udata] */
|
||||
{ 0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_com_section },
|
||||
{ 0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_und_section },
|
||||
{ 0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_abs_section },
|
||||
{ 0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_ind_section },
|
||||
};
|
||||
|
||||
#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
|
||||
asymbol *SYM = (asymbol *) &global_syms[IDX]; \
|
||||
asection SEC = { NAME, 0, 0, FLAGS, 0, 0, (boolean) 0, 0, 0, 0, &SEC,\
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (boolean) 0, \
|
||||
(asymbol *) &global_syms[IDX], &SYM, }
|
||||
|
||||
STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, BFD_COM_SECTION_NAME, 0);
|
||||
STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1);
|
||||
STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2);
|
||||
STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3);
|
||||
#undef STD_SECTION
|
||||
|
||||
/*
|
||||
DOCDD
|
||||
INODE
|
||||
section prototypes, , typedef asection, Sections
|
||||
SUBSECTION
|
||||
section prototypes
|
||||
|
||||
These are the functions exported by the section handling part of
|
||||
<<libbfd>.
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_section_by_name
|
||||
|
||||
SYNOPSIS
|
||||
asection *bfd_get_section_by_name(bfd *abfd, CONST char *name);
|
||||
|
||||
DESCRIPTION
|
||||
Runs through the provided @var{abfd} and returns the one of the
|
||||
<<asection>>s who's name matches that provided, otherwise NULL.
|
||||
@xref{Sections}, for more information.
|
||||
|
||||
This should only be used in special cases; the normal way to process
|
||||
all sections of a given name is to use bfd_map_over_sections and
|
||||
strcmp on the name (or better yet, base it on the section flags
|
||||
or something else) for each section.
|
||||
*/
|
||||
|
||||
asection *
|
||||
DEFUN(bfd_get_section_by_name,(abfd, name),
|
||||
bfd *abfd AND
|
||||
CONST char *name)
|
||||
{
|
||||
asection *sect;
|
||||
|
||||
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
||||
if (!strcmp (sect->name, name)) return sect;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_make_section_old_way
|
||||
|
||||
SYNOPSIS
|
||||
asection *bfd_make_section_old_way(bfd *, CONST char *name);
|
||||
|
||||
DESCRIPTION
|
||||
This function creates a new empty section called @var{name}
|
||||
and attaches it to the end of the chain of sections for the
|
||||
BFD supplied. An attempt to create a section with a name which
|
||||
is already in use, returns its pointer without changing the
|
||||
section chain.
|
||||
|
||||
It has the funny name since this is the way it used to be
|
||||
before is was rewritten...
|
||||
|
||||
Possible errors are:
|
||||
o invalid_operation -
|
||||
If output has already started for this BFD.
|
||||
o no_memory -
|
||||
If obstack alloc fails.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
asection *
|
||||
DEFUN(bfd_make_section_old_way,(abfd, name),
|
||||
bfd *abfd AND
|
||||
CONST char * name)
|
||||
{
|
||||
asection *sec = bfd_get_section_by_name(abfd, name);
|
||||
if (sec == (asection *)NULL)
|
||||
{
|
||||
sec = bfd_make_section(abfd, name);
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_make_section_anyway
|
||||
|
||||
SYNOPSIS
|
||||
asection *bfd_make_section_anyway(bfd *, CONST char *name);
|
||||
|
||||
DESCRIPTION
|
||||
Create a new empty section called @var{name} and attach it to the end of
|
||||
the chain of sections for @var{abfd}. Create a new section even if there
|
||||
is already a section with that name.
|
||||
|
||||
Returns NULL and sets bfd_error on error; possible errors are:
|
||||
o invalid_operation - If output has already started for @var{abfd}.
|
||||
o no_memory - If obstack alloc fails.
|
||||
*/
|
||||
|
||||
sec_ptr
|
||||
bfd_make_section_anyway (abfd, name)
|
||||
bfd *abfd;
|
||||
CONST char *name;
|
||||
{
|
||||
asection *newsect;
|
||||
asection **prev = &abfd->sections;
|
||||
asection * sect = abfd->sections;
|
||||
|
||||
if (abfd->output_has_begun)
|
||||
{
|
||||
bfd_error = invalid_operation;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (sect) {
|
||||
prev = §->next;
|
||||
sect = sect->next;
|
||||
}
|
||||
|
||||
newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
|
||||
if (newsect == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newsect->name = name;
|
||||
newsect->index = abfd->section_count++;
|
||||
newsect->flags = SEC_NO_FLAGS;
|
||||
|
||||
newsect->userdata = 0;
|
||||
newsect->next = (asection *)NULL;
|
||||
newsect->relocation = (arelent *)NULL;
|
||||
newsect->reloc_count = 0;
|
||||
newsect->line_filepos =0;
|
||||
newsect->owner = abfd;
|
||||
|
||||
/* Create a symbol whos only job is to point to this section. This is
|
||||
useful for things like relocs which are relative to the base of a
|
||||
section. */
|
||||
newsect->symbol = bfd_make_empty_symbol(abfd);
|
||||
newsect->symbol->name = name;
|
||||
newsect->symbol->value = 0;
|
||||
newsect->symbol->section = newsect;
|
||||
newsect->symbol->flags = BSF_SECTION_SYM;
|
||||
|
||||
newsect->symbol_ptr_ptr = &newsect->symbol;
|
||||
|
||||
if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
|
||||
free (newsect);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*prev = newsect;
|
||||
return newsect;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_make_section
|
||||
|
||||
SYNOPSIS
|
||||
asection *bfd_make_section(bfd *, CONST char *name);
|
||||
|
||||
DESCRIPTION
|
||||
Like bfd_make_section_anyway, but return NULL (without setting
|
||||
bfd_error) without changing the section chain if there is already a
|
||||
section named @var{name}. If there is an error, return NULL and set
|
||||
bfd_error.
|
||||
*/
|
||||
|
||||
sec_ptr
|
||||
DEFUN(bfd_make_section,(abfd, name),
|
||||
bfd *abfd AND
|
||||
CONST char * name)
|
||||
{
|
||||
asection * sect = abfd->sections;
|
||||
|
||||
if (strcmp(name, BFD_ABS_SECTION_NAME) == 0)
|
||||
{
|
||||
return &bfd_abs_section;
|
||||
}
|
||||
if (strcmp(name, BFD_COM_SECTION_NAME) == 0)
|
||||
{
|
||||
return &bfd_com_section;
|
||||
}
|
||||
if (strcmp(name, BFD_UND_SECTION_NAME) == 0)
|
||||
{
|
||||
return &bfd_und_section;
|
||||
}
|
||||
|
||||
if (strcmp(name, BFD_IND_SECTION_NAME) == 0)
|
||||
{
|
||||
return &bfd_ind_section;
|
||||
}
|
||||
|
||||
while (sect) {
|
||||
if (!strcmp(sect->name, name)) return NULL;
|
||||
sect = sect->next;
|
||||
}
|
||||
|
||||
/* The name is not already used; go ahead and make a new section. */
|
||||
return bfd_make_section_anyway (abfd, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_section_flags
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_section_flags(bfd *, asection *, flagword);
|
||||
|
||||
DESCRIPTION
|
||||
Attempts to set the attributes of the section named in the BFD
|
||||
supplied to the value. Returns true on success, false on
|
||||
error. Possible error returns are:
|
||||
|
||||
o invalid operation -
|
||||
The section cannot have one or more of the attributes
|
||||
requested. For example, a .bss section in <<a.out>> may not
|
||||
have the <<SEC_HAS_CONTENTS>> field set.
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_set_section_flags,(abfd, section, flags),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
flagword flags)
|
||||
{
|
||||
#if 0
|
||||
/* If you try to copy a text section from an input file (where it
|
||||
has the SEC_CODE flag set) to an output file, this loses big if
|
||||
the bfd_applicable_section_flags (abfd) doesn't have the SEC_CODE
|
||||
set - which it doesn't, at least not for a.out. FIXME */
|
||||
|
||||
if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
section->flags = flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_map_over_sections
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_map_over_sections(bfd *abfd,
|
||||
void (*func)(bfd *abfd,
|
||||
asection *sect,
|
||||
PTR obj),
|
||||
PTR obj);
|
||||
|
||||
DESCRIPTION
|
||||
Calls the provided function @var{func} for each section
|
||||
attached to the BFD @var{abfd}, passing @var{obj} as an
|
||||
argument. The function will be called as if by
|
||||
|
||||
| func(abfd, the_section, obj);
|
||||
|
||||
This is the prefered method for iterating over sections, an
|
||||
alternative would be to use a loop:
|
||||
|
||||
| section *p;
|
||||
| for (p = abfd->sections; p != NULL; p = p->next)
|
||||
| func(abfd, p, ...)
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*VARARGS2*/
|
||||
void
|
||||
DEFUN(bfd_map_over_sections,(abfd, operation, user_storage),
|
||||
bfd *abfd AND
|
||||
void (*operation) PARAMS ((bfd *abfd, asection *sect, PTR obj)) AND
|
||||
PTR user_storage)
|
||||
{
|
||||
asection *sect;
|
||||
int i = 0;
|
||||
|
||||
for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
|
||||
(*operation) (abfd, sect, user_storage);
|
||||
|
||||
if (i != abfd->section_count) /* Debugging */
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_section_size
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_section_size(bfd *, asection *, bfd_size_type val);
|
||||
|
||||
DESCRIPTION
|
||||
Sets @var{section} to the size @var{val}. If the operation is
|
||||
ok, then <<true>> is returned, else <<false>>.
|
||||
|
||||
Possible error returns:
|
||||
o invalid_operation -
|
||||
Writing has started to the BFD, so setting the size is invalid
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_set_section_size,(abfd, ptr, val),
|
||||
bfd *abfd AND
|
||||
sec_ptr ptr AND
|
||||
bfd_size_type val)
|
||||
{
|
||||
/* Once you've started writing to any section you cannot create or change
|
||||
the size of any others. */
|
||||
|
||||
if (abfd->output_has_begun) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr->_cooked_size = val;
|
||||
ptr->_raw_size = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_section_contents
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_section_contents
|
||||
(bfd *abfd,
|
||||
asection *section,
|
||||
PTR data,
|
||||
file_ptr offset,
|
||||
bfd_size_type count);
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
Sets the contents of the section @var{section} in BFD
|
||||
@var{abfd} to the data starting in memory at @var{data}. The
|
||||
data is written to the output section starting at offset
|
||||
@var{offset} for @var{count} bytes.
|
||||
|
||||
|
||||
|
||||
Normally <<true>> is returned, else <<false>>. Possible error
|
||||
returns are:
|
||||
o no_contents -
|
||||
The output section does not have the <<SEC_HAS_CONTENTS>>
|
||||
attribute, so nothing can be written to it.
|
||||
o and some more too
|
||||
|
||||
This routine is front end to the back end function
|
||||
<<_bfd_set_section_contents>>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#define bfd_get_section_size_now(abfd,sec) \
|
||||
(sec->reloc_done \
|
||||
? bfd_get_section_size_after_reloc (sec) \
|
||||
: bfd_get_section_size_before_reloc (sec))
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type count)
|
||||
{
|
||||
bfd_size_type sz;
|
||||
|
||||
if (!bfd_get_section_flags(abfd, section) & SEC_HAS_CONTENTS)
|
||||
{
|
||||
bfd_error = no_contents;
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
bad_val:
|
||||
bfd_error = bad_value;
|
||||
return false;
|
||||
}
|
||||
sz = bfd_get_section_size_now (abfd, section);
|
||||
if (offset > sz
|
||||
|| count > sz
|
||||
|| offset + count > sz)
|
||||
goto bad_val;
|
||||
|
||||
switch (abfd->direction)
|
||||
{
|
||||
case read_direction:
|
||||
case no_direction:
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
|
||||
case write_direction:
|
||||
break;
|
||||
|
||||
case both_direction:
|
||||
/* File is opened for update. `output_has_begun' some time ago when
|
||||
the file was created. Do not recompute sections sizes or alignments
|
||||
in _bfd_set_section_content. */
|
||||
abfd->output_has_begun = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (BFD_SEND (abfd, _bfd_set_section_contents,
|
||||
(abfd, section, location, offset, count)))
|
||||
{
|
||||
abfd->output_has_begun = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_section_contents
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_get_section_contents
|
||||
(bfd *abfd, asection *section, PTR location,
|
||||
file_ptr offset, bfd_size_type count);
|
||||
|
||||
DESCRIPTION
|
||||
This function reads data from @var{section} in BFD @var{abfd}
|
||||
into memory starting at @var{location}. The data is read at an
|
||||
offset of @var{offset} from the start of the input section,
|
||||
and is read for @var{count} bytes.
|
||||
|
||||
If the contents of a constuctor with the <<SEC_CONSTUCTOR>>
|
||||
flag set are requested, then the @var{location} is filled with
|
||||
zeroes. If no errors occur, <<true>> is returned, else
|
||||
<<false>>.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
boolean
|
||||
DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type count)
|
||||
{
|
||||
bfd_size_type sz;
|
||||
|
||||
if (section->flags & SEC_CONSTRUCTOR)
|
||||
{
|
||||
memset(location, 0, (unsigned)count);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
bad_val:
|
||||
bfd_error = bad_value;
|
||||
return false;
|
||||
}
|
||||
sz = bfd_get_section_size_now (abfd, section);
|
||||
if (offset > sz
|
||||
|| count > sz
|
||||
|| offset + count > sz)
|
||||
goto bad_val;
|
||||
|
||||
if (count == 0)
|
||||
/* Don't bother. */
|
||||
return true;
|
||||
|
||||
return BFD_SEND (abfd, _bfd_get_section_contents,
|
||||
(abfd, section, location, offset, count));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
|||
/* Table of stab names for the BFD library.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: stab-syms.c,v 1.1 1994/01/28 12:38:10 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
#define ARCH_SIZE 32 /* Value doesn't matter. */
|
||||
#include "libaout.h"
|
||||
#include "aout/aout64.h"
|
||||
|
||||
/* Create a table of debugging stab-codes and corresponding names. */
|
||||
|
||||
#define __define_name(CODE, STRING) {(int)CODE, STRING},
|
||||
#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING)
|
||||
CONST struct {short code; char string[10];} aout_stab_names[]
|
||||
= {
|
||||
#include "aout/stab.def"
|
||||
|
||||
/* These are not really stab symbols, but it is
|
||||
convenient to have them here for the sake of nm.
|
||||
For completeness, we could also add N_TEXT etc, but those
|
||||
are never needed, since nm treats those specially. */
|
||||
__define_name (N_SETA, "SETA") /* Absolute set element symbol */
|
||||
__define_name (N_SETT, "SETT") /* Text set element symbol */
|
||||
__define_name (N_SETD, "SETD") /* Data set element symbol */
|
||||
__define_name (N_SETB, "SETB") /* Bss set element symbol */
|
||||
__define_name (N_SETV, "SETV") /* Pointer to set vector in data area. */
|
||||
__define_name (N_INDR, "INDR")
|
||||
__define_name (N_WARNING, "WARNING")
|
||||
};
|
||||
#undef __define_stab
|
||||
#undef GNU_EXTRA_STABS
|
||||
|
||||
CONST char *
|
||||
DEFUN(aout_stab_name,(code),
|
||||
int code)
|
||||
{
|
||||
register int i = sizeof(aout_stab_names) / sizeof(aout_stab_names[0]);
|
||||
while (--i >= 0)
|
||||
if (aout_stab_names[i].code == code)
|
||||
return aout_stab_names[i].string;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,530 @@
|
|||
/* Generic symbol-table support for the BFD library.
|
||||
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: syms.c,v 1.1 1994/01/28 12:38:12 pk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Symbols
|
||||
|
||||
BFD trys to maintain as much symbol information as it can when
|
||||
it moves information from file to file. BFD passes information
|
||||
to applications though the <<asymbol>> structure. When the
|
||||
application requests the symbol table, BFD reads the table in
|
||||
the native form and translates parts of it into the internal
|
||||
format. To maintain more than the infomation passed to
|
||||
applications some targets keep some information `behind the
|
||||
scenes', in a structure only the particular back end knows
|
||||
about. For example, the coff back end keeps the original
|
||||
symbol table structure as well as the canonical structure when
|
||||
a BFD is read in. On output, the coff back end can reconstruct
|
||||
the output symbol table so that no information is lost, even
|
||||
information unique to coff which BFD doesn't know or
|
||||
understand. If a coff symbol table was read, but was written
|
||||
through an a.out back end, all the coff specific information
|
||||
would be lost. The symbol table of a BFD
|
||||
is not necessarily read in until a canonicalize request is
|
||||
made. Then the BFD back end fills in a table provided by the
|
||||
application with pointers to the canonical information. To
|
||||
output symbols, the application provides BFD with a table of
|
||||
pointers to pointers to <<asymbol>>s. This allows applications
|
||||
like the linker to output a symbol as read, since the `behind
|
||||
the scenes' information will be still available.
|
||||
@menu
|
||||
@* Reading Symbols::
|
||||
@* Writing Symbols::
|
||||
@* typedef asymbol::
|
||||
@* symbol handling functions::
|
||||
@end menu
|
||||
|
||||
INODE
|
||||
Reading Symbols, Writing Symbols, Symbols, Symbols
|
||||
SUBSECTION
|
||||
Reading Symbols
|
||||
|
||||
There are two stages to reading a symbol table from a BFD;
|
||||
allocating storage, and the actual reading process. This is an
|
||||
excerpt from an appliction which reads the symbol table:
|
||||
|
||||
| unsigned int storage_needed;
|
||||
| asymbol **symbol_table;
|
||||
| unsigned int number_of_symbols;
|
||||
| unsigned int i;
|
||||
|
|
||||
| storage_needed = get_symtab_upper_bound (abfd);
|
||||
|
|
||||
| if (storage_needed == 0) {
|
||||
| return ;
|
||||
| }
|
||||
| symbol_table = (asymbol **) bfd_xmalloc (storage_needed);
|
||||
| ...
|
||||
| number_of_symbols =
|
||||
| bfd_canonicalize_symtab (abfd, symbol_table);
|
||||
|
|
||||
| for (i = 0; i < number_of_symbols; i++) {
|
||||
| process_symbol (symbol_table[i]);
|
||||
| }
|
||||
|
||||
All storage for the symbols themselves is in an obstack
|
||||
connected to the BFD, and is freed when the BFD is closed.
|
||||
|
||||
|
||||
INODE
|
||||
Writing Symbols, typedef asymbol, Reading Symbols, Symbols
|
||||
SUBSECTION
|
||||
Writing Symbols
|
||||
|
||||
Writing of a symbol table is automatic when a BFD open for
|
||||
writing is closed. The application attaches a vector of
|
||||
pointers to pointers to symbols to the BFD being written, and
|
||||
fills in the symbol count. The close and cleanup code reads
|
||||
through the table provided and performs all the necessary
|
||||
operations. The outputing code must always be provided with an
|
||||
'owned' symbol; one which has come from another BFD, or one
|
||||
which has been created using <<bfd_make_empty_symbol>>. An
|
||||
example showing the creation of a symbol table with only one element:
|
||||
|
||||
| #include "bfd.h"
|
||||
| main()
|
||||
| {
|
||||
| bfd *abfd;
|
||||
| asymbol *ptrs[2];
|
||||
| asymbol *new;
|
||||
|
|
||||
| abfd = bfd_openw("foo","a.out-sunos-big");
|
||||
| bfd_set_format(abfd, bfd_object);
|
||||
| new = bfd_make_empty_symbol(abfd);
|
||||
| new->name = "dummy_symbol";
|
||||
| new->section = bfd_make_section_old_way(abfd, ".text");
|
||||
| new->flags = BSF_GLOBAL;
|
||||
| new->value = 0x12345;
|
||||
|
|
||||
| ptrs[0] = new;
|
||||
| ptrs[1] = (asymbol *)0;
|
||||
|
|
||||
| bfd_set_symtab(abfd, ptrs, 1);
|
||||
| bfd_close(abfd);
|
||||
| }
|
||||
|
|
||||
| ./makesym
|
||||
| nm foo
|
||||
| 00012345 A dummy_symbol
|
||||
|
||||
Many formats cannot represent arbitary symbol information; for
|
||||
instance the <<a.out>> object format does not allow an
|
||||
arbitary number of sections. A symbol pointing to a section
|
||||
which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
|
||||
be described.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
DOCDD
|
||||
INODE
|
||||
typedef asymbol, symbol handling functions, Writing Symbols, Symbols
|
||||
|
||||
*/
|
||||
/*
|
||||
SUBSECTION
|
||||
typedef asymbol
|
||||
|
||||
An <<asymbol>> has the form:
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
CODE_FRAGMENT
|
||||
|
||||
.
|
||||
.typedef struct symbol_cache_entry
|
||||
.{
|
||||
. {* A pointer to the BFD which owns the symbol. This information
|
||||
. is necessary so that a back end can work out what additional
|
||||
. information (invisible to the application writer) is carried
|
||||
. with the symbol.
|
||||
.
|
||||
. This field is *almost* redundant, since you can use section->owner
|
||||
. instead, except that some symbols point to the global sections
|
||||
. bfd_{abs,com,und}_section. This could be fixed by making
|
||||
. these globals be per-bfd (or per-target-flavor). FIXME. *}
|
||||
.
|
||||
. struct _bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *}
|
||||
.
|
||||
. {* The text of the symbol. The name is left alone, and not copied - the
|
||||
. application may not alter it. *}
|
||||
. CONST char *name;
|
||||
.
|
||||
. {* The value of the symbol. This really should be a union of a
|
||||
. numeric value with a pointer, since some flags indicate that
|
||||
. a pointer to another symbol is stored here. *}
|
||||
. symvalue value;
|
||||
.
|
||||
. {* Attributes of a symbol: *}
|
||||
.
|
||||
.#define BSF_NO_FLAGS 0x00
|
||||
.
|
||||
. {* The symbol has local scope; <<static>> in <<C>>. The value
|
||||
. is the offset into the section of the data. *}
|
||||
.#define BSF_LOCAL 0x01
|
||||
.
|
||||
. {* The symbol has global scope; initialized data in <<C>>. The
|
||||
. value is the offset into the section of the data. *}
|
||||
.#define BSF_GLOBAL 0x02
|
||||
.
|
||||
. {* The symbol has global scope, and is exported. The value is
|
||||
. the offset into the section of the data. *}
|
||||
.#define BSF_EXPORT BSF_GLOBAL {* no real difference *}
|
||||
.
|
||||
. {* A normal C symbol would be one of:
|
||||
. <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
|
||||
. <<BSF_GLOBAL>> *}
|
||||
.
|
||||
. {* The symbol is a debugging record. The value has an arbitary
|
||||
. meaning. *}
|
||||
.#define BSF_DEBUGGING 0x08
|
||||
.
|
||||
. {* The symbol denotes a function entry point. Used in ELF,
|
||||
. perhaps others someday. *}
|
||||
.#define BSF_FUNCTION 0x10
|
||||
.
|
||||
. {* Used by the linker. *}
|
||||
.#define BSF_KEEP 0x20
|
||||
.#define BSF_KEEP_G 0x40
|
||||
.
|
||||
. {* A weak global symbol, overridable without warnings by
|
||||
. a regular global symbol of the same name. *}
|
||||
.#define BSF_WEAK 0x80
|
||||
.
|
||||
. {* This symbol was created to point to a section, e.g. ELF's
|
||||
. STT_SECTION symbols. *}
|
||||
.#define BSF_SECTION_SYM 0x100
|
||||
.
|
||||
. {* The symbol used to be a common symbol, but now it is
|
||||
. allocated. *}
|
||||
.#define BSF_OLD_COMMON 0x200
|
||||
.
|
||||
. {* The default value for common data. *}
|
||||
.#define BFD_FORT_COMM_DEFAULT_VALUE 0
|
||||
.
|
||||
. {* In some files the type of a symbol sometimes alters its
|
||||
. location in an output file - ie in coff a <<ISFCN>> symbol
|
||||
. which is also <<C_EXT>> symbol appears where it was
|
||||
. declared and not at the end of a section. This bit is set
|
||||
. by the target BFD part to convey this information. *}
|
||||
.
|
||||
.#define BSF_NOT_AT_END 0x400
|
||||
.
|
||||
. {* Signal that the symbol is the label of constructor section. *}
|
||||
.#define BSF_CONSTRUCTOR 0x800
|
||||
.
|
||||
. {* Signal that the symbol is a warning symbol. If the symbol
|
||||
. is a warning symbol, then the value field (I know this is
|
||||
. tacky) will point to the asymbol which when referenced will
|
||||
. cause the warning. *}
|
||||
.#define BSF_WARNING 0x1000
|
||||
.
|
||||
. {* Signal that the symbol is indirect. The value of the symbol
|
||||
. is a pointer to an undefined asymbol which contains the
|
||||
. name to use instead. *}
|
||||
.#define BSF_INDIRECT 0x2000
|
||||
.
|
||||
. {* BSF_FILE marks symbols that contain a file name. This is used
|
||||
. for ELF STT_FILE symbols. *}
|
||||
.#define BSF_FILE 0x4000
|
||||
.
|
||||
. flagword flags;
|
||||
.
|
||||
. {* A pointer to the section to which this symbol is
|
||||
. relative. This will always be non NULL, there are special
|
||||
. sections for undefined and absolute symbols *}
|
||||
. struct sec *section;
|
||||
.
|
||||
. {* Back end special data. This is being phased out in favour
|
||||
. of making this a union. *}
|
||||
. PTR udata;
|
||||
.
|
||||
.} asymbol;
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "libbfd.h"
|
||||
#include "aout/stab_gnu.h"
|
||||
|
||||
/*
|
||||
DOCDD
|
||||
INODE
|
||||
symbol handling functions, , typedef asymbol, Symbols
|
||||
SUBSECTION
|
||||
Symbol Handling Functions
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
get_symtab_upper_bound
|
||||
|
||||
DESCRIPTION
|
||||
Returns the number of bytes required in a vector of pointers
|
||||
to <<asymbols>> for all the symbols in the supplied BFD,
|
||||
including a terminal NULL pointer. If there are no symbols in
|
||||
the BFD, then 0 is returned.
|
||||
|
||||
.#define get_symtab_upper_bound(abfd) \
|
||||
. BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_canonicalize_symtab
|
||||
|
||||
DESCRIPTION
|
||||
Supplied a BFD and a pointer to an uninitialized vector of
|
||||
pointers. This reads in the symbols from the BFD, and fills in
|
||||
the table with pointers to the symbols, and a trailing NULL.
|
||||
The routine returns the actual number of symbol pointers not
|
||||
including the NULL.
|
||||
|
||||
|
||||
.#define bfd_canonicalize_symtab(abfd, location) \
|
||||
. BFD_SEND (abfd, _bfd_canonicalize_symtab,\
|
||||
. (abfd, location))
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_set_symtab
|
||||
|
||||
DESCRIPTION
|
||||
Provided a table of pointers to symbols and a count, writes to
|
||||
the output BFD the symbols when closed.
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_set_symtab (bfd *, asymbol **, unsigned int );
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_set_symtab (abfd, location, symcount)
|
||||
bfd *abfd;
|
||||
asymbol **location;
|
||||
unsigned int symcount;
|
||||
{
|
||||
if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
bfd_get_outsymbols (abfd) = location;
|
||||
bfd_get_symcount (abfd) = symcount;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_print_symbol_vandf
|
||||
|
||||
DESCRIPTION
|
||||
Prints the value and flags of the symbol supplied to the stream file.
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_print_symbol_vandf(PTR file, asymbol *symbol);
|
||||
*/
|
||||
void
|
||||
DEFUN(bfd_print_symbol_vandf,(file, symbol),
|
||||
PTR file AND
|
||||
asymbol *symbol)
|
||||
{
|
||||
flagword type = symbol->flags;
|
||||
if (symbol->section != (asection *)NULL)
|
||||
{
|
||||
fprintf_vma(file, symbol->value+symbol->section->vma);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_vma(file, symbol->value);
|
||||
}
|
||||
fprintf(file," %c%c%c%c%c%c%c",
|
||||
(type & BSF_LOCAL) ? 'l':' ',
|
||||
(type & BSF_GLOBAL) ? 'g' : ' ',
|
||||
(type & BSF_WEAK) ? 'w' : ' ',
|
||||
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
|
||||
(type & BSF_WARNING) ? 'W' : ' ',
|
||||
(type & BSF_INDIRECT) ? 'I' : ' ',
|
||||
(type & BSF_DEBUGGING) ? 'd' :' ');
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_make_empty_symbol
|
||||
|
||||
DESCRIPTION
|
||||
This function creates a new <<asymbol>> structure for the BFD,
|
||||
and returns a pointer to it.
|
||||
|
||||
This routine is necessary, since each back end has private
|
||||
information surrounding the <<asymbol>>. Building your own
|
||||
<<asymbol>> and pointing to it will not create the private
|
||||
information, and will cause problems later on.
|
||||
|
||||
.#define bfd_make_empty_symbol(abfd) \
|
||||
. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_make_debug_symbol
|
||||
|
||||
DESCRIPTION
|
||||
This function creates a new <<asymbol>> structure for the BFD,
|
||||
to be used as a debugging symbol. Further details of its use have
|
||||
yet to be worked out.
|
||||
|
||||
.#define bfd_make_debug_symbol(abfd,ptr,size) \
|
||||
. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
|
||||
*/
|
||||
|
||||
struct section_to_type
|
||||
{
|
||||
CONST char *section;
|
||||
char type;
|
||||
};
|
||||
|
||||
/* Map COFF section names to POSIX/BSD single-character symbol types.
|
||||
This table is probably incomplete. It is sorted for convenience of
|
||||
adding entries. Since it is so short, a linear search is used. */
|
||||
static CONST struct section_to_type stt[] = {
|
||||
{"*DEBUG*", 'N'},
|
||||
{".bss", 'b'},
|
||||
{".data", 'd'},
|
||||
{".sbss", 's'}, /* Small BSS (uninitialized data) */
|
||||
{".scommon", 'c'}, /* Small common */
|
||||
{".sdata", 'g'}, /* Small initialized data */
|
||||
{".text", 't'},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/* Return the single-character symbol type corresponding to
|
||||
COFF section S, or '?' for an unknown COFF section. */
|
||||
|
||||
static char
|
||||
coff_section_type (s)
|
||||
char *s;
|
||||
{
|
||||
CONST struct section_to_type *t;
|
||||
|
||||
for (t = &stt[0]; t->section; t++)
|
||||
if (!strcmp (s, t->section))
|
||||
return t->type;
|
||||
return '?';
|
||||
}
|
||||
|
||||
#ifndef islower
|
||||
#define islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||
#endif
|
||||
#ifndef toupper
|
||||
#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c))
|
||||
#endif
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_decode_symclass
|
||||
|
||||
DESCRIPTION
|
||||
Return a character corresponding to the symbol
|
||||
class of symbol, or '?' for an unknown class.
|
||||
|
||||
SYNOPSIS
|
||||
int bfd_decode_symclass(asymbol *symbol);
|
||||
*/
|
||||
int
|
||||
DEFUN(bfd_decode_symclass,(symbol),
|
||||
asymbol *symbol)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (bfd_is_com_section (symbol->section))
|
||||
return 'C';
|
||||
if (symbol->section == &bfd_und_section)
|
||||
return 'U';
|
||||
if (symbol->section == &bfd_ind_section)
|
||||
return 'I';
|
||||
if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
|
||||
return '?';
|
||||
|
||||
if (symbol->section == &bfd_abs_section)
|
||||
c = 'a';
|
||||
else if (symbol->section)
|
||||
c = coff_section_type (symbol->section->name);
|
||||
else
|
||||
return '?';
|
||||
if (symbol->flags & BSF_GLOBAL)
|
||||
c = toupper (c);
|
||||
return c;
|
||||
|
||||
/* We don't have to handle these cases just yet, but we will soon:
|
||||
N_SETV: 'v';
|
||||
N_SETA: 'l';
|
||||
N_SETT: 'x';
|
||||
N_SETD: 'z';
|
||||
N_SETB: 's';
|
||||
N_INDR: 'i';
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_symbol_info
|
||||
|
||||
DESCRIPTION
|
||||
Fill in the basic info about symbol that nm needs.
|
||||
Additional info may be added by the back-ends after
|
||||
calling this function.
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_symbol_info(asymbol *symbol, symbol_info *ret);
|
||||
*/
|
||||
|
||||
void
|
||||
DEFUN(bfd_symbol_info,(symbol, ret),
|
||||
asymbol *symbol AND
|
||||
symbol_info *ret)
|
||||
{
|
||||
ret->type = bfd_decode_symclass (symbol);
|
||||
if (ret->type != 'U')
|
||||
ret->value = symbol->value+symbol->section->vma;
|
||||
else
|
||||
ret->value = 0;
|
||||
ret->name = symbol->name;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_symbol_is_absolute()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
|
@ -0,0 +1,638 @@
|
|||
/* Generic target-file-type support for the BFD library.
|
||||
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: targets.c,v 1.1 1994/01/28 12:38:13 pk Exp $
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Targets
|
||||
|
||||
DESCRIPTION
|
||||
Each port of BFD to a different machine requries the creation
|
||||
of a target back end. All the back end provides to the root
|
||||
part of BFD is a structure containing pointers to functions
|
||||
which perform certain low level operations on files. BFD
|
||||
translates the applications's requests through a pointer into
|
||||
calls to the back end routines.
|
||||
|
||||
When a file is opened with <<bfd_openr>>, its format and
|
||||
target are unknown. BFD uses various mechanisms to determine
|
||||
how to interpret the file. The operations performed are:
|
||||
|
||||
o First a BFD is created by calling the internal routine
|
||||
<<new_bfd>>, then <<bfd_find_target>> is called with the
|
||||
target string supplied to <<bfd_openr>> and the new BFD pointer.
|
||||
|
||||
o If a null target string was provided to <<bfd_find_target>>,
|
||||
it looks up the environment variable <<GNUTARGET>> and uses
|
||||
that as the target string.
|
||||
|
||||
o If the target string is still NULL, or the target string is
|
||||
<<default>>, then the first item in the target vector is used
|
||||
as the target type, and <<target_defaulted>> is set to
|
||||
cause <<bfd_check_format>> to loop through all the targets.
|
||||
@xref{bfd_target}. @xref{Formats}.
|
||||
|
||||
o Otherwise, the elements in the target vector are inspected
|
||||
one by one, until a match on target name is found. When found,
|
||||
that is used.
|
||||
|
||||
o Otherwise the error <<invalid_target>> is returned to
|
||||
<<bfd_openr>>.
|
||||
|
||||
o <<bfd_openr>> attempts to open the file using
|
||||
<<bfd_open_file>>, and returns the BFD.
|
||||
|
||||
Once the BFD has been opened and the target selected, the file
|
||||
format may be determined. This is done by calling
|
||||
<<bfd_check_format>> on the BFD with a suggested format.
|
||||
If <<target_defaulted>> has been set, each possible target
|
||||
type is tried to see if it recognizes the specified format. The
|
||||
routine returns <<true>> when the application guesses right.
|
||||
@menu
|
||||
@* bfd_target::
|
||||
@end menu
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
INODE
|
||||
bfd_target, , Targets, Targets
|
||||
DOCDD
|
||||
SUBSECTION
|
||||
bfd_target
|
||||
|
||||
DESCRIPTION
|
||||
This structure contains everything that BFD knows about a
|
||||
target. It includes things like its byte order, name, what
|
||||
routines to call to do various operations, etc.
|
||||
|
||||
Every BFD points to a target structure with its <<xvec>>
|
||||
member.
|
||||
|
||||
These macros are used to dispatch to functions through the
|
||||
bfd_target vector. They are used in a number of macros further
|
||||
down in @file{bfd.h}, and are also used when calling various
|
||||
routines by hand inside the BFD implementation. The "arglist"
|
||||
argument must be parenthesized; it contains all the arguments
|
||||
to the called function.
|
||||
|
||||
They make the documentation (more) unpleasant to read, so if
|
||||
someone wants to fix this and not break the above, please do.
|
||||
|
||||
.#define BFD_SEND(bfd, message, arglist) \
|
||||
. ((*((bfd)->xvec->message)) arglist)
|
||||
|
||||
For operations which index on the BFD format
|
||||
|
||||
.#define BFD_SEND_FMT(bfd, message, arglist) \
|
||||
. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
|
||||
|
||||
This is the struct which defines the type of BFD this is. The
|
||||
<<xvec>> member of the struct <<bfd>> itself points here. Each
|
||||
module that implements access to a different target under BFD,
|
||||
defines one of these.
|
||||
|
||||
|
||||
FIXME, these names should be rationalised with the names of
|
||||
the entry points which call them. Too bad we can't have one
|
||||
macro to define them both!
|
||||
|
||||
.typedef struct bfd_target
|
||||
.{
|
||||
|
||||
Identifies the kind of target, eg SunOS4, Ultrix, etc.
|
||||
|
||||
. char *name;
|
||||
|
||||
The "flavour" of a back end is a general indication about the contents
|
||||
of a file.
|
||||
|
||||
. enum target_flavour {
|
||||
. bfd_target_unknown_flavour,
|
||||
. bfd_target_aout_flavour,
|
||||
. bfd_target_coff_flavour,
|
||||
. bfd_target_ecoff_flavour,
|
||||
. bfd_target_elf_flavour,
|
||||
. bfd_target_ieee_flavour,
|
||||
. bfd_target_nlm_flavour,
|
||||
. bfd_target_oasys_flavour,
|
||||
. bfd_target_tekhex_flavour,
|
||||
. bfd_target_srec_flavour,
|
||||
. bfd_target_hppa_flavour} flavour;
|
||||
|
||||
The order of bytes within the data area of a file.
|
||||
|
||||
. boolean byteorder_big_p;
|
||||
|
||||
The order of bytes within the header parts of a file.
|
||||
|
||||
. boolean header_byteorder_big_p;
|
||||
|
||||
This is a mask of all the flags which an executable may have set -
|
||||
from the set <<NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>.
|
||||
|
||||
. flagword object_flags;
|
||||
|
||||
This is a mask of all the flags which a section may have set - from
|
||||
the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>.
|
||||
|
||||
. flagword section_flags;
|
||||
|
||||
The character normally found at the front of a symbol
|
||||
(if any), perhaps _.
|
||||
|
||||
. char symbol_leading_char;
|
||||
|
||||
The pad character for filenames within an archive header.
|
||||
|
||||
. char ar_pad_char;
|
||||
|
||||
The maximum number of characters in an archive header.
|
||||
|
||||
. unsigned short ar_max_namelen;
|
||||
|
||||
The minimum alignment restriction for any section.
|
||||
|
||||
. unsigned int align_power_min;
|
||||
|
||||
Entries for byte swapping for data. These are different to the other
|
||||
entry points, since they don't take BFD as first arg. Certain other handlers
|
||||
could do the same.
|
||||
|
||||
. bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
|
||||
. bfd_vma (*bfd_getx32) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
|
||||
. bfd_vma (*bfd_getx16) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
|
||||
|
||||
Byte swapping for the headers
|
||||
|
||||
. bfd_vma (*bfd_h_getx64) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
|
||||
. bfd_vma (*bfd_h_getx32) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
|
||||
. bfd_vma (*bfd_h_getx16) PARAMS ((bfd_byte *));
|
||||
. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((bfd_byte *));
|
||||
. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
|
||||
|
||||
Format dependent routines: these are vectors of entry points
|
||||
within the target vector structure, one for each format to check.
|
||||
|
||||
Check the format of a file being read. Return bfd_target * or zero.
|
||||
|
||||
. struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
|
||||
|
||||
Set the format of a file being written.
|
||||
|
||||
. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
|
||||
|
||||
Write cached information into a file being written, at bfd_close.
|
||||
|
||||
. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
|
||||
|
||||
The following functions are defined in <<JUMP_TABLE>>. The idea is
|
||||
that the back end writer of <<foo>> names all the routines
|
||||
<<foo_>>@var{entry_point}, <<JUMP_TABLE>> will built the entries
|
||||
in this structure in the right order.
|
||||
|
||||
Core file entry points
|
||||
|
||||
. char * (*_core_file_failing_command) PARAMS ((bfd *));
|
||||
. int (*_core_file_failing_signal) PARAMS ((bfd *));
|
||||
. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
|
||||
|
||||
Archive entry points
|
||||
|
||||
. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
|
||||
. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
|
||||
. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *));
|
||||
. boolean (*write_armap) PARAMS ((bfd *arch,
|
||||
. unsigned int elength,
|
||||
. struct orl *map,
|
||||
. unsigned int orl_count,
|
||||
. int stridx));
|
||||
|
||||
Standard stuff.
|
||||
|
||||
. boolean (*_close_and_cleanup) PARAMS ((bfd *));
|
||||
. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
|
||||
. file_ptr, bfd_size_type));
|
||||
. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
|
||||
. file_ptr, bfd_size_type));
|
||||
. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
|
||||
|
||||
Symbols and relocations
|
||||
|
||||
. unsigned int (*_get_symtab_upper_bound) PARAMS ((bfd *));
|
||||
. unsigned int (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
|
||||
. struct symbol_cache_entry **));
|
||||
. unsigned int (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
|
||||
. unsigned int (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
|
||||
. struct symbol_cache_entry **));
|
||||
. struct symbol_cache_entry *
|
||||
. (*_bfd_make_empty_symbol) PARAMS ((bfd *));
|
||||
. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR,
|
||||
. struct symbol_cache_entry *,
|
||||
. bfd_print_symbol_type));
|
||||
.#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
|
||||
. void (*_bfd_get_symbol_info) PARAMS ((bfd *,
|
||||
. struct symbol_cache_entry *,
|
||||
. symbol_info *));
|
||||
.#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
|
||||
|
||||
. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
|
||||
.
|
||||
. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
|
||||
. unsigned long));
|
||||
.
|
||||
. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
|
||||
.
|
||||
. boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd,
|
||||
. struct sec *section, struct symbol_cache_entry **symbols,
|
||||
. bfd_vma offset, CONST char **file, CONST char **func,
|
||||
. unsigned int *line));
|
||||
.
|
||||
. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
|
||||
.
|
||||
. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
|
||||
.
|
||||
. void (*_bfd_debug_info_start) PARAMS ((bfd *));
|
||||
. void (*_bfd_debug_info_end) PARAMS ((bfd *));
|
||||
. void (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *));
|
||||
.
|
||||
. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
|
||||
. struct bfd_seclet *, bfd_byte *data,
|
||||
. boolean relocateable));
|
||||
.
|
||||
. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
|
||||
. struct symbol_cache_entry **));
|
||||
.
|
||||
. boolean (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
|
||||
. boolean relocateable));
|
||||
|
||||
. {* See documentation on reloc types. *}
|
||||
. CONST struct reloc_howto_struct *
|
||||
. (*reloc_type_lookup) PARAMS ((bfd *abfd,
|
||||
. bfd_reloc_code_real_type code));
|
||||
.
|
||||
. {* Back-door to allow format-aware applications to create debug symbols
|
||||
. while using BFD for everything else. Currently used by the assembler
|
||||
. when creating COFF files. *}
|
||||
. asymbol * (*_bfd_make_debug_symbol) PARAMS ((
|
||||
. bfd *abfd,
|
||||
. void *ptr,
|
||||
. unsigned long size));
|
||||
|
||||
Data for use by back-end routines, which isn't generic enough to belong
|
||||
in this structure.
|
||||
|
||||
. PTR backend_data;
|
||||
.} bfd_target;
|
||||
|
||||
*/
|
||||
|
||||
/* All known xvecs (even those that don't compile on all systems).
|
||||
Alphabetized for easy reference.
|
||||
They are listed a second time below, since
|
||||
we can't intermix extern's and initializers. */
|
||||
extern bfd_target a29kcoff_big_vec;
|
||||
extern bfd_target a_out_adobe_vec;
|
||||
extern bfd_target aout_mips_big_vec;
|
||||
extern bfd_target aout_mips_little_vec;
|
||||
extern bfd_target apollocoff_vec;
|
||||
extern bfd_target b_out_vec_big_host;
|
||||
extern bfd_target b_out_vec_little_host;
|
||||
extern bfd_target bfd_elf32_big_generic_vec;
|
||||
extern bfd_target bfd_elf32_bigmips_vec;
|
||||
extern bfd_target bfd_elf32_hppa_vec;
|
||||
extern bfd_target bfd_elf32_i386_vec;
|
||||
extern bfd_target bfd_elf32_i860_vec;
|
||||
extern bfd_target bfd_elf32_little_generic_vec;
|
||||
extern bfd_target bfd_elf32_littlemips_vec;
|
||||
extern bfd_target bfd_elf32_m68k_vec;
|
||||
extern bfd_target bfd_elf32_m88k_vec;
|
||||
extern bfd_target bfd_elf32_sparc_vec;
|
||||
extern bfd_target bfd_elf64_big_generic_vec;
|
||||
extern bfd_target bfd_elf64_little_generic_vec;
|
||||
extern bfd_target demo_64_vec;
|
||||
extern bfd_target ecoff_big_vec;
|
||||
extern bfd_target ecoff_little_vec;
|
||||
extern bfd_target ecoffalpha_little_vec;
|
||||
extern bfd_target h8300coff_vec;
|
||||
extern bfd_target h8500coff_vec;
|
||||
extern bfd_target host_aout_vec;
|
||||
extern bfd_target hp300bsd_vec;
|
||||
extern bfd_target hp300hpux_vec;
|
||||
extern bfd_target hppa_vec;
|
||||
extern bfd_target i386aout_vec;
|
||||
extern bfd_target i386bsd_vec;
|
||||
extern bfd_target i386coff_vec;
|
||||
extern bfd_target i386linux_vec;
|
||||
extern bfd_target i386lynx_aout_vec;
|
||||
extern bfd_target i386lynx_coff_vec;
|
||||
extern bfd_target icoff_big_vec;
|
||||
extern bfd_target icoff_little_vec;
|
||||
extern bfd_target ieee_vec;
|
||||
extern bfd_target m68kcoff_vec;
|
||||
extern bfd_target m68kcoffun_vec;
|
||||
extern bfd_target m68klynx_aout_vec;
|
||||
extern bfd_target m68klynx_coff_vec;
|
||||
extern bfd_target m88kbcs_vec;
|
||||
extern bfd_target newsos3_vec;
|
||||
extern bfd_target nlm32_big_generic_vec;
|
||||
extern bfd_target nlm32_i386_vec;
|
||||
extern bfd_target nlm32_little_generic_vec;
|
||||
extern bfd_target nlm64_big_generic_vec;
|
||||
extern bfd_target nlm64_little_generic_vec;
|
||||
extern bfd_target oasys_vec;
|
||||
extern bfd_target rs6000coff_vec;
|
||||
extern bfd_target shcoff_vec;
|
||||
extern bfd_target sunos_big_vec;
|
||||
extern bfd_target tekhex_vec;
|
||||
extern bfd_target we32kcoff_vec;
|
||||
extern bfd_target z8kcoff_vec;
|
||||
extern bfd_target netbsd_386_vec;
|
||||
extern bfd_target netbsd_sparc_vec;
|
||||
extern bfd_target netbsd_m68k_vec;
|
||||
|
||||
/* srec is always included. */
|
||||
extern bfd_target srec_vec;
|
||||
extern bfd_target symbolsrec_vec;
|
||||
|
||||
/* All of the xvecs for core files. */
|
||||
extern bfd_target aix386_core_vec;
|
||||
extern bfd_target hpux_core_vec;
|
||||
extern bfd_target osf_core_vec;
|
||||
extern bfd_target sco_core_vec;
|
||||
extern bfd_target trad_core_vec;
|
||||
|
||||
bfd_target *target_vector[] = {
|
||||
|
||||
#ifdef SELECT_VECS
|
||||
|
||||
SELECT_VECS,
|
||||
|
||||
#else /* not SELECT_VECS */
|
||||
|
||||
#ifdef DEFAULT_VECTOR
|
||||
&DEFAULT_VECTOR,
|
||||
#endif
|
||||
/* This list is alphabetized to make it easy to compare
|
||||
with other vector lists -- the decls above and
|
||||
the case statement in configure.in.
|
||||
Vectors that don't compile on all systems, or aren't finished,
|
||||
should have an entry here with #if 0 around it, to show that
|
||||
it wasn't omitted by mistake. */
|
||||
&a29kcoff_big_vec,
|
||||
&a_out_adobe_vec,
|
||||
#if 0 /* No one seems to use this. */
|
||||
&aout_mips_big_vec,
|
||||
#endif
|
||||
&aout_mips_little_vec,
|
||||
&b_out_vec_big_host,
|
||||
&b_out_vec_little_host,
|
||||
#if 0 /* No one seems to use this. */
|
||||
&bfd_elf32_big_generic_vec,
|
||||
&bfd_elf32_bigmips_vec,
|
||||
#endif
|
||||
#if 0
|
||||
&bfd_elf32_hppa_vec,
|
||||
#endif
|
||||
&bfd_elf32_i386_vec,
|
||||
&bfd_elf32_i860_vec,
|
||||
#if 0 /* No one seems to use this. */
|
||||
&bfd_elf32_little_generic_vec,
|
||||
&bfd_elf32_littlemips_vec,
|
||||
#endif
|
||||
&bfd_elf32_m68k_vec,
|
||||
&bfd_elf32_m88k_vec,
|
||||
&bfd_elf32_sparc_vec,
|
||||
#ifdef BFD64 /* No one seems to use this. */
|
||||
&bfd_elf64_big_generic_vec,
|
||||
&bfd_elf64_little_generic_vec,
|
||||
#endif
|
||||
#ifdef BFD64
|
||||
&demo_64_vec, /* Only compiled if host has long-long support */
|
||||
#endif
|
||||
&ecoff_big_vec,
|
||||
&ecoff_little_vec,
|
||||
#if 0
|
||||
&ecoffalpha_little_vec,
|
||||
#endif
|
||||
&h8300coff_vec,
|
||||
&h8500coff_vec,
|
||||
#if 0
|
||||
&host_aout_vec,
|
||||
#endif
|
||||
#if 0 /* Clashes with sunos_big_vec magic no. */
|
||||
&hp300bsd_vec,
|
||||
#endif
|
||||
&hp300hpux_vec,
|
||||
#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
|
||||
&hppa_vec,
|
||||
#endif
|
||||
&i386aout_vec,
|
||||
&i386bsd_vec,
|
||||
&netbsd386_vec,
|
||||
&i386coff_vec,
|
||||
#if 0
|
||||
&i386linux_vec,
|
||||
#endif
|
||||
&i386lynx_aout_vec,
|
||||
&i386lynx_coff_vec,
|
||||
&icoff_big_vec,
|
||||
&icoff_little_vec,
|
||||
&ieee_vec,
|
||||
&m68kcoff_vec,
|
||||
&m68kcoffun_vec,
|
||||
&m68klynx_aout_vec,
|
||||
&m68klynx_coff_vec,
|
||||
&m88kbcs_vec,
|
||||
&newsos3_vec,
|
||||
#if 0 /* No one seems to use this. */
|
||||
&nlm32_big_generic_vec,
|
||||
#endif
|
||||
&nlm32_i386_vec,
|
||||
#if 0 /* No one seems to use this. */
|
||||
&nlm32_little_generic_vec,
|
||||
#endif
|
||||
#ifdef BFD64
|
||||
&nlm64_big_generic_vec,
|
||||
&nlm64_little_generic_vec,
|
||||
#endif
|
||||
#if 0
|
||||
/* We have no oasys tools anymore, so we can't test any of this
|
||||
anymore. If you want to test the stuff yourself, go ahead...
|
||||
steve@cygnus.com
|
||||
Worse, since there is no magic number for archives, there
|
||||
can be annoying target mis-matches. */
|
||||
&oasys_vec,
|
||||
#endif
|
||||
&rs6000coff_vec,
|
||||
&shcoff_vec,
|
||||
&sunos_big_vec,
|
||||
#if 0
|
||||
&tekhex_vec,
|
||||
#endif
|
||||
&we32kcoff_vec,
|
||||
&z8kcoff_vec,
|
||||
|
||||
#endif /* not SELECT_VECS */
|
||||
|
||||
/* Always support S-records, for convenience. */
|
||||
&srec_vec,
|
||||
&symbolsrec_vec,
|
||||
|
||||
/* Add any required traditional-core-file-handler. */
|
||||
|
||||
#ifdef AIX386_CORE
|
||||
&aix386_core_vec,
|
||||
#endif
|
||||
#ifdef HPUX_CORE
|
||||
&hpux_core_vec,
|
||||
#endif
|
||||
#ifdef OSF_CORE
|
||||
&osf_core_vec,
|
||||
#endif
|
||||
#ifdef SCO_CORE
|
||||
&sco_core_vec,
|
||||
#endif
|
||||
#ifdef TRAD_CORE
|
||||
&trad_core_vec,
|
||||
#endif
|
||||
|
||||
NULL /* end of list marker */
|
||||
};
|
||||
|
||||
/* default_vector[0] contains either the address of the default vector,
|
||||
if there is one, or zero if there isn't. */
|
||||
|
||||
bfd_target *default_vector[] = {
|
||||
#ifdef DEFAULT_VECTOR
|
||||
&DEFAULT_VECTOR,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_find_target
|
||||
|
||||
DESCRIPTION
|
||||
Returns a pointer to the transfer vector for the object target
|
||||
named target_name. If target_name is NULL, chooses the one in
|
||||
the environment variable GNUTARGET; if that is null or not
|
||||
defined thenthe first entry in the target list is chosen.
|
||||
Passing in the string "default" or setting the environment
|
||||
variable to "default" will cause the first entry in the target
|
||||
list to be returned, and "target_defaulted" will be set in the
|
||||
BFD. This causes <<bfd_check_format>> to loop over all the
|
||||
targets to find the one that matches the file being read.
|
||||
|
||||
SYNOPSIS
|
||||
bfd_target *bfd_find_target(CONST char *, bfd *);
|
||||
*/
|
||||
|
||||
bfd_target *
|
||||
DEFUN(bfd_find_target,(target_name, abfd),
|
||||
CONST char *target_name AND
|
||||
bfd *abfd)
|
||||
{
|
||||
bfd_target **target;
|
||||
extern char *getenv ();
|
||||
CONST char *targname = (target_name ? target_name :
|
||||
(CONST char *) getenv ("GNUTARGET"));
|
||||
|
||||
/* This is safe; the vector cannot be null */
|
||||
if (targname == NULL || !strcmp (targname, "default")) {
|
||||
abfd->target_defaulted = true;
|
||||
return abfd->xvec = target_vector[0];
|
||||
}
|
||||
|
||||
abfd->target_defaulted = false;
|
||||
|
||||
for (target = &target_vector[0]; *target != NULL; target++) {
|
||||
if (!strcmp (targname, (*target)->name))
|
||||
return abfd->xvec = *target;
|
||||
}
|
||||
|
||||
bfd_error = invalid_target;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_target_list
|
||||
|
||||
DESCRIPTION
|
||||
This function returns a freshly malloced NULL-terminated
|
||||
vector of the names of all the valid BFD targets. Do not
|
||||
modify the names
|
||||
|
||||
SYNOPSIS
|
||||
CONST char **bfd_target_list(void);
|
||||
|
||||
*/
|
||||
|
||||
CONST char **
|
||||
DEFUN_VOID(bfd_target_list)
|
||||
{
|
||||
int vec_length= 0;
|
||||
#ifdef NATIVE_HPPAHPUX_COMPILER
|
||||
/* The native compiler on the HP9000/700 has a bug which causes it
|
||||
to loop endlessly when compiling this file. This avoids it. */
|
||||
volatile
|
||||
#endif
|
||||
bfd_target **target;
|
||||
CONST char **name_list, **name_ptr;
|
||||
|
||||
for (target = &target_vector[0]; *target != NULL; target++)
|
||||
vec_length++;
|
||||
|
||||
name_ptr =
|
||||
name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **));
|
||||
|
||||
if (name_list == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (target = &target_vector[0]; *target != NULL; target++)
|
||||
*(name_ptr++) = (*target)->name;
|
||||
|
||||
return name_list;
|
||||
}
|
|
@ -0,0 +1,380 @@
|
|||
/* BFD back end for traditional Unix core files (U-area and raw sections)
|
||||
Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
Written by John Gilmore of Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: trad-core.c,v 1.1 1994/01/28 12:38:14 pk Exp $
|
||||
*/
|
||||
|
||||
/* To use this file on a particular host, configure the host with these
|
||||
parameters in the config/h-HOST file:
|
||||
|
||||
HDEFINES=-DTRAD_CORE
|
||||
HDEPFILES=trad-core.o
|
||||
|
||||
*/
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "libaout.h" /* BFD a.out internal data structures */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/user.h> /* After a.out.h */
|
||||
#if 0
|
||||
/* file.h is included by std-host.h. So we better not try to include it
|
||||
twice; on some systems (dpx2) it is not protected against multiple
|
||||
inclusion. I have checked that all the hosts which use this file
|
||||
include sys/file.h in the hosts file. */
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
struct trad_core_struct
|
||||
{
|
||||
asection *data_section;
|
||||
asection *stack_section;
|
||||
asection *reg_section;
|
||||
struct user u;
|
||||
} *rawptr;
|
||||
|
||||
#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
|
||||
#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
|
||||
#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
|
||||
#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
bfd_target * trad_unix_core_file_p PARAMS ((bfd *abfd));
|
||||
char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd));
|
||||
int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd));
|
||||
boolean trad_unix_core_file_matches_executable_p
|
||||
PARAMS ((bfd *core_bfd, bfd *exec_bfd));
|
||||
|
||||
/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
|
||||
|
||||
/* ARGSUSED */
|
||||
bfd_target *
|
||||
trad_unix_core_file_p (abfd)
|
||||
bfd *abfd;
|
||||
|
||||
{
|
||||
int val;
|
||||
struct user u;
|
||||
|
||||
#ifdef TRAD_CORE_USER_OFFSET
|
||||
/* If defined, this macro is the file position of the user struct. */
|
||||
if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
val = bfd_read ((void *)&u, 1, sizeof u, abfd);
|
||||
if (val != sizeof u)
|
||||
{
|
||||
/* Too small to be a core file */
|
||||
bfd_error = wrong_format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check perhaps??? */
|
||||
if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
|
||||
{
|
||||
bfd_error = wrong_format;
|
||||
return 0;
|
||||
}
|
||||
if (u.u_ssize > 0x1000000)
|
||||
{
|
||||
bfd_error = wrong_format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that the size claimed is no greater than the file size. */
|
||||
{
|
||||
FILE *stream = bfd_cache_lookup (abfd);
|
||||
struct stat statbuf;
|
||||
if (stream == NULL)
|
||||
return 0;
|
||||
if (fstat (fileno (stream), &statbuf) < 0)
|
||||
{
|
||||
bfd_error = system_call_error;
|
||||
return 0;
|
||||
}
|
||||
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
|
||||
{
|
||||
bfd_error = file_truncated;
|
||||
return 0;
|
||||
}
|
||||
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
|
||||
#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
|
||||
/* Some systems write the file too big. */
|
||||
+ TRAD_CORE_EXTRA_SIZE_ALLOWED
|
||||
#endif
|
||||
< statbuf.st_size)
|
||||
{
|
||||
/* The file is too big. Maybe it's not a core file
|
||||
or we otherwise have bad values for u_dsize and u_ssize). */
|
||||
bfd_error = wrong_format;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, we believe you. You're a core file (sure, sure). */
|
||||
|
||||
/* Allocate both the upage and the struct core_data at once, so
|
||||
a single free() will free them both. */
|
||||
rawptr = (struct trad_core_struct *)
|
||||
bfd_zalloc (abfd, sizeof (struct trad_core_struct));
|
||||
if (rawptr == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return 0;
|
||||
}
|
||||
|
||||
abfd->tdata.trad_core_data = rawptr;
|
||||
|
||||
rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
|
||||
|
||||
/* Create the sections. This is raunchy, but bfd_close wants to free
|
||||
them separately. */
|
||||
|
||||
core_stacksec(abfd) = (asection *) zalloc (sizeof (asection));
|
||||
if (core_stacksec (abfd) == NULL) {
|
||||
loser:
|
||||
bfd_error = no_memory;
|
||||
free ((void *)rawptr);
|
||||
return 0;
|
||||
}
|
||||
core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
|
||||
if (core_datasec (abfd) == NULL) {
|
||||
loser1:
|
||||
free ((void *)core_stacksec (abfd));
|
||||
goto loser;
|
||||
}
|
||||
core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
|
||||
if (core_regsec (abfd) == NULL) {
|
||||
free ((void *)core_datasec (abfd));
|
||||
goto loser1;
|
||||
}
|
||||
|
||||
core_stacksec (abfd)->name = ".stack";
|
||||
core_datasec (abfd)->name = ".data";
|
||||
core_regsec (abfd)->name = ".reg";
|
||||
|
||||
core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
|
||||
core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
|
||||
core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
|
||||
|
||||
core_datasec (abfd)->_raw_size = NBPG * u.u_dsize;
|
||||
core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
|
||||
core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
|
||||
|
||||
/* What a hack... we'd like to steal it from the exec file,
|
||||
since the upage does not seem to provide it. FIXME. */
|
||||
#ifdef HOST_DATA_START_ADDR
|
||||
core_datasec (abfd)->vma = HOST_DATA_START_ADDR;
|
||||
#else
|
||||
core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
|
||||
#endif
|
||||
|
||||
#ifdef HOST_STACK_START_ADDR
|
||||
core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
|
||||
#else
|
||||
core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
|
||||
#endif
|
||||
|
||||
/* This is tricky. As the "register section", we give them the entire
|
||||
upage and stack. u.u_ar0 points to where "register 0" is stored.
|
||||
There are two tricks with this, though. One is that the rest of the
|
||||
registers might be at positive or negative (or both) displacements
|
||||
from *u_ar0. The other is that u_ar0 is sometimes an absolute address
|
||||
in kernel memory, and on other systems it is an offset from the beginning
|
||||
of the `struct user'.
|
||||
|
||||
As a practical matter, we don't know where the registers actually are,
|
||||
so we have to pass the whole area to GDB. We encode the value of u_ar0
|
||||
by setting the .regs section up so that its virtual memory address
|
||||
0 is at the place pointed to by u_ar0 (by setting the vma of the start
|
||||
of the section to -u_ar0). GDB uses this info to locate the regs,
|
||||
using minor trickery to get around the offset-or-absolute-addr problem. */
|
||||
core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
|
||||
|
||||
core_datasec (abfd)->filepos = NBPG * UPAGES;
|
||||
#ifdef TRAD_CORE_STACK_FILEPOS
|
||||
core_stacksec (abfd)->filepos = TRAD_CORE_STACK_FILEPOS;
|
||||
#else
|
||||
core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
|
||||
#endif
|
||||
core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
|
||||
|
||||
/* Align to word at least */
|
||||
core_stacksec (abfd)->alignment_power = 2;
|
||||
core_datasec (abfd)->alignment_power = 2;
|
||||
core_regsec (abfd)->alignment_power = 2;
|
||||
|
||||
abfd->sections = core_stacksec (abfd);
|
||||
core_stacksec (abfd)->next = core_datasec (abfd);
|
||||
core_datasec (abfd)->next = core_regsec (abfd);
|
||||
abfd->section_count = 3;
|
||||
|
||||
return abfd->xvec;
|
||||
}
|
||||
|
||||
char *
|
||||
trad_unix_core_file_failing_command (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
#ifndef NO_CORE_COMMAND
|
||||
char *com = abfd->tdata.trad_core_data->u.u_comm;
|
||||
if (*com)
|
||||
return com;
|
||||
else
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
trad_unix_core_file_failing_signal (ignore_abfd)
|
||||
bfd *ignore_abfd;
|
||||
{
|
||||
#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
|
||||
return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
|
||||
#else
|
||||
return -1; /* FIXME, where is it? */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
boolean
|
||||
trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
|
||||
bfd *core_bfd, *exec_bfd;
|
||||
{
|
||||
return true; /* FIXME, We have no way of telling at this point */
|
||||
}
|
||||
|
||||
/* No archive file support via this BFD */
|
||||
#define trad_unix_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define trad_unix_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define trad_unix_slurp_armap bfd_false
|
||||
#define trad_unix_slurp_extended_name_table bfd_true
|
||||
#define trad_unix_write_armap (boolean (*) PARAMS \
|
||||
((bfd *arch, unsigned int elength, struct orl *map, \
|
||||
unsigned int orl_count, int stridx))) bfd_false
|
||||
#define trad_unix_truncate_arname bfd_dont_truncate_arname
|
||||
#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
|
||||
#define trad_unix_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
#define trad_unix_set_section_contents (boolean (*) PARAMS \
|
||||
((bfd *abfd, asection *section, PTR data, file_ptr offset, \
|
||||
bfd_size_type count))) bfd_false
|
||||
#define trad_unix_get_section_contents bfd_generic_get_section_contents
|
||||
#define trad_unix_new_section_hook (boolean (*) PARAMS \
|
||||
((bfd *, sec_ptr))) bfd_true
|
||||
#define trad_unix_get_symtab_upper_bound bfd_0u
|
||||
#define trad_unix_get_symtab (unsigned int (*) PARAMS \
|
||||
((bfd *, struct symbol_cache_entry **))) bfd_0u
|
||||
#define trad_unix_get_reloc_upper_bound (unsigned int (*) PARAMS \
|
||||
((bfd *, sec_ptr))) bfd_0u
|
||||
#define trad_unix_canonicalize_reloc (unsigned int (*) PARAMS \
|
||||
((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
|
||||
#define trad_unix_make_empty_symbol (struct symbol_cache_entry * \
|
||||
(*) PARAMS ((bfd *))) bfd_false
|
||||
#define trad_unix_print_symbol (void (*) PARAMS \
|
||||
((bfd *, PTR, struct symbol_cache_entry *, \
|
||||
bfd_print_symbol_type))) bfd_false
|
||||
#define trad_unix_get_symbol_info (void (*) PARAMS \
|
||||
((bfd *, struct symbol_cache_entry *, \
|
||||
symbol_info *))) bfd_false
|
||||
#define trad_unix_get_lineno (alent * (*) PARAMS \
|
||||
((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
|
||||
#define trad_unix_set_arch_mach (boolean (*) PARAMS \
|
||||
((bfd *, enum bfd_architecture, unsigned long))) bfd_false
|
||||
#define trad_unix_find_nearest_line (boolean (*) PARAMS \
|
||||
((bfd *abfd, struct sec *section, \
|
||||
struct symbol_cache_entry **symbols,bfd_vma offset, \
|
||||
CONST char **file, CONST char **func, unsigned int *line))) bfd_false
|
||||
#define trad_unix_sizeof_headers (int (*) PARAMS \
|
||||
((bfd *, boolean))) bfd_0
|
||||
|
||||
#define trad_unix_bfd_debug_info_start bfd_void
|
||||
#define trad_unix_bfd_debug_info_end bfd_void
|
||||
#define trad_unix_bfd_debug_info_accumulate (void (*) PARAMS \
|
||||
((bfd *, struct sec *))) bfd_void
|
||||
#define trad_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
|
||||
#define trad_unix_bfd_relax_section bfd_generic_relax_section
|
||||
#define trad_unix_bfd_seclet_link \
|
||||
((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
|
||||
#define trad_unix_bfd_reloc_type_lookup \
|
||||
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
|
||||
#define trad_unix_bfd_make_debug_symbol \
|
||||
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
|
||||
|
||||
/* If somebody calls any byte-swapping routines, shoot them. */
|
||||
void
|
||||
swap_abort()
|
||||
{
|
||||
abort(); /* This way doesn't require any declaration for ANSI to fuck up */
|
||||
}
|
||||
#define NO_GET ((bfd_vma (*) PARAMS (( bfd_byte *))) swap_abort )
|
||||
#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
|
||||
#define NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
|
||||
|
||||
bfd_target trad_core_vec =
|
||||
{
|
||||
"trad-core",
|
||||
bfd_target_unknown_flavour,
|
||||
true, /* target byte order */
|
||||
true, /* target headers byte order */
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
|
||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
0, /* symbol prefix */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
3, /* minimum alignment power */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
|
||||
NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
|
||||
|
||||
{ /* bfd_check_format */
|
||||
_bfd_dummy_target, /* unknown format */
|
||||
_bfd_dummy_target, /* object file */
|
||||
_bfd_dummy_target, /* archive */
|
||||
trad_unix_core_file_p /* a core file */
|
||||
},
|
||||
{ /* bfd_set_format */
|
||||
bfd_false, bfd_false,
|
||||
bfd_false, bfd_false
|
||||
},
|
||||
{ /* bfd_write_contents */
|
||||
bfd_false, bfd_false,
|
||||
bfd_false, bfd_false
|
||||
},
|
||||
|
||||
JUMP_TABLE(trad_unix),
|
||||
(PTR) 0 /* backend_data */
|
||||
};
|
Loading…
Reference in New Issue