diff options
author | John Gilmore <gnu@cygnus> | 1991-10-25 07:06:02 +0000 |
---|---|---|
committer | John Gilmore <gnu@cygnus> | 1991-10-25 07:06:02 +0000 |
commit | cbdc790909da22bc1114e681765b152e650aa92b (patch) | |
tree | ca55e91a8ba4fc80a9eed11c59049bdbf1f35dac | |
parent | c8c0a2bd59cf277c1ebaf857b4e84eff91b94580 (diff) | |
download | gdb-cbdc790909da22bc1114e681765b152e650aa92b.zip gdb-cbdc790909da22bc1114e681765b152e650aa92b.tar.gz gdb-cbdc790909da22bc1114e681765b152e650aa92b.tar.bz2 |
RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and John Gilmore.
-rw-r--r-- | bfd/ChangeLog | 28 | ||||
-rw-r--r-- | bfd/Makefile.in | 16 | ||||
-rw-r--r-- | bfd/aoutx.h | 11 | ||||
-rw-r--r-- | bfd/archures.c | 180 | ||||
-rw-r--r-- | bfd/bfd-in.h | 20 | ||||
-rw-r--r-- | bfd/bfd.c | 23 | ||||
-rw-r--r-- | bfd/coffcode.h | 718 | ||||
-rw-r--r-- | bfd/configure.in | 6 | ||||
-rw-r--r-- | bfd/section.c | 33 | ||||
-rw-r--r-- | bfd/targets.c | 6 |
10 files changed, 621 insertions, 420 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 47d356b..2acd974 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,31 @@ +Thu Oct 24 22:40:07 1991 John Gilmore (gnu at cygnus.com) + + RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and + John Gilmore. + + * Makefile.in: Add cpu-rs6000.c and rs6000coff.c. + * configure.in: Add rs6000 case. + * targets.c: Add rs6000 vector. + * archures.c: Add rs6000, fix comment on romp. + * bfd-in.h (enum bfd_error): Add no_debug_section error. + * libcoff-in.h (struct coff_tdata): Remove unused string_table. + * bfd.c (bfd_errmsgs): Add no_debug_section error message. + * section.c (bfd_make_section): Return NULL on attempt to create + a section twice. + * coffcode.h (bfd_swap_reloc_in): Handle r_type and r_size. + (bfd_swap_aouthdr_in): Handle lots more members. + (make_a_section_from_file): If section has already been seen, + just return false rather than overwriting it. + (coff_real_object_p): Understand incoming magic numbers. + (coff_set_flags): Understand outgoing magic numbers. + (coff_compute_section_file_positions): outgoing aouthdr magic #. + (build_debug_section): Add fn for reading debug string section. + (get_normalized_symtab): Handle symbol names in debug string section. + Remove unused obj_string_table. + (coff_slurp_symbol_table): Handle rs6000-specific storage classes. + * aoutx.h (translate_from_native_sym_flags, N_SET*): Check for + existing section before making one. + Thu Oct 24 02:03:24 1991 Fred Fish (fnf at cygnus.com) * elf.c: Add partial support for ELF format corefiles. Still needs diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 71079c0..f67d864 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -43,12 +43,13 @@ CFLAGS = -g $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \ archures.o core.o section.o format.o syms.o reloc.o init.o -BFD_MACHINES=cpu-h8300.o cpu-i960.o cpu-sparc.o cpu-m68k.o cpu-m88k.o \ - cpu-vax.o cpu-mips.o cpu-a29k.o cpu-i386.o +BFD_MACHINES = cpu-h8300.o cpu-i960.o cpu-sparc.o cpu-m68k.o cpu-m88k.o \ + cpu-vax.o cpu-mips.o cpu-a29k.o cpu-i386.o cpu-rs6000.o BFD_BACKENDS = oasys.o ieee.o srec.o \ aout64.o aout32.o demo64.o sunos.o newsos3.o i386aout.o bout.o \ - icoff.o amdcoff.o m68kcoff.o i386coff.o m88k-bcs.o ecoff.o elf.o + icoff.o amdcoff.o m68kcoff.o i386coff.o m88k-bcs.o ecoff.o elf.o \ + rs6000coff.o OPTIONAL_BACKENDS = trad-core.o @@ -58,11 +59,11 @@ BFD_H=$(INCDIR)/bfd.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 amdcoff.c \ + oasys.c ieee.c m68kcoff.c amdcoff.c rs6000coff.c \ format.c section.c core.c syms.c reloc.c init.c \ m88k-bcs.c ecoff.c trad-core.c newsos3.c i386aout.c bout.c elf.c \ cpu-h8300.c cpu-i960.c cpu-sparc.c cpu-m68k.c cpu-m88k.c \ - cpu-vax.c cpu-mips.c cpu-a29k.c cpu-i386.o + cpu-vax.c cpu-mips.c cpu-a29k.c cpu-i386.c cpu-rs6000.c STAGESTUFF = $(TARGETLIB) $(OFILES) @@ -125,6 +126,9 @@ $(BFD_MACHINES): libbfd.h $(BFD_H) $(RECONFIG) $(BFD_BACKENDS): libbfd.h $(BFD_H) $(RECONFIG) $(OPTIONAL_BACKENDS): libbfd.h $(BFD_H) $(RECONFIG) +# Get around a Sun Make bug in SunOS 4.1.1 with VPATH +cpu-i386.o:cpu-i386.c + saber: #suppress 65 on bfd_map_over_sections #suppress 66 on bfd_map_over_sections @@ -262,6 +266,8 @@ m68kcoff.o : m68kcoff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \ $(INCDIR)/m68kcoff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h amdcoff.o : amdcoff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \ $(INCDIR)/amdcoff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h +rs6000coff.o: rs6000coff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \ + $(INCDIR)/rs6000coff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h format.o : format.c $(INCDIR)/bfd.h \ $(INCDIR)/obstack.h libbfd.h section.o : section.c $(INCDIR)/bfd.h \ diff --git a/bfd/aoutx.h b/bfd/aoutx.h index ae53c8d..1cdba1b 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -700,7 +700,10 @@ bfd *abfd) asection *section ; arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain)); strcpy(copy, cache_ptr->symbol.name); - section = bfd_make_section(abfd,copy); + section = bfd_get_section_by_name (abfd, copy); + if (!section) + section = bfd_make_section(abfd,copy); + switch ( (cache_ptr->type & N_TYPE) ) { case N_SETA: section->flags = SEC_CONSTRUCTOR; @@ -1700,9 +1703,9 @@ DEFUN(NAME(aout,find_nearest_line),(abfd, } int -DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable), - bfd *ignore_abfd AND +DEFUN(NAME(aout,sizeof_headers),(abfd, execable), + bfd *abfd AND boolean execable) { - return EXEC_BYTES_SIZE; + return adata(abfd)->exec_bytes_size; } diff --git a/bfd/archures.c b/bfd/archures.c index f8d7418..9141d5e 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -22,11 +22,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*doc* @section Architectures BFD's idea of an architecture is implimented in @code{archures.c}. BFD -keeps one atoms in a BFD describing the architecture of the data -attached to the BFD; a pointer to a @code{bfd_arch_info_struct}. +keeps one atom in a BFD describing the architecture of the data +attached to the BFD; a pointer to a @code{bfd_arch_info_type}. Pointers to structures can be requested independently of a bfd so that -an archictectures information can be interrogated without access to an +an architecture's information can be interrogated without access to an open bfd. The arch information is provided by each architecture package. The @@ -82,12 +82,13 @@ enum bfd_architecture bfd_arch_ns32k, {* National Semiconductor 32xxx *} bfd_arch_tahoe, {* CCI/Harris Tahoe *} bfd_arch_i860, {* Intel 860 *} - bfd_arch_romp, {* IBM ROMP RS/6000 *} + bfd_arch_romp, {* IBM ROMP PC/RT *} bfd_arch_alliant, {* Alliant *} bfd_arch_convex, {* Convex *} bfd_arch_m88k, {* Motorola 88xxx *} bfd_arch_pyramid, {* Pyramid Technology *} bfd_arch_h8300, {* Hitachi H8/300 *} + bfd_arch_rs6000, {* IBM RS/6000 *} bfd_arch_last }; *- @@ -100,16 +101,16 @@ stuff /* $Id$ */ -#include <sysdep.h> #include "bfd.h" +#include "sysdep.h" #include "libbfd.h" -/*proto* bfd_arch_info_struct +/*proto* bfd_arch_info This structure contains information on architectures. *+ -typedef int bfd_reloc_code_enum_type; +typedef int bfd_reloc_code_type; -typedef struct bfd_arch_info_struct +typedef struct bfd_arch_info { int bits_per_word; int bits_per_address; @@ -120,52 +121,25 @@ typedef struct bfd_arch_info_struct CONST char *printable_name; {* true if this is the default machine for the architecture *} boolean the_default; - CONST struct bfd_arch_info_struct * EXFUN((*compatible),(CONST struct bfd_arch_info_struct *a, - CONST struct bfd_arch_info_struct *b)); + CONST struct bfd_arch_info * EXFUN((*compatible),(CONST struct bfd_arch_info *a, + CONST struct bfd_arch_info *b)); - - boolean EXFUN((*scan),(CONST struct bfd_arch_info_struct *,CONST char *)); + boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *)); unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data, PTR stream)); - CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (bfd_reloc_code_enum_type code)); + CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (CONST struct + bfd_arch_info *, + bfd_reloc_code_type code)); - struct bfd_arch_info_struct *next; + struct bfd_arch_info *next; -} bfd_arch_info_struct_type; +} bfd_arch_info_type; *- */ -bfd_arch_info_struct_type *bfd_arch_info_list; - -/*proto* bfd_printable_arch_mach -Return a printable string representing the architecture and machine -type. - -NB. The use of this routine is depreciated. - -*; PROTO(CONST char *,bfd_printable_arch_mach, - (enum bfd_architecture arch, unsigned long machine)); -*/ - -CONST char * -DEFUN(bfd_printable_arch_mach,(arch, machine), - enum bfd_architecture arch AND - unsigned long machine) -{ - bfd_arch_info_struct_type *ap; - bfd_check_init(); - for (ap = bfd_arch_info_list; - ap != (bfd_arch_info_struct_type *)NULL; - ap = ap->next) { - if (ap->arch == arch && - ((ap->mach == machine) || (ap->the_default && machine == 0))) { - return ap->printable_name; - } - } - return "UNKNOWN!"; -} +bfd_arch_info_type *bfd_arch_info_list; /*proto* bfd_printable_name @@ -193,26 +167,24 @@ supports any cpu which could be described with the name provided. The routine returns a pointer to an arch_info structure if a machine is found, otherwise NULL. -*; bfd_arch_info_struct_type *EXFUN(bfd_scan_arch,(CONST char *)); +*; bfd_arch_info_type *EXFUN(bfd_scan_arch,(CONST char *)); */ -bfd_arch_info_struct_type * +bfd_arch_info_type * DEFUN(bfd_scan_arch,(string), CONST char *string) { - struct bfd_arch_info_struct *ap; + struct bfd_arch_info *ap; /* Look through all the installed architectures */ for (ap = bfd_arch_info_list; - ap != (bfd_arch_info_struct_type *)NULL; + ap != (bfd_arch_info_type *)NULL; ap = ap->next) { - /* Don't bother with anything if the first chars don't match */ - if (ap->arch_name[0] != string[0]) - continue; + if (ap->scan(ap, string)) return ap; } - return (bfd_arch_info_struct_type *)NULL; + return (bfd_arch_info_type *)NULL; } @@ -224,12 +196,12 @@ denominator between the two architectures and machine types implied by the BFDs and returns a pointer to an arch_info structure describing the compatible machine. -*; CONST bfd_arch_info_struct_type *EXFUN(bfd_arch_get_compatible, +*; CONST bfd_arch_info_type *EXFUN(bfd_arch_get_compatible, (CONST bfd *abfd, CONST bfd *bbfd)); */ -CONST bfd_arch_info_struct_type * +CONST bfd_arch_info_type * DEFUN(bfd_arch_get_compatible,(abfd, bbfd), CONST bfd *abfd AND CONST bfd *bbfd) @@ -244,11 +216,11 @@ CONST bfd *bbfd) What bfds are seeded with *+ -extern bfd_arch_info_struct_type bfd_default_arch_struct; +extern bfd_arch_info_type bfd_default_arch_struct; *- */ -bfd_arch_info_struct_type bfd_default_arch_struct = +bfd_arch_info_type bfd_default_arch_struct = { 32,32,8,bfd_arch_unknown,0,"unknown","unknown",true, bfd_default_compatible, bfd_default_scan, @@ -257,13 +229,13 @@ bfd_arch_info_struct_type bfd_default_arch_struct = /*proto* bfd_set_arch_info -*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_struct_type *)); +*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_type *)); */ void DEFUN(bfd_set_arch_info,(abfd, arg), bfd *abfd AND -bfd_arch_info_struct_type *arg) +bfd_arch_info_type *arg) { abfd->arch_info = arg; } @@ -284,15 +256,15 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach), enum bfd_architecture arch AND unsigned long mach) { - static struct bfd_arch_info_struct *old_ptr = &bfd_default_arch_struct; + static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct; boolean found = false; /* run through the table to find the one we want, we keep a little cache to speed things up */ if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) { - bfd_arch_info_struct_type *ptr; - old_ptr = (bfd_arch_info_struct_type *)NULL; + bfd_arch_info_type *ptr; + old_ptr = (bfd_arch_info_type *)NULL; for (ptr = bfd_arch_info_list; - ptr != (bfd_arch_info_struct_type *)NULL; + ptr != (bfd_arch_info_type *)NULL; ptr= ptr->next) { if (ptr->arch == arch && ((ptr->mach == mach) || (ptr->the_default && mach == 0))) { @@ -385,6 +357,7 @@ extern void EXFUN(bfd_vax_arch,(void)); extern void EXFUN(bfd_a29k_arch,(void)); extern void EXFUN(bfd_mips_arch,(void)); extern void EXFUN(bfd_i386_arch,(void)); +extern void EXFUN(bfd_rs6000_arch,(void)); @@ -402,6 +375,7 @@ static void EXFUN((*archures_init_table[]),()) = bfd_i960_arch, bfd_m68k_arch, bfd_vax_arch, + bfd_rs6000_arch, #endif 0 }; @@ -434,12 +408,12 @@ DEFUN_VOID(bfd_arch_init) Link the provided arch info structure into the list -*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_struct_type *)); +*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_type *)); */ void DEFUN(bfd_arch_linkin,(ptr), - bfd_arch_info_struct_type *ptr) + bfd_arch_info_type *ptr) { ptr->next = bfd_arch_info_list; bfd_arch_info_list = ptr; @@ -450,17 +424,17 @@ void DEFUN(bfd_arch_linkin,(ptr), The default function for testing for compatibility -*; CONST bfd_arch_info_struct_type *EXFUN(bfd_default_compatible, - (CONST bfd_arch_info_struct_type *a, - CONST bfd_arch_info_struct_type *b)); +*; CONST bfd_arch_info_type *EXFUN(bfd_default_compatible, + (CONST bfd_arch_info_type *a, + CONST bfd_arch_info_type *b)); */ -CONST bfd_arch_info_struct_type * +CONST bfd_arch_info_type * DEFUN(bfd_default_compatible,(a,b), - CONST bfd_arch_info_struct_type *a AND - CONST bfd_arch_info_struct_type *b) + CONST bfd_arch_info_type *a AND + CONST bfd_arch_info_type *b) { - if(a->arch != b->arch) return (bfd_arch_info_struct_type *)NULL; + if(a->arch != b->arch) return NULL; if (a->mach > b->mach) { return a; @@ -475,13 +449,13 @@ DEFUN(bfd_default_compatible,(a,b), The default function for working out whether this is an architecture hit and a machine hit -*; boolean EXFUN(bfd_default_scan,(CONST struct bfd_arch_info_struct *, CONST char *)); +*; boolean EXFUN(bfd_default_scan,(CONST struct bfd_arch_info *, CONST char *)); */ boolean DEFUN(bfd_default_scan,(info, string), -CONST struct bfd_arch_info_struct *info AND +CONST struct bfd_arch_info *info AND CONST char *string) { CONST char *ptr_src; @@ -554,6 +528,10 @@ CONST char *string) arch = bfd_arch_i860; break; + case 6000: + arch = bfd_arch_rs6000; + break; + default: return false; } @@ -571,13 +549,65 @@ CONST char *string) /*proto* bfd_get_arch_info -*; bfd_arch_info_struct_type * EXFUN(bfd_get_arch_info,(bfd *)); +*; bfd_arch_info_type * EXFUN(bfd_get_arch_info,(bfd *)); */ -bfd_arch_info_struct_type * +bfd_arch_info_type * DEFUN(bfd_get_arch_info,(abfd), bfd *abfd) { return abfd->arch_info; } + + +/*proto* bfd_lookup_arch + +*; bfd_arch_info_type * EXFUN(bfd_lookup_arch,(enum + bfd_architecture arch,long machine)); + +Look for the architecure info struct which matches the arguments +given. A machine of 0 will match the machine/architecture structure which +marks itself as the default. + +*/ + +bfd_arch_info_type * +DEFUN(bfd_lookup_arch,(arch, machine), +enum bfd_architecture arch AND +long machine) +{ + bfd_arch_info_type *ap; + bfd_check_init(); + for (ap = bfd_arch_info_list; + ap != (bfd_arch_info_type *)NULL; + ap = ap->next) { + if (ap->arch == arch && + ((ap->mach == machine) || (ap->the_default && machine == 0))) { + return ap; + } + } + return (bfd_arch_info_type *)NULL; +} + + + +/*proto* bfd_printable_arch_mach +Return a printable string representing the architecture and machine +type. + +NB. The use of this routine is depreciated. + +*; PROTO(CONST char *,bfd_printable_arch_mach, + (enum bfd_architecture arch, unsigned long machine)); +*/ + +CONST char * +DEFUN(bfd_printable_arch_mach,(arch, machine), + enum bfd_architecture arch AND + unsigned long machine) +{ + bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine); + if(ap) return ap->printable_name; + return "UNKNOWN!"; +} diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index fbbecd4..a0915df 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -204,7 +204,8 @@ typedef enum bfd_error { no_more_archived_files, malformed_archive, symbol_not_found, file_not_recognized, file_ambiguously_recognized, no_contents, - bfd_error_nonrepresentable_section, + bfd_error_nonrepresentable_section, + no_debug_section, invalid_error_code} bfd_ec; extern bfd_ec bfd_error; @@ -220,10 +221,10 @@ PROTO (void, bfd_perror, (CONST char *message)); typedef enum bfd_print_symbol { - bfd_print_symbol_name_enum, - bfd_print_symbol_type_enum, - bfd_print_symbol_all_enum -} bfd_print_symbol_enum_type; + bfd_print_symbol_name, + bfd_print_symbol_more, + bfd_print_symbol_all +} bfd_print_symbol_type; @@ -269,7 +270,14 @@ CAT(NAME,_bfd_debug_info_start),\ CAT(NAME,_bfd_debug_info_end),\ CAT(NAME,_bfd_debug_info_accumulate) -#define COFF_SWAP_TABLE coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, +#define COFF_SWAP_TABLE \ + coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \ + coff_swap_aux_out, coff_swap_sym_out, \ + coff_swap_lineno_out, coff_swap_reloc_out, \ + coff_swap_filehdr_out, coff_swap_aouthdr_out, \ + coff_swap_scnhdr_out + + /* User program access to BFD facilities */ @@ -162,6 +162,7 @@ $}; #include "sysdep.h" #include "libbfd.h" +#undef strerror extern char *strerror(); @@ -196,6 +197,7 @@ char *bfd_errmsgs[] = { "No error", "File format is ambiguous", "Section has no contents", "Nonrepresentable section on output", + "Symbol needs debug section which does not exist", "#<Invalid error code>" }; @@ -418,6 +420,27 @@ bfd_get_mtime (abfd) #define bfd_set_arch_mach(abfd, arch, mach)\ BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) +#define bfd_coff_swap_reloc_out(abfd, i, o) \ + BFD_SEND (abfd, _bfd_coff_swap_reloc_out, (abfd, i, o)) + +#define bfd_coff_swap_lineno_out(abfd, i, o) \ + BFD_SEND (abfd, _bfd_coff_swap_lineno_out, (abfd, i, o)) + +#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \ + BFD_SEND (abfd, _bfd_coff_swap_aux_out, (abfd, i,t,c, o)) + +#define bfd_coff_swap_sym_out(abfd, i,o) \ + BFD_SEND (abfd, _bfd_coff_swap_sym_out, (abfd, i, o)) + +#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ + BFD_SEND (abfd, _bfd_coff_swap_scnhdr_out, (abfd, i, o)) + +#define bfd_coff_swap_filehdr_out(abfd, i,o) \ + BFD_SEND (abfd, _bfd_coff_swap_filehdr_out, (abfd, i, o)) + +#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ + BFD_SEND (abfd, _bfd_coff_swap_aouthdr_out, (abfd, i, o)) + *- */ diff --git a/bfd/coffcode.h b/bfd/coffcode.h index bfa0036..315daac 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -34,12 +34,12 @@ 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}. +@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{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}. +than @code{m88k-bcs.h}. @subsection Porting To A New Version of Coff @@ -49,7 +49,7 @@ 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. +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 @@ -105,7 +105,7 @@ avenue to disaster disappear. 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". +"behind the scenes". When a symbol table is requested (through a call to @code{bfd_canonicalize_symtab}, a request gets through to @@ -147,14 +147,14 @@ 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. +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 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 @@ -163,7 +163,7 @@ 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. +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 @@ -279,7 +279,7 @@ $ } coff_symbol_type; #ifndef PUT_LNSZ_SIZE #define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) #endif -#ifndef GET_SCN_SCNLEN +#ifndef GET_SCN_SCNLEN #define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) #endif #ifndef GET_SCN_NRELOC @@ -288,7 +288,7 @@ $ } coff_symbol_type; #ifndef GET_SCN_NLINNO #define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno) #endif -#ifndef PUT_SCN_SCNLEN +#ifndef PUT_SCN_SCNLEN #define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) #endif #ifndef PUT_SCN_NRELOC @@ -302,13 +302,13 @@ $ } coff_symbol_type; /* void warning(); */ -/* - * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the +/* + * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the * incoming SEC_* flags. The inverse of this function is styp_to_sec_flags(). * NOTE: If you add to/change this routine, you should mirror the changes * in styp_to_sec_flags(). */ -static long +static long DEFUN(sec_to_styp_flags, (sec_name, sec_flags), CONST char * sec_name AND flagword sec_flags) @@ -321,16 +321,16 @@ DEFUN(sec_to_styp_flags, (sec_name, sec_flags), return((long)STYP_DATA); } else if (!strcmp(sec_name, _BSS)) { return((long)STYP_BSS); - } + } /* Try and figure out what it should be */ - if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT; - if (sec_flags & SEC_DATA) styp_flags = STYP_DATA; - else if (sec_flags & SEC_READONLY) + if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT; + if (sec_flags & SEC_DATA) styp_flags = STYP_DATA; + else if (sec_flags & SEC_READONLY) #ifdef STYP_LIT /* 29k readonly text/data section */ - styp_flags = STYP_LIT; + styp_flags = STYP_LIT; #else - styp_flags = STYP_TEXT; + styp_flags = STYP_TEXT; #endif /* STYP_LIT */ else if (sec_flags & SEC_LOAD) styp_flags = STYP_TEXT; @@ -338,14 +338,14 @@ DEFUN(sec_to_styp_flags, (sec_name, sec_flags), return(styp_flags); } -/* +/* * Return a word with SEC_* flags set to represent the incoming - * STYP_* flags (from scnhdr.s_flags). The inverse of this - * function is sec_to_styp_flags(). + * STYP_* flags (from scnhdr.s_flags). The inverse of this + * function is sec_to_styp_flags(). * NOTE: If you add to/change this routine, you should mirror the changes * in sec_to_styp_flags(). */ -static flagword +static flagword DEFUN(styp_to_sec_flags, (styp_flags), long styp_flags) { @@ -369,7 +369,7 @@ DEFUN(styp_to_sec_flags, (styp_flags), /* ********************************************************************** Here are all the routines for swapping the structures seen in the -outside world into the internal forms. +outside world into the internal forms. */ @@ -381,7 +381,14 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst), { reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); reloc_dst->r_symndx = bfd_h_get_32(abfd, (bfd_byte *) reloc_src->r_symndx); + +#ifdef RS6000COFF_C + reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type); + reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size); +#else reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type); +#endif + #if M88 reloc_dst->r_offset = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_offset); #endif @@ -441,7 +448,7 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out), #ifndef NO_COFF_SYMBOLS -static void +static void DEFUN(coff_swap_sym_in,(abfd, ext1, in1), bfd *abfd AND PTR ext1 AND @@ -494,7 +501,7 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp), } bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2) + if (sizeof(ext->e_type) == 2) { bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); } @@ -584,7 +591,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp), switch (class) { case C_FILE: if (in->x_file.x_fname[0] == 0) { - PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes ); + PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); PUTWORD(abfd, in->x_file.x_n.x_offset, (bfd_byte *) ext->x_file.x_n.x_offset); @@ -595,7 +602,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp), #else memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); #endif - } + } break; case C_STAT: #ifdef C_LEAFSTAT @@ -685,7 +692,7 @@ DEFUN(coff_swap_lineno_out,(abfd, inp, outp), #endif /* NO_COFF_LINENOS */ -static void +static void DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1), bfd *abfd AND PTR aouthdr_ext1 AND @@ -705,6 +712,20 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1), #ifdef I960 aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries); #endif + +#ifdef RS6000COFF_C + aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc); + aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry); + aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext); + aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata); + aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc); + aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader); + aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss); + aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext); + aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata); + aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype); + aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack); +#endif } static unsigned int @@ -730,7 +751,7 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out), return sizeof(AOUTHDR); } -static void +static void DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), bfd *abfd AND SCNHDR *scnhdr_ext AND @@ -756,7 +777,7 @@ DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), #endif } -static unsigned int +static unsigned int DEFUN(coff_swap_scnhdr_out,(abfd, in, out), bfd *abfd AND PTR in AND @@ -780,7 +801,7 @@ DEFUN(coff_swap_scnhdr_out,(abfd, in, out), PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); #endif -#if defined(I960) +#if defined(I960) PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align); #endif return sizeof(SCNHDR); @@ -821,6 +842,8 @@ DEFUN(make_a_section_from_file,(abfd, hdr), name[sizeof (hdr->s_name)] = 0; return_section = bfd_make_section(abfd, name); + if (return_section == NULL) + return false; } /* s_paddr is presumed to be = to s_vaddr */ @@ -890,20 +913,20 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), long machine; 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; @@ -929,15 +952,15 @@ machine = 0; machine = 0; break; #endif - -#ifdef A29K_MAGIC_BIG + +#ifdef A29K_MAGIC_BIG case A29K_MAGIC_BIG: case A29K_MAGIC_LITTLE: arch = bfd_arch_a29k; machine = 0; break; #endif - + #ifdef MIPS case MIPS_MAGIC_1: case MIPS_MAGIC_2: @@ -946,7 +969,7 @@ machine = 0; machine = 0; break; #endif - + #ifdef MC68MAGIC case MC68MAGIC: case M68MAGIC: @@ -967,7 +990,7 @@ machine = 0; case I960ROMAGIC: case I960RWMAGIC: arch = bfd_arch_i960; - switch (F_I960TYPE & internal_f->f_flags) + switch (F_I960TYPE & internal_f->f_flags) { default: case F_I960CORE: @@ -988,17 +1011,26 @@ machine = 0; case F_I960KA: machine = bfd_mach_i960_ka_sa; break; - } break; #endif #endif - + +#ifdef U802ROMAGIC + case U802ROMAGIC: + case U802WRMAGIC: + case U802TOCMAGIC: + arch = bfd_arch_rs6000; + machine = 6000; + break; +#endif + + default: /* Unreadable input file type */ arch = bfd_arch_obscure; break; } - + bfd_default_set_arch_mach(abfd, arch, machine); if (!(internal_f->f_flags & F_RELFLG)) abfd->flags |= HAS_RELOC; @@ -1008,14 +1040,14 @@ machine = 0; abfd->flags |= HAS_LINENO; if (!(internal_f->f_flags & F_LSYMS)) abfd->flags |= HAS_LOCALS; - - + + bfd_get_symcount(abfd) = internal_f->f_nsyms; if (internal_f->f_nsyms) abfd->flags |= HAS_SYMS; - + coff->sym_filepos = internal_f->f_symptr; - + /* These members communicate important constants about the symbol table to GDB's symbol-reading code. These `constants' unfortunately vary from coff implementation to implementation... */ @@ -1028,10 +1060,10 @@ machine = 0; coff->local_auxesz = AUXESZ; coff->local_linesz = LINESZ; #endif - + coff->symbols = (coff_symbol_type *) NULL; bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0; - + return abfd->xvec; fail: bfd_release(abfd, coff); @@ -1047,45 +1079,45 @@ DEFUN(coff_object_p,(abfd), AOUTHDR opthdr; struct internal_filehdr internal_f; struct internal_aouthdr internal_a; - + bfd_error = system_call_error; - + /* 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); - + 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, (char *)&opthdr, (char *)&internal_a); } - + /* 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 defined(M88) || defined(I960) 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); } @@ -1093,7 +1125,7 @@ DEFUN(coff_object_p,(abfd), #ifndef NO_COFF_LINENOS -static void +static void DEFUN(coff_count_linenumbers,(abfd), bfd *abfd) { @@ -1107,8 +1139,8 @@ DEFUN(coff_count_linenumbers,(abfd), 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) { @@ -1134,7 +1166,7 @@ DEFUN(coff_count_linenumbers,(abfd), #ifndef NO_COFF_SYMBOLS -/* +/* Takes a bfd and a symbol, returns a pointer to the coff specific area of the symbol if there is one. */ @@ -1143,12 +1175,12 @@ DEFUN(coff_symbol_from,(ignore_abfd, symbol), bfd *ignore_abfd AND asymbol *symbol) { - if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour) + if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour) return (coff_symbol_type *)NULL; - + if (symbol->the_bfd->tdata == (PTR)NULL) return (coff_symbol_type *)NULL; - + return (coff_symbol_type *) symbol; } @@ -1172,17 +1204,17 @@ struct internal_syment *syment) 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 { if (coff_symbol_ptr->symbol.section) { - syment->n_scnum = + syment->n_scnum = coff_symbol_ptr->symbol.section->output_section->index+1; - - syment->n_value = + + syment->n_value = coff_symbol_ptr->symbol.value + coff_symbol_ptr->symbol.section->output_offset + coff_symbol_ptr->symbol.section->output_section->vma; @@ -1190,13 +1222,13 @@ struct internal_syment *syment) else { /* This can happen, but I don't know why yet (steve@cygnus.com) */ syment->n_scnum = N_ABS; - syment->n_value = coff_symbol_ptr->symbol.value; + syment->n_value = coff_symbol_ptr->symbol.value; } } } /* run through all the symbols in the symbol table and work out what - their indexes into the symbol table will be when output + their indexes into the symbol table will be when output 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 @@ -1212,14 +1244,14 @@ DEFUN(coff_renumber_symbols,(bfd_ptr), 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++) + 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; - if (s->u.syment.n_sclass == C_FILE) + if (s->u.syment.n_sclass == C_FILE) { if (last_file != (struct internal_syment *)NULL) { last_file->n_value = native_index; @@ -1249,31 +1281,28 @@ DEFUN(coff_renumber_symbols,(bfd_ptr), entries are changed to the entries' index in the output symbol table. */ -static void +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 symbol_index; - - for (symbol_index = 0; symbol_index < symbol_count; 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 ) { + 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; + 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 = @@ -1293,15 +1322,15 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), struct internal_syment *last_fcn = (struct internal_syment *)NULL; struct internal_syment *block_stack[50]; struct internal_syment **last_block = &block_stack[0]; - boolean first_time = true; + boolean first_time = true; unsigned int symbol_index; unsigned int native_index = 0; - + 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_type *)NULL) { - /* + /* This symbol has no coff information in it, it will take up only one slot in the output symbol table */ @@ -1325,46 +1354,44 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), 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 = + syment->n_scnum = coff_symbol_ptr->symbol.section->output_section->index+1; - - syment->n_value = + + syment->n_value = coff_symbol_ptr->symbol.value + coff_symbol_ptr->symbol.section->output_offset + coff_symbol_ptr->symbol.section->output_section->vma; } - - + /* If this symbol ties up something then do it */ - + if (syment->n_sclass == C_FILE && last_file != (struct internal_syment *)NULL) { last_file->n_value = native_index; } - else if ((syment->n_sclass == C_EXT - || syment->n_sclass == C_STAT + else if ((syment->n_sclass == C_EXT /* FIXME - may need C_HIDEXT */ + || syment->n_sclass == C_STAT #ifdef C_LEAFEXT - || syment->n_sclass == C_LEAFEXT + || syment->n_sclass == C_LEAFEXT || syment->n_sclass == C_LEAFSTAT #endif ) - && last_fcn != (struct internal_syment *)NULL) + && last_fcn != (struct internal_syment *)NULL) { union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1); auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index; last_fcn = (struct internal_syment *)NULL; - } else if (syment->n_sclass == C_EOS && last_tagndx != (struct internal_syment*)NULL) { union internal_auxent *auxent = (union internal_auxent *)(last_tagndx+1); - /* Remember that we keep the native index in the offset + /* Remember that we keep the native index in the offset so patch the beginning of the struct to point to this */ /*if (last_ @@ -1374,17 +1401,17 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), auxent = (union internal_auxent *)(syment+1); 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') + 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.l = native_index + syment->n_numaux + 1; } - if (syment->n_sclass == C_EXT - && !ISFCN(syment->n_type) - && first_time == true + if (syment->n_sclass == C_EXT + && !ISFCN(syment->n_type) + && first_time == true && last_file != (struct internal_syment *)NULL) { - /* This is the first external symbol seen which isn't a + /* This is the first external symbol seen which isn't a function place it in the last .file entry */ last_file->n_value = native_index; first_time = false; @@ -1393,28 +1420,28 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), if (syment->n_sclass == C_LEAFPROC && syment->n_numaux == 2) { union internal_auxent *auxent = (union internal_auxent *)(syment+2); - /* This is the definition of a leaf proc, we'll relocate the + /* This is the definition of a leaf proc, we'll relocate the address */ - auxent->x_bal.x_balntry = - coff_symbol_ptr->symbol.section->output_offset + + auxent->x_bal.x_balntry = + coff_symbol_ptr->symbol.section->output_offset + coff_symbol_ptr->symbol.section->output_section->vma + auxent->x_bal.x_balntry ; } #endif /* If this symbol needs to be tied up then remember some facts */ - if (syment->n_sclass == C_FILE) + if (syment->n_sclass == C_FILE) { last_file = syment; } if (syment->n_numaux != 0) { /* If this symbol would like to point to something in the - future then remember where it is + future then remember where it is */ if (uses_x_sym_x_tagndx_p(bfd_ptr, syment)) { - /* - If this is a ref to a structure then we'll tie it up - now - there are never any forward refs for one + /* + If this is a ref to a structure then we'll tie it up + now - there are never any forward refs for one */ if (syment->n_sclass == C_STRTAG || syment->n_sclass == C_ENTAG || @@ -1430,16 +1457,14 @@ 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); + 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;*/ - - } } if (ISFCN(syment->n_type)) { last_fcn = syment; } - if (syment->n_sclass == C_BLOCK + if (syment->n_sclass == C_BLOCK && coff_symbol_ptr->symbol.name[1] == 'b') { *last_block++ = syment; @@ -1454,7 +1479,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), #endif -static int string_size; +static int string_size; static void DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native), bfd *ignore_abfd AND @@ -1471,11 +1496,11 @@ DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native), name = (char *)symbol->name; } 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); @@ -1508,7 +1533,7 @@ DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native), -static unsigned int +static unsigned int DEFUN(coff_write_symbol,(abfd, symbol, native, written), bfd *abfd AND asymbol *symbol AND @@ -1524,7 +1549,7 @@ unsigned int written) 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++) + for (j = 0; j != native->u.syment.n_numaux; j++) { AUXENT buf1; bzero((PTR)&buf, AUXESZ); @@ -1588,23 +1613,23 @@ DEFUN(coff_write_alien_symbol,(abfd, symbol, written), } #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 + 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 +static unsigned int DEFUN(coff_write_native_symbol,(abfd, symbol, written), bfd *abfd AND coff_symbol_type *symbol AND @@ -1624,8 +1649,8 @@ unsigned int written) 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 = + + a->x_sym.x_fcnary.x_fcn.x_lnnoptr = symbol->symbol.section->output_section->moving_line_filepos; } /* @@ -1640,12 +1665,11 @@ unsigned int written) } symbol->symbol.section->output_section->moving_line_filepos += count * LINESZ; - } return coff_write_symbol(abfd, &( symbol->symbol), native,written); } -static void +static void DEFUN(coff_write_symbols,(abfd), bfd *abfd) { @@ -1656,20 +1680,18 @@ DEFUN(coff_write_symbols,(abfd), asymbol **p; string_size = 0; - - + + /* Seek to the right place */ bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET); - + /* Output all the symbols we have */ - + written = 0; - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) + for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { 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) @@ -1686,15 +1708,17 @@ DEFUN(coff_write_symbols,(abfd), bfd_get_symcount(abfd) = written; /* Now write out strings */ - - if (string_size != 0) + + if (string_size != 0) { unsigned int size = string_size + 4; bfd_byte buffer[4]; bfd_h_put_32(abfd, size, buffer); bfd_write((PTR) buffer, 1, sizeof(buffer), abfd); - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) + for (p = abfd->outsymbols, i = 0; + i < limit; + i++, p++) { asymbol *q = *p; size_t name_length = strlen(q->name); @@ -1703,7 +1727,7 @@ DEFUN(coff_write_symbols,(abfd), 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); } @@ -1714,11 +1738,11 @@ DEFUN(coff_write_symbols,(abfd), out 4 so that any stupid coff reader which tries to read the string table even when there isn't one won't croak. */ - + uint32e_type size = 4; size = size; bfd_write((PTR)&size, 1, sizeof(size), abfd); - + } } @@ -1735,7 +1759,7 @@ Then the @code{internal_reloc} is swapped into the shape of an @code{external_reloc} and written out to disk. */ -static void +static void DEFUN(coff_write_relocs,(abfd), bfd *abfd) { @@ -1743,7 +1767,7 @@ DEFUN(coff_write_relocs,(abfd), 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++) { @@ -1769,7 +1793,7 @@ DEFUN(coff_write_relocs,(abfd), #ifndef NO_COFF_LINENOS -static void +static void DEFUN(coff_write_linenumbers,(abfd), bfd *abfd) { @@ -1833,7 +1857,7 @@ bfd *abfd; #ifndef NO_COFF_SYMBOLS -static void +static void DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how), bfd *ignore_abfd AND PTR filep AND @@ -1854,15 +1878,15 @@ DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how), 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); } - - + + break; } } @@ -1879,11 +1903,11 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp), unsigned short *flagsp) { switch (bfd_get_arch(abfd)) { - + #ifdef I960ROMAGIC - + case bfd_arch_i960: - + { unsigned flags; *magicp = I960ROMAGIC; @@ -1934,7 +1958,7 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp), *magicp = MC68MAGIC; return true; #endif - + #ifdef MC88MAGIC case bfd_arch_m88k: *magicp = MC88OMAGIC; @@ -1951,13 +1975,19 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp), return true; break; #endif - + +#ifdef U802TOCMAGIC + case bfd_arch_rs6000: + *magicp = U802TOCMAGIC; + break; +#endif + default: /* Unknown architecture */ /* return false; -- fall through to "return false" below, to avoid - "statement never reached" errors on the one below. */ + "statement never reached" errors on the one below. */ break; } - + return false; } @@ -1981,7 +2011,7 @@ DEFUN(coff_set_arch_mach,(abfd, arch, machine), /* Calculate the file position for each section. */ -static void +static void DEFUN(coff_compute_section_file_positions,(abfd), bfd *abfd) { @@ -1996,22 +2026,22 @@ DEFUN(coff_compute_section_file_positions,(abfd), } if (abfd->flags & EXEC_P) sofar += AOUTSZ; - - + + sofar += abfd->section_count * SCNHSZ; - for (current = abfd->sections; + 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 + + /* 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 - { + { /* Whatever the alignment, make sure that the sections are big enough to cover the gap */ bfd_vma old_sofar= sofar; @@ -2023,7 +2053,7 @@ DEFUN(coff_compute_section_file_positions,(abfd), 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; } @@ -2052,18 +2082,18 @@ DEFUN(coff_write_object_contents,(abfd), asection *text_sec = NULL; asection *data_sec = NULL; asection *bss_sec = NULL; - + struct internal_filehdr internal_f; struct internal_aouthdr internal_a; - - + + bfd_error = system_call_error; - - + + if(abfd->output_has_begun == false) { coff_compute_section_file_positions(abfd); } - + if (abfd->sections != (asection *)NULL) { scn_base = abfd->sections->filepos; } @@ -2073,17 +2103,17 @@ DEFUN(coff_write_object_contents,(abfd), if (bfd_seek(abfd, scn_base, SEEK_SET) != 0) return false; reloc_base = obj_relocbase(abfd); - + /* Make a pass through the symbol table to count line number entries and put them into the correct asections */ - + #ifndef NO_COFF_LINENOS coff_count_linenumbers(abfd); #endif data_base = scn_base; - + /* Work out the size of the reloc and linno areas */ - + for (current = abfd->sections; current != NULL; current = current->next) { reloc_size += current->reloc_count * RELSZ; #ifndef NO_COFF_LINENOS @@ -2091,10 +2121,10 @@ DEFUN(coff_write_object_contents,(abfd), #endif data_base += SCNHSZ; } - + lineno_base = reloc_base + reloc_size; sym_base = lineno_base + lnno_size; - + /* Indicate in each section->line_filepos its actual file address */ for (current = abfd->sections; current != NULL; current = current->next) { if (current->lineno_count) { @@ -2115,20 +2145,20 @@ DEFUN(coff_write_object_contents,(abfd), current->rel_filepos = 0; } } - + /* Write section headers to the file. */ - + bfd_seek(abfd, (file_ptr) ((abfd->flags & EXEC_P) ? (FILHSZ + AOUTSZ) : FILHSZ), SEEK_SET); - + { #if 0 unsigned int pad = abfd->flags & D_PAGED ? data_base : 0; #endif unsigned int pad = 0; - + for (current = abfd->sections; current != NULL; current = current->next) { struct internal_scnhdr section; strncpy(&(section.s_name[0]), current->name, 8); @@ -2142,7 +2172,6 @@ DEFUN(coff_write_object_contents,(abfd), if (current->size - pad == 0 || (current->flags & SEC_LOAD) == 0) { section.s_scnptr = 0; - } else { section.s_scnptr = current->filepos; @@ -2155,7 +2184,7 @@ DEFUN(coff_write_object_contents,(abfd), hasrelocs = true; if (current->lineno_count != 0) haslinno = true; - + section.s_flags = sec_to_styp_flags(current->name,current->flags); if (!strcmp(current->name, _TEXT)) { @@ -2164,8 +2193,8 @@ DEFUN(coff_write_object_contents,(abfd), data_sec = current; } else if (!strcmp(current->name, _BSS)) { bss_sec = current; - } - + } + #ifdef I960 section.s_align = (current->alignment_power ? 1 << current->alignment_power @@ -2241,12 +2270,12 @@ DEFUN(coff_write_object_contents,(abfd), internal_f.f_flags |= flags; /* ...and the "opt"hdr... */ -#ifdef A29K +#ifdef A29K # ifdef ULTRA3 /* NYU's machine */ /* FIXME: This is a bogus check. I really want to see if there * is a .shbss or a .shdata section, if so then set the magic * number to indicate a shared data executable. - */ + */ if (internal_f.f_nscns >= 7) internal_a.magic = SHMAGIC; /* Shared magic */ else @@ -2255,7 +2284,7 @@ DEFUN(coff_write_object_contents,(abfd), #define __A_MAGIC_SET__ #endif /* A29K */ #ifdef I960 - internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC); + internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC); #define __A_MAGIC_SET__ #endif /* I960 */ #if M88 @@ -2265,9 +2294,16 @@ DEFUN(coff_write_object_contents,(abfd), #if M68 || I386 || MIPS #define __A_MAGIC_SET__ - /* Never was anything here for the 68k */ + /* Never was anything here for the 68k */ #endif /* M88 */ +#if RS6000COFF_C +#define __A_MAGIC_SET__ + internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC: + (abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC: + RS6K_AOUTHDR_OMAGIC; +#endif + #ifndef __A_MAGIC_SET__ # include "Your aouthdr magic number is not being set!" #else @@ -2395,7 +2431,7 @@ coff_close_and_cleanup(abfd) } #endif -static PTR +static PTR buy_and_read(abfd, where, seek_direction, size) bfd *abfd; file_ptr where; @@ -2425,20 +2461,18 @@ bfd *abfd) 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. - */ - + + /* 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, (bfd_byte *) string_table_size_buffer); - + if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) { bfd_error = no_memory; return (NULL); @@ -2446,10 +2480,50 @@ bfd *abfd) if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) { bfd_error = system_call_error; return (NULL); - } + } return string_table; } +/* Allocate space for the ".debug" section, and read it. + We did not read the debug section until now, because + we didn't want to go to the trouble until someone needed it. */ + +static char * +DEFUN(build_debug_section,(abfd), + bfd *abfd) +{ + char *debug_section; + long position; + + asection *sect = bfd_get_section_by_name (abfd, ".debug"); + + if (!sect) { + bfd_error = no_debug_section; + return NULL; + } + + debug_section = (PTR) bfd_alloc (abfd, bfd_section_size (abfd, sect)); + if (debug_section == NULL) { + bfd_error = no_memory; + return NULL; + } + + /* Seek to the beginning of the `.debug' section and read it. + Save the current position first; it is needed by our caller. + Then read debug section and reset the file pointer. */ + + position = bfd_tell (abfd); + bfd_seek (abfd, sect->filepos, SEEK_SET); + if (bfd_read (debug_section, bfd_section_size (abfd, sect), 1, abfd) + != bfd_section_size (abfd, sect)) { + bfd_error = system_call_error; + return NULL; + } + bfd_seek (abfd, position, SEEK_SET); + return debug_section; +} + + /* 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. */ @@ -2461,13 +2535,13 @@ DEFUN(copy_name,(abfd, name, 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); @@ -2478,19 +2552,19 @@ DEFUN(copy_name,(abfd, name, maxlen), } -/* -read a symbol table into freshly mallocated memory, swap it, and knit the -symbol names into a normalized form. By normalized here I mean that all -symbols have an n_offset pointer that points to a NULL terminated string. -Oh, and the first symbol MUST be a C_FILE. If there wasn't one there -before, put one there. -*/ +/* Read a symbol table into freshly bfd_allocated memory, swap it, and + knit the symbol names into a normalized form. By normalized here I + mean that all symbols have an n_offset pointer that points to a null- + terminated string. */ + +#ifndef SYMNAME_IN_DEBUG +#define SYMNAME_IN_DEBUG(x) 0 +#endif static combined_entry_type * DEFUN(get_normalized_symtab,(abfd), bfd *abfd) { - combined_entry_type *internal; combined_entry_type *internal_ptr; combined_entry_type *internal_end; @@ -2498,9 +2572,9 @@ bfd *abfd) SYMENT *raw_src; SYMENT *raw_end; char *string_table = NULL; + char *debug_section = NULL; unsigned long size; - unsigned int raw_size; if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) { return obj_raw_syments(abfd); @@ -2529,39 +2603,46 @@ bfd *abfd) */ /* Swap all the raw entries */ - for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) { + for (raw_src = raw, internal_ptr = internal; + raw_src < raw_end; + raw_src++, internal_ptr++) { + unsigned int i; - coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment); + coff_swap_sym_in(abfd, (char *)raw_src, (char *)&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++) { + 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, (char *)(raw_src +1), internal_ptr->u.syment.n_type, - internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent); + coff_swap_aux_in(abfd, (char *)(raw_src +1), + internal_ptr->u.syment.n_type, + internal_ptr->u.syment.n_sclass, + &(internal_ptr+1)->u.auxent); - coff_pointerize_aux(abfd, + 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); for (internal_ptr = internal; internal_ptr < internal_end; - internal_ptr ++) + 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 - */ + /* the filename is a long one, point into the string table */ if (string_table == NULL) { string_table = build_string_table(abfd); } @@ -2573,28 +2654,24 @@ bfd *abfd) 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); - + 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. - */ + /* 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. - */ - + + /* find the length of this string without walking into memory + that isn't ours. */ 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); @@ -2603,23 +2680,29 @@ bfd *abfd) 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 { - /* This is a long name already. Just point it at the string in memory. */ + else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) { + /* Long name already. Point symbol at the string in the table. */ 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->u.syment._n._n_n._n_offset = (int) + (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset); + } + else { + /* Long name in debug section. Very similar. */ + if (debug_section == NULL) { + debug_section = build_debug_section(abfd); + } + internal_ptr->u.syment._n._n_n._n_offset = (int) + (debug_section + internal_ptr->u.syment._n._n_n._n_offset); + } } internal_ptr += internal_ptr->u.syment.n_numaux; - } + } obj_raw_syments(abfd) = internal; - obj_string_table(abfd) = string_table; - + return (internal); } /* get_normalized_symtab() */ @@ -2668,9 +2751,9 @@ asection *asect; { LINENO *native_lineno; alent *lineno_cache; - + BFD_ASSERT(asect->lineno == (alent *) NULL); - + native_lineno = (LINENO *) buy_and_read(abfd, asect->line_filepos, SEEK_SET, @@ -2681,16 +2764,16 @@ asection *asect; if (lineno_cache == NULL) { bfd_error = no_memory; return false; - } else { + } else { unsigned int counter = 0; alent *cache_ptr = lineno_cache; LINENO *src = native_lineno; - + while (counter < asect->lineno_count) { struct internal_lineno dst; coff_swap_lineno_in(abfd, src, &dst); cache_ptr->line_number = dst.l_lnno; - + if (cache_ptr->line_number == 0) { coff_symbol_type *sym = (coff_symbol_type *) (dst.l_addr.l_symndx @@ -2703,13 +2786,13 @@ asection *asect; cache_ptr->u.offset = dst.l_addr.l_paddr - bfd_section_vma(abfd, asect); } /* If no linenumber expect a symbol index */ - + cache_ptr++; src++; counter++; } cache_ptr->line_number = 0; - + } asect->lineno = lineno_cache; /* FIXME, free native_lineno here, or use alloca or something. */ @@ -2727,23 +2810,22 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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); - + /* 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))); - + if (cached_area == NULL) { bfd_error = no_memory; return false; @@ -2751,7 +2833,7 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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; @@ -2763,7 +2845,7 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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->u.syment._n._n_n._n_offset); /* We use the native name field to point to the cached field @@ -2780,10 +2862,13 @@ DEFUN(coff_slurp_symbol_table,(abfd), dst->symbol.flags |= BSF_NOT_AT_END; #endif /* Fall through to next case */ - + #endif - + case C_EXT: +#ifdef RS6000COFF_C + case C_HIDEXT: +#endif if ((src->u.syment.n_scnum) == 0) { if ((src->u.syment.n_value) == 0) { dst->symbol.flags = BSF_UNDEFINED; @@ -2814,8 +2899,8 @@ DEFUN(coff_slurp_symbol_table,(abfd), dst->symbol.flags |= BSF_NOT_AT_END; } } - break; + case C_STAT: /* static */ #ifdef I960 case C_LEAFSTAT: /* static leaf procedure */ @@ -2835,7 +2920,7 @@ DEFUN(coff_slurp_symbol_table,(abfd), else dst->symbol.value = (src->u.syment.n_value) ; break; - + case C_MOS: /* member of structure */ case C_EOS: /* end of structure */ #ifdef NOTDEF /* C_AUTOARG has the same value */ @@ -2849,7 +2934,6 @@ DEFUN(coff_slurp_symbol_table,(abfd), case C_AUTOARG: /* 960-specific storage class */ #endif case C_TPDEF: /* type definition */ - case C_ARG: case C_AUTO: /* automatic variable */ case C_FIELD: /* bit field */ @@ -2857,17 +2941,31 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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->u.syment.n_value); break; - + case C_FILE: /* file name */ case C_STRTAG: /* structure tag */ +#ifdef RS6000COFF_C + case C_BINCL: /* beginning of include file */ + case C_EINCL: /* ending of include file */ + case C_GSYM: + case C_LSYM: + case C_PSYM: + case C_RSYM: + case C_RPSYM: + case C_STSYM: + case C_DECL: + case C_ENTRY: + case C_FUN: + case C_BSTAT: + case C_ESTAT: +#endif 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" */ case C_EFCN: /* physical end of function */ @@ -2876,8 +2974,8 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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_NULL: case C_EXTDEF: /* external definition */ case C_ULABEL: /* undefined label */ @@ -2885,22 +2983,20 @@ DEFUN(coff_slurp_symbol_table,(abfd), case C_LINE: /* line # reformatted as symbol table entry */ case C_ALIAS: /* duplicate tag */ case C_HIDDEN: /* ext symbol in dmert public lib */ - default: - - fprintf(stderr,"Unrecognized storage class %d\n", + + fprintf(stderr,"Unrecognized storage class %d\n", src->u.syment.n_sclass); abort(); dst->symbol.flags = BSF_DEBUGGING; dst->symbol.value = (src->u.syment.n_value); - break; } - + BFD_ASSERT(dst->symbol.flags != 0); - + dst->native = src; - + dst->symbol.udata = 0; dst->lineno = (alent *) NULL; this_index += (src->u.syment.n_numaux) + 1; @@ -2908,10 +3004,10 @@ DEFUN(coff_slurp_symbol_table,(abfd), 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 */ @@ -2932,7 +3028,7 @@ bfd *abfd; { if (!coff_slurp_symbol_table(abfd)) return 0; - + return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *)); } @@ -2947,7 +3043,7 @@ asymbol **alocation; coff_symbol_type **location = (coff_symbol_type **) (alocation); if (!coff_slurp_symbol_table(abfd)) return 0; - + for (symbase = obj_symbols(abfd); counter++ < bfd_get_symcount(abfd);) *(location++) = symbase++; *location++ = 0; @@ -2971,11 +3067,11 @@ sec_ptr asect; /*doc* @subsubsection Reading Relocations Coff relocations are easily transformed into the internal BFD form -(@code{arelent}). +(@code{arelent}). Reading a coff relocation table is done in the following stages: @itemize @bullet -@item +@item The entire coff relocation table is read into memory. @item Each relocation is processed in turn, first it is swapped from the @@ -3019,7 +3115,7 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), asect->reloc_count)); reloc_cache = (arelent *) bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent))); - + if (reloc_cache == NULL) { bfd_error = no_memory; return false; @@ -3034,10 +3130,10 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), struct internal_reloc dst; asymbol *ptr; bfd_swap_reloc_in(abfd, src, &dst); - + dst.r_symndx += obj_symbol_slew(abfd); cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx]; -#ifdef A29K +#ifdef A29K /* AMD has two relocation entries for the 'consth' instruction. * The first is R_IHIHALF (part 1), the second is R_IHCONST * (part 2). The second entry's r_symndx does not contain @@ -3055,13 +3151,12 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), relocated as if their sections started at 0. But the offsets refering to the symbols in the raw data have not been modified, so we have to have a negative addend to compensate. - - Note that symbols which used to be common must be left alone - */ - - if (ptr && ptr->the_bfd == abfd - && ptr->section != (asection *) NULL - && ((ptr->flags & BSF_OLD_COMMON)== 0)) + + Note that symbols which used to be common must be left alone */ + + if (ptr && ptr->the_bfd == abfd + && ptr->section != (asection *) NULL + && ((ptr->flags & BSF_OLD_COMMON)== 0)) { #ifndef M88 cache_ptr->addend = -(ptr->section->vma + ptr->value); @@ -3073,12 +3168,12 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), else { cache_ptr->addend = 0; } - + cache_ptr->address -= asect->vma; - + cache_ptr->section = (asection *) NULL; -#ifdef A29K +#ifdef A29K if (dst.r_type == R_IHCONST) { /* Add in the value which was stored in the symbol index */ /* See above comment */ @@ -3106,11 +3201,9 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), BFD_ASSERT(0); } #endif - } - } - + asect->relocation = reloc_cache; return true; } @@ -3131,12 +3224,12 @@ asymbol **symbols; tblptr = section->relocation; if (!tblptr) return 0; - + for (; count++ < section->reloc_count;) *relptr++ = tblptr++; - + *relptr = 0; - + return section->reloc_count; } @@ -3169,28 +3262,28 @@ DEFUN(coff_find_nearest_line,(abfd, static bfd_vma cache_offset; static unsigned int cache_i; static alent *cache_l; - + unsigned int i = 0; coff_data_type *cof = coff_data(abfd); /* Run through the raw syments if available */ combined_entry_type *p; alent *l; unsigned int line_base = 0; - - + + *filename_ptr = 0; *functionname_ptr = 0; *line_ptr = 0; - + /* Don't try and find line numbers in a non coff file */ if (abfd->xvec->flavour != bfd_target_coff_flavour) return false; - + if (cof == NULL) return false; p = cof->raw_syments; - + for (i = 0; i < cof->raw_syment_count; i++) { if (p->u.syment.n_sclass == C_FILE) { /* File name has been moved into symbol */ @@ -3215,7 +3308,7 @@ DEFUN(coff_find_nearest_line,(abfd, i = 0; l = section->lineno; } - + for (; i < section->lineno_count; i++) { if (l->line_number == 0) { /* Get the symbol this line number points at */ @@ -3243,7 +3336,7 @@ DEFUN(coff_find_nearest_line,(abfd, } l++; } - + cache_abfd = abfd; cache_section = section; cache_offset = offset; @@ -3265,20 +3358,20 @@ bfd *abfd; #endif /* NO_COFF_SYMBOLS */ -static int +static int DEFUN(coff_sizeof_headers,(abfd, reloc), bfd *abfd AND boolean reloc) { size_t size; - + if (reloc == false) { size = FILHSZ + AOUTSZ; } else { size = FILHSZ; } - + size += abfd->section_count * SCNHSZ; return size; } @@ -3298,4 +3391,3 @@ DEFUN(coff_sizeof_headers,(abfd, reloc), #define coff_bfd_debug_info_start bfd_void #define coff_bfd_debug_info_end bfd_void #define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void - diff --git a/bfd/configure.in b/bfd/configure.in index a0243a7..b1c241b 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -111,6 +111,12 @@ sony) bfd_target=news ;; intel) bfd_target=${target_cpu}-coff ;; cbm) bfd_target=${target_cpu}-elf ;; +ibm) my_host=rs6000 + case "${target_cpu}" in + rs6000) bfd_target=rs6000 ;; + esac + ;; + amd) case "${target_os}" in ebmon) bfd_target=a29k-coff ;; diff --git a/bfd/section.c b/bfd/section.c index f5b2137..18baa11 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -34,20 +34,19 @@ the list. * section prototypes:: @end menu -@node Section Input, Section Output,,Sections -@comment node-name, next, previous, up +@node Section Input, Section Output, Sections, Sections @subsection Section Input When a BFD is opened for reading, the section structures are created -and attatched to the BFD. +and attached to the BFD. Each section has a name which describes the section in the outside world - for example, @code{a.out} would contain at least three sections, called @code{.text}, @code{.data} and @code{.bss}. Sometimes a BFD will contain more than the 'natural' number of -sections. A back end may attatch other sections containing constructor +sections. A back end may attach other sections containing constructor data, or an application may add a section (using bfd_make_section) to -the sections attatched to an already open BFD. For example, the linker +the sections attached to an already open BFD. For example, the linker creates a supernumary section @code{COMMON} for each input file's BFD to hold information about common storage. @@ -60,17 +59,17 @@ file doesn't contain raw data in sections, but data and relocation expressions intermixed, so the data area has to be parsed to get out the data and relocations. -@node Section Output,typedef asection,Section Input,Sections +@node Section Output, typedef asection, Section Input, Sections @subsection Section Output To write a new object style BFD, the various sections to be written -have to be created. They are attatched to the BFD in the same way as +have to be created. They are attached to the BFD in the same way as input sections, data is written to the sections using @code{bfd_set_section_contents}. The linker uses the fields @code{output_section} and @code{output_offset} to create an output file. -The data to be written comes from input sections attatched to the +The data to be written comes from input sections attached to the output sections. The output section structure can be considered a filter for the input section, the output section determines the vma of the output data and the name, but the input section determines the @@ -97,13 +96,13 @@ subsections, "A" at offset 0x0 (ie at vma 0x100) and "B" at offset */ -#include "sysdep.h" #include "bfd.h" +#include "sysdep.h" #include "libbfd.h" /*doc* -@node typedef asection,section prototypes,Section Output,Sections +@node typedef asection, section prototypes, Section Output, Sections @subsection typedef asection */ @@ -171,7 +170,7 @@ The section contains constructor information. This section type is used by the linker to create lists of constructors and destructors used by @code{g++}. When a back end sees a symbol which should be used in a constructor list, it creates a new section for the type of name -(eg @code{__CTOR_LIST__}), attatches the symbol to it and builds a +(eg @code{__CTOR_LIST__}), attaches the symbol to it and builds a relocation. To build the lists of constructors, all the linker has to to is catenate all the sections called @code{__CTOR_LIST__} and relocte the data contained within - exactly the operations it would @@ -297,7 +296,7 @@ $} asection ; */ /*doc* -@node section prototypes,Section,typedef section,Sections +@node section prototypes, , typedef asection, Sections @subsection section prototypes */ @@ -322,10 +321,10 @@ DEFUN(bfd_get_section_by_name,(abfd, name), /*proto* bfd_make_section -This function creates a new empty section called @var{name} and attatches it +This function creates a new empty section called @var{name} and attaches it to the end of the chain of sections for the BFD supplied. An attempt to -create a section with a name which is already in use, returns the old -section by that name instead. +create a section with a name which is already in use, returns NULL without +changing the section chain. Possible errors are: @table @code @@ -355,7 +354,7 @@ DEFUN(bfd_make_section,(abfd, name), } while (sect) { - if (!strcmp(sect->name, name)) return sect; + if (!strcmp(sect->name, name)) return NULL; prev = §->next; sect = sect->next; } @@ -418,7 +417,7 @@ DEFUN(bfd_set_section_flags,(abfd, section, flags), /*proto* bfd_map_over_sections -Calls the provided function @var{func} for each section attatched to +Calls the provided function @var{func} for each section attached to the BFD @var{abfd}, passing @var{obj} as an argument. The function will be called as if by diff --git a/bfd/targets.c b/bfd/targets.c index 05d7eff..d89e7bc 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -341,6 +341,7 @@ extern bfd_target i386coff_vec; extern bfd_target i386aout_vec; extern bfd_target a29kcoff_big_vec; extern bfd_target trad_core_vec; +extern bfd_target rs6000coff_vec; #ifdef SELECT_VECS @@ -387,6 +388,7 @@ extern bfd_target DEFAULT_VECTOR; #define I386COFF_VEC i386coff_vec #define I386AOUT_VEC i386aout_vec #define A29KCOFF_BIG_VEC a29kcoff_big_vec +#define RS6000COFF_VEC rs6000coff_vec #endif bfd_target *target_vector[] = { @@ -473,6 +475,10 @@ bfd_target *target_vector[] = { &trad_core_vec, #endif +#ifdef RS6000COFF_VEC + &RS6000COFF_VEC, +#endif + NULL, /* end of list marker */ }; |