Things-to-keep:
COPYING
+bfd.texinfo
ChangeLog
+Makefile
Makefile.in
TODO
VERSION
archures.c
archures.h
bfd.c
-bfd.doc
bout.c
cache.c
coffcode.h
-coffish.h
-coffswap.c
-config
-configure
+config.status
+configure*
configure.in
-cplus-dem.c
+core.c
demo64.c
ecoff.c
filemode.c
+format.c
host-aout.c
i386coff.c
icoff.c
liboasys.h
m68kcoff.c
m88k-bcs.c
-misc.h
newsos3.c
oasys.c
opncls.c
+reloc.c
+section.c
srec.c
sunos.c
+syms.c
targets.c
trad-core.c
trad-core.h
#
#
# $Log$
-# Revision 1.3 1991/05/31 11:22:12 gnu
+# Revision 1.4 1991/07/04 16:52:54 steve
+# Now full of documentation. Yum Yum.
+#
+# Revision 1.3 1991/05/31 11:22:12 gnu
# Remove coff-code.h and liba.out.h, add libaout.h.
#
# Revision 1.2 1991/05/29 02:40:08 gnu
-#
+ #
# Copyright (C) 1990, 1991 Free Software Foundation, Inc.
#
# This file is part of BFD, the Binary File Diddler.
# $Id$
srcdir = .
+destdir = /usr/local
+libdir = $(destdir)/lib
RANLIB = ranlib
AR = ar
BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \
- archures.o
+ archures.o core.o section.o format.o syms.o reloc.o
-BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o demo64.o \
- m68kcoff.o i386coff.o m88k-bcs.o coffswap.o ecoff.o newsos3.o # trad-core.o bout.o
+BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o \
+demo64.o \
+m68kcoff.o i386coff.o m88k-bcs.o ecoff.o newsos3.o # trad-core.o bout.o
BFD_H=$(INCDIR)/bfd.h
SYSDEP_H=$(INCDIR)/sysdep.h
# C source files that correspond to .o's.
CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
- i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c oasys.c ieee.c m68kcoff.c \
- m88k-bcs.c coffswap.c ecoff.c trad-core.c newsos3.c #bout.c
+ i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \
+oasys.c ieee.c m68kcoff.c \
+format.c section.c core.c syms.c reloc.c \
+ m88k-bcs.c ecoff.c trad-core.c newsos3.c #bout.c
STAGESTUFF = $(TARGETLIB) $(OFILES)
force:
install:
+ install -c libbfd.a $(libdir)
+ $(RANLIB) $(libdir)/libbfd.a
# Target to uncomment host-specific lines in this makefile. Such lines must
# have the following string beginning in column 1: #__<hostname>__#
dep: $(CFILES)
mkdep $(CFLAGS) $?
+
+
+# Stuff to make the documentation for bfd.
+#
+# make docs
+# rebuilds the documentation. Has to be done when the source is
+# modified until I work out how to do this properly
+#
+# make docs headers
+# rebuilds the header files from the source
+#
+# make docs texdoc
+# rebuilds the bfd.dvi manual
+#
+# make docs texinfo
+# rebuilts the bfdinfo manual
+
+
+.SUFFIXES: .doc .o .c .h .proto
+
+.c.doc:
+ makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+.h.doc:
+ makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+.proto.doc:
+ makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop
+
+
+DSRC=$(CFILES)
+
+docs: syms.doc bfd.doc cache.doc format.doc section.doc archive.doc \
+ core.doc libbfd.doc archures.doc reloc.doc opncls.doc \
+ targets.doc aoutx.doc coffcode.doc
+
+
+PROTOS = doc/opncls.proto doc/archures.proto doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \
+ doc/reloc.proto doc/targets.proto doc/format.proto
+
+
+headers : $(PROTOS)
+ mkdir -f doc
+ # Rebuild prototypes in bfd.h
+ sed <$(BFD_H) >bfd.h.new -e '1,/THE FOLLOWING/!d'
+ cat doc/opncls.proto doc/archures.proto \
+ doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \
+ doc/reloc.proto doc/targets.proto doc/format.proto >>bfd.h.new
+ echo >> bfd.h.new
+ echo "#endif" >> bfd.h.new
+ echo >> bfd.h.new
+ mv bfd.h.new $(BFD_H)
+
+ # and libbfd.h
+ sed < libbfd.h >libbfd.h.new -e '1,/THE FOLLOWING/!d'
+ cat doc/libbfd.protointernal doc/cache.protointernal doc/reloc.protointernal >> libbfd.h.new
+ echo >> libbfd.h.new
+ mv libbfd.h.new libbfd.h
+
+ # and libcoff.h
+ sed < $(srcdir)/libcoff.h >libcoff.h.new -e '1,/THE FOLLOWING/!d'
+ cat doc/coffcode.proto >>libcoff.h.new
+ mv libcoff.h.new $(srcdir)/libcoff.h
+
+
+texinfo:
+ makeinfo +no-validate bfd.texinfo
+
+texdoc:
+ tex bfd.texinfo
+ texindex bfd.??
+ tex bfd.texinfo
+
+quickdoc: $(DSRC) docs
+ tex bfd.texinfo
+
+
+
-/* BFD backend for generic a.out flavour 1 */
-
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Diddler.
along with BFD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
#include <ansidecl.h>
#include <sysdep.h>
struct external_exec;
#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)();
choose_reloc_size(abfd);
/* FIXME */
- N_SET_FLAGS (*execp, 0x81);
+ N_SET_FLAGS (*execp, 0x1);
WRITE_HEADERS(abfd, execp);
#define aout_64_core_file_failing_signal sunos4_core_file_failing_signal
#define aout_64_core_file_matches_executable_p sunos4_core_file_matches_executable_p
+#define aout_64_bfd_debug_info_start bfd_void
+#define aout_64_bfd_debug_info_end bfd_void
+#define aout_64_bfd_debug_info_accumulate bfd_void
+
+#define aout_32_bfd_debug_info_start bfd_void
+#define aout_32_bfd_debug_info_end bfd_void
+#define aout_32_bfd_debug_info_accumulate bfd_void
+
+
+
/* We implement these routines ourselves, rather than using the generic
a.out versions. */
#define aout_write_object_contents sunos4_write_object_contents
bfd_target VECNAME =
{
-TARGETNAME,
- bfd_target_aout_flavour_enum,
- true, /* target byte order */
- true, /* target headers byte order */
- (HAS_RELOC | EXEC_P | /* object flags */
- HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
- ' ', /* ar_pad_char */
- 16, /* ar_max_namelen */
- _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
- _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
-
- {_bfd_dummy_target, NAME(sunos,object_p),
- bfd_generic_archive_p, sunos4_core_file_p},
- {bfd_false, NAME(aout,mkobject),
- _bfd_generic_mkarchive, bfd_false},
- {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
- _bfd_write_archive_contents, bfd_false},
-
- JUMP_TABLE(JNAME(aout))
-};
+ TARGETNAME,
+ bfd_target_aout_flavour_enum,
+ true, /* target byte order */
+ true, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ 3, /* minimum alignment power */
+ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
+ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+
+ {_bfd_dummy_target, NAME(sunos,object_p),
+ bfd_generic_archive_p, sunos4_core_file_p},
+ {bfd_false, NAME(aout,mkobject),
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ JUMP_TABLE(JNAME(aout))
+ };
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+/*doc*
+@section a.out backends
+
+BFD supports a number of different flavours of a.out format, though
+the major differences are only the sizes of the structures on disk,
+and the shape of the relocation information.
+
+The support is split into a basic support file @code{aoutx.h} and
+other files which derive functions from the base. One derivation file
+is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
+functions support for sun3, sun4, 386 and 29k a.out files, to create a
+target jump vector for a specific target.
+
+This information is further split out into more specific files for each
+machine, including @code{sunos.c} - for sun3 and sun4 and
+@code{demo64} for a demonstration of a 64 bit a.out format.
+
+The base file @code{aoutx.h} defines general mechanisms for reading
+and writing records to and from disk, and various other methods which
+bfd requires. It is included by @code{aout32.c} and @code{aout64.c} to
+form the names aout_32_swap_exec_header_in,
+aout_64_swap_exec_header_in, etc.
+
+As an example, this is what goes on to make the back end for a sun4, from aout32.c
+
+@example
+ #define ARCH_SIZE 32
+ #include "aoutx.h"
+@end example
+
+Which exports names:
+@example
+ ...
+ aout_32_canonicalize_reloc
+ aout_32_find_nearest_line
+ aout_32_get_lineno
+ aout_32_get_reloc_upper_bound
+ ...
+@end example
+
+from sunos.c
+
+@example
+ #define ARCH 32
+ #define TARGET_NAME "a.out-sunos-big"
+ #define VECNAME sunos_big_vec
+ #include "aoutf1.h"
+@end example
+requires all the names from aout32.c, and produces the jump vector
+
+@example
+ sunos_big_vec
+@end example
+
+*/
+
#include <sysdep.h>
#include <ansidecl.h>
#include "bfd.h"
struct external_exec;
-#include "liba.out.h"
+#include "libaout.h"
#include "libbfd.h"
#include "aout64.h"
#include "stab.gnu.h"
void (*bfd_error_trap)();
-/*SUPPRESS558*/
-/*SUPPRESS529*/
+/*doc*
+@subsection relocations
+The file @code{aoutx.h} caters for both the @emph{standard} and
+@emph{extended} forms of a.out relocation records.
+The standard records are characterised by containing only an address,
+a symbol index and a type field. The extended records (used on 29ks
+and sparcs) also have a full integer for an addend.
+*/
#define CTOR_TABLE_RELOC_IDX 2
static reloc_howto_type howto_table_ext[] =
{
bfd_error_vector_type bfd_error_vector;
+
+/*doc*
+@subsection Internal Entry Points
+@code{aoutx.h} exports several routines for accessing the contents of
+an a.out file, which are gathered and exported in turn by various
+format specific files (eg sunos.c).
+*/
+
+/*doc*
+*i aout_<size>_swap_exec_header_in
+Swaps the information in an executable header taken from a raw byte stream memory image,
+into the internal exec_header structure.
+*; PROTO(void, aout_<size>_swap_exec_header_in,
+ (bfd *abfd,
+ struct external_exec *raw_bytes,
+ struct internal_exec *execp));
+*/
+
void
DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
bfd *abfd AND
execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
}
+/*doc*
+*i aout_<size>_swap_exec_header_out
+Swaps the information in an internal exec header structure into the
+supplied buffer ready for writing to disk.
+*; PROTO(void, aout_<size>_swap_exec_header_out,
+ (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *raw_bytes));
+*/
void
DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
bfd *abfd AND
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
- it really is. Call back to the calling environments "finish up"
- function just before returning, to handle any last-minute setup. */
+
+/*doc*
+*i aout_<size>_some_aout_object_p
+
+Some A.OUT variant thinks that the file whose format we're checking
+is an a.out file. Do some more checking, and set up for access if
+it really is. Call back to the calling environments "finish up"
+function just before returning, to handle any last-minute setup.
+
+*; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
+ (bfd *abfd,
+ bfd_target *(*callback_to_real_object_p)()));
+*/
bfd_target *
DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p),
return (*callback_to_real_object_p)(abfd);
}
+/*doc*
+*i aout_<size>_mkobject
+
+This routine initializes a bfd for use with a.out files.
+
+*; PROTO(boolean, aout_<size>_mkobject, (bfd *));
+*/
boolean
DEFUN(NAME(aout,mkobject),(abfd),
return true;
}
-/* Keep track of machine architecture and machine type for a.out's.
+
+/*doc*
+*i aout_<size>_machine_type
+
+Keep track of machine architecture and machine type for a.out's.
Return the machine_type for a particular arch&machine, or M_UNKNOWN
if that exact arch&machine can't be represented in a.out format.
If the architecture is understood, machine type 0 (default) should
-always be understood. */
+always be understood.
+
+*; PROTO(enum machine_type, aout_<size>_machine_type,
+ (enum bfd_architecture arch,
+ unsigned long machine));
+*/
enum machine_type
DEFUN(NAME(aout,machine_type),(arch, machine),
return arch_flags;
}
+/*doc*
+*i aout_<size>_set_arch_mach
+
+Sets the architecture and the machine of the bfd to those values
+supplied. Verifies that the format can support the architecture
+required.
+
+*; PROTO(boolean, aout_<size>_set_arch_mach,
+ (bfd *,
+ enum bfd_architecture,
+ unsigned long machine));
+*/
+
boolean
DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
bfd *abfd AND
return false; /* We can't represent this type */
return true; /* We're easy ... */
}
-\f
-/* exec and core file sections */
+/*doc*
+*i aout_<size>new_section_hook
+
+Called by the bfd in response to a @code{bfd_make_section} request.
+*; PROTO(boolean, aout_<size>_new_section_hook,
+ (bfd *abfd,
+ asection *newsect));
+*/
boolean
DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
bfd *abfd AND
buffer[sizeof(buffer)-1] = 0;
/* Have to remove : stuff */
p = strchr(buffer,':');
- if (p != NULL) {*p = NULL; }
+ if (p != NULL) { *p = NULL; }
*functionname_ptr = buffer;
return true;
-/*** archive.c -- an attempt at combining the machine-independent parts of
- archives */
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+/*doc*
+@setfilename archive-info
+@section Archives
+
+Gumby, you promised to write this bit...
+
+Archives are supported in bfd in @code{archive.c}.
+
+An archive is represented internally just like another bfd, with a
+pointer to a chain of contained bfds. Archives can be created by
+opening bfds, linking them together and attatching them as children to
+another bfd and then closing the parent bfd.
+
+*-*/
+
/* Assumes:
o - all archive elements start on an even boundary, newline padded;
o - all arch headers are char *;
return true;
}
+/*proto* bfd_get_next_mapent
+What this does
+*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
+*/
symindex
bfd_get_next_mapent (abfd, prev, entry)
bfd *abfd;
return nbfd;
}
+/*proto* bfd_set_archive_head
+Used whilst processing archives. Sets the head of the chain of bfds
+contained in an archive to @var{new_head}. (see chapter on archives)
+*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
+*/
+
boolean
-bfd_set_archive_head (output_archive, new_head)
- bfd *output_archive, *new_head;
+DEFUN(bfd_set_archive_head,(output_archive, new_head),
+ bfd *output_archive AND
+ bfd *new_head)
{
output_archive->archive_head = new_head;
return NULL;
}
- /* extract the filename from the archive */
- if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
+ /* extract the filename from the archive - there are two ways to
+ specify an extendend name table, either the first char of the
+ name is a space, or it's a slash */
+ if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
filename = get_extended_arelt_filename (abfd, hdr.ar_name);
if (filename == NULL) {
bfd_error = malformed_archive;
return result;
}
-/* If you've got an archive, call this to read each subfile. */
+/*proto* bfd_openr_next_archived_file
+Initially provided a bfd containing an archive and NULL, opens a bfd
+on the first contained element and returns that. Subsequent calls to
+bfd_openr_next_archived_file should pass the archive and the previous
+return value to return a created bfd to the next contained element.
+NULL is returned when there are no more.
+
+*; PROTO(bfd*, bfd_openr_next_archived_file,
+ (bfd *archive, bfd *previous));
+
+*/
+
bfd *
-bfd_openr_next_archived_file (archive, last_file)
- bfd *archive, *last_file;
+DEFUN(bfd_openr_next_archived_file,(archive, last_file),
+ bfd *archive AND
+ bfd*last_file)
{
if ((bfd_get_format (archive) != bfd_archive) ||
bfd_slurp_bsd_armap (abfd)
bfd *abfd;
{
- int i;
+
struct areltdata *mapdata;
char nextname[17];
unsigned int counter = 0;
goto byebye;
}
- ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef);
+ ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
ardata->cache = 0;
rbase = raw_armap+1;
ardata->symdefs = (carsym *) rbase;
for (;counter < ardata->symdef_count; counter++) {
struct symdef *sym = ((struct symdef *) rbase) + counter;
- sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
- sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
+ sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
+ sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
}
ardata->first_file_filepos = bfd_tell (abfd);
if (mapdata == NULL) return false;
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
- if (raw_armap == NULL) {
+
+ if (raw_armap == NULL)
+ {
bfd_error = no_memory;
byebye:
bfd_release (abfd, (PTR)mapdata);
return false;
}
+ /* read in the raw map */
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
mapdata->parsed_size) {
bfd_error = malformed_archive;
ardata->first_file_filepos = bfd_tell (abfd);
/* Pad to an even boundary if you have to */
ardata->first_file_filepos += (ardata->first_file_filepos) %2;
- bfd_release (abfd, (PTR)raw_armap);
- bfd_release (abfd, (PTR)mapdata);
+
+/* bfd_release (abfd, (PTR)raw_armap);
+ bfd_release (abfd, (PTR)mapdata);*/
bfd_has_map (abfd) = true;
return true;
}
\f
/** Extended name table.
- Normally archives support only 14-character filenames. Intel has extended
- the format: longer names are stored in a special element (the first in the
- archive, or second if there is an armap); the name in the ar_hdr is replaced
- by <space><index into filename element>. Index is the P.R. of an int (radix:
- 8). */
+ Normally archives support only 14-character filenames.
+
+ Intel has extended the format: longer names are stored in a special
+ element (the first in the archive, or second if there is an armap);
+ the name in the ar_hdr is replaced by <space><index into filename
+ element>. Index is the P.R. of an int (radix: 8). Data General have
+ extended the format by using the prefix // for the special element */
/* Returns false on error, true otherwise */
boolean
we probably don't want to return true. */
if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
- bfd_seek (abfd, -16L, SEEK_CUR);
+ bfd_seek (abfd, -16L, SEEK_CUR);
- if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
- bfd_ardata (abfd)->extended_names = NULL;
- return true;
- }
+ if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
+ strncmp (nextname, "// ", 16) != 0)
+ {
+ bfd_ardata (abfd)->extended_names = NULL;
+ return true;
+ }
- namedata = snarf_ar_hdr (abfd);
- if (namedata == NULL) return false;
+ namedata = snarf_ar_hdr (abfd);
+ if (namedata == NULL) return false;
- bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
- if (bfd_ardata (abfd)->extended_names == NULL) {
- bfd_error = no_memory;
- byebye:
- bfd_release (abfd, (PTR)namedata);
- return false;
- }
+ bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
+ if (bfd_ardata (abfd)->extended_names == NULL) {
+ bfd_error = no_memory;
+ byebye:
+ bfd_release (abfd, (PTR)namedata);
+ return false;
+ }
- if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
- namedata->parsed_size, abfd) != namedata->parsed_size) {
- bfd_error = malformed_archive;
- bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
- bfd_ardata (abfd)->extended_names = NULL;
- goto byebye;
- }
+ if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
+ namedata->parsed_size, abfd) != namedata->parsed_size) {
+ bfd_error = malformed_archive;
+ bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
+ bfd_ardata (abfd)->extended_names = NULL;
+ goto byebye;
+ }
- /* It appears that the extended names are newline-padded, not null padded.
- */
- {
- char *temp = bfd_ardata (abfd)->extended_names;
- for (; *temp != '\0'; ++temp)
- if (*temp == '\n') *temp = '\0';
- }
+ /* Since the archive is supposed to be printable if it contains
+ text, the entries in the list are newline-padded, not null
+ padded. We'll fix that there.. */
+ {
+ char *temp = bfd_ardata (abfd)->extended_names;
+ for (; *temp != '\0'; ++temp)
+ if (*temp == '\n') *temp = '\0';
+ }
- /* Pad to an even boundary if you have to */
- bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
- bfd_ardata (abfd)->first_file_filepos +=
- (bfd_ardata (abfd)->first_file_filepos) %2;
-
- /* FIXME, we can't release namedata here because it was allocated
- below extended_names on the obstack... */
- /* bfd_release (abfd, namedata); */
-}
+ /* Pad to an even boundary if you have to */
+ bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+ bfd_ardata (abfd)->first_file_filepos +=
+ (bfd_ardata (abfd)->first_file_filepos) %2;
+
+ /* FIXME, we can't release namedata here because it was allocated
+ below extended_names on the obstack... */
+ /* bfd_release (abfd, namedata); */
+ }
return true;
}
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
- bfd_h_put_32(arch, ranlibsize, &temp);
+ bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
bfd_write (&temp, 1, sizeof (temp), arch);
for (count = 0; count < orl_count; count++) {
} /* if new archive element */
last_elt = current;
- bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
- bfd_h_put_32(arch, firstreal, &outs.file_offset);
+ bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
+ bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
bfd_write ((char *)outp, 1, sizeof (outs), arch);
}
/* now write the strings themselves */
- bfd_h_put_32(arch, stridx, &temp);
+ bfd_h_put_32(arch, stridx, (PTR)&temp);
bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
for (count = 0; count < orl_count; count++)
bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
- /* -*- C -*- */
-
-/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
- Every definition in this file should be exported and declared
- in bfd.h. If you don't want it to be user-visible, put it in
- libbfd.c!
-*/
-
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Diddler.
along with BFD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
/* $Id$ */
+
+/*proto*
+@section typedef bfd
+
+Pointers to bfd structs are the cornerstone of any application using
+libbfd. References though the bfd and to data in the bfd give the
+entire bfd functionality.
+
+Finally! The BFD struct itself. This contains the major data about
+the file, and contains pointers to the rest of the data.
+
+*+++
+
+$struct _bfd
+${
+ The filename the application opened the bfd with.
+
+$ CONST char *filename;
+
+A pointer to the target jump table.
+
+$ struct bfd_target *xvec;
+
+
+To avoid dragging too many header files into every file that
+includes bfd.h, IOSTREAM has been declared as a "char *", and MTIME
+as a "long". Their correct types, to which they are cast when used,
+are "FILE *" and "time_t".
+
+The iostream is the result of an fopen on the filename.
+
+$ char *iostream;
+
+Is the file being cached @xref{File Caching}.
+
+$ boolean cacheable;
+
+Marks whether there was a default target specified when the bfd was
+opened. This is used to select what matching algorithm to use to chose
+the back end.
+
+$ boolean target_defaulted;
+
+The caching routines use these to maintain an LRU list of bfds.
+
+$ struct _bfd *lru_prev, *lru_next;
+
+When a file is closed by the caching routines, it retains the state
+here:
+
+$ file_ptr where;
+
+and here:
+
+$ boolean opened_once;
+
+$ boolean mtime_set;
+File modified time
+
+$ long mtime;
+
+For output files, channel we locked (is this used?).
+
+$int ifd;
+
+The format which belongs to the bfd.
+
+$ bfd_format format;
+
+The direction the bfd was opened with
+
+$ enum bfd_direction {no_direction = 0,
+$ read_direction = 1,
+$ write_direction = 2,
+$ both_direction = 3} direction;
+
+Format_specific flags
+
+$ flagword flags;
+
+Currently my_archive is tested before adding origin to anything. I
+believe that this can become always an add of origin, with origin set
+to 0 for non archive files.
+
+$ file_ptr origin;
+
+Remember when output has begun, to stop strange things happening.
+
+$ boolean output_has_begun;
+
+Pointer to linked list of sections
+
+$ struct sec *sections;
+
+The number of sections
+
+$ unsigned int section_count;
+
+Stuff only usefull for object files:
+The start address.
+
+$ bfd_vma start_address;
+Used for input and output
+
+$ unsigned int symcount;
+Symtab for output bfd
+
+$ struct symbol_cache_entry **outsymbols;
+
+Architecture of object machine, eg m68k
+
+$ enum bfd_architecture obj_arch;
+
+Particular machine within arch, e.g. 68010
+
+$ unsigned long obj_machine;
+
+Stuff only usefull for archives:
+
+$ PTR arelt_data;
+$ struct _bfd *my_archive;
+$ struct _bfd *next;
+$ struct _bfd *archive_head;
+$ boolean has_armap;
+
+Used by the back end to hold private data.
+
+$ PTR tdata;
+
+Used by the application to hold private data
+
+$ PTR usrdata;
+
+Where all the allocated stuff under this BFD goes
+
+$ struct obstack memory;
+$};
+
+*---
+
+*/
#include <sysdep.h>
#include "bfd.h"
#include "libbfd.h"
+
short _bfd_host_big_endian = 0x0100;
- /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
- return 1 if the host is big-endian, 0 otherwise.
- (assuming that a short is two bytes long!!! FIXME)
- (See HOST_IS_BIG_ENDIAN_P in bfd.h.) */
+ /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
+ return 1 if the host is big-endian, 0 otherwise.
+ (assuming that a short is two bytes long!!! FIXME)
+ (See HOST_IS_BIG_ENDIAN_P in bfd.h.) */
\f
/** Error handling
o - Most functions return nonzero on success (check doc for
- precise semantics); 0 or NULL on error.
+ precise semantics); 0 or NULL on error.
o - Internal errors are documented by the value of bfd_error.
- If that is system_call_error then check errno.
+ If that is system_call_error then check errno.
o - The easiest way to report this to the user is to use bfd_perror.
*/
bfd_ec bfd_error = no_error;
-char *bfd_errmsgs[] = { "No error",
- "System call error",
- "Invalid target",
- "File in wrong format",
- "Invalid operation",
- "Memory exhausted",
- "No symbols",
- "No relocation info",
- "No more archived files",
- "Malformed archive",
- "Symbol not found",
- "File format not recognized",
- "File format is ambiguous",
- "Section has no contents",
- "Nonrepresentable section on output",
- "#<Invalid error code>"
- };
+char *bfd_errmsgs[] = { "No error",
+ "System call error",
+ "Invalid target",
+ "File in wrong format",
+ "Invalid operation",
+ "Memory exhausted",
+ "No symbols",
+ "No relocation info",
+ "No more archived files",
+ "Malformed archive",
+ "Symbol not found",
+ "File format not recognized",
+ "File format is ambiguous",
+ "Section has no contents",
+ "Nonrepresentable section on output",
+ "#<Invalid error code>"
+ };
static
void
DEFUN(bfd_nonrepresentable_section,(abfd, name),
- CONST bfd * CONST abfd AND
- CONST char * CONST name)
+ CONST bfd * CONST abfd AND
+ CONST char * CONST name)
{
printf("bfd error writing file %s, format %s can't represent section %s\n",
- abfd->filename,
- abfd->xvec->name,
- name);
+ abfd->filename,
+ abfd->xvec->name,
+ name);
exit(1);
}
extern char *sys_errlist[];
return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" :
- sys_errlist [code]);
+ sys_errlist [code]);
}
#endif /* not ANSI_LIBRARIES */
CONST char *message)
{
if (bfd_error == system_call_error)
- perror((char *)message); /* must be system error then... */
+ perror((char *)message); /* must be system error then... */
else {
if (message == NULL || *message == '\0')
fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
}
}
-/* 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";
- }
-}
-\f
-/** 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;
-}
-\f
-/* 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)));
- }
-}
-
-\f
-/** 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));
-}
-\f
+ \f
/** Symbols */
-boolean
-bfd_set_symtab (abfd, location, symcount)
- bfd *abfd;
- asymbol **location;
- unsigned int symcount;
-{
- if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
- bfd_error = invalid_operation;
- return false;
- }
-
- bfd_get_outsymbols (abfd) = location;
- bfd_get_symcount (abfd) = symcount;
- return true;
-}
-
/* returns the number of octets of storage required */
+
unsigned int
get_reloc_upper_bound (abfd, asect)
bfd *abfd;
return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
}
-void
-bfd_print_symbol_vandf(file, symbol)
-PTR file;
-asymbol *symbol;
-{
- flagword type = symbol->flags;
- if (symbol->section != (asection *)NULL)
- {
-
- fprintf_vma(file, symbol->value+symbol->section->vma);
- }
- else
- {
- fprintf_vma(file, symbol->value);
- }
- fprintf(file," %c%c%c%c%c%c%c",
- (type & BSF_LOCAL) ? 'l':' ',
- (type & BSF_GLOBAL) ? 'g' : ' ',
- (type & BSF_IMPORT) ? 'i' : ' ',
- (type & BSF_EXPORT) ? 'e' : ' ',
- (type & BSF_UNDEFINED) ? 'u' : ' ',
- (type & BSF_FORT_COMM) ? 'c' : ' ',
- (type & BSF_DEBUGGING) ? 'd' :' ');
-
-}
-
boolean
bfd_set_file_flags (abfd, flags)
asect->orelocation = location;
asect->reloc_count = count;
}
-/*
-If an output_bfd is supplied to this function the generated image
-will be relocatable, the relocations are copied to the output file
-after they have been changed to reflect the new state of the world.
-There are two ways of reflecting the results of partial linkage in an
-output file; by modifying the output data in place, and by modifying
-the relocation record. Some native formats (eg basic a.out and basic
-coff) have no way of specifying an addend in the relocation type, so
-the addend has to go in the output data. This is no big deal since in
-these formats the output data slot will always be big enough for the
-addend. Complex reloc types with addends were invented to solve just
-this problem.
-*/
-
-bfd_reloc_status_enum_type
-DEFUN(bfd_perform_relocation,(abfd,
- reloc_entry,
- data,
- input_section,
- output_bfd),
- bfd *abfd AND
- arelent *reloc_entry AND
- PTR data AND
- asection *input_section AND
- bfd *output_bfd)
-{
- bfd_vma relocation;
- bfd_reloc_status_enum_type flag = bfd_reloc_ok;
- bfd_vma addr = reloc_entry->address ;
- bfd_vma output_base = 0;
- reloc_howto_type *howto = reloc_entry->howto;
- asection *reloc_target_output_section;
- asection *reloc_target_input_section;
- asymbol *symbol;
-
- if (reloc_entry->sym_ptr_ptr) {
- symbol = *( reloc_entry->sym_ptr_ptr);
- if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
- flag = bfd_reloc_undefined;
- }
- }
- else {
- symbol = (asymbol*)NULL;
- }
-
- if (howto->special_function){
- bfd_reloc_status_enum_type cont;
- cont = howto->special_function(abfd,
- reloc_entry,
- symbol,
- data,
- input_section);
- if (cont != bfd_reloc_continue) return cont;
- }
-
- /*
- Work out which section the relocation is targetted at and the
- initial relocation command value.
- */
-
-
- if (symbol != (asymbol *)NULL){
- if (symbol->flags & BSF_FORT_COMM) {
- relocation = 0;
- }
- else {
- relocation = symbol->value;
- }
- if (symbol->section != (asection *)NULL)
- {
- reloc_target_input_section = symbol->section;
- }
- else {
- reloc_target_input_section = (asection *)NULL;
- }
- }
- else if (reloc_entry->section != (asection *)NULL)
- {
- relocation = 0;
- reloc_target_input_section = reloc_entry->section;
- }
- else {
- relocation = 0;
- reloc_target_input_section = (asection *)NULL;
- }
-
-
- if (reloc_target_input_section != (asection *)NULL) {
-
- reloc_target_output_section =
- reloc_target_input_section->output_section;
-
- if (output_bfd && howto->partial_inplace==false) {
- output_base = 0;
- }
- else {
- output_base = reloc_target_output_section->vma;
-
- }
-
- relocation += output_base + reloc_target_input_section->output_offset;
- }
-
- relocation += reloc_entry->addend ;
-
-
- if(reloc_entry->address > (bfd_vma)(input_section->size))
- {
- return bfd_reloc_outofrange;
- }
-
-
- if (howto->pc_relative == true)
- {
- /*
- Anything which started out as pc relative should end up that
- way too.
-
- There are two ways we can see a pcrel instruction. Sometimes
- the pcrel displacement has been partially calculated, it
- includes the distance from the start of the section to the
- instruction in it (eg sun3), and sometimes the field is
- totally blank - eg m88kbcs.
- */
-
-
- relocation -=
- output_base + input_section->output_offset;
-
- if (howto->pcrel_offset == true) {
- relocation -= reloc_entry->address;
- }
-
- }
-
- if (output_bfd!= (bfd *)NULL) {
- if ( howto->partial_inplace == false) {
- /*
- This is a partial relocation, and we want to apply the relocation
- to the reloc entry rather than the raw data. Modify the reloc
- inplace to reflect what we now know.
- */
- reloc_entry->addend = relocation ;
- reloc_entry->section = reloc_target_input_section;
- if (reloc_target_input_section != (asection *)NULL) {
- /* If we know the output section we can forget the symbol */
- reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
- }
- reloc_entry->address +=
- input_section->output_offset;
- return flag;
- }
- else
- {
- /* This is a partial relocation, but inplace, so modify the
- reloc record a bit
- */
-
- }
- }
-
- reloc_entry->addend = 0;
-
-
- /*
- Either we are relocating all the way, or we don't want to apply
- the relocation to the reloc entry (probably because there isn't
- any room in the output format to describe addends to relocs)
- */
- relocation >>= howto->rightshift;
-
- /* Shift everything up to where it's going to be used */
-
- relocation <<= howto->bitpos;
-
- /* Wait for the day when all have the mask in them */
-
- /* What we do:
- i instruction to be left alone
- o offset within instruction
- r relocation offset to apply
- S src mask
- D dst mask
- N ~dst mask
- A part 1
- B part 2
- R result
-
- Do this:
- i i i i i o o o o o from bfd_get<size>
- and S S S S S to get the size offset we want
- + r r r r r r r r r r to get the final value to place
- and D D D D D to chop to right size
- -----------------------
- A A A A A
- And this:
- ... i i i i i o o o o o from bfd_get<size>
- and N N N N N get instruction
- -----------------------
- ... B B B B B
-
- And then:
- B B B B B
- or A A A A A
- -----------------------
- R R R R R R R R R R put into bfd_put<size>
- */
-
-#define DOIT(x) \
- x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
-
- switch (howto->size)
- {
- case 0:
- {
- char x = bfd_get_8(abfd, (char *)data + addr);
- DOIT(x);
- bfd_put_8(abfd,x, (unsigned char *) data + addr);
- }
- break;
-
- case 1:
- {
- short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
- DOIT(x);
- bfd_put_16(abfd, x, (unsigned char *)data + addr);
- }
- break;
- case 2:
- {
- long x = bfd_get_32(abfd, (bfd_byte *) data + addr);
- DOIT(x);
- bfd_put_32(abfd,x, (bfd_byte *)data + addr);
- }
- break;
- case 3:
- /* Do nothing */
- break;
- default:
- return bfd_reloc_other;
- }
-
- return flag;
-}
void
bfd_assert(file, line)
}
+/*proto* bfd_set_start_address
+
+Marks the entry point of an output bfd. Returns @code{true} on
+success, @code{false} otherwise.
+
+*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma));
+*/
+
boolean
bfd_set_start_address(abfd, vma)
bfd *abfd;
}
-bfd_vma bfd_log2(x)
-bfd_vma x;
-{
- bfd_vma result = 0;
- while ( (bfd_vma)(1<< result) < x)
- result++;
- return result;
-}
+/*proto* bfd_get_mtime
+
+Return cached file modification time (e.g. as read from archive header
+for archive members, or from file system if we have been called
+before); else determine modify time, cache it, and return it.
-/* bfd_get_mtime: Return cached file modification time (e.g. as read
- from archive header for archive members, or from file system if we have
- been called before); else determine modify time, cache it, and
- return it. */
+*;PROTO(long, bfd_get_mtime, (bfd *));
+
+*/
long
bfd_get_mtime (abfd)
abfd->mtime = buf.st_mtime;
return abfd->mtime;
}
+
+/*proto*
+*i stuff
+*+
+#define bfd_sizeof_headers(abfd, reloc) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, section, symbols, offset, filename_ptr, func, line_ptr))
+
+#define bfd_debug_info_start(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+ BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+ BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+*-
+
+*/
+
+
+
+
+
+
This file is part of BFD, the Binary File Diddler.
BFD is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 1, or (at your option) any later version.
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 1, or (at your option) any later version.
BFD is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
You should have received a copy of the GNU General Public License along with
- BFD; see the file COPYING. If not, write to the Free Software Foundation,
- 675 Mass Ave, Cambridge, MA 02139, USA.
+BFD; see the file COPYING. If not, write to the Free Software Foundation,
+675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*doc*
+@section coff backends
+
+BFD supports a number of different flavours of coff format. The major
+difference between formats are the sizes and alignments of fields in
+structures on disk, and the occasional extra field.
+
+Coff in all its varieties is implimented with a few common files and a
+number of implementation specific files. For example, The 88k bcs coff
+format is implemented in the file @code{m88k-bcs.c}. This file
+@code{#include}s @code{m88k-bcs.h} which defines the external
+structure of the coff format for the 88k, and @code{internalcoff.h}
+which defines the internal structure. @code{m88k-bcs.c} also defines
+the relocations used by the 88k format @xref{Relocations}. Then the
+major portion of coff code is included (@code{coffcode.h}) which
+defines the methods used to act upon the types defined in
+@code{m88k-bcs.h} and @code{internalcoff.h}.
+
+The Intel i960 processor version of coff is implemented in
+@code{icoff.c}. This file has the same structure as
+@code{m88k-bcs.c}, except that it includes @code{intel-coff.h} rather
+than @code{m88k-bcs.h}.
+
+@subsection Porting To A New Version of Coff
+
+The recommended method is to select from the existing implimentations
+the version of coff which is most like the one you want to use, for
+our purposes, we'll say that i386 coff is the one you select, and that
+your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
+copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
+add the lines to @code{targets.c} and @code{Makefile.in} so that your
+new back end is used.
+
+Alter the shapes of the structures in @code{../include/foocoff.h} so
+that they match what you need. You will probably also have to add
+@code{#ifdef}s to the code in @code{internalcoff.h} and
+@code{coffcode.h} if your version of coff is too wild.
+
+You can verify that your new bfd backend works quite simply by
+building @code{objdump} from the @code{binutils} directory, and
+making sure that its version of what's going on at your host systems
+idea (assuming it has the pretty standard coff dump utility (usually
+called @code{att-dump} or just @code{dump})) are the same.
+
+Then clean up your code, and send what you've done to Cygnus. Then your stuff
+will be in the next release, and you won't have to keep integrating
+it.
+
+@subsection How The Coff Backend Works
+
+@subsubsection Bit Twiddling
+Each flavour of coff supported in bfd has its own header file
+descibing the external layout of the structures. There is also an
+internal description of the coff layout (in @code{internalcoff.h})
+file (@code{}). A major function of the coff backend is swapping the
+bytes and twiddling the bits to translate the external form of the
+structures into the normal internal form. This is all performed in the
+@code{bfd_swap}_@i{thing}_@i{direction} routines. Some elements are
+different sizes between different versions of coff, it is the duty of
+the coff version specific include file to override the definitions of
+various packing routines in @code{coffcode.h}. Eg the size of line
+number entry in coff is sometimes 16 bits, and sometimes 32 bits.
+@code{#define}ing @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will
+select the correct one. No doubt, some day someone will find a version
+of coff which has a varying field size not catered for at the moment.
+To port bfd, that person will have to add more @code{#defines}.
+
+Three of the bit twiddling routines are exported to @code{gdb};
+@code{coff_swap_aux_in}, @code{coff_swap_sym_in} and
+@code{coff_swap_linno_in}. @code{GDB} reads the symbol table on its
+own, but uses bfd to fix things up.
+
+@subsubsection Symbol Reading
+The simple canonical form for symbols used by bfd is not rich enough
+to keep all the information available in a coff symbol table. The back
+end gets around this by keeping the original symbol table around,
+"behind the sceens".
+
+When a symbol table is requested (through a call to
+@code{bfd_canonicalize_symtab}, a request gets through to
+@code{get_normalized_symtab}. This reads the symbol table from the
+coff file and swaps all the structures inside into the internal form.
+It also fixes up all the pointers in the table (represented in the file
+by offsets from the first symbol in the table) into physical pointers
+to elements in the new internal table. This involves some work since
+the meanings of fields changes depending upon context; a field that is a
+pointer to another structure in the symbol table at one moment may be
+the size in bytes of a structure in the next.
+
+Another pass is made over the table. All symbols which mark file names
+(@code{C_FILE} symbols) are modified so that the internal string
+points to the value in the auxent (the real filename) rather than the
+normal text associated with the symbol (@code{".file"}).
+
+At this time the symbol names are moved around. Coff stores all
+symbols less than nine characters long physically within the symbol
+table, longer strings are kept at the end of the file in the string
+table. This pass moves all strings into memory, and replaces them with
+pointers to the strings.
+
+The symbol table is massaged once again, this time to create the
+canonical table used by the bfd application. Each symbol is inspected
+in turn, and a decision made (using the @code{sclass} field) about the
+various flags to set in the @code{asymbol} @xref{Symbols}. The
+generated canonical table shares strings with the hidden internal
+symbol table.
+
+Any linenumbers are read from the coff file too, and attatched to the
+symbols which own the functions the linenumbers belong to.
+
+@subsubsection Symbol Writing
+Writing a symbol to a coff file which didn't come from a coff file
+will lose any debugging information. The @code{asymbol} structure
+remembers the bfd from which was born, and on output the back end
+makes sure that the same destination target as source target is
+present.
+
+When the symbols have come from a coff file then all the debugging
+information is preserved.
+
+Symbol tables are provided for writing to the back end in a vector of
+pointers to pointers. This allows applications like the linker to
+accumulate and output large symbol tables without having to do too
+much byte copying.
+
+The symbol table is not output to a writable bfd until it is closed.
+The order of operations on the canonical symbol table at that point
+are:
+@table @code
+@item coff_renumber_symbols
+This function runs through the provided symbol table and patches each
+symbol marked as a file place holder (@code{C_FILE}) to point to the
+next file place holder in the list. It also marks each @code{offset}
+field in the list with the offset from the first symbol of the current
+symbol.
+
+Another function of this procedure is to turn the canonical value form
+of bfd into the form used by coff. Internally, bfd expects symbol
+values to be offsets from a section base; so a symbol physically at
+0x120, but in a section starting at 0x100, would have the value 0x20.
+Coff expects symbols to contain their final value, so symbols have
+their values changed at this point to reflect their sum with their
+owning section. Note that this transformation uses the
+@code{output_section} field of the @code{asymbol}'s @code{asection}
+@xref{Sections}.
+@item coff_mangle_symbols
+This routine runs though the provided symbol table and uses the
+offsets generated by the previous pass and the pointers generated when
+the symbol table was read in to create the structured hierachy
+required by coff. It changes each pointer to a symbol to an index into
+the symbol table of the symbol being referenced.
+@item coff_write_symbols
+This routine runs through the symbol table and patches up the symbols
+from their internal form into the coff way, calls the bit twiddlers
+and writes out the tabel to the file.
+@end table
+*/
+
+/*proto*
+
+The hidden information for an asymbol is:
+
+*+++
+
+$ typedef struct coff_ptr_struct
+$ {
+
+Remembers the offset from the first symbol in the file for this
+symbol. Generated by @code{coff_renumber_symbols}.
+
+$ unsigned int offset;
+
+Should the tag field of this symbol be renumbered.
+Created by @code{coff_pointerize_aux}.
+
+$ char fix_tag;
+
+Should the endidx field of this symbol be renumbered.
+Created by @code{coff_pointerize_aux}.
+
+$ char fix_end;
+
+The container for the symbol structure as read and translated from the file.
+
+$ union {
+$ union internal_auxent auxent;
+$ struct internal_syment syment;
+$ } u;
+$ } combined_entry_type;
+$
+
+*---
+
+Each canonical asymbol really looks like this:
+
+*+++
+
+$ typedef struct coff_symbol_struct
+$ {
+
+The actual symbol which the rest of bfd works with
+
+$ asymbol symbol;
+
+A pointer to the hidden information for this symbol
+
+$ combined_entry_type *native;
+
+A pointer to the linenumber information for this symbol
+
+$ struct lineno_cache_entry *lineno;
+$ } coff_symbol_type;
+
+*---
+
*/
/* $Id$ */
#include "archures.h" /* Machine architectures and types */
-/* SUPPRESS 558 */
-/* SUPPRESS 590 */
-/* SUPPRESS 529 */
-/* SUPPRESS 530 */
-
/* Align an address upward to a boundary, expressed as a number of bytes.
E.g. align to an 8-byte boundary with argument of 8. */
#define ALIGN(this, boundary) \
#define i960_align(addr, align) \
( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
-#define sp(x) bfd_h_put_x(abfd, x, &x)
#define PUTWORD bfd_h_put_32
#define PUTHALF bfd_h_put_16
-#ifndef I960
-#define GDB_EXPORT static
-#else
-#define GDB_EXPORT /* nothing */
+
+#ifndef GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN
+#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN
+#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in,ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, ext->x_scn.x_nlinno)
#endif
-PROTO(static void,force_indices_file_symbol_relative,(bfd *abfd,
- struct internal_syment *symtab));
\f
/* void warning(); */
-extern asection abs_section;
+
static int
DEFUN(get_index,(symbol),
}
-
-
-
-/* All the swapping routines:
+/* **********************************************************************
+Here are all the routines for swapping the structures seen in the
+outside world into the internal forms.
*/
filehdr_dst->f_flags = bfd_h_get_16(abfd,filehdr_src-> f_flags);
}
-GDB_EXPORT void
+static void
DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out),
bfd *abfd AND
struct internal_filehdr *filehdr_in AND
static void
-DEFUN(coff_swap_sym_in,(abfd, ext, in),
+DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
bfd *abfd AND
- SYMENT *ext AND
- struct internal_syment *in)
+ PTR ext1 AND
+ PTR in1)
{
+ SYMENT *ext = (SYMENT *)ext1;
+ struct internal_syment *in = (struct internal_syment *)in1;
+
if( ext->e.e_name[0] == 0) {
in->_n._n_n._n_zeroes = 0;
in->_n._n_n._n_offset = bfd_h_get_32(abfd, ext->e.e.e_offset);
in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
}
-GDB_EXPORT void
+static void
DEFUN(coff_swap_sym_out,(abfd,in, ext),
bfd *abfd AND
struct internal_syment *in AND
}
static void
-DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in),
+DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
bfd *abfd AND
- AUXENT *ext AND
+ PTR ext1 AND
int type AND
int class AND
- union internal_auxent *in)
+ PTR in1)
{
+ AUXENT *ext = (AUXENT *)ext1;
+ union internal_auxent *in = (union internal_auxent *)in1;
switch (class) {
case C_FILE:
if (ext->x_file.x_fname[0] == 0) {
#endif
case C_HIDDEN:
if (type == T_NULL) {
- in->x_scn.x_scnlen = bfd_h_get_32(abfd, ext->x_scn.x_scnlen);
- in->x_scn.x_nreloc = bfd_h_get_16(abfd, ext->x_scn.x_nreloc);
- in->x_scn.x_nlinno = bfd_h_get_16(abfd, ext->x_scn.x_nlinno);
+ in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
+ in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
+ in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
break;
}
default:
- in->x_sym.x_tagndx = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
+ in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
in->x_sym.x_tvndx = bfd_h_get_16(abfd, ext->x_sym.x_tvndx);
+#endif
if (ISARY(type) || class == C_BLOCK) {
in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
}
- else {
- in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
- in->x_sym.x_fcnary.x_fcn.x_endndx = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
- }
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
+
if (ISFCN(type)) {
in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, ext->x_sym.x_misc.x_fsize);
}
else {
- in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
- in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size);
+ in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
+ in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
}
}
}
-GDB_EXPORT void
+static void
DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext),
bfd *abfd AND
union internal_auxent *in AND
PUTWORD(abfd, 0, ext->x_file.x_n.x_zeroes );
PUTWORD(abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
}
-
+ else {
+ memcpy ( ext->x_file.x_fname,in->x_file.x_fname,
+ sizeof (in->x_file.x_fname));
+ }
break;
case C_STAT:
#ifdef C_LEAFSTAT
#endif
case C_HIDDEN:
if (type == T_NULL) {
- PUTWORD(abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
- PUTWORD(abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
- PUTWORD(abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
+
+ PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
+ PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
+ PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
break;
}
default:
- PUTWORD(abfd, in->x_sym.x_tagndx, ext->x_sym.x_tagndx);
+ PUTWORD(abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
PUTWORD(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx);
+#endif
- if (ISARY(type) || class == C_BLOCK) {
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
- }
- else {
- PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
- PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx, ext->x_sym.x_fcnary.x_fcn.x_endndx);
- }
if (ISFCN(type)) {
- PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
+ PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
}
else {
- bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_misc.x_lnsz.x_lnno);
- bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext->x_sym.x_misc.x_lnsz.x_size);
+
+ if (ISARY(type) || class == C_BLOCK) {
+ bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+
+ }
+ PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+ PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+
+
}
}
}
-GDB_EXPORT void
-DEFUN(coff_swap_lineno_in,(abfd, ext, in),
+static void
+DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
bfd *abfd AND
- LINENO *ext AND
- struct internal_lineno *in)
+ PTR ext1 AND
+ PTR in1)
{
- in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx);
- in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno);
+ LINENO *ext = (LINENO *)ext1;
+ struct internal_lineno *in = (struct internal_lineno *)in1;
+
+ in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx);
+#if defined(M88)
+ in->l_lnno = bfd_h_get_32(abfd, ext->l_lnno);
+#else
+ in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno);
+#endif
}
-GDB_EXPORT void
+static void
DEFUN(coff_swap_lineno_out,(abfd, in, ext),
bfd *abfd AND
struct internal_lineno *in AND
struct external_lineno *ext)
{
PUTWORD(abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
+#if defined(M88)
+ PUTWORD(abfd, in->l_lnno, ext->l_lnno);
+#else
PUTHALF(abfd, in->l_lnno, ext->l_lnno);
+#endif
}
-GDB_EXPORT void
-DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int),
+static void
+DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
bfd *abfd AND
- AOUTHDR *aouthdr_ext AND
- struct internal_aouthdr *aouthdr_int)
+ PTR aouthdr_ext1 AND
+ PTR aouthdr_int1)
{
+ AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+ struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
+
aouthdr_int->magic = bfd_h_get_16(abfd, aouthdr_ext->magic);
aouthdr_int->vstamp = bfd_h_get_16(abfd, aouthdr_ext->vstamp);
aouthdr_int->tsize = bfd_h_get_32(abfd, aouthdr_ext->tsize);
#endif
}
-GDB_EXPORT void
+static void
DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out),
bfd *abfd AND
struct internal_aouthdr *aouthdr_in AND
#endif
}
-GDB_EXPORT void
+static void
DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
bfd *abfd AND
SCNHDR *scnhdr_ext AND
scnhdr_int->s_scnptr = bfd_h_get_32(abfd, scnhdr_ext->s_scnptr);
scnhdr_int->s_relptr = bfd_h_get_32(abfd, scnhdr_ext->s_relptr);
scnhdr_int->s_lnnoptr = bfd_h_get_32(abfd, scnhdr_ext->s_lnnoptr);
+ scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags);
+#if defined(M88)
+ scnhdr_int->s_nreloc = bfd_h_get_32(abfd, scnhdr_ext->s_nreloc);
+ scnhdr_int->s_nlnno = bfd_h_get_32(abfd, scnhdr_ext->s_nlnno);
+#else
scnhdr_int->s_nreloc = bfd_h_get_16(abfd, scnhdr_ext->s_nreloc);
scnhdr_int->s_nlnno = bfd_h_get_16(abfd, scnhdr_ext->s_nlnno);
- scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags);
+#endif
#ifdef I960
scnhdr_int->s_align = bfd_h_get_32(abfd, scnhdr_ext->s_align);
#endif
PUTWORD(abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
PUTWORD(abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
PUTWORD(abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
+#if defined(M88)
+ PUTWORD(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
+ PUTWORD(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
+#else
PUTHALF(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
PUTHALF(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
-#ifdef I960
+#endif
+
+#if defined(I960)
PUTWORD(abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
#endif
}
+
+/* **********************************************************************/
+/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
+ \0-terminated, but will not exceed 'maxlen' characters. The copy *will*
+ be \0-terminated.
+ */
+static char *
+DEFUN(copy_name,(abfd, name, maxlen),
+ bfd *abfd AND
+ char *name AND
+ int maxlen)
+{
+ int len;
+ char *newname;
+
+ for (len = 0; len < maxlen; ++len) {
+ if (name[len] == '\0') {
+ break;
+ }
+ }
+
+ if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
+ bfd_error = no_memory;
+ return (NULL);
+ }
+ strncpy(newname, name, len);
+ newname[len] = '\0';
+ return newname;
+}
+
/*
initialize a section structure with information peculiar to this
particular implementation of coff
bfd *abfd_ignore AND
asection *section_ignore)
{
-#ifdef MC88MAGIC
- /* FIXME, shouldn't this ifdef be on something that says we are
- actually COMPILING FOR an 88K coff file, rather than simply
- knowing its magic number? */
- /* Align to at least 16 bytes */
- section_ignore->alignment_power = 4;
-#endif
-#if M68
- section_ignore->alignment_power = 3;
-#endif
-#if I386
- section_ignore->alignment_power = 2;
-#endif
+ section_ignore->alignment_power = abfd_ignore->xvec->align_power_min;
return true;
}
struct internal_aouthdr *internal_a)
{
coff_data_type *coff;
-
+
size_t readsize; /* length of file_info */
SCNHDR *external_sections;
-
+
/* Build a play area */
if (coff_mkobject(abfd) != true)
return 0;
coff = coff_data(abfd);
-
-
+
+
external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
+
if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
goto fail;
}
-
-
-
+
+
/* Now copy data as required; construct all asections etc */
coff->symbol_index_slew = 0;
coff->relocbase =0;
static bfd_target *
DEFUN(coff_object_p,(abfd),
bfd *abfd)
- {
- int nscns;
- FILHDR filehdr;
- AOUTHDR opthdr;
- struct internal_filehdr internal_f;
- struct internal_aouthdr internal_a;
+{
+ int nscns;
+ FILHDR filehdr;
+ AOUTHDR opthdr;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
- bfd_error = system_call_error;
+ bfd_error = system_call_error;
- /* figure out how much to read */
- if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
- return 0;
+ /* figure out how much to read */
+ if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
+ return 0;
- bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
+ bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
- if (BADMAG(internal_f)) {
- bfd_error = wrong_format;
- return 0;
- }
- nscns =internal_f.f_nscns;
+ if (BADMAG(internal_f)) {
+ bfd_error = wrong_format;
+ return 0;
+ }
+ nscns =internal_f.f_nscns;
- if (internal_f.f_opthdr) {
- if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
- return 0;
- }
- bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
+ if (internal_f.f_opthdr) {
+ if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
+ return 0;
}
+ bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
+ }
- /* Seek past the opt hdr stuff */
- bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
+ /* Seek past the opt hdr stuff */
+ bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
- /* if the optional header is NULL or not the correct size then
- quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
- and Intel 960 readwrite headers (I960WRMAGIC) is that the
- optional header is of a different size.
-
- But the mips keeps extra stuff in it's opthdr, so dont check
- when doing that
- */
+ /* if the optional header is NULL or not the correct size then
+ quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
+ and Intel 960 readwrite headers (I960WRMAGIC) is that the
+ optional header is of a different size.
+
+ But the mips keeps extra stuff in it's opthdr, so dont check
+ when doing that
+ */
#ifndef MIPS
- if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
- return (bfd_target *)NULL;
+ if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
+ return (bfd_target *)NULL;
#endif
- return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
- }
+ return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
+}
DEFUN(coff_symbol_from,(abfd, symbol),
bfd *abfd AND
asymbol *symbol)
- {
- if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum)
- return (coff_symbol_type *)NULL;
+{
+ if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum)
+ return (coff_symbol_type *)NULL;
- if (symbol->the_bfd->tdata == (PTR)NULL)
- return (coff_symbol_type *)NULL;
+ if (symbol->the_bfd->tdata == (PTR)NULL)
+ return (coff_symbol_type *)NULL;
- return (coff_symbol_type *) symbol;
- }
+ return (coff_symbol_type *) symbol;
+}
static void
DEFUN(coff_count_linenumbers,(abfd),
bfd *abfd)
- {
- unsigned int limit = bfd_get_symcount(abfd);
- unsigned int i;
- asymbol **p;
- {
- asection *s = abfd->sections->output_section;
- while (s) {
- BFD_ASSERT(s->lineno_count == 0);
- s = s->next;
- }
+{
+ unsigned int limit = bfd_get_symcount(abfd);
+ unsigned int i;
+ asymbol **p;
+ {
+ asection *s = abfd->sections->output_section;
+ while (s) {
+ BFD_ASSERT(s->lineno_count == 0);
+ s = s->next;
}
+ }
- for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
- asymbol *q_maybe = *p;
- if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum) {
- coff_symbol_type *q = coffsymbol(q_maybe);
- if (q->lineno) {
- /*
- This symbol has a linenumber, increment the owning
- section's linenumber count
- */
- alent *l = q->lineno;
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
+ asymbol *q_maybe = *p;
+ if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum) {
+ coff_symbol_type *q = coffsymbol(q_maybe);
+ if (q->lineno) {
+ /*
+ This symbol has a linenumber, increment the owning
+ section's linenumber count
+ */
+ alent *l = q->lineno;
+ q->symbol.section->output_section->lineno_count++;
+ l++;
+ while (l->line_number) {
q->symbol.section->output_section->lineno_count++;
l++;
- while (l->line_number) {
- q->symbol.section->output_section->lineno_count++;
- l++;
- }
}
}
}
}
+}
-/*
-This function returns true if the supplied SYMENT has an AUXENT with
-a tagndx field which should be relocated.
-The coff book says that all auxents have this and should be moved,
-but all the actual implementations I've looked at do this ..
-(sac@cygnus.com)
-*/
-static boolean
-DEFUN(uses_x_sym_x_tagndx_p,(abfd, native),
- bfd *abfd AND
- struct internal_syment *native)
- {
- if (BTYPE(native->n_type) == T_STRUCT) return true;
- if (BTYPE(native->n_type) == T_UNION) return true;
- if (BTYPE(native->n_type) == T_ENUM) return true;
- return false;
- }
+static void
+DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
+coff_symbol_type *coff_symbol_ptr AND
+struct internal_syment *syment)
+{
+ /* Normalize the symbol flags */
+ if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
+ /* a common symbol is undefined with a value */
+ syment->n_scnum = N_UNDEF;
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
+ syment->n_scnum = N_UNDEF;
+ syment->n_value = 0;
+ }
+ else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
+ syment->n_scnum = N_ABS;
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ else {
+ syment->n_scnum =
+ coff_symbol_ptr->symbol.section->output_section->index+1;
+
+ syment->n_value =
+ coff_symbol_ptr->symbol.value +
+ coff_symbol_ptr->symbol.section->output_offset +
+ coff_symbol_ptr->symbol.section->output_section->vma;
+ }
+}
-/*
-This procedure runs through the native entries in a coff symbol table
-and links up all the elements which should point to one another, in
-particular these are:
+/* run through all the symbols in the symbol table and work out what
+ their indexes into the symbol table will be when output
-strtag, entag and untags have an auxent endindex which points to the
-first syment after the .eos. This is simple to do, we just keep a
-pointer to the symbol with the most recent pending strtag and patch it
-when we see the eos. This works since coff structs are never nested.
+ Coff requires that each C_FILE symbol points to the next one in the
+ chain, and that the last one points to the first external symbol. We
+ do that here too.
-ISFCN type entries have an endindex which points to the next static or
-extern in the table, thereby skipping the function contents.
-The coff book says that an ISFCN's tagindex
-points to the first .bf for the function, so far I havn't seen it
-used. We do this using the same mechanism as strtags.
+*/
+static void
+DEFUN(coff_renumber_symbols,(bfd_ptr),
+ bfd *bfd_ptr)
+{
+ unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
+ asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+ unsigned int native_index = 0;
+ struct internal_syment *last_file = (struct internal_syment *)NULL;
+ unsigned int symbol_index;
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ {
+ coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+ if (coff_symbol_ptr && coff_symbol_ptr->native) {
+ combined_entry_type *s = coff_symbol_ptr->native;
+ int i;
-Each file entry has a value which points to the next file entry,
-the last file entry points to the first extern symbol in the table
-which is not an ISFCN.
+ if (s->u.syment.n_sclass == C_FILE)
+ {
+ if (last_file != (struct internal_syment *)NULL) {
+ last_file->n_value = native_index;
+ }
+ last_file = &(s->u.syment);
+ }
+ else {
-Each .bb entry points to the matching .eb entry, but these are nested
-so we keep a stack of them.
+ /* Modify the symbol values according to their section and
+ type */
-The tagndx of .eos items points to the strtag attached to them, this
-is simply the last_tagndx again.
+ fixup_symbol_value(coff_symbol_ptr, &(s->u.syment));
+ }
+ for (i = 0; i < s->u.syment.n_numaux + 1; i++) {
+ s[i].offset = native_index ++;
+ }
+ }
+ else {
+ native_index++;
+ }
+ }
+}
-The tagndx of items with type strtag point to the defining struct.
-This bit is complicated; We know that a struct ref and def must be
-within the same file, so all the natives will be in the same vector.
-This means that we can subtracts two pointers and get the index
-differences between to items, used to work out the true index of the
-target.
-We store in the name field of each syment the actual native index
-applied so we can dig it out through a pointer. */
+/*doc*
+ Run thorough the symbol table again, and fix it so that all pointers to
+ entries are changed to the entries' index in the output symbol table.
+*/
static void
DEFUN(coff_mangle_symbols,(bfd_ptr),
bfd *bfd_ptr)
- {
+{
+ unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
+ asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+ unsigned int native_index = 0;
+ unsigned int symbol_index;
+
+
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ {
+ coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+ if (coff_symbol_ptr && coff_symbol_ptr->native ) {
+ int i;
+ combined_entry_type *s = coff_symbol_ptr->native;
+
+
+
+
+
+ for (i = 0; i < s->u.syment.n_numaux ; i++) {
+ combined_entry_type *a = s + i + 1;
+ if (a->fix_tag) {
+ a->u.auxent.x_sym.x_tagndx.l = a->u.auxent.x_sym.x_tagndx.p->offset;
+ }
+ if (a->fix_end) {
+ a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
+ a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
+ }
+
+ }
+ }
+ }
+}
+
+#if 0
unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
struct internal_syment *last_tagndx = (struct internal_syment *)NULL;
&& last_fcn != (struct internal_syment *)NULL)
{
union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
- auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index;
+ auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
last_fcn = (struct internal_syment *)NULL;
}
/* Remember that we keep the native index in the offset
so patch the beginning of the struct to point to this
*/
- auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;
- auxent->x_sym.x_fcnary.x_fcn.x_endndx = syment->n_numaux + 1 + native_index;
+/*if (last_
+ auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;*/
+ auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = syment->n_numaux + 1 + native_index;
/* Now point the eos to the structure */
auxent = (union internal_auxent *)(syment+1);
- auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;
+ auxent->x_sym.x_tagndx.l = last_tagndx->_n._n_n._n_offset;
}
else if (syment->n_sclass == C_BLOCK
&& coff_symbol_ptr->symbol.name[1] == 'e')
{
union internal_auxent *auxent = (union internal_auxent *)((*(--last_block))+1);
- auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index + syment->n_numaux + 1;
+ auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index + syment->n_numaux + 1;
}
if (syment->n_sclass == C_EXT
&& !ISFCN(syment->n_type)
union internal_auxent *auxent = (union internal_auxent *)(syment+1);
bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
struct internal_syment *base = obj_raw_syments(bfd_ptr);
- auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;
+/* auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
}
}
+#endif
+static int string_size;
+static void
+DEFUN(coff_fix_symbol_name,(abfd, symbol, native),
+ bfd *abfd AND
+ asymbol *symbol AND
+ combined_entry_type *native)
+{
+ unsigned int name_length;
+ union internal_auxent *auxent;
+CONST char * name = symbol->name;
+
+ if (name == (char *) NULL) {
+ /*
+ coff symbols always have names, so we'll make one up
+ */
+ name = symbol->name = "strange";
+ }
+ name_length = strlen(name);
+
+ if (native->u.syment.n_sclass == C_FILE) {
+ strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
+ auxent = &(native+1)->u.auxent;
+
+#ifdef COFF_LONG_FILENAMES
+ if (name_length <= FILNMLEN) {
+ strncpy(auxent->x_file.x_fname, name, FILNMLEN);
+ }
+ else {
+ auxent->x_file.x_n.x_offset = string_size + 4;
+ auxent->x_file.x_n.x_zeroes = 0;
+ string_size += name_length + 1;
+ }
+#else
+ strncpy(auxent->x_file.x_fname, name, FILNMLEN);
+ if (name_length > FILNMLEN) {
+ name[FILNMLEN] = '\0';
+ }
+#endif
+ }
+ else
+ { /* NOT A C_FILE SYMBOL */
+ if (name_length <= SYMNMLEN) {
+ /* This name will fit into the symbol neatly */
+ strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN);
+ }
+ else {
+ native->u.syment._n._n_n._n_offset = string_size + 4;
+ native->u.syment._n._n_n._n_zeroes = 0;
+ string_size += name_length + 1;
+ }
+ }
+}
+
+
+
+static unsigned int
+DEFUN(coff_write_symbol,(abfd, symbol, native, written),
+bfd *abfd AND
+asymbol *symbol AND
+combined_entry_type *native AND
+unsigned int written)
+{
+ unsigned int numaux = native->u.syment.n_numaux;
+ int type = native->u.syment.n_type;
+ int class = native->u.syment.n_sclass;
+ SYMENT buf;
+ unsigned int j;
+
+ coff_fix_symbol_name(abfd, symbol, native);
+ coff_swap_sym_out(abfd, &native->u.syment, &buf);
+ bfd_write((PTR)& buf, 1, SYMESZ, abfd);
+ for (j = 0; j != native->u.syment.n_numaux; j++)
+ {
+ AUXENT buf1;
+ coff_swap_aux_out(abfd,
+ &( (native + j + 1)->u.auxent), type, class, &buf1);
+ bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);
+ }
+ /*
+ Reuse somewhere in the symbol to keep the index
+ */
+ set_index(symbol, written);
+ return written + 1 + numaux;
+}
+
+
+static unsigned int
+DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
+ bfd *abfd AND
+ asymbol *symbol AND
+ unsigned int written)
+{
+ /*
+ This symbol has been created by the loader, or come from a non
+ coff format. It has no native element to inherit, make our
+ own
+ */
+ combined_entry_type *native;
+ combined_entry_type dummy;
+ native = &dummy;
+ native->u.syment.n_type = T_NULL;
+#ifdef I960
+ native->u.syment.n_flags = 0;
+#endif
+ if (symbol->flags & BSF_ABSOLUTE) {
+ native->u.syment.n_scnum = N_ABS;
+ native->u.syment.n_value = symbol->value;
+ }
+ else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
+ native->u.syment.n_scnum = N_UNDEF;
+ native->u.syment.n_value = symbol->value;
+ }
+ else if (symbol->flags & BSF_DEBUGGING) {
+ /*
+ remove name so it doesn't take up any space
+ */
+ symbol->name = "";
+ }
+ else {
+ native->u.syment.n_scnum = symbol->section->output_section->index +
+ 1;
+ native->u.syment.n_value = symbol->value +
+ symbol->section->output_section->vma +
+ symbol->section->output_offset;
+#ifdef I960
+ /* Copy the any flags from the the file hdr into the symbol */
+ {
+ coff_symbol_type *c = coff_symbol_from(abfd, symbol);
+ if (c != (coff_symbol_type *)NULL) {
+ native->u.syment.n_flags = c->symbol.the_bfd->flags;
+ }
+ }
+#endif
+ }
+
+#ifdef HASPAD1
+ native->u.syment.pad1[0] = 0;
+ native->u.syment.pad1[0] = 0;
+#endif
+
+ native->u.syment.n_type = 0;
+ if (symbol->flags & BSF_LOCAL)
+ native->u.syment.n_sclass = C_STAT;
+ else
+ native->u.syment.n_sclass = C_EXT;
+ native->u.syment.n_numaux = 0;
+
+ return coff_write_symbol(abfd, symbol, native, written);
+}
+
+static unsigned int
+DEFUN(coff_write_native_symbol,(abfd, symbol, written),
+bfd *abfd AND
+coff_symbol_type *symbol AND
+unsigned int written)
+{
+ /*
+ Does this symbol have an ascociated line number - if so then
+ make it remember this symbol index. Also tag the auxent of
+ this symbol to point to the right place in the lineno table
+ */
+ combined_entry_type *native = symbol->native;
+
+ alent *lineno = symbol->lineno;
+
+ if (lineno) {
+ unsigned int count = 0;
+ lineno[count].u.offset = written;
+ if (native->u.syment.n_numaux) {
+ union internal_auxent *a = &((native+1)->u.auxent);
+
+ a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ symbol->symbol.section->output_section->moving_line_filepos;
+ }
+ /*
+ And count and relocate all other linenumbers
+ */
+ count++;
+ while (lineno[count].line_number) {
+ lineno[count].u.offset +=
+ symbol->symbol.section->output_section->vma +
+ symbol->symbol.section->output_offset;
+ count++;
+ }
+ symbol->symbol.section->output_section->moving_line_filepos +=
+ count * LINESZ;
+
+ }
+ return coff_write_symbol(abfd, &( symbol->symbol), native,written);
+}
+
static void
DEFUN(coff_write_symbols,(abfd),
-bfd *abfd)
+ bfd *abfd)
{
unsigned int i;
unsigned int limit = bfd_get_symcount(abfd);
unsigned int written = 0;
- struct internal_syment dummy;
+
asymbol **p;
- unsigned int string_size = 0;
+
+ string_size = 0;
/* Seek to the right place */
/* Output all the symbols we have */
written = 0;
- for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
- asymbol *symbol = *p;
- coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
-
- unsigned int j;
- struct internal_syment *native;
- if (c_symbol == (coff_symbol_type *) NULL ||
- c_symbol->native == (struct internal_syment *) NULL) {
- /*
- This symbol has been created by the loader, or come from a non
- coff format. It has no native element to inherit, make our
- own
- */
-
- native = &dummy;
- native->n_type = T_NULL;
-#ifdef I960
- native->n_flags = 0;
-#endif
- if (symbol->flags & BSF_ABSOLUTE) {
- native->n_scnum = N_ABS;
- native->n_value = symbol->value;
- }
- else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
- native->n_scnum = N_UNDEF;
- native->n_value = symbol->value;
- }
- else if (symbol->flags & BSF_DEBUGGING) {
- /*
- remove name so it doesn't take up any space
- */
- symbol->name = "";
- continue;
- }
- else {
- native->n_scnum = symbol->section->output_section->index +
- 1;
- native->n_value = symbol->value +
- symbol->section->output_section->vma +
- symbol->section->output_offset;
-#ifdef I960
- /* Copy the any flags from the the file hdr into the symbol */
- {
- coff_symbol_type *c = coff_symbol_from(abfd, symbol);
- if (c != (coff_symbol_type *)NULL) {
- native->n_flags = c->symbol.the_bfd->flags;
- }
- }
-#endif
- }
-
-#ifdef HASPAD1
- native->pad1[0] = 0;
- native->pad1[0] = 0;
-#endif
-
- native->n_type = 0;
- if (symbol->flags & BSF_LOCAL)
- native->n_sclass = C_STAT;
- else
- native->n_sclass = C_EXT;
- native->n_numaux = 0;
- }
- else
- /*
- Does this symbol have an ascociated line number - if so then
- make it remember this symbol index. Also tag the auxent of
- this symbol to point to the right place in the lineno table
- */
- {
- alent *lineno = c_symbol->lineno;
- native = c_symbol->native;
- if (lineno) {
- unsigned int count = 0;
- lineno[count].u.offset = written;
- if (native->n_numaux) {
- union internal_auxent *a = (union internal_auxent *) (native + 1);
-
- a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
- c_symbol->symbol.section->output_section->moving_line_filepos;
- }
- /*
- And count and relocate all other linenumbers
- */
- count++;
- while (lineno[count].line_number) {
- lineno[count].u.offset +=
- c_symbol->symbol.section->output_section->vma +
- c_symbol->symbol.section->output_offset;
- count++;
- }
- c_symbol->symbol.section->output_section->moving_line_filepos +=
- count * LINESZ;
-
- }
- } /* if symbol new to coff */
-
- /* Fix the symbol names */
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
{
- unsigned int name_length;
- if (symbol->name == (char *) NULL) {
- /*
- coff symbols always have names, so we'll make one up
- */
- symbol->name = "strange";
- }
- name_length = strlen(symbol->name);
- if (name_length <= SYMNMLEN) {
- /* This name will fit into the symbol neatly */
- strncpy(native->_n._n_name, symbol->name, SYMNMLEN);
- }
- else {
- native->_n._n_n._n_offset = string_size + 4;
- native->_n._n_n._n_zeroes = 0;
- string_size += name_length + 1;
- }
- {
- unsigned int numaux = native->n_numaux;
- int type = native->n_type;
- int class = native->n_sclass;
- SYMENT buf;
- coff_swap_sym_out(abfd, native, &buf);
- bfd_write((PTR)& buf, 1, SYMESZ, abfd);
- for (j = 0; j != native->n_numaux;
- j++) {
- AUXENT buf1;
- coff_swap_aux_out(abfd,
- (union internal_auxent *)(native + j + 1), type, class, &buf1);
- bfd_write((PTR) (native + j + 1), 1, AUXESZ, abfd);
+ asymbol *symbol = *p;
+ coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
+
+
+
+ if (c_symbol == (coff_symbol_type *) NULL ||
+ c_symbol->native == (combined_entry_type *)NULL)
+ {
+ written = coff_write_alien_symbol(abfd, symbol, written);
}
- /*
- Reuse somewhere in the symbol to keep the index
- */
- set_index(symbol, written);
- written += 1 + numaux;
- }
+ else
+ {
+ written = coff_write_native_symbol(abfd, c_symbol, written);
+ }
+
}
- } /* for each out symbol */
-
+
bfd_get_symcount(abfd) = written;
+
/* Now write out strings */
- if (string_size) {
- unsigned int size = string_size + 4;
- size = size;
- bfd_write((PTR) &size, 1, sizeof(size), abfd);
- for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
- asymbol *q = *p;
- size_t name_length = strlen(q->name);
- if (name_length > SYMNMLEN) {
- bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
- }
- }
- }
+ if (string_size != 0)
+ {
+ unsigned int size = string_size + 4;
+ size = size;
+ bfd_write((PTR) &size, 1, sizeof(size), abfd);
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
+ {
+ asymbol *q = *p;
+ size_t name_length = strlen(q->name);
+ int maxlen;
+ coff_symbol_type* c_symbol = coff_symbol_from(abfd, q);
+ maxlen = ((c_symbol != NULL && c_symbol->native != NULL) && (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
+ FILNMLEN : SYMNMLEN;
+
+ if (name_length > maxlen) {
+ bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
+ }
+ }
+ }
else {
/* We would normally not write anything here, but we'll write
out 4 so that any stupid coff reader which tries to read
bfd_write((PTR)&size, 1, sizeof(size), abfd);
}
-
}
+/*doc*
+@subsubsection Writing Relocations
+To write a relocations, all the back end does is step though the
+canonical relocation table, and create an @code{internal_reloc}. The
+symbol index to use is removed from the @code{offset} field in the
+symbol table supplied, the address comes directly from the sum of the
+section base address and the relocation offset and the type is dug
+directly from the howto field.
+
+Then the @code{internal_reloc} is swapped into the shape of an
+@code{external_reloc} and written out to disk.
+*/
static void
-coff_write_relocs(abfd)
-bfd *abfd;
- {
- asection *s;
- for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
- unsigned int i;
- struct external_reloc dst;
+DEFUN(coff_write_relocs,(abfd),
+ bfd *abfd)
+{
+ asection *s;
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
+ unsigned int i;
+ struct external_reloc dst;
- arelent **p = s->orelocation;
- bfd_seek(abfd, s->rel_filepos, SEEK_SET);
- for (i = 0; i < s->reloc_count; i++) {
- struct internal_reloc n;
- arelent *q = p[i];
- memset((PTR)&n, 0, sizeof(n));
- n.r_vaddr = q->address + s->vma;
- if (q->sym_ptr_ptr) {
- n.r_symndx = get_index((*(q->sym_ptr_ptr)));
- }
+ arelent **p = s->orelocation;
+ bfd_seek(abfd, s->rel_filepos, SEEK_SET);
+ for (i = 0; i < s->reloc_count; i++) {
+ struct internal_reloc n;
+ arelent *q = p[i];
+ memset((PTR)&n, 0, sizeof(n));
+ n.r_vaddr = q->address + s->vma;
+ if (q->sym_ptr_ptr) {
+ n.r_symndx = get_index((*(q->sym_ptr_ptr)));
+ }
#ifdef SELECT_RELOC
- /* Work out reloc type from what is required */
- SELECT_RELOC(n.r_type, q->howto);
+ /* Work out reloc type from what is required */
+ SELECT_RELOC(n.r_type, q->howto);
#else
- n.r_type = q->howto->type;
+ n.r_type = q->howto->type;
#endif
- bfd_swap_reloc_out(abfd, &n, &dst);
- bfd_write((PTR) &n, 1, RELSZ, abfd);
- }
+ bfd_swap_reloc_out(abfd, &n, &dst);
+ bfd_write((PTR) &n, 1, RELSZ, abfd);
}
}
+}
static void
DEFUN(coff_write_linenumbers,(abfd),
bfd *abfd)
- {
- asection *s;
- for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
- if (s->lineno_count) {
- asymbol **q = abfd->outsymbols;
- bfd_seek(abfd, s->line_filepos, SEEK_SET);
- /* Find all the linenumbers in this section */
- while (*q) {
- asymbol *p = *q;
- alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
- if (l) {
- /* Found a linenumber entry, output */
- struct internal_lineno out;
- LINENO buff;
- bzero( (PTR)&out, sizeof(out));
- out.l_lnno = 0;
+{
+ asection *s;
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
+ if (s->lineno_count) {
+ asymbol **q = abfd->outsymbols;
+ bfd_seek(abfd, s->line_filepos, SEEK_SET);
+ /* Find all the linenumbers in this section */
+ while (*q) {
+ asymbol *p = *q;
+ alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
+ if (l) {
+ /* Found a linenumber entry, output */
+ struct internal_lineno out;
+ LINENO buff;
+ memset( (PTR)&out, 0, sizeof(out));
+ out.l_lnno = 0;
+ out.l_addr.l_symndx = l->u.offset;
+ coff_swap_lineno_out(abfd, &out, &buff);
+ bfd_write((PTR) &buff, 1, LINESZ, abfd);
+ l++;
+ while (l->line_number) {
+ out.l_lnno = l->line_number;
out.l_addr.l_symndx = l->u.offset;
coff_swap_lineno_out(abfd, &out, &buff);
bfd_write((PTR) &buff, 1, LINESZ, abfd);
l++;
- while (l->line_number) {
- out.l_lnno = l->line_number;
- out.l_addr.l_symndx = l->u.offset;
- coff_swap_lineno_out(abfd, &out, &buff);
- bfd_write((PTR) &buff, 1, LINESZ, abfd);
- l++;
- }
}
- q++;
}
+ q++;
}
}
}
+}
static asymbol *
coff_make_empty_symbol(abfd)
bfd *abfd;
- {
- coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
- if (new == NULL) {
- bfd_error = no_memory;
- return (NULL);
- } /* on error */
- new->native = 0;
- new->lineno = (alent *) NULL;
- new->symbol.the_bfd = abfd;
- return &new->symbol;
- }
+{
+ coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
+ if (new == NULL) {
+ bfd_error = no_memory;
+ return (NULL);
+ } /* on error */
+ new->native = 0;
+ new->lineno = (alent *) NULL;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
static void
-coff_print_symbol(ignore_abfd, file, symbol, how)
-bfd *ignore_abfd;
-FILE *file;
-asymbol *symbol;
-bfd_print_symbol_enum_type how;
- {
- switch (how) {
- case bfd_print_symbol_name_enum:
- fprintf(file, "%s", symbol->name);
- break;
- case bfd_print_symbol_type_enum:
- fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
- (unsigned long) coffsymbol(symbol)->lineno);
- break;
- case bfd_print_symbol_all_enum:
- {
- CONST char *section_name = symbol->section == (asection *) NULL ?
- "*abs" : symbol->section->name;
- bfd_print_symbol_vandf((PTR) file, symbol);
+DEFUN(coff_print_symbol,(ignore_abfd, file, symbol, how),
+ bfd *ignore_abfd AND
+ FILE *file AND
+ asymbol *symbol AND
+ bfd_print_symbol_enum_type how)
+{
+ switch (how) {
+ case bfd_print_symbol_name_enum:
+ fprintf(file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_type_enum:
+ fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
+ (unsigned long) coffsymbol(symbol)->lineno);
+ break;
+ case bfd_print_symbol_all_enum:
+ {
+ CONST char *section_name = symbol->section == (asection *) NULL ?
+ "*abs" : symbol->section->name;
+ bfd_print_symbol_vandf((PTR) file, symbol);
- fprintf(file, " %-5s %s %s %s",
- section_name,
- coffsymbol(symbol)->native ? "n" : "g",
- coffsymbol(symbol)->lineno ? "l" : " ",
- symbol->name);
- }
+ fprintf(file, " %-5s %s %s %s",
+ section_name,
+ coffsymbol(symbol)->native ? "n" : "g",
+ coffsymbol(symbol)->lineno ? "l" : " ",
+ symbol->name);
+ }
- break;
- }
+ break;
}
+}
static alent *
-coff_get_lineno(ignore_abfd, symbol)
-bfd *ignore_abfd;
-asymbol *symbol;
- {
- return coffsymbol(symbol)->lineno;
- }
+DEFUN(coff_get_lineno,(ignore_abfd, symbol),
+ bfd *ignore_abfd AND
+ asymbol *symbol)
+{
+ return coffsymbol(symbol)->lineno;
+}
/*
Set flags and magic number of a coff file from architecture and machine
type. Result is true if we can represent the arch&type, false if not.
*/
static boolean
-coff_set_flags(abfd, magicp, flagsp)
-bfd *abfd;
-unsigned *magicp,
-*flagsp;
- {
+DEFUN(coff_set_flags,(abfd, magicp, flagsp),
+ bfd *abfd AND
+ unsigned *magicp AND
+ unsigned short *flagsp)
+{
- switch (abfd->obj_arch) {
+ switch (abfd->obj_arch) {
#ifdef I960ROMAGIC
-
- case bfd_arch_i960:
-
- {
- unsigned flags;
- *magicp = I960ROMAGIC;
- /*
- ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
- I960RWMAGIC); FIXME???
- */
- switch (abfd->obj_machine) {
- case bfd_mach_i960_core:
- flags = F_I960CORE;
- break;
- case bfd_mach_i960_kb_sb:
- flags = F_I960KB;
- break;
- case bfd_mach_i960_mc:
- flags = F_I960MC;
- break;
- case bfd_mach_i960_xa:
- flags = F_I960XA;
- break;
- case bfd_mach_i960_ca:
- flags = F_I960CA;
- break;
- case bfd_mach_i960_ka_sa:
- flags = F_I960KA;
- break;
- default:
- return false;
- }
- *flagsp = flags;
- return true;
+
+ case bfd_arch_i960:
+
+ {
+ unsigned flags;
+ *magicp = I960ROMAGIC;
+ /*
+ ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
+ I960RWMAGIC); FIXME???
+ */
+ switch (abfd->obj_machine) {
+ case bfd_mach_i960_core:
+ flags = F_I960CORE;
+ break;
+ case bfd_mach_i960_kb_sb:
+ flags = F_I960KB;
+ break;
+ case bfd_mach_i960_mc:
+ flags = F_I960MC;
+ break;
+ case bfd_mach_i960_xa:
+ flags = F_I960XA;
+ break;
+ case bfd_mach_i960_ca:
+ flags = F_I960CA;
+ break;
+ case bfd_mach_i960_ka_sa:
+ flags = F_I960KA;
+ break;
+ default:
+ return false;
}
- break;
+ *flagsp = flags;
+ return true;
+ }
+ break;
#endif
#ifdef MIPS
- case bfd_arch_mips:
- *magicp = MIPS_MAGIC_2;
- return true;
- break;
+ case bfd_arch_mips:
+ *magicp = MIPS_MAGIC_2;
+ return true;
+ break;
#endif
#ifdef I386MAGIC
- case bfd_arch_i386:
- *magicp = I386MAGIC;
- return true;
+ case bfd_arch_i386:
+ *magicp = I386MAGIC;
+ return true;
#endif
#ifdef MC68MAGIC
- case bfd_arch_m68k:
- *magicp = MC68MAGIC;
- return true;
+ case bfd_arch_m68k:
+ *magicp = MC68MAGIC;
+ return true;
#endif
#ifdef MC88MAGIC
- case bfd_arch_m88k:
- *magicp = MC88OMAGIC;
- return true;
- break;
+ case bfd_arch_m88k:
+ *magicp = MC88OMAGIC;
+ return true;
+ break;
#endif
- default: /* Unknown architecture */
- return false;
- }
-
+ default: /* Unknown architecture */
return false;
}
+
+ return false;
+}
static boolean
-coff_set_arch_mach(abfd, arch, machine)
-bfd *abfd;
-enum bfd_architecture arch;
-unsigned long machine;
- {
- unsigned dummy1,
- dummy2;
+DEFUN(coff_set_arch_mach,(abfd, arch, machine),
+ bfd *abfd AND
+ enum bfd_architecture arch AND
+ unsigned long machine)
+{
+ unsigned dummy1;
+ unsigned short dummy2;
abfd->obj_arch = arch;
abfd->obj_machine = machine;
if (arch != bfd_arch_unknown &&
coff_set_flags(abfd, &dummy1, &dummy2) != true)
return false; /* We can't represent this type */
- return true; /* We're easy ... */
+ return true; /* We're easy ... */
}
/* Calculate the file position for each section. */
static void
-coff_compute_section_file_positions(abfd)
-bfd *abfd;
- {
- asection *current;
- file_ptr sofar = FILHSZ;
- if (bfd_get_start_address(abfd)) {
- /*
- A start address may have been added to the original file. In this
- case it will need an optional header to record it.
- */
- abfd->flags |= EXEC_P;
- }
- if (abfd->flags & EXEC_P)
- sofar += AOUTSZ;
-
-
- sofar += abfd->section_count * SCNHSZ;
-
- for (current = abfd->sections; current != NULL; current =
- current->next) {
- /* Only deal with sections which have contents */
- if (!(current->flags & SEC_HAS_CONTENTS))
- continue;
-
- /* Align the sections in the file to the same boundary on
- which they are aligned in virtual memory. I960 doesn't
- do this (FIXME) so we can stay in sync with Intel. 960
- doesn't yet page from files... */
+DEFUN(coff_compute_section_file_positions,(abfd),
+ bfd *abfd)
+{
+ asection *current;
+ file_ptr sofar = FILHSZ;
+ if (bfd_get_start_address(abfd)) {
+ /*
+ A start address may have been added to the original file. In this
+ case it will need an optional header to record it.
+ */
+ abfd->flags |= EXEC_P;
+ }
+ if (abfd->flags & EXEC_P)
+ sofar += AOUTSZ;
+
+
+ sofar += abfd->section_count * SCNHSZ;
+ for (current = abfd->sections;
+ current != (asection *)NULL;
+ current = current->next) {
+ /* Only deal with sections which have contents */
+ if (!(current->flags & SEC_HAS_CONTENTS))
+ continue;
+
+ /* Align the sections in the file to the same boundary on
+ which they are aligned in virtual memory. I960 doesn't
+ do this (FIXME) so we can stay in sync with Intel. 960
+ doesn't yet page from files... */
#ifndef I960
- sofar = ALIGN(sofar, 1 << current->alignment_power);
+ sofar = ALIGN(sofar, 1 << current->alignment_power);
#endif
- /* FIXME, in demand paged files, the low order bits of the file
- offset must match the low order bits of the virtual address.
- "Low order" is apparently implementation defined. Add code
- here to round sofar up to match the virtual address. */
-
- current->filepos = sofar;
- sofar += current->size;
- }
- obj_relocbase(abfd) = sofar;
+ /* FIXME, in demand paged files, the low order bits of the file
+ offset must match the low order bits of the virtual address.
+ "Low order" is apparently implementation defined. Add code
+ here to round sofar up to match the virtual address. */
+
+ current->filepos = sofar;
+ sofar += current->size;
}
+ obj_relocbase(abfd) = sofar;
+}
/* SUPPRESS 529 */
static boolean
DEFUN(coff_write_object_contents,(abfd),
-bfd *abfd)
-{
- asection *current;
- boolean hasrelocs = false;
- boolean haslinno = false;
- file_ptr reloc_base;
- file_ptr lineno_base;
- file_ptr sym_base;
- file_ptr scn_base;
- file_ptr data_base;
- unsigned long reloc_size = 0;
- unsigned long lnno_size = 0;
- asection *text_sec = NULL;
- asection *data_sec = NULL;
- asection *bss_sec = NULL;
-
- struct internal_filehdr internal_f;
- struct internal_aouthdr internal_a;
+ bfd *abfd)
+ {
+ asection *current;
+ boolean hasrelocs = false;
+ boolean haslinno = false;
+ file_ptr reloc_base;
+ file_ptr lineno_base;
+ file_ptr sym_base;
+ file_ptr scn_base;
+ file_ptr data_base;
+ unsigned long reloc_size = 0;
+ unsigned long lnno_size = 0;
+ asection *text_sec = NULL;
+ asection *data_sec = NULL;
+ asection *bss_sec = NULL;
+
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
- struct icofdata *coff = obj_icof(abfd);
+ struct icofdata *coff = obj_icof(abfd);
- bfd_error = system_call_error;
+ bfd_error = system_call_error;
- if(abfd->output_has_begun == false) {
- coff_compute_section_file_positions(abfd);
- }
+ if(abfd->output_has_begun == false) {
+ coff_compute_section_file_positions(abfd);
+ }
- if (abfd->sections != (asection *)NULL) {
- scn_base = abfd->sections->filepos;
+ if (abfd->sections != (asection *)NULL) {
+ scn_base = abfd->sections->filepos;
}
else {
scn_base = 0;
{ int magic = 0;
int flags = 0;
- coff_set_flags(abfd, &magic, &flags);
+ coff_set_flags(abfd, &magic, &internal_f.f_flags);
internal_f.f_magic = magic;
- internal_f.f_flags = flags;
-
/* ...and the "opt"hdr... */
#ifdef I960
obj_sym_filepos(abfd) = sym_base;
if (bfd_get_symcount(abfd) != 0) {
+ coff_renumber_symbols(abfd);
coff_mangle_symbols(abfd);
coff_write_symbols(abfd);
coff_write_linenumbers(abfd);
bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
}
return true;
+}
+
+/*
+this function transforms the offsets into the symbol table into
+pointers to syments.
+*/
+
+
+static void
+DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent),
+bfd *abfd AND
+combined_entry_type *table_base AND
+int type AND
+int class AND
+combined_entry_type *auxent)
+{
+ /* Don't bother if this is a file or a section */
+ if (class == C_STAT && type == T_NULL) return;
+ if (class == C_FILE) return;
+
+ /* Otherwise patch up */
+ if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
+ auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
+ auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
+ auxent->fix_end = 1;
+ }
+if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
+ auxent->u.auxent.x_sym.x_tagndx.p = table_base + auxent->u.auxent.x_sym.x_tagndx.l;
+ auxent->fix_tag = 1;
+}
+
+
+
}
static boolean
-coff_set_section_contents(abfd, section, location, offset, count)
- bfd *abfd;
- sec_ptr section;
- PTR location;
- file_ptr offset;
- size_t count;
+DEFUN(coff_set_section_contents,(abfd, section, location, offset, count),
+ bfd *abfd AND
+ sec_ptr section AND
+ PTR location AND
+ file_ptr offset AND
+ size_t count)
{
if (abfd->output_has_begun == false) /* set by bfd.c handler */
coff_compute_section_file_positions(abfd);
return (area);
} /* buy_and_read() */
-static void
-DEFUN(offset_symbol_indices,(abfd, symtab, count, offset),
- bfd *abfd AND
- struct internal_syment *symtab AND
- unsigned long count AND
- long offset)
+
+
+static char *
+DEFUN(build_string_table,(abfd),
+bfd *abfd)
{
- struct internal_syment *end = symtab + count;
- for (; symtab < end; ++symtab) {
- if (symtab->n_sclass == C_FILE) {
- symtab->n_value = 0;
- }
- else if (symtab->n_sclass == C_ALIAS) {
- /*
- These guys have indices in their values.
- */
- symtab->n_value = symtab->n_value + offset;
- }
- else if (symtab->n_numaux) {
- /*
- anybody else without an aux, has no indices.
- */
-
- if (symtab->n_sclass == C_EOS
- || (BTYPE(symtab->n_type) == T_STRUCT
- && symtab->n_sclass != C_STRTAG)
- || BTYPE(symtab->n_type) == T_UNION
- || BTYPE(symtab->n_type) == T_ENUM) {
- /* If the tagndx is 0 then the struct hasn't really been
- defined, so leave it alone */
-
- if(((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx != 0) {
- ((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx += offset;
- }
-
- } /* These guys have a tagndx */
- if (symtab->n_sclass == C_STRTAG
- || symtab->n_sclass == C_UNTAG
- || symtab->n_sclass == C_ENTAG
- || symtab->n_sclass == C_BLOCK
- || symtab->n_sclass == C_FCN
- || ISFCN(symtab->n_type)) {
-
- ((union internal_auxent *) (symtab +
- 1))->x_sym.x_fcnary.x_fcn.x_endndx
- += offset;
-
- } /* These guys have an endndx */
-#ifndef I960
- if (ISFCN(symtab->n_type)) {
- ((union internal_auxent *) (symtab + 1))->x_sym.x_tvndx += offset;
- } /* These guys have a tvndx. I think...
- (FIXME) */
-#endif /* Not I960 */
-
- } /* if value, else if aux */
- symtab += symtab->n_numaux;
- } /* walk the symtab */
-
- return;
-} /* offset_symbol_indices() */
+ char string_table_size_buffer[4];
+ unsigned int string_table_size;
+ char *string_table;
+ /*
+ At this point we should be "seek"'d to the end of the
+ symbols === the symbol table size.
+ */
+
+ if (bfd_read((char *) string_table_size_buffer,
+ sizeof(string_table_size_buffer),
+ 1, abfd) != sizeof(string_table_size)) {
+ bfd_error = system_call_error;
+ return (NULL);
+ } /* on error */
+
+ string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
+
+ if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
+ bfd_error = no_memory;
+ return (NULL);
+ } /* on mallocation error */
+ if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
+ bfd_error = system_call_error;
+ return (NULL);
+ }
+ return string_table;
+}
/*
read a symbol table into freshly mallocated memory, swap it, and knit the
before, put one there.
*/
-static struct internal_syment *
+static combined_entry_type *
DEFUN(get_normalized_symtab,(abfd),
bfd *abfd)
{
- struct internal_syment *internal;
- struct internal_syment *internal_ptr;
- struct internal_syment *internal_end;
+ combined_entry_type *internal;
+ combined_entry_type *internal_ptr;
+ combined_entry_type *internal_end;
SYMENT *raw;
SYMENT *raw_src;
SYMENT *raw_end;
char *string_table = NULL;
unsigned long size;
- char string_table_size_buffer[4];
+
unsigned long string_table_size = 0;
unsigned int raw_size;
- if (obj_raw_syments(abfd) != (struct internal_syment *)NULL) {
+ if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
return obj_raw_syments(abfd);
}
- if ((size = bfd_get_symcount(abfd) * sizeof(struct internal_syment)) == 0) {
+ if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
bfd_error = no_symbols;
return (NULL);
}
- internal = (struct internal_syment *)bfd_alloc(abfd, size);
+ internal = (combined_entry_type *)bfd_alloc(abfd, size);
internal_end = internal + bfd_get_symcount(abfd);
raw_size = bfd_get_symcount(abfd) * SYMESZ;
/* Swap all the raw entries */
for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
unsigned int i;
- coff_swap_sym_in(abfd, raw_src,internal_ptr);
- for (i = internal_ptr->n_numaux; i; --i, raw_src++, internal_ptr++) {
- coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->n_type,
- internal_ptr->n_sclass, (union
- internal_auxent *)(internal_ptr +1));
+ coff_swap_sym_in(abfd, raw_src,&internal_ptr->u.syment);
+ internal_ptr->fix_tag = 0;
+ internal_ptr->fix_end = 0;
+
+ for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
+ (internal_ptr+1)->fix_tag = 0;
+ (internal_ptr+1)->fix_end = 0;
+
+ coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->u.syment.n_type,
+ internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent);
+
+ coff_pointerize_aux(abfd,
+ internal,
+ internal_ptr->u.syment.n_type,
+ internal_ptr->u.syment.n_sclass,
+ internal_ptr +1);
}
}
/* Free all the raw stuff */
bfd_release(abfd, raw_src);
- for (internal_ptr = internal; internal_ptr < internal_end; internal_ptr ++) {
+ for (internal_ptr = internal; internal_ptr < internal_end;
+ internal_ptr ++)
+ {
+ if (internal_ptr->u.syment.n_sclass == C_FILE) {
+ /* make a file symbol point to the name in the auxent, since
+ the text ".file" is redundant */
+ if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
+ /* the filename is a long one, point into the string table
+ */
+ if (string_table == NULL) {
+ string_table = build_string_table(abfd);
+ }
- if (internal_ptr->_n._n_n._n_zeroes != 0) {
- /*
- This is a "short" name. Make it long.
- */
- unsigned long i = 0;
- char *newstring = NULL;
- /*
- find the length of this string without walking into memory
- that isn't ours.
- */
+ internal_ptr->u.syment._n._n_n._n_offset =
+ (int) (string_table - 4 +
+ (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
+ }
+ else {
+ /* ordinary short filename, put into memory anyway */
+ internal_ptr->u.syment._n._n_n._n_offset = (int)
+ copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
+
+ }
+ }
+ else {
+ if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
+ /*
+ This is a "short" name. Make it long.
+ */
+ unsigned long i = 0;
+ char *newstring = NULL;
+ /*
+ find the length of this string without walking into memory
+ that isn't ours.
+ */
- for (i = 0; i < 8; ++i) {
- if (internal_ptr->_n._n_name[i] == '\0') {
- break;
- } /* if end of string */
- } /* possible lengths of this string. */
+ for (i = 0; i < 8; ++i) {
+ if (internal_ptr->u.syment._n._n_name[i] == '\0') {
+ break;
+ } /* if end of string */
+ } /* possible lengths of this string. */
- if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
- bfd_error = no_memory;
- return (NULL);
- } /* on error */
- bzero(newstring, i);
- strncpy(newstring, internal_ptr->_n._n_name, i-1);
- internal_ptr->_n._n_n._n_offset = (int) newstring;
- internal_ptr->_n._n_n._n_zeroes = 0;
+ if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
+ bfd_error = no_memory;
+ return (NULL);
+ } /* on error */
+ bzero(newstring, i);
+ strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
+ internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
+ internal_ptr->u.syment._n._n_n._n_zeroes = 0;
- }
- else {
- if (string_table == NULL) {
- /*
- NOTE: we don't read the string table until now because we
- don't necessarily know that we have one until now.
- */
- /*
- At this point we should be "seek"'d to the end of the
- symbols === the symbol table size.
- */
-
- if (bfd_read((char *) string_table_size_buffer,
- sizeof(string_table_size_buffer),
- 1, abfd) != sizeof(string_table_size)) {
- bfd_error = system_call_error;
- return (NULL);
- } /* on error */
-
- string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
-
- if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
- bfd_error = no_memory;
- return (NULL);
- } /* on mallocation error */
- if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
- bfd_error = system_call_error;
- return (NULL);
- } /* on error */
- } /* have not yet read the string table. */
- /*
- This is a long name already. Just point it at the string in
- memory.
- */
- internal_ptr->_n._n_n._n_offset = (int) (string_table - 4 + internal_ptr->_n._n_n._n_offset);
+ }
+ else {
+ /* This is a long name already. Just point it at the string in memory. */
+ if (string_table == NULL) {
+ string_table = build_string_table(abfd);
+ }
+ internal_ptr->u.syment._n._n_n._n_offset =
+ (int) (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
+ }
+ }
+ internal_ptr += internal_ptr->u.syment.n_numaux;
+ }
- } /* switch on type of symbol name */
-
- internal_ptr += internal_ptr->n_numaux;
- } /* for each symbol */
-#if 0
-#ifndef GNU960
- /* I'm not sure of the repercussions of this, so the Intel
- folks will always do the force
- */
- if (obj_symbol_slew(abfd) > 0)
- force_indices_file_symbol_relative(abfd, internal);
-#else
- force_indices_file_symbol_relative(abfd, internal);
-#endif
-#endif
obj_raw_syments(abfd) = internal;
obj_string_table(abfd) = string_table;
+/*doc*
+@subsubsection Reading Linenumbers
+Createing the linenumber table is done by reading in the entire coff
+linenumber table, and creating another table for internal use.
+
+A coff line number table is structured so that each
+function is marked as having a line number of 0. Each line within the
+function is an offset from the first line in the function. The base of
+the line number information for the table is stored in the symbol
+associated with the function.
+
+The information is copied from the external to the internal table, and
+each symbol which marks a function is marked by pointing its...
+
+**How does this work ?**
+
+*/
static boolean
coff_slurp_line_table(abfd, asect)
coff_symbol_type *sym =
(coff_symbol_type *) (dst.l_addr.l_symndx
+ obj_symbol_slew(abfd)
- + obj_raw_syments(abfd))->_n._n_n._n_zeroes;
+ + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes;
cache_ptr->u.sym = (asymbol *) sym;
sym->lineno = cache_ptr;
}
static boolean
DEFUN(coff_slurp_symbol_table,(abfd),
bfd *abfd)
- {
- struct internal_syment *native_symbols;
- coff_symbol_type *cached_area;
- unsigned int *table_ptr;
+{
+ combined_entry_type *native_symbols;
+ coff_symbol_type *cached_area;
+ unsigned int *table_ptr;
- unsigned int number_of_symbols = 0;
- if (obj_symbols(abfd))
- return true;
- bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
+ unsigned int number_of_symbols = 0;
+ if (obj_symbols(abfd))
+ return true;
+ bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
- /* Read in the symbol table */
- if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
- return (false);
- } /* on error */
+ /* Read in the symbol table */
+ if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
+ return (false);
+ } /* on error */
- /* Allocate enough room for all the symbols in cached form */
- cached_area =
- (coff_symbol_type *)
- bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
+ /* Allocate enough room for all the symbols in cached form */
+ cached_area =
+ (coff_symbol_type *)
+ bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
- if (cached_area == NULL) {
- bfd_error = no_memory;
- return false;
- } /* on error */
- table_ptr =
- (unsigned int *)
- bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
+ if (cached_area == NULL) {
+ bfd_error = no_memory;
+ return false;
+ } /* on error */
+ table_ptr =
+ (unsigned int *)
+ bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
- if (table_ptr == NULL) {
- bfd_error = no_memory;
- return false;
- } else {
- coff_symbol_type *dst = cached_area;
- unsigned int last_native_index = bfd_get_symcount(abfd);
- unsigned int this_index = 0;
- while (this_index < last_native_index) {
- struct internal_syment *src = native_symbols + this_index;
- table_ptr[this_index] = number_of_symbols;
- dst->symbol.the_bfd = abfd;
+ if (table_ptr == NULL) {
+ bfd_error = no_memory;
+ return false;
+ } else {
+ coff_symbol_type *dst = cached_area;
+ unsigned int last_native_index = bfd_get_symcount(abfd);
+ unsigned int this_index = 0;
+ while (this_index < last_native_index) {
+ combined_entry_type *src = native_symbols + this_index;
+ table_ptr[this_index] = number_of_symbols;
+ dst->symbol.the_bfd = abfd;
- dst->symbol.name = (char *)(src->_n._n_n._n_offset);
- /*
- We use the native name field to point to the cached field
- */
- src->_n._n_n._n_zeroes = (int) dst;
- dst->symbol.section = section_from_bfd_index(abfd,
- src->n_scnum);
- switch (src->n_sclass) {
+ dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
+ /*
+ We use the native name field to point to the cached field
+ */
+ src->u.syment._n._n_n._n_zeroes = (int) dst;
+ dst->symbol.section = section_from_bfd_index(abfd,
+ src->u.syment.n_scnum);
+ switch (src->u.syment.n_sclass) {
#ifdef I960
- case C_LEAFEXT:
+ case C_LEAFEXT:
#if 0
- dst->symbol.value = src->n_value - dst->symbol.section->vma;
- dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
- dst->symbol.flags |= BSF_NOT_AT_END;
+ dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
+ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+ dst->symbol.flags |= BSF_NOT_AT_END;
#endif
- /* Fall through to next case */
+ /* Fall through to next case */
#endif
- case C_EXT:
- if ((src->n_scnum) == 0) {
- if ((src->n_value) == 0) {
- dst->symbol.flags = BSF_UNDEFINED;
- dst->symbol.value= 0;
- }
- else {
- dst->symbol.flags = BSF_FORT_COMM;
- dst->symbol.value = (src->n_value);
- }
+ case C_EXT:
+ if ((src->u.syment.n_scnum) == 0) {
+ if ((src->u.syment.n_value) == 0) {
+ dst->symbol.flags = BSF_UNDEFINED;
+ dst->symbol.value= 0;
+ }
+ else {
+ dst->symbol.flags = BSF_FORT_COMM;
+ dst->symbol.value = (src->u.syment.n_value);
+ }
+ }
+ else {
+ /*
+ Base the value as an index from the base of the
+ section
+ */
+ if (dst->symbol.section == (asection *) NULL) {
+ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
+ dst->symbol.value = src->u.syment.n_value;
}
else {
+ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+ dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
+ }
+ if (ISFCN((src->u.syment.n_type))) {
/*
- Base the value as an index from the base of the
- section
- */
- if (dst->symbol.section == (asection *) NULL) {
- dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
- dst->symbol.value = src->n_value;
- }
- else {
- dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
- dst->symbol.value = src->n_value - dst->symbol.section->vma;
- }
- if (ISFCN((src->n_type))) {
- /*
- A function ext does not go at the end of a file
- */
- dst->symbol.flags |= BSF_NOT_AT_END;
- }
+ A function ext does not go at the end of a file
+ */
+ dst->symbol.flags |= BSF_NOT_AT_END;
}
+ }
- break;
- case C_STAT: /* static */
+ break;
+ case C_STAT: /* static */
#ifdef I960
- case C_LEAFSTAT: /* static leaf procedure */
+ case C_LEAFSTAT: /* static leaf procedure */
#endif
- case C_LABEL: /* label */
- dst->symbol.flags = BSF_LOCAL;
- /*
- Base the value as an index from the base of the section
- */
- dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
- break;
+ case C_LABEL: /* label */
+ dst->symbol.flags = BSF_LOCAL;
+ /*
+ Base the value as an index from the base of the section
+ */
+ dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
+ break;
- case C_MOS: /* member of structure */
- case C_EOS: /* end of structure */
- case C_REGPARM: /* register parameter */
- case C_REG: /* register variable */
+ case C_MOS: /* member of structure */
+ case C_EOS: /* end of structure */
+ case C_REGPARM: /* register parameter */
+ case C_REG: /* register variable */
#ifdef C_AUTOARG
- case C_AUTOARG: /* 960-specific storage class */
+ case C_AUTOARG: /* 960-specific storage class */
#endif
- case C_TPDEF: /* type definition */
+ case C_TPDEF: /* type definition */
- case C_ARG:
- case C_AUTO: /* automatic variable */
- case C_FIELD: /* bit field */
- case C_ENTAG: /* enumeration tag */
- case C_MOE: /* member of enumeration */
- case C_MOU: /* member of union */
- case C_UNTAG: /* union tag */
+ case C_ARG:
+ case C_AUTO: /* automatic variable */
+ case C_FIELD: /* bit field */
+ case C_ENTAG: /* enumeration tag */
+ case C_MOE: /* member of enumeration */
+ case C_MOU: /* member of union */
+ case C_UNTAG: /* union tag */
- dst->symbol.flags = BSF_DEBUGGING;
- dst->symbol.value = (src->n_value);
- break;
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
+ break;
- case C_FILE: /* file name */
- case C_STRTAG: /* structure tag */
- dst->symbol.flags = BSF_DEBUGGING;
- dst->symbol.value = (src->n_value);
+ case C_FILE: /* file name */
+ case C_STRTAG: /* structure tag */
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
- break;
- case C_BLOCK: /* ".bb" or ".eb" */
- case C_FCN: /* ".bf" or ".ef" */
- dst->symbol.flags = BSF_LOCAL;
- /*
- Base the value as an index from the base of the section
- */
- dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
+ break;
+ case C_BLOCK: /* ".bb" or ".eb" */
+ case C_FCN: /* ".bf" or ".ef" */
+ dst->symbol.flags = BSF_LOCAL;
+ /*
+ Base the value as an index from the base of the section
+ */
+ dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
- break;
- case C_EFCN: /* physical end of function */
- case C_NULL:
- case C_EXTDEF: /* external definition */
- case C_ULABEL: /* undefined label */
- case C_USTATIC: /* undefined static */
- case C_LINE: /* line # reformatted as symbol table entry */
- case C_ALIAS: /* duplicate tag */
- case C_HIDDEN: /* ext symbol in dmert public lib */
+ break;
+ case C_EFCN: /* physical end of function */
+ case C_NULL:
+ case C_EXTDEF: /* external definition */
+ case C_ULABEL: /* undefined label */
+ case C_USTATIC: /* undefined static */
+ case C_LINE: /* line # reformatted as symbol table entry */
+ case C_ALIAS: /* duplicate tag */
+ case C_HIDDEN: /* ext symbol in dmert public lib */
- default:
+ default:
- abort();
- dst->symbol.flags = BSF_DEBUGGING;
- dst->symbol.value = (src->n_value);
+ abort();
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
- break;
- }
+ break;
+ }
- BFD_ASSERT(dst->symbol.flags != 0);
+ BFD_ASSERT(dst->symbol.flags != 0);
- dst->native = src;
+ dst->native = src;
- dst->symbol.udata = 0;
- dst->lineno = (alent *) NULL;
- this_index += (src->n_numaux) + 1;
- dst++;
- number_of_symbols++;
- } /* walk the native symtab */
- } /* bfdize the native symtab */
-
- obj_symbols(abfd) = cached_area;
- obj_raw_syments(abfd) = native_symbols;
-
- bfd_get_symcount(abfd) = number_of_symbols;
- obj_convert(abfd) = table_ptr;
- /* Slurp the line tables for each section too */
- {
- asection *p;
- p = abfd->sections;
- while (p) {
- coff_slurp_line_table(abfd, p);
- p = p->next;
- }
+ dst->symbol.udata = 0;
+ dst->lineno = (alent *) NULL;
+ this_index += (src->u.syment.n_numaux) + 1;
+ dst++;
+ number_of_symbols++;
+ } /* walk the native symtab */
+ } /* bfdize the native symtab */
+
+ obj_symbols(abfd) = cached_area;
+ obj_raw_syments(abfd) = native_symbols;
+
+ bfd_get_symcount(abfd) = number_of_symbols;
+ obj_convert(abfd) = table_ptr;
+ /* Slurp the line tables for each section too */
+ {
+ asection *p;
+ p = abfd->sections;
+ while (p) {
+ coff_slurp_line_table(abfd, p);
+ p = p->next;
}
- return true;
- } /* coff_slurp_symbol_table() */
+ }
+ return true;
+} /* coff_slurp_symbol_table() */
static unsigned int
coff_get_symtab_upper_bound(abfd)
return (asect->reloc_count + 1) * sizeof(arelent *);
}
+/*doc*
+@subsubsection Reading Relocations
+Coff relocations are easily transformed into the internal bfd form
+(@code{arelent}).
+
+Reading a coff relocation table is done in the following stages:
+@itemize @bullet
+@item
+The entire coff relocation table is read into memory.
+@item
+Each relocation is processed in turn, first it is swapped from the
+external to the internal form.
+@item
+The symbol referenced in the relocation's symbol index is turned into
+a pointer into the canonical symbol table. Note that this table is the
+same as the one returned by a call to @code{bfd_canonicalize_symtab}.
+The back end will call the routine and save the result if a
+canonicalization hasn't been done.
+@item
+The reloc index is turned into a pointer to a howto structure, in a
+back end specific way. For instance, the 386 and 960 use the
+@code{r_type} to directly produce an index into a howto table vector;
+the 88k subtracts a number from the @code{r_type} field and creates an
+addend field.
+@end itemize
+*/
+
static boolean
DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
bfd *abfd AND
&& ptr->section != (asection *) NULL
&& ((ptr->flags & BSF_OLD_COMMON)== 0))
{
+#ifndef M88
cache_ptr->addend = -(ptr->section->vma + ptr->value);
+#else
+ cache_ptr->addend = 0;
+#endif
+
}
else {
cache_ptr->addend = 0;
unsigned int i = 0;
struct icofdata *cof = obj_icof(abfd);
/* Run through the raw syments if available */
- struct internal_syment *p;
+ combined_entry_type *p;
alent *l;
unsigned int line_base = 0;
if (cof == (struct icofdata *)NULL)
return false;
-
+
p = cof->raw_syments;
- /*
- I don't know for sure what's right, but this isn't it. First off, an
- object file may not have any C_FILE's in it. After
- get_normalized_symtab(), it should have at least 1, the one I put
- there, but otherwise, all bets are off. Point #2, the first C_FILE
- isn't necessarily the right C_FILE because any given object may have
- many. I think you'll have to track sections as they coelesce in order
- to find the C_STAT symbol for this section. Then you'll have to work
- backwards to find the previous C_FILE, or choke if you get to a C_STAT
- for the same kind of section. That will mean that the original object
- file didn't have a C_FILE. xoxorich.
- */
-/*
-#ifdef WEREBEINGPEDANTIC
- return false;
-#endif
- */
for (i = 0; i < cof->raw_syment_count; i++) {
- if (p->n_sclass == C_FILE) {
- /* File name is embeded in auxent */
- /*
- This isn't right. The fname should probably be normalized
- during get_normalized_symtab(). In any case, what was here
- wasn't right because a SYMENT.n_name isn't an
- AUXENT.x_file.x_fname. xoxorich.
- */
-
- *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname;
+ if (p->u.syment.n_sclass == C_FILE) {
+ /* File name has been moved into symbol */
+ *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
break;
}
- p += 1 + p->n_numaux;
+ p += 1 + p->u.syment.n_numaux;
}
/* Now wander though the raw linenumbers of the section */
/*
coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
*functionname_ptr = coff->symbol.name;
if (coff->native) {
- struct internal_syment *s = coff->native;
- s = s + 1 + s->n_numaux;
+ combined_entry_type *s = coff->native;
+ s = s + 1 + s->u.syment.n_numaux;
/*
S should now point to the .bf of the function
*/
- if (s->n_numaux) {
+ if (s->u.syment.n_numaux) {
/*
The linenumber is stored in the auxent
*/
- union internal_auxent *a = (union internal_auxent *) (s + 1);
+ union internal_auxent *a = &((s + 1)->u.auxent);
line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
}
}
cache_offset = offset;
cache_i = i;
cache_l = l;
+
return true;
}
#define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt
#define coff_get_section_contents bfd_generic_get_section_contents
#define coff_close_and_cleanup bfd_generic_close_and_cleanup
+
+#define coff_bfd_debug_info_start bfd_void
+#define coff_bfd_debug_info_end bfd_void
+#define coff_bfd_debug_info_accumulate bfd_void
*/
-#define this_byte(ieee) *(ieee->input_p)
-#define next_byte(ieee) (ieee->input_p++)
-#define this_byte_and_next(ieee) (*(ieee->input_p++))
+#define this_byte(ieee) *((ieee)->input_p)
+#define next_byte(ieee) ((ieee)->input_p++)
+#define this_byte_and_next(ieee) (*((ieee)->input_p++))
static unsigned short
DEFUN(read_2bytes,(ieee),
- ieee_data_type *ieee)
+ common_header_type *ieee)
{
unsigned char c1 = this_byte_and_next(ieee);
unsigned char c2 = this_byte_and_next(ieee);
static void
DEFUN(bfd_get_string,(ieee, string, length),
- ieee_data_type *ieee AND
+ common_header_type *ieee AND
char *string AND
size_t length)
{
static char *
DEFUN(read_id,(ieee),
- ieee_data_type *ieee)
+ common_header_type *ieee)
{
size_t length;
char *string;
static boolean
DEFUN(parse_int,(ieee, value_ptr),
- ieee_data_type *ieee AND
+ common_header_type *ieee AND
bfd_vma *value_ptr)
{
int value = this_byte(ieee);
}
static int
DEFUN(parse_i,(ieee, ok),
- ieee_data_type *ieee AND
+ common_header_type *ieee AND
boolean *ok)
{
bfd_vma x;
static bfd_vma
DEFUN(must_parse_int,(ieee),
- ieee_data_type *ieee)
+ common_header_type *ieee)
{
bfd_vma result;
BFD_ASSERT(parse_int(ieee, &result) == true);
ieee_value_type *sp = stack;
while (loop) {
- switch (this_byte(ieee))
+ switch (this_byte(&(ieee->h)))
{
case ieee_variable_P_enum:
/* P variable, current program counter for section n */
{
int section_n ;
- next_byte(ieee);
+ next_byte(&(ieee->h));
*pcrel = true;
- section_n = must_parse_int(ieee);
+ section_n = must_parse_int(&(ieee->h));
PUSH(NOSYMBOL, 0,
TOS.value = ieee->section_table[section_n]->vma +
ieee_per_section(ieee->section_table[section_n])->pc);
}
case ieee_variable_L_enum:
/* L variable address of section N */
- next_byte(ieee);
- PUSH(NOSYMBOL,ieee->section_table[must_parse_int(ieee)],0);
+ next_byte(&(ieee->h));
+ PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
break;
case ieee_variable_R_enum:
/* R variable, logical address of section module */
/* FIXME, this should be different to L */
- next_byte(ieee);
- PUSH(NOSYMBOL,ieee->section_table[must_parse_int(ieee)],0);
+ next_byte(&(ieee->h));
+ PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
break;
case ieee_variable_S_enum:
/* S variable, size in MAUS of section module */
- next_byte(ieee);
+ next_byte(&(ieee->h));
PUSH(NOSYMBOL,
0,
- ieee->section_table[must_parse_int(ieee)]->size);
+ ieee->section_table[must_parse_int(&(ieee->h))]->size);
break;
case ieee_variable_X_enum:
/* Push the address of external variable n */
{
ieee_symbol_index_type sy;
- next_byte(ieee);
- sy.index = (int)(must_parse_int(ieee)) ;
+ next_byte(&(ieee->h));
+ sy.index = (int)(must_parse_int(&(ieee->h))) ;
sy.letter = 'X';
PUSH(sy, 0, 0);
bfd_vma value1, value2;
asection *section1, *section_dummy;
ieee_symbol_index_type sy;
- next_byte(ieee);
+ next_byte(&(ieee->h));
POP(sy, section1, value1);
POP(sy, section_dummy, value2);
asection *section2;
ieee_symbol_index_type sy1;
ieee_symbol_index_type sy2;
- next_byte(ieee);
+ next_byte(&(ieee->h));
POP(sy1, section1, value1);
POP(sy2, section2, value2);
default:
{
bfd_vma va;
- BFD_ASSERT(this_byte(ieee) < (int)ieee_variable_A_enum
- || this_byte(ieee) > (int)ieee_variable_Z_enum);
- if (parse_int(ieee, &va))
+ BFD_ASSERT(this_byte(&(ieee->h)) < (int)ieee_variable_A_enum
+ || this_byte(&(ieee->h)) > (int)ieee_variable_Z_enum);
+ if (parse_int(&(ieee->h), &va))
{
PUSH(NOSYMBOL,0, va);
}
#define ieee_seek(abfd, offset) \
- ieee_data(abfd)->input_p = ieee_data(abfd)->first_byte + offset
+ ieee_data(abfd)->h.input_p = ieee_data(abfd)->h.first_byte + offset
+
+#define ieee_pos(abfd) ieee_data(abfd)->h.input_p -ieee_data(abfd)->h.first_byte
static void
DEFUN(ieee_slurp_external_symbols,(abfd),
ieee_seek(abfd, offset );
while (loop) {
- switch (this_byte(ieee)) {
+ switch (this_byte(&(ieee->h))) {
case ieee_external_symbol_enum:
- next_byte(ieee);
- symbol = (ieee_symbol_type *)bfd_alloc(ieee->abfd, sizeof(ieee_symbol_type));
+ next_byte(&(ieee->h));
+ symbol = (ieee_symbol_type *)bfd_alloc(ieee->h.abfd, sizeof(ieee_symbol_type));
*prev_symbols_ptr = symbol;
prev_symbols_ptr= &symbol->next;
- symbol->index = must_parse_int(ieee);
+ symbol->index = must_parse_int(&(ieee->h));
if (symbol->index > ieee->external_symbol_max_index) {
ieee->external_symbol_max_index = symbol->index;
}
BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
symbol_count++;
symbol->symbol.the_bfd = abfd;
- symbol->symbol.name = read_id(ieee);
+ symbol->symbol.name = read_id(&(ieee->h));
symbol->symbol.udata = (PTR)NULL;
symbol->symbol.flags = BSF_NO_FLAGS;
break;
unsigned int symbol_type_index;
unsigned int symbol_attribute_def;
bfd_vma value;
- next_byte(ieee); /* Skip prefix */
- next_byte(ieee);
- symbol_name_index = must_parse_int(ieee);
- symbol_type_index = must_parse_int(ieee);
- symbol_attribute_def = must_parse_int(ieee);
+ next_byte(&(ieee->h)); /* Skip prefix */
+ next_byte(&(ieee->h));
+ symbol_name_index = must_parse_int(&(ieee->h));
+ symbol_type_index = must_parse_int(&(ieee->h));
+ symbol_attribute_def = must_parse_int(&(ieee->h));
- parse_int(ieee,&value);
+ parse_int(&(ieee->h),&value);
}
break;
ieee_symbol_index_type symbol_ignore;
boolean pcrel_ignore;
unsigned int extra;
- next_byte(ieee);
- next_byte(ieee);
+ next_byte(&(ieee->h));
+ next_byte(&(ieee->h));
- symbol_name_index = must_parse_int(ieee);
+ symbol_name_index = must_parse_int(&(ieee->h));
parse_expression(ieee,
&symbol->symbol.value,
&symbol->symbol.section,
case ieee_weak_external_reference_enum:
{ bfd_vma size;
bfd_vma value ;
- next_byte(ieee);
+ next_byte(&(ieee->h));
/* Throw away the external reference index */
- (void)must_parse_int(ieee);
+ (void)must_parse_int(&(ieee->h));
/* Fetch the default size if not resolved */
- size = must_parse_int(ieee);
+ size = must_parse_int(&(ieee->h));
/* Fetch the defautlt value if available */
- if ( parse_int(ieee, &value) == false) {
+ if ( parse_int(&(ieee->h), &value) == false) {
value = 0;
}
/* This turns into a common */
break;
case ieee_external_reference_enum:
- next_byte(ieee);
- symbol = (ieee_symbol_type *)bfd_alloc(ieee->abfd, sizeof(ieee_symbol_type));
+ next_byte(&(ieee->h));
+ symbol = (ieee_symbol_type *)bfd_alloc(ieee->h.abfd, sizeof(ieee_symbol_type));
symbol_count++;
*prev_reference_ptr = symbol;
prev_reference_ptr = &symbol->next;
- symbol->index = must_parse_int(ieee);
+ symbol->index = must_parse_int(&(ieee->h));
symbol->symbol.the_bfd = abfd;
- symbol->symbol.name = read_id(ieee);
+ symbol->symbol.name = read_id(&(ieee->h));
symbol->symbol.udata = (PTR)NULL;
symbol->symbol.section = (asection *)NULL;
symbol->symbol.value = (bfd_vma)0;
bfd_byte section_type[3];
ieee_seek(abfd, offset);
while (true) {
- switch (this_byte(ieee)) {
+ switch (this_byte(&(ieee->h))) {
case ieee_section_type_enum:
{
unsigned int section_index ;
- next_byte(ieee);
- section_index = must_parse_int(ieee);
+ next_byte(&(ieee->h));
+ section_index = must_parse_int(&(ieee->h));
/* Fixme to be nice about a silly number of sections */
BFD_ASSERT(section_index < NSECTIONS);
ieee->section_table[section_index] = section;
section->flags = SEC_NO_FLAGS;
section->target_index = section_index;
- section_type[0] = this_byte_and_next(ieee);
+ section_type[0] = this_byte_and_next(&(ieee->h));
switch (section_type[0]) {
case 0xC3:
- section_type[1] = this_byte(ieee);
- section->flags = SEC_LOAD;
+ section_type[1] = this_byte(&(ieee->h));
+ section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
switch (section_type[1]) {
case 0xD0:
/* Normal code */
- next_byte(ieee);
+ next_byte(&(ieee->h));
section->flags |= SEC_LOAD | SEC_CODE;
break;
case 0xC4:
- next_byte(ieee);
+ next_byte(&(ieee->h));
section->flags |= SEC_LOAD | SEC_DATA;
/* Normal data */
break;
case 0xD2:
- next_byte(ieee);
+ next_byte(&(ieee->h));
/* Normal rom data */
section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
break;
break;
}
}
- section->name = read_id(ieee);
+ section->name = read_id(&(ieee->h));
{ bfd_vma parent, brother, context;
- parse_int(ieee, &parent);
- parse_int(ieee, &brother);
- parse_int(ieee, &context);
+ parse_int(&(ieee->h), &parent);
+ parse_int(&(ieee->h), &brother);
+ parse_int(&(ieee->h), &context);
}
{
unsigned int section_index;
bfd_vma value;
- next_byte(ieee);
- section_index = must_parse_int(ieee);
+ next_byte(&(ieee->h));
+ section_index = must_parse_int(&ieee->h);
if (section_index > ieee->section_count) {
ieee->section_count = section_index;
}
ieee->section_table[section_index]->alignment_power =
- bfd_log2(must_parse_int(ieee));
- (void)parse_int(ieee, & value);
+ bfd_log2(must_parse_int(&ieee->h));
+ (void)parse_int(&(ieee->h), & value);
}
break;
case ieee_e2_first_byte_enum:
{
- ieee_record_enum_type t = read_2bytes(ieee);
+ ieee_record_enum_type t = read_2bytes(&(ieee->h));
switch (t) {
case ieee_section_size_enum:
- section = ieee->section_table[must_parse_int(ieee)];
- section->size = must_parse_int(ieee);
+ section = ieee->section_table[must_parse_int(&(ieee->h))];
+ section->size = must_parse_int(&(ieee->h));
break;
case ieee_physical_region_size_enum:
- section = ieee->section_table[must_parse_int(ieee)];
- section->size = must_parse_int(ieee);
+ section = ieee->section_table[must_parse_int(&(ieee->h))];
+ section->size = must_parse_int(&(ieee->h));
break;
case ieee_region_base_address_enum:
- section = ieee->section_table[must_parse_int(ieee)];
- section->vma = must_parse_int(ieee);
+ section = ieee->section_table[must_parse_int(&(ieee->h))];
+ section->vma = must_parse_int(&(ieee->h));
break;
case ieee_mau_size_enum:
- must_parse_int(ieee);
- must_parse_int(ieee);
+ must_parse_int(&(ieee->h));
+ must_parse_int(&(ieee->h));
break;
case ieee_m_value_enum:
- must_parse_int(ieee);
- must_parse_int(ieee);
+ must_parse_int(&(ieee->h));
+ must_parse_int(&(ieee->h));
break;
case ieee_section_base_address_enum:
- section = ieee->section_table[must_parse_int(ieee)];
- section->vma = must_parse_int(ieee);
+ section = ieee->section_table[must_parse_int(&(ieee->h))];
+ section->vma = must_parse_int(&(ieee->h));
break;
case ieee_section_offset_enum:
- (void) must_parse_int(ieee);
- (void) must_parse_int(ieee);
+ (void) must_parse_int(&(ieee->h));
+ (void) must_parse_int(&(ieee->h));
break;
default:
return;
DEFUN(ieee_archive_p,(abfd),
bfd *abfd)
{
- return 0;
-#if 0
char *library;
boolean loop;
- ieee_ar_data_type *ar;
+
unsigned int i;
+uint8e_type buffer[512];
+ int buffer_i = 0;
+ int buffer_offset = 0;
+ ieee_ar_data_type *save = ieee_ar_data(abfd);
+ ieee_ar_data_type *ieee ;
+ set_tdata(abfd, bfd_alloc(abfd, sizeof(ieee_ar_data_type)));
+ ieee= ieee_ar_data(abfd);
+
+
+ bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
-/* FIXME */
- ieee_seek(abfd, (file_ptr) 0);
- if (this_byte(abfd) != Module_Beginning) return (bfd_target*)NULL;
- next_byte(ieee);
- library= read_id(ieee);
+ ieee->h.abfd = abfd;
+
+ if (this_byte(&(ieee->h)) != Module_Beginning) return (bfd_target*)NULL;
+
+ next_byte(&(ieee->h));
+ library= read_id(&(ieee->h));
if (strcmp(library , "LIBRARY") != 0) {
- free(library);
+ bfd_release(abfd, ieee);
+ ieee_ar_data(abfd)= save;
return (bfd_target *)NULL;
}
/* Throw away the filename */
- free( read_id(ieee));
+ free( read_id(&(ieee->h)));
/* This must be an IEEE archive, so we'll buy some space to do
things */
- ar = (ieee_ar_data_type *) malloc(sizeof(ieee_ar_data_type));
- set_tdata (abfd, ar);
- ar->element_count = 0;
- ar->element_index = 0;
- obstack_init(&ar->element_obstack);
+ ieee->element_count = 0;
+ ieee->element_index = 0;
- next_byte(ieee); /* Drop the ad part */
- must_parse_int(ieee); /* And the two dummy numbers */
- must_parse_int(ieee);
+ next_byte(&(ieee->h)); /* Drop the ad part */
+ must_parse_int(&(ieee->h)); /* And the two dummy numbers */
+ must_parse_int(&(ieee->h));
loop = true;
/* Read the index of the BB table */
while (loop) {
ieee_ar_obstack_type t;
- int rec =read_2bytes(abfd);
+ int rec =read_2bytes(&(ieee->h));
if (rec ==ieee_assign_value_to_variable_enum) {
- int record_number = must_parse_int(ieee);
- t.file_offset = must_parse_int(ieee);
+ int record_number = must_parse_int(&(ieee->h));
+ t.file_offset = must_parse_int(&(ieee->h));
t.abfd = (bfd *)NULL;
- ar->element_count++;
- obstack_grow(&ar->element_obstack, (PTR)&t, sizeof(t));
+ ieee->element_count++;
+ bfd_alloc_grow(abfd, (PTR)&t, sizeof(t));
+
+ /* Make sure that we don't go over the end of the buffer */
+
+ if (ieee_pos(abfd) > sizeof(buffer)/2) {
+ /* Past half way, reseek and reprime */
+ buffer_offset += ieee_pos(abfd);
+ bfd_seek(abfd, buffer_offset, SEEK_SET);
+ bfd_read(buffer, 1, sizeof(buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+ }
}
else loop = false;
}
- ar->elements = (ieee_ar_obstack_type *)obstack_base(&ar->element_obstack);
+
+ ieee->elements = (ieee_ar_obstack_type *)bfd_alloc_finish(abfd);
/* Now scan the area again, and replace BB offsets with file */
/* offsets */
- for (i = 2; i < ar->element_count; i++) {
- ieee_seek(abfd, ar->elements[i].file_offset);
- next_byte(ieee); /* Drop F8 */
- next_byte(ieee); /* Drop 14 */
- must_parse_int(ieee); /* Drop size of block */
- if (must_parse_int(ieee) != 0) {
+ for (i = 2; i < ieee->element_count; i++) {
+ bfd_seek(abfd, ieee->elements[i].file_offset, SEEK_SET);
+ bfd_read(buffer, 1, sizeof(buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+
+ next_byte(&(ieee->h)); /* Drop F8 */
+ next_byte(&(ieee->h)); /* Drop 14 */
+ must_parse_int(&(ieee->h)); /* Drop size of block */
+ if (must_parse_int(&(ieee->h)) != 0) {
/* This object has been deleted */
- ar->elements[i].file_offset = 0;
+ ieee->elements[i].file_offset = 0;
}
else {
- ar->elements[i].file_offset = must_parse_int(ieee);
+ ieee->elements[i].file_offset = must_parse_int(&(ieee->h));
}
}
- obstack_finish(&ar->element_obstack);
return abfd->xvec;
-#endif
+
}
static boolean
DEFUN(ieee_mkobject,(abfd),
bfd *abfd)
-{
- set_tdata (abfd, bfd_alloc(abfd,sizeof(ieee_data_type)));
+{
+ set_tdata (abfd, bfd_zalloc(abfd,sizeof(ieee_data_type)));
+
+
return true;
}
/* Read the first few bytes in to see if it makes sense */
bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
- ieee->input_p = buffer;
- if (this_byte_and_next(ieee) != Module_Beginning) goto fail;
+ ieee->h.input_p = buffer;
+ if (this_byte_and_next(&(ieee->h)) != Module_Beginning) goto fail;
ieee->read_symbols= false;
ieee->read_data= false;
ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
ieee->external_reference_min_index =IEEE_REFERENCE_BASE;
ieee->external_reference_max_index = 0;
- ieee->abfd = abfd;
+ ieee->h.abfd = abfd;
memset((PTR)ieee->section_table, 0, sizeof(ieee->section_table));
- processor = ieee->mb.processor = read_id(ieee);
+ processor = ieee->mb.processor = read_id(&(ieee->h));
if (strcmp(processor,"LIBRARY") == 0) goto fail;
- ieee->mb.module_name = read_id(ieee);
+ ieee->mb.module_name = read_id(&(ieee->h));
if (abfd->filename == (char *)NULL) {
abfd->filename = ieee->mb.module_name;
}
/* Determine the architecture and machine type of the object file. */
bfd_scan_arch_mach(processor, &abfd->obj_arch, &abfd->obj_machine);
- if (this_byte(ieee) != ieee_address_descriptor_enum) {
+ if (this_byte(&(ieee->h)) != ieee_address_descriptor_enum) {
goto fail;
}
- next_byte(ieee);
+ next_byte(&(ieee->h));
- if (parse_int(ieee, &ieee->ad.number_of_bits_mau) == false) {
+ if (parse_int(&(ieee->h), &ieee->ad.number_of_bits_mau) == false) {
goto fail;
}
- if(parse_int(ieee, &ieee->ad.number_of_maus_in_address) == false) {
+ if(parse_int(&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) {
goto fail;
}
/* If there is a byte order info, take it */
- if (this_byte(ieee) == ieee_variable_L_enum ||
- this_byte(ieee) == ieee_variable_M_enum)
- next_byte(ieee);
+ if (this_byte(&(ieee->h)) == ieee_variable_L_enum ||
+ this_byte(&(ieee->h)) == ieee_variable_M_enum)
+ next_byte(&(ieee->h));
for (part = 0; part < N_W_VARIABLES; part++) {
boolean ok;
- if (read_2bytes(ieee) != ieee_assign_value_to_variable_enum) {
+ if (read_2bytes(&(ieee->h)) != ieee_assign_value_to_variable_enum) {
goto fail;
}
- if (this_byte_and_next(ieee) != part) {
+ if (this_byte_and_next(&(ieee->h)) != part) {
goto fail;
}
- ieee->w.offset[part] = parse_i(ieee, &ok);
+ ieee->w.offset[part] = parse_i(&(ieee->h), &ok);
if (ok==false) {
goto fail;
}
quickly. We can work out how big the file is from the trailer
record */
- ieee_data(abfd)->first_byte = (uint8e_type *) bfd_alloc(ieee->abfd, ieee->w.r.me_record
+ ieee_data(abfd)->h.first_byte = (uint8e_type *) bfd_alloc(ieee->h.abfd, ieee->w.r.me_record
+ 50);
bfd_seek(abfd, 0, 0);
- bfd_read((PTR)(ieee_data(abfd)->first_byte), 1, ieee->w.r.me_record+50, abfd);
+ bfd_read((PTR)(ieee_data(abfd)->h.first_byte), 1, ieee->w.r.me_record+50, abfd);
ieee_slurp_sections(abfd);
return abfd->xvec;
uint8e_type *location_ptr AND
asection *s)
{
- switch (this_byte(ieee))
+ switch (this_byte(&(ieee->h)))
{
case ieee_load_constant_bytes_enum:
{
unsigned int number_of_maus;
unsigned int i;
- next_byte(ieee);
- number_of_maus = must_parse_int(ieee);
+ next_byte(&(ieee->h));
+ number_of_maus = must_parse_int(&(ieee->h));
for (i = 0; i < number_of_maus; i++) {
- location_ptr[current_map->pc++]= this_byte(ieee);
- next_byte(ieee);
+ location_ptr[current_map->pc++]= this_byte(&(ieee->h));
+ next_byte(&(ieee->h));
}
}
break;
case ieee_load_with_relocation_enum:
{
boolean loop = true;
- next_byte(ieee);
+ next_byte(&(ieee->h));
while (loop)
{
- switch (this_byte(ieee))
+ switch (this_byte(&(ieee->h)))
{
case ieee_variable_R_enum:
boolean pcrel = false;
ieee_reloc_type *r =
- (ieee_reloc_type *) bfd_alloc(ieee->abfd,
+ (ieee_reloc_type *) bfd_alloc(ieee->h.abfd,
sizeof(ieee_reloc_type));
*(current_map->reloc_tail_ptr) = r;
current_map->reloc_tail_ptr= &r->next;
r->next = (ieee_reloc_type *)NULL;
- next_byte(ieee);
+ next_byte(&(ieee->h));
parse_expression(ieee,
&r->relent.addend,
&r->relent.section,
&pcrel, &extra);
r->relent.address = current_map->pc;
s->reloc_count++;
- switch (this_byte(ieee)) {
+ switch (this_byte(&(ieee->h))) {
case ieee_function_signed_close_b_enum:
- next_byte(ieee);
+ next_byte(&(ieee->h));
break;
case ieee_function_unsigned_close_b_enum:
- next_byte(ieee);
+ next_byte(&(ieee->h));
break;
case ieee_function_either_close_b_enum:
- next_byte(ieee);
+ next_byte(&(ieee->h));
break;
default:
break;
}
/* Build a relocation entry for this type */
- if (this_byte(ieee) == ieee_comma) {
- next_byte(ieee);
+ if (this_byte(&(ieee->h)) == ieee_comma) {
+ next_byte(&(ieee->h));
/* Fetch number of bytes to pad */
- extra = must_parse_int(ieee);
+ extra = must_parse_int(&(ieee->h));
};
/* If pc rel then stick -ve pc into instruction
case 4:
if (pcrel == true)
{
- bfd_put_32(ieee->abfd, -current_map->pc, location_ptr +
+ bfd_put_32(ieee->h.abfd, -current_map->pc, location_ptr +
current_map->pc);
r->relent.howto = &rel32_howto;
r->relent.addend -= current_map->pc;
}
else
{
- bfd_put_32(ieee->abfd, 0, location_ptr +
+ bfd_put_32(ieee->h.abfd, 0, location_ptr +
current_map->pc);
r->relent.howto = &abs32_howto;
}
break;
case 2:
if (pcrel == true) {
- bfd_put_16(ieee->abfd, (int)(-current_map->pc), location_ptr +current_map->pc);
+ bfd_put_16(ieee->h.abfd, (int)(-current_map->pc), location_ptr +current_map->pc);
r->relent.addend -= current_map->pc;
r->relent.howto = &rel16_howto;
}
else {
- bfd_put_16(ieee->abfd, 0, location_ptr +current_map->pc);
+ bfd_put_16(ieee->h.abfd, 0, location_ptr +current_map->pc);
r->relent.howto = &abs16_howto;
}
current_map->pc +=2;
default:
{
bfd_vma this_size ;
- if (parse_int(ieee, &this_size) == true) {
+ if (parse_int(&(ieee->h), &this_size) == true) {
unsigned int i;
for (i = 0; i < this_size; i++) {
- location_ptr[current_map->pc ++] = this_byte(ieee);
- next_byte(ieee);
+ location_ptr[current_map->pc ++] = this_byte(&(ieee->h));
+ next_byte(&(ieee->h));
}
}
else {
}
}
- /* Read in all the section data and relocation stuff too */
+/* Read in all the section data and relocation stuff too */
static boolean
DEFUN(ieee_slurp_section_data,(abfd),
bfd *abfd)
for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
- per->data = (bfd_byte *) bfd_alloc(ieee->abfd, s->size);
+ per->data = (bfd_byte *) bfd_alloc(ieee->h.abfd, s->size);
/*SUPPRESS 68*/
per->reloc_tail_ptr =
(ieee_reloc_type **)&(s->relocation);
while (true) {
- switch (this_byte(ieee))
+ switch (this_byte(&(ieee->h)))
{
/* IF we see anything strange then quit */
default:
return true;
case ieee_set_current_section_enum:
- next_byte(ieee);
- section_number = must_parse_int(ieee);
+ next_byte(&(ieee->h));
+ section_number = must_parse_int(&(ieee->h));
s = ieee->section_table[section_number];
current_map = (ieee_per_section_type *) s->used_by_bfd;
location_ptr = current_map->data - s->vma;
case ieee_e2_first_byte_enum:
- next_byte(ieee);
- switch (this_byte(ieee))
+ next_byte(&(ieee->h));
+ switch (this_byte(&(ieee->h)))
{
case ieee_set_current_pc_enum & 0xff:
{
ieee_symbol_index_type symbol;
unsigned int extra;
boolean pcrel;
- next_byte(ieee);
- must_parse_int(ieee); /* Thow away section #*/
+ next_byte(&(ieee->h));
+ must_parse_int(&(ieee->h)); /* Thow away section #*/
parse_expression(ieee, &value, &dsection, &symbol,
&pcrel, &extra);
current_map->pc = value;
{
/* Repeat the following LD or LR n times - we do this by
remembering the stream pointer before running it and
- resetting it and running it n times
+ resetting it and running it n times. We special case
+ the repetition of a repeat_data/load_constant
*/
unsigned int iterations ;
uint8e_type *start ;
- next_byte(ieee);
- iterations = must_parse_int(ieee);
- start = ieee->input_p;
- while (iterations != 0) {
- ieee->input_p = start;
- do_one(ieee, current_map, location_ptr,s);
- iterations --;
+ next_byte(&(ieee->h));
+ iterations = must_parse_int(&(ieee->h));
+ start = ieee->h.input_p;
+ if (start[0] == ieee_load_constant_bytes_enum &&
+ start[1] == 1) {
+ while (iterations != 0) {
+ location_ptr[current_map->pc++] = start[2];
+ iterations--;
+ }
+ next_byte(&(ieee->h));
+ next_byte(&(ieee->h));
+ next_byte(&(ieee->h));
+ }
+ else {
+ while (iterations != 0) {
+ ieee->h.input_p = start;
+ do_one(ieee, current_map, location_ptr,s);
+ iterations --;
+ }
}
}
break;
ieee_write_byte(abfd, ieee_section_type_enum);
ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
- switch (s->flags & (SEC_LOAD | SEC_CODE | SEC_DATA | SEC_ROM)) {
- case SEC_LOAD | SEC_CODE:
- /* Normal named section, code */
- ieee_write_byte(abfd, ieee_variable_C_enum);
- ieee_write_byte(abfd, ieee_variable_P_enum);
- break;
- case SEC_LOAD | SEC_DATA:
- /* Normal named section, data */
- ieee_write_byte(abfd, ieee_variable_C_enum);
- ieee_write_byte(abfd, ieee_variable_D_enum);
- break;
- case SEC_LOAD | SEC_DATA | SEC_ROM:
- /* Normal named section, data rom */
- ieee_write_byte(abfd, ieee_variable_C_enum);
- ieee_write_byte(abfd, ieee_variable_R_enum);
- break;
- default:
- ieee_write_byte(abfd, ieee_variable_C_enum);
- break;
- }
+ if (abfd->flags & EXEC_P)
+ {
+ /* This image is executable, so output absolute sections */
+ ieee_write_byte(abfd, ieee_variable_A_enum);
+ ieee_write_byte(abfd, ieee_variable_S_enum);
+ }
+ else
+ {
+ ieee_write_byte(abfd, ieee_variable_C_enum);
+ }
+
+ switch (s->flags &(SEC_CODE | SEC_DATA | SEC_ROM))
+ {
+ case SEC_CODE | SEC_LOAD:
+ case SEC_CODE:
+ ieee_write_byte(abfd, ieee_variable_P_enum);
+ break;
+ case SEC_DATA:
+ default:
+ ieee_write_byte(abfd, ieee_variable_D_enum);
+ break;
+ case SEC_ROM:
+ case SEC_ROM | SEC_DATA:
+ case SEC_ROM | SEC_LOAD:
+ case SEC_ROM | SEC_DATA | SEC_LOAD:
+
+ ieee_write_byte(abfd, ieee_variable_R_enum);
+ }
+
ieee_write_id(abfd, s->name);
+#if 0
ieee_write_int(abfd, 0); /* Parent */
ieee_write_int(abfd, 0); /* Brother */
ieee_write_int(abfd, 0); /* Context */
-
+#endif
/* Alignment */
ieee_write_byte(abfd, ieee_section_alignment_enum);
ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
ieee_write_int(abfd, s->size);
/* Vma */
- ieee_write_2bytes(abfd, ieee_region_base_address_enum);
+ ieee_write_2bytes(abfd, ieee_section_base_address_enum);
ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
ieee_write_int(abfd, s->vma);
-/* write the data in an ieee way */
-static void
-DEFUN(ieee_write_data_part,(abfd),
- bfd *abfd)
+static void
+DEFUN(do_with_relocs,(abfd, s),
+ bfd *abfd AND
+ asection *s)
{
- asection *s;
- ieee_data_type *ieee = ieee_data(abfd);
- ieee->w.r.data_part = bfd_tell(abfd);
- for (s = abfd->sections; s != (asection *)NULL; s = s->next)
+ unsigned int relocs_to_go = s->reloc_count;
+ bfd_byte header[11];
+
+ bfd_byte *stream = ieee_per_section(s)->data;
+ arelent **p = s->orelocation;
+
+ bfd_size_type current_byte_index = 0;
+
+ qsort(s->orelocation,
+ relocs_to_go,
+ sizeof(arelent **),
+ comp);
+
+
+
+ /* Output the section preheader */
+ header[0] =ieee_set_current_section_enum;
+ header[1] = s->index + IEEE_SECTION_NUMBER_BASE;
+
+ header[2] = ieee_set_current_pc_enum >> 8;
+ header[3]= ieee_set_current_pc_enum & 0xff;
+ header[4] = s->index + IEEE_SECTION_NUMBER_BASE;
+ ieee_write_int5(header+5, s->vma );
+ header[10] = ieee_load_with_relocation_enum;
+ bfd_write((PTR)header, 1, sizeof(header), abfd);
+
+ /* Output the data stream as the longest sequence of bytes
+ possible, allowing for the a reasonable packet size and
+ relocation stuffs */
+
+ if ((PTR)stream == (PTR)NULL) {
+ /* Outputting a section without data, fill it up */
+ stream = (uint8e_type *)(bfd_alloc(abfd, s->size));
+ memset((PTR)stream, 0, s->size);
+ }
+ while (current_byte_index < s->size) {
+ bfd_size_type run;
+ unsigned int MAXRUN = 32;
+ if (relocs_to_go) {
+ run = (*p)->address - current_byte_index;
+ }
+ else {
+ run = MAXRUN;
+ }
+ if (run > s->size - current_byte_index) {
+ run = s->size - current_byte_index;
+ }
+
+ if (run != 0) {
+ /* Output a stream of bytes */
+ ieee_write_int(abfd, run);
+ bfd_write((PTR)(stream + current_byte_index),
+ 1,
+ run,
+ abfd);
+ current_byte_index += run;
+ }
+ /* Output any relocations here */
+ if (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
+ while (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
+
+ arelent *r = *p;
+ bfd_vma ov;
+ if (r->howto->pc_relative) {
+ r->addend += current_byte_index;
+ }
+
+ switch (r->howto->size) {
+ case 2:
+
+ ov = bfd_get_32(abfd,
+ stream+current_byte_index);
+ current_byte_index +=4;
+ break;
+ case 1:
+ ov = bfd_get_16(abfd,
+ stream+current_byte_index);
+ current_byte_index +=2;
+ break;
+ default:
+ BFD_FAIL();
+ }
+ ieee_write_byte(abfd, ieee_function_either_open_b_enum);
+
+ if (r->sym_ptr_ptr != (asymbol **)NULL) {
+ ieee_write_expression(abfd, r->addend + ov,
+ r->section,
+ *(r->sym_ptr_ptr),
+ r->howto->pc_relative, s->target_index);
+ }
+ else {
+ ieee_write_expression(abfd, r->addend + ov,
+ r->section,
+ (asymbol *)NULL,
+ r->howto->pc_relative, s->target_index);
+ }
+ ieee_write_byte(abfd,
+ ieee_function_either_close_b_enum);
+ if (r->howto->size != 2) {
+ ieee_write_byte(abfd, ieee_comma);
+ ieee_write_int(abfd, 1<< r->howto->size);
+ }
+
+ relocs_to_go --;
+ p++;
+ }
+
+ }
+ }
+}
+
+/* If there are no relocations in the output section then we can
+be clever about how we write. We block items up into a max of 127
+bytes */
+
+static void
+DEFUN(do_as_repeat, (abfd, s),
+ bfd *abfd AND
+ asection *s)
+{
+ ieee_write_byte(abfd, ieee_set_current_section_enum);
+ ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
+ ieee_write_byte(abfd, ieee_set_current_pc_enum >> 8);
+ ieee_write_byte(abfd, ieee_set_current_pc_enum & 0xff);
+ ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
+ ieee_write_int(abfd, s->vma );
+
+ ieee_write_byte(abfd,ieee_repeat_data_enum);
+ ieee_write_int(abfd, s->size);
+ ieee_write_byte(abfd, ieee_load_constant_bytes_enum);
+ ieee_write_byte(abfd, 1);
+ ieee_write_byte(abfd, 0);
+}
+
+static void
+DEFUN(do_without_relocs, (abfd, s),
+ bfd *abfd AND
+ asection *s)
+{
+ bfd_byte *stream = ieee_per_section(s)->data;
+
+ if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
{
- bfd_byte header[11];
- bfd_byte *stream = ieee_per_section(s)->data;
- arelent **p = s->orelocation;
- unsigned int relocs_to_go = s->reloc_count;
- bfd_size_type current_byte_index = 0;
+ do_as_repeat(abfd, s);
+ }
+ else
+ {
+ unsigned int i;
+ for (i = 0; i < s->size; i++) {
+ if (stream[i] != 0) {
+ do_with_relocs(abfd, s);
+ return;
+ }
+ }
+ do_as_repeat(abfd, s);
+ }
+
+}
- /* Sort the reloc records so we can insert them in the correct
- places */
- if (s->reloc_count != 0) {
- qsort(s->orelocation,
- relocs_to_go,
- sizeof(arelent **),
- comp);
+
+static unsigned char *output_ptr_start;
+static unsigned char *output_ptr;
+static unsigned char *output_ptr_end;
+static unsigned char *input_ptr_start;
+static unsigned char *input_ptr;
+static unsigned char *input_ptr_end;
+static bfd *input_bfd;
+static bfd *output_bfd;
+static int output_buffer;
+
+static void fill()
+{
+ bfd_read(input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
+ input_ptr = input_ptr_start;
+}
+static void flush()
+{
+ bfd_write(output_ptr_start,1,output_ptr - output_ptr_start, output_bfd);
+ output_ptr = output_ptr_start;
+ output_buffer++;
+}
+
+#define THIS() ( *input_ptr )
+#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
+#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); }
+
+static void write_int(value)
+int value;
+{
+ if (value >= 0 && value <= 127) {
+ OUT(value);
+ }
+ else {
+ unsigned int length;
+ /* How many significant bytes ? */
+ /* FIXME FOR LONGER INTS */
+ if (value & 0xff000000) {
+ length = 4;
+ }
+ else if (value & 0x00ff0000) {
+ length = 3;
+ }
+ else if (value & 0x0000ff00) {
+ length = 2;
+ }
+ else length = 1;
+
+ OUT((int)ieee_number_repeat_start_enum + length);
+ switch (length) {
+ case 4:
+ OUT( value >> 24);
+ case 3:
+ OUT( value >> 16);
+ case 2:
+ OUT( value >> 8);
+ case 1:
+ OUT( value);
+ }
+
+ }
+}
+static void copy_id()
+{
+ int length = THIS();
+ char ch;
+ OUT(length);
+ NEXT();
+ while (length--) {
+ ch = THIS();
+ OUT(ch);
+ NEXT();
+ }
+}
+#define VAR(x) ((x | 0x80))
+static void copy_expression()
+{
+ int stack[10];
+ int *tos = stack;
+ int value = 0;
+ while (1) {
+ switch (THIS()) {
+ case 0x84:
+ NEXT();
+ value = THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ *tos ++ = value;
+ break;
+ case 0x83:
+ NEXT();
+ value = THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ *tos ++ = value;
+ break;
+ case 0x82:
+ NEXT();
+ value = THIS(); NEXT();
+ value = (value << 8) | THIS(); NEXT();
+ *tos ++ = value;
+ break;
+ case 0x81:
+ NEXT();
+ value = THIS(); NEXT();
+ *tos ++ = value;
+ break;
+ case 0x80:
+ NEXT();
+ *tos ++ = 0;
+ break;
+ default:
+ if (THIS() >0x84) {
+ /* Not a number, just bug out with the answer */
+ write_int(*(--tos));
+ return;
+ }
+ *tos++ = THIS();
+NEXT();
+ value = 0;
+ break;
+ case 0xa5:
+ /* PLUS anything */
+ {
+ int value = *(--tos);
+ value += *(--tos);
+ *tos++ = value;
+ NEXT();
}
+ break;
+ case VAR('R') :
+ {
+ int section_number ;
+ ieee_data_type *ieee;
+ asection *s;
+ NEXT();
+ section_number = THIS();
+
+ NEXT();
+ ieee= ieee_data(input_bfd);
+ s = ieee->section_table[section_number];
+ if (s->output_section) {
+ value = s->output_section->vma ;
+ } else { value = 0; }
+ value += s->output_offset;
+ *tos++ = value;
+ value = 0;
+ }
+ break;
+ case 0x90:
+ {
+ NEXT();
+ write_int(*(--tos));
+ OUT(0x90);
+ return;
+ }
+ }
+ }
+
+}
- /* Output the section preheader */
- header[0] =ieee_set_current_section_enum;
- header[1] = s->index + IEEE_SECTION_NUMBER_BASE;
+/* Drop the int in the buffer, and copy a null into the gap, which we
+ will overwrite later */
- header[2] = ieee_set_current_pc_enum >> 8;
- header[3]= ieee_set_current_pc_enum & 0xff;
- header[4] = s->index + IEEE_SECTION_NUMBER_BASE;
- ieee_write_int5(header+5, s->vma );
- header[10] = ieee_load_with_relocation_enum;
- bfd_write((PTR)header, 1, sizeof(header), abfd);
+struct output_buffer_struct {
+unsigned char *ptrp;
+ int buffer;
+} ;
- /* Output the data stream as the longest sequence of bytes
- possible, allowing for the a reasonable packet size and
- relocation stuffs */
+static void
+DEFUN(fill_int,(buf),
+ struct output_buffer_struct *buf)
+{
+ if (buf->buffer == output_buffer) {
+ /* Still a chance to output the size */
+ int value = output_ptr - buf->ptrp + 3;
+ buf->ptrp[0] = value >> 24;
+ buf->ptrp[1] = value >> 16;
+ buf->ptrp[2] = value >> 8;
+ buf->ptrp[3] = value >> 0;
+ }
- if ((PTR)stream == (PTR)NULL) {
- /* Outputting a section without data, fill it up */
- stream = (uint8e_type *)(bfd_alloc(abfd, s->size));
- memset((PTR)stream, 0, s->size);
+}
+static void
+DEFUN(drop_int,(buf),
+ struct output_buffer_struct *buf)
+{
+ int type = THIS();
+ int ch;
+ if (type <= 0x84) {
+ NEXT();
+ switch(type) {
+ case 0x84: ch = THIS(); NEXT();
+ case 0x83: ch = THIS(); NEXT();
+ case 0x82: ch = THIS(); NEXT();
+ case 0x81: ch = THIS(); NEXT();
+ case 0x80: break;
+ }
+ }
+ OUT(0x84);
+ buf->ptrp = output_ptr;
+ buf->buffer = output_buffer;
+ OUT(0);OUT(0);OUT(0);OUT(0);
+}
+
+static void copy_int()
+{
+ int type = THIS();
+ int ch;
+ if (type <= 0x84) {
+ OUT(type);
+ NEXT();
+ switch(type) {
+ case 0x84: ch = THIS(); NEXT(); OUT(ch);
+ case 0x83: ch = THIS(); NEXT(); OUT(ch);
+ case 0x82: ch = THIS(); NEXT(); OUT(ch);
+ case 0x81: ch = THIS(); NEXT(); OUT(ch);
+ case 0x80: break;
+ }
+ }
+}
+
+#define ID copy_id()
+#define INT copy_int()
+#define EXP copy_expression()
+static void copy_till_end();
+#define INTn(q) copy_int()
+#define EXPn(q) copy_expression()
+static void f1_record()
+{
+ int ch;
+ /* ATN record */
+ NEXT();
+ ch = THIS();
+ switch (ch)
+ {
+ default:
+ OUT(0xf1); OUT(ch);
+ break;
+ case 0xc9:
+ NEXT();
+ OUT(0xf1); OUT(0xc9);
+ INT; INT; ch = THIS();
+ switch (ch)
+ {
+ case 0x16: NEXT();break;
+ case 0x01: NEXT();break;
+ case 0x00: NEXT(); INT; break;
+ case 0x03: NEXT(); INT; break;
+ case 0x13: EXPn(instruction address); break;
+ default:
+ break;
+ }
+ break;
+ case 0xd8:
+ /* EXternal ref */
+ NEXT();
+ OUT(0xf1); OUT(0xd8);
+ EXP ; EXP; EXP; EXP;
+ break;
+ case 0xce:
+ NEXT();
+ OUT(0xf1);OUT(0xce); INT; INT; ch = THIS(); INT;
+ switch (ch) {
+ case 0x01:
+ INT; INT; break;
+ case 0x02:
+ INT; break;
+ case 0x04:
+ EXPn(external function); break;
+ case 0x05:
+ break;
+ case 0x07: INTn(line number); INT;
+ case 0x08: break;
+ case 0x0a: INTn(locked register); INT; break;
+ case 0x3f: copy_till_end(); break;
+ case 0x3e: copy_till_end(); break;
+ case 0x40: copy_till_end(); break;
+ case 0x41: ID; break;
}
- while (current_byte_index < s->size) {
- bfd_size_type run;
- unsigned int MAXRUN = 32;
- if (relocs_to_go) {
- run = (*p)->address - current_byte_index;
- }
- else {
- run = MAXRUN;
+ }
+
+}
+static void f0_record()
+{
+ /* Attribute record */
+ NEXT();
+ OUT(0xf0);
+ INTn(Symbol name );
+ ID;
+}
+static void copy_till_end()
+{
+ int ch = THIS();
+ while (1) {
+ while (ch <= 0x80)
+ {
+ OUT(ch);
+ NEXT();
+ ch = THIS();
+ }
+ switch (ch) {
+ case 0x84:
+ OUT(THIS());
+ NEXT();
+ case 0x83:
+ OUT(THIS());
+ NEXT();
+ case 0x82:
+ OUT(THIS());
+ NEXT();
+ case 0x81:
+ OUT(THIS());
+ NEXT();
+ OUT(THIS());
+ NEXT();
+
+ ch = THIS();
+ break;
+ default:
+ return;
+ }
+ }
+
+}
+
+static void f2_record()
+{
+ int ch;
+ NEXT();
+ OUT(0xf2);
+ INT ;
+ NEXT();
+ OUT(0xce);
+ INT ;
+copy_till_end();
+}
+
+
+static void block();
+static void f8_record()
+{
+ int ch;
+ NEXT();
+ ch = THIS();
+ switch (ch)
+ {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ /* Unique typedefs for module */
+ /* GLobal typedefs */
+ /* High level module scope beginning */
+ {
+ struct output_buffer_struct ob;
+ NEXT();
+ OUT(0xf8); OUT(ch);
+ drop_int(&ob); ID ;
+
+ block();
+
+ NEXT();
+ fill_int(&ob);
+ OUT(0xf9);
}
- if (run > s->size - current_byte_index) {
- run = s->size - current_byte_index;
+ break;
+ case 0x04:
+ /* Global function */
+ {
+ struct output_buffer_struct ob;
+ NEXT();
+ OUT(0xf8); OUT(0x04);
+ drop_int(&ob); ID ; INTn(stack size); INTn(ret val);
+ EXPn(offset);
+
+ block();
+
+ NEXT();
+ OUT(0xf9);
+ EXPn(size of block);
+ fill_int(&ob);
}
+ break;
- if (run != 0) {
- /* Output a stream of bytes */
- ieee_write_int(abfd, run);
- bfd_write((PTR)(stream + current_byte_index),
- 1,
- run,
- abfd);
- current_byte_index += run;
+ case 0x05:
+ /* File name for source line numbers */
+ {
+ struct output_buffer_struct ob;
+ NEXT();
+ OUT(0xf8); OUT(0x05);
+ drop_int(&ob);
+ ID; INTn(year); INTn(month); INTn(day);
+ INTn(hour); INTn(monute); INTn(second);
+ block();
+ NEXT();
+ OUT(0xf9);
+ fill_int(&ob);
}
- /* Output any relocations here */
- if (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
- while (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
-
- arelent *r = *p;
- bfd_vma ov;
- if (r->howto->pc_relative) {
- r->addend += current_byte_index;
- }
+ break;
+
+ case 0x06:
+ /* Local function */
+ { struct output_buffer_struct ob;
+ NEXT(); OUT(0xf8); OUT(0x06);
+ drop_int(&ob);
+ ID; INTn(stack size); INTn(type return);
+ EXPn(offset);
+ block();
+ NEXT();
+ OUT(0xf9);
+ EXPn(size);
+ fill_int(&ob);
+ }
+ break;
+
+ case 0x0a:
+ /* Assembler module scope beginning -*/
+ { struct output_buffer_struct ob;
- switch (r->howto->size) {
- case 2:
+ NEXT();
+ OUT(0xf8); OUT(0x0a);
+ drop_int(&ob);
+ ID; ID; INT; ID; INT; INT; INT; INT; INT; INT;
- ov = bfd_get_32(abfd,
- stream+current_byte_index);
- current_byte_index +=4;
- break;
- case 1:
- ov = bfd_get_16(abfd,
- stream+current_byte_index);
- current_byte_index +=2;
- break;
- default:
- BFD_FAIL();
- }
- ieee_write_byte(abfd, ieee_function_either_open_b_enum);
+ block();
- if (r->sym_ptr_ptr != (asymbol **)NULL) {
- ieee_write_expression(abfd, r->addend + ov,
- r->section,
- *(r->sym_ptr_ptr),
- r->howto->pc_relative, s->target_index);
- }
- else {
- ieee_write_expression(abfd, r->addend + ov,
- r->section,
- (asymbol *)NULL,
- r->howto->pc_relative, s->target_index);
- }
- ieee_write_byte(abfd,
- ieee_function_either_close_b_enum);
- if (r->howto->size != 2) {
- ieee_write_byte(abfd, ieee_comma);
- ieee_write_int(abfd, 1<< r->howto->size);
- }
+ NEXT();
+ OUT(0xf9);
+ fill_int(&ob);
+ }
+ break;
+ case 0x0b:
+ {
+ struct output_buffer_struct ob;
+ NEXT();
+ OUT(0xf8); OUT(0x0b);
+ drop_int(&ob); ID ; INT; INTn(section index); EXPn(offset); INTn(stuff);
- relocs_to_go --;
- p++;
- }
+ block();
+ OUT(0xf9);
+ NEXT();
+ EXPn(Size in Maus);
+ fill_int(&ob);
}
- }
+ break;
}
+}
+static void e2_record()
+{
+ OUT(0xe2);
+ NEXT();
+ OUT(0xce);
+ NEXT();
+ INT;
+ EXP;
+}
+
+static void DEFUN_VOID(block)
+{
+ int ch ;
+ while (1) {
+ ch = THIS();
+ switch (ch) {
+ case 0xe1:
+ case 0xe5:
+ return;
+ case 0xf9:
+ return;
+ case 0xf0:
+ f0_record();
+ break;
+ case 0xf1:
+ f1_record();
+ break;
+ case 0xf2:
+ f2_record();
+ break;
+ case 0xf8:
+ f8_record();
+ break;
+ case 0xe2:
+ e2_record();
+ break;
+
+ }
+ }
+}
+
+
+
+/* relocate_debug,
+ moves all the debug information from the source bfd to the output
+ bfd, and relocates any expressions it finds
+*/
+
+static void
+DEFUN(relocate_debug,(output, input),
+ bfd *output AND
+ bfd *input)
+{
+#define IBS 400
+#define OBS 400
+ unsigned char input_buffer[IBS];
+
+ input_ptr_start = input_ptr = input_buffer;
+ input_ptr_end = input_buffer + IBS;
+ input_bfd = input;
+ bfd_read(input_ptr_start, 1, IBS, input);
+ block();
+}
+/*
+ During linking, we we told about the bfds which made up our
+ contents, we have a list of them. They will still be open, so go to
+ the debug info in each, and copy it out, relocating it as we go.
+*/
+
+static void
+DEFUN(ieee_write_debug_part, (abfd),
+ bfd *abfd)
+{
+ ieee_data_type *ieee = ieee_data(abfd);
+ bfd_chain_type *chain = ieee->chain_root;
+ unsigned char output_buffer[OBS];
+ output_ptr_start = output_ptr = output_buffer ;
+ output_ptr_end = output_buffer + OBS;
+ output_ptr = output_buffer;
+ output_bfd = abfd;
+ ieee->w.r.debug_information_part = bfd_tell(abfd);
+ while (chain != (bfd_chain_type *)NULL) {
+ bfd *entry = chain->this;
+ ieee_data_type *entry_ieee = ieee_data(entry);
+ if (entry_ieee->w.r.debug_information_part) {
+ bfd_seek(entry, entry_ieee->w.r.debug_information_part, SEEK_SET);
+ relocate_debug(abfd, entry);
+ }
+
+ chain = chain->next;
+ }
+
+ flush();
+
+}
+/* write the data in an ieee way */
+static void
+DEFUN(ieee_write_data_part,(abfd),
+ bfd *abfd)
+{
+ asection *s;
+ ieee_data_type *ieee = ieee_data(abfd);
+ ieee->w.r.data_part = bfd_tell(abfd);
+ for (s = abfd->sections; s != (asection *)NULL; s = s->next)
+ {
+ /* Sort the reloc records so we can insert them in the correct
+ places */
+ if (s->reloc_count != 0)
+ {
+ do_with_relocs(abfd, s);
+ }
+ else
+ {
+ do_without_relocs(abfd, s);
+ }
+ }
}
ieee_write_int(abfd, public_index);
if (p->section != (asection *)NULL)
{
- ieee_write_expression(abfd,
- p->value + p->section->output_offset,
- p->section->output_section,
- (asymbol *)NULL, false, 0);
+ if (abfd->flags & EXEC_P)
+ {
+ /* If fully linked, then output all symbols
+ relocated */
+ ieee_write_int(abfd,
+ p->value + p->section->output_offset+ p->section->output_section->vma);
+
+ }
+ else {
+ ieee_write_expression(abfd,
+ p->value + p->section->output_offset,
+ p->section->output_section,
+ (asymbol *)NULL, false, 0);
+ }
}
else
{
ieee_write_id(abfd, bfd_printable_arch_mach(abfd->obj_arch,
abfd->obj_machine));
ieee_write_id(abfd, abfd->filename);
+
+
+
+
+ /* Fast forward over the variable bits */
+
+
+
ieee_write_byte(abfd, ieee_address_descriptor_enum);
ieee_write_byte(abfd, 8); /* Bits per MAU */
ieee_write_byte(abfd, 4); /* MAU's per address */
- /* Fast forward over the variable bits */
old = bfd_tell(abfd);
bfd_seek(abfd, 8 * N_W_VARIABLES, 1);
+
+ ieee->w.r.extension_record = bfd_tell(abfd);
+ ieee->w.r.environmental_record = bfd_tell(abfd);
+ ieee_write_byte(abfd, 0xf0);
+ ieee_write_byte(abfd, 0x20);
+ ieee_write_byte(abfd, 0x00);
+ ieee_write_byte(abfd, 0xf1);
+ ieee_write_byte(abfd, 0xce);
+ ieee_write_byte(abfd, 0x20);
+ ieee_write_byte(abfd, 0x00);
+ ieee_write_byte(abfd, 0x55);
+ ieee_write_id(abfd,"built using BFD");
+
+
+
/*
First write the symbols, this changes their values into table
indeces so we cant use it after this point
ieee_write_section_part(abfd);
ieee_write_byte(abfd, ieee_record_seperator_enum);
+
+
+ /*
+ Write any debugs we have been told about
+ */
+ieee_write_debug_part(abfd);
+
/*
Can only write the data once the symbols have been written since
the data contains relocation information which points to the
}
static bfd *
-ieee_openr_next_archived_file(arch, prev)
-bfd *arch;
-bfd *prev;
+DEFUN(ieee_openr_next_archived_file,(arch, prev),
+ bfd *arch AND
+ bfd *prev)
{
ieee_ar_data_type *ar = ieee_ar_data(arch);
/* take the next one from the arch state, or reset */
}
}
else {
+ bfd_error = no_more_archived_files;
return (bfd *)NULL;
}
return 0;
}
+
+
+static void
+DEFUN(ieee_bfd_debug_info_start,(abfd),
+ bfd *abfd)
+ {
+
+ }
+
+static void
+DEFUN(ieee_bfd_debug_info_end,(abfd),
+ bfd *abfd)
+ {
+
+ }
+
+
+/* Add this section to the list of sections we have debug info for, to
+ be ready to output it at close time
+ */
+static void
+DEFUN(ieee_bfd_debug_info_accumulate,(abfd, section),
+ bfd *abfd AND
+ asection *section)
+{
+ ieee_data_type *ieee = ieee_data(section->owner);
+ ieee_data_type *output_ieee = ieee_data(abfd);
+ /* can only accumulate data from other ieee bfds */
+ if (section->owner->xvec != abfd->xvec)
+ return;
+ /* Only bother once per bfd */
+ if (ieee->done_debug == true)
+ return;
+ ieee->done_debug = true;
+
+ /* Don't bother if there is no debug info */
+ if (ieee->w.r.debug_information_part == 0)
+ return;
+
+
+ /* Add to chain */
+ {
+ bfd_chain_type *n = (bfd_chain_type *) bfd_alloc(abfd, sizeof(bfd_chain_type));
+ n->this = section->owner;
+ n->next = (bfd_chain_type *)NULL;
+
+ if (output_ieee->chain_head) {
+ output_ieee->chain_head->next = n;
+ }
+ else {
+ output_ieee->chain_root = n;
+
+ }
+ output_ieee->chain_head = n;
+ }
+}
+
+
+
+
+
+
+#define FOO PROTO
#define ieee_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
#define ieee_core_file_failing_signal (int (*)())bfd_0
-#define ieee_core_file_matches_executable_p ( PROTO(boolean, (*),(bfd *, bfd *)))bfd_false
+#define ieee_core_file_matches_executable_p ( FOO(boolean, (*),(bfd *, bfd *)))bfd_false
#define ieee_slurp_armap bfd_true
#define ieee_slurp_extended_name_table bfd_true
#define ieee_truncate_arname (void (*)())bfd_nullvoidptr
-#define ieee_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
+#define ieee_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
#define ieee_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
#define ieee_close_and_cleanup bfd_generic_close_and_cleanup
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
+ 1, /* minimum alignment */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
static
int DEFUN(real_read,(where, a,b, file),
- PTR where AND
- int a AND
- int b AND
- FILE *file)
+ PTR where AND
+ int a AND
+ int b AND
+ FILE *file)
{
return fread(where, a,b,file);
}
CONST file_ptr position AND
CONST int direction)
{
- /* For the time being, a bfd may not seek to it's end. The
- problem is that we don't easily have a way to recognize
- the end of an element in an archive. */
-
- BFD_ASSERT(direction == SEEK_SET
- || direction == SEEK_CUR);
-
- if (direction == SEEK_SET && abfd->my_archive != NULL)
- {
- /* This is a set within an archive, so we need to
- add the base of the object within the archive */
- return(fseek(bfd_cache_lookup(abfd),
- position + abfd->origin,
- direction));
- }
- else
- {
- return(fseek(bfd_cache_lookup(abfd), position, direction));
- }
+ /* For the time being, a bfd may not seek to it's end. The
+ problem is that we don't easily have a way to recognize
+ the end of an element in an archive. */
+
+ BFD_ASSERT(direction == SEEK_SET
+ || direction == SEEK_CUR);
+
+ if (direction == SEEK_SET && abfd->my_archive != NULL)
+ {
+ /* This is a set within an archive, so we need to
+ add the base of the object within the archive */
+ return(fseek(bfd_cache_lookup(abfd),
+ position + abfd->origin,
+ direction));
+ }
+ else
+ {
+ return(fseek(bfd_cache_lookup(abfd), position, direction));
+ }
}
long
DEFUN(bfd_tell,(abfd),
bfd *abfd)
{
- file_ptr ptr;
+ file_ptr ptr;
- ptr = ftell (bfd_cache_lookup(abfd));
+ ptr = ftell (bfd_cache_lookup(abfd));
- if (abfd->my_archive)
- ptr -= abfd->origin;
- return ptr;
+ if (abfd->my_archive)
+ ptr -= abfd->origin;
+ return ptr;
}
\f
/** Make a string table */
-/* Add string to table pointed to by table, at location starting with free_ptr.
+/*>bfd.h<
+ Add string to table pointed to by table, at location starting with free_ptr.
resizes the table if necessary (if it's NULL, creates it, ignoring
table_length). Updates free_ptr, table, table_length */
/* Avoid a useless regrow if we can (but of course we still
take it next time */
space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
- DEFAULT_STRING_SPACE_SIZE : string_length+1);
+ DEFAULT_STRING_SPACE_SIZE : string_length+1);
base = zalloc (space_length);
if (base == NULL) {
/* FIXME: Should these take a count argument?
Answer (gnu@cygnus.com): No, but perhaps they should be inline
- functions in swap.h #ifdef __GNUC__.
- Gprof them later and find out. */
+ functions in swap.h #ifdef __GNUC__.
+ Gprof them later and find out. */
+
+/*proto*
+*i bfd_put_size
+*i bfd_get_size
+These macros as used for reading and writing raw data in sections;
+each access (except for bytes) is vectored through the target format
+of the bfd and mangled accordingly. The mangling performs any
+necessary endian translations and removes alignment restrictions.
+*+
+#define bfd_put_8(abfd, val, ptr) \
+ (*((char *)ptr) = (char)val)
+#define bfd_get_8(abfd, ptr) \
+ (*((char *)ptr))
+#define bfd_put_16(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx16, (val,ptr))
+#define bfd_get_16(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_put_32(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx32, (val,ptr))
+#define bfd_get_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_put_64(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx64, (val, ptr))
+#define bfd_get_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx64, (ptr))
+*-
+*-*/
+
+/*proto*
+*i bfd_h_put_size
+*i bfd_h_get_size
+These macros have the same function as their @code{bfd_get_x}
+bretherin, except that they are used for removing information for the
+header records of object files. Believe it or not, some object files
+keep their header records in big endian order, and their data in little
+endan order.
+*+
+#define bfd_h_put_8(abfd, val, ptr) \
+ (*((char *)ptr) = (char)val)
+#define bfd_h_get_8(abfd, ptr) \
+ (*((char *)ptr))
+#define bfd_h_put_16(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+#define bfd_h_get_16(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx16,(ptr))
+#define bfd_h_put_32(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+#define bfd_h_get_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx32,(ptr))
+#define bfd_h_put_64(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+#define bfd_h_get_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx64,(ptr))
+*-
+*-*/
unsigned int
DEFUN(_do_getb16,(addr),
register bfd_byte *addr)
{
- return (addr[0] << 8) | addr[1];
+ return (addr[0] << 8) | addr[1];
}
unsigned int
DEFUN(_do_getl16,(addr),
register bfd_byte *addr)
{
- return (addr[1] << 8) | addr[0];
+ return (addr[1] << 8) | addr[0];
}
void
int data AND
register bfd_byte *addr)
{
- addr[0] = (bfd_byte)(data >> 8);
- addr[1] = (bfd_byte )data;
+ addr[0] = (bfd_byte)(data >> 8);
+ addr[1] = (bfd_byte )data;
}
void
DEFUN(_do_putl16,(data, addr),
- int data AND
+ int data AND
register bfd_byte *addr)
{
- addr[0] = (bfd_byte )data;
- addr[1] = (bfd_byte)(data >> 8);
+ addr[0] = (bfd_byte )data;
+ addr[1] = (bfd_byte)(data >> 8);
}
unsigned int
DEFUN(_do_getb32,(addr),
register bfd_byte *addr)
{
- return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
+ return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
}
unsigned int
_do_getl32 (addr)
- register bfd_byte *addr;
+ register bfd_byte *addr;
{
- return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
+ return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
}
bfd_64_type
bfd_64_type low, high;
high= ((((((((addr[0]) << 8) |
- addr[1]) << 8) |
- addr[2]) << 8) |
- addr[3]) );
+ addr[1]) << 8) |
+ addr[2]) << 8) |
+ addr[3]) );
low = ((((((((addr[4]) << 8) |
- addr[5]) << 8) |
- addr[6]) << 8) |
- addr[7]));
+ addr[5]) << 8) |
+ addr[6]) << 8) |
+ addr[7]));
return high << 32 | low;
#else
+ bfd_64_type foo;
BFD_FAIL();
+ return foo;
#endif
}
DEFUN(_do_getl64,(addr),
register bfd_byte *addr)
{
- bfd_64_type low, high;
+
#ifdef HOST_64_BIT
+ bfd_64_type low, high;
high= (((((((addr[7] << 8) |
- addr[6]) << 8) |
- addr[5]) << 8) |
- addr[4]));
+ addr[6]) << 8) |
+ addr[5]) << 8) |
+ addr[4]));
low = (((((((addr[3] << 8) |
- addr[2]) << 8) |
- addr[1]) << 8) |
- addr[0]) );
+ addr[2]) << 8) |
+ addr[1]) << 8) |
+ addr[0]) );
return high << 32 | low;
#else
+bfd_64_type foo;
BFD_FAIL();
+return foo;
#endif
+
}
void
unsigned long data AND
register bfd_byte *addr)
{
- addr[0] = (bfd_byte)(data >> 24);
- addr[1] = (bfd_byte)(data >> 16);
- addr[2] = (bfd_byte)(data >> 8);
- addr[3] = (bfd_byte)data;
+ addr[0] = (bfd_byte)(data >> 24);
+ addr[1] = (bfd_byte)(data >> 16);
+ addr[2] = (bfd_byte)(data >> 8);
+ addr[3] = (bfd_byte)data;
}
void
unsigned long data AND
register bfd_byte *addr)
{
- addr[0] = (bfd_byte)data;
- addr[1] = (bfd_byte)(data >> 8);
- addr[2] = (bfd_byte)(data >> 16);
- addr[3] = (bfd_byte)(data >> 24);
+ addr[0] = (bfd_byte)data;
+ addr[1] = (bfd_byte)(data >> 8);
+ addr[2] = (bfd_byte)(data >> 16);
+ addr[3] = (bfd_byte)(data >> 24);
}
void
DEFUN(_do_putb64,(data, addr),
- bfd_64_type data AND
- register bfd_byte *addr)
+ bfd_64_type data AND
+ register bfd_byte *addr)
{
#ifdef HOST_64_BIT
addr[0] = (bfd_byte)(data >> (7*8));
bfd_size_type count)
{
if (count == 0)
- return true;
+ return true;
if ((bfd_size_type)offset >= section->size
- || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
- || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
- return (false); /* on error */
+ || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
+ || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
+ return (false); /* on error */
return (true);
}
+
+/*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;
+}
PROTO(PTR, bfd_alloc, (bfd *abfd, bfd_size_type size));
PROTO(PTR, bfd_zalloc,(bfd *abfd, bfd_size_type size));
PROTO(PTR, bfd_realloc,(bfd *abfd, PTR orig, bfd_size_type new));
+PROTO(void, bfd_alloc_grow,(bfd *abfd, PTR thing, bfd_size_type size));
+PROTO(PTR, bfd_alloc_finish,(bfd *abfd));
+
#define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
-PROTO (bfd_target *, bfd_find_target, (CONST char *target_name, bfd *));
+
PROTO (bfd_size_type, bfd_read, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
PROTO (bfd_size_type, bfd_write, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
-PROTO (FILE *, bfd_cache_lookup, (bfd *));
-PROTO (void, bfd_cache_close, (bfd *));
+
+
PROTO (int, bfd_seek,(bfd* abfd, file_ptr fp , int direction));
PROTO (long, bfd_tell, (bfd *abfd));
PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd));
PROTO (FILE *, bfd_cache_lookup_worker, (bfd *));
extern bfd *bfd_last_cache;
-#define bfd_cache_lookup(x) \
- (x==bfd_last_cache?(FILE*)(bfd_last_cache->iostream):bfd_cache_lookup_worker(x))
/* Now Steve, what's the story here? */
#ifdef lint
/* Generic routine for close_and_cleanup is really just bfd_true. */
#define bfd_generic_close_and_cleanup bfd_true
+
+/* THE FOLLOWING IS EXTRACTED FROM THE SOURCE*/
+
+/* Return the log base 2 of the value supplied, rounded up. eg an arg
+of 1025 would return 11.
+*/
+PROTO(bfd_vma, bfd_log2,(bfd_vma x));
+/* The maxiumum number of files which the cache will keep open at one
+time.
+*/
+#define BFD_CACHE_MAX_OPEN 10
+
+/* Zero, or a pointer to the topmost bfd on the chain. This is used by the
+bfd_cache_lookup() macro in libbfd.h to determine when it can avoid a function
+call.
+*/
+extern bfd *bfd_last_cache;
+
+/* Checks to see if the required bfd is the same as the last one looked
+up. If so then it can use the iostream in the bfd with impunity, since
+it can't have changed since the last lookup, otherwise it has to
+perform the complicated lookup function
+*/
+#define bfd_cache_lookup(x) \
+ ((x)==bfd_last_cache? \
+ (FILE*)(bfd_last_cache->iostream): \
+ bfd_cache_lookup_worker(x))
+
+
+/* Initialize a BFD by putting it on the cache LRU.
+*/
+PROTO(void, bfd_cache_init, (bfd *));
+/* Remove the bfd from the cache. If the attatched file is open, then close it too.
+*/
+PROTO(void, bfd_cache_close, (bfd *));
+/* Call the OS to open a file for this BFD. Returns the FILE *
+(possibly null) that results from this operation. Sets up the
+BFD so that future accesses know the file is open. If the FILE *
+returned is null, then there is won't have been put in the cache, so
+it won't have to be removed from it.
+*/
+PROTO(FILE *, bfd_open_file, (bfd *));
+/* Called when the macro @code{bfd_cache_lookup} fails to find a quick
+answer. Finds a file descriptor for this BFD. If necessary, it open it.
+If there are already more than BFD_CACHE_MAX_OPEN files open, it trys to close
+one first, to avoid running out of file descriptors.
+*/
+PROTO(FILE *, bfd_cache_lookup_worker, (bfd *));
#include "bfd.h"
#include "libbfd.h"
#include "aout64.h"
+
+/**From: bothner@cs.wisc.edu***********************************************/
+#undef N_TXTOFF
+#define N_TXTOFF(x) ( (N_MAGIC((x)) == ZMAGIC) ? PAGE_SIZE : EXEC_BYTES_SIZE)
+/**************************************************************************/
+
#include "stab.gnu.h"
#include "ar.h"
#include "libaout.h" /* BFD a.out internal data structures */
-
+#if 0
int vfprintf(file, format, args) /* Temporary crock! */
FILE *file; char *format; char *args;
{
return _doprnt (format, args, file);
}
-
+#endif
bfd_target *newsos3_callback ();
DEFUN(newsos3_object_p,(abfd),
bfd *abfd)
{
- unsigned char magicbuf[LONG_SIZE]; /* Raw bytes of magic number from file */
+ unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
unsigned long magic; /* Swapped magic number */
bfd_error = system_call_error;
/* Transfer vectors for NEWS-OS version 3 */
/* We use BFD generic archive files. */
-#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
-#define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
-#define aout_32_slurp_armap bfd_slurp_bsd_armap
-#define aout_32_slurp_extended_name_table bfd_true
-#define aout_32_write_armap bsd_write_armap
-#define aout_32_truncate_arname bfd_bsd_truncate_arname
+#define newsos_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define newsos_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define newsos_slurp_armap bfd_slurp_bsd_armap
+#define newsos_slurp_extended_name_table bfd_true
+#define newsos_write_armap bsd_write_armap
+#define newsos_truncate_arname bfd_bsd_truncate_arname
/* We don't support core files yet. FIXME. */
-#define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
-#define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
-#define aout_32_core_file_matches_executable_p \
+#define newsos_core_file_failing_command _bfd_dummy_core_file_failing_command
+#define newsos_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define newsos_core_file_matches_executable_p \
_bfd_dummy_core_file_matches_executable_p
-#define aout_32_core_file_p _bfd_dummy_target
+#define newsos_core_file_p _bfd_dummy_target
+
+#define newsos_bfd_debug_info_start bfd_void
+#define newsos_bfd_debug_info_end bfd_void
+#define newsos_bfd_debug_info_accumulate bfd_void
+
+#define newsos_mkobject aout_32_mkobject
+#define newsos_close_and_cleanup aout_32_close_and_cleanup
+#define newsos_set_section_contents aout_32_set_section_contents
+#define newsos_get_section_contents aout_32_get_section_contents
+#define newsos_new_section_hook aout_32_new_section_hook
+#define newsos_get_symtab_upper_bound aout_32_get_symtab_upper_bound
+#define newsos_get_symtab aout_32_get_symtab
+#define newsos_get_reloc_upper_bound aout_32_get_reloc_upper_bound
+#define newsos_canonicalize_reloc aout_32_canonicalize_reloc
+#define newsos_make_empty_symbol aout_32_make_empty_symbol
+#define newsos_print_symbol aout_32_print_symbol
+#define newsos_get_lineno aout_32_get_lineno
+#define newsos_set_arch_mach aout_32_set_arch_mach
+#define newsos_find_nearest_line aout_32_find_nearest_line
+#define newsos_sizeof_headers aout_32_sizeof_headers
+
/* We define our own versions of these routines. */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
-
+ 1, /* minimum alignment */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
{_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */
- bfd_generic_archive_p, aout_32_core_file_p},
- {bfd_false, aout_32_mkobject, /* bfd_set_format */
+ bfd_generic_archive_p, newsos_core_file_p},
+ {bfd_false, newsos_mkobject, /* bfd_set_format */
_bfd_generic_mkarchive, bfd_false},
{bfd_false, newsos3_write_object_contents, /* bfd_write_contents */
_bfd_write_archive_contents, bfd_false},
- JUMP_TABLE(aout_32)
+ JUMP_TABLE(newsos)
};
#include "libbfd.h"
#include "oasys.h"
#include "liboasys.h"
+
+
+/* Read in all the section data and relocation stuff too */
+PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
+
static void
DEFUN(oasys_read_record,(abfd, record),
bfd *CONST abfd AND
if (record.header.type == oasys_record_is_local_enum)
{
dest->flags = BSF_LOCAL;
+ if (dest->section ==(asection *)(~0)) {
+ /* It seems that sometimes internal symbols are tied up, but
+ still get output, even though there is no
+ section */
+ dest->section = 0;
+ }
}
else {
oasys_module_table_type record;
- oasys_external_module_table_type record_ext;
+
set_tdata(abfd, ar);
ar->module = module;
filepos = header.mod_tbl_offset;
for (i = 0; i < header.mod_count; i++) {
bfd_seek(abfd , filepos, SEEK_SET);
- bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
+
+ /* There are two ways of specifying the archive header */
+
+ if (0) {
+ oasys_external_module_table_type_a_type record_ext;
+ bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
- record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
- record.file_offset = bfd_h_get_32(abfd,
- record_ext.file_offset);
+ 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.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);
+ module[i].name = bfd_alloc(abfd,33);
- module[i].name = bfd_alloc(abfd,33);
+ memcpy(module[i].name, record_ext.mod_name, 33);
+ filepos +=
+ sizeof(record_ext) +
+ record.dep_count * 4 +
+ record.depee_count * 4 +
+ 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;
- memcpy(module[i].name, record_ext.mod_name, 33);
- filepos +=
- sizeof(record_ext) +
- record.dep_count * 4 +
- record.depee_count * 4 +
- record.sect_count * 8 + 187,
+ }
module[i].size = record.mod_size;
s->size = bfd_h_get_32(abfd, & record.section.value[0]) ;
s->vma = bfd_h_get_32(abfd, &record.section.vma[0]);
- s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+ s->flags= 0;
had_usefull = true;
}
break;
if (abfd->symcount != 0) {
abfd->flags |= HAS_SYMS;
}
+
+ /*
+ We don't know if a section has data until we've read it..
+ */
+
+ oasys_slurp_section_data(abfd);
+
+
return abfd->xvec;
fail:
asection *s;
- /* Buy enough memory for all the section data and relocations */
+ /* See if the data has been slurped already .. */
for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
per = oasys_per_section(s);
- if (per->data != (bfd_byte*)NULL) return true;
- per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
- per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
- per->had_vma = false;
- s->reloc_count = 0;
+ if (per->initialized == true)
+ return true;
}
if (data->first_data_record == 0) return true;
+
bfd_seek(abfd, data->first_data_record, SEEK_SET);
while (loop) {
oasys_read_record(abfd, &record);
- switch (record.header.type) {
- case oasys_record_is_header_enum:
- break;
- case oasys_record_is_data_enum:
+ switch (record.header.type)
{
+ case oasys_record_is_header_enum:
+ break;
+ case oasys_record_is_data_enum:
+ {
+
+ uint8e_type *src = record.data.data;
+ uint8e_type *end_src = ((uint8e_type *)&record) +
+ record.header.length;
+ unsigned int relbit;
+ bfd_byte *dst_ptr ;
+ bfd_byte *dst_base_ptr ;
+ unsigned int count;
+ asection * section =
+ data->sections[record.data.relb & RELOCATION_SECT_BITS];
+ bfd_vma dst_offset ;
+ per = oasys_per_section(section);
+
+
+ if (per->initialized == false)
+ {
+ per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
+ per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
+ per->had_vma = false;
+ per->initialized = true;
+ section->reloc_count = 0;
+ section->flags = SEC_ALLOC;
+ }
- uint8e_type *src = record.data.data;
- uint8e_type *end_src = ((uint8e_type *)&record) +
- record.header.length;
- unsigned int relbit;
- bfd_byte *dst_ptr ;
- bfd_byte *dst_base_ptr ;
- unsigned int count;
- asection * section =
- data->sections[record.data.relb & RELOCATION_SECT_BITS];
- bfd_vma dst_offset ;
- per = oasys_per_section(section);
- dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
- if (per->had_vma == false) {
- /* Take the first vma we see as the base */
-
- section->vma = dst_offset;
- per->had_vma = true;
- }
+ dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
+ if (per->had_vma == false) {
+ /* Take the first vma we see as the base */
+ section->vma = dst_offset;
+ per->had_vma = true;
+ }
- dst_offset -= section->vma;
-
-
- dst_base_ptr = oasys_per_section(section)->data;
- dst_ptr = oasys_per_section(section)->data +
- dst_offset;
-
- while (src < end_src) {
- uint32_type gap = end_src - src -1;
- uint8e_type mod_byte = *src++;
- count = 8;
- if (mod_byte == 0 && gap >= 8) {
- dst_ptr[0] = src[0];
- dst_ptr[1] = src[1];
- dst_ptr[2] = src[2];
- dst_ptr[3] = src[3];
- dst_ptr[4] = src[4];
- dst_ptr[5] = src[5];
- dst_ptr[6] = src[6];
- dst_ptr[7] = src[7];
- dst_ptr+= 8;
- src += 8;
- }
- else {
- for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
- {
- if (relbit & mod_byte)
- {
- uint8e_type reloc = *src;
- /* This item needs to be relocated */
- switch (reloc & RELOCATION_TYPE_BITS) {
- case RELOCATION_TYPE_ABS:
-
- break;
-
- case RELOCATION_TYPE_REL:
- {
- /* Relocate the item relative to the section */
- oasys_reloc_type *r =
- (oasys_reloc_type *)
- bfd_alloc(abfd,
- sizeof(oasys_reloc_type));
- *(per->reloc_tail_ptr) = r;
- per->reloc_tail_ptr = &r->next;
- r->next= (oasys_reloc_type *)NULL;
- /* Reference to undefined symbol */
- src++;
- /* There is no symbol */
- r->symbol = 0;
- /* Work out the howto */
- r->relent.section =
- data->sections[reloc & RELOCATION_SECT_BITS];
- r->relent.addend = - r->relent.section->vma;
- r->relent.address = dst_ptr - dst_base_ptr;
- r->relent.howto = &howto_table[reloc>>6];
- r->relent.sym_ptr_ptr = (asymbol **)NULL;
- section->reloc_count++;
-
- /* Fake up the data to look like it's got the -ve pc in it, this makes
- it much easier to convert into other formats. This is done by
- hitting the addend.
- */
- if (r->relent.howto->pc_relative == true) {
- r->relent.addend -= dst_ptr - dst_base_ptr;
- }
+ dst_offset -= section->vma;
- }
- break;
-
-
- case RELOCATION_TYPE_UND:
- {
- oasys_reloc_type *r =
- (oasys_reloc_type *)
- bfd_alloc(abfd,
- sizeof(oasys_reloc_type));
- *(per->reloc_tail_ptr) = r;
- per->reloc_tail_ptr = &r->next;
- r->next= (oasys_reloc_type *)NULL;
- /* Reference to undefined symbol */
- src++;
- /* Get symbol number */
- r->symbol = (src[0]<<8) | src[1];
- /* Work out the howto */
- r->relent.section = (asection *)NULL;
- r->relent.addend = 0;
- r->relent.address = dst_ptr - dst_base_ptr;
- r->relent.howto = &howto_table[reloc>>6];
- r->relent.sym_ptr_ptr = (asymbol **)NULL;
- section->reloc_count++;
-
- src+=2;
- /* Fake up the data to look like it's got the -ve pc in it, this makes
- it much easier to convert into other formats. This is done by
- hitting the addend.
- */
- if (r->relent.howto->pc_relative == true) {
- r->relent.addend -= dst_ptr - dst_base_ptr;
- }
+
+ dst_base_ptr = oasys_per_section(section)->data;
+ dst_ptr = oasys_per_section(section)->data +
+ dst_offset;
+
+ if (src < end_src) {
+ section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+ }
+ while (src < end_src) {
+ uint8e_type mod_byte = *src++;
+ uint32_type gap = end_src - src;
+
+ count = 8;
+ if (mod_byte == 0 && gap >= 8) {
+ dst_ptr[0] = src[0];
+ dst_ptr[1] = src[1];
+ dst_ptr[2] = src[2];
+ dst_ptr[3] = src[3];
+ dst_ptr[4] = src[4];
+ dst_ptr[5] = src[5];
+ dst_ptr[6] = src[6];
+ dst_ptr[7] = src[7];
+ dst_ptr+= 8;
+ src += 8;
+ }
+ else {
+ for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
+ {
+ if (relbit & mod_byte)
+ {
+ uint8e_type reloc = *src;
+ /* This item needs to be relocated */
+ switch (reloc & RELOCATION_TYPE_BITS) {
+ case RELOCATION_TYPE_ABS:
+
+ break;
+
+ case RELOCATION_TYPE_REL:
+ {
+ /* Relocate the item relative to the section */
+ oasys_reloc_type *r =
+ (oasys_reloc_type *)
+ bfd_alloc(abfd,
+ sizeof(oasys_reloc_type));
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next= (oasys_reloc_type *)NULL;
+ /* Reference to undefined symbol */
+ src++;
+ /* There is no symbol */
+ r->symbol = 0;
+ /* Work out the howto */
+ r->relent.section =
+ data->sections[reloc & RELOCATION_SECT_BITS];
+ r->relent.addend = - r->relent.section->vma;
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc>>6];
+ r->relent.sym_ptr_ptr = (asymbol **)NULL;
+ section->reloc_count++;
+
+ /* Fake up the data to look like it's got the -ve pc in it, this makes
+ it much easier to convert into other formats. This is done by
+ hitting the addend.
+ */
+ if (r->relent.howto->pc_relative == true) {
+ r->relent.addend -= dst_ptr - dst_base_ptr;
+ }
+
+
+ }
+ break;
+
+
+ case RELOCATION_TYPE_UND:
+ {
+ oasys_reloc_type *r =
+ (oasys_reloc_type *)
+ bfd_alloc(abfd,
+ sizeof(oasys_reloc_type));
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next= (oasys_reloc_type *)NULL;
+ /* Reference to undefined symbol */
+ src++;
+ /* Get symbol number */
+ r->symbol = (src[0]<<8) | src[1];
+ /* Work out the howto */
+ r->relent.section = (asection *)NULL;
+ r->relent.addend = 0;
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc>>6];
+ r->relent.sym_ptr_ptr = (asymbol **)NULL;
+ section->reloc_count++;
+
+ src+=2;
+ /* Fake up the data to look like it's got the -ve pc in it, this makes
+ it much easier to convert into other formats. This is done by
+ hitting the addend.
+ */
+ if (r->relent.howto->pc_relative == true) {
+ r->relent.addend -= dst_ptr - dst_base_ptr;
+ }
+ }
+ break;
+ case RELOCATION_TYPE_COM:
+ BFD_FAIL();
}
- break;
- case RELOCATION_TYPE_COM:
- BFD_FAIL();
- }
- }
- *dst_ptr++ = *src++;
- }
+ }
+ *dst_ptr++ = *src++;
+ }
+ }
+ }
}
- }
+ break;
+ case oasys_record_is_local_enum:
+ case oasys_record_is_symbol_enum:
+ case oasys_record_is_section_enum:
+ break;
+ default:
+ loop = false;
}
- break;
- case oasys_record_is_local_enum:
- case oasys_record_is_symbol_enum:
- case oasys_record_is_section_enum:
- break;
- default:
- loop = false;
- }
}
+
return true;
}
oasys_per_section( newsect)->data = (bfd_byte *)NULL;
oasys_per_section(newsect)->section = newsect;
oasys_per_section(newsect)->offset = 0;
- newsect->alignment_power = 3;
+ oasys_per_section(newsect)->initialized = false;
+ newsect->alignment_power = 1;
/* Turn the section string into an index */
sscanf(newsect->name,"%u", &newsect->target_index);
{
oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
oasys_slurp_section_data(abfd);
- (void) memcpy(location, p->data + offset, (int)count);
+ if (p->initialized == false)
+ {
+ (void) memset(location, 0, (int)count);
+ }
+ else
+ {
+ (void) memcpy(location, p->data + offset, (int)count);
+ }
return true;
}
continue;
}
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]));
}
while (src[l]) {
{
asection *s;
for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
- uint8e_type *raw_data = oasys_per_section(s)->data;
- oasys_data_record_type processed_data;
- bfd_size_type current_byte_index = 0;
- unsigned int relocs_to_go = s->reloc_count;
- arelent **p = s->orelocation;
- if (s->reloc_count != 0) {
- /* Sort the reloc records so it's easy to insert the relocs into the
- data */
+ if (s->flags & SEC_LOAD) {
+ uint8e_type *raw_data = oasys_per_section(s)->data;
+ oasys_data_record_type processed_data;
+ bfd_size_type current_byte_index = 0;
+ unsigned int relocs_to_go = s->reloc_count;
+ arelent **p = s->orelocation;
+ if (s->reloc_count != 0) {
+ /* Sort the reloc records so it's easy to insert the relocs into the
+ data */
- qsort(s->orelocation,
- s->reloc_count,
- sizeof(arelent **),
- comp);
- }
- current_byte_index = 0;
- processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
+ qsort(s->orelocation,
+ s->reloc_count,
+ sizeof(arelent **),
+ comp);
+ }
+ current_byte_index = 0;
+ processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
- while (current_byte_index < s->size)
- {
- /* Scan forwards by eight bytes or however much is left and see if
- there are any relocations going on */
- uint8e_type *mod = &processed_data.data[0];
- uint8e_type *dst = &processed_data.data[1];
+ while (current_byte_index < s->size)
+ {
+ /* Scan forwards by eight bytes or however much is left and see if
+ there are any relocations going on */
+ uint8e_type *mod = &processed_data.data[0];
+ uint8e_type *dst = &processed_data.data[1];
- unsigned int i;
- unsigned int long_length = 128;
+ unsigned int i;
+ unsigned int long_length = 128;
- bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
- if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
- long_length = s->size - current_byte_index;
- }
- while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
+ bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
+ if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
+ long_length = s->size - current_byte_index;
+ }
+ while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
- unsigned int length = long_length;
- *mod =0;
- if (length > 8)
- length = 8;
-
- for (i = 0; i < length; i++) {
- if (relocs_to_go != 0) {
- arelent *r = *p;
- reloc_howto_type *CONST how=r->howto;
- /* There is a relocation, is it for this byte ? */
- if (r->address == current_byte_index) {
- uint8e_type rel_byte;
- p++;
- relocs_to_go--;
-
- *mod |= (1<<i);
- if(how->pc_relative) {
- rel_byte = 0x80;
-
- /* Also patch the raw data so that it doesn't have
- the -ve stuff any more */
- if (how->size != 2) {
- bfd_put_16(abfd,
+ unsigned int length = long_length;
+ *mod =0;
+ if (length > 8)
+ length = 8;
+
+ for (i = 0; i < length; i++) {
+ if (relocs_to_go != 0) {
+ arelent *r = *p;
+ reloc_howto_type *CONST how=r->howto;
+ /* There is a relocation, is it for this byte ? */
+ if (r->address == current_byte_index) {
+ uint8e_type rel_byte;
+ p++;
+ relocs_to_go--;
+
+ *mod |= (1<<i);
+ if(how->pc_relative) {
+ rel_byte = 0x80;
+
+ /* Also patch the raw data so that it doesn't have
+ the -ve stuff any more */
+ if (how->size != 2) {
+ bfd_put_16(abfd,
bfd_get_16(abfd,raw_data) +
current_byte_index, raw_data);
- }
+ }
+ else {
+ bfd_put_32(abfd,
+ bfd_get_32(abfd,raw_data) +
+ current_byte_index, raw_data);
+ }
+ }
else {
- bfd_put_32(abfd,
- bfd_get_32(abfd,raw_data) +
- current_byte_index, raw_data);
+ rel_byte = 0;
+ }
+ if (how->size ==2) {
+ rel_byte |= 0x40;
}
- }
- else {
- rel_byte = 0;
- }
- if (how->size ==2) {
- rel_byte |= 0x40;
- }
- /* Is this a section relative relocation, or a symbol
- relative relocation ? */
- if (r->section != (asection*)NULL)
- {
- /* The relent has a section attatched, so it must be section
- relative */
- rel_byte |= RELOCATION_TYPE_REL;
- rel_byte |= r->section->output_section->target_index;
- *dst++ = rel_byte;
- }
- else
- {
- asymbol *p = *(r->sym_ptr_ptr);
-
- /* If this symbol has a section attatched, then it
- has already been resolved. Change from a symbol
- ref to a section ref */
- if(p->section != (asection *)NULL) {
+ /* Is this a section relative relocation, or a symbol
+ relative relocation ? */
+ if (r->section != (asection*)NULL)
+ {
+ /* The relent has a section attatched, so it must be section
+ relative */
rel_byte |= RELOCATION_TYPE_REL;
- rel_byte |=
- p->section->output_section->target_index;
+ rel_byte |= r->section->output_section->target_index;
*dst++ = rel_byte;
}
- else {
- rel_byte |= RELOCATION_TYPE_UND;
+ else
+ {
+ asymbol *p = *(r->sym_ptr_ptr);
+
+ /* If this symbol has a section attatched, then it
+ has already been resolved. Change from a symbol
+ ref to a section ref */
+ if(p->section != (asection *)NULL) {
+ rel_byte |= RELOCATION_TYPE_REL;
+ rel_byte |=
+ p->section->output_section->target_index;
+ *dst++ = rel_byte;
+ }
+ else {
+ rel_byte |= RELOCATION_TYPE_UND;
- *dst++ = rel_byte;
- /* Next two bytes are a symbol index - we can get
- this from the symbol value which has been zapped
- into the symbol index in the table when the
- symbol table was written
- */
- *dst++ = p->value >> 8;
- *dst++ = p->value;
- }
+ *dst++ = rel_byte;
+ /* Next two bytes are a symbol index - we can get
+ this from the symbol value which has been zapped
+ into the symbol index in the table when the
+ symbol table was written
+ */
+ *dst++ = p->value >> 8;
+ *dst++ = p->value;
+ }
- }
+ }
+ }
}
+ /* If this is coming from an unloadable section then copy
+ zeros */
+ if (raw_data == (uint8e_type *)NULL) {
+ *dst++ = 0;
+ }
+ else {
+ *dst++ = *raw_data++;
+ }
+ current_byte_index++;
}
- /* If this is coming from an unloadable section then copy
- zeros */
- if (raw_data == (uint8e_type *)NULL) {
- *dst++ = 0;
- }
- else {
- *dst++ = *raw_data++;
- }
- current_byte_index++;
+ mod = dst++;
+ long_length -= length;
}
- mod = dst++;
- long_length -= length;
- }
- oasys_write_record(abfd,
- oasys_record_is_data_enum,
- (oasys_record_union_type *)&processed_data,
- dst - (uint8e_type*)&processed_data);
+ oasys_write_record(abfd,
+ oasys_record_is_data_enum,
+ (oasys_record_union_type *)&processed_data,
+ dst - (uint8e_type*)&processed_data);
- }
+ }
+ }
}
}
static boolean
{
return 0;
}
-
+#define FOO PROTO
#define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
#define oasys_core_file_failing_signal (int (*)())bfd_0
-#define oasys_core_file_matches_executable_p 0 /*(PROTO(boolean, (*),(bfd*, bfd*)))bfd_false*/
+#define oasys_core_file_matches_executable_p 0
#define oasys_slurp_armap bfd_true
#define oasys_slurp_extended_name_table bfd_true
#define oasys_truncate_arname (void (*)())bfd_nullvoidptr
-#define oasys_write_armap 0 /* (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr*/
+#define oasys_write_armap 0
#define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
#define oasys_close_and_cleanup bfd_generic_close_and_cleanup
+#define oasys_bfd_debug_info_start bfd_void
+#define oasys_bfd_debug_info_end bfd_void
+#define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
/*SUPPRESS 460 */
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
-
+ 1, /* minimum alignment */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
return nbfd;
}
-/** bfd_openr, bfd_fdopenr -- open for reading.
- Returns a pointer to a freshly-allocated bfd on success, or NULL. */
+/*doc*
+@section Opening and Closing BFDs
+
+*/
+/*proto*
+*i bfd_openr
+Opens the file supplied (using fopen) with the target supplied, it
+returns a pointer to the created bfd.
+
+If NULL is returned then an error has occured.
+Possible errors are no_memory, invalid_target or system_call error.
+*; PROTO(bfd*, bfd_openr, (CONST char *filename,CONST char*target));
+*-*/
bfd *
DEFUN(bfd_openr, (filename, target),
close it if anything goes wrong. Closing the stream means closing
the file descriptor too, even though we didn't open it.
*/
+/*proto*
+*i bfd_fdopenr
+bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen. It opens a bfd on
+a file already described by the @var{fd} supplied.
+
+Possible errors are no_memory, invalid_target and system_call error.
+*; PROTO(bfd *, bfd_fdopenr,
+ (CONST char *filename, CONST char *target, int fd));
+*-*/
bfd *
DEFUN(bfd_fdopenr,(filename, target, fd),
bfd_error = system_call_error;
- fdflags = fcntl (fd, F_GETFL);
+ fdflags = fcntl (fd, F_GETFL, NULL);
if (fdflags == -1) return NULL;
#ifdef BFD_LOCKS
See comment by bfd_fdopenr before you try to modify this function. */
+/*proto* bfd_openw
+Creates a bfd, associated with file @var{filename}, using the file
+format @var{target}, and returns a pointer to it.
+
+Possible errors are system_call_error, no_memory, invalid_target.
+*; PROTO(bfd *, bfd_openw, (CONST char *filename, CONST char *target));
+*/
+
bfd *
DEFUN(bfd_openw,(filename, target),
CONST char *filename AND
}
return nbfd;
}
-\f
-/* Close up shop, get your deposit back. */
+
+/*proto* bfd_close
+This function closes a bfd. If the bfd was open for writing, then
+pending operations are completed and the file written out and closed.
+If the created file is executable, then @code{chmod} is called to mark
+it as such.
+
+All memory attatched to the bfd's obstacks is released.
+
+@code{true} is returned if all is ok, otherwise @code{false}.
+*; PROTO(boolean, bfd_close,(bfd *));
+*/
+
boolean
-bfd_close (abfd)
- bfd *abfd;
+DEFUN(bfd_close,(abfd),
+ bfd *abfd)
{
if (!bfd_read_p(abfd))
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
return true;
}
-/* Create a bfd with no associated file or target. */
+/*proto* bfd_create
+This routine creates a new bfd in the manner of bfd_openw, but without
+opening a file. The new bfd takes the target from the target used by
+@var{template}. The format is always set to @code{bfd_object}.
+
+*; PROTO(bfd *, bfd_create, (CONST char *filename, bfd *template));
+*/
bfd *
DEFUN(bfd_create,(filename, template),
CONST char *filename AND
- CONST bfd *template)
+ bfd *template)
{
bfd *nbfd = new_bfd();
if (nbfd == (bfd *)NULL) {
PTR res = obstack_alloc(&(abfd->memory), size);
return res;
}
+
+DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
+ bfd *abfd AND
+ PTR ptr AND
+ bfd_size_type size)
+{
+ obstack_grow(&(abfd->memory), ptr, size);
+}
+DEFUN(PTR bfd_alloc_finish,(abfd),
+ bfd *abfd)
+{
+ return obstack_finish(&(abfd->memory));
+}
+
DEFUN(PTR bfd_alloc, (abfd, size),
bfd *abfd AND
bfd_size_type size)
return res;
}
+/*proto* bfd_alloc_size
+Return the number of bytes in the obstacks connected to the supplied
+bfd.
+*; PROTO(bfd_size_type,bfd_alloc_size,(bfd *abfd));
+*/
-DEFUN(bfd_size_type bfd_alloc_size,(abfd),
+bfd_size_type
+DEFUN( bfd_alloc_size,(abfd),
bfd *abfd)
{
struct _obstack_chunk *chunk = abfd->memory.chunk;
+ (HEX(buffer.u.type_3.address+1) << 16)
+ (HEX(buffer.u.type_3.address+2) << 8)
+ (HEX(buffer.u.type_3.address+3));
- func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
+ func(abfd,section, address, buffer.u.type_3.data, bytes_on_line -1);
break;
check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
size = bytes_this_chunk + 5;
data = buffer.u.type_3.data;
-
+ break;
case 2:
check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
size = bytes_this_chunk + 3;
data = buffer.u.type_1.data;
+ break;
}
for (i = 0; i < bytes_this_chunk; i++) {
new->the_bfd = abfd;
return new;
}
-/*SUPPRESS 460 */
-
-#define srec_new_section_hook (PROTO(boolean, (*), (bfd *, asection *)))bfd_true
+#define FOO PROTO
+#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
#define srec_get_symtab_upper_bound bfd_false
-#define srec_get_symtab (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
-#define srec_get_reloc_upper_bound (PROTO(unsigned int, (*),(bfd*, asection *)))bfd_false
-#define srec_canonicalize_reloc (PROTO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
+#define srec_get_symtab (FOO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
+#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
+#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
-#define srec_print_symbol (PROTO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
+#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
-#define srec_openr_next_archived_file (PROTO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
-#define srec_find_nearest_line (PROTO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
-#define srec_generic_stat_arch_elt (PROTO(int, (*), (bfd *,struct stat *))) bfd_0
+#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
+#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
+#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0
#define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
#define srec_core_file_failing_signal (int (*)())bfd_0
-#define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false
+#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
#define srec_slurp_armap bfd_true
#define srec_slurp_extended_name_table bfd_true
#define srec_truncate_arname (void (*)())bfd_nullvoidptr
-#define srec_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
+#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
-
#define srec_close_and_cleanup bfd_generic_close_and_cleanup
+#define srec_bfd_debug_info_start bfd_void
+#define srec_bfd_debug_info_end bfd_void
+#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void
bfd_target srec_vec =
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
+ 1, /* minimum alignment */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
/* $Id$ */
-/* This -*- C -*- source file will someday be machine-generated */
-
-/*** Defines the target vector through which operations dispatch */
#include <sysdep.h>
#include "bfd.h"
#include "libbfd.h"
+/*doc*
+@section Targets
+Each port of BFD to a different machine requries the creation of a
+target back end. All the back end provides to the root part of bfd is
+a structure containing pointers to functions which perform certain low
+level operations on files. BFD translates the applications's requests
+through a pointer into calls to the back end routines.
+
+When a file is opened with @code{bfd_openr}, its format and target are
+unknown. BFD uses various mechanisms to determine how to interpret the
+file. The operatios performed are:
+@itemize @bullet
+@item
+First a bfd is created by calling the internal routine
+@code{new_bfd}, then @code{bfd_find_target} is called with the target
+string supplied to @code{bfd_openr} and the new bfd pointer.
+@item
+If a null target string was provided to
+@code{bfd_find_target}, it looks up the environment variable
+@code{GNUTARGET} and uses that as the target string.
+@item
+If the target string is still NULL, or the target string
+is @code{default}, then the first item in the target vector is used as
+the target type. @xref{targets}.
+@item
+Otherwise, the elements in the target vector are
+inspected one by one, until a match on target name is found. When
+found, that is used.
+@item
+Otherwise the error @code{invalid_target} is returned to
+@code{bfd_openr}.
+@item
+@code{bfd_openr} attempts to open the file using
+@code{bfd_open_file}, and returns the bfd.
+@end itemize
+Once the bfd has been opened and the target selected, the file format
+may be determined. This is done by calling @code{bfd_check_format} on
+the bfd with a suggested format. The routine returns @code{true} when
+the application guesses right.
+*/
+
+
+/*proto* bfd_target
+@node bfd_target
+@subsection bfd_target
+This structure contains everything that BFD knows about a target.
+It includes things like its byte order, name, what routines to call
+to do various operations, etc.
+
+Every BFD points to a target structure with its "xvec" member.
+
+
+Shortcut for declaring fields which are prototyped function pointers,
+while avoiding anguish on compilers that don't support protos.
+
+$#define SDEF(ret, name, arglist) \
+$ PROTO(ret,(*name),arglist)
+$#define SDEF_FMT(ret, name, arglist) \
+$ PROTO(ret,(*name[bfd_type_end]),arglist)
+
+These macros are used to dispatch to functions through the bfd_target
+vector. They are used in a number of macros further down in bfd.h, and
+are also used when calling various routines by hand inside the bfd
+implementation. The "arglist" argument must be parenthesized; it
+contains all the arguments to the called function.
+
+$#define BFD_SEND(bfd, message, arglist) \
+$ ((*((bfd)->xvec->message)) arglist)
+
+For operations which index on the bfd format
+
+$#define BFD_SEND_FMT(bfd, message, arglist) \
+$ (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+
+This is the struct which defines the type of BFD this is. The
+"xvec" member of the struct bfd itself points here. Each module
+that implements access to a different target under BFD, defines
+one of these.
+
+FIXME, these names should be rationalised with the names of the
+entry points which call them. Too bad we can't have one macro to
+define them both!
+
+*+++
+
+$typedef struct bfd_target
+${
+
+identifies the kind of target, eg SunOS4, Ultrix, etc
+
+$ char *name;
+
+The "flavour" of a back end is a general indication about the contents
+of a file.
+
+$ enum target_flavour_enum {
+$ bfd_target_aout_flavour_enum,
+$ bfd_target_coff_flavour_enum,
+$ bfd_target_ieee_flavour_enum,
+$ bfd_target_oasys_flavour_enum,
+$ bfd_target_srec_flavour_enum} flavour;
+
+The order of bytes within the data area of a file.
+
+$ boolean byteorder_big_p;
+
+The order of bytes within the header parts of a file.
+
+$ boolean header_byteorder_big_p;
+
+This is a mask of all the flags which an executable may have set -
+from the set @code{NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}.
+
+$ flagword object_flags;
+
+This is a mask of all the flags which a section may have set - from
+the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}.
+
+$ flagword section_flags;
+
+The pad character for filenames within an archive header.
+
+$ char ar_pad_char;
+
+The maximum number of characters in an archive header.
+
+$ unsigned short ar_max_namelen;
+
+The minimum alignment restriction for any section.
+
+$ unsigned int align_power_min;
+
+Entries for byte swapping for data. These are different to the other
+entry points, since they don't take bfd as first arg. Certain other handlers
+could do the same.
+
+$ SDEF (bfd_64_type, bfd_getx64, (bfd_byte *));
+$ SDEF (void, bfd_putx64, (bfd_64_type, bfd_byte *));
+$ SDEF (unsigned int, bfd_getx32, (bfd_byte *));
+$ SDEF (void, bfd_putx32, (unsigned long, bfd_byte *));
+$ SDEF (unsigned int, bfd_getx16, (bfd_byte *));
+$ SDEF (void, bfd_putx16, (int, bfd_byte *));
+
+Byte swapping for the headers
+
+$ SDEF (bfd_64_type, bfd_h_getx64, (bfd_byte *));
+$ SDEF (void, bfd_h_putx64, (bfd_64_type, bfd_byte *));
+$ SDEF (unsigned int, bfd_h_getx32, (bfd_byte *));
+$ SDEF (void, bfd_h_putx32, (unsigned long, bfd_byte *));
+$ SDEF (unsigned int, bfd_h_getx16, (bfd_byte *));
+$ SDEF (void, bfd_h_putx16, (int, bfd_byte *));
+
+Format dependent routines, these turn into vectors of entry points
+within the target vector structure; one for each format to check.
+
+Check the format of a file being read. Return bfd_target * or zero.
+
+$ SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
+
+Set the format of a file being written.
+
+$ SDEF_FMT (boolean, _bfd_set_format, (bfd *));
+
+Write cached information into a file being written, at bfd_close.
+
+$ SDEF_FMT (boolean, _bfd_write_contents, (bfd *));
+
+The following functions are defined in @code{JUMP_TABLE}. The idea is
+that the back end writer of @code{foo} names all the routines
+@code{foo_}@var{entry_point}, @code{JUMP_TABLE} will built the entries
+in this structure in the right order.
+
+Core file entry points
+
+$ SDEF (char *, _core_file_failing_command, (bfd *));
+$ SDEF (int, _core_file_failing_signal, (bfd *));
+$ SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
+
+Archive entry points
+
+$ SDEF (boolean, _bfd_slurp_armap, (bfd *));
+$ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
+$ SDEF (void, _bfd_truncate_arname, (bfd *, CONST char *, char *));
+$ SDEF (boolean, write_armap, (bfd *arch,
+$ unsigned int elength,
+$ struct orl *map,
+$ int orl_count,
+$ int stridx));
+
+Standard stuff.
+
+$ SDEF (boolean, _close_and_cleanup, (bfd *));
+$ SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
+$ file_ptr, bfd_size_type));
+$ SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR,
+$ file_ptr, bfd_size_type));
+$ SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
+
+Symbols and reloctions
+
+$ SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
+$ SDEF (unsigned int, _bfd_canonicalize_symtab,
+$ (bfd *, struct symbol_cache_entry **));
+$ SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
+$ SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
+$ struct symbol_cache_entry**));
+$ SDEF (struct symbol_cache_entry *, _bfd_make_empty_symbol, (bfd *));
+$ SDEF (void, _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry *,
+$ bfd_print_symbol_enum_type));
+$#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+$ SDEF (alent *, _get_lineno, (bfd *, struct symbol_cache_entry *));
+$
+$ SDEF (boolean, _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
+$ unsigned long));
+$
+$ SDEF (bfd *, openr_next_archived_file, (bfd *arch, bfd *prev));
+$ SDEF (boolean, _bfd_find_nearest_line,
+$ (bfd *abfd, struct sec *section,
+$ struct symbol_cache_entry **symbols,bfd_vma offset,
+$ CONST char **file, CONST char **func, unsigned int *line));
+$ SDEF (int, _bfd_stat_arch_elt, (bfd *, struct stat *));
+$
+$ SDEF (int, _bfd_sizeof_headers, (bfd *, boolean));
+$
+$ SDEF (void, _bfd_debug_info_start, (bfd *));
+$ SDEF (void, _bfd_debug_info_end, (bfd *));
+$ SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec *));
+
+Special entry points for gdb to swap in coff symbol table parts
+
+$ SDEF(void, _bfd_coff_swap_aux_in,(
+$ bfd *abfd ,
+$ PTR ext,
+$ int type,
+$ int class ,
+$ PTR in));
+$
+$ SDEF(void, _bfd_coff_swap_sym_in,(
+$ bfd *abfd ,
+$ PTR ext,
+$ PTR in));
+$
+$ SDEF(void, _bfd_coff_swap_lineno_in, (
+$ bfd *abfd,
+$ PTR ext,
+$ PTR in));
+$
+$} bfd_target;
+
+*---
+
+*/
extern bfd_target ecoff_little_vec;
extern bfd_target ecoff_big_vec;
extern bfd_target sunos_big_vec;
#endif
#ifdef GNU960
-#define ICOFF_LITTLE_VEC icoff_little_vec
-#define ICOFF_BIG_VEC icoff_big_vec
-#define B_OUT_VEC_LITTLE_HOST b_out_vec_little_host
-#define B_OUT_VEC_BIG_HOST b_out_vec_big_host
+#define ICOFF_LITTLE_VEC icoff_little_vec
+#define ICOFF_BIG_VEC icoff_big_vec
+#define B_OUT_VEC_LITTLE_HOST b_out_vec_little_host
+#define B_OUT_VEC_BIG_HOST b_out_vec_big_host
#endif /* GNU960 */
#ifndef RESTRICTED
-#define ECOFF_LITTLE_VEC ecoff_little_vec
-#define ECOFF_BIG_VEC ecoff_big_vec
-#define ICOFF_LITTLE_VEC icoff_little_vec
-#define ICOFF_BIG_VEC icoff_big_vec
-#define XB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
-#define XB_OUT_VEC_BIG_HOST b_out_vec_big_host
-#define SUNOS_VEC_BIG_HOST sunos_big_vec
-#define DEMO_64_VEC demo_64_vec
-#define OASYS_VEC oasys_vec
-#define IEEE_VEC ieee_vec
-#define M88K_BCS_VEC m88k_bcs_vec
-#define SREC_VEC srec_vec
-#define M68KCOFF_VEC m68kcoff_vec
-#define I386COFF_VEC i386coff_vec
+#define ECOFF_LITTLE_VEC ecoff_little_vec
+#define ECOFF_BIG_VEC ecoff_big_vec
+#define ICOFF_LITTLE_VEC icoff_little_vec
+#define ICOFF_BIG_VEC icoff_big_vec
+#define ZB_OUT_VEC_LITTLE_HOST b_out_vec_little_host
+#define ZB_OUT_VEC_BIG_HOST b_out_vec_big_host
+#define SUNOS_VEC_BIG_HOST sunos_big_vec
+#define DEMO_64_VEC demo_64_vec
+#define OASYS_VEC oasys_vec
+#define IEEE_VEC ieee_vec
+#define M88K_BCS_VEC m88k_bcs_vec
+#define SREC_VEC srec_vec
+#define M68KCOFF_VEC m68kcoff_vec
+#define I386COFF_VEC i386coff_vec
#endif
bfd_target *target_vector[] = {
#ifdef DEFAULT_VECTOR
- &DEFAULT_VECTOR,
+ &DEFAULT_VECTOR,
#endif /* DEFAULT_VECTOR */
-#ifdef I386COFF_VEC
- &I386COFF_VEC,
-#endif /* I386COFF_VEC */
+#ifdef I386COFF_VEC
+ &I386COFF_VEC,
+#endif /* I386COFF_VEC */
#ifdef ECOFF_LITTLE_VEC
- &ECOFF_LITTLE_VEC,
+ &ECOFF_LITTLE_VEC,
#endif
#ifdef ECOFF_BIG_VEC
- &ECOFF_BIG_VEC,
+ &ECOFF_BIG_VEC,
#endif
#ifdef IEEE_VEC
- &IEEE_VEC,
+ &IEEE_VEC,
#endif /* IEEE_VEC */
#ifdef OASYS_VEC
- &OASYS_VEC,
+ &OASYS_VEC,
#endif /* OASYS_VEC */
#ifdef SUNOS_VEC_BIG_HOST
- &SUNOS_VEC_BIG_HOST,
+ &SUNOS_VEC_BIG_HOST,
#endif /* SUNOS_BIG_VEC */
#ifdef HOST_64_BIT
#ifdef DEMO_64_VEC
- &DEMO_64_VEC,
+ &DEMO_64_VEC,
#endif
#endif
#ifdef M88K_BCS_VEC
- &M88K_BCS_VEC,
+ &M88K_BCS_VEC,
#endif /* M88K_BCS_VEC */
#ifdef SREC_VEC
- &SREC_VEC,
+ &SREC_VEC,
#endif /* SREC_VEC */
-
+
#ifdef ICOFF_LITTLE_VEC
- &ICOFF_LITTLE_VEC,
+ &ICOFF_LITTLE_VEC,
#endif /* ICOFF_LITTLE_VEC */
#ifdef ICOFF_BIG_VEC
- &ICOFF_BIG_VEC,
+ &ICOFF_BIG_VEC,
#endif /* ICOFF_BIG_VEC */
#ifdef B_OUT_VEC_LITTLE_HOST
- &B_OUT_VEC_LITTLE_HOST,
+ &B_OUT_VEC_LITTLE_HOST,
#endif /* B_OUT_VEC_LITTLE_HOST */
#ifdef B_OUT_VEC_BIG_HOST
- &B_OUT_VEC_BIG_HOST,
+ &B_OUT_VEC_BIG_HOST,
#endif /* B_OUT_VEC_BIG_HOST */
-#ifdef M68KCOFF_VEC
- &M68KCOFF_VEC,
-#endif /* M68KCOFF_VEC */
+#ifdef M68KCOFF_VEC
+ &M68KCOFF_VEC,
+#endif /* M68KCOFF_VEC */
- NULL, /* end of list marker */
+ NULL, /* end of list marker */
};
bfd_target *default_vector[] = {
#ifdef DEFAULT_VECTOR
- &DEFAULT_VECTOR,
+ &DEFAULT_VECTOR,
#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;
+}