From: Steve Chamberlain Date: Thu, 4 Jul 1991 16:52:56 +0000 (+0000) Subject: Now full of documentation. Yum Yum. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6f715d66ad223169971e668f968db6774c41e52a;p=binutils-gdb.git Now full of documentation. Yum Yum. --- diff --git a/bfd/.Sanitize b/bfd/.Sanitize index 7c527afa377..89a5e3dec6f 100644 --- a/bfd/.Sanitize +++ b/bfd/.Sanitize @@ -28,7 +28,9 @@ echo Sanitizing `pwd`... Things-to-keep: COPYING +bfd.texinfo ChangeLog +Makefile Makefile.in TODO VERSION @@ -40,19 +42,17 @@ archive.c archures.c archures.h bfd.c -bfd.doc bout.c cache.c coffcode.h -coffish.h -coffswap.c -config -configure +config.status +configure* configure.in -cplus-dem.c +core.c demo64.c ecoff.c filemode.c +format.c host-aout.c i386coff.c icoff.c @@ -65,12 +65,14 @@ libieee.h liboasys.h m68kcoff.c m88k-bcs.c -misc.h newsos3.c oasys.c opncls.c +reloc.c +section.c srec.c sunos.c +syms.c targets.c trad-core.c trad-core.h @@ -82,7 +84,10 @@ echo Done in `pwd`. # # # $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 diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 9d32e339df5..a8a74e2f615 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -1,4 +1,4 @@ -# + # # Copyright (C) 1990, 1991 Free Software Foundation, Inc. # # This file is part of BFD, the Binary File Diddler. @@ -20,6 +20,8 @@ # $Id$ srcdir = . +destdir = /usr/local +libdir = $(destdir)/lib RANLIB = ranlib AR = ar @@ -35,18 +37,21 @@ CFLAGS = -g $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \ - archures.o + archures.o core.o section.o format.o syms.o reloc.o -BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o demo64.o \ - m68kcoff.o i386coff.o m88k-bcs.o coffswap.o ecoff.o newsos3.o # trad-core.o bout.o +BFD_BACKENDS = oasys.o ieee.o srec.o aout64.o aout32.o sunos.o icoff.o \ +demo64.o \ +m68kcoff.o i386coff.o m88k-bcs.o ecoff.o newsos3.o # trad-core.o bout.o BFD_H=$(INCDIR)/bfd.h SYSDEP_H=$(INCDIR)/sysdep.h # C source files that correspond to .o's. CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \ - i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c oasys.c ieee.c m68kcoff.c \ - m88k-bcs.c coffswap.c ecoff.c trad-core.c newsos3.c #bout.c + i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \ +oasys.c ieee.c m68kcoff.c \ +format.c section.c core.c syms.c reloc.c \ + m88k-bcs.c ecoff.c trad-core.c newsos3.c #bout.c STAGESTUFF = $(TARGETLIB) $(OFILES) @@ -149,6 +154,8 @@ roll: force: install: + install -c libbfd.a $(libdir) + $(RANLIB) $(libdir)/libbfd.a # Target to uncomment host-specific lines in this makefile. Such lines must # have the following string beginning in column 1: #____# @@ -181,3 +188,81 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/configure dep: $(CFILES) mkdep $(CFLAGS) $? + + +# Stuff to make the documentation for bfd. +# +# make docs +# rebuilds the documentation. Has to be done when the source is +# modified until I work out how to do this properly +# +# make docs headers +# rebuilds the header files from the source +# +# make docs texdoc +# rebuilds the bfd.dvi manual +# +# make docs texinfo +# rebuilts the bfdinfo manual + + +.SUFFIXES: .doc .o .c .h .proto + +.c.doc: + makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop + +.h.doc: + makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop + +.proto.doc: + makedoc <$< doc/$*.doc doc/$*.proto doc/$*.protointernal doc/$*.drop + + +DSRC=$(CFILES) + +docs: syms.doc bfd.doc cache.doc format.doc section.doc archive.doc \ + core.doc libbfd.doc archures.doc reloc.doc opncls.doc \ + targets.doc aoutx.doc coffcode.doc + + +PROTOS = doc/opncls.proto doc/archures.proto doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \ + doc/reloc.proto doc/targets.proto doc/format.proto + + +headers : $(PROTOS) + mkdir -f doc + # Rebuild prototypes in bfd.h + sed <$(BFD_H) >bfd.h.new -e '1,/THE FOLLOWING/!d' + cat doc/opncls.proto doc/archures.proto \ + doc/libbfd.proto doc/section.proto doc/syms.proto doc/bfd.proto doc/archive.proto \ + doc/reloc.proto doc/targets.proto doc/format.proto >>bfd.h.new + echo >> bfd.h.new + echo "#endif" >> bfd.h.new + echo >> bfd.h.new + mv bfd.h.new $(BFD_H) + + # and libbfd.h + sed < libbfd.h >libbfd.h.new -e '1,/THE FOLLOWING/!d' + cat doc/libbfd.protointernal doc/cache.protointernal doc/reloc.protointernal >> libbfd.h.new + echo >> libbfd.h.new + mv libbfd.h.new libbfd.h + + # and libcoff.h + sed < $(srcdir)/libcoff.h >libcoff.h.new -e '1,/THE FOLLOWING/!d' + cat doc/coffcode.proto >>libcoff.h.new + mv libcoff.h.new $(srcdir)/libcoff.h + + +texinfo: + makeinfo +no-validate bfd.texinfo + +texdoc: + tex bfd.texinfo + texindex bfd.?? + tex bfd.texinfo + +quickdoc: $(DSRC) docs + tex bfd.texinfo + + + diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h index ad3c12ded9c..a9a993421e1 100644 --- a/bfd/aoutf1.h +++ b/bfd/aoutf1.h @@ -1,5 +1,3 @@ -/* BFD backend for generic a.out flavour 1 */ - /* Copyright (C) 1990, 1991 Free Software Foundation, Inc. This file is part of BFD, the Binary File Diddler. @@ -18,6 +16,7 @@ You should have received a copy of the GNU General Public License along with BFD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include struct external_exec; @@ -33,6 +32,33 @@ struct external_exec; #include "ar.h" +/* +inheritd two core files and various implimentation files. +The file @code{aoutf1.h} contains the code for BFD's +a.out back end. Control over the generated back end is given by these +three preprocessor names: +@table @code +@item ARCH +This value should be either 32 or 64, depending upon the size of an +int in the target format. It changes the sizes of the structs which +perform the memory/disk mapping of structures. + +The 64 bit backend may only be used if the host compiler supports 64 +ints (eg with gcc), by defining the name @code{HOST_64_BIT}. With this +name defined, @emph{all} bfd operations are performed with 64bit +arithmetic, not just those to a 64bit target. + +@item TARGETNAME +bit long longsIf bfd is being compiled with gcc, (or any other compiler which gives +64 bit long longs), +@item +It is structured in such a way that @code{#define}ing +the size of the architecture into a @code{#include}ing +it with different @code{#define}s present will alter the definitions +of various structures in include files and generate correct code for +th + +*/ void (*bfd_error_trap)(); @@ -177,7 +203,7 @@ DEFUN(NAME(aout,sunos4_write_object_contents),(abfd), choose_reloc_size(abfd); /* FIXME */ - N_SET_FLAGS (*execp, 0x81); + N_SET_FLAGS (*execp, 0x1); WRITE_HEADERS(abfd, execp); @@ -461,31 +487,42 @@ DEFUN(swapcore,(abfd, core), #define aout_64_core_file_failing_signal sunos4_core_file_failing_signal #define aout_64_core_file_matches_executable_p sunos4_core_file_matches_executable_p +#define aout_64_bfd_debug_info_start bfd_void +#define aout_64_bfd_debug_info_end bfd_void +#define aout_64_bfd_debug_info_accumulate bfd_void + +#define aout_32_bfd_debug_info_start bfd_void +#define aout_32_bfd_debug_info_end bfd_void +#define aout_32_bfd_debug_info_accumulate bfd_void + + + /* We implement these routines ourselves, rather than using the generic a.out versions. */ #define aout_write_object_contents sunos4_write_object_contents 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)) + }; diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 399584cca09..8d68ccc6a5a 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -20,13 +20,69 @@ along with BFD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +/*doc* +@section a.out backends + +BFD supports a number of different flavours of a.out format, though +the major differences are only the sizes of the structures on disk, +and the shape of the relocation information. + +The support is split into a basic support file @code{aoutx.h} and +other files which derive functions from the base. One derivation file +is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out +functions support for sun3, sun4, 386 and 29k a.out files, to create a +target jump vector for a specific target. + +This information is further split out into more specific files for each +machine, including @code{sunos.c} - for sun3 and sun4 and +@code{demo64} for a demonstration of a 64 bit a.out format. + +The base file @code{aoutx.h} defines general mechanisms for reading +and writing records to and from disk, and various other methods which +bfd requires. It is included by @code{aout32.c} and @code{aout64.c} to +form the names aout_32_swap_exec_header_in, +aout_64_swap_exec_header_in, etc. + +As an example, this is what goes on to make the back end for a sun4, from aout32.c + +@example + #define ARCH_SIZE 32 + #include "aoutx.h" +@end example + +Which exports names: +@example + ... + aout_32_canonicalize_reloc + aout_32_find_nearest_line + aout_32_get_lineno + aout_32_get_reloc_upper_bound + ... +@end example + +from sunos.c + +@example + #define ARCH 32 + #define TARGET_NAME "a.out-sunos-big" + #define VECNAME sunos_big_vec + #include "aoutf1.h" +@end example +requires all the names from aout32.c, and produces the jump vector + +@example + sunos_big_vec +@end example + +*/ + #include #include #include "bfd.h" struct external_exec; -#include "liba.out.h" +#include "libaout.h" #include "libbfd.h" #include "aout64.h" #include "stab.gnu.h" @@ -34,9 +90,15 @@ struct external_exec; void (*bfd_error_trap)(); -/*SUPPRESS558*/ -/*SUPPRESS529*/ +/*doc* +@subsection relocations +The file @code{aoutx.h} caters for both the @emph{standard} and +@emph{extended} forms of a.out relocation records. +The standard records are characterised by containing only an address, +a symbol index and a type field. The extended records (used on 29ks +and sparcs) also have a full integer for an addend. +*/ #define CTOR_TABLE_RELOC_IDX 2 static reloc_howto_type howto_table_ext[] = { @@ -85,6 +147,24 @@ HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedfac bfd_error_vector_type bfd_error_vector; + +/*doc* +@subsection Internal Entry Points +@code{aoutx.h} exports several routines for accessing the contents of +an a.out file, which are gathered and exported in turn by various +format specific files (eg sunos.c). +*/ + +/*doc* +*i aout__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__swap_exec_header_in, + (bfd *abfd, + struct external_exec *raw_bytes, + struct internal_exec *execp)); +*/ + void DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp), bfd *abfd AND @@ -104,6 +184,15 @@ DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp), execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); } +/*doc* +*i aout__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__swap_exec_header_out, + (bfd *abfd, + struct internal_exec *execp, + struct external_exec *raw_bytes)); +*/ void DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes), bfd *abfd AND @@ -128,10 +217,19 @@ struct container { struct internal_exec e; }; -/* Some A.OUT variant thinks that the file whose format we're checking - 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__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__some_aout_object_p, + (bfd *abfd, + bfd_target *(*callback_to_real_object_p)())); +*/ bfd_target * DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p), @@ -282,6 +380,13 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, callback_to_real_object_p), return (*callback_to_real_object_p)(abfd); } +/*doc* +*i aout__mkobject + +This routine initializes a bfd for use with a.out files. + +*; PROTO(boolean, aout__mkobject, (bfd *)); +*/ boolean DEFUN(NAME(aout,mkobject),(abfd), @@ -314,12 +419,21 @@ DEFUN(NAME(aout,mkobject),(abfd), return true; } -/* Keep track of machine architecture and machine type for a.out's. + +/*doc* +*i aout__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__machine_type, + (enum bfd_architecture arch, + unsigned long machine)); +*/ enum machine_type DEFUN(NAME(aout,machine_type),(arch, machine), @@ -360,6 +474,19 @@ DEFUN(NAME(aout,machine_type),(arch, machine), return arch_flags; } +/*doc* +*i aout__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__set_arch_mach, + (bfd *, + enum bfd_architecture, + unsigned long machine)); +*/ + boolean DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine), bfd *abfd AND @@ -373,9 +500,15 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine), return false; /* We can't represent this type */ return true; /* We're easy ... */ } - -/* exec and core file sections */ +/*doc* +*i aout_new_section_hook + +Called by the bfd in response to a @code{bfd_make_section} request. +*; PROTO(boolean, aout__new_section_hook, + (bfd *abfd, + asection *newsect)); +*/ boolean DEFUN(NAME(aout,new_section_hook),(abfd, newsect), bfd *abfd AND @@ -1460,7 +1593,7 @@ DEFUN(NAME(aout,find_nearest_line),(abfd, 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; diff --git a/bfd/archive.c b/bfd/archive.c index a4431cc2c86..fd7fc3c5cf7 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -1,6 +1,4 @@ -/*** archive.c -- an attempt at combining the machine-independent parts of - archives */ /* Copyright (C) 1990, 1991 Free Software Foundation, Inc. @@ -21,6 +19,21 @@ along with BFD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +/*doc* +@setfilename archive-info +@section Archives + +Gumby, you promised to write this bit... + +Archives are supported in bfd in @code{archive.c}. + +An archive is represented internally just like another bfd, with a +pointer to a chain of contained bfds. Archives can be created by +opening bfds, linking them together and attatching them as children to +another bfd and then closing the parent bfd. + +*-*/ + /* Assumes: o - all archive elements start on an even boundary, newline padded; o - all arch headers are char *; @@ -72,6 +85,10 @@ _bfd_generic_mkarchive (abfd) return true; } +/*proto* bfd_get_next_mapent +What this does +*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **)); +*/ symindex bfd_get_next_mapent (abfd, prev, entry) bfd *abfd; @@ -107,9 +124,16 @@ _bfd_create_empty_archive_element_shell (obfd) return nbfd; } +/*proto* bfd_set_archive_head +Used whilst processing archives. Sets the head of the chain of bfds +contained in an archive to @var{new_head}. (see chapter on archives) +*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head)); +*/ + boolean -bfd_set_archive_head (output_archive, new_head) - bfd *output_archive, *new_head; +DEFUN(bfd_set_archive_head,(output_archive, new_head), + bfd *output_archive AND + bfd *new_head) { output_archive->archive_head = new_head; @@ -229,8 +253,10 @@ snarf_ar_hdr (abfd) return NULL; } - /* extract the filename from the archive */ - if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) { + /* extract the filename from the archive - there are two ways to + specify an extendend name table, either the first char of the + name is a space, or it's a slash */ + if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) { filename = get_extended_arelt_filename (abfd, hdr.ar_name); if (filename == NULL) { bfd_error = malformed_archive; @@ -325,10 +351,22 @@ bfd_get_elt_at_index (abfd, index) return result; } -/* If you've got an archive, call this to read each subfile. */ +/*proto* bfd_openr_next_archived_file +Initially provided a bfd containing an archive and NULL, opens a bfd +on the first contained element and returns that. Subsequent calls to +bfd_openr_next_archived_file should pass the archive and the previous +return value to return a created bfd to the next contained element. +NULL is returned when there are no more. + +*; PROTO(bfd*, bfd_openr_next_archived_file, + (bfd *archive, bfd *previous)); + +*/ + bfd * -bfd_openr_next_archived_file (archive, last_file) - bfd *archive, *last_file; +DEFUN(bfd_openr_next_archived_file,(archive, last_file), + bfd *archive AND + bfd*last_file) { if ((bfd_get_format (archive) != bfd_archive) || @@ -411,7 +449,7 @@ boolean bfd_slurp_bsd_armap (abfd) bfd *abfd; { - int i; + struct areltdata *mapdata; char nextname[17]; unsigned int counter = 0; @@ -451,7 +489,7 @@ bfd_slurp_bsd_armap (abfd) goto byebye; } - ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef); + ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef); ardata->cache = 0; rbase = raw_armap+1; ardata->symdefs = (carsym *) rbase; @@ -459,8 +497,8 @@ bfd_slurp_bsd_armap (abfd) for (;counter < ardata->symdef_count; counter++) { struct symdef *sym = ((struct symdef *) rbase) + counter; - sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase; - sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset)); + sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase; + sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset))); } ardata->first_file_filepos = bfd_tell (abfd); @@ -501,13 +539,16 @@ bfd_slurp_coff_armap (abfd) if (mapdata == NULL) return false; raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size); - if (raw_armap == NULL) { + + if (raw_armap == NULL) + { bfd_error = no_memory; byebye: bfd_release (abfd, (PTR)mapdata); return false; } + /* read in the raw map */ if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) != mapdata->parsed_size) { bfd_error = malformed_archive; @@ -552,19 +593,22 @@ bfd_slurp_coff_armap (abfd) ardata->first_file_filepos = bfd_tell (abfd); /* Pad to an even boundary if you have to */ ardata->first_file_filepos += (ardata->first_file_filepos) %2; - bfd_release (abfd, (PTR)raw_armap); - bfd_release (abfd, (PTR)mapdata); + +/* bfd_release (abfd, (PTR)raw_armap); + bfd_release (abfd, (PTR)mapdata);*/ bfd_has_map (abfd) = true; return true; } /** Extended name table. - Normally archives support only 14-character filenames. Intel has extended - the format: longer names are stored in a special element (the first in the - archive, or second if there is an armap); the name in the ar_hdr is replaced - by . 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 . 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 @@ -578,49 +622,52 @@ _bfd_slurp_extended_name_table (abfd) 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; } @@ -1127,7 +1174,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx) for (i = 0; i < sizeof (struct ar_hdr); i++) if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' '; bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch); - bfd_h_put_32(arch, ranlibsize, &temp); + bfd_h_put_32(arch, ranlibsize, (PTR)&temp); bfd_write (&temp, 1, sizeof (temp), arch); for (count = 0; count < orl_count; count++) { @@ -1143,13 +1190,13 @@ bsd_write_armap (arch, elength, map, orl_count, stridx) } /* if new archive element */ last_elt = current; - bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset); - bfd_h_put_32(arch, firstreal, &outs.file_offset); + bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset); + bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset); bfd_write ((char *)outp, 1, sizeof (outs), arch); } /* now write the strings themselves */ - bfd_h_put_32(arch, stridx, &temp); + bfd_h_put_32(arch, stridx, (PTR)&temp); bfd_write ((PTR)&temp, 1, sizeof (temp), arch); for (count = 0; count < orl_count; count++) bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch); diff --git a/bfd/bfd.c b/bfd/bfd.c index b05ec9cedca..eb435c85da7 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1,11 +1,3 @@ - /* -*- C -*- */ - -/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support. - Every definition in this file should be exported and declared - in bfd.h. If you don't want it to be user-visible, put it in - libbfd.c! -*/ - /* Copyright (C) 1990, 1991 Free Software Foundation, Inc. This file is part of BFD, the Binary File Diddler. @@ -24,55 +16,198 @@ You should have received a copy of the GNU General Public License along with BFD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* $Id$ */ + +/*proto* +@section typedef bfd + +Pointers to bfd structs are the cornerstone of any application using +libbfd. References though the bfd and to data in the bfd give the +entire bfd functionality. + +Finally! The BFD struct itself. This contains the major data about +the file, and contains pointers to the rest of the data. + +*+++ + +$struct _bfd +${ + The filename the application opened the bfd with. + +$ CONST char *filename; + +A pointer to the target jump table. + +$ struct bfd_target *xvec; + + +To avoid dragging too many header files into every file that +includes bfd.h, IOSTREAM has been declared as a "char *", and MTIME +as a "long". Their correct types, to which they are cast when used, +are "FILE *" and "time_t". + +The iostream is the result of an fopen on the filename. + +$ char *iostream; + +Is the file being cached @xref{File Caching}. + +$ boolean cacheable; + +Marks whether there was a default target specified when the bfd was +opened. This is used to select what matching algorithm to use to chose +the back end. + +$ boolean target_defaulted; + +The caching routines use these to maintain an LRU list of bfds. + +$ struct _bfd *lru_prev, *lru_next; + +When a file is closed by the caching routines, it retains the state +here: + +$ file_ptr where; + +and here: + +$ boolean opened_once; + +$ boolean mtime_set; +File modified time + +$ long mtime; + +For output files, channel we locked (is this used?). + +$int ifd; + +The format which belongs to the bfd. + +$ bfd_format format; + +The direction the bfd was opened with + +$ enum bfd_direction {no_direction = 0, +$ read_direction = 1, +$ write_direction = 2, +$ both_direction = 3} direction; + +Format_specific flags + +$ flagword flags; + +Currently my_archive is tested before adding origin to anything. I +believe that this can become always an add of origin, with origin set +to 0 for non archive files. + +$ file_ptr origin; + +Remember when output has begun, to stop strange things happening. + +$ boolean output_has_begun; + +Pointer to linked list of sections + +$ struct sec *sections; + +The number of sections + +$ unsigned int section_count; + +Stuff only usefull for object files: +The start address. + +$ bfd_vma start_address; +Used for input and output + +$ unsigned int symcount; +Symtab for output bfd + +$ struct symbol_cache_entry **outsymbols; + +Architecture of object machine, eg m68k + +$ enum bfd_architecture obj_arch; + +Particular machine within arch, e.g. 68010 + +$ unsigned long obj_machine; + +Stuff only usefull for archives: + +$ PTR arelt_data; +$ struct _bfd *my_archive; +$ struct _bfd *next; +$ struct _bfd *archive_head; +$ boolean has_armap; + +Used by the back end to hold private data. + +$ PTR tdata; + +Used by the application to hold private data + +$ PTR usrdata; + +Where all the allocated stuff under this BFD goes + +$ struct obstack memory; +$}; + +*--- + +*/ #include #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.) */ /** 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", - "#" - }; +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", + "#" + }; 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); } @@ -90,7 +225,7 @@ strerror (code) extern char *sys_errlist[]; return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" : - sys_errlist [code]); + sys_errlist [code]); } #endif /* not ANSI_LIBRARIES */ @@ -127,7 +262,7 @@ DEFUN(bfd_perror,(message), 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)); @@ -136,415 +271,11 @@ DEFUN(bfd_perror,(message), } } -/* for error messages */ -char * -bfd_format_string (format) - bfd_format format; -{ - if (((int)format <(int) bfd_unknown) || ((int)format >=(int) bfd_type_end)) return "invalid"; - - switch (format) { - case bfd_object: return "object"; /* linker/assember/compiler output */ - case bfd_archive: return "archive"; /* object archive file */ - case bfd_core: return "core"; /* core dump */ - default: return "unknown"; - } -} - -/** Target configurations */ - -extern bfd_target *target_vector[]; -extern bfd_target *default_vector[]; - -/* Returns a pointer to the transfer vector for the object target - named target_name. If target_name is NULL, chooses the one in the - environment variable GNUTARGET; if that is null or not defined then - the first entry in the target list is chosen. Passing in the - string "default" or setting the environment variable to "default" - will cause the first entry in the target list to be returned, - and "target_defaulted" will be set in the bfd. This causes - bfd_check_format to loop over all the targets to find the one - that matches the file being read. */ - -bfd_target * -DEFUN(bfd_find_target,(target_name, abfd), - CONST char *target_name AND - bfd *abfd) -{ - bfd_target **target; - extern char *getenv (); - CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET")); - - /* This is safe; the vector cannot be null */ - if (targname == NULL || !strcmp (targname, "default")) { - abfd->target_defaulted = true; - return abfd->xvec = target_vector[0]; - } - - abfd->target_defaulted = false; - - for (target = &target_vector[0]; *target != NULL; target++) { - if (!strcmp (targname, (*target)->name)) - return abfd->xvec = *target; - } - - bfd_error = invalid_target; - return NULL; -} - - -/* Returns a freshly-consed, NULL-terminated vector of the names of all the - valid bfd targets. Do not modify the names */ - -char ** -bfd_target_list () -{ - int vec_length= 0; - bfd_target **target; - char **name_list, **name_ptr; - - for (target = &target_vector[0]; *target != NULL; target++) - vec_length++; - - name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **)); - - if (name_list == NULL) { - bfd_error = no_memory; - return NULL; - } - - for (target = &target_vector[0]; *target != NULL; target++) - *(name_ptr++) = (*target)->name; - - return name_list; -} - -/* Init a bfd for read of the proper format. If the target was unspecified, - search all the possible targets. */ - -boolean -DEFUN(bfd_check_format,(abfd, format), - bfd *abfd AND - bfd_format format) -{ - bfd_target **target, *save_targ, *right_targ; - int match_count; - - if (!bfd_read_p (abfd) || - ((int)(abfd->format) < (int)bfd_unknown) || - ((int)(abfd->format) >= (int)bfd_type_end)) { - bfd_error = invalid_operation; - return false; - } - - if (abfd->format != bfd_unknown) - return (abfd->format == format)? true: false; - - /* presume the answer is yes */ - abfd->format = format; - - /* If the target type was explicitly specified, just check that target. */ - - if (!abfd->target_defaulted) { - bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */ - - right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (right_targ) { - abfd->xvec = right_targ; /* Set the target as returned */ - return true; /* File position has moved, BTW */ - } - return false; /* Specified target is not right */ - } - - /* Since the target type was defaulted, check them - all in the hope that one will be uniquely recognized. */ - - save_targ = abfd->xvec; - match_count = 0; - right_targ = 0; - - for (target = target_vector; *target != NULL; target++) { - bfd_target *temp; - - abfd->xvec = *target; /* Change BFD's target temporarily */ - bfd_seek (abfd, (file_ptr)0, SEEK_SET); - temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (temp) { /* This format checks out as ok! */ - right_targ = temp; - match_count++; - /* If this is the default target, accept it, even if other targets - might match. People who want those other targets have to set - the GNUTARGET variable. */ - if (temp == default_vector[0]) - break; -#ifdef GNU960 - /* Big- and little-endian b.out archives look the same, but it doesn't - * matter: there is no difference in their headers, and member file byte - * orders will (I hope) be handled appropriately by bfd. Ditto for big - * and little coff archives. And the 4 coff/b.out object formats are - * unambiguous. So accept the first match we find. - */ - break; -#endif - } - } - - if (match_count == 1) { - abfd->xvec = right_targ; /* Change BFD's target permanently */ - return true; /* File position has moved, BTW */ - } - - abfd->xvec = save_targ; /* Restore original target type */ - abfd->format = bfd_unknown; /* Restore original format */ - bfd_error = ((match_count == 0) ? file_not_recognized : - file_ambiguously_recognized); - return false; -} - -boolean -DEFUN(bfd_set_format,(abfd, format), - bfd *abfd AND - bfd_format format) -{ - - if (bfd_read_p (abfd) || - ((int)abfd->format < (int)bfd_unknown) || - ((int)abfd->format >= (int)bfd_type_end)) { - bfd_error = invalid_operation; - return false; - } - - if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false; - - /* presume the answer is yes */ - abfd->format = format; - - if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) { - abfd->format = bfd_unknown; - return false; - } - - return true; -} - -/* Hack object and core file sections */ - -sec_ptr -DEFUN(bfd_get_section_by_name,(abfd, name), - bfd *abfd AND - CONST char *name) -{ - asection *sect; - - for (sect = abfd->sections; sect != NULL; sect = sect->next) - if (!strcmp (sect->name, name)) return sect; - return NULL; -} - -/* If you try to create a section with a name which is already in use, - returns the old section by that name instead. */ -sec_ptr -DEFUN(bfd_make_section,(abfd, name), - bfd *abfd AND - CONST char *CONST name) -{ - asection *newsect; - asection ** prev = &abfd->sections; - asection * sect = abfd->sections; - - if (abfd->output_has_begun) { - bfd_error = invalid_operation; - return NULL; - } - - while (sect) { - if (!strcmp(sect->name, name)) return sect; - prev = §->next; - sect = sect->next; - } - - newsect = (asection *) bfd_zalloc(abfd, sizeof (asection)); - if (newsect == NULL) { - bfd_error = no_memory; - return NULL; - } - - newsect->name = name; - newsect->index = abfd->section_count++; - newsect->flags = SEC_NO_FLAGS; - - newsect->userdata = 0; - newsect->next = (asection *)NULL; - newsect->relocation = (arelent *)NULL; - newsect->reloc_count = 0; - newsect->line_filepos =0; - - if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) { - free (newsect); - return NULL; - } - - *prev = newsect; - return newsect; -} - -/* Call operation on each section. Operation gets three args: the bfd, - the section, and a void * pointer (whatever the user supplied). */ - -/* This is attractive except that without lexical closures its use is hard - to make reentrant. */ -/*VARARGS2*/ -void -bfd_map_over_sections (abfd, operation, user_storage) - bfd *abfd; - void (*operation)(); - PTR user_storage; -{ - asection *sect; - int i = 0; - - for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) - (*operation) (abfd, sect, user_storage); - - if (i != abfd->section_count) /* Debugging */ - abort(); -} - -boolean -bfd_set_section_flags (abfd, section, flags) - bfd *abfd; - sec_ptr section; - flagword flags; -{ - if ((flags & bfd_applicable_section_flags (abfd)) != flags) { - bfd_error = invalid_operation; - return false; - } - - section->flags = flags; -return true; -} - - -boolean -bfd_set_section_size (abfd, ptr, val) - bfd *abfd; - sec_ptr ptr; - unsigned long val; -{ - /* Once you've started writing to any section you cannot create or change - the size of any others. */ - - if (abfd->output_has_begun) { - bfd_error = invalid_operation; - return false; - } - - ptr->size = val; - - return true; -} - -boolean -DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count), - bfd *abfd AND - sec_ptr section AND - PTR location AND - file_ptr offset AND - bfd_size_type count) -{ - if (!(bfd_get_section_flags(abfd, section) & - SEC_HAS_CONTENTS)) { - bfd_error = no_contents; - return(false); - } /* if section has no contents */ - - if (BFD_SEND (abfd, _bfd_set_section_contents, - (abfd, section, location, offset, count))) { - abfd->output_has_begun = true; - return true; - } - - return false; -} - -boolean -DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count), - bfd *abfd AND - sec_ptr section AND - PTR location AND - file_ptr offset AND - bfd_size_type count) -{ - if (section->flags & SEC_CONSTRUCTOR) { - memset(location, 0, (unsigned)count); - return true; - } - else { - return (BFD_SEND (abfd, _bfd_get_section_contents, - (abfd, section, location, offset, count))); - } -} - - -/** Some core file info commands */ - -/* Returns a read-only string explaining what program was running when - it failed. */ - -char * -bfd_core_file_failing_command (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_error = invalid_operation; - return NULL; - } - return BFD_SEND (abfd, _core_file_failing_command, (abfd)); -} - -int -bfd_core_file_failing_signal (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_error = invalid_operation; - return 0; - } - return BFD_SEND (abfd, _core_file_failing_signal, (abfd)); -} - -boolean -core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) { - bfd_error = wrong_format; - return false; - } - - return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd)); -} - + /** Symbols */ -boolean -bfd_set_symtab (abfd, location, symcount) - bfd *abfd; - asymbol **location; - unsigned int symcount; -{ - if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) { - bfd_error = invalid_operation; - return false; - } - - bfd_get_outsymbols (abfd) = location; - bfd_get_symcount (abfd) = symcount; - return true; -} - /* returns the number of octets of storage required */ + unsigned int get_reloc_upper_bound (abfd, asect) bfd *abfd; @@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols) return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols)); } -void -bfd_print_symbol_vandf(file, symbol) -PTR file; -asymbol *symbol; -{ - flagword type = symbol->flags; - if (symbol->section != (asection *)NULL) - { - - fprintf_vma(file, symbol->value+symbol->section->vma); - } - else - { - fprintf_vma(file, symbol->value); - } - fprintf(file," %c%c%c%c%c%c%c", - (type & BSF_LOCAL) ? 'l':' ', - (type & BSF_GLOBAL) ? 'g' : ' ', - (type & BSF_IMPORT) ? 'i' : ' ', - (type & BSF_EXPORT) ? 'e' : ' ', - (type & BSF_UNDEFINED) ? 'u' : ' ', - (type & BSF_FORT_COMM) ? 'c' : ' ', - (type & BSF_DEBUGGING) ? 'd' :' '); - -} - boolean bfd_set_file_flags (abfd, flags) @@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count) asect->orelocation = location; asect->reloc_count = count; } -/* -If an output_bfd is supplied to this function the generated image -will be relocatable, the relocations are copied to the output file -after they have been changed to reflect the new state of the world. -There are two ways of reflecting the results of partial linkage in an -output file; by modifying the output data in place, and by modifying -the relocation record. Some native formats (eg basic a.out and basic -coff) have no way of specifying an addend in the relocation type, so -the addend has to go in the output data. This is no big deal since in -these formats the output data slot will always be big enough for the -addend. Complex reloc types with addends were invented to solve just -this problem. -*/ - -bfd_reloc_status_enum_type -DEFUN(bfd_perform_relocation,(abfd, - reloc_entry, - data, - input_section, - output_bfd), - bfd *abfd AND - arelent *reloc_entry AND - PTR data AND - asection *input_section AND - bfd *output_bfd) -{ - bfd_vma relocation; - bfd_reloc_status_enum_type flag = bfd_reloc_ok; - bfd_vma addr = reloc_entry->address ; - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asection *reloc_target_input_section; - asymbol *symbol; - - if (reloc_entry->sym_ptr_ptr) { - symbol = *( reloc_entry->sym_ptr_ptr); - if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) { - flag = bfd_reloc_undefined; - } - } - else { - symbol = (asymbol*)NULL; - } - - if (howto->special_function){ - bfd_reloc_status_enum_type cont; - cont = howto->special_function(abfd, - reloc_entry, - symbol, - data, - input_section); - if (cont != bfd_reloc_continue) return cont; - } - - /* - Work out which section the relocation is targetted at and the - initial relocation command value. - */ - - - if (symbol != (asymbol *)NULL){ - if (symbol->flags & BSF_FORT_COMM) { - relocation = 0; - } - else { - relocation = symbol->value; - } - if (symbol->section != (asection *)NULL) - { - reloc_target_input_section = symbol->section; - } - else { - reloc_target_input_section = (asection *)NULL; - } - } - else if (reloc_entry->section != (asection *)NULL) - { - relocation = 0; - reloc_target_input_section = reloc_entry->section; - } - else { - relocation = 0; - reloc_target_input_section = (asection *)NULL; - } - - - if (reloc_target_input_section != (asection *)NULL) { - - reloc_target_output_section = - reloc_target_input_section->output_section; - - if (output_bfd && howto->partial_inplace==false) { - output_base = 0; - } - else { - output_base = reloc_target_output_section->vma; - - } - - relocation += output_base + reloc_target_input_section->output_offset; - } - - relocation += reloc_entry->addend ; - - - if(reloc_entry->address > (bfd_vma)(input_section->size)) - { - return bfd_reloc_outofrange; - } - - - if (howto->pc_relative == true) - { - /* - Anything which started out as pc relative should end up that - way too. - - There are two ways we can see a pcrel instruction. Sometimes - the pcrel displacement has been partially calculated, it - includes the distance from the start of the section to the - instruction in it (eg sun3), and sometimes the field is - totally blank - eg m88kbcs. - */ - - - relocation -= - output_base + input_section->output_offset; - - if (howto->pcrel_offset == true) { - relocation -= reloc_entry->address; - } - - } - - if (output_bfd!= (bfd *)NULL) { - if ( howto->partial_inplace == false) { - /* - This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. - */ - reloc_entry->addend = relocation ; - reloc_entry->section = reloc_target_input_section; - if (reloc_target_input_section != (asection *)NULL) { - /* If we know the output section we can forget the symbol */ - reloc_entry->sym_ptr_ptr = (asymbol**)NULL; - } - reloc_entry->address += - input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit - */ - - } - } - - reloc_entry->addend = 0; - - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - relocation >>= howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get - 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 - 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 - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8(abfd, (char *)data + addr); - DOIT(x); - bfd_put_8(abfd,x, (unsigned char *) data + addr); - } - break; - - case 1: - { - short x = bfd_get_16(abfd, (bfd_byte *)data + addr); - DOIT(x); - bfd_put_16(abfd, x, (unsigned char *)data + addr); - } - break; - case 2: - { - long x = bfd_get_32(abfd, (bfd_byte *) data + addr); - DOIT(x); - bfd_put_32(abfd,x, (bfd_byte *)data + addr); - } - break; - case 3: - /* Do nothing */ - break; - default: - return bfd_reloc_other; - } - - return flag; -} void bfd_assert(file, line) @@ -889,6 +350,14 @@ int line; } +/*proto* bfd_set_start_address + +Marks the entry point of an output bfd. Returns @code{true} on +success, @code{false} otherwise. + +*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma)); +*/ + boolean bfd_set_start_address(abfd, vma) bfd *abfd; @@ -899,19 +368,15 @@ bfd_vma vma; } -bfd_vma bfd_log2(x) -bfd_vma x; -{ - bfd_vma result = 0; - while ( (bfd_vma)(1<< result) < x) - result++; - return result; -} +/*proto* bfd_get_mtime + +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) @@ -931,3 +396,33 @@ bfd_get_mtime (abfd) abfd->mtime = buf.st_mtime; return abfd->mtime; } + +/*proto* +*i stuff +*+ +#define bfd_sizeof_headers(abfd, reloc) \ + BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) + +#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \ + BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, section, symbols, offset, filename_ptr, func, line_ptr)) + +#define bfd_debug_info_start(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) + +#define bfd_debug_info_end(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) + +#define bfd_debug_info_accumulate(abfd, section) \ + BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) + +#define bfd_stat_arch_elt(abfd, stat) \ + BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +*- + +*/ + + + + + + diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 63630c38b36..2dea71a3e74 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5,17 +5,234 @@ 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$ */ @@ -23,11 +240,6 @@ You should have received a copy of the GNU General Public License along with #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) \ @@ -38,22 +250,59 @@ You should have received a copy of the GNU General Public License along with #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)); /* void warning(); */ -extern asection abs_section; + static int DEFUN(get_index,(symbol), @@ -71,10 +320,9 @@ DEFUN(set_index,(symbol, idx), } - - - -/* All the swapping routines: +/* ********************************************************************** +Here are all the routines for swapping the structures seen in the +outside world into the internal forms. */ @@ -123,7 +371,7 @@ DEFUN(bfd_swap_filehdr_in,(abfd, filehdr_src, filehdr_dst), 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 @@ -141,11 +389,14 @@ DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out), 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); @@ -165,7 +416,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext, in), 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 @@ -193,13 +444,15 @@ DEFUN(coff_swap_sym_out,(abfd,in, ext), } 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) { @@ -217,14 +470,16 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in), #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]); @@ -232,21 +487,20 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in), 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 @@ -260,7 +514,10 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext), 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 @@ -268,64 +525,86 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext), #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); @@ -339,7 +618,7 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int), #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 @@ -358,7 +637,7 @@ DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out), #endif } -GDB_EXPORT void +static void DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), bfd *abfd AND SCNHDR *scnhdr_ext AND @@ -371,9 +650,14 @@ DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), 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 @@ -393,13 +677,49 @@ DEFUN(swap_scnhdr_out,(abfd, scnhdr_int, scnhdr_ext), 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 @@ -410,19 +730,7 @@ DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore), 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; } @@ -514,23 +822,23 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), 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; @@ -647,53 +955,53 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), 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); +} @@ -706,15 +1014,15 @@ static coff_symbol_type * 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; +} @@ -725,101 +1033,167 @@ DEFUN(coff_symbol_from,(abfd, 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; @@ -891,7 +1265,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), && 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; } @@ -901,17 +1275,18 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), /* 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) @@ -964,7 +1339,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), 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;*/ } @@ -986,16 +1361,209 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), } +#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 */ @@ -1004,160 +1572,48 @@ bfd *abfd) /* 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 @@ -1169,278 +1625,289 @@ bfd *abfd) 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; +} @@ -1449,37 +1916,37 @@ bfd *abfd; /* 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; @@ -1648,10 +2115,8 @@ bfd *abfd) { 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 @@ -1665,6 +2130,7 @@ bfd *abfd) 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); @@ -1699,15 +2165,48 @@ bfd *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); @@ -1765,67 +2264,39 @@ buy_and_read(abfd, where, seek_direction, size) 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 @@ -1835,31 +2306,31 @@ Oh, and the first symbol MUST be a C_FILE. If there wasn't one there 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; @@ -1880,96 +2351,92 @@ bfd *abfd) /* 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; @@ -1994,6 +2461,23 @@ DEFUN(section_from_bfd_index,(abfd, index), +/*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) @@ -2029,7 +2513,7 @@ asection *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; } @@ -2053,193 +2537,193 @@ asection *asect; 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) @@ -2281,6 +2765,33 @@ sec_ptr asect; 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 @@ -2336,7 +2847,12 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), && 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; @@ -2430,7 +2946,7 @@ DEFUN(coff_find_nearest_line,(abfd, 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; @@ -2445,40 +2961,16 @@ DEFUN(coff_find_nearest_line,(abfd, 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 */ /* @@ -2503,16 +2995,16 @@ DEFUN(coff_find_nearest_line,(abfd, 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; } } @@ -2530,6 +3022,7 @@ DEFUN(coff_find_nearest_line,(abfd, cache_offset = offset; cache_i = i; cache_l = l; + return true; } @@ -2572,3 +3065,7 @@ DEFUN(coff_sizeof_headers,(abfd, reloc), #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 diff --git a/bfd/ieee.c b/bfd/ieee.c index 5a532ea5ab3..801f6eee88f 100644 --- a/bfd/ieee.c +++ b/bfd/ieee.c @@ -119,14 +119,14 @@ standard requires: */ -#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); @@ -136,7 +136,7 @@ DEFUN(read_2bytes,(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) { @@ -148,7 +148,7 @@ DEFUN(bfd_get_string,(ieee, string, length), static char * DEFUN(read_id,(ieee), - ieee_data_type *ieee) + common_header_type *ieee) { size_t length; char *string; @@ -272,7 +272,7 @@ DEFUN(ieee_write_int5_out, (abfd, value), 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); @@ -297,7 +297,7 @@ DEFUN(parse_int,(ieee, value_ptr), } static int DEFUN(parse_i,(ieee, ok), - ieee_data_type *ieee AND + common_header_type *ieee AND boolean *ok) { bfd_vma x; @@ -307,7 +307,7 @@ DEFUN(parse_i,(ieee, ok), 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); @@ -364,15 +364,15 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), 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); @@ -380,29 +380,29 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), } 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); @@ -413,7 +413,7 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), 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); @@ -427,7 +427,7 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), 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); @@ -437,9 +437,9 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), 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); } @@ -472,7 +472,9 @@ DEFUN(parse_expression,(ieee, value, section, symbol, pcrel, extra), #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), @@ -492,21 +494,21 @@ 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; @@ -516,13 +518,13 @@ DEFUN(ieee_slurp_external_symbols,(abfd), 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; @@ -532,10 +534,10 @@ DEFUN(ieee_slurp_external_symbols,(abfd), 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, @@ -553,13 +555,13 @@ DEFUN(ieee_slurp_external_symbols,(abfd), 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 */ @@ -569,14 +571,14 @@ DEFUN(ieee_slurp_external_symbols,(abfd), 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; @@ -715,12 +717,12 @@ DEFUN(ieee_slurp_sections,(abfd), 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); @@ -728,24 +730,24 @@ DEFUN(ieee_slurp_sections,(abfd), 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; @@ -753,11 +755,11 @@ DEFUN(ieee_slurp_sections,(abfd), 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); } @@ -767,47 +769,47 @@ DEFUN(ieee_slurp_sections,(abfd), { 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; @@ -828,81 +830,107 @@ bfd_target * 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; } @@ -922,8 +950,8 @@ DEFUN(ieee_object_p,(abfd), /* 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; @@ -932,46 +960,46 @@ DEFUN(ieee_object_p,(abfd), 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; } @@ -984,10 +1012,10 @@ DEFUN(ieee_object_p,(abfd), 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; @@ -1049,18 +1077,18 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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; @@ -1068,10 +1096,10 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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: @@ -1083,13 +1111,13 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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, @@ -1097,24 +1125,24 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), &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 @@ -1126,14 +1154,14 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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; } @@ -1141,12 +1169,12 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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; @@ -1161,11 +1189,11 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), 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 { @@ -1178,7 +1206,7 @@ DEFUN(do_one,(ieee, current_map, location_ptr,s), } } - /* 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) @@ -1199,7 +1227,7 @@ DEFUN(ieee_slurp_section_data,(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); @@ -1208,15 +1236,15 @@ DEFUN(ieee_slurp_section_data,(abfd), 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; @@ -1228,8 +1256,8 @@ DEFUN(ieee_slurp_section_data,(abfd), 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: { @@ -1238,8 +1266,8 @@ DEFUN(ieee_slurp_section_data,(abfd), 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; @@ -1259,18 +1287,31 @@ DEFUN(ieee_slurp_section_data,(abfd), { /* 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; @@ -1393,32 +1434,42 @@ DEFUN(ieee_write_section_part,(abfd), 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); @@ -1430,7 +1481,7 @@ DEFUN(ieee_write_section_part,(abfd), 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); @@ -1439,128 +1490,737 @@ DEFUN(ieee_write_section_part,(abfd), -/* 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); + } + } } @@ -1650,10 +2310,20 @@ DEFUN(ieee_write_external_part,(abfd), 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 { @@ -1701,14 +2371,36 @@ DEFUN(ieee_write_object_contents,(abfd), 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 @@ -1718,6 +2410,13 @@ DEFUN(ieee_write_object_contents,(abfd), 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 @@ -1765,9 +2464,9 @@ DEFUN(ieee_make_empty_symbol,(abfd), } 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 */ @@ -1788,6 +2487,7 @@ bfd *prev; } } else { + bfd_error = no_more_archived_files; return (bfd *)NULL; } @@ -1838,13 +2538,76 @@ DEFUN(ieee_sizeof_headers,(abfd, x), 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 @@ -1863,6 +2626,7 @@ bfd_target ieee_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 */ diff --git a/bfd/libbfd.c b/bfd/libbfd.c index ff64c281827..eb3515a74a4 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -138,10 +138,10 @@ DEFUN(zalloc,(size), 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); } @@ -171,43 +171,44 @@ DEFUN(bfd_seek,(abfd, position, direction), 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; } /** 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 */ @@ -227,7 +228,7 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr), /* 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) { @@ -265,21 +266,76 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr), /* 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 @@ -287,31 +343,31 @@ DEFUN(_do_putb16,(data, addr), 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 @@ -322,18 +378,20 @@ DEFUN(_do_getb64,(addr), 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 } @@ -342,22 +400,26 @@ bfd_64_type DEFUN(_do_getl64,(addr), register bfd_byte *addr) { - bfd_64_type low, high; + #ifdef HOST_64_BIT + bfd_64_type low, high; high= (((((((addr[7] << 8) | - addr[6]) << 8) | - addr[5]) << 8) | - 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 @@ -365,10 +427,10 @@ DEFUN(_do_putb32,(data, addr), 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 @@ -376,15 +438,15 @@ DEFUN(_do_putl32,(data, addr), 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)); @@ -433,10 +495,26 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count) 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; +} diff --git a/bfd/libbfd.h b/bfd/libbfd.h index bef46ddd59b..795682b58e1 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -65,14 +65,17 @@ PROTO (char *, zalloc, (bfd_size_type size)); PROTO(PTR, bfd_alloc, (bfd *abfd, bfd_size_type size)); PROTO(PTR, bfd_zalloc,(bfd *abfd, bfd_size_type size)); PROTO(PTR, bfd_realloc,(bfd *abfd, PTR orig, bfd_size_type new)); +PROTO(void, bfd_alloc_grow,(bfd *abfd, PTR thing, bfd_size_type size)); +PROTO(PTR, bfd_alloc_finish,(bfd *abfd)); + #define bfd_release(x,y) (void) obstack_free(&(x->memory),y) -PROTO (bfd_target *, bfd_find_target, (CONST char *target_name, bfd *)); + PROTO (bfd_size_type, bfd_read, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); PROTO (bfd_size_type, bfd_write, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -PROTO (FILE *, bfd_cache_lookup, (bfd *)); -PROTO (void, bfd_cache_close, (bfd *)); + + PROTO (int, bfd_seek,(bfd* abfd, file_ptr fp , int direction)); PROTO (long, bfd_tell, (bfd *abfd)); PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd)); @@ -161,8 +164,6 @@ PROTO (void, bfd_assert,(char*,int)); PROTO (FILE *, bfd_cache_lookup_worker, (bfd *)); extern bfd *bfd_last_cache; -#define bfd_cache_lookup(x) \ - (x==bfd_last_cache?(FILE*)(bfd_last_cache->iostream):bfd_cache_lookup_worker(x)) /* Now Steve, what's the story here? */ #ifdef lint @@ -175,3 +176,51 @@ extern bfd *bfd_last_cache; /* Generic routine for close_and_cleanup is really just bfd_true. */ #define bfd_generic_close_and_cleanup bfd_true + +/* THE FOLLOWING IS EXTRACTED FROM THE SOURCE*/ + +/* Return the log base 2 of the value supplied, rounded up. eg an arg +of 1025 would return 11. +*/ +PROTO(bfd_vma, bfd_log2,(bfd_vma x)); +/* The maxiumum number of files which the cache will keep open at one +time. +*/ +#define BFD_CACHE_MAX_OPEN 10 + +/* Zero, or a pointer to the topmost bfd on the chain. This is used by the +bfd_cache_lookup() macro in libbfd.h to determine when it can avoid a function +call. +*/ +extern bfd *bfd_last_cache; + +/* Checks to see if the required bfd is the same as the last one looked +up. If so then it can use the iostream in the bfd with impunity, since +it can't have changed since the last lookup, otherwise it has to +perform the complicated lookup function +*/ +#define bfd_cache_lookup(x) \ + ((x)==bfd_last_cache? \ + (FILE*)(bfd_last_cache->iostream): \ + bfd_cache_lookup_worker(x)) + + +/* Initialize a BFD by putting it on the cache LRU. +*/ +PROTO(void, bfd_cache_init, (bfd *)); +/* Remove the bfd from the cache. If the attatched file is open, then close it too. +*/ +PROTO(void, bfd_cache_close, (bfd *)); +/* Call the OS to open a file for this BFD. Returns the FILE * +(possibly null) that results from this operation. Sets up the +BFD so that future accesses know the file is open. If the FILE * +returned is null, then there is won't have been put in the cache, so +it won't have to be removed from it. +*/ +PROTO(FILE *, bfd_open_file, (bfd *)); +/* Called when the macro @code{bfd_cache_lookup} fails to find a quick +answer. Finds a file descriptor for this BFD. If necessary, it open it. +If there are already more than BFD_CACHE_MAX_OPEN files open, it trys to close +one first, to avoid running out of file descriptors. +*/ +PROTO(FILE *, bfd_cache_lookup_worker, (bfd *)); diff --git a/bfd/newsos3.c b/bfd/newsos3.c index a14a91c4d6e..e16648f95d0 100644 --- a/bfd/newsos3.c +++ b/bfd/newsos3.c @@ -31,16 +31,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "libbfd.h" #include "aout64.h" + +/**From: bothner@cs.wisc.edu***********************************************/ +#undef N_TXTOFF +#define N_TXTOFF(x) ( (N_MAGIC((x)) == ZMAGIC) ? PAGE_SIZE : EXEC_BYTES_SIZE) +/**************************************************************************/ + #include "stab.gnu.h" #include "ar.h" #include "libaout.h" /* BFD a.out internal data structures */ - +#if 0 int vfprintf(file, format, args) /* Temporary crock! */ FILE *file; char *format; char *args; { return _doprnt (format, args, file); } - +#endif bfd_target *newsos3_callback (); @@ -49,7 +55,7 @@ bfd_target * DEFUN(newsos3_object_p,(abfd), bfd *abfd) { - unsigned char magicbuf[LONG_SIZE]; /* Raw bytes of magic number from file */ + unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ unsigned long magic; /* Swapped magic number */ bfd_error = system_call_error; @@ -99,19 +105,40 @@ DEFUN(newsos3_write_object_contents,(abfd), /* Transfer vectors for NEWS-OS version 3 */ /* We use BFD generic archive files. */ -#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file -#define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define aout_32_slurp_armap bfd_slurp_bsd_armap -#define aout_32_slurp_extended_name_table bfd_true -#define aout_32_write_armap bsd_write_armap -#define aout_32_truncate_arname bfd_bsd_truncate_arname +#define newsos_openr_next_archived_file bfd_generic_openr_next_archived_file +#define newsos_generic_stat_arch_elt bfd_generic_stat_arch_elt +#define newsos_slurp_armap bfd_slurp_bsd_armap +#define newsos_slurp_extended_name_table bfd_true +#define newsos_write_armap bsd_write_armap +#define newsos_truncate_arname bfd_bsd_truncate_arname /* We don't support core files yet. FIXME. */ -#define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command -#define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal -#define aout_32_core_file_matches_executable_p \ +#define newsos_core_file_failing_command _bfd_dummy_core_file_failing_command +#define newsos_core_file_failing_signal _bfd_dummy_core_file_failing_signal +#define newsos_core_file_matches_executable_p \ _bfd_dummy_core_file_matches_executable_p -#define aout_32_core_file_p _bfd_dummy_target +#define newsos_core_file_p _bfd_dummy_target + +#define newsos_bfd_debug_info_start bfd_void +#define newsos_bfd_debug_info_end bfd_void +#define newsos_bfd_debug_info_accumulate bfd_void + +#define newsos_mkobject aout_32_mkobject +#define newsos_close_and_cleanup aout_32_close_and_cleanup +#define newsos_set_section_contents aout_32_set_section_contents +#define newsos_get_section_contents aout_32_get_section_contents +#define newsos_new_section_hook aout_32_new_section_hook +#define newsos_get_symtab_upper_bound aout_32_get_symtab_upper_bound +#define newsos_get_symtab aout_32_get_symtab +#define newsos_get_reloc_upper_bound aout_32_get_reloc_upper_bound +#define newsos_canonicalize_reloc aout_32_canonicalize_reloc +#define newsos_make_empty_symbol aout_32_make_empty_symbol +#define newsos_print_symbol aout_32_print_symbol +#define newsos_get_lineno aout_32_get_lineno +#define newsos_set_arch_mach aout_32_set_arch_mach +#define newsos_find_nearest_line aout_32_find_nearest_line +#define newsos_sizeof_headers aout_32_sizeof_headers + /* We define our own versions of these routines. */ @@ -128,16 +155,16 @@ bfd_target newsos3_vec = /* Sony 68k-based machines running newos3 */ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ ' ', /* ar_pad_char */ 16, /* ar_max_namelen */ - + 1, /* minimum alignment */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */ {_bfd_dummy_target, newsos3_object_p, /* bfd_check_format */ - bfd_generic_archive_p, aout_32_core_file_p}, - {bfd_false, aout_32_mkobject, /* bfd_set_format */ + bfd_generic_archive_p, newsos_core_file_p}, + {bfd_false, newsos_mkobject, /* bfd_set_format */ _bfd_generic_mkarchive, bfd_false}, {bfd_false, newsos3_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, - JUMP_TABLE(aout_32) + JUMP_TABLE(newsos) }; diff --git a/bfd/oasys.c b/bfd/oasys.c index 4719273ad11..196bb120eea 100644 --- a/bfd/oasys.c +++ b/bfd/oasys.c @@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "libbfd.h" #include "oasys.h" #include "liboasys.h" + + +/* Read in all the section data and relocation stuff too */ +PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd)); + static void DEFUN(oasys_read_record,(abfd, record), bfd *CONST abfd AND @@ -127,6 +132,12 @@ DEFUN(oasys_slurp_symbol_table,(abfd), if (record.header.type == oasys_record_is_local_enum) { dest->flags = BSF_LOCAL; + if (dest->section ==(asection *)(~0)) { + /* It seems that sometimes internal symbols are tied up, but + still get output, even though there is no + section */ + dest->section = 0; + } } else { @@ -258,7 +269,7 @@ DEFUN(oasys_archive_p,(abfd), oasys_module_table_type record; - oasys_external_module_table_type record_ext; + set_tdata(abfd, ar); ar->module = module; @@ -268,25 +279,53 @@ DEFUN(oasys_archive_p,(abfd), 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; @@ -375,7 +414,7 @@ DEFUN(oasys_object_p,(abfd), s->size = bfd_h_get_32(abfd, & record.section.value[0]) ; s->vma = bfd_h_get_32(abfd, &record.section.vma[0]); - s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; + s->flags= 0; had_usefull = true; } break; @@ -402,6 +441,14 @@ DEFUN(oasys_object_p,(abfd), if (abfd->symcount != 0) { abfd->flags |= HAS_SYMS; } + + /* + We don't know if a section has data until we've read it.. + */ + + oasys_slurp_section_data(abfd); + + return abfd->xvec; fail: @@ -465,169 +512,185 @@ DEFUN(oasys_slurp_section_data,(abfd), asection *s; - /* Buy enough memory for all the section data and relocations */ + /* See if the data has been slurped already .. */ for (s = abfd->sections; s != (asection *)NULL; s= s->next) { per = oasys_per_section(s); - if (per->data != (bfd_byte*)NULL) return true; - per->data = (bfd_byte *) bfd_alloc(abfd, s->size); - per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation); - per->had_vma = false; - s->reloc_count = 0; + if (per->initialized == true) + return true; } if (data->first_data_record == 0) return true; + bfd_seek(abfd, data->first_data_record, SEEK_SET); while (loop) { oasys_read_record(abfd, &record); - switch (record.header.type) { - 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; } @@ -646,7 +709,8 @@ DEFUN(oasys_new_section_hook,(abfd, newsect), oasys_per_section( newsect)->data = (bfd_byte *)NULL; oasys_per_section(newsect)->section = newsect; oasys_per_section(newsect)->offset = 0; - newsect->alignment_power = 3; + oasys_per_section(newsect)->initialized = false; + newsect->alignment_power = 1; /* Turn the section string into an index */ sscanf(newsect->name,"%u", &newsect->target_index); @@ -674,7 +738,14 @@ DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count), { oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd; oasys_slurp_section_data(abfd); - (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; } @@ -781,7 +852,15 @@ DEFUN(oasys_write_syms, (abfd), 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]) { @@ -900,140 +979,142 @@ DEFUN(oasys_write_data, (abfd), { 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<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<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 @@ -1180,17 +1261,20 @@ DEFUN(oasys_sizeof_headers,(abfd, exec), { return 0; } - +#define FOO PROTO #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr) #define oasys_core_file_failing_signal (int (*)())bfd_0 -#define oasys_core_file_matches_executable_p 0 /*(PROTO(boolean, (*),(bfd*, bfd*)))bfd_false*/ +#define oasys_core_file_matches_executable_p 0 #define oasys_slurp_armap bfd_true #define oasys_slurp_extended_name_table bfd_true #define oasys_truncate_arname (void (*)())bfd_nullvoidptr -#define oasys_write_armap 0 /* (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr*/ +#define oasys_write_armap 0 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr #define oasys_close_and_cleanup bfd_generic_close_and_cleanup +#define oasys_bfd_debug_info_start bfd_void +#define oasys_bfd_debug_info_end bfd_void +#define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void /*SUPPRESS 460 */ @@ -1207,7 +1291,7 @@ bfd_target oasys_vec = |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ ' ', /* ar_pad_char */ 16, /* ar_max_namelen */ - + 1, /* minimum alignment */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */ diff --git a/bfd/opncls.c b/bfd/opncls.c index 84c66510a74..2601ef022d0 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -96,8 +96,19 @@ bfd *obfd; return nbfd; } -/** bfd_openr, bfd_fdopenr -- open for reading. - Returns a pointer to a freshly-allocated bfd on success, or NULL. */ +/*doc* +@section Opening and Closing BFDs + +*/ +/*proto* +*i bfd_openr +Opens the file supplied (using fopen) with the target supplied, it +returns a pointer to the created bfd. + +If NULL is returned then an error has occured. +Possible errors are no_memory, invalid_target or system_call error. +*; PROTO(bfd*, bfd_openr, (CONST char *filename,CONST char*target)); +*-*/ bfd * DEFUN(bfd_openr, (filename, target), @@ -139,6 +150,15 @@ DEFUN(bfd_openr, (filename, target), close it if anything goes wrong. Closing the stream means closing the file descriptor too, even though we didn't open it. */ +/*proto* +*i bfd_fdopenr +bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen. It opens a bfd on +a file already described by the @var{fd} supplied. + +Possible errors are no_memory, invalid_target and system_call error. +*; PROTO(bfd *, bfd_fdopenr, + (CONST char *filename, CONST char *target, int fd)); +*-*/ bfd * DEFUN(bfd_fdopenr,(filename, target, fd), @@ -155,7 +175,7 @@ DEFUN(bfd_fdopenr,(filename, target, fd), bfd_error = system_call_error; - fdflags = fcntl (fd, F_GETFL); + fdflags = fcntl (fd, F_GETFL, NULL); if (fdflags == -1) return NULL; #ifdef BFD_LOCKS @@ -214,6 +234,14 @@ DEFUN(bfd_fdopenr,(filename, target, fd), See comment by bfd_fdopenr before you try to modify this function. */ +/*proto* bfd_openw +Creates a bfd, associated with file @var{filename}, using the file +format @var{target}, and returns a pointer to it. + +Possible errors are system_call_error, no_memory, invalid_target. +*; PROTO(bfd *, bfd_openw, (CONST char *filename, CONST char *target)); +*/ + bfd * DEFUN(bfd_openw,(filename, target), CONST char *filename AND @@ -246,11 +274,22 @@ DEFUN(bfd_openw,(filename, target), } return nbfd; } - -/* Close up shop, get your deposit back. */ + +/*proto* bfd_close +This function closes a bfd. If the bfd was open for writing, then +pending operations are completed and the file written out and closed. +If the created file is executable, then @code{chmod} is called to mark +it as such. + +All memory attatched to the bfd's obstacks is released. + +@code{true} is returned if all is ok, otherwise @code{false}. +*; PROTO(boolean, bfd_close,(bfd *)); +*/ + boolean -bfd_close (abfd) - bfd *abfd; +DEFUN(bfd_close,(abfd), + bfd *abfd) { if (!bfd_read_p(abfd)) if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true) @@ -283,12 +322,18 @@ bfd_close (abfd) return true; } -/* Create a bfd with no associated file or target. */ +/*proto* bfd_create +This routine creates a new bfd in the manner of bfd_openw, but without +opening a file. The new bfd takes the target from the target used by +@var{template}. The format is always set to @code{bfd_object}. + +*; PROTO(bfd *, bfd_create, (CONST char *filename, bfd *template)); +*/ bfd * DEFUN(bfd_create,(filename, template), CONST char *filename AND - CONST bfd *template) + bfd *template) { bfd *nbfd = new_bfd(); if (nbfd == (bfd *)NULL) { @@ -313,6 +358,20 @@ DEFUN(PTR bfd_alloc_by_size_t,(abfd, size), PTR res = obstack_alloc(&(abfd->memory), size); return res; } + +DEFUN(void bfd_alloc_grow,(abfd, ptr, size), + bfd *abfd AND + PTR ptr AND + bfd_size_type size) +{ + obstack_grow(&(abfd->memory), ptr, size); +} +DEFUN(PTR bfd_alloc_finish,(abfd), + bfd *abfd) +{ + return obstack_finish(&(abfd->memory)); +} + DEFUN(PTR bfd_alloc, (abfd, size), bfd *abfd AND bfd_size_type size) @@ -339,8 +398,14 @@ DEFUN(PTR bfd_realloc,(abfd, old, size), return res; } +/*proto* bfd_alloc_size +Return the number of bytes in the obstacks connected to the supplied +bfd. +*; PROTO(bfd_size_type,bfd_alloc_size,(bfd *abfd)); +*/ -DEFUN(bfd_size_type bfd_alloc_size,(abfd), +bfd_size_type +DEFUN( bfd_alloc_size,(abfd), bfd *abfd) { struct _obstack_chunk *chunk = abfd->memory.chunk; diff --git a/bfd/srec.c b/bfd/srec.c index aef929bc6c5..9ba2f7647f9 100644 --- a/bfd/srec.c +++ b/bfd/srec.c @@ -187,7 +187,7 @@ asection *section; + (HEX(buffer.u.type_3.address+1) << 16) + (HEX(buffer.u.type_3.address+2) << 8) + (HEX(buffer.u.type_3.address+3)); - func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1); + func(abfd,section, address, buffer.u.type_3.data, bytes_on_line -1); break; @@ -320,7 +320,7 @@ int bytes_to_do; check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0); size = bytes_this_chunk + 5; data = buffer.u.type_3.data; - + break; case 2: check_sum = TOHEX(buffer.u.type_3.address, address >> 16); check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8); @@ -334,6 +334,7 @@ int bytes_to_do; check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0); size = bytes_this_chunk + 3; data = buffer.u.type_1.data; + break; } for (i = 0; i < bytes_this_chunk; i++) { @@ -380,31 +381,32 @@ DEFUN(srec_make_empty_symbol, (abfd), new->the_bfd = abfd; return new; } -/*SUPPRESS 460 */ - -#define srec_new_section_hook (PROTO(boolean, (*), (bfd *, asection *)))bfd_true +#define FOO PROTO +#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true #define srec_get_symtab_upper_bound bfd_false -#define srec_get_symtab (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0 -#define srec_get_reloc_upper_bound (PROTO(unsigned int, (*),(bfd*, asection *)))bfd_false -#define srec_canonicalize_reloc (PROTO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0 +#define srec_get_symtab (FOO(unsigned int, (*), (bfd *, asymbol **)))bfd_0 +#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false +#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0 -#define srec_print_symbol (PROTO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void +#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void -#define srec_openr_next_archived_file (PROTO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr -#define srec_find_nearest_line (PROTO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false -#define srec_generic_stat_arch_elt (PROTO(int, (*), (bfd *,struct stat *))) bfd_0 +#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr +#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false +#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr) #define srec_core_file_failing_signal (int (*)())bfd_0 -#define srec_core_file_matches_executable_p (PROTO(boolean, (*),(bfd*, bfd*)))bfd_false +#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false #define srec_slurp_armap bfd_true #define srec_slurp_extended_name_table bfd_true #define srec_truncate_arname (void (*)())bfd_nullvoidptr -#define srec_write_armap (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr +#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr - #define srec_close_and_cleanup bfd_generic_close_and_cleanup +#define srec_bfd_debug_info_start bfd_void +#define srec_bfd_debug_info_end bfd_void +#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void bfd_target srec_vec = @@ -420,6 +422,7 @@ bfd_target srec_vec = |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ ' ', /* ar_pad_char */ 16, /* ar_max_namelen */ + 1, /* minimum alignment */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */ diff --git a/bfd/targets.c b/bfd/targets.c index 22cda5c8c7a..4a0236e8e89 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -19,13 +19,262 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id$ */ -/* This -*- C -*- source file will someday be machine-generated */ - -/*** Defines the target vector through which operations dispatch */ #include #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; @@ -46,93 +295,93 @@ extern bfd_target DEFAULT_VECTOR; #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 */ }; @@ -141,7 +390,85 @@ bfd_target *target_vector[] = { 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; +}