mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 08:24:05 +08:00
Now full of documentation. Yum Yum.
This commit is contained in:
@ -28,7 +28,9 @@ echo Sanitizing `pwd`...
|
|||||||
Things-to-keep:
|
Things-to-keep:
|
||||||
|
|
||||||
COPYING
|
COPYING
|
||||||
|
bfd.texinfo
|
||||||
ChangeLog
|
ChangeLog
|
||||||
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
TODO
|
TODO
|
||||||
VERSION
|
VERSION
|
||||||
@ -40,19 +42,17 @@ archive.c
|
|||||||
archures.c
|
archures.c
|
||||||
archures.h
|
archures.h
|
||||||
bfd.c
|
bfd.c
|
||||||
bfd.doc
|
|
||||||
bout.c
|
bout.c
|
||||||
cache.c
|
cache.c
|
||||||
coffcode.h
|
coffcode.h
|
||||||
coffish.h
|
config.status
|
||||||
coffswap.c
|
configure*
|
||||||
config
|
|
||||||
configure
|
|
||||||
configure.in
|
configure.in
|
||||||
cplus-dem.c
|
core.c
|
||||||
demo64.c
|
demo64.c
|
||||||
ecoff.c
|
ecoff.c
|
||||||
filemode.c
|
filemode.c
|
||||||
|
format.c
|
||||||
host-aout.c
|
host-aout.c
|
||||||
i386coff.c
|
i386coff.c
|
||||||
icoff.c
|
icoff.c
|
||||||
@ -65,12 +65,14 @@ libieee.h
|
|||||||
liboasys.h
|
liboasys.h
|
||||||
m68kcoff.c
|
m68kcoff.c
|
||||||
m88k-bcs.c
|
m88k-bcs.c
|
||||||
misc.h
|
|
||||||
newsos3.c
|
newsos3.c
|
||||||
oasys.c
|
oasys.c
|
||||||
opncls.c
|
opncls.c
|
||||||
|
reloc.c
|
||||||
|
section.c
|
||||||
srec.c
|
srec.c
|
||||||
sunos.c
|
sunos.c
|
||||||
|
syms.c
|
||||||
targets.c
|
targets.c
|
||||||
trad-core.c
|
trad-core.c
|
||||||
trad-core.h
|
trad-core.h
|
||||||
@ -82,6 +84,9 @@ echo Done in `pwd`.
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# $Log$
|
# $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
|
# Revision 1.3 1991/05/31 11:22:12 gnu
|
||||||
# Remove coff-code.h and liba.out.h, add libaout.h.
|
# Remove coff-code.h and liba.out.h, add libaout.h.
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
# Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of BFD, the Binary File Diddler.
|
# This file is part of BFD, the Binary File Diddler.
|
||||||
@ -20,6 +20,8 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
srcdir = .
|
srcdir = .
|
||||||
|
destdir = /usr/local
|
||||||
|
libdir = $(destdir)/lib
|
||||||
|
|
||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
AR = ar
|
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 \
|
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 \
|
BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o \
|
||||||
m68kcoff.o i386coff.o m88k-bcs.o coffswap.o ecoff.o newsos3.o # trad-core.o bout.o
|
demo64.o \
|
||||||
|
m68kcoff.o i386coff.o m88k-bcs.o ecoff.o newsos3.o # trad-core.o bout.o
|
||||||
|
|
||||||
BFD_H=$(INCDIR)/bfd.h
|
BFD_H=$(INCDIR)/bfd.h
|
||||||
SYSDEP_H=$(INCDIR)/sysdep.h
|
SYSDEP_H=$(INCDIR)/sysdep.h
|
||||||
|
|
||||||
# C source files that correspond to .o's.
|
# C source files that correspond to .o's.
|
||||||
CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
|
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 \
|
i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \
|
||||||
m88k-bcs.c coffswap.c ecoff.c trad-core.c newsos3.c #bout.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)
|
STAGESTUFF = $(TARGETLIB) $(OFILES)
|
||||||
|
|
||||||
@ -149,6 +154,8 @@ roll:
|
|||||||
force:
|
force:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
install -c libbfd.a $(libdir)
|
||||||
|
$(RANLIB) $(libdir)/libbfd.a
|
||||||
|
|
||||||
# Target to uncomment host-specific lines in this makefile. Such lines must
|
# Target to uncomment host-specific lines in this makefile. Such lines must
|
||||||
# have the following string beginning in column 1: #__<hostname>__#
|
# have the following string beginning in column 1: #__<hostname>__#
|
||||||
@ -181,3 +188,81 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/configure
|
|||||||
|
|
||||||
dep: $(CFILES)
|
dep: $(CFILES)
|
||||||
mkdep $(CFLAGS) $?
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
47
bfd/aoutf1.h
47
bfd/aoutf1.h
@ -1,5 +1,3 @@
|
|||||||
/* BFD backend for generic a.out flavour 1 */
|
|
||||||
|
|
||||||
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Diddler.
|
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
|
along with BFD; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
|
||||||
#include <ansidecl.h>
|
#include <ansidecl.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
struct external_exec;
|
struct external_exec;
|
||||||
@ -33,6 +32,33 @@ struct external_exec;
|
|||||||
#include "ar.h"
|
#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)();
|
void (*bfd_error_trap)();
|
||||||
|
|
||||||
@ -177,7 +203,7 @@ DEFUN(NAME(aout,sunos4_write_object_contents),(abfd),
|
|||||||
choose_reloc_size(abfd);
|
choose_reloc_size(abfd);
|
||||||
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
N_SET_FLAGS (*execp, 0x81);
|
N_SET_FLAGS (*execp, 0x1);
|
||||||
|
|
||||||
WRITE_HEADERS(abfd, execp);
|
WRITE_HEADERS(abfd, execp);
|
||||||
|
|
||||||
@ -461,13 +487,23 @@ DEFUN(swapcore,(abfd, core),
|
|||||||
#define aout_64_core_file_failing_signal sunos4_core_file_failing_signal
|
#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_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
|
/* We implement these routines ourselves, rather than using the generic
|
||||||
a.out versions. */
|
a.out versions. */
|
||||||
#define aout_write_object_contents sunos4_write_object_contents
|
#define aout_write_object_contents sunos4_write_object_contents
|
||||||
|
|
||||||
bfd_target VECNAME =
|
bfd_target VECNAME =
|
||||||
{
|
{
|
||||||
TARGETNAME,
|
TARGETNAME,
|
||||||
bfd_target_aout_flavour_enum,
|
bfd_target_aout_flavour_enum,
|
||||||
true, /* target byte order */
|
true, /* target byte order */
|
||||||
true, /* target headers byte order */
|
true, /* target headers byte order */
|
||||||
@ -477,6 +513,7 @@ TARGETNAME,
|
|||||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||||
' ', /* ar_pad_char */
|
' ', /* ar_pad_char */
|
||||||
16, /* ar_max_namelen */
|
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, /* data */
|
||||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||||
|
|
||||||
@ -488,4 +525,4 @@ TARGETNAME,
|
|||||||
_bfd_write_archive_contents, bfd_false},
|
_bfd_write_archive_contents, bfd_false},
|
||||||
|
|
||||||
JUMP_TABLE(JNAME(aout))
|
JUMP_TABLE(JNAME(aout))
|
||||||
};
|
};
|
||||||
|
157
bfd/aoutx.h
157
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. */
|
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 <sysdep.h>
|
||||||
#include <ansidecl.h>
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
struct external_exec;
|
struct external_exec;
|
||||||
#include "liba.out.h"
|
#include "libaout.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
#include "aout64.h"
|
#include "aout64.h"
|
||||||
#include "stab.gnu.h"
|
#include "stab.gnu.h"
|
||||||
@ -34,9 +90,15 @@ struct external_exec;
|
|||||||
|
|
||||||
void (*bfd_error_trap)();
|
void (*bfd_error_trap)();
|
||||||
|
|
||||||
/*SUPPRESS558*/
|
/*doc*
|
||||||
/*SUPPRESS529*/
|
@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
|
#define CTOR_TABLE_RELOC_IDX 2
|
||||||
static reloc_howto_type howto_table_ext[] =
|
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;
|
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
|
void
|
||||||
DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
|
DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
|
||||||
bfd *abfd AND
|
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);
|
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
|
void
|
||||||
DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
|
DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
|
||||||
bfd *abfd AND
|
bfd *abfd AND
|
||||||
@ -128,10 +217,19 @@ struct container {
|
|||||||
struct internal_exec e;
|
struct internal_exec e;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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
|
/*doc*
|
||||||
it really is. Call back to the calling environments "finish up"
|
*i aout_<size>_some_aout_object_p
|
||||||
function just before returning, to handle any last-minute setup. */
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
|
||||||
|
(bfd *abfd,
|
||||||
|
bfd_target *(*callback_to_real_object_p)()));
|
||||||
|
*/
|
||||||
|
|
||||||
bfd_target *
|
bfd_target *
|
||||||
DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
|
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);
|
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
|
boolean
|
||||||
DEFUN(NAME(aout,mkobject),(abfd),
|
DEFUN(NAME(aout,mkobject),(abfd),
|
||||||
@ -314,12 +419,21 @@ DEFUN(NAME(aout,mkobject),(abfd),
|
|||||||
return true;
|
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
|
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 that exact arch&machine can't be represented in a.out format.
|
||||||
|
|
||||||
If the architecture is understood, machine type 0 (default) should
|
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
|
enum machine_type
|
||||||
DEFUN(NAME(aout,machine_type),(arch, machine),
|
DEFUN(NAME(aout,machine_type),(arch, machine),
|
||||||
@ -360,6 +474,19 @@ DEFUN(NAME(aout,machine_type),(arch, machine),
|
|||||||
return arch_flags;
|
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
|
boolean
|
||||||
DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
|
DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
|
||||||
bfd *abfd AND
|
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 false; /* We can't represent this type */
|
||||||
return true; /* We're easy ... */
|
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
|
boolean
|
||||||
DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
|
DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
|
||||||
bfd *abfd AND
|
bfd *abfd AND
|
||||||
@ -1460,7 +1593,7 @@ DEFUN(NAME(aout,find_nearest_line),(abfd,
|
|||||||
buffer[sizeof(buffer)-1] = 0;
|
buffer[sizeof(buffer)-1] = 0;
|
||||||
/* Have to remove : stuff */
|
/* Have to remove : stuff */
|
||||||
p = strchr(buffer,':');
|
p = strchr(buffer,':');
|
||||||
if (p != NULL) {*p = NULL; }
|
if (p != NULL) { *p = NULL; }
|
||||||
*functionname_ptr = buffer;
|
*functionname_ptr = buffer;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
105
bfd/archive.c
105
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.
|
/* 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. */
|
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:
|
/* Assumes:
|
||||||
o - all archive elements start on an even boundary, newline padded;
|
o - all archive elements start on an even boundary, newline padded;
|
||||||
o - all arch headers are char *;
|
o - all arch headers are char *;
|
||||||
@ -72,6 +85,10 @@ _bfd_generic_mkarchive (abfd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*proto* bfd_get_next_mapent
|
||||||
|
What this does
|
||||||
|
*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
|
||||||
|
*/
|
||||||
symindex
|
symindex
|
||||||
bfd_get_next_mapent (abfd, prev, entry)
|
bfd_get_next_mapent (abfd, prev, entry)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -107,9 +124,16 @@ _bfd_create_empty_archive_element_shell (obfd)
|
|||||||
return nbfd;
|
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
|
boolean
|
||||||
bfd_set_archive_head (output_archive, new_head)
|
DEFUN(bfd_set_archive_head,(output_archive, new_head),
|
||||||
bfd *output_archive, *new_head;
|
bfd *output_archive AND
|
||||||
|
bfd *new_head)
|
||||||
{
|
{
|
||||||
|
|
||||||
output_archive->archive_head = new_head;
|
output_archive->archive_head = new_head;
|
||||||
@ -229,8 +253,10 @@ snarf_ar_hdr (abfd)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract the filename from the archive */
|
/* extract the filename from the archive - there are two ways to
|
||||||
if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
|
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);
|
filename = get_extended_arelt_filename (abfd, hdr.ar_name);
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
bfd_error = malformed_archive;
|
bfd_error = malformed_archive;
|
||||||
@ -325,10 +351,22 @@ bfd_get_elt_at_index (abfd, index)
|
|||||||
return result;
|
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 *
|
||||||
bfd_openr_next_archived_file (archive, last_file)
|
DEFUN(bfd_openr_next_archived_file,(archive, last_file),
|
||||||
bfd *archive, *last_file;
|
bfd *archive AND
|
||||||
|
bfd*last_file)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((bfd_get_format (archive) != bfd_archive) ||
|
if ((bfd_get_format (archive) != bfd_archive) ||
|
||||||
@ -411,7 +449,7 @@ boolean
|
|||||||
bfd_slurp_bsd_armap (abfd)
|
bfd_slurp_bsd_armap (abfd)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct areltdata *mapdata;
|
struct areltdata *mapdata;
|
||||||
char nextname[17];
|
char nextname[17];
|
||||||
unsigned int counter = 0;
|
unsigned int counter = 0;
|
||||||
@ -451,7 +489,7 @@ bfd_slurp_bsd_armap (abfd)
|
|||||||
goto byebye;
|
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;
|
ardata->cache = 0;
|
||||||
rbase = raw_armap+1;
|
rbase = raw_armap+1;
|
||||||
ardata->symdefs = (carsym *) rbase;
|
ardata->symdefs = (carsym *) rbase;
|
||||||
@ -459,8 +497,8 @@ bfd_slurp_bsd_armap (abfd)
|
|||||||
|
|
||||||
for (;counter < ardata->symdef_count; counter++) {
|
for (;counter < ardata->symdef_count; counter++) {
|
||||||
struct symdef *sym = ((struct symdef *) rbase) + counter;
|
struct symdef *sym = ((struct symdef *) rbase) + counter;
|
||||||
sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
|
sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
|
||||||
sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
|
sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ardata->first_file_filepos = bfd_tell (abfd);
|
ardata->first_file_filepos = bfd_tell (abfd);
|
||||||
@ -501,13 +539,16 @@ bfd_slurp_coff_armap (abfd)
|
|||||||
if (mapdata == NULL) return false;
|
if (mapdata == NULL) return false;
|
||||||
|
|
||||||
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
|
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
|
||||||
if (raw_armap == NULL) {
|
|
||||||
|
if (raw_armap == NULL)
|
||||||
|
{
|
||||||
bfd_error = no_memory;
|
bfd_error = no_memory;
|
||||||
byebye:
|
byebye:
|
||||||
bfd_release (abfd, (PTR)mapdata);
|
bfd_release (abfd, (PTR)mapdata);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* read in the raw map */
|
||||||
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
|
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
|
||||||
mapdata->parsed_size) {
|
mapdata->parsed_size) {
|
||||||
bfd_error = malformed_archive;
|
bfd_error = malformed_archive;
|
||||||
@ -552,19 +593,22 @@ bfd_slurp_coff_armap (abfd)
|
|||||||
ardata->first_file_filepos = bfd_tell (abfd);
|
ardata->first_file_filepos = bfd_tell (abfd);
|
||||||
/* Pad to an even boundary if you have to */
|
/* Pad to an even boundary if you have to */
|
||||||
ardata->first_file_filepos += (ardata->first_file_filepos) %2;
|
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;
|
bfd_has_map (abfd) = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extended name table.
|
/** Extended name table.
|
||||||
|
|
||||||
Normally archives support only 14-character filenames. Intel has extended
|
Normally archives support only 14-character filenames.
|
||||||
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
|
Intel has extended the format: longer names are stored in a special
|
||||||
by <space><index into filename element>. Index is the P.R. of an int (radix:
|
element (the first in the archive, or second if there is an armap);
|
||||||
8). */
|
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 */
|
/* Returns false on error, true otherwise */
|
||||||
boolean
|
boolean
|
||||||
@ -580,7 +624,9 @@ _bfd_slurp_extended_name_table (abfd)
|
|||||||
|
|
||||||
bfd_seek (abfd, -16L, SEEK_CUR);
|
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;
|
bfd_ardata (abfd)->extended_names = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -604,8 +650,9 @@ _bfd_slurp_extended_name_table (abfd)
|
|||||||
goto byebye;
|
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;
|
char *temp = bfd_ardata (abfd)->extended_names;
|
||||||
for (; *temp != '\0'; ++temp)
|
for (; *temp != '\0'; ++temp)
|
||||||
@ -620,7 +667,7 @@ _bfd_slurp_extended_name_table (abfd)
|
|||||||
/* FIXME, we can't release namedata here because it was allocated
|
/* FIXME, we can't release namedata here because it was allocated
|
||||||
below extended_names on the obstack... */
|
below extended_names on the obstack... */
|
||||||
/* bfd_release (abfd, namedata); */
|
/* bfd_release (abfd, namedata); */
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,7 +1174,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
|
|||||||
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
||||||
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
|
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
|
||||||
bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
|
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);
|
bfd_write (&temp, 1, sizeof (temp), arch);
|
||||||
|
|
||||||
for (count = 0; count < orl_count; count++) {
|
for (count = 0; count < orl_count; count++) {
|
||||||
@ -1143,13 +1190,13 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
|
|||||||
} /* if new archive element */
|
} /* if new archive element */
|
||||||
|
|
||||||
last_elt = current;
|
last_elt = current;
|
||||||
bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
|
bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
|
||||||
bfd_h_put_32(arch, firstreal, &outs.file_offset);
|
bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
|
||||||
bfd_write ((char *)outp, 1, sizeof (outs), arch);
|
bfd_write ((char *)outp, 1, sizeof (outs), arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now write the strings themselves */
|
/* 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);
|
bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
|
||||||
for (count = 0; count < orl_count; count++)
|
for (count = 0; count < orl_count; count++)
|
||||||
bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
|
bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
|
||||||
|
887
bfd/bfd.c
887
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.
|
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Diddler.
|
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
|
along with BFD; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
|
||||||
/* $Id$ */
|
/* $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 <sysdep.h>
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
|
|
||||||
|
|
||||||
short _bfd_host_big_endian = 0x0100;
|
short _bfd_host_big_endian = 0x0100;
|
||||||
/* Accessing the above as (*(char*)&_bfd_host_big_endian), will
|
/* Accessing the above as (*(char*)&_bfd_host_big_endian), will
|
||||||
return 1 if the host is big-endian, 0 otherwise.
|
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 */
|
/** 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 */
|
/* returns the number of octets of storage required */
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
get_reloc_upper_bound (abfd, asect)
|
get_reloc_upper_bound (abfd, asect)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols)
|
|||||||
return BFD_SEND (abfd, _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
|
boolean
|
||||||
bfd_set_file_flags (abfd, flags)
|
bfd_set_file_flags (abfd, flags)
|
||||||
@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
|
|||||||
asect->orelocation = location;
|
asect->orelocation = location;
|
||||||
asect->reloc_count = count;
|
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
|
void
|
||||||
bfd_assert(file, line)
|
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
|
boolean
|
||||||
bfd_set_start_address(abfd, vma)
|
bfd_set_start_address(abfd, vma)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -899,19 +368,15 @@ bfd_vma vma;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bfd_vma bfd_log2(x)
|
/*proto* bfd_get_mtime
|
||||||
bfd_vma x;
|
|
||||||
{
|
|
||||||
bfd_vma result = 0;
|
|
||||||
while ( (bfd_vma)(1<< result) < x)
|
|
||||||
result++;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bfd_get_mtime: Return cached file modification time (e.g. as read
|
Return cached file modification time (e.g. as read from archive header
|
||||||
from archive header for archive members, or from file system if we have
|
for archive members, or from file system if we have been called
|
||||||
been called before); else determine modify time, cache it, and
|
before); else determine modify time, cache it, and return it.
|
||||||
return it. */
|
|
||||||
|
*;PROTO(long, bfd_get_mtime, (bfd *));
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
long
|
long
|
||||||
bfd_get_mtime (abfd)
|
bfd_get_mtime (abfd)
|
||||||
@ -931,3 +396,33 @@ bfd_get_mtime (abfd)
|
|||||||
abfd->mtime = buf.st_mtime;
|
abfd->mtime = buf.st_mtime;
|
||||||
return abfd->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))
|
||||||
|
*-
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1617
bfd/coffcode.h
1617
bfd/coffcode.h
File diff suppressed because it is too large
Load Diff
1180
bfd/ieee.c
1180
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 */
|
/** 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
|
resizes the table if necessary (if it's NULL, creates it, ignoring
|
||||||
table_length). Updates free_ptr, table, table_length */
|
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__.
|
functions in swap.h #ifdef __GNUC__.
|
||||||
Gprof them later and find out. */
|
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
|
unsigned int
|
||||||
DEFUN(_do_getb16,(addr),
|
DEFUN(_do_getb16,(addr),
|
||||||
register bfd_byte *addr)
|
register bfd_byte *addr)
|
||||||
@ -333,7 +389,9 @@ DEFUN(_do_getb64,(addr),
|
|||||||
|
|
||||||
return high << 32 | low;
|
return high << 32 | low;
|
||||||
#else
|
#else
|
||||||
|
bfd_64_type foo;
|
||||||
BFD_FAIL();
|
BFD_FAIL();
|
||||||
|
return foo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -342,8 +400,9 @@ bfd_64_type
|
|||||||
DEFUN(_do_getl64,(addr),
|
DEFUN(_do_getl64,(addr),
|
||||||
register bfd_byte *addr)
|
register bfd_byte *addr)
|
||||||
{
|
{
|
||||||
bfd_64_type low, high;
|
|
||||||
#ifdef HOST_64_BIT
|
#ifdef HOST_64_BIT
|
||||||
|
bfd_64_type low, high;
|
||||||
high= (((((((addr[7] << 8) |
|
high= (((((((addr[7] << 8) |
|
||||||
addr[6]) << 8) |
|
addr[6]) << 8) |
|
||||||
addr[5]) << 8) |
|
addr[5]) << 8) |
|
||||||
@ -356,8 +415,11 @@ DEFUN(_do_getl64,(addr),
|
|||||||
|
|
||||||
return high << 32 | low;
|
return high << 32 | low;
|
||||||
#else
|
#else
|
||||||
|
bfd_64_type foo;
|
||||||
BFD_FAIL();
|
BFD_FAIL();
|
||||||
|
return foo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -440,3 +502,19 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count)
|
|||||||
return (false); /* on error */
|
return (false); /* on error */
|
||||||
return (true);
|
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_alloc, (bfd *abfd, bfd_size_type size));
|
||||||
PROTO(PTR, bfd_zalloc,(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(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)
|
#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_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 (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 (int, bfd_seek,(bfd* abfd, file_ptr fp , int direction));
|
||||||
PROTO (long, bfd_tell, (bfd *abfd));
|
PROTO (long, bfd_tell, (bfd *abfd));
|
||||||
PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd));
|
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 *));
|
PROTO (FILE *, bfd_cache_lookup_worker, (bfd *));
|
||||||
|
|
||||||
extern bfd *bfd_last_cache;
|
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? */
|
/* Now Steve, what's the story here? */
|
||||||
#ifdef lint
|
#ifdef lint
|
||||||
@ -175,3 +176,51 @@ extern bfd *bfd_last_cache;
|
|||||||
|
|
||||||
/* Generic routine for close_and_cleanup is really just bfd_true. */
|
/* Generic routine for close_and_cleanup is really just bfd_true. */
|
||||||
#define bfd_generic_close_and_cleanup 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 "bfd.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
#include "aout64.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 "stab.gnu.h"
|
||||||
#include "ar.h"
|
#include "ar.h"
|
||||||
#include "libaout.h" /* BFD a.out internal data structures */
|
#include "libaout.h" /* BFD a.out internal data structures */
|
||||||
|
#if 0
|
||||||
int vfprintf(file, format, args) /* Temporary crock! */
|
int vfprintf(file, format, args) /* Temporary crock! */
|
||||||
FILE *file; char *format; char *args;
|
FILE *file; char *format; char *args;
|
||||||
{
|
{
|
||||||
return _doprnt (format, args, file);
|
return _doprnt (format, args, file);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bfd_target *newsos3_callback ();
|
bfd_target *newsos3_callback ();
|
||||||
@ -49,7 +55,7 @@ bfd_target *
|
|||||||
DEFUN(newsos3_object_p,(abfd),
|
DEFUN(newsos3_object_p,(abfd),
|
||||||
bfd *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 */
|
unsigned long magic; /* Swapped magic number */
|
||||||
|
|
||||||
bfd_error = system_call_error;
|
bfd_error = system_call_error;
|
||||||
@ -99,19 +105,40 @@ DEFUN(newsos3_write_object_contents,(abfd),
|
|||||||
/* Transfer vectors for NEWS-OS version 3 */
|
/* Transfer vectors for NEWS-OS version 3 */
|
||||||
|
|
||||||
/* We use BFD generic archive files. */
|
/* We use BFD generic archive files. */
|
||||||
#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
|
#define newsos_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||||
#define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
#define newsos_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||||
#define aout_32_slurp_armap bfd_slurp_bsd_armap
|
#define newsos_slurp_armap bfd_slurp_bsd_armap
|
||||||
#define aout_32_slurp_extended_name_table bfd_true
|
#define newsos_slurp_extended_name_table bfd_true
|
||||||
#define aout_32_write_armap bsd_write_armap
|
#define newsos_write_armap bsd_write_armap
|
||||||
#define aout_32_truncate_arname bfd_bsd_truncate_arname
|
#define newsos_truncate_arname bfd_bsd_truncate_arname
|
||||||
|
|
||||||
/* We don't support core files yet. FIXME. */
|
/* We don't support core files yet. FIXME. */
|
||||||
#define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
|
#define newsos_core_file_failing_command _bfd_dummy_core_file_failing_command
|
||||||
#define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
|
#define newsos_core_file_failing_signal _bfd_dummy_core_file_failing_signal
|
||||||
#define aout_32_core_file_matches_executable_p \
|
#define newsos_core_file_matches_executable_p \
|
||||||
_bfd_dummy_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. */
|
/* 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 */
|
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||||
' ', /* ar_pad_char */
|
' ', /* ar_pad_char */
|
||||||
16, /* ar_max_namelen */
|
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, /* data */
|
||||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||||
|
|
||||||
{_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */
|
{_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */
|
||||||
bfd_generic_archive_p, aout_32_core_file_p},
|
bfd_generic_archive_p, newsos_core_file_p},
|
||||||
{bfd_false, aout_32_mkobject, /* bfd_set_format */
|
{bfd_false, newsos_mkobject, /* bfd_set_format */
|
||||||
_bfd_generic_mkarchive, bfd_false},
|
_bfd_generic_mkarchive, bfd_false},
|
||||||
{bfd_false, newsos3_write_object_contents, /* bfd_write_contents */
|
{bfd_false, newsos3_write_object_contents, /* bfd_write_contents */
|
||||||
_bfd_write_archive_contents, bfd_false},
|
_bfd_write_archive_contents, bfd_false},
|
||||||
|
|
||||||
JUMP_TABLE(aout_32)
|
JUMP_TABLE(newsos)
|
||||||
};
|
};
|
||||||
|
120
bfd/oasys.c
120
bfd/oasys.c
@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
#include "oasys.h"
|
#include "oasys.h"
|
||||||
#include "liboasys.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
|
static void
|
||||||
DEFUN(oasys_read_record,(abfd, record),
|
DEFUN(oasys_read_record,(abfd, record),
|
||||||
bfd *CONST abfd AND
|
bfd *CONST abfd AND
|
||||||
@ -127,6 +132,12 @@ DEFUN(oasys_slurp_symbol_table,(abfd),
|
|||||||
if (record.header.type == oasys_record_is_local_enum)
|
if (record.header.type == oasys_record_is_local_enum)
|
||||||
{
|
{
|
||||||
dest->flags = BSF_LOCAL;
|
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 {
|
else {
|
||||||
|
|
||||||
@ -258,7 +269,7 @@ DEFUN(oasys_archive_p,(abfd),
|
|||||||
|
|
||||||
|
|
||||||
oasys_module_table_type record;
|
oasys_module_table_type record;
|
||||||
oasys_external_module_table_type record_ext;
|
|
||||||
|
|
||||||
set_tdata(abfd, ar);
|
set_tdata(abfd, ar);
|
||||||
ar->module = module;
|
ar->module = module;
|
||||||
@ -268,6 +279,11 @@ DEFUN(oasys_archive_p,(abfd),
|
|||||||
filepos = header.mod_tbl_offset;
|
filepos = header.mod_tbl_offset;
|
||||||
for (i = 0; i < header.mod_count; i++) {
|
for (i = 0; i < header.mod_count; i++) {
|
||||||
bfd_seek(abfd , filepos, SEEK_SET);
|
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);
|
bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
|
||||||
|
|
||||||
record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
|
record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
|
||||||
@ -286,7 +302,30 @@ DEFUN(oasys_archive_p,(abfd),
|
|||||||
sizeof(record_ext) +
|
sizeof(record_ext) +
|
||||||
record.dep_count * 4 +
|
record.dep_count * 4 +
|
||||||
record.depee_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;
|
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->size = bfd_h_get_32(abfd, & record.section.value[0]) ;
|
||||||
s->vma = bfd_h_get_32(abfd, &record.section.vma[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;
|
had_usefull = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -402,6 +441,14 @@ DEFUN(oasys_object_p,(abfd),
|
|||||||
if (abfd->symcount != 0) {
|
if (abfd->symcount != 0) {
|
||||||
abfd->flags |= HAS_SYMS;
|
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;
|
return abfd->xvec;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -465,21 +512,20 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
|||||||
|
|
||||||
asection *s;
|
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) {
|
for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
|
||||||
per = oasys_per_section(s);
|
per = oasys_per_section(s);
|
||||||
if (per->data != (bfd_byte*)NULL) return true;
|
if (per->initialized == true)
|
||||||
per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
|
return true;
|
||||||
per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
|
|
||||||
per->had_vma = false;
|
|
||||||
s->reloc_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->first_data_record == 0) return true;
|
if (data->first_data_record == 0) return true;
|
||||||
|
|
||||||
bfd_seek(abfd, data->first_data_record, SEEK_SET);
|
bfd_seek(abfd, data->first_data_record, SEEK_SET);
|
||||||
while (loop) {
|
while (loop) {
|
||||||
oasys_read_record(abfd, &record);
|
oasys_read_record(abfd, &record);
|
||||||
switch (record.header.type) {
|
switch (record.header.type)
|
||||||
|
{
|
||||||
case oasys_record_is_header_enum:
|
case oasys_record_is_header_enum:
|
||||||
break;
|
break;
|
||||||
case oasys_record_is_data_enum:
|
case oasys_record_is_data_enum:
|
||||||
@ -496,6 +542,18 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
|||||||
data->sections[record.data.relb & RELOCATION_SECT_BITS];
|
data->sections[record.data.relb & RELOCATION_SECT_BITS];
|
||||||
bfd_vma dst_offset ;
|
bfd_vma dst_offset ;
|
||||||
per = oasys_per_section(section);
|
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) ;
|
dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
|
||||||
if (per->had_vma == false) {
|
if (per->had_vma == false) {
|
||||||
/* Take the first vma we see as the base */
|
/* 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_ptr = oasys_per_section(section)->data +
|
||||||
dst_offset;
|
dst_offset;
|
||||||
|
|
||||||
|
if (src < end_src) {
|
||||||
|
section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
|
||||||
|
}
|
||||||
while (src < end_src) {
|
while (src < end_src) {
|
||||||
uint32_type gap = end_src - src -1;
|
|
||||||
uint8e_type mod_byte = *src++;
|
uint8e_type mod_byte = *src++;
|
||||||
|
uint32_type gap = end_src - src;
|
||||||
|
|
||||||
count = 8;
|
count = 8;
|
||||||
if (mod_byte == 0 && gap >= 8) {
|
if (mod_byte == 0 && gap >= 8) {
|
||||||
dst_ptr[0] = src[0];
|
dst_ptr[0] = src[0];
|
||||||
@ -529,7 +591,7 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
|||||||
src += 8;
|
src += 8;
|
||||||
}
|
}
|
||||||
else {
|
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)
|
if (relbit & mod_byte)
|
||||||
{
|
{
|
||||||
@ -628,6 +690,7 @@ DEFUN(oasys_slurp_section_data,(abfd),
|
|||||||
loop = false;
|
loop = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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)->data = (bfd_byte *)NULL;
|
||||||
oasys_per_section(newsect)->section = newsect;
|
oasys_per_section(newsect)->section = newsect;
|
||||||
oasys_per_section(newsect)->offset = 0;
|
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 */
|
/* Turn the section string into an index */
|
||||||
|
|
||||||
sscanf(newsect->name,"%u", &newsect->target_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_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
|
||||||
oasys_slurp_section_data(abfd);
|
oasys_slurp_section_data(abfd);
|
||||||
|
if (p->initialized == false)
|
||||||
|
{
|
||||||
|
(void) memset(location, 0, (int)count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
(void) memcpy(location, p->data + offset, (int)count);
|
(void) memcpy(location, p->data + offset, (int)count);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +852,15 @@ DEFUN(oasys_write_syms, (abfd),
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
|
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]));
|
bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
|
||||||
}
|
}
|
||||||
while (src[l]) {
|
while (src[l]) {
|
||||||
@ -900,6 +979,7 @@ DEFUN(oasys_write_data, (abfd),
|
|||||||
{
|
{
|
||||||
asection *s;
|
asection *s;
|
||||||
for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
|
for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
|
||||||
|
if (s->flags & SEC_LOAD) {
|
||||||
uint8e_type *raw_data = oasys_per_section(s)->data;
|
uint8e_type *raw_data = oasys_per_section(s)->data;
|
||||||
oasys_data_record_type processed_data;
|
oasys_data_record_type processed_data;
|
||||||
bfd_size_type current_byte_index = 0;
|
bfd_size_type current_byte_index = 0;
|
||||||
@ -1035,6 +1115,7 @@ DEFUN(oasys_write_data, (abfd),
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static boolean
|
static boolean
|
||||||
DEFUN(oasys_write_object_contents, (abfd),
|
DEFUN(oasys_write_object_contents, (abfd),
|
||||||
@ -1180,17 +1261,20 @@ DEFUN(oasys_sizeof_headers,(abfd, exec),
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#define FOO PROTO
|
||||||
#define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
|
#define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
|
||||||
#define oasys_core_file_failing_signal (int (*)())bfd_0
|
#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_armap bfd_true
|
||||||
#define oasys_slurp_extended_name_table bfd_true
|
#define oasys_slurp_extended_name_table bfd_true
|
||||||
#define oasys_truncate_arname (void (*)())bfd_nullvoidptr
|
#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_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
|
||||||
#define oasys_close_and_cleanup bfd_generic_close_and_cleanup
|
#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 */
|
/*SUPPRESS 460 */
|
||||||
@ -1207,7 +1291,7 @@ bfd_target oasys_vec =
|
|||||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||||
' ', /* ar_pad_char */
|
' ', /* ar_pad_char */
|
||||||
16, /* ar_max_namelen */
|
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, /* data */
|
||||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
_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;
|
return nbfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** bfd_openr, bfd_fdopenr -- open for reading.
|
/*doc*
|
||||||
Returns a pointer to a freshly-allocated bfd on success, or NULL. */
|
@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 *
|
bfd *
|
||||||
DEFUN(bfd_openr, (filename, target),
|
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
|
close it if anything goes wrong. Closing the stream means closing
|
||||||
the file descriptor too, even though we didn't open it.
|
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 *
|
bfd *
|
||||||
DEFUN(bfd_fdopenr,(filename, target, fd),
|
DEFUN(bfd_fdopenr,(filename, target, fd),
|
||||||
@ -155,7 +175,7 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
|
|||||||
|
|
||||||
bfd_error = system_call_error;
|
bfd_error = system_call_error;
|
||||||
|
|
||||||
fdflags = fcntl (fd, F_GETFL);
|
fdflags = fcntl (fd, F_GETFL, NULL);
|
||||||
if (fdflags == -1) return NULL;
|
if (fdflags == -1) return NULL;
|
||||||
|
|
||||||
#ifdef BFD_LOCKS
|
#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. */
|
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 *
|
bfd *
|
||||||
DEFUN(bfd_openw,(filename, target),
|
DEFUN(bfd_openw,(filename, target),
|
||||||
CONST char *filename AND
|
CONST char *filename AND
|
||||||
@ -246,11 +274,22 @@ DEFUN(bfd_openw,(filename, target),
|
|||||||
}
|
}
|
||||||
return nbfd;
|
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
|
boolean
|
||||||
bfd_close (abfd)
|
DEFUN(bfd_close,(abfd),
|
||||||
bfd *abfd;
|
bfd *abfd)
|
||||||
{
|
{
|
||||||
if (!bfd_read_p(abfd))
|
if (!bfd_read_p(abfd))
|
||||||
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
|
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
|
||||||
@ -283,12 +322,18 @@ bfd_close (abfd)
|
|||||||
return true;
|
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 *
|
bfd *
|
||||||
DEFUN(bfd_create,(filename, template),
|
DEFUN(bfd_create,(filename, template),
|
||||||
CONST char *filename AND
|
CONST char *filename AND
|
||||||
CONST bfd *template)
|
bfd *template)
|
||||||
{
|
{
|
||||||
bfd *nbfd = new_bfd();
|
bfd *nbfd = new_bfd();
|
||||||
if (nbfd == (bfd *)NULL) {
|
if (nbfd == (bfd *)NULL) {
|
||||||
@ -313,6 +358,20 @@ DEFUN(PTR bfd_alloc_by_size_t,(abfd, size),
|
|||||||
PTR res = obstack_alloc(&(abfd->memory), size);
|
PTR res = obstack_alloc(&(abfd->memory), size);
|
||||||
return res;
|
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),
|
DEFUN(PTR bfd_alloc, (abfd, size),
|
||||||
bfd *abfd AND
|
bfd *abfd AND
|
||||||
bfd_size_type size)
|
bfd_size_type size)
|
||||||
@ -339,8 +398,14 @@ DEFUN(PTR bfd_realloc,(abfd, old, size),
|
|||||||
return res;
|
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)
|
bfd *abfd)
|
||||||
{
|
{
|
||||||
struct _obstack_chunk *chunk = abfd->memory.chunk;
|
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+1) << 16)
|
||||||
+ (HEX(buffer.u.type_3.address+2) << 8)
|
+ (HEX(buffer.u.type_3.address+2) << 8)
|
||||||
+ (HEX(buffer.u.type_3.address+3));
|
+ (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;
|
break;
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ int bytes_to_do;
|
|||||||
check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
|
check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
|
||||||
size = bytes_this_chunk + 5;
|
size = bytes_this_chunk + 5;
|
||||||
data = buffer.u.type_3.data;
|
data = buffer.u.type_3.data;
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
|
check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
|
||||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
|
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);
|
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
|
||||||
size = bytes_this_chunk + 3;
|
size = bytes_this_chunk + 3;
|
||||||
data = buffer.u.type_1.data;
|
data = buffer.u.type_1.data;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < bytes_this_chunk; i++) {
|
for (i = 0; i < bytes_this_chunk; i++) {
|
||||||
@ -380,31 +381,32 @@ DEFUN(srec_make_empty_symbol, (abfd),
|
|||||||
new->the_bfd = abfd;
|
new->the_bfd = abfd;
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
/*SUPPRESS 460 */
|
#define FOO PROTO
|
||||||
|
#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
|
||||||
#define srec_new_section_hook (PROTO(boolean, (*), (bfd *, asection *)))bfd_true
|
|
||||||
#define srec_get_symtab_upper_bound bfd_false
|
#define srec_get_symtab_upper_bound bfd_false
|
||||||
#define srec_get_symtab (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
|
#define srec_get_symtab (FOO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
|
||||||
#define srec_get_reloc_upper_bound (PROTO(unsigned int, (*),(bfd*, asection *)))bfd_false
|
#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
|
||||||
#define srec_canonicalize_reloc (PROTO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
|
#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_openr_next_archived_file (FOO(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_find_nearest_line (FOO(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_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_command (char *(*)())(bfd_nullvoidptr)
|
||||||
#define srec_core_file_failing_signal (int (*)())bfd_0
|
#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_armap bfd_true
|
||||||
#define srec_slurp_extended_name_table bfd_true
|
#define srec_slurp_extended_name_table bfd_true
|
||||||
#define srec_truncate_arname (void (*)())bfd_nullvoidptr
|
#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_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
|
||||||
|
|
||||||
#define srec_close_and_cleanup bfd_generic_close_and_cleanup
|
#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 =
|
bfd_target srec_vec =
|
||||||
@ -420,6 +422,7 @@ bfd_target srec_vec =
|
|||||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||||
' ', /* ar_pad_char */
|
' ', /* ar_pad_char */
|
||||||
16, /* ar_max_namelen */
|
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, /* data */
|
||||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
_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$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
|
||||||
/* This -*- C -*- source file will someday be machine-generated */
|
|
||||||
|
|
||||||
/*** Defines the target vector through which operations dispatch */
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "libbfd.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_little_vec;
|
||||||
extern bfd_target ecoff_big_vec;
|
extern bfd_target ecoff_big_vec;
|
||||||
extern bfd_target sunos_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 ECOFF_BIG_VEC ecoff_big_vec
|
||||||
#define ICOFF_LITTLE_VEC icoff_little_vec
|
#define ICOFF_LITTLE_VEC icoff_little_vec
|
||||||
#define ICOFF_BIG_VEC icoff_big_vec
|
#define ICOFF_BIG_VEC icoff_big_vec
|
||||||
#define XB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
|
#define ZB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
|
||||||
#define XB_OUT_VEC_BIG_HOST b_out_vec_big_host
|
#define ZB_OUT_VEC_BIG_HOST b_out_vec_big_host
|
||||||
#define SUNOS_VEC_BIG_HOST sunos_big_vec
|
#define SUNOS_VEC_BIG_HOST sunos_big_vec
|
||||||
#define DEMO_64_VEC demo_64_vec
|
#define DEMO_64_VEC demo_64_vec
|
||||||
#define OASYS_VEC oasys_vec
|
#define OASYS_VEC oasys_vec
|
||||||
@ -145,3 +394,81 @@ bfd_target *default_vector[] = {
|
|||||||
#endif
|
#endif
|
||||||
0,
|
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