X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoff-ppc.c;h=c5e695d311a93dd16013d10e3da551d0ae7aafcf;hb=c555c5c58e07aec1d70bd969e49e5f9609a73be0;hp=76c20569da1d0b841059f71af2f404c875adb3d6;hpb=13d1a4dda9c2eeb850bae5110672e2adeb828fac;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c index 76c20569da..c5e695d311 100644 --- a/bfd/coff-ppc.c +++ b/bfd/coff-ppc.c @@ -1,5 +1,6 @@ /* BFD back-end for PowerPC Microsoft Portable Executable files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. Original version pieced together by Kim Knuttila (krk@cygnus.com) @@ -21,7 +22,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Current State: - objdump works @@ -36,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "sysdep.h" #include "libbfd.h" -#include "obstack.h" #include "coff/powerpc.h" #include "coff/internal.h" @@ -51,6 +52,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "libcoff.h" +/* This file is compiled more than once, but we only compile the + final_link routine once. */ +extern boolean ppc_bfd_coff_final_link + PARAMS ((bfd *, struct bfd_link_info *)); +extern void dump_toc PARAMS ((PTR)); + /* The toc is a set of bfd_vma fields. We use the fact that valid */ /* addresses are even (i.e. the bit representing "1" is off) to allow */ /* us to encode a little extra information in the field */ @@ -68,6 +75,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MARK_AS_WRITTEN(x) ((x) |= 1) #define MAKE_ADDR_AGAIN(x) ((x) &= ~1) + +/* Turn on this check if you suspect something amiss in the hash tables */ +#ifdef DEBUG_HASH + +/* Need a 7 char string for an eye catcher */ +#define EYE "krkjunk" + +#define HASH_CHECK_DCL char eye_catcher[8]; +#define HASH_CHECK_INIT(ret) strcpy(ret->eye_catcher, EYE) +#define HASH_CHECK(addr) \ + if (strcmp(addr->eye_catcher, EYE) != 0) \ + { \ + fprintf(stderr,\ + _("File %s, line %d, Hash check failure, bad eye %8s\n"), \ + __FILE__, __LINE__, addr->eye_catcher); \ + abort(); \ + } + + +#else + +#define HASH_CHECK_DCL +#define HASH_CHECK_INIT(ret) +#define HASH_CHECK(addr) + +#endif + /* In order not to add an int to every hash table item for every coff linker, we define our own hash table, derived from the coff one */ @@ -82,20 +116,10 @@ struct ppc_coff_link_hash_entry bfd_vma toc_offset; /* Our addition, as required */ int symbol_is_glue; unsigned long int glue_insn; - char eye_catcher[8]; + + HASH_CHECK_DCL }; -/* Need a 7 char string for an eye catcher */ -#define EYE "krkjunk" - -#define CHECK_EYE(addr) \ - if (strcmp(addr, EYE) != 0) \ - { \ - fprintf(stderr,\ - "File %s, line %d, Hash check failure, bad eye %8s\n", \ - __FILE__, __LINE__, addr); \ - abort(); \ - } /* PE linker hash table. */ @@ -107,6 +131,20 @@ struct ppc_coff_link_hash_table static struct bfd_hash_entry *ppc_coff_link_hash_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); +static boolean ppc_coff_link_hash_table_init + PARAMS ((struct ppc_coff_link_hash_table *, bfd *, + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *))); +static struct bfd_link_hash_table *ppc_coff_link_hash_table_create + PARAMS ((bfd *)); +static boolean coff_ppc_relocate_section + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + struct internal_reloc *, struct internal_syment *, asection **)); +static reloc_howto_type *coff_ppc_rtype_to_howto + PARAMS ((bfd *, asection *, struct internal_reloc *, + struct coff_link_hash_entry *, struct internal_syment *, + bfd_vma *)); /* Routine to create an entry in the link hash table. */ @@ -140,7 +178,8 @@ ppc_coff_link_hash_newfunc (entry, table, string) SET_UNALLOCATED(ret->toc_offset); ret->symbol_is_glue = 0; ret->glue_insn = 0; - strcpy(ret->eye_catcher, EYE); + + HASH_CHECK_INIT(ret); } return (struct bfd_hash_entry *) ret; @@ -186,8 +225,8 @@ ppc_coff_link_hash_table_create (abfd) /* The nt loader points the toc register to &toc + 32768, in order to */ -/* use the complete range of a 16-bit displacement (I guess). We have */ -/* to adjust for this when we fix up loads displaced off the toc reg. */ +/* use the complete range of a 16-bit displacement. We have to adjust */ +/* for this when we fix up loads displaced off the toc reg. */ #define TOC_LOAD_ADJUSTMENT (-32768) #define TOC_SECTION_NAME ".private.toc" @@ -293,6 +332,7 @@ static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd, asection *section, bfd *output_bfd, char **error)); +#if 0 static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, @@ -300,6 +340,7 @@ static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd, asection *section, bfd *output_bfd, char **error)); +#endif static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, @@ -317,6 +358,7 @@ static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd, bfd *output_bfd, char **error)); +#if 0 static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, @@ -324,7 +366,7 @@ static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd, asection *section, bfd *output_bfd, char **error)); - +#endif static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, @@ -746,7 +788,7 @@ static reloc_howto_type ppc_coff_howto_table[] = if (i == 0) \ { \ i = 1; \ - fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \ + fprintf(stderr,_("Unimplemented Relocation -- %s\n"),x); \ } \ } @@ -783,6 +825,10 @@ static reloc_howto_type ppc_coff_howto_table[] = /* toc construction and management routines */ + +/* This file is compiled twice, and these variables are defined in one + of the compilations. FIXME: This is confusing and weird. Also, + BFD should not use global variables. */ extern bfd* bfd_of_toc_owner; extern long int global_toc_size; @@ -816,8 +862,11 @@ struct list_ele extern struct list_ele *head; extern struct list_ele *tail; +static void record_toc + PARAMS ((asection *, int, enum ref_category, const char *)); + static void -record_toc(toc_section, our_toc_offset, cat, name) +record_toc (toc_section, our_toc_offset, cat, name) asection *toc_section; int our_toc_offset; enum ref_category cat; @@ -825,7 +874,7 @@ record_toc(toc_section, our_toc_offset, cat, name) { /* add this entry to our toc addr-offset-name list */ struct list_ele *t; - t = bfd_malloc (sizeof (struct list_ele)); + t = (struct list_ele *) bfd_malloc (sizeof (struct list_ele)); if (t == NULL) abort (); t->next = 0; @@ -846,24 +895,23 @@ record_toc(toc_section, our_toc_offset, cat, name) } } +#ifdef COFF_IMAGE_WITH_PE + +static boolean ppc_record_toc_entry + PARAMS ((bfd *, struct bfd_link_info *, asection *, int, enum toc_type)); +static void ppc_mark_symbol_as_glue + PARAMS ((bfd *, int, struct internal_reloc *)); + /* record a toc offset against a symbol */ -static int +static boolean ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) bfd *abfd; - struct bfd_link_info *info; - asection *sec; + struct bfd_link_info *info ATTRIBUTE_UNUSED; + asection *sec ATTRIBUTE_UNUSED; int sym; - enum toc_type toc_kind; + enum toc_type toc_kind ATTRIBUTE_UNUSED; { - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; struct ppc_coff_link_hash_entry *h; - struct coff_symbol_struct *target; - int ret_val; const char *name; int *local_syms; @@ -873,7 +921,7 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); if (h != 0) { - CHECK_EYE(h->eye_catcher); + HASH_CHECK(h); } if (h == 0) @@ -881,7 +929,7 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) local_syms = obj_coff_local_toc_table(abfd); if (local_syms == 0) { - int i; + unsigned int i; /* allocate a table */ local_syms = (int *) bfd_zalloc (abfd, @@ -898,31 +946,15 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) if (IS_UNALLOCATED(local_syms[sym])) { local_syms[sym] = global_toc_size; - ret_val = global_toc_size; global_toc_size += 4; /* The size must fit in a 16bit displacment */ - if (global_toc_size >= 65535) + if (global_toc_size > 65535) { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); + (*_bfd_error_handler) (_("TOC overflow")); + bfd_set_error (bfd_error_file_too_big); + return false; } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif } } else @@ -934,151 +966,19 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) if (IS_UNALLOCATED(h->toc_offset)) { h->toc_offset = global_toc_size; - ret_val = global_toc_size; global_toc_size += 4; /* The size must fit in a 16bit displacment */ if (global_toc_size >= 65535) { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); + (*_bfd_error_handler) (_("TOC overflow")); + bfd_set_error (bfd_error_file_too_big); + return false; } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif } } - return ret_val; -} -/* FIXME: record a toc offset against a data-in-toc symbol */ -/* Now, there is currenly some confusion on what this means. In some - compilers one sees the moral equivalent of: - .tocd - define some data - .text - refer to the data with a [tocv] qualifier - In general, one sees something to indicate that a tocd has been - seen, and that would trigger the allocation of data in toc. The IBM - docs seem to suggest that anything with the TOCDEFN qualifier should - never trigger storage allocation. However, in the kernel32.lib that - we've been using for our test bed, there are a couple of variables - referenced that fail that test. - - So it can't work that way. -*/ -static int -ppc_record_data_in_toc_entry(abfd, info, sec, sym, toc_kind) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - int sym; - enum toc_type toc_kind; -{ - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; - struct ppc_coff_link_hash_entry *h = 0; - struct coff_symbol_struct *target; - int ret_val; - const char *name; - - int *local_syms; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - - if (h == 0) - { - local_syms = obj_coff_local_toc_table(abfd); - if (local_syms == 0) - { - int i; - /* allocate a table */ - local_syms = - (int *) bfd_zalloc (abfd, - obj_raw_syment_count(abfd) * sizeof(int)); - if (local_syms == 0) - return false; - obj_coff_local_toc_table(abfd) = local_syms; - for (i = 0; i < obj_raw_syment_count(abfd); ++i) - { - SET_UNALLOCATED(local_syms[i]); - } - } - - if (IS_UNALLOCATED(local_syms[sym])) - { - local_syms[sym] = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif - } - } - else - { - CHECK_EYE(h->eye_catcher); - - name = h->root.root.root.string; - - /* check to see if there's a toc slot allocated. If not, do it - here. It will be used in relocate_section */ - if (IS_UNALLOCATED(h->toc_offset)) - { -#if 0 - h->toc_offset = global_toc_size; -#endif - ret_val = global_toc_size; - /* We're allocating a chunk of the toc, as opposed to a slot */ - /* FIXME: alignment? */ - - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - } - - return ret_val; + return true; } /* record a toc offset against a symbol */ @@ -1092,7 +992,7 @@ ppc_mark_symbol_as_glue(abfd, sym, rel) h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - CHECK_EYE(h->eye_catcher); + HASH_CHECK(h); h->symbol_is_glue = 1; h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr); @@ -1100,35 +1000,14 @@ ppc_mark_symbol_as_glue(abfd, sym, rel) return; } +#endif /* COFF_IMAGE_WITH_PE */ -/* Provided the symbol, returns the value reffed */ -static long get_symbol_value PARAMS ((asymbol *)); - -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - { - relocation = 0; - } - else - { - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - } - - return(relocation); -} /* Return true if this relocation should appear in the output .reloc section. */ static boolean in_reloc_p(abfd, howto) - bfd * abfd; + bfd * abfd ATTRIBUTE_UNUSED; reloc_howto_type *howto; { return @@ -1146,6 +1025,8 @@ static boolean in_reloc_p(abfd, howto) && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ; } +#if 0 + /* this function is in charge of performing all the ppc PE relocations */ /* Don't yet know if we want to do this this particular way ... (krk) */ /* FIXME: (it is not yet enabled) */ @@ -1166,17 +1047,10 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, static boolean part1_consth_active = false; static unsigned long part1_consth_value; - unsigned long insn; unsigned long sym_value; - unsigned long unsigned_value; unsigned short r_type; - long signed_value; - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME); - r_type = reloc_entry->howto->type; if (output_bfd) @@ -1201,7 +1075,7 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) { part1_consth_active = false; - *error_message = (char *) "Missing PAIR"; + *error_message = (char *) _("Missing PAIR"); return(bfd_reloc_dangerous); } @@ -1211,6 +1085,8 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, return(bfd_reloc_ok); } +#endif /* 0 */ + /* The reloc processing routine for the optimized COFF linker. */ static boolean @@ -1233,15 +1109,6 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, bfd_vma relocation; reloc_howto_type *howto = 0; -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - /* If we are performing a relocateable link, we don't need to do a thing. The caller will take care of adjusting the reloc addresses and symbol indices. */ @@ -1266,25 +1133,7 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, unsigned short r_type = EXTRACT_TYPE (rel->r_type); unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - symndx = rel->r_symndx; loc = contents + rel->r_vaddr - input_section->vma; @@ -1302,12 +1151,18 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, (obj_coff_sym_hashes (input_bfd)[symndx]); if (h != 0) { - CHECK_EYE(h->eye_catcher); + HASH_CHECK(h); } sym = syms + symndx; } + if (r_type == IMAGE_REL_PPC_IMGLUE && h == 0) + { + /* An IMGLUE reloc must have a name. Something is very wrong. */ + abort(); + } + sec = NULL; val = 0; @@ -1321,13 +1176,14 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, sec = sections[symndx]; val = (sec->output_section->vma + sec->output_offset - + sym->n_value - - sec->vma); + + sym->n_value); + if (! obj_pe (output_bfd)) + val -= sec->vma; } } else { - CHECK_EYE(h->eye_catcher); + HASH_CHECK(h); if (h->root.root.type == bfd_link_hash_defined || h->root.root.type == bfd_link_hash_defweak) @@ -1339,11 +1195,9 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, } else { -fprintf(stderr, - "missing %s\n",h->root.root.root.string); if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) + rel->r_vaddr - input_section->vma, true))) return false; } } @@ -1354,11 +1208,10 @@ fprintf(stderr, switch (r_type) { default: - fprintf( stderr, - "ERROR: during reloc processing -- unsupported reloc %s\n", - howto->name); + (*_bfd_error_handler) + (_("%s: unsupported relocation type 0x%02x"), + bfd_get_filename (input_bfd), r_type); bfd_set_error (bfd_error_bad_value); - abort(); return false; case IMAGE_REL_PPC_TOCREL16: { @@ -1371,17 +1224,10 @@ fprintf(stderr, { toc_section = bfd_get_section_by_name (bfd_of_toc_owner, TOC_SECTION_NAME); -#ifdef TOC_DEBUG - - fprintf(stderr, - "BFD of toc owner %p (%s), section addr of %s %p\n", - bfd_of_toc_owner, bfd_of_toc_owner->filename, - TOC_SECTION_NAME, toc_section); -#endif if ( toc_section == NULL ) { - fprintf(stderr, "No Toc section!\n"); + /* There is no toc section. Something is very wrong. */ abort(); } } @@ -1412,27 +1258,14 @@ fprintf(stderr, again. */ MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif } else { /* write out the toc entry */ - record_toc(toc_section, our_toc_offset, priv, strdup(name)); -#ifdef TOC_DEBUG - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif + record_toc(toc_section, + our_toc_offset, + priv, + strdup(name)); bfd_put_32(output_bfd, val, @@ -1449,11 +1282,6 @@ fprintf(stderr, if ((r_flags & IMAGE_REL_PPC_TOCDEFN) == IMAGE_REL_PPC_TOCDEFN ) -#if 0 - /* This is wrong. If tocdefn is on, we must unconditionally - assume the following path */ - && IS_UNALLOCATED(our_toc_offset)) -#endif { /* This is unbelievable cheese. Some knowledgable asm hacker has decided to use r2 as a base for loading @@ -1469,28 +1297,19 @@ fprintf(stderr, dll linkage, takes advantage of that and considers the IAT to be part of the toc, thus saving a load. */ -#ifdef DEBUG_RELOC - fprintf(stderr, - "TOCDEFN is on, (%s) (%p) our_toc_offset = %x\n", - name, h, our_toc_offset); -#endif our_toc_offset = val - (toc_section->output_section->vma + toc_section->output_offset); -#ifdef DEBUG_RELOC - fprintf(stderr, - " our_toc_offset set to %x\n", our_toc_offset); -#endif - /* The size must still fit in a 16bit displacment */ if (our_toc_offset >= 65535) { - fprintf(stderr, - "TOCDEFN Relocation exceeded " - "displacment of 65535\n"); - abort(); + (*_bfd_error_handler) + (_("%s: Relocation for %s of %x exceeds Toc size limit"), + bfd_get_filename (input_bfd), name, our_toc_offset); + bfd_set_error (bfd_error_bad_value); + return false; } record_toc(toc_section, our_toc_offset, pub, strdup(name)); @@ -1502,28 +1321,11 @@ fprintf(stderr, again. */ MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif } else { record_toc(toc_section, our_toc_offset, pub, strdup(name)); -#ifdef TOC_DEBUG - /* write out the toc entry */ - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif - /* write out the toc entry */ bfd_put_32(output_bfd, val, @@ -1551,10 +1353,6 @@ fprintf(stderr, if (coff_data(output_bfd)->pe) addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; -#ifdef DEBUG_RELOC - fprintf(stderr, - " Toc Section .reloc candidate addr = %x\n", addr); -#endif fwrite (&addr, 1,4, (FILE *) info->base_file); } @@ -1563,9 +1361,12 @@ fprintf(stderr, if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN && our_toc_offset > toc_section->_raw_size) { - fprintf(stderr, - "reloc offset is bigger than the toc size!\n"); - abort(); + (*_bfd_error_handler) + (_("%s: Relocation exceeds allocated TOC (%x)"), + bfd_get_filename (input_bfd), + toc_section->_raw_size); + bfd_set_error (bfd_error_bad_value); + return false; } /* Now we know the relocation for this toc reference */ @@ -1620,13 +1421,14 @@ fprintf(stderr, } fprintf(stderr, - "Warning: unsupported reloc %s \n", + _("Warning: unsupported reloc %s \n"), howto->name, bfd_get_filename(input_bfd), input_section->name); - fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n", - rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr); + fprintf(stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", + rel->r_symndx, my_name, (long) rel->r_vaddr, + (unsigned long) rel->r_vaddr); } break; case IMAGE_REL_PPC_IMGLUE: @@ -1637,15 +1439,13 @@ fprintf(stderr, if (h->symbol_is_glue == 1) break; my_name = h->root.root.root.string; - fprintf(stderr, - "Warning: previously missed IMGLUE reloc %s \n", - howto->name, - bfd_get_filename(input_bfd), - input_section->name); - break; + (*_bfd_error_handler) + (_("%s: Out of order IMGLUE reloc for %s"), + bfd_get_filename (input_bfd), my_name); + bfd_set_error (bfd_error_bad_value); + return false; } - break; case IMAGE_REL_PPC_ADDR32NB: { @@ -1676,12 +1476,6 @@ fprintf(stderr, "__idata4_magic__", false, false, true); import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - fprintf(stderr, - "first computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif } if (h == 0) @@ -1710,8 +1504,7 @@ fprintf(stderr, false, false, true); if (myh == 0) { - fprintf(stderr, "Missing idata magic cookies, " - "this cannot work anyway...\n"); + /* Missing magic cookies. Something is very wrong. */ abort(); } @@ -1738,13 +1531,6 @@ fprintf(stderr, "__idata4_magic__", false, false, true); import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - - fprintf(stderr, - "second computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif } } } @@ -1794,17 +1580,8 @@ fprintf(stderr, if (coff_data(output_bfd)->pe) { - bfd_vma before_addr = addr; addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; -#ifdef DEBUG_RELOC - fprintf(stderr, - " adjusted down from %x to %x", before_addr, addr); -#endif } -#ifdef DEBUG_RELOC - fprintf(stderr, "\n"); -#endif - fwrite (&addr, 1,4, (FILE *) info->base_file); } } @@ -1835,28 +1612,12 @@ fprintf(stderr, buf[SYMNMLEN] = '\0'; name = buf; } -#if 0 - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } -#endif if (! ((*info->callbacks->reloc_overflow) (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_vaddr - input_section->vma))) { -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif return false; } } @@ -1864,21 +1625,15 @@ fprintf(stderr, } -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - return true; } - #ifdef COFF_IMAGE_WITH_PE +/* FIXME: BFD should not use global variables. This file is compiled + twice, and these variables are shared. This is confusing and + weird. */ + long int global_toc_size = 4; bfd* bfd_of_toc_owner = 0; @@ -1891,49 +1646,49 @@ struct list_ele *head; struct list_ele *tail; static char * -h1 = "\n\t\t\tTOC MAPPING\n\n"; +h1 = N_("\n\t\t\tTOC MAPPING\n\n"); static char * -h2 = " TOC disassembly Comments Name\n"; +h2 = N_(" TOC disassembly Comments Name\n"); static char * -h3 = " Offset spelling (if present)\n"; +h3 = N_(" Offset spelling (if present)\n"); void -dump_toc(vfile) - void *vfile; +dump_toc (vfile) + PTR vfile; { - FILE *file = vfile; + FILE *file = (FILE *) vfile; struct list_ele *t; - fprintf(file, h1); - fprintf(file, h2); - fprintf(file, h3); + fprintf(file, _(h1)); + fprintf(file, _(h2)); + fprintf(file, _(h3)); for(t = head; t != 0; t=t->next) { - char *cat; + const char *cat = ""; if (t->cat == priv) - cat = "private "; + cat = _("private "); else if (t->cat == pub) - cat = "public "; + cat = _("public "); else if (t->cat == data) - cat = "data-in-toc "; + cat = _("data-in-toc "); if (t->offset > global_toc_size) { if (t->offset <= global_toc_size + thunk_size) - cat = "IAT reference "; + cat = _("IAT reference "); else { fprintf(file, - "**** global_toc_size %d(%x), thunk_size %d(%x)\n", + _("**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n"), global_toc_size, global_toc_size, thunk_size, thunk_size); - cat = "Out of bounds!"; + cat = _("Out of bounds!"); } } fprintf(file, - " %04lx (%d)", t->offset, t->offset - 32768); + " %04lx (%d)", (unsigned long) t->offset, t->offset - 32768); fprintf(file, " %s %s\n", cat, t->name); @@ -1945,7 +1700,7 @@ dump_toc(vfile) boolean ppc_allocate_toc_section (info) - struct bfd_link_info *info; + struct bfd_link_info *info ATTRIBUTE_UNUSED; { asection *s; bfd_byte *foo; @@ -1956,19 +1711,18 @@ ppc_allocate_toc_section (info) if (bfd_of_toc_owner == 0) { - fprintf(stderr, - "There is no bfd that owns the toc section!\n"); + /* No toc owner? Something is very wrong. */ abort(); } s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME); if (s == NULL) { - fprintf(stderr, "No Toc section!\n"); + /* No toc section? Something is very wrong. */ abort(); } - foo = bfd_alloc(bfd_of_toc_owner, global_toc_size); + foo = (bfd_byte *) bfd_alloc(bfd_of_toc_owner, global_toc_size); memset(foo, test_char, global_toc_size); s->_raw_size = s->_cooked_size = global_toc_size; @@ -1985,12 +1739,6 @@ ppc_process_before_allocation (abfd, info) asection *sec; struct internal_reloc *i, *rel; -#ifdef DEBUG_RELOC - fprintf(stderr, - "ppc_process_before_allocation: BFD %s\n", - bfd_get_filename(abfd)); -#endif - /* here we have a bfd that is to be included on the link. We have a hook to do reloc rummaging, before section sizes are nailed down. */ @@ -2006,15 +1754,6 @@ ppc_process_before_allocation (abfd, info) for (; sec != 0; sec = sec->next) { - int toc_offset; - -#ifdef DEBUG_RELOC - fprintf(stderr, - " section %s reloc count %d\n", - sec->name, - sec->reloc_count); -#endif - if (sec->reloc_count == 0) continue; @@ -2029,47 +1768,20 @@ ppc_process_before_allocation (abfd, info) { unsigned short r_type = EXTRACT_TYPE (rel->r_type); unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); + boolean ok = true; -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); switch(r_type) { case IMAGE_REL_PPC_TOCREL16: -#if 0 - /* FIXME: - This remains unimplemented for now, as it currently adds - un-necessary elements to the toc. All we need to do today - is not do anything if TOCDEFN is on. - */ - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec, - rel->r_symndx, - default_toc); - else - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); -#endif + /* if TOCDEFN is on, ignore as someone else has allocated the + toc entry */ if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); + ok = ppc_record_toc_entry(abfd, info, sec, + rel->r_symndx, default_toc); + if (!ok) + return false; break; case IMAGE_REL_PPC_IMGLUE: ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel); @@ -2079,6 +1791,8 @@ ppc_process_before_allocation (abfd, info) } } } + + return true; } #endif @@ -2092,13 +1806,13 @@ ppc_refhi_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("REFHI"); DUMP_RELOC("REFHI",reloc_entry); @@ -2109,6 +1823,8 @@ ppc_refhi_reloc (abfd, return bfd_reloc_undefined; } +#if 0 + static bfd_reloc_status_type ppc_reflo_reloc (abfd, reloc_entry, @@ -2134,6 +1850,8 @@ ppc_reflo_reloc (abfd, return bfd_reloc_undefined; } +#endif + static bfd_reloc_status_type ppc_pair_reloc (abfd, reloc_entry, @@ -2142,13 +1860,13 @@ ppc_pair_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("PAIR"); DUMP_RELOC("PAIR",reloc_entry); @@ -2168,13 +1886,13 @@ ppc_toc16_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("TOCREL16"); DUMP_RELOC("TOCREL16",reloc_entry); @@ -2187,6 +1905,8 @@ ppc_toc16_reloc (abfd, return bfd_reloc_ok; } +#if 0 + /* ADDR32NB : 32 bit address relative to the virtual origin. */ /* (On the alpha, this is always a linker generated thunk)*/ /* (i.e. 32bit addr relative to the image base) */ @@ -2215,6 +1935,8 @@ ppc_addr32nb_reloc (abfd, return bfd_reloc_ok; } +#endif + static bfd_reloc_status_type ppc_secrel_reloc (abfd, reloc_entry, @@ -2223,13 +1945,13 @@ ppc_secrel_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("SECREL"); DUMP_RELOC("SECREL",reloc_entry); @@ -2248,13 +1970,13 @@ ppc_section_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("SECTION"); DUMP_RELOC("SECTION",reloc_entry); @@ -2273,13 +1995,13 @@ ppc_imglue_reloc (abfd, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; + bfd *abfd ATTRIBUTE_UNUSED; + arelent *reloc_entry ATTRIBUTE_UNUSED; + asymbol *symbol ATTRIBUTE_UNUSED; + PTR data ATTRIBUTE_UNUSED; + asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; - char **error_message; + char **error_message ATTRIBUTE_UNUSED; { UN_IMPL("IMGLUE"); DUMP_RELOC("IMGLUE",reloc_entry); @@ -2326,38 +2048,11 @@ ppc_coff_rtype2howto (relent, internal) /* the masking process only slices off the bottom byte for r_type. */ if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n", - internal->r_type, 0, MAX_RELOC_INDEX); - abort(); - } + abort(); /* check for absolute crap */ if ( junk != 0 ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d contains junk %d\n", - internal->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif + abort(); switch(r_type) { @@ -2385,7 +2080,7 @@ ppc_coff_rtype2howto (relent, internal) break; default: fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", + _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"), ppc_coff_howto_table[r_type].name, r_type); howto = ppc_coff_howto_table + r_type; @@ -2398,11 +2093,11 @@ ppc_coff_rtype2howto (relent, internal) static reloc_howto_type * coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; + bfd *abfd ATTRIBUTE_UNUSED; asection *sec; struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; + struct coff_link_hash_entry *h ATTRIBUTE_UNUSED; + struct internal_syment *sym ATTRIBUTE_UNUSED; bfd_vma *addendp; { reloc_howto_type *howto; @@ -2424,39 +2119,12 @@ coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp) /* the masking process only slices off the bottom byte for r_type. */ if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n", - r_type, 0, MAX_RELOC_INDEX); - abort(); - } + abort(); /* check for absolute crap */ if ( junk != 0 ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n", - rel->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - + abort(); + switch(r_type) { case IMAGE_REL_PPC_ADDR32NB: @@ -2487,7 +2155,7 @@ coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp) break; default: fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", + _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"), ppc_coff_howto_table[r_type].name, r_type); howto = ppc_coff_howto_table + r_type; @@ -2507,15 +2175,9 @@ PARAMS ((bfd *, bfd_reloc_code_real_type)); static reloc_howto_type * ppc_coff_reloc_type_lookup (abfd, code) - bfd *abfd; + bfd *abfd ATTRIBUTE_UNUSED; bfd_reloc_code_real_type code; { - -#ifdef DEBUG_RELOC - fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n", - bfd_get_reloc_code_name(code)); -#endif - switch (code) { HOW2MAP(BFD_RELOC_32_GOTOFF, IMAGE_REL_PPC_IMGLUE); @@ -2530,8 +2192,7 @@ ppc_coff_reloc_type_lookup (abfd, code) default: return NULL; } - - return NULL; + /*NOTREACHED*/ } #undef HOW2MAP @@ -2542,8 +2203,7 @@ ppc_coff_reloc_type_lookup (abfd, code) #define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst) #ifndef COFF_IMAGE_WITH_PE -static void -ppc_coff_swap_sym_in_hook (); +static void ppc_coff_swap_sym_in_hook PARAMS ((bfd *, PTR, PTR)); #endif /* We use the special COFF backend linker, with our own special touch. */ @@ -2554,6 +2214,7 @@ ppc_coff_swap_sym_in_hook (); #define coff_bfd_final_link ppc_bfd_coff_final_link #ifndef COFF_IMAGE_WITH_PE +/* FIXME: This no longer works. */ #define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook #endif @@ -2561,8 +2222,25 @@ ppc_coff_swap_sym_in_hook (); #define COFF_PAGE_SIZE 0x1000 +/* FIXME: This controls some code that used to be in peicode.h and is + now in peigen.c. It will not control the code in peigen.c. If + anybody wants to get this working, you will need to fix that. */ #define POWERPC_LE_PE +#define COFF_SECTION_ALIGNMENT_ENTRIES \ +{ COFF_SECTION_NAME_EXACT_MATCH (".idata$2"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \ +{ COFF_SECTION_NAME_EXACT_MATCH (".idata$3"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \ +{ COFF_SECTION_NAME_EXACT_MATCH (".idata$4"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_EXACT_MATCH (".idata$5"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_EXACT_MATCH (".idata$6"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 }, \ +{ COFF_SECTION_NAME_EXACT_MATCH (".reloc"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 } + #include "coffcode.h" @@ -2585,10 +2263,9 @@ ppc_coff_swap_sym_in_hook (); static void ppc_coff_swap_sym_in_hook (abfd, ext1, in1) bfd *abfd; - PTR ext1; + PTR ext1 ATTRIBUTE_UNUSED; PTR in1; { - SYMENT *ext = (SYMENT *)ext1; struct internal_syment *in = (struct internal_syment *)in1; if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */ @@ -2598,7 +2275,6 @@ ppc_coff_swap_sym_in_hook (abfd, ext1, in1) { flagword flags; register asection *s; - char *foo; s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME); if (s != NULL) @@ -2608,20 +2284,13 @@ ppc_coff_swap_sym_in_hook (abfd, ext1, in1) flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ; -#ifdef TOC_DEBUG - fprintf(stderr, - "ppc_coff_swap_sym_in_hook: about to create the %s section\n", - TOC_SECTION_NAME); -#endif - s = bfd_make_section (abfd, TOC_SECTION_NAME); if (s == NULL || !bfd_set_section_flags (abfd, s, flags) || !bfd_set_section_alignment (abfd, s, 2)) { - fprintf(stderr, - "toc section allocation failed!\n"); + /* FIXME: set appropriate bfd error */ abort(); } @@ -2633,13 +2302,13 @@ ppc_coff_swap_sym_in_hook (abfd, ext1, in1) } #endif -boolean -ppc_bfd_coff_final_link (); - #ifndef COFF_IMAGE_WITH_PE +static boolean ppc_do_last PARAMS ((bfd *)); +static bfd *ppc_get_last PARAMS ((void)); + static boolean -ppc_do_last(abfd) +ppc_do_last (abfd) bfd *abfd; { if (abfd == bfd_of_toc_owner) @@ -2665,7 +2334,6 @@ ppc_get_last() where the POWERPC_LE_PE macro modifies the code. It is left in as a precise form of comment. krk@cygnus.com */ -#define POWERPC_LE_PE /* Do the final link step. */ @@ -2700,6 +2368,7 @@ ppc_bfd_coff_final_link (abfd, info) finfo.strtab = NULL; finfo.section_info = NULL; finfo.last_file_index = -1; + finfo.last_bf_index = -1; finfo.internal_syms = NULL; finfo.sec_ptrs = NULL; finfo.sym_indices = NULL; @@ -2722,7 +2391,10 @@ ppc_bfd_coff_final_link (abfd, info) /* Compute the file positions for all the sections. */ if (! abfd->output_has_begun) - bfd_coff_compute_section_file_positions (abfd); + { + if (! bfd_coff_compute_section_file_positions (abfd)) + return false; + } /* Count the line numbers and relocation entries required for the output file. Set the file positions for the relocs. */ @@ -2745,6 +2417,12 @@ ppc_bfd_coff_final_link (abfd, info) sec = p->u.indirect.section; + /* Mark all sections which are to be included in the + link. This will normally be every section. We need + to do this so that we can identify any sections which + the linker has decided to not include. */ + sec->linker_mark = true; + if (info->strip == strip_none || info->strip == strip_some) o->lineno_count += sec->lineno_count; @@ -2920,7 +2598,7 @@ ppc_bfd_coff_final_link (abfd, info) if (! sub->output_has_begun) #endif { - if (! coff_link_input_bfd (&finfo, sub)) + if (! _bfd_coff_link_input_bfd (&finfo, sub)) goto error_return; sub->output_has_begun = true; } @@ -2928,7 +2606,7 @@ ppc_bfd_coff_final_link (abfd, info) else if (p->type == bfd_section_reloc_link_order || p->type == bfd_symbol_reloc_link_order) { - if (! coff_reloc_link_order (abfd, &finfo, o, p)) + if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) goto error_return; } else @@ -2941,18 +2619,17 @@ ppc_bfd_coff_final_link (abfd, info) #ifdef POWERPC_LE_PE { - extern bfd* ppc_get_last(); bfd* last_one = ppc_get_last(); if (last_one) { - if (! coff_link_input_bfd (&finfo, last_one)) + if (! _bfd_coff_link_input_bfd (&finfo, last_one)) goto error_return; } last_one->output_has_begun = true; } #endif - /* Free up the buffers used by coff_link_input_bfd. */ + /* Free up the buffers used by _bfd_coff_link_input_bfd. */ coff_debug_merge_hash_table_free (&finfo.debug_merge); debug_merge_allocated = false; @@ -3012,12 +2689,12 @@ ppc_bfd_coff_final_link (abfd, info) /* Write out the global symbols. */ finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), coff_write_global_sym, + coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, (PTR) &finfo); if (finfo.failed) goto error_return; - /* The outsyms buffer is used by coff_write_global_sym. */ + /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ if (finfo.outsyms != NULL) { free (finfo.outsyms); @@ -3084,6 +2761,13 @@ ppc_bfd_coff_final_link (abfd, info) finfo.section_info = NULL; } + /* If we have optimized stabs strings, output them. */ + if (coff_hash_table (info)->stab_info != NULL) + { + if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info)) + return false; + } + /* Write out the string table. */ if (obj_raw_syment_count (abfd) != 0) { @@ -3157,11 +2841,15 @@ ppc_bfd_coff_final_link (abfd, info) #endif +/* Forward declaration for use by alternative_target field. */ +#ifdef TARGET_BIG_SYM +extern const bfd_target TARGET_BIG_SYM; +#endif + /* The transfer vectors that lead the outside world to all of the above. */ #ifdef TARGET_LITTLE_SYM -const bfd_target -TARGET_LITTLE_SYM = +const bfd_target TARGET_LITTLE_SYM = { TARGET_LITTLE_NAME, /* name or coff-arm-little */ bfd_target_coff_flavour, @@ -3170,9 +2858,15 @@ TARGET_LITTLE_SYM = (HAS_RELOC | EXEC_P | /* FIXME: object flags */ HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), +#ifndef COFF_WITH_PE (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ +#else + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), +#endif + 0, /* leading char */ '/', /* ar_pad_char */ 15, /* ar_max_namelen??? FIXMEmgo */ @@ -3201,14 +2895,20 @@ TARGET_LITTLE_SYM = BFD_JUMP_TABLE_WRITE (coff), BFD_JUMP_TABLE_LINK (coff), BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + /* Alternative_target. */ +#ifdef TARGET_BIG_SYM + & TARGET_BIG_SYM, +#else + NULL, +#endif - COFF_SWAP_TABLE, + COFF_SWAP_TABLE }; #endif #ifdef TARGET_BIG_SYM -const bfd_target -TARGET_BIG_SYM = +const bfd_target TARGET_BIG_SYM = { TARGET_BIG_NAME, bfd_target_coff_flavour, @@ -3217,9 +2917,15 @@ TARGET_BIG_SYM = (HAS_RELOC | EXEC_P | /* FIXME: object flags */ HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), +#ifndef COFF_WITH_PE (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ +#else + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), +#endif + 0, /* leading char */ '/', /* ar_pad_char */ 15, /* ar_max_namelen??? FIXMEmgo */ @@ -3249,7 +2955,15 @@ TARGET_BIG_SYM = BFD_JUMP_TABLE_LINK (coff), BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - COFF_SWAP_TABLE, + + /* Alternative_target. */ +#ifdef TARGET_LITTLE_SYM + & TARGET_LITTLE_SYM, +#else + NULL, +#endif + + COFF_SWAP_TABLE }; #endif