mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 06:17:47 +08:00
Now full of documentation. Yum Yum.
This commit is contained in:
@ -28,7 +28,9 @@ echo Sanitizing `pwd`...
|
||||
Things-to-keep:
|
||||
|
||||
COPYING
|
||||
bfd.texinfo
|
||||
ChangeLog
|
||||
Makefile
|
||||
Makefile.in
|
||||
TODO
|
||||
VERSION
|
||||
@ -40,19 +42,17 @@ archive.c
|
||||
archures.c
|
||||
archures.h
|
||||
bfd.c
|
||||
bfd.doc
|
||||
bout.c
|
||||
cache.c
|
||||
coffcode.h
|
||||
coffish.h
|
||||
coffswap.c
|
||||
config
|
||||
configure
|
||||
config.status
|
||||
configure*
|
||||
configure.in
|
||||
cplus-dem.c
|
||||
core.c
|
||||
demo64.c
|
||||
ecoff.c
|
||||
filemode.c
|
||||
format.c
|
||||
host-aout.c
|
||||
i386coff.c
|
||||
icoff.c
|
||||
@ -65,12 +65,14 @@ libieee.h
|
||||
liboasys.h
|
||||
m68kcoff.c
|
||||
m88k-bcs.c
|
||||
misc.h
|
||||
newsos3.c
|
||||
oasys.c
|
||||
opncls.c
|
||||
reloc.c
|
||||
section.c
|
||||
srec.c
|
||||
sunos.c
|
||||
syms.c
|
||||
targets.c
|
||||
trad-core.c
|
||||
trad-core.h
|
||||
@ -82,6 +84,9 @@ echo Done in `pwd`.
|
||||
#
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.4 1991/07/04 16:52:54 steve
|
||||
# Now full of documentation. Yum Yum.
|
||||
#
|
||||
# Revision 1.3 1991/05/31 11:22:12 gnu
|
||||
# Remove coff-code.h and liba.out.h, add libaout.h.
|
||||
#
|
||||
|
@ -20,6 +20,8 @@
|
||||
# $Id$
|
||||
|
||||
srcdir = .
|
||||
destdir = /usr/local
|
||||
libdir = $(destdir)/lib
|
||||
|
||||
RANLIB = ranlib
|
||||
AR = ar
|
||||
@ -35,18 +37,21 @@ CFLAGS = -g $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION
|
||||
|
||||
|
||||
BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \
|
||||
archures.o
|
||||
archures.o core.o section.o format.o syms.o reloc.o
|
||||
|
||||
BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o demo64.o \
|
||||
m68kcoff.o i386coff.o m88k-bcs.o coffswap.o ecoff.o newsos3.o # trad-core.o bout.o
|
||||
BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o \
|
||||
demo64.o \
|
||||
m68kcoff.o i386coff.o m88k-bcs.o ecoff.o newsos3.o # trad-core.o bout.o
|
||||
|
||||
BFD_H=$(INCDIR)/bfd.h
|
||||
SYSDEP_H=$(INCDIR)/sysdep.h
|
||||
|
||||
# C source files that correspond to .o's.
|
||||
CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
|
||||
i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c oasys.c ieee.c m68kcoff.c \
|
||||
m88k-bcs.c coffswap.c ecoff.c trad-core.c newsos3.c #bout.c
|
||||
i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \
|
||||
oasys.c ieee.c m68kcoff.c \
|
||||
format.c section.c core.c syms.c reloc.c \
|
||||
m88k-bcs.c ecoff.c trad-core.c newsos3.c #bout.c
|
||||
|
||||
STAGESTUFF = $(TARGETLIB) $(OFILES)
|
||||
|
||||
@ -149,6 +154,8 @@ roll:
|
||||
force:
|
||||
|
||||
install:
|
||||
install -c libbfd.a $(libdir)
|
||||
$(RANLIB) $(libdir)/libbfd.a
|
||||
|
||||
# Target to uncomment host-specific lines in this makefile. Such lines must
|
||||
# have the following string beginning in column 1: #__<hostname>__#
|
||||
@ -181,3 +188,81 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/configure
|
||||
|
||||
dep: $(CFILES)
|
||||
mkdep $(CFLAGS) $?
|
||||
|
||||
|
||||
# Stuff to make the documentation for bfd.
|
||||
#
|
||||
# make docs
|
||||
# rebuilds the documentation. Has to be done when the source is
|
||||
# modified until I work out how to do this properly
|
||||
#
|
||||
# make docs headers
|
||||
# rebuilds the header files from the source
|
||||
#
|
||||
# make docs texdoc
|
||||
# rebuilds the bfd.dvi manual
|
||||
#
|
||||
# make docs texinfo
|
||||
# rebuilts the bfdinfo manual
|
||||
|
||||
|
||||
.SUFFIXES: .doc .o .c .h .proto
|
||||
|
||||
.c.doc:
|
||||
makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
|
||||
|
||||
.h.doc:
|
||||
makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
|
||||
|
||||
.proto.doc:
|
||||
makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
|
||||
|
||||
|
||||
DSRC=$(CFILES)
|
||||
|
||||
docs: syms.doc bfd.doc cache.doc format.doc section.doc archive.doc \
|
||||
core.doc libbfd.doc archures.doc reloc.doc opncls.doc \
|
||||
targets.doc aoutx.doc coffcode.doc
|
||||
|
||||
|
||||
PROTOS = doc/opncls.proto doc/archures.proto doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \
|
||||
doc/reloc.proto doc/targets.proto doc/format.proto
|
||||
|
||||
|
||||
headers : $(PROTOS)
|
||||
mkdir -f doc
|
||||
# Rebuild prototypes in bfd.h
|
||||
sed <$(BFD_H) >bfd.h.new -e '1,/THE FOLLOWING/!d'
|
||||
cat doc/opncls.proto doc/archures.proto \
|
||||
doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \
|
||||
doc/reloc.proto doc/targets.proto doc/format.proto >>bfd.h.new
|
||||
echo >> bfd.h.new
|
||||
echo "#endif" >> bfd.h.new
|
||||
echo >> bfd.h.new
|
||||
mv bfd.h.new $(BFD_H)
|
||||
|
||||
# and libbfd.h
|
||||
sed < libbfd.h >libbfd.h.new -e '1,/THE FOLLOWING/!d'
|
||||
cat doc/libbfd.protointernal doc/cache.protointernal doc/reloc.protointernal >> libbfd.h.new
|
||||
echo >> libbfd.h.new
|
||||
mv libbfd.h.new libbfd.h
|
||||
|
||||
# and libcoff.h
|
||||
sed < $(srcdir)/libcoff.h >libcoff.h.new -e '1,/THE FOLLOWING/!d'
|
||||
cat doc/coffcode.proto >>libcoff.h.new
|
||||
mv libcoff.h.new $(srcdir)/libcoff.h
|
||||
|
||||
|
||||
texinfo:
|
||||
makeinfo +no-validate bfd.texinfo
|
||||
|
||||
texdoc:
|
||||
tex bfd.texinfo
|
||||
texindex bfd.??
|
||||
tex bfd.texinfo
|
||||
|
||||
quickdoc: $(DSRC) docs
|
||||
tex bfd.texinfo
|
||||
|
||||
|
||||
|
||||
|
43
bfd/aoutf1.h
43
bfd/aoutf1.h
@ -1,5 +1,3 @@
|
||||
/* BFD backend for generic a.out flavour 1 */
|
||||
|
||||
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Diddler.
|
||||
@ -18,6 +16,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with BFD; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <ansidecl.h>
|
||||
#include <sysdep.h>
|
||||
struct external_exec;
|
||||
@ -33,6 +32,33 @@ struct external_exec;
|
||||
#include "ar.h"
|
||||
|
||||
|
||||
/*
|
||||
inheritd two core files and various implimentation files.
|
||||
The file @code{aoutf1.h} contains the code for BFD's
|
||||
a.out back end. Control over the generated back end is given by these
|
||||
three preprocessor names:
|
||||
@table @code
|
||||
@item ARCH
|
||||
This value should be either 32 or 64, depending upon the size of an
|
||||
int in the target format. It changes the sizes of the structs which
|
||||
perform the memory/disk mapping of structures.
|
||||
|
||||
The 64 bit backend may only be used if the host compiler supports 64
|
||||
ints (eg with gcc), by defining the name @code{HOST_64_BIT}. With this
|
||||
name defined, @emph{all} bfd operations are performed with 64bit
|
||||
arithmetic, not just those to a 64bit target.
|
||||
|
||||
@item TARGETNAME
|
||||
bit long longsIf bfd is being compiled with gcc, (or any other compiler which gives
|
||||
64 bit long longs),
|
||||
@item
|
||||
It is structured in such a way that @code{#define}ing
|
||||
the size of the architecture into a @code{#include}ing
|
||||
it with different @code{#define}s present will alter the definitions
|
||||
of various structures in include files and generate correct code for
|
||||
th
|
||||
|
||||
*/
|
||||
|
||||
void (*bfd_error_trap)();
|
||||
|
||||
@ -177,7 +203,7 @@ DEFUN(NAME(aout,sunos4_write_object_contents),(abfd),
|
||||
choose_reloc_size(abfd);
|
||||
|
||||
/* FIXME */
|
||||
N_SET_FLAGS (*execp, 0x81);
|
||||
N_SET_FLAGS (*execp, 0x1);
|
||||
|
||||
WRITE_HEADERS(abfd, execp);
|
||||
|
||||
@ -461,6 +487,16 @@ DEFUN(swapcore,(abfd, core),
|
||||
#define aout_64_core_file_failing_signal sunos4_core_file_failing_signal
|
||||
#define aout_64_core_file_matches_executable_p sunos4_core_file_matches_executable_p
|
||||
|
||||
#define aout_64_bfd_debug_info_start bfd_void
|
||||
#define aout_64_bfd_debug_info_end bfd_void
|
||||
#define aout_64_bfd_debug_info_accumulate bfd_void
|
||||
|
||||
#define aout_32_bfd_debug_info_start bfd_void
|
||||
#define aout_32_bfd_debug_info_end bfd_void
|
||||
#define aout_32_bfd_debug_info_accumulate bfd_void
|
||||
|
||||
|
||||
|
||||
/* We implement these routines ourselves, rather than using the generic
|
||||
a.out versions. */
|
||||
#define aout_write_object_contents sunos4_write_object_contents
|
||||
@ -477,6 +513,7 @@ TARGETNAME,
|
||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
3, /* minimum alignment power */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
|
||||
|
151
bfd/aoutx.h
151
bfd/aoutx.h
@ -20,13 +20,69 @@ along with BFD; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/*doc*
|
||||
@section a.out backends
|
||||
|
||||
BFD supports a number of different flavours of a.out format, though
|
||||
the major differences are only the sizes of the structures on disk,
|
||||
and the shape of the relocation information.
|
||||
|
||||
The support is split into a basic support file @code{aoutx.h} and
|
||||
other files which derive functions from the base. One derivation file
|
||||
is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
|
||||
functions support for sun3, sun4, 386 and 29k a.out files, to create a
|
||||
target jump vector for a specific target.
|
||||
|
||||
This information is further split out into more specific files for each
|
||||
machine, including @code{sunos.c} - for sun3 and sun4 and
|
||||
@code{demo64} for a demonstration of a 64 bit a.out format.
|
||||
|
||||
The base file @code{aoutx.h} defines general mechanisms for reading
|
||||
and writing records to and from disk, and various other methods which
|
||||
bfd requires. It is included by @code{aout32.c} and @code{aout64.c} to
|
||||
form the names aout_32_swap_exec_header_in,
|
||||
aout_64_swap_exec_header_in, etc.
|
||||
|
||||
As an example, this is what goes on to make the back end for a sun4, from aout32.c
|
||||
|
||||
@example
|
||||
#define ARCH_SIZE 32
|
||||
#include "aoutx.h"
|
||||
@end example
|
||||
|
||||
Which exports names:
|
||||
@example
|
||||
...
|
||||
aout_32_canonicalize_reloc
|
||||
aout_32_find_nearest_line
|
||||
aout_32_get_lineno
|
||||
aout_32_get_reloc_upper_bound
|
||||
...
|
||||
@end example
|
||||
|
||||
from sunos.c
|
||||
|
||||
@example
|
||||
#define ARCH 32
|
||||
#define TARGET_NAME "a.out-sunos-big"
|
||||
#define VECNAME sunos_big_vec
|
||||
#include "aoutf1.h"
|
||||
@end example
|
||||
requires all the names from aout32.c, and produces the jump vector
|
||||
|
||||
@example
|
||||
sunos_big_vec
|
||||
@end example
|
||||
|
||||
*/
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <ansidecl.h>
|
||||
|
||||
|
||||
#include "bfd.h"
|
||||
struct external_exec;
|
||||
#include "liba.out.h"
|
||||
#include "libaout.h"
|
||||
#include "libbfd.h"
|
||||
#include "aout64.h"
|
||||
#include "stab.gnu.h"
|
||||
@ -34,9 +90,15 @@ struct external_exec;
|
||||
|
||||
void (*bfd_error_trap)();
|
||||
|
||||
/*SUPPRESS558*/
|
||||
/*SUPPRESS529*/
|
||||
/*doc*
|
||||
@subsection relocations
|
||||
The file @code{aoutx.h} caters for both the @emph{standard} and
|
||||
@emph{extended} forms of a.out relocation records.
|
||||
|
||||
The standard records are characterised by containing only an address,
|
||||
a symbol index and a type field. The extended records (used on 29ks
|
||||
and sparcs) also have a full integer for an addend.
|
||||
*/
|
||||
#define CTOR_TABLE_RELOC_IDX 2
|
||||
static reloc_howto_type howto_table_ext[] =
|
||||
{
|
||||
@ -85,6 +147,24 @@ HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedfac
|
||||
|
||||
|
||||
bfd_error_vector_type bfd_error_vector;
|
||||
|
||||
/*doc*
|
||||
@subsection Internal Entry Points
|
||||
@code{aoutx.h} exports several routines for accessing the contents of
|
||||
an a.out file, which are gathered and exported in turn by various
|
||||
format specific files (eg sunos.c).
|
||||
*/
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_swap_exec_header_in
|
||||
Swaps the information in an executable header taken from a raw byte stream memory image,
|
||||
into the internal exec_header structure.
|
||||
*; PROTO(void, aout_<size>_swap_exec_header_in,
|
||||
(bfd *abfd,
|
||||
struct external_exec *raw_bytes,
|
||||
struct internal_exec *execp));
|
||||
*/
|
||||
|
||||
void
|
||||
DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
|
||||
bfd *abfd AND
|
||||
@ -104,6 +184,15 @@ DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
|
||||
execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
|
||||
}
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_swap_exec_header_out
|
||||
Swaps the information in an internal exec header structure into the
|
||||
supplied buffer ready for writing to disk.
|
||||
*; PROTO(void, aout_<size>_swap_exec_header_out,
|
||||
(bfd *abfd,
|
||||
struct internal_exec *execp,
|
||||
struct external_exec *raw_bytes));
|
||||
*/
|
||||
void
|
||||
DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
|
||||
bfd *abfd AND
|
||||
@ -128,10 +217,19 @@ struct container {
|
||||
struct internal_exec e;
|
||||
};
|
||||
|
||||
/* Some A.OUT variant thinks that the file whose format we're checking
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_some_aout_object_p
|
||||
|
||||
Some A.OUT variant thinks that the file whose format we're checking
|
||||
is an a.out file. Do some more checking, and set up for access if
|
||||
it really is. Call back to the calling environments "finish up"
|
||||
function just before returning, to handle any last-minute setup. */
|
||||
function just before returning, to handle any last-minute setup.
|
||||
|
||||
*; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
|
||||
(bfd *abfd,
|
||||
bfd_target *(*callback_to_real_object_p)()));
|
||||
*/
|
||||
|
||||
bfd_target *
|
||||
DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
|
||||
@ -282,6 +380,13 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
|
||||
return (*callback_to_real_object_p)(abfd);
|
||||
}
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_mkobject
|
||||
|
||||
This routine initializes a bfd for use with a.out files.
|
||||
|
||||
*; PROTO(boolean, aout_<size>_mkobject, (bfd *));
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(NAME(aout,mkobject),(abfd),
|
||||
@ -314,12 +419,21 @@ DEFUN(NAME(aout,mkobject),(abfd),
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Keep track of machine architecture and machine type for a.out's.
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_machine_type
|
||||
|
||||
Keep track of machine architecture and machine type for a.out's.
|
||||
Return the machine_type for a particular arch&machine, or M_UNKNOWN
|
||||
if that exact arch&machine can't be represented in a.out format.
|
||||
|
||||
If the architecture is understood, machine type 0 (default) should
|
||||
always be understood. */
|
||||
always be understood.
|
||||
|
||||
*; PROTO(enum machine_type, aout_<size>_machine_type,
|
||||
(enum bfd_architecture arch,
|
||||
unsigned long machine));
|
||||
*/
|
||||
|
||||
enum machine_type
|
||||
DEFUN(NAME(aout,machine_type),(arch, machine),
|
||||
@ -360,6 +474,19 @@ DEFUN(NAME(aout,machine_type),(arch, machine),
|
||||
return arch_flags;
|
||||
}
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>_set_arch_mach
|
||||
|
||||
Sets the architecture and the machine of the bfd to those values
|
||||
supplied. Verifies that the format can support the architecture
|
||||
required.
|
||||
|
||||
*; PROTO(boolean, aout_<size>_set_arch_mach,
|
||||
(bfd *,
|
||||
enum bfd_architecture,
|
||||
unsigned long machine));
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
|
||||
bfd *abfd AND
|
||||
@ -373,9 +500,15 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
|
||||
return false; /* We can't represent this type */
|
||||
return true; /* We're easy ... */
|
||||
}
|
||||
|
||||
/* exec and core file sections */
|
||||
|
||||
/*doc*
|
||||
*i aout_<size>new_section_hook
|
||||
|
||||
Called by the bfd in response to a @code{bfd_make_section} request.
|
||||
*; PROTO(boolean, aout_<size>_new_section_hook,
|
||||
(bfd *abfd,
|
||||
asection *newsect));
|
||||
*/
|
||||
boolean
|
||||
DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
|
||||
bfd *abfd AND
|
||||
|
103
bfd/archive.c
103
bfd/archive.c
@ -1,6 +1,4 @@
|
||||
|
||||
/*** archive.c -- an attempt at combining the machine-independent parts of
|
||||
archives */
|
||||
|
||||
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||
|
||||
@ -21,6 +19,21 @@ along with BFD; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/*doc*
|
||||
@setfilename archive-info
|
||||
@section Archives
|
||||
|
||||
Gumby, you promised to write this bit...
|
||||
|
||||
Archives are supported in bfd in @code{archive.c}.
|
||||
|
||||
An archive is represented internally just like another bfd, with a
|
||||
pointer to a chain of contained bfds. Archives can be created by
|
||||
opening bfds, linking them together and attatching them as children to
|
||||
another bfd and then closing the parent bfd.
|
||||
|
||||
*-*/
|
||||
|
||||
/* Assumes:
|
||||
o - all archive elements start on an even boundary, newline padded;
|
||||
o - all arch headers are char *;
|
||||
@ -72,6 +85,10 @@ _bfd_generic_mkarchive (abfd)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*proto* bfd_get_next_mapent
|
||||
What this does
|
||||
*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
|
||||
*/
|
||||
symindex
|
||||
bfd_get_next_mapent (abfd, prev, entry)
|
||||
bfd *abfd;
|
||||
@ -107,9 +124,16 @@ _bfd_create_empty_archive_element_shell (obfd)
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/*proto* bfd_set_archive_head
|
||||
Used whilst processing archives. Sets the head of the chain of bfds
|
||||
contained in an archive to @var{new_head}. (see chapter on archives)
|
||||
*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_set_archive_head (output_archive, new_head)
|
||||
bfd *output_archive, *new_head;
|
||||
DEFUN(bfd_set_archive_head,(output_archive, new_head),
|
||||
bfd *output_archive AND
|
||||
bfd *new_head)
|
||||
{
|
||||
|
||||
output_archive->archive_head = new_head;
|
||||
@ -229,8 +253,10 @@ snarf_ar_hdr (abfd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* extract the filename from the archive */
|
||||
if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
|
||||
/* extract the filename from the archive - there are two ways to
|
||||
specify an extendend name table, either the first char of the
|
||||
name is a space, or it's a slash */
|
||||
if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
|
||||
filename = get_extended_arelt_filename (abfd, hdr.ar_name);
|
||||
if (filename == NULL) {
|
||||
bfd_error = malformed_archive;
|
||||
@ -325,10 +351,22 @@ bfd_get_elt_at_index (abfd, index)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* If you've got an archive, call this to read each subfile. */
|
||||
/*proto* bfd_openr_next_archived_file
|
||||
Initially provided a bfd containing an archive and NULL, opens a bfd
|
||||
on the first contained element and returns that. Subsequent calls to
|
||||
bfd_openr_next_archived_file should pass the archive and the previous
|
||||
return value to return a created bfd to the next contained element.
|
||||
NULL is returned when there are no more.
|
||||
|
||||
*; PROTO(bfd*, bfd_openr_next_archived_file,
|
||||
(bfd *archive, bfd *previous));
|
||||
|
||||
*/
|
||||
|
||||
bfd *
|
||||
bfd_openr_next_archived_file (archive, last_file)
|
||||
bfd *archive, *last_file;
|
||||
DEFUN(bfd_openr_next_archived_file,(archive, last_file),
|
||||
bfd *archive AND
|
||||
bfd*last_file)
|
||||
{
|
||||
|
||||
if ((bfd_get_format (archive) != bfd_archive) ||
|
||||
@ -411,7 +449,7 @@ boolean
|
||||
bfd_slurp_bsd_armap (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
int i;
|
||||
|
||||
struct areltdata *mapdata;
|
||||
char nextname[17];
|
||||
unsigned int counter = 0;
|
||||
@ -451,7 +489,7 @@ bfd_slurp_bsd_armap (abfd)
|
||||
goto byebye;
|
||||
}
|
||||
|
||||
ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef);
|
||||
ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
|
||||
ardata->cache = 0;
|
||||
rbase = raw_armap+1;
|
||||
ardata->symdefs = (carsym *) rbase;
|
||||
@ -459,8 +497,8 @@ bfd_slurp_bsd_armap (abfd)
|
||||
|
||||
for (;counter < ardata->symdef_count; counter++) {
|
||||
struct symdef *sym = ((struct symdef *) rbase) + counter;
|
||||
sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
|
||||
sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
|
||||
sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
|
||||
sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
|
||||
}
|
||||
|
||||
ardata->first_file_filepos = bfd_tell (abfd);
|
||||
@ -501,13 +539,16 @@ bfd_slurp_coff_armap (abfd)
|
||||
if (mapdata == NULL) return false;
|
||||
|
||||
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
|
||||
if (raw_armap == NULL) {
|
||||
|
||||
if (raw_armap == NULL)
|
||||
{
|
||||
bfd_error = no_memory;
|
||||
byebye:
|
||||
bfd_release (abfd, (PTR)mapdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read in the raw map */
|
||||
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
|
||||
mapdata->parsed_size) {
|
||||
bfd_error = malformed_archive;
|
||||
@ -552,19 +593,22 @@ bfd_slurp_coff_armap (abfd)
|
||||
ardata->first_file_filepos = bfd_tell (abfd);
|
||||
/* Pad to an even boundary if you have to */
|
||||
ardata->first_file_filepos += (ardata->first_file_filepos) %2;
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
bfd_release (abfd, (PTR)mapdata);
|
||||
|
||||
/* bfd_release (abfd, (PTR)raw_armap);
|
||||
bfd_release (abfd, (PTR)mapdata);*/
|
||||
bfd_has_map (abfd) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Extended name table.
|
||||
|
||||
Normally archives support only 14-character filenames. Intel has extended
|
||||
the format: longer names are stored in a special element (the first in the
|
||||
archive, or second if there is an armap); the name in the ar_hdr is replaced
|
||||
by <space><index into filename element>. Index is the P.R. of an int (radix:
|
||||
8). */
|
||||
Normally archives support only 14-character filenames.
|
||||
|
||||
Intel has extended the format: longer names are stored in a special
|
||||
element (the first in the archive, or second if there is an armap);
|
||||
the name in the ar_hdr is replaced by <space><index into filename
|
||||
element>. Index is the P.R. of an int (radix: 8). Data General have
|
||||
extended the format by using the prefix // for the special element */
|
||||
|
||||
/* Returns false on error, true otherwise */
|
||||
boolean
|
||||
@ -580,7 +624,9 @@ _bfd_slurp_extended_name_table (abfd)
|
||||
|
||||
bfd_seek (abfd, -16L, SEEK_CUR);
|
||||
|
||||
if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
|
||||
if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
|
||||
strncmp (nextname, "// ", 16) != 0)
|
||||
{
|
||||
bfd_ardata (abfd)->extended_names = NULL;
|
||||
return true;
|
||||
}
|
||||
@ -604,8 +650,9 @@ _bfd_slurp_extended_name_table (abfd)
|
||||
goto byebye;
|
||||
}
|
||||
|
||||
/* It appears that the extended names are newline-padded, not null padded.
|
||||
*/
|
||||
/* Since the archive is supposed to be printable if it contains
|
||||
text, the entries in the list are newline-padded, not null
|
||||
padded. We'll fix that there.. */
|
||||
{
|
||||
char *temp = bfd_ardata (abfd)->extended_names;
|
||||
for (; *temp != '\0'; ++temp)
|
||||
@ -1127,7 +1174,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
|
||||
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
||||
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
|
||||
bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
|
||||
bfd_h_put_32(arch, ranlibsize, &temp);
|
||||
bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
|
||||
bfd_write (&temp, 1, sizeof (temp), arch);
|
||||
|
||||
for (count = 0; count < orl_count; count++) {
|
||||
@ -1143,13 +1190,13 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
|
||||
} /* if new archive element */
|
||||
|
||||
last_elt = current;
|
||||
bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
|
||||
bfd_h_put_32(arch, firstreal, &outs.file_offset);
|
||||
bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
|
||||
bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
|
||||
bfd_write ((char *)outp, 1, sizeof (outs), arch);
|
||||
}
|
||||
|
||||
/* now write the strings themselves */
|
||||
bfd_h_put_32(arch, stridx, &temp);
|
||||
bfd_h_put_32(arch, stridx, (PTR)&temp);
|
||||
bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
|
||||
for (count = 0; count < orl_count; count++)
|
||||
bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
|
||||
|
885
bfd/bfd.c
885
bfd/bfd.c
@ -1,11 +1,3 @@
|
||||
/* -*- C -*- */
|
||||
|
||||
/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
|
||||
Every definition in this file should be exported and declared
|
||||
in bfd.h. If you don't want it to be user-visible, put it in
|
||||
libbfd.c!
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Diddler.
|
||||
@ -24,11 +16,154 @@ You should have received a copy of the GNU General Public License
|
||||
along with BFD; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*proto*
|
||||
@section typedef bfd
|
||||
|
||||
Pointers to bfd structs are the cornerstone of any application using
|
||||
libbfd. References though the bfd and to data in the bfd give the
|
||||
entire bfd functionality.
|
||||
|
||||
Finally! The BFD struct itself. This contains the major data about
|
||||
the file, and contains pointers to the rest of the data.
|
||||
|
||||
*+++
|
||||
|
||||
$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 @xref{File Caching}.
|
||||
|
||||
$ 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 an LRU list of bfds.
|
||||
|
||||
$ struct _bfd *lru_prev, *lru_next;
|
||||
|
||||
When a file is closed by the caching routines, it retains the state
|
||||
here:
|
||||
|
||||
$ file_ptr where;
|
||||
|
||||
and here:
|
||||
|
||||
$ boolean opened_once;
|
||||
|
||||
$ boolean mtime_set;
|
||||
File modified time
|
||||
|
||||
$ long mtime;
|
||||
|
||||
For output files, channel we locked (is this used?).
|
||||
|
||||
$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 usefull for object files:
|
||||
The start address.
|
||||
|
||||
$ bfd_vma start_address;
|
||||
Used for input and output
|
||||
|
||||
$ unsigned int symcount;
|
||||
Symtab for output bfd
|
||||
|
||||
$ struct symbol_cache_entry **outsymbols;
|
||||
|
||||
Architecture of object machine, eg m68k
|
||||
|
||||
$ enum bfd_architecture obj_arch;
|
||||
|
||||
Particular machine within arch, e.g. 68010
|
||||
|
||||
$ unsigned long obj_machine;
|
||||
|
||||
Stuff only usefull 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.
|
||||
|
||||
$ PTR tdata;
|
||||
|
||||
Used by the application to hold private data
|
||||
|
||||
$ PTR usrdata;
|
||||
|
||||
Where all the allocated stuff under this BFD goes
|
||||
|
||||
$ struct obstack memory;
|
||||
$};
|
||||
|
||||
*---
|
||||
|
||||
*/
|
||||
#include <sysdep.h>
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
|
||||
short _bfd_host_big_endian = 0x0100;
|
||||
/* Accessing the above as (*(char*)&_bfd_host_big_endian), will
|
||||
return 1 if the host is big-endian, 0 otherwise.
|
||||
@ -136,415 +271,11 @@ DEFUN(bfd_perror,(message),
|
||||
}
|
||||
}
|
||||
|
||||
/* for error messages */
|
||||
char *
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
/** Target configurations */
|
||||
|
||||
extern bfd_target *target_vector[];
|
||||
extern bfd_target *default_vector[];
|
||||
|
||||
/* 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 then
|
||||
the 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. */
|
||||
|
||||
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 : 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;
|
||||
}
|
||||
|
||||
|
||||
/* Returns a freshly-consed, NULL-terminated vector of the names of all the
|
||||
valid bfd targets. Do not modify the names */
|
||||
|
||||
char **
|
||||
bfd_target_list ()
|
||||
{
|
||||
int vec_length= 0;
|
||||
bfd_target **target;
|
||||
char **name_list, **name_ptr;
|
||||
|
||||
for (target = &target_vector[0]; *target != NULL; target++)
|
||||
vec_length++;
|
||||
|
||||
name_ptr = name_list = (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;
|
||||
}
|
||||
|
||||
/* Init a bfd for read of the proper format. If the target was unspecified,
|
||||
search all the possible targets. */
|
||||
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
return false; /* Specified target is not right */
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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);
|
||||
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])
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Hack object and core file sections */
|
||||
|
||||
sec_ptr
|
||||
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;
|
||||
}
|
||||
|
||||
/* If you try to create a section with a name which is already in use,
|
||||
returns the old section by that name instead. */
|
||||
sec_ptr
|
||||
DEFUN(bfd_make_section,(abfd, name),
|
||||
bfd *abfd AND
|
||||
CONST char *CONST name)
|
||||
{
|
||||
asection *newsect;
|
||||
asection ** prev = &abfd->sections;
|
||||
asection * sect = abfd->sections;
|
||||
|
||||
if (abfd->output_has_begun) {
|
||||
bfd_error = invalid_operation;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (sect) {
|
||||
if (!strcmp(sect->name, name)) return 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;
|
||||
|
||||
if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
|
||||
free (newsect);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*prev = newsect;
|
||||
return newsect;
|
||||
}
|
||||
|
||||
/* Call operation on each section. Operation gets three args: the bfd,
|
||||
the section, and a void * pointer (whatever the user supplied). */
|
||||
|
||||
/* This is attractive except that without lexical closures its use is hard
|
||||
to make reentrant. */
|
||||
/*VARARGS2*/
|
||||
void
|
||||
bfd_map_over_sections (abfd, operation, user_storage)
|
||||
bfd *abfd;
|
||||
void (*operation)();
|
||||
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();
|
||||
}
|
||||
|
||||
boolean
|
||||
bfd_set_section_flags (abfd, section, flags)
|
||||
bfd *abfd;
|
||||
sec_ptr section;
|
||||
flagword flags;
|
||||
{
|
||||
if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
|
||||
bfd_error = invalid_operation;
|
||||
return false;
|
||||
}
|
||||
|
||||
section->flags = flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
bfd_set_section_size (abfd, ptr, val)
|
||||
bfd *abfd;
|
||||
sec_ptr ptr;
|
||||
unsigned long 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->size = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!(bfd_get_section_flags(abfd, section) &
|
||||
SEC_HAS_CONTENTS)) {
|
||||
bfd_error = no_contents;
|
||||
return(false);
|
||||
} /* if section has no contents */
|
||||
|
||||
if (BFD_SEND (abfd, _bfd_set_section_contents,
|
||||
(abfd, section, location, offset, count))) {
|
||||
abfd->output_has_begun = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return 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)
|
||||
{
|
||||
if (section->flags & SEC_CONSTRUCTOR) {
|
||||
memset(location, 0, (unsigned)count);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return (BFD_SEND (abfd, _bfd_get_section_contents,
|
||||
(abfd, section, location, offset, count)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Some core file info commands */
|
||||
|
||||
/* Returns a read-only string explaining what program was running when
|
||||
it failed. */
|
||||
|
||||
char *
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/** Symbols */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* returns the number of octets of storage required */
|
||||
|
||||
unsigned int
|
||||
get_reloc_upper_bound (abfd, asect)
|
||||
bfd *abfd;
|
||||
@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols)
|
||||
return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
|
||||
}
|
||||
|
||||
void
|
||||
bfd_print_symbol_vandf(file, symbol)
|
||||
PTR file;
|
||||
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_IMPORT) ? 'i' : ' ',
|
||||
(type & BSF_EXPORT) ? 'e' : ' ',
|
||||
(type & BSF_UNDEFINED) ? 'u' : ' ',
|
||||
(type & BSF_FORT_COMM) ? 'c' : ' ',
|
||||
(type & BSF_DEBUGGING) ? 'd' :' ');
|
||||
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
bfd_set_file_flags (abfd, flags)
|
||||
@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
|
||||
asect->orelocation = location;
|
||||
asect->reloc_count = count;
|
||||
}
|
||||
/*
|
||||
If an output_bfd is supplied to this function the generated image
|
||||
will be relocatable, the relocations are copied to the output file
|
||||
after they have been changed to reflect the new state of the world.
|
||||
There are two ways of reflecting the results of partial linkage in an
|
||||
output file; by modifying the output data in place, and by modifying
|
||||
the relocation record. Some native formats (eg basic a.out and basic
|
||||
coff) have no way of specifying an addend in the relocation type, so
|
||||
the addend has to go in the output data. This is no big deal since in
|
||||
these formats the output data slot will always be big enough for the
|
||||
addend. Complex reloc types with addends were invented to solve just
|
||||
this problem.
|
||||
*/
|
||||
|
||||
bfd_reloc_status_enum_type
|
||||
DEFUN(bfd_perform_relocation,(abfd,
|
||||
reloc_entry,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd),
|
||||
bfd *abfd AND
|
||||
arelent *reloc_entry AND
|
||||
PTR data AND
|
||||
asection *input_section AND
|
||||
bfd *output_bfd)
|
||||
{
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_enum_type flag = bfd_reloc_ok;
|
||||
bfd_vma addr = reloc_entry->address ;
|
||||
bfd_vma output_base = 0;
|
||||
reloc_howto_type *howto = reloc_entry->howto;
|
||||
asection *reloc_target_output_section;
|
||||
asection *reloc_target_input_section;
|
||||
asymbol *symbol;
|
||||
|
||||
if (reloc_entry->sym_ptr_ptr) {
|
||||
symbol = *( reloc_entry->sym_ptr_ptr);
|
||||
if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
|
||||
flag = bfd_reloc_undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
symbol = (asymbol*)NULL;
|
||||
}
|
||||
|
||||
if (howto->special_function){
|
||||
bfd_reloc_status_enum_type cont;
|
||||
cont = howto->special_function(abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section);
|
||||
if (cont != bfd_reloc_continue) return cont;
|
||||
}
|
||||
|
||||
/*
|
||||
Work out which section the relocation is targetted at and the
|
||||
initial relocation command value.
|
||||
*/
|
||||
|
||||
|
||||
if (symbol != (asymbol *)NULL){
|
||||
if (symbol->flags & BSF_FORT_COMM) {
|
||||
relocation = 0;
|
||||
}
|
||||
else {
|
||||
relocation = symbol->value;
|
||||
}
|
||||
if (symbol->section != (asection *)NULL)
|
||||
{
|
||||
reloc_target_input_section = symbol->section;
|
||||
}
|
||||
else {
|
||||
reloc_target_input_section = (asection *)NULL;
|
||||
}
|
||||
}
|
||||
else if (reloc_entry->section != (asection *)NULL)
|
||||
{
|
||||
relocation = 0;
|
||||
reloc_target_input_section = reloc_entry->section;
|
||||
}
|
||||
else {
|
||||
relocation = 0;
|
||||
reloc_target_input_section = (asection *)NULL;
|
||||
}
|
||||
|
||||
|
||||
if (reloc_target_input_section != (asection *)NULL) {
|
||||
|
||||
reloc_target_output_section =
|
||||
reloc_target_input_section->output_section;
|
||||
|
||||
if (output_bfd && howto->partial_inplace==false) {
|
||||
output_base = 0;
|
||||
}
|
||||
else {
|
||||
output_base = reloc_target_output_section->vma;
|
||||
|
||||
}
|
||||
|
||||
relocation += output_base + reloc_target_input_section->output_offset;
|
||||
}
|
||||
|
||||
relocation += reloc_entry->addend ;
|
||||
|
||||
|
||||
if(reloc_entry->address > (bfd_vma)(input_section->size))
|
||||
{
|
||||
return bfd_reloc_outofrange;
|
||||
}
|
||||
|
||||
|
||||
if (howto->pc_relative == true)
|
||||
{
|
||||
/*
|
||||
Anything which started out as pc relative should end up that
|
||||
way too.
|
||||
|
||||
There are two ways we can see a pcrel instruction. Sometimes
|
||||
the pcrel displacement has been partially calculated, it
|
||||
includes the distance from the start of the section to the
|
||||
instruction in it (eg sun3), and sometimes the field is
|
||||
totally blank - eg m88kbcs.
|
||||
*/
|
||||
|
||||
|
||||
relocation -=
|
||||
output_base + input_section->output_offset;
|
||||
|
||||
if (howto->pcrel_offset == true) {
|
||||
relocation -= reloc_entry->address;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (output_bfd!= (bfd *)NULL) {
|
||||
if ( howto->partial_inplace == false) {
|
||||
/*
|
||||
This is a partial relocation, and we want to apply the relocation
|
||||
to the reloc entry rather than the raw data. Modify the reloc
|
||||
inplace to reflect what we now know.
|
||||
*/
|
||||
reloc_entry->addend = relocation ;
|
||||
reloc_entry->section = reloc_target_input_section;
|
||||
if (reloc_target_input_section != (asection *)NULL) {
|
||||
/* If we know the output section we can forget the symbol */
|
||||
reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
|
||||
}
|
||||
reloc_entry->address +=
|
||||
input_section->output_offset;
|
||||
return flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a partial relocation, but inplace, so modify the
|
||||
reloc record a bit
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
reloc_entry->addend = 0;
|
||||
|
||||
|
||||
/*
|
||||
Either we are relocating all the way, or we don't want to apply
|
||||
the relocation to the reloc entry (probably because there isn't
|
||||
any room in the output format to describe addends to relocs)
|
||||
*/
|
||||
relocation >>= howto->rightshift;
|
||||
|
||||
/* Shift everything up to where it's going to be used */
|
||||
|
||||
relocation <<= howto->bitpos;
|
||||
|
||||
/* Wait for the day when all have the mask in them */
|
||||
|
||||
/* What we do:
|
||||
i instruction to be left alone
|
||||
o offset within instruction
|
||||
r relocation offset to apply
|
||||
S src mask
|
||||
D dst mask
|
||||
N ~dst mask
|
||||
A part 1
|
||||
B part 2
|
||||
R result
|
||||
|
||||
Do this:
|
||||
i i i i i o o o o o from bfd_get<size>
|
||||
and S S S S S to get the size offset we want
|
||||
+ r r r r r r r r r r to get the final value to place
|
||||
and D D D D D to chop to right size
|
||||
-----------------------
|
||||
A A A A A
|
||||
And this:
|
||||
... i i i i i o o o o o from bfd_get<size>
|
||||
and N N N N N get instruction
|
||||
-----------------------
|
||||
... B B B B B
|
||||
|
||||
And then:
|
||||
B B B B B
|
||||
or A A A A A
|
||||
-----------------------
|
||||
R R R R R R R R R R put into bfd_put<size>
|
||||
*/
|
||||
|
||||
#define DOIT(x) \
|
||||
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
|
||||
|
||||
switch (howto->size)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
char x = bfd_get_8(abfd, (char *)data + addr);
|
||||
DOIT(x);
|
||||
bfd_put_8(abfd,x, (unsigned char *) data + addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
|
||||
DOIT(x);
|
||||
bfd_put_16(abfd, x, (unsigned char *)data + addr);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
long x = bfd_get_32(abfd, (bfd_byte *) data + addr);
|
||||
DOIT(x);
|
||||
bfd_put_32(abfd,x, (bfd_byte *)data + addr);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
return bfd_reloc_other;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_assert(file, line)
|
||||
@ -889,6 +350,14 @@ int line;
|
||||
}
|
||||
|
||||
|
||||
/*proto* bfd_set_start_address
|
||||
|
||||
Marks the entry point of an output bfd. Returns @code{true} on
|
||||
success, @code{false} otherwise.
|
||||
|
||||
*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma));
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_set_start_address(abfd, vma)
|
||||
bfd *abfd;
|
||||
@ -899,19 +368,15 @@ bfd_vma vma;
|
||||
}
|
||||
|
||||
|
||||
bfd_vma bfd_log2(x)
|
||||
bfd_vma x;
|
||||
{
|
||||
bfd_vma result = 0;
|
||||
while ( (bfd_vma)(1<< result) < x)
|
||||
result++;
|
||||
return result;
|
||||
}
|
||||
/*proto* bfd_get_mtime
|
||||
|
||||
/* bfd_get_mtime: Return cached file modification time (e.g. as read
|
||||
from archive header for archive members, or from file system if we have
|
||||
been called before); else determine modify time, cache it, and
|
||||
return it. */
|
||||
Return cached file modification time (e.g. as read from archive header
|
||||
for archive members, or from file system if we have been called
|
||||
before); else determine modify time, cache it, and return it.
|
||||
|
||||
*;PROTO(long, bfd_get_mtime, (bfd *));
|
||||
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_mtime (abfd)
|
||||
@ -931,3 +396,33 @@ bfd_get_mtime (abfd)
|
||||
abfd->mtime = buf.st_mtime;
|
||||
return abfd->mtime;
|
||||
}
|
||||
|
||||
/*proto*
|
||||
*i stuff
|
||||
*+
|
||||
#define bfd_sizeof_headers(abfd, reloc) \
|
||||
BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
|
||||
|
||||
#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \
|
||||
BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, section, symbols, offset, filename_ptr, func, line_ptr))
|
||||
|
||||
#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))
|
||||
*-
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1553
bfd/coffcode.h
1553
bfd/coffcode.h
File diff suppressed because it is too large
Load Diff
1178
bfd/ieee.c
1178
bfd/ieee.c
File diff suppressed because it is too large
Load Diff
82
bfd/libbfd.c
82
bfd/libbfd.c
@ -207,7 +207,8 @@ DEFUN(bfd_tell,(abfd),
|
||||
|
||||
/** Make a string table */
|
||||
|
||||
/* Add string to table pointed to by table, at location starting with free_ptr.
|
||||
/*>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 */
|
||||
|
||||
@ -268,6 +269,61 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
|
||||
functions in swap.h #ifdef __GNUC__.
|
||||
Gprof them later and find out. */
|
||||
|
||||
/*proto*
|
||||
*i bfd_put_size
|
||||
*i bfd_get_size
|
||||
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.
|
||||
*+
|
||||
#define bfd_put_8(abfd, val, ptr) \
|
||||
(*((char *)ptr) = (char)val)
|
||||
#define bfd_get_8(abfd, ptr) \
|
||||
(*((char *)ptr))
|
||||
#define bfd_put_16(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_putx16, (val,ptr))
|
||||
#define bfd_get_16(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_getx16, (ptr))
|
||||
#define bfd_put_32(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_putx32, (val,ptr))
|
||||
#define bfd_get_32(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_getx32, (ptr))
|
||||
#define bfd_put_64(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_putx64, (val, ptr))
|
||||
#define bfd_get_64(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_getx64, (ptr))
|
||||
*-
|
||||
*-*/
|
||||
|
||||
/*proto*
|
||||
*i bfd_h_put_size
|
||||
*i bfd_h_get_size
|
||||
These macros have the same function as their @code{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
|
||||
endan order.
|
||||
*+
|
||||
#define bfd_h_put_8(abfd, val, ptr) \
|
||||
(*((char *)ptr) = (char)val)
|
||||
#define bfd_h_get_8(abfd, ptr) \
|
||||
(*((char *)ptr))
|
||||
#define bfd_h_put_16(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
|
||||
#define bfd_h_get_16(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_getx16,(ptr))
|
||||
#define bfd_h_put_32(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
|
||||
#define bfd_h_get_32(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_getx32,(ptr))
|
||||
#define bfd_h_put_64(abfd, val, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
|
||||
#define bfd_h_get_64(abfd, ptr) \
|
||||
BFD_SEND(abfd, bfd_h_getx64,(ptr))
|
||||
*-
|
||||
*-*/
|
||||
|
||||
unsigned int
|
||||
DEFUN(_do_getb16,(addr),
|
||||
register bfd_byte *addr)
|
||||
@ -333,7 +389,9 @@ DEFUN(_do_getb64,(addr),
|
||||
|
||||
return high << 32 | low;
|
||||
#else
|
||||
bfd_64_type foo;
|
||||
BFD_FAIL();
|
||||
return foo;
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -342,8 +400,9 @@ bfd_64_type
|
||||
DEFUN(_do_getl64,(addr),
|
||||
register bfd_byte *addr)
|
||||
{
|
||||
bfd_64_type low, high;
|
||||
|
||||
#ifdef HOST_64_BIT
|
||||
bfd_64_type low, high;
|
||||
high= (((((((addr[7] << 8) |
|
||||
addr[6]) << 8) |
|
||||
addr[5]) << 8) |
|
||||
@ -356,8 +415,11 @@ DEFUN(_do_getl64,(addr),
|
||||
|
||||
return high << 32 | low;
|
||||
#else
|
||||
bfd_64_type foo;
|
||||
BFD_FAIL();
|
||||
return foo;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -440,3 +502,19 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count)
|
||||
return (false); /* on error */
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*proto-internal*
|
||||
*i bfd_log2
|
||||
Return the log base 2 of the value supplied, rounded up. eg an arg
|
||||
of 1025 would return 11.
|
||||
*; PROTO(bfd_vma, bfd_log2,(bfd_vma x));
|
||||
*-*/
|
||||
|
||||
bfd_vma bfd_log2(x)
|
||||
bfd_vma x;
|
||||
{
|
||||
bfd_vma result = 0;
|
||||
while ( (bfd_vma)(1<< result) < x)
|
||||
result++;
|
||||
return result;
|
||||
}
|
||||
|
59
bfd/libbfd.h
59
bfd/libbfd.h
@ -65,14 +65,17 @@ PROTO (char *, zalloc, (bfd_size_type size));
|
||||
PROTO(PTR, bfd_alloc, (bfd *abfd, bfd_size_type size));
|
||||
PROTO(PTR, bfd_zalloc,(bfd *abfd, bfd_size_type size));
|
||||
PROTO(PTR, bfd_realloc,(bfd *abfd, PTR orig, bfd_size_type new));
|
||||
PROTO(void, bfd_alloc_grow,(bfd *abfd, PTR thing, bfd_size_type size));
|
||||
PROTO(PTR, bfd_alloc_finish,(bfd *abfd));
|
||||
|
||||
#define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
|
||||
|
||||
PROTO (bfd_target *, bfd_find_target, (CONST char *target_name, bfd *));
|
||||
|
||||
PROTO (bfd_size_type, bfd_read, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
|
||||
PROTO (bfd_size_type, bfd_write, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
|
||||
|
||||
PROTO (FILE *, bfd_cache_lookup, (bfd *));
|
||||
PROTO (void, bfd_cache_close, (bfd *));
|
||||
|
||||
|
||||
PROTO (int, bfd_seek,(bfd* abfd, file_ptr fp , int direction));
|
||||
PROTO (long, bfd_tell, (bfd *abfd));
|
||||
PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd));
|
||||
@ -161,8 +164,6 @@ PROTO (void, bfd_assert,(char*,int));
|
||||
PROTO (FILE *, bfd_cache_lookup_worker, (bfd *));
|
||||
|
||||
extern bfd *bfd_last_cache;
|
||||
#define bfd_cache_lookup(x) \
|
||||
(x==bfd_last_cache?(FILE*)(bfd_last_cache->iostream):bfd_cache_lookup_worker(x))
|
||||
|
||||
/* Now Steve, what's the story here? */
|
||||
#ifdef lint
|
||||
@ -175,3 +176,51 @@ extern bfd *bfd_last_cache;
|
||||
|
||||
/* Generic routine for close_and_cleanup is really just bfd_true. */
|
||||
#define bfd_generic_close_and_cleanup bfd_true
|
||||
|
||||
/* THE FOLLOWING IS EXTRACTED FROM THE SOURCE*/
|
||||
|
||||
/* Return the log base 2 of the value supplied, rounded up. eg an arg
|
||||
of 1025 would return 11.
|
||||
*/
|
||||
PROTO(bfd_vma, bfd_log2,(bfd_vma x));
|
||||
/* The maxiumum number of files which the cache will keep open at one
|
||||
time.
|
||||
*/
|
||||
#define BFD_CACHE_MAX_OPEN 10
|
||||
|
||||
/* Zero, or a pointer to the topmost bfd on the chain. This is used by the
|
||||
bfd_cache_lookup() macro in libbfd.h to determine when it can avoid a function
|
||||
call.
|
||||
*/
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
/* 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))
|
||||
|
||||
|
||||
/* Initialize a BFD by putting it on the cache LRU.
|
||||
*/
|
||||
PROTO(void, bfd_cache_init, (bfd *));
|
||||
/* Remove the bfd from the cache. If the attatched file is open, then close it too.
|
||||
*/
|
||||
PROTO(void, bfd_cache_close, (bfd *));
|
||||
/* 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.
|
||||
*/
|
||||
PROTO(FILE *, bfd_open_file, (bfd *));
|
||||
/* Called when the macro @code{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.
|
||||
*/
|
||||
PROTO(FILE *, bfd_cache_lookup_worker, (bfd *));
|
||||
|
@ -31,16 +31,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
#include "aout64.h"
|
||||
|
||||
/**From: bothner@cs.wisc.edu***********************************************/
|
||||
#undef N_TXTOFF
|
||||
#define N_TXTOFF(x) ( (N_MAGIC((x)) == ZMAGIC) ? PAGE_SIZE : EXEC_BYTES_SIZE)
|
||||
/**************************************************************************/
|
||||
|
||||
#include "stab.gnu.h"
|
||||
#include "ar.h"
|
||||
#include "libaout.h" /* BFD a.out internal data structures */
|
||||
|
||||
#if 0
|
||||
int vfprintf(file, format, args) /* Temporary crock! */
|
||||
FILE *file; char *format; char *args;
|
||||
{
|
||||
return _doprnt (format, args, file);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
bfd_target *newsos3_callback ();
|
||||
@ -49,7 +55,7 @@ bfd_target *
|
||||
DEFUN(newsos3_object_p,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
unsigned char magicbuf[LONG_SIZE]; /* Raw bytes of magic number from file */
|
||||
unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
|
||||
unsigned long magic; /* Swapped magic number */
|
||||
|
||||
bfd_error = system_call_error;
|
||||
@ -99,19 +105,40 @@ DEFUN(newsos3_write_object_contents,(abfd),
|
||||
/* Transfer vectors for NEWS-OS version 3 */
|
||||
|
||||
/* We use BFD generic archive files. */
|
||||
#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define aout_32_slurp_armap bfd_slurp_bsd_armap
|
||||
#define aout_32_slurp_extended_name_table bfd_true
|
||||
#define aout_32_write_armap bsd_write_armap
|
||||
#define aout_32_truncate_arname bfd_bsd_truncate_arname
|
||||
#define newsos_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define newsos_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define newsos_slurp_armap bfd_slurp_bsd_armap
|
||||
#define newsos_slurp_extended_name_table bfd_true
|
||||
#define newsos_write_armap bsd_write_armap
|
||||
#define newsos_truncate_arname bfd_bsd_truncate_arname
|
||||
|
||||
/* We don't support core files yet. FIXME. */
|
||||
#define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
|
||||
#define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
|
||||
#define aout_32_core_file_matches_executable_p \
|
||||
#define newsos_core_file_failing_command _bfd_dummy_core_file_failing_command
|
||||
#define newsos_core_file_failing_signal _bfd_dummy_core_file_failing_signal
|
||||
#define newsos_core_file_matches_executable_p \
|
||||
_bfd_dummy_core_file_matches_executable_p
|
||||
#define aout_32_core_file_p _bfd_dummy_target
|
||||
#define newsos_core_file_p _bfd_dummy_target
|
||||
|
||||
#define newsos_bfd_debug_info_start bfd_void
|
||||
#define newsos_bfd_debug_info_end bfd_void
|
||||
#define newsos_bfd_debug_info_accumulate bfd_void
|
||||
|
||||
#define newsos_mkobject aout_32_mkobject
|
||||
#define newsos_close_and_cleanup aout_32_close_and_cleanup
|
||||
#define newsos_set_section_contents aout_32_set_section_contents
|
||||
#define newsos_get_section_contents aout_32_get_section_contents
|
||||
#define newsos_new_section_hook aout_32_new_section_hook
|
||||
#define newsos_get_symtab_upper_bound aout_32_get_symtab_upper_bound
|
||||
#define newsos_get_symtab aout_32_get_symtab
|
||||
#define newsos_get_reloc_upper_bound aout_32_get_reloc_upper_bound
|
||||
#define newsos_canonicalize_reloc aout_32_canonicalize_reloc
|
||||
#define newsos_make_empty_symbol aout_32_make_empty_symbol
|
||||
#define newsos_print_symbol aout_32_print_symbol
|
||||
#define newsos_get_lineno aout_32_get_lineno
|
||||
#define newsos_set_arch_mach aout_32_set_arch_mach
|
||||
#define newsos_find_nearest_line aout_32_find_nearest_line
|
||||
#define newsos_sizeof_headers aout_32_sizeof_headers
|
||||
|
||||
|
||||
/* We define our own versions of these routines. */
|
||||
|
||||
@ -128,16 +155,16 @@ bfd_target newsos3_vec = /* Sony 68k-based machines running newos3 */
|
||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
|
||||
1, /* minimum alignment */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
|
||||
{_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */
|
||||
bfd_generic_archive_p, aout_32_core_file_p},
|
||||
{bfd_false, aout_32_mkobject, /* bfd_set_format */
|
||||
bfd_generic_archive_p, newsos_core_file_p},
|
||||
{bfd_false, newsos_mkobject, /* bfd_set_format */
|
||||
_bfd_generic_mkarchive, bfd_false},
|
||||
{bfd_false, newsos3_write_object_contents, /* bfd_write_contents */
|
||||
_bfd_write_archive_contents, bfd_false},
|
||||
|
||||
JUMP_TABLE(aout_32)
|
||||
JUMP_TABLE(newsos)
|
||||
};
|
||||
|
118
bfd/oasys.c
118
bfd/oasys.c
@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "libbfd.h"
|
||||
#include "oasys.h"
|
||||
#include "liboasys.h"
|
||||
|
||||
|
||||
/* Read in all the section data and relocation stuff too */
|
||||
PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
|
||||
|
||||
static void
|
||||
DEFUN(oasys_read_record,(abfd, record),
|
||||
bfd *CONST abfd AND
|
||||
@ -127,6 +132,12 @@ DEFUN(oasys_slurp_symbol_table,(abfd),
|
||||
if (record.header.type == oasys_record_is_local_enum)
|
||||
{
|
||||
dest->flags = BSF_LOCAL;
|
||||
if (dest->section ==(asection *)(~0)) {
|
||||
/* It seems that sometimes internal symbols are tied up, but
|
||||
still get output, even though there is no
|
||||
section */
|
||||
dest->section = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@ -258,7 +269,7 @@ DEFUN(oasys_archive_p,(abfd),
|
||||
|
||||
|
||||
oasys_module_table_type record;
|
||||
oasys_external_module_table_type record_ext;
|
||||
|
||||
|
||||
set_tdata(abfd, ar);
|
||||
ar->module = module;
|
||||
@ -268,6 +279,11 @@ DEFUN(oasys_archive_p,(abfd),
|
||||
filepos = header.mod_tbl_offset;
|
||||
for (i = 0; i < header.mod_count; i++) {
|
||||
bfd_seek(abfd , filepos, SEEK_SET);
|
||||
|
||||
/* There are two ways of specifying the archive header */
|
||||
|
||||
if (0) {
|
||||
oasys_external_module_table_type_a_type record_ext;
|
||||
bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
|
||||
|
||||
record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
|
||||
@ -286,7 +302,30 @@ DEFUN(oasys_archive_p,(abfd),
|
||||
sizeof(record_ext) +
|
||||
record.dep_count * 4 +
|
||||
record.depee_count * 4 +
|
||||
record.sect_count * 8 + 187,
|
||||
record.sect_count * 8 + 187;
|
||||
}
|
||||
else {
|
||||
oasys_external_module_table_type_b_type record_ext;
|
||||
bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
|
||||
|
||||
record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
|
||||
record.file_offset = bfd_h_get_32(abfd,
|
||||
record_ext.file_offset);
|
||||
|
||||
record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
|
||||
record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
|
||||
record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
|
||||
record.module_name_size = bfd_h_get_32(abfd, record_ext.mod_name_length);
|
||||
|
||||
module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
|
||||
bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
|
||||
module[i].name[record.module_name_size] = 0;
|
||||
filepos +=
|
||||
sizeof(record_ext) +
|
||||
record.dep_count * 4 +
|
||||
record.module_name_size + 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
module[i].size = record.mod_size;
|
||||
@ -375,7 +414,7 @@ DEFUN(oasys_object_p,(abfd),
|
||||
|
||||
s->size = bfd_h_get_32(abfd, & record.section.value[0]) ;
|
||||
s->vma = bfd_h_get_32(abfd, &record.section.vma[0]);
|
||||
s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
|
||||
s->flags= 0;
|
||||
had_usefull = true;
|
||||
}
|
||||
break;
|
||||
@ -402,6 +441,14 @@ DEFUN(oasys_object_p,(abfd),
|
||||
if (abfd->symcount != 0) {
|
||||
abfd->flags |= HAS_SYMS;
|
||||
}
|
||||
|
||||
/*
|
||||
We don't know if a section has data until we've read it..
|
||||
*/
|
||||
|
||||
oasys_slurp_section_data(abfd);
|
||||
|
||||
|
||||
return abfd->xvec;
|
||||
|
||||
fail:
|
||||
@ -465,21 +512,20 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
||||
|
||||
asection *s;
|
||||
|
||||
/* Buy enough memory for all the section data and relocations */
|
||||
/* See if the data has been slurped already .. */
|
||||
for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
|
||||
per = oasys_per_section(s);
|
||||
if (per->data != (bfd_byte*)NULL) return true;
|
||||
per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
|
||||
per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
|
||||
per->had_vma = false;
|
||||
s->reloc_count = 0;
|
||||
if (per->initialized == true)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data->first_data_record == 0) return true;
|
||||
|
||||
bfd_seek(abfd, data->first_data_record, SEEK_SET);
|
||||
while (loop) {
|
||||
oasys_read_record(abfd, &record);
|
||||
switch (record.header.type) {
|
||||
switch (record.header.type)
|
||||
{
|
||||
case oasys_record_is_header_enum:
|
||||
break;
|
||||
case oasys_record_is_data_enum:
|
||||
@ -496,6 +542,18 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
||||
data->sections[record.data.relb & RELOCATION_SECT_BITS];
|
||||
bfd_vma dst_offset ;
|
||||
per = oasys_per_section(section);
|
||||
|
||||
|
||||
if (per->initialized == false)
|
||||
{
|
||||
per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
|
||||
per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
|
||||
per->had_vma = false;
|
||||
per->initialized = true;
|
||||
section->reloc_count = 0;
|
||||
section->flags = SEC_ALLOC;
|
||||
}
|
||||
|
||||
dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
|
||||
if (per->had_vma == false) {
|
||||
/* Take the first vma we see as the base */
|
||||
@ -512,9 +570,13 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
||||
dst_ptr = oasys_per_section(section)->data +
|
||||
dst_offset;
|
||||
|
||||
if (src < end_src) {
|
||||
section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
|
||||
}
|
||||
while (src < end_src) {
|
||||
uint32_type gap = end_src - src -1;
|
||||
uint8e_type mod_byte = *src++;
|
||||
uint32_type gap = end_src - src;
|
||||
|
||||
count = 8;
|
||||
if (mod_byte == 0 && gap >= 8) {
|
||||
dst_ptr[0] = src[0];
|
||||
@ -529,7 +591,7 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
||||
src += 8;
|
||||
}
|
||||
else {
|
||||
for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
|
||||
for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
|
||||
{
|
||||
if (relbit & mod_byte)
|
||||
{
|
||||
@ -628,6 +690,7 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@ -646,7 +709,8 @@ DEFUN(oasys_new_section_hook,(abfd, newsect),
|
||||
oasys_per_section( newsect)->data = (bfd_byte *)NULL;
|
||||
oasys_per_section(newsect)->section = newsect;
|
||||
oasys_per_section(newsect)->offset = 0;
|
||||
newsect->alignment_power = 3;
|
||||
oasys_per_section(newsect)->initialized = false;
|
||||
newsect->alignment_power = 1;
|
||||
/* Turn the section string into an index */
|
||||
|
||||
sscanf(newsect->name,"%u", &newsect->target_index);
|
||||
@ -674,7 +738,14 @@ DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
|
||||
{
|
||||
oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
|
||||
oasys_slurp_section_data(abfd);
|
||||
if (p->initialized == false)
|
||||
{
|
||||
(void) memset(location, 0, (int)count);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) memcpy(location, p->data + offset, (int)count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -780,8 +851,16 @@ DEFUN(oasys_write_syms, (abfd),
|
||||
/* throw it away */
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (g->section == (asection *)NULL) {
|
||||
/* Sometime, the oasys tools give out a symbol with illegal
|
||||
bits in it, we'll output it in the same broken way */
|
||||
|
||||
symbol.relb = RELOCATION_TYPE_REL | 0;
|
||||
}
|
||||
else {
|
||||
symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
|
||||
}
|
||||
bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
|
||||
}
|
||||
while (src[l]) {
|
||||
@ -900,6 +979,7 @@ DEFUN(oasys_write_data, (abfd),
|
||||
{
|
||||
asection *s;
|
||||
for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
|
||||
if (s->flags & SEC_LOAD) {
|
||||
uint8e_type *raw_data = oasys_per_section(s)->data;
|
||||
oasys_data_record_type processed_data;
|
||||
bfd_size_type current_byte_index = 0;
|
||||
@ -1036,6 +1116,7 @@ DEFUN(oasys_write_data, (abfd),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static boolean
|
||||
DEFUN(oasys_write_object_contents, (abfd),
|
||||
bfd * CONST abfd)
|
||||
@ -1180,17 +1261,20 @@ DEFUN(oasys_sizeof_headers,(abfd, exec),
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FOO PROTO
|
||||
#define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
|
||||
#define oasys_core_file_failing_signal (int (*)())bfd_0
|
||||
#define oasys_core_file_matches_executable_p 0 /*(PROTO(boolean, (*),(bfd*, bfd*)))bfd_false*/
|
||||
#define oasys_core_file_matches_executable_p 0
|
||||
#define oasys_slurp_armap bfd_true
|
||||
#define oasys_slurp_extended_name_table bfd_true
|
||||
#define oasys_truncate_arname (void (*)())bfd_nullvoidptr
|
||||
#define oasys_write_armap 0 /* (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr*/
|
||||
#define oasys_write_armap 0
|
||||
#define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
|
||||
#define oasys_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
|
||||
#define oasys_bfd_debug_info_start bfd_void
|
||||
#define oasys_bfd_debug_info_end bfd_void
|
||||
#define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
|
||||
|
||||
|
||||
/*SUPPRESS 460 */
|
||||
@ -1207,7 +1291,7 @@ bfd_target oasys_vec =
|
||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
|
||||
1, /* minimum alignment */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
|
||||
|
85
bfd/opncls.c
85
bfd/opncls.c
@ -96,8 +96,19 @@ bfd *obfd;
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/** bfd_openr, bfd_fdopenr -- open for reading.
|
||||
Returns a pointer to a freshly-allocated bfd on success, or NULL. */
|
||||
/*doc*
|
||||
@section Opening and Closing BFDs
|
||||
|
||||
*/
|
||||
/*proto*
|
||||
*i bfd_openr
|
||||
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.
|
||||
*; PROTO(bfd*, bfd_openr, (CONST char *filename,CONST char*target));
|
||||
*-*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_openr, (filename, target),
|
||||
@ -139,6 +150,15 @@ DEFUN(bfd_openr, (filename, target),
|
||||
close it if anything goes wrong. Closing the stream means closing
|
||||
the file descriptor too, even though we didn't open it.
|
||||
*/
|
||||
/*proto*
|
||||
*i bfd_fdopenr
|
||||
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.
|
||||
|
||||
Possible errors are no_memory, invalid_target and system_call error.
|
||||
*; PROTO(bfd *, bfd_fdopenr,
|
||||
(CONST char *filename, CONST char *target, int fd));
|
||||
*-*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_fdopenr,(filename, target, fd),
|
||||
@ -155,7 +175,7 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
|
||||
|
||||
bfd_error = system_call_error;
|
||||
|
||||
fdflags = fcntl (fd, F_GETFL);
|
||||
fdflags = fcntl (fd, F_GETFL, NULL);
|
||||
if (fdflags == -1) return NULL;
|
||||
|
||||
#ifdef BFD_LOCKS
|
||||
@ -214,6 +234,14 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
|
||||
|
||||
See comment by bfd_fdopenr before you try to modify this function. */
|
||||
|
||||
/*proto* bfd_openw
|
||||
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.
|
||||
*; PROTO(bfd *, bfd_openw, (CONST char *filename, CONST char *target));
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_openw,(filename, target),
|
||||
CONST char *filename AND
|
||||
@ -246,11 +274,22 @@ DEFUN(bfd_openw,(filename, target),
|
||||
}
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
/* Close up shop, get your deposit back. */
|
||||
|
||||
/*proto* bfd_close
|
||||
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 @code{chmod} is called to mark
|
||||
it as such.
|
||||
|
||||
All memory attatched to the bfd's obstacks is released.
|
||||
|
||||
@code{true} is returned if all is ok, otherwise @code{false}.
|
||||
*; PROTO(boolean, bfd_close,(bfd *));
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_close (abfd)
|
||||
bfd *abfd;
|
||||
DEFUN(bfd_close,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
if (!bfd_read_p(abfd))
|
||||
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
|
||||
@ -283,12 +322,18 @@ bfd_close (abfd)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create a bfd with no associated file or target. */
|
||||
/*proto* bfd_create
|
||||
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 @code{bfd_object}.
|
||||
|
||||
*; PROTO(bfd *, bfd_create, (CONST char *filename, bfd *template));
|
||||
*/
|
||||
|
||||
bfd *
|
||||
DEFUN(bfd_create,(filename, template),
|
||||
CONST char *filename AND
|
||||
CONST bfd *template)
|
||||
bfd *template)
|
||||
{
|
||||
bfd *nbfd = new_bfd();
|
||||
if (nbfd == (bfd *)NULL) {
|
||||
@ -313,6 +358,20 @@ DEFUN(PTR bfd_alloc_by_size_t,(abfd, size),
|
||||
PTR res = obstack_alloc(&(abfd->memory), size);
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
|
||||
bfd *abfd AND
|
||||
PTR ptr AND
|
||||
bfd_size_type size)
|
||||
{
|
||||
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
|
||||
bfd_size_type size)
|
||||
@ -339,8 +398,14 @@ DEFUN(PTR bfd_realloc,(abfd, old, size),
|
||||
return res;
|
||||
}
|
||||
|
||||
/*proto* bfd_alloc_size
|
||||
Return the number of bytes in the obstacks connected to the supplied
|
||||
bfd.
|
||||
*; PROTO(bfd_size_type,bfd_alloc_size,(bfd *abfd));
|
||||
*/
|
||||
|
||||
DEFUN(bfd_size_type bfd_alloc_size,(abfd),
|
||||
bfd_size_type
|
||||
DEFUN( bfd_alloc_size,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
struct _obstack_chunk *chunk = abfd->memory.chunk;
|
||||
|
33
bfd/srec.c
33
bfd/srec.c
@ -187,7 +187,7 @@ asection *section;
|
||||
+ (HEX(buffer.u.type_3.address+1) << 16)
|
||||
+ (HEX(buffer.u.type_3.address+2) << 8)
|
||||
+ (HEX(buffer.u.type_3.address+3));
|
||||
func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
|
||||
func(abfd,section, address, buffer.u.type_3.data, bytes_on_line -1);
|
||||
|
||||
break;
|
||||
|
||||
@ -320,7 +320,7 @@ int bytes_to_do;
|
||||
check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
|
||||
size = bytes_this_chunk + 5;
|
||||
data = buffer.u.type_3.data;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
|
||||
@ -334,6 +334,7 @@ int bytes_to_do;
|
||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
|
||||
size = bytes_this_chunk + 3;
|
||||
data = buffer.u.type_1.data;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytes_this_chunk; i++) {
|
||||
@ -380,31 +381,32 @@ DEFUN(srec_make_empty_symbol, (abfd),
|
||||
new->the_bfd = abfd;
|
||||
return new;
|
||||
}
|
||||
/*SUPPRESS 460 */
|
||||
|
||||
#define srec_new_section_hook (PROTO(boolean, (*), (bfd *, asection *)))bfd_true
|
||||
#define FOO PROTO
|
||||
#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
|
||||
#define srec_get_symtab_upper_bound bfd_false
|
||||
#define srec_get_symtab (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
|
||||
#define srec_get_reloc_upper_bound (PROTO(unsigned int, (*),(bfd*, asection *)))bfd_false
|
||||
#define srec_canonicalize_reloc (PROTO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
|
||||
#define srec_get_symtab (FOO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
|
||||
#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
|
||||
#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
|
||||
|
||||
#define srec_print_symbol (PROTO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
|
||||
#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
|
||||
|
||||
#define srec_openr_next_archived_file (PROTO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
|
||||
#define srec_find_nearest_line (PROTO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
|
||||
#define srec_generic_stat_arch_elt (PROTO(int, (*), (bfd *,struct stat *))) bfd_0
|
||||
#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
|
||||
#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
|
||||
#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0
|
||||
|
||||
|
||||
#define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
|
||||
#define srec_core_file_failing_signal (int (*)())bfd_0
|
||||
#define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false
|
||||
#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
|
||||
#define srec_slurp_armap bfd_true
|
||||
#define srec_slurp_extended_name_table bfd_true
|
||||
#define srec_truncate_arname (void (*)())bfd_nullvoidptr
|
||||
#define srec_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
|
||||
#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
|
||||
#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
|
||||
|
||||
#define srec_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
#define srec_bfd_debug_info_start bfd_void
|
||||
#define srec_bfd_debug_info_end bfd_void
|
||||
#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void
|
||||
|
||||
|
||||
bfd_target srec_vec =
|
||||
@ -420,6 +422,7 @@ bfd_target srec_vec =
|
||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
1, /* minimum alignment */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
|
||||
|
337
bfd/targets.c
337
bfd/targets.c
@ -19,13 +19,262 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
/* This -*- C -*- source file will someday be machine-generated */
|
||||
|
||||
/*** Defines the target vector through which operations dispatch */
|
||||
#include <sysdep.h>
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/*doc*
|
||||
@section Targets
|
||||
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 @code{bfd_openr}, its format and target are
|
||||
unknown. BFD uses various mechanisms to determine how to interpret the
|
||||
file. The operatios performed are:
|
||||
@itemize @bullet
|
||||
@item
|
||||
First a bfd is created by calling the internal routine
|
||||
@code{new_bfd}, then @code{bfd_find_target} is called with the target
|
||||
string supplied to @code{bfd_openr} and the new bfd pointer.
|
||||
@item
|
||||
If a null target string was provided to
|
||||
@code{bfd_find_target}, it looks up the environment variable
|
||||
@code{GNUTARGET} and uses that as the target string.
|
||||
@item
|
||||
If the target string is still NULL, or the target string
|
||||
is @code{default}, then the first item in the target vector is used as
|
||||
the target type. @xref{targets}.
|
||||
@item
|
||||
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.
|
||||
@item
|
||||
Otherwise the error @code{invalid_target} is returned to
|
||||
@code{bfd_openr}.
|
||||
@item
|
||||
@code{bfd_openr} attempts to open the file using
|
||||
@code{bfd_open_file}, and returns the bfd.
|
||||
@end itemize
|
||||
Once the bfd has been opened and the target selected, the file format
|
||||
may be determined. This is done by calling @code{bfd_check_format} on
|
||||
the bfd with a suggested format. The routine returns @code{true} when
|
||||
the application guesses right.
|
||||
*/
|
||||
|
||||
|
||||
/*proto* bfd_target
|
||||
@node bfd_target
|
||||
@subsection bfd_target
|
||||
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.
|
||||
|
||||
|
||||
Shortcut for declaring fields which are prototyped function pointers,
|
||||
while avoiding anguish on compilers that don't support protos.
|
||||
|
||||
$#define SDEF(ret, name, arglist) \
|
||||
$ PROTO(ret,(*name),arglist)
|
||||
$#define SDEF_FMT(ret, name, arglist) \
|
||||
$ PROTO(ret,(*name[bfd_type_end]),arglist)
|
||||
|
||||
These macros are used to dispatch to functions through the bfd_target
|
||||
vector. They are used in a number of macros further down in 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.
|
||||
|
||||
$#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_enum {
|
||||
$ bfd_target_aout_flavour_enum,
|
||||
$ bfd_target_coff_flavour_enum,
|
||||
$ bfd_target_ieee_flavour_enum,
|
||||
$ bfd_target_oasys_flavour_enum,
|
||||
$ bfd_target_srec_flavour_enum} 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 @code{NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}.
|
||||
|
||||
$ flagword object_flags;
|
||||
|
||||
This is a mask of all the flags which a section may have set - from
|
||||
the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}.
|
||||
|
||||
$ flagword section_flags;
|
||||
|
||||
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.
|
||||
|
||||
$ SDEF (bfd_64_type, bfd_getx64, (bfd_byte *));
|
||||
$ SDEF (void, bfd_putx64, (bfd_64_type, bfd_byte *));
|
||||
$ SDEF (unsigned int, bfd_getx32, (bfd_byte *));
|
||||
$ SDEF (void, bfd_putx32, (unsigned long, bfd_byte *));
|
||||
$ SDEF (unsigned int, bfd_getx16, (bfd_byte *));
|
||||
$ SDEF (void, bfd_putx16, (int, bfd_byte *));
|
||||
|
||||
Byte swapping for the headers
|
||||
|
||||
$ SDEF (bfd_64_type, bfd_h_getx64, (bfd_byte *));
|
||||
$ SDEF (void, bfd_h_putx64, (bfd_64_type, bfd_byte *));
|
||||
$ SDEF (unsigned int, bfd_h_getx32, (bfd_byte *));
|
||||
$ SDEF (void, bfd_h_putx32, (unsigned long, bfd_byte *));
|
||||
$ SDEF (unsigned int, bfd_h_getx16, (bfd_byte *));
|
||||
$ SDEF (void, bfd_h_putx16, (int, bfd_byte *));
|
||||
|
||||
Format dependent routines, these turn into 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.
|
||||
|
||||
$ SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
|
||||
|
||||
Set the format of a file being written.
|
||||
|
||||
$ SDEF_FMT (boolean, _bfd_set_format, (bfd *));
|
||||
|
||||
Write cached information into a file being written, at bfd_close.
|
||||
|
||||
$ SDEF_FMT (boolean, _bfd_write_contents, (bfd *));
|
||||
|
||||
The following functions are defined in @code{JUMP_TABLE}. The idea is
|
||||
that the back end writer of @code{foo} names all the routines
|
||||
@code{foo_}@var{entry_point}, @code{JUMP_TABLE} will built the entries
|
||||
in this structure in the right order.
|
||||
|
||||
Core file entry points
|
||||
|
||||
$ SDEF (char *, _core_file_failing_command, (bfd *));
|
||||
$ SDEF (int, _core_file_failing_signal, (bfd *));
|
||||
$ SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
|
||||
|
||||
Archive entry points
|
||||
|
||||
$ SDEF (boolean, _bfd_slurp_armap, (bfd *));
|
||||
$ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
|
||||
$ SDEF (void, _bfd_truncate_arname, (bfd *, CONST char *, char *));
|
||||
$ SDEF (boolean, write_armap, (bfd *arch,
|
||||
$ unsigned int elength,
|
||||
$ struct orl *map,
|
||||
$ int orl_count,
|
||||
$ int stridx));
|
||||
|
||||
Standard stuff.
|
||||
|
||||
$ SDEF (boolean, _close_and_cleanup, (bfd *));
|
||||
$ SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
|
||||
$ file_ptr, bfd_size_type));
|
||||
$ SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR,
|
||||
$ file_ptr, bfd_size_type));
|
||||
$ SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
|
||||
|
||||
Symbols and reloctions
|
||||
|
||||
$ SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
|
||||
$ SDEF (unsigned int, _bfd_canonicalize_symtab,
|
||||
$ (bfd *, struct symbol_cache_entry **));
|
||||
$ SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
|
||||
$ SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
|
||||
$ struct symbol_cache_entry**));
|
||||
$ SDEF (struct symbol_cache_entry *, _bfd_make_empty_symbol, (bfd *));
|
||||
$ SDEF (void, _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry *,
|
||||
$ bfd_print_symbol_enum_type));
|
||||
$#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
|
||||
$ SDEF (alent *, _get_lineno, (bfd *, struct symbol_cache_entry *));
|
||||
$
|
||||
$ SDEF (boolean, _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
|
||||
$ unsigned long));
|
||||
$
|
||||
$ SDEF (bfd *, openr_next_archived_file, (bfd *arch, bfd *prev));
|
||||
$ SDEF (boolean, _bfd_find_nearest_line,
|
||||
$ (bfd *abfd, struct sec *section,
|
||||
$ struct symbol_cache_entry **symbols,bfd_vma offset,
|
||||
$ CONST char **file, CONST char **func, unsigned int *line));
|
||||
$ SDEF (int, _bfd_stat_arch_elt, (bfd *, struct stat *));
|
||||
$
|
||||
$ SDEF (int, _bfd_sizeof_headers, (bfd *, boolean));
|
||||
$
|
||||
$ SDEF (void, _bfd_debug_info_start, (bfd *));
|
||||
$ SDEF (void, _bfd_debug_info_end, (bfd *));
|
||||
$ SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec *));
|
||||
|
||||
Special entry points for gdb to swap in coff symbol table parts
|
||||
|
||||
$ SDEF(void, _bfd_coff_swap_aux_in,(
|
||||
$ bfd *abfd ,
|
||||
$ PTR ext,
|
||||
$ int type,
|
||||
$ int class ,
|
||||
$ PTR in));
|
||||
$
|
||||
$ SDEF(void, _bfd_coff_swap_sym_in,(
|
||||
$ bfd *abfd ,
|
||||
$ PTR ext,
|
||||
$ PTR in));
|
||||
$
|
||||
$ SDEF(void, _bfd_coff_swap_lineno_in, (
|
||||
$ bfd *abfd,
|
||||
$ PTR ext,
|
||||
$ PTR in));
|
||||
$
|
||||
$} bfd_target;
|
||||
|
||||
*---
|
||||
|
||||
*/
|
||||
extern bfd_target ecoff_little_vec;
|
||||
extern bfd_target ecoff_big_vec;
|
||||
extern bfd_target sunos_big_vec;
|
||||
@ -57,8 +306,8 @@ extern bfd_target DEFAULT_VECTOR;
|
||||
#define ECOFF_BIG_VEC ecoff_big_vec
|
||||
#define ICOFF_LITTLE_VEC icoff_little_vec
|
||||
#define ICOFF_BIG_VEC icoff_big_vec
|
||||
#define XB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
|
||||
#define XB_OUT_VEC_BIG_HOST b_out_vec_big_host
|
||||
#define ZB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
|
||||
#define ZB_OUT_VEC_BIG_HOST b_out_vec_big_host
|
||||
#define SUNOS_VEC_BIG_HOST sunos_big_vec
|
||||
#define DEMO_64_VEC demo_64_vec
|
||||
#define OASYS_VEC oasys_vec
|
||||
@ -145,3 +394,81 @@ bfd_target *default_vector[] = {
|
||||
#endif
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*proto*
|
||||
*i bfd_find_target
|
||||
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 then
|
||||
the 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.
|
||||
*; PROTO(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 : 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;
|
||||
}
|
||||
|
||||
|
||||
/*proto*
|
||||
*i bfd_target_list
|
||||
This function returns a freshly malloced NULL-terminated vector of the
|
||||
names of all the valid bfd targets. Do not modify the names
|
||||
*; PROTO(CONST char **,bfd_target_list,());
|
||||
|
||||
*-*/
|
||||
|
||||
CONST char **
|
||||
DEFUN_VOID(bfd_target_list)
|
||||
{
|
||||
int vec_length= 0;
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user