Back to index

cell-binutils  2.17cvs20070401
coff-ppc.c
Go to the documentation of this file.
00001 /* BFD back-end for PowerPC Microsoft Portable Executable files.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00004    Free Software Foundation, Inc.
00005 
00006    Original version pieced together by Kim Knuttila (krk@cygnus.com)
00007 
00008    There is nothing new under the sun. This file draws a lot on other
00009    coff files, in particular, those for the rs/6000, alpha, mips, and
00010    intel backends, and the PE work for the arm.
00011 
00012    This file is part of BFD, the Binary File Descriptor library.
00013 
00014    This program is free software; you can redistribute it and/or modify
00015    it under the terms of the GNU General Public License as published by
00016    the Free Software Foundation; either version 2 of the License, or
00017    (at your option) any later version.
00018 
00019    This program is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022    GNU General Public License for more details.
00023 
00024    You should have received a copy of the GNU General Public License
00025    along with this program; if not, write to the Free Software
00026    Foundation, 51 Franklin Street - Fifth Floor,
00027    Boston, MA 02110-1301, USA.  */
00028 
00029 /* Current State:
00030    - objdump works
00031    - relocs generated by gas
00032    - ld will link files, but they do not run.
00033    - dlltool will not produce correct output in some .reloc cases, and will
00034      not produce the right glue code for dll function calls.  */
00035 
00036 #include "bfd.h"
00037 #include "sysdep.h"
00038 
00039 #include "libbfd.h"
00040 
00041 #include "coff/powerpc.h"
00042 #include "coff/internal.h"
00043 
00044 #include "coff/pe.h"
00045 
00046 #ifdef BADMAG
00047 #undef BADMAG
00048 #endif
00049 
00050 #define BADMAG(x) PPCBADMAG(x)
00051 
00052 #include "libcoff.h"
00053 
00054 /* This file is compiled more than once, but we only compile the
00055    final_link routine once.  */
00056 extern bfd_boolean ppc_bfd_coff_final_link
00057   PARAMS ((bfd *, struct bfd_link_info *));
00058 extern void dump_toc PARAMS ((PTR));
00059 
00060 /* The toc is a set of bfd_vma fields. We use the fact that valid
00061    addresses are even (i.e. the bit representing "1" is off) to allow
00062    us to encode a little extra information in the field
00063    - Unallocated addresses are initialized to 1.
00064    - Allocated addresses are even numbers.
00065    The first time we actually write a reference to the toc in the bfd,
00066    we want to record that fact in a fixup file (if it is asked for), so
00067    we keep track of whether or not an address has been written by marking
00068    the low order bit with a "1" upon writing.  */
00069 
00070 #define SET_UNALLOCATED(x)  ((x) = 1)
00071 #define IS_UNALLOCATED(x)   ((x) == 1)
00072 
00073 #define IS_WRITTEN(x)       ((x) & 1)
00074 #define MARK_AS_WRITTEN(x)  ((x) |= 1)
00075 #define MAKE_ADDR_AGAIN(x)  ((x) &= ~1)
00076 
00077 /* Turn on this check if you suspect something amiss in the hash tables.  */
00078 #ifdef DEBUG_HASH
00079 
00080 /* Need a 7 char string for an eye catcher.  */
00081 #define EYE "krkjunk"
00082 
00083 #define HASH_CHECK_DCL char eye_catcher[8];
00084 #define HASH_CHECK_INIT(ret)      strcpy(ret->eye_catcher, EYE)
00085 #define HASH_CHECK(addr) \
00086  if (strcmp(addr->eye_catcher, EYE) != 0) \
00087   { \
00088     fprintf (stderr,\
00089     _("File %s, line %d, Hash check failure, bad eye %8s\n"), \
00090     __FILE__, __LINE__, addr->eye_catcher); \
00091     abort (); \
00092  }
00093 
00094 #else
00095 
00096 #define HASH_CHECK_DCL
00097 #define HASH_CHECK_INIT(ret)
00098 #define HASH_CHECK(addr)
00099 
00100 #endif
00101 
00102 /* In order not to add an int to every hash table item for every coff
00103    linker, we define our own hash table, derived from the coff one.  */
00104 
00105 /* PE linker hash table entries.  */
00106 
00107 struct ppc_coff_link_hash_entry
00108 {
00109   struct coff_link_hash_entry root; /* First entry, as required.  */
00110 
00111   /* As we wonder around the relocs, we'll keep the assigned toc_offset
00112      here.  */
00113   bfd_vma toc_offset;               /* Our addition, as required.  */
00114   int symbol_is_glue;
00115   unsigned long int glue_insn;
00116 
00117   HASH_CHECK_DCL
00118 };
00119 
00120 /* PE linker hash table.  */
00121 
00122 struct ppc_coff_link_hash_table
00123 {
00124   struct coff_link_hash_table root; /* First entry, as required.  */
00125 };
00126 
00127 static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
00128   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
00129           const char *));
00130 static struct bfd_link_hash_table *ppc_coff_link_hash_table_create
00131   PARAMS ((bfd *));
00132 static bfd_boolean coff_ppc_relocate_section
00133   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00134           struct internal_reloc *, struct internal_syment *, asection **));
00135 static reloc_howto_type *coff_ppc_rtype_to_howto
00136   PARAMS ((bfd *, asection *, struct internal_reloc *,
00137           struct coff_link_hash_entry *, struct internal_syment *,
00138           bfd_vma *));
00139 
00140 /* Routine to create an entry in the link hash table.  */
00141 
00142 static struct bfd_hash_entry *
00143 ppc_coff_link_hash_newfunc (entry, table, string)
00144      struct bfd_hash_entry *entry;
00145      struct bfd_hash_table *table;
00146      const char *string;
00147 {
00148   struct ppc_coff_link_hash_entry *ret =
00149     (struct ppc_coff_link_hash_entry *) entry;
00150 
00151   /* Allocate the structure if it has not already been allocated by a
00152      subclass.  */
00153   if (ret == (struct ppc_coff_link_hash_entry *) NULL)
00154     ret = (struct ppc_coff_link_hash_entry *)
00155       bfd_hash_allocate (table,
00156                       sizeof (struct ppc_coff_link_hash_entry));
00157 
00158   if (ret == (struct ppc_coff_link_hash_entry *) NULL)
00159     return NULL;
00160 
00161   /* Call the allocation method of the superclass.  */
00162   ret = ((struct ppc_coff_link_hash_entry *)
00163         _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret,
00164                                   table, string));
00165 
00166   if (ret)
00167     {
00168       /* Initialize the local fields.  */
00169       SET_UNALLOCATED (ret->toc_offset);
00170       ret->symbol_is_glue = 0;
00171       ret->glue_insn = 0;
00172 
00173       HASH_CHECK_INIT (ret);
00174     }
00175 
00176   return (struct bfd_hash_entry *) ret;
00177 }
00178 
00179 /* Initialize a PE linker hash table.  */
00180 
00181 static bfd_boolean
00182 ppc_coff_link_hash_table_init (struct ppc_coff_link_hash_table *table,
00183                             bfd *abfd,
00184                             struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
00185                                                           struct bfd_hash_table *,
00186                                                           const char *),
00187                             unsigned int entsize)
00188 {
00189   return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc, entsize);
00190 }
00191 
00192 /* Create a PE linker hash table.  */
00193 
00194 static struct bfd_link_hash_table *
00195 ppc_coff_link_hash_table_create (abfd)
00196      bfd *abfd;
00197 {
00198   struct ppc_coff_link_hash_table *ret;
00199   bfd_size_type amt = sizeof (struct ppc_coff_link_hash_table);
00200 
00201   ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt);
00202   if (ret == NULL)
00203     return NULL;
00204   if (!ppc_coff_link_hash_table_init (ret, abfd,
00205                                   ppc_coff_link_hash_newfunc,
00206                                   sizeof (struct ppc_coff_link_hash_entry)))
00207     {
00208       free (ret);
00209       return (struct bfd_link_hash_table *) NULL;
00210     }
00211   return &ret->root.root;
00212 }
00213 
00214 /* Now, tailor coffcode.h to use our hash stuff.  */
00215 
00216 #define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
00217 
00218 /* The nt loader points the toc register to &toc + 32768, in order to
00219    use the complete range of a 16-bit displacement. We have to adjust
00220    for this when we fix up loads displaced off the toc reg.  */
00221 #define TOC_LOAD_ADJUSTMENT (-32768)
00222 #define TOC_SECTION_NAME ".private.toc"
00223 
00224 /* The main body of code is in coffcode.h.  */
00225 
00226 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00227 
00228 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00229    from smaller values.  Start with zero, widen, *then* decrement.  */
00230 #define MINUS_ONE    (((bfd_vma)0) - 1)
00231 
00232 /* These should definitely go in a header file somewhere...  */
00233 
00234 /* NOP */
00235 #define IMAGE_REL_PPC_ABSOLUTE          0x0000
00236 
00237 /* 64-bit address */
00238 #define IMAGE_REL_PPC_ADDR64            0x0001
00239 
00240 /* 32-bit address */
00241 #define IMAGE_REL_PPC_ADDR32            0x0002
00242 
00243 /* 26-bit address, shifted left 2 (branch absolute) */
00244 #define IMAGE_REL_PPC_ADDR24            0x0003
00245 
00246 /* 16-bit address */
00247 #define IMAGE_REL_PPC_ADDR16            0x0004
00248 
00249 /* 16-bit address, shifted left 2 (load doubleword) */
00250 #define IMAGE_REL_PPC_ADDR14            0x0005
00251 
00252 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
00253 #define IMAGE_REL_PPC_REL24             0x0006
00254 
00255 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
00256 #define IMAGE_REL_PPC_REL14             0x0007
00257 
00258 /* 16-bit offset from TOC base */
00259 #define IMAGE_REL_PPC_TOCREL16          0x0008
00260 
00261 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
00262 #define IMAGE_REL_PPC_TOCREL14          0x0009
00263 
00264 /* 32-bit addr w/o image base */
00265 #define IMAGE_REL_PPC_ADDR32NB          0x000A
00266 
00267 /* va of containing section (as in an image sectionhdr) */
00268 #define IMAGE_REL_PPC_SECREL            0x000B
00269 
00270 /* sectionheader number */
00271 #define IMAGE_REL_PPC_SECTION           0x000C
00272 
00273 /* substitute TOC restore instruction iff symbol is glue code */
00274 #define IMAGE_REL_PPC_IFGLUE            0x000D
00275 
00276 /* symbol is glue code; virtual address is TOC restore instruction */
00277 #define IMAGE_REL_PPC_IMGLUE            0x000E
00278 
00279 /* va of containing section (limited to 16 bits) */
00280 #define IMAGE_REL_PPC_SECREL16          0x000F
00281 
00282 /* Stuff to handle immediate data when the number of bits in the
00283    data is greater than the number of bits in the immediate field
00284    We need to do (usually) 32 bit arithmetic on 16 bit chunks.  */
00285 #define IMAGE_REL_PPC_REFHI             0x0010
00286 #define IMAGE_REL_PPC_REFLO             0x0011
00287 #define IMAGE_REL_PPC_PAIR              0x0012
00288 
00289 /* This is essentially the same as tocrel16, with TOCDEFN assumed.  */
00290 #define IMAGE_REL_PPC_TOCREL16_DEFN     0x0013
00291 
00292 /* Flag bits in IMAGE_RELOCATION.TYPE.  */
00293 
00294 /* Subtract reloc value rather than adding it.  */
00295 #define IMAGE_REL_PPC_NEG               0x0100
00296 
00297 /* Fix branch prediction bit to predict branch taken.  */
00298 #define IMAGE_REL_PPC_BRTAKEN           0x0200
00299 
00300 /* Fix branch prediction bit to predict branch not taken.  */
00301 #define IMAGE_REL_PPC_BRNTAKEN          0x0400
00302 
00303 /* TOC slot defined in file (or, data in toc).  */
00304 #define IMAGE_REL_PPC_TOCDEFN           0x0800
00305 
00306 /* Masks to isolate above values in IMAGE_RELOCATION.Type.  */
00307 #define IMAGE_REL_PPC_TYPEMASK          0x00FF
00308 #define IMAGE_REL_PPC_FLAGMASK          0x0F00
00309 
00310 #define EXTRACT_TYPE(x)                 ((x) & IMAGE_REL_PPC_TYPEMASK)
00311 #define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
00312 #define EXTRACT_JUNK(x)  \
00313            ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
00314 
00315 /* Static helper functions to make relocation work.  */
00316 /* (Work In Progress) */
00317 
00318 static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
00319                                                 arelent *reloc,
00320                                                 asymbol *symbol,
00321                                                 PTR data,
00322                                                 asection *section,
00323                                                 bfd *output_bfd,
00324                                                 char **error));
00325 static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
00326                                                arelent *reloc,
00327                                                asymbol *symbol,
00328                                                PTR data,
00329                                                asection *section,
00330                                                bfd *output_bfd,
00331                                                char **error));
00332 
00333 static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
00334                                                 arelent *reloc,
00335                                                 asymbol *symbol,
00336                                                 PTR data,
00337                                                 asection *section,
00338                                                 bfd *output_bfd,
00339                                                 char **error));
00340 
00341 static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
00342                                                  arelent *reloc,
00343                                                  asymbol *symbol,
00344                                                  PTR data,
00345                                                  asection *section,
00346                                                  bfd *output_bfd,
00347                                                  char **error));
00348 
00349 static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
00350                                                  arelent *reloc,
00351                                                  asymbol *symbol,
00352                                                  PTR data,
00353                                                  asection *section,
00354                                                  bfd *output_bfd,
00355                                                  char **error));
00356 
00357 static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
00358                                                  arelent *reloc,
00359                                                  asymbol *symbol,
00360                                                  PTR data,
00361                                                  asection *section,
00362                                                  bfd *output_bfd,
00363                                                  char **error));
00364 
00365 static bfd_boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
00366 
00367 /* FIXME: It'll take a while to get through all of these. I only need a few to
00368    get us started, so those I'll make sure work. Those marked FIXME are either
00369    completely unverified or have a specific unknown marked in the comment.  */
00370 
00371 /* Relocation entries for Windows/NT on PowerPC.                             
00372 
00373    From the document "" we find the following listed as used relocs:
00374 
00375      ABSOLUTE       : The noop
00376      ADDR[64|32|16] : fields that hold addresses in data fields or the
00377                       16 bit displacement field on a load/store.
00378      ADDR[24|14]    : fields that hold addresses in branch and cond
00379                       branches. These represent [26|16] bit addresses.
00380                       The low order 2 bits are preserved.
00381      REL[24|14]     : branches relative to the Instruction Address
00382                       register. These represent [26|16] bit addresses,
00383                       as before. The instruction field will be zero, and
00384                       the address of the SYM will be inserted at link time.
00385      TOCREL16       : 16 bit displacement field referring to a slot in
00386                       toc.
00387      TOCREL14       : 16 bit displacement field, similar to REL14 or ADDR14.
00388      ADDR32NB       : 32 bit address relative to the virtual origin.
00389                       (On the alpha, this is always a linker generated thunk)
00390                       (i.e. 32bit addr relative to the image base)
00391      SECREL         : The value is relative to the start of the section
00392                       containing the symbol.
00393      SECTION        : access to the header containing the item. Supports the
00394                       codeview debugger.
00395 
00396    In particular, note that the document does not indicate that the
00397    relocations listed in the header file are used.  */
00398 
00399 
00400 static reloc_howto_type ppc_coff_howto_table[] =
00401 {
00402   /* IMAGE_REL_PPC_ABSOLUTE 0x0000   NOP */
00403   /* Unused: */
00404   HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */
00405         0,                     /* rightshift */
00406         0,                     /* size (0 = byte, 1 = short, 2 = long) */
00407         0,                     /* bitsize */
00408         FALSE,                        /* pc_relative */
00409         0,                     /* bitpos */
00410         complain_overflow_dont, /* dont complain_on_overflow */
00411         0,                    /* special_function */
00412         "ABSOLUTE",             /* name */
00413         FALSE,                        /* partial_inplace */
00414         0x00,                 /* src_mask */
00415         0x00,                       /* dst_mask */
00416         FALSE),                 /* pcrel_offset */
00417 
00418   /* IMAGE_REL_PPC_ADDR64 0x0001  64-bit address */
00419   /* Unused: */
00420   HOWTO(IMAGE_REL_PPC_ADDR64,    /* type */
00421        0,                      /* rightshift */
00422        3,                      /* size (0 = byte, 1 = short, 2 = long) */
00423        64,                     /* bitsize */
00424        FALSE,                  /* pc_relative */
00425        0,                      /* bitpos */
00426        complain_overflow_bitfield,         /* complain_on_overflow */
00427        0,                     /* special_function */
00428        "ADDR64",               /* name */
00429        TRUE,                   /* partial_inplace */
00430        MINUS_ONE,            /* src_mask */
00431        MINUS_ONE,            /* dst_mask */
00432        FALSE),                 /* pcrel_offset */
00433 
00434   /* IMAGE_REL_PPC_ADDR32 0x0002  32-bit address */
00435   /* Used: */
00436   HOWTO (IMAGE_REL_PPC_ADDR32,     /* type */
00437         0,                    /* rightshift */
00438         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00439         32,                   /* bitsize */
00440         FALSE,                       /* pc_relative */
00441         0,                    /* bitpos */
00442         complain_overflow_bitfield, /* complain_on_overflow */
00443         0,                   /* special_function */
00444         "ADDR32",              /* name */
00445         TRUE,                 /* partial_inplace */
00446         0xffffffff,            /* src_mask */
00447         0xffffffff,            /* dst_mask */
00448         FALSE),                /* pcrel_offset */
00449 
00450   /* IMAGE_REL_PPC_ADDR24 0x0003  26-bit address, shifted left 2 (branch absolute) */
00451   /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
00452   /* Of course, That's the IBM approved bit numbering, which is not what */
00453   /* anyone else uses.... The li field is in bit 2 thru 25 */
00454   /* Used: */
00455   HOWTO (IMAGE_REL_PPC_ADDR24,  /* type */
00456         0,                    /* rightshift */
00457         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00458         26,                   /* bitsize */
00459         FALSE,                       /* pc_relative */
00460         0,                    /* bitpos */
00461         complain_overflow_bitfield, /* complain_on_overflow */
00462         0,                   /* special_function */
00463         "ADDR24",              /* name */
00464         TRUE,                 /* partial_inplace */
00465         0x07fffffc,          /* src_mask */
00466         0x07fffffc,         /* dst_mask */
00467         FALSE),                /* pcrel_offset */
00468 
00469   /* IMAGE_REL_PPC_ADDR16 0x0004  16-bit address */
00470   /* Used: */
00471   HOWTO (IMAGE_REL_PPC_ADDR16,  /* type */
00472         0,                    /* rightshift */
00473         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00474         16,                   /* bitsize */
00475         FALSE,                       /* pc_relative */
00476         0,                    /* bitpos */
00477         complain_overflow_signed, /* complain_on_overflow */
00478         0,                   /* special_function */
00479         "ADDR16",              /* name */
00480         TRUE,                 /* partial_inplace */
00481         0xffff,              /* src_mask */
00482         0xffff,             /* dst_mask */
00483         FALSE),                /* pcrel_offset */
00484 
00485   /* IMAGE_REL_PPC_ADDR14 0x0005 */
00486   /*  16-bit address, shifted left 2 (load doubleword) */
00487   /* FIXME: the mask is likely wrong, and the bit position may be as well */
00488   /* Unused: */
00489   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */
00490         1,                    /* rightshift */
00491         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00492         16,                   /* bitsize */
00493         FALSE,                       /* pc_relative */
00494         0,                    /* bitpos */
00495         complain_overflow_signed, /* complain_on_overflow */
00496         0,                   /* special_function */
00497         "ADDR16",              /* name */
00498         TRUE,                 /* partial_inplace */
00499         0xffff,              /* src_mask */
00500         0xffff,             /* dst_mask */
00501         FALSE),                /* pcrel_offset */
00502 
00503   /* IMAGE_REL_PPC_REL24 0x0006 */
00504   /*   26-bit PC-relative offset, shifted left 2 (branch relative) */
00505   /* Used: */
00506   HOWTO (IMAGE_REL_PPC_REL24,   /* type */
00507         0,                    /* rightshift */
00508         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00509         26,                   /* bitsize */
00510         TRUE,                 /* pc_relative */
00511         0,                    /* bitpos */
00512         complain_overflow_signed, /* complain_on_overflow */
00513         0,                   /* special_function */
00514         "REL24",               /* name */
00515         TRUE,                 /* partial_inplace */
00516         0x3fffffc,           /* src_mask */
00517         0x3fffffc,          /* dst_mask */
00518         FALSE),                /* pcrel_offset */
00519 
00520   /* IMAGE_REL_PPC_REL14 0x0007 */
00521   /*   16-bit PC-relative offset, shifted left 2 (br cond relative) */
00522   /* FIXME: the mask is likely wrong, and the bit position may be as well */
00523   /* FIXME: how does it know how far to shift? */
00524   /* Unused: */
00525   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */
00526         1,                    /* rightshift */
00527         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00528         16,                   /* bitsize */
00529         FALSE,                       /* pc_relative */
00530         0,                    /* bitpos */
00531         complain_overflow_signed, /* complain_on_overflow */
00532         0,                   /* special_function */
00533         "ADDR16",              /* name */
00534         TRUE,                 /* partial_inplace */
00535         0xffff,              /* src_mask */
00536         0xffff,             /* dst_mask */
00537         TRUE),                 /* pcrel_offset */
00538 
00539   /* IMAGE_REL_PPC_TOCREL16 0x0008 */
00540   /*   16-bit offset from TOC base */
00541   /* Used: */
00542   HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */
00543         0,                    /* rightshift */
00544         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00545         16,                   /* bitsize */
00546         FALSE,                       /* pc_relative */
00547         0,                    /* bitpos */
00548         complain_overflow_dont, /* complain_on_overflow */
00549         ppc_toc16_reloc,       /* special_function */
00550         "TOCREL16",            /* name */
00551         FALSE,                       /* partial_inplace */
00552         0xffff,              /* src_mask */
00553         0xffff,             /* dst_mask */
00554         FALSE),                /* pcrel_offset */
00555 
00556   /* IMAGE_REL_PPC_TOCREL14 0x0009 */
00557   /*   16-bit offset from TOC base, shifted left 2 (load doubleword) */
00558   /* Unused: */
00559   HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */
00560         1,                    /* rightshift */
00561         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00562         16,                   /* bitsize */
00563         FALSE,                       /* pc_relative */
00564         0,                    /* bitpos */
00565         complain_overflow_signed, /* complain_on_overflow */
00566         0,                   /* special_function */
00567         "TOCREL14",            /* name */
00568         FALSE,                       /* partial_inplace */
00569         0xffff,              /* src_mask */
00570         0xffff,             /* dst_mask */
00571         FALSE),                /* pcrel_offset */
00572 
00573   /* IMAGE_REL_PPC_ADDR32NB 0x000A */
00574   /*   32-bit addr w/ image base */
00575   /* Unused: */
00576   HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */
00577         0,                    /* rightshift */
00578         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00579         32,                   /* bitsize */
00580         FALSE,                       /* pc_relative */
00581         0,                    /* bitpos */
00582         complain_overflow_signed, /* complain_on_overflow */
00583         0,                     /* special_function */
00584         "ADDR32NB",            /* name */
00585         TRUE,                 /* partial_inplace */
00586         0xffffffff,          /* src_mask */
00587         0xffffffff,         /* dst_mask */
00588         FALSE),                 /* pcrel_offset */
00589 
00590   /* IMAGE_REL_PPC_SECREL 0x000B */
00591   /*   va of containing section (as in an image sectionhdr) */
00592   /* Unused: */
00593   HOWTO (IMAGE_REL_PPC_SECREL,/* type */
00594         0,                    /* rightshift */
00595         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00596         32,                   /* bitsize */
00597         FALSE,                       /* pc_relative */
00598         0,                    /* bitpos */
00599         complain_overflow_signed, /* complain_on_overflow */
00600         ppc_secrel_reloc,      /* special_function */
00601         "SECREL",              /* name */
00602         TRUE,                 /* partial_inplace */
00603         0xffffffff,          /* src_mask */
00604         0xffffffff,         /* dst_mask */
00605         TRUE),                 /* pcrel_offset */
00606 
00607   /* IMAGE_REL_PPC_SECTION 0x000C */
00608   /*   sectionheader number */
00609   /* Unused: */
00610   HOWTO (IMAGE_REL_PPC_SECTION,/* type */
00611         0,                    /* rightshift */
00612         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00613         32,                   /* bitsize */
00614         FALSE,                       /* pc_relative */
00615         0,                    /* bitpos */
00616         complain_overflow_signed, /* complain_on_overflow */
00617         ppc_section_reloc,     /* special_function */
00618         "SECTION",             /* name */
00619         TRUE,                 /* partial_inplace */
00620         0xffffffff,          /* src_mask */
00621         0xffffffff,         /* dst_mask */
00622         TRUE),                 /* pcrel_offset */
00623 
00624   /* IMAGE_REL_PPC_IFGLUE 0x000D */
00625   /*   substitute TOC restore instruction iff symbol is glue code */
00626   /* Used: */
00627   HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */
00628         0,                    /* rightshift */
00629         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00630         32,                   /* bitsize */
00631         FALSE,                       /* pc_relative */
00632         0,                    /* bitpos */
00633         complain_overflow_signed, /* complain_on_overflow */
00634         0,                   /* special_function */
00635         "IFGLUE",              /* name */
00636         TRUE,                 /* partial_inplace */
00637         0xffffffff,          /* src_mask */
00638         0xffffffff,         /* dst_mask */
00639         FALSE),                /* pcrel_offset */
00640 
00641   /* IMAGE_REL_PPC_IMGLUE 0x000E */
00642   /*   symbol is glue code; virtual address is TOC restore instruction */
00643   /* Unused: */
00644   HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */
00645         0,                    /* rightshift */
00646         2,                    /* size (0 = byte, 1 = short, 2 = long) */
00647         32,                   /* bitsize */
00648         FALSE,                       /* pc_relative */
00649         0,                    /* bitpos */
00650         complain_overflow_dont, /* complain_on_overflow */
00651         ppc_imglue_reloc,      /* special_function */
00652         "IMGLUE",              /* name */
00653         FALSE,                       /* partial_inplace */
00654         0xffffffff,          /* src_mask */
00655         0xffffffff,         /* dst_mask */
00656         FALSE),                 /* pcrel_offset */
00657 
00658   /* IMAGE_REL_PPC_SECREL16 0x000F */
00659   /*   va of containing section (limited to 16 bits) */
00660   /* Unused: */
00661   HOWTO (IMAGE_REL_PPC_SECREL16,/* type */
00662         0,                    /* rightshift */
00663         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00664         16,                   /* bitsize */
00665         FALSE,                       /* pc_relative */
00666         0,                    /* bitpos */
00667         complain_overflow_signed, /* complain_on_overflow */
00668         0,                   /* special_function */
00669         "SECREL16",            /* name */
00670         TRUE,                 /* partial_inplace */
00671         0xffff,              /* src_mask */
00672         0xffff,             /* dst_mask */
00673         TRUE),                 /* pcrel_offset */
00674 
00675   /* IMAGE_REL_PPC_REFHI             0x0010 */
00676   /* Unused: */
00677   HOWTO (IMAGE_REL_PPC_REFHI,   /* type */
00678         0,                    /* rightshift */
00679         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00680         16,                   /* bitsize */
00681         FALSE,                       /* pc_relative */
00682         0,                    /* bitpos */
00683         complain_overflow_signed, /* complain_on_overflow */
00684         ppc_refhi_reloc,    /* special_function */
00685         "REFHI",               /* name */
00686         TRUE,                 /* partial_inplace */
00687         0xffffffff,          /* src_mask */
00688         0xffffffff,         /* dst_mask */
00689         FALSE),                 /* pcrel_offset */
00690 
00691   /* IMAGE_REL_PPC_REFLO             0x0011 */
00692   /* Unused: */
00693   HOWTO (IMAGE_REL_PPC_REFLO,   /* type */
00694         0,                    /* rightshift */
00695         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00696         16,                   /* bitsize */
00697         FALSE,                       /* pc_relative */
00698         0,                    /* bitpos */
00699         complain_overflow_signed, /* complain_on_overflow */
00700         ppc_refhi_reloc,    /* special_function */
00701         "REFLO",               /* name */
00702         TRUE,                 /* partial_inplace */
00703         0xffffffff,          /* src_mask */
00704         0xffffffff,         /* dst_mask */
00705         FALSE),                /* pcrel_offset */
00706 
00707   /* IMAGE_REL_PPC_PAIR              0x0012 */
00708   /* Unused: */
00709   HOWTO (IMAGE_REL_PPC_PAIR,    /* type */
00710         0,                    /* rightshift */
00711         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00712         16,                   /* bitsize */
00713         FALSE,                       /* pc_relative */
00714         0,                    /* bitpos */
00715         complain_overflow_signed, /* complain_on_overflow */
00716         ppc_pair_reloc,        /* special_function */
00717         "PAIR",                /* name */
00718         TRUE,                 /* partial_inplace */
00719         0xffffffff,          /* src_mask */
00720         0xffffffff,         /* dst_mask */
00721         FALSE),                /* pcrel_offset */
00722 
00723   /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */
00724   /*   16-bit offset from TOC base, without causing a definition */
00725   /* Used: */
00726   HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */
00727         0,                    /* rightshift */
00728         1,                    /* size (0 = byte, 1 = short, 2 = long) */
00729         16,                   /* bitsize */
00730         FALSE,                       /* pc_relative */
00731         0,                    /* bitpos */
00732         complain_overflow_dont, /* complain_on_overflow */
00733         0,                     /* special_function */
00734         "TOCREL16, TOCDEFN",   /* name */
00735         FALSE,                       /* partial_inplace */
00736         0xffff,              /* src_mask */
00737         0xffff,             /* dst_mask */
00738         FALSE),                /* pcrel_offset */
00739 
00740 };
00741 
00742 /* Some really cheezy macros that can be turned on to test stderr :-)  */
00743 
00744 #ifdef DEBUG_RELOC
00745 #define UN_IMPL(x)                                           \
00746 {                                                            \
00747    static int i;                                             \
00748    if (i == 0)                                               \
00749      {                                                       \
00750        i = 1;                                                \
00751        fprintf (stderr,_("Unimplemented Relocation -- %s\n"),x); \
00752      }                                                       \
00753 }
00754 
00755 #define DUMP_RELOC(n,r)                              \
00756 {                                                    \
00757    fprintf (stderr,"%s sym %d, addr %d, addend %d\n", \
00758           n, (*(r->sym_ptr_ptr))->name,             \
00759           r->address, r->addend);                   \
00760 }
00761 
00762 /* Given a reloc name, n, and a pointer to an internal_reloc,
00763    dump out interesting information on the contents
00764 
00765 #define n_name              _n._n_name
00766 #define n_zeroes     _n._n_n._n_zeroes
00767 #define n_offset     _n._n_n._n_offset  */
00768 
00769 #define DUMP_RELOC2(n,r)                                \
00770 {                                                       \
00771    fprintf (stderr,"%s sym %d, r_vaddr %d %s\n",        \
00772           n, r->r_symndx, r->r_vaddr,                   \
00773           (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
00774           ?" ":" TOCDEFN"  );                           \
00775 }
00776 
00777 #else
00778 #define UN_IMPL(x)
00779 #define DUMP_RELOC(n,r)
00780 #define DUMP_RELOC2(n,r)
00781 #endif
00782 
00783 /* TOC construction and management routines.  */
00784 
00785 /* This file is compiled twice, and these variables are defined in one
00786    of the compilations.  FIXME: This is confusing and weird.  Also,
00787    BFD should not use global variables.  */
00788 extern bfd *    bfd_of_toc_owner;
00789 extern long int global_toc_size;
00790 extern long int import_table_size;
00791 extern long int first_thunk_address;
00792 extern long int thunk_size;
00793 
00794 enum toc_type
00795 {
00796   default_toc,
00797   toc_32,
00798   toc_64
00799 };
00800 
00801 enum ref_category
00802 {
00803   priv,
00804   pub,
00805   tocdata
00806 };
00807 
00808 struct list_ele
00809 {
00810   struct list_ele *next;
00811   bfd_vma addr;
00812   enum ref_category cat;
00813   int offset;
00814   const char *name;
00815 };
00816 
00817 extern struct list_ele *head;
00818 extern struct list_ele *tail;
00819 
00820 static void record_toc
00821   PARAMS ((asection *, bfd_signed_vma, enum ref_category, const char *));
00822 
00823 static void
00824 record_toc (toc_section, our_toc_offset, cat, name)
00825      asection *toc_section;
00826      bfd_signed_vma our_toc_offset;
00827      enum ref_category cat;
00828      const char *name;
00829 {
00830   /* Add this entry to our toc addr-offset-name list.  */
00831   bfd_size_type amt = sizeof (struct list_ele);
00832   struct list_ele *t = (struct list_ele *) bfd_malloc (amt);
00833 
00834   if (t == NULL)
00835     abort ();
00836   t->next = 0;
00837   t->offset = our_toc_offset;
00838   t->name = name;
00839   t->cat = cat;
00840   t->addr = toc_section->output_offset + our_toc_offset;
00841 
00842   if (head == 0)
00843     {
00844       head = t;
00845       tail = t;
00846     }
00847   else
00848     {
00849       tail->next = t;
00850       tail = t;
00851     }
00852 }
00853 
00854 #ifdef COFF_IMAGE_WITH_PE
00855 
00856 static bfd_boolean ppc_record_toc_entry
00857   PARAMS ((bfd *, struct bfd_link_info *, asection *, int, enum toc_type));
00858 static void ppc_mark_symbol_as_glue
00859   PARAMS ((bfd *, int, struct internal_reloc *));
00860 
00861 /* Record a toc offset against a symbol.  */
00862 static bfd_boolean
00863 ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
00864      bfd *abfd;
00865      struct bfd_link_info *info ATTRIBUTE_UNUSED;
00866      asection *sec ATTRIBUTE_UNUSED;
00867      int sym;
00868      enum toc_type toc_kind ATTRIBUTE_UNUSED;
00869 {
00870   struct ppc_coff_link_hash_entry *h;
00871   const char *name;
00872 
00873   int *local_syms;
00874 
00875   h = 0;
00876 
00877   h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
00878   if (h != 0)
00879     {
00880       HASH_CHECK(h);
00881     }
00882 
00883   if (h == 0)
00884     {
00885       local_syms = obj_coff_local_toc_table(abfd);
00886 
00887       if (local_syms == 0)
00888        {
00889          unsigned int i;
00890          bfd_size_type amt;
00891 
00892          /* allocate a table */
00893          amt = (bfd_size_type) obj_raw_syment_count (abfd) * sizeof (int);
00894          local_syms = (int *) bfd_zalloc (abfd, amt);
00895          if (local_syms == 0)
00896            return FALSE;
00897          obj_coff_local_toc_table (abfd) = local_syms;
00898 
00899          for (i = 0; i < obj_raw_syment_count (abfd); ++i)
00900            {
00901              SET_UNALLOCATED (local_syms[i]);
00902            }
00903        }
00904 
00905       if (IS_UNALLOCATED(local_syms[sym]))
00906        {
00907          local_syms[sym] = global_toc_size;
00908          global_toc_size += 4;
00909 
00910          /* The size must fit in a 16-bit displacement.  */
00911          if (global_toc_size > 65535)
00912            {
00913              (*_bfd_error_handler) (_("TOC overflow"));
00914              bfd_set_error (bfd_error_file_too_big);
00915              return FALSE;
00916            }
00917        }
00918     }
00919   else
00920     {
00921       name = h->root.root.root.string;
00922 
00923       /* Check to see if there's a toc slot allocated. If not, do it
00924         here. It will be used in relocate_section.  */
00925       if (IS_UNALLOCATED(h->toc_offset))
00926        {
00927          h->toc_offset = global_toc_size;
00928          global_toc_size += 4;
00929 
00930          /* The size must fit in a 16-bit displacement.  */
00931          if (global_toc_size >= 65535)
00932            {
00933              (*_bfd_error_handler) (_("TOC overflow"));
00934              bfd_set_error (bfd_error_file_too_big);
00935              return FALSE;
00936            }
00937        }
00938     }
00939 
00940   return TRUE;
00941 }
00942 
00943 /* Record a toc offset against a symbol.  */
00944 static void
00945 ppc_mark_symbol_as_glue(abfd, sym, rel)
00946      bfd *abfd;
00947      int sym;
00948      struct internal_reloc *rel;
00949 {
00950   struct ppc_coff_link_hash_entry *h;
00951 
00952   h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
00953 
00954   HASH_CHECK(h);
00955 
00956   h->symbol_is_glue = 1;
00957   h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
00958 
00959   return;
00960 }
00961 
00962 #endif /* COFF_IMAGE_WITH_PE */
00963 
00964 /* Return TRUE if this relocation should
00965    appear in the output .reloc section.  */
00966 
00967 static bfd_boolean in_reloc_p(abfd, howto)
00968      bfd * abfd ATTRIBUTE_UNUSED;
00969      reloc_howto_type *howto;
00970 {
00971   return
00972     (! howto->pc_relative)
00973       && (howto->type != IMAGE_REL_PPC_ADDR32NB)
00974       && (howto->type != IMAGE_REL_PPC_TOCREL16)
00975       && (howto->type != IMAGE_REL_PPC_IMGLUE)
00976       && (howto->type != IMAGE_REL_PPC_IFGLUE)
00977       && (howto->type != IMAGE_REL_PPC_SECREL)
00978       && (howto->type != IMAGE_REL_PPC_SECTION)
00979       && (howto->type != IMAGE_REL_PPC_SECREL16)
00980       && (howto->type != IMAGE_REL_PPC_REFHI)
00981       && (howto->type != IMAGE_REL_PPC_REFLO)
00982       && (howto->type != IMAGE_REL_PPC_PAIR)
00983       && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
00984 }
00985 
00986 /* The reloc processing routine for the optimized COFF linker.  */
00987 
00988 static bfd_boolean
00989 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
00990                         contents, relocs, syms, sections)
00991      bfd *output_bfd;
00992      struct bfd_link_info *info;
00993      bfd *input_bfd;
00994      asection *input_section;
00995      bfd_byte *contents;
00996      struct internal_reloc *relocs;
00997      struct internal_syment *syms;
00998      asection **sections;
00999 {
01000   struct internal_reloc *rel;
01001   struct internal_reloc *relend;
01002   bfd_boolean hihalf;
01003   bfd_vma hihalf_val;
01004   asection *toc_section = 0;
01005   bfd_vma relocation;
01006   reloc_howto_type *howto = 0;
01007 
01008   /* If we are performing a relocatable link, we don't need to do a
01009      thing.  The caller will take care of adjusting the reloc
01010      addresses and symbol indices.  */
01011   if (info->relocatable)
01012     return TRUE;
01013 
01014   hihalf = FALSE;
01015   hihalf_val = 0;
01016 
01017   rel = relocs;
01018   relend = rel + input_section->reloc_count;
01019   for (; rel < relend; rel++)
01020     {
01021       long symndx;
01022       struct ppc_coff_link_hash_entry *h;
01023       struct internal_syment *sym;
01024       bfd_vma val;
01025 
01026       asection *sec;
01027       bfd_reloc_status_type rstat;
01028       bfd_byte *loc;
01029 
01030       unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
01031       unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
01032 
01033       symndx = rel->r_symndx;
01034       loc = contents + rel->r_vaddr - input_section->vma;
01035 
01036       /* FIXME: check bounds on r_type */
01037       howto = ppc_coff_howto_table + r_type;
01038 
01039       if (symndx == -1)
01040        {
01041          h = NULL;
01042          sym = NULL;
01043        }
01044       else
01045        {
01046          h = (struct ppc_coff_link_hash_entry *)
01047            (obj_coff_sym_hashes (input_bfd)[symndx]);
01048          if (h != 0)
01049            {
01050              HASH_CHECK(h);
01051            }
01052 
01053          sym = syms + symndx;
01054        }
01055 
01056       if (r_type == IMAGE_REL_PPC_IMGLUE && h == 0)
01057        {
01058          /* An IMGLUE reloc must have a name. Something is very wrong.  */
01059          abort ();
01060        }
01061 
01062       sec = NULL;
01063       val = 0;
01064 
01065       /* FIXME: PAIR unsupported in the following code.  */
01066       if (h == NULL)
01067        {
01068          if (symndx == -1)
01069            sec = bfd_abs_section_ptr;
01070          else
01071            {
01072              sec = sections[symndx];
01073              val = (sec->output_section->vma
01074                    + sec->output_offset
01075                    + sym->n_value);
01076              if (! obj_pe (output_bfd))
01077               val -= sec->vma;
01078            }
01079        }
01080       else
01081        {
01082          HASH_CHECK(h);
01083 
01084          if (h->root.root.type == bfd_link_hash_defined
01085              || h->root.root.type == bfd_link_hash_defweak)
01086            {
01087              sec = h->root.root.u.def.section;
01088              val = (h->root.root.u.def.value
01089                    + sec->output_section->vma
01090                    + sec->output_offset);
01091            }
01092          else
01093            {
01094              if (! ((*info->callbacks->undefined_symbol)
01095                    (info, h->root.root.root.string, input_bfd, input_section,
01096                     rel->r_vaddr - input_section->vma, TRUE)))
01097               return FALSE;
01098            }
01099        }
01100 
01101       rstat = bfd_reloc_ok;
01102 
01103       /* Each case must do its own relocation, setting rstat appropriately.  */
01104       switch (r_type)
01105        {
01106        default:
01107          (*_bfd_error_handler)
01108            (_("%B: unsupported relocation type 0x%02x"), input_bfd, r_type);
01109          bfd_set_error (bfd_error_bad_value);
01110          return FALSE;
01111        case IMAGE_REL_PPC_TOCREL16:
01112          {
01113            bfd_signed_vma our_toc_offset;
01114            int fixit;
01115 
01116            DUMP_RELOC2(howto->name, rel);
01117 
01118            if (toc_section == 0)
01119              {
01120               toc_section = bfd_get_section_by_name (bfd_of_toc_owner,
01121                                                  TOC_SECTION_NAME);
01122 
01123               if ( toc_section == NULL )
01124                 {
01125                   /* There is no toc section. Something is very wrong.  */
01126                   abort ();
01127                 }
01128              }
01129 
01130            /* Amazing bit tricks present. As we may have seen earlier, we
01131               use the 1 bit to tell us whether or not a toc offset has been
01132               allocated. Now that they've all been allocated, we will use
01133               the 1 bit to tell us if we've written this particular toc
01134               entry out.  */
01135            fixit = FALSE;
01136            if (h == 0)
01137              {
01138               /* It is a file local symbol.  */
01139               int *local_toc_table;
01140               const char *name;
01141 
01142               sym = syms + symndx;
01143               name = sym->_n._n_name;
01144 
01145               local_toc_table = obj_coff_local_toc_table(input_bfd);
01146               our_toc_offset = local_toc_table[symndx];
01147 
01148               if (IS_WRITTEN(our_toc_offset))
01149                 {
01150                   /* If it has been written out, it is marked with the
01151                      1 bit. Fix up our offset, but do not write it out
01152                      again.  */
01153                   MAKE_ADDR_AGAIN(our_toc_offset);
01154                 }
01155               else
01156                 {
01157                   /* Write out the toc entry.  */
01158                   record_toc (toc_section, our_toc_offset, priv,
01159                             strdup (name));
01160 
01161                   bfd_put_32 (output_bfd, val,
01162                             toc_section->contents + our_toc_offset);
01163 
01164                   MARK_AS_WRITTEN(local_toc_table[symndx]);
01165                   fixit = TRUE;
01166                 }
01167              }
01168            else
01169              {
01170               const char *name = h->root.root.root.string;
01171               our_toc_offset = h->toc_offset;
01172 
01173               if ((r_flags & IMAGE_REL_PPC_TOCDEFN)
01174                   == IMAGE_REL_PPC_TOCDEFN )
01175                 {
01176                   /* This is unbelievable cheese. Some knowledgable asm
01177                      hacker has decided to use r2 as a base for loading
01178                      a value. He/She does this by setting the tocdefn bit,
01179                      and not supplying a toc definition. The behaviour is
01180                      then to use the difference between the value of the
01181                      symbol and the actual location of the toc as the toc
01182                      index.
01183 
01184                      In fact, what is usually happening is, because the
01185                      Import Address Table is mapped immediately following
01186                      the toc, some trippy library code trying for speed on
01187                      dll linkage, takes advantage of that and considers
01188                      the IAT to be part of the toc, thus saving a load.  */
01189 
01190                   our_toc_offset = val - (toc_section->output_section->vma
01191                                        + toc_section->output_offset);
01192 
01193                   /* The size must still fit in a 16-bit displacement.  */
01194                   if ((bfd_vma) our_toc_offset >= 65535)
01195                     {
01196                      (*_bfd_error_handler)
01197                        (_("%B: Relocation for %s of %lx exceeds Toc size limit"),
01198                         input_bfd, name,
01199                         (unsigned long) our_toc_offset);
01200                      bfd_set_error (bfd_error_bad_value);
01201                      return FALSE;
01202                     }
01203 
01204                   record_toc (toc_section, our_toc_offset, pub,
01205                             strdup (name));
01206                 }
01207               else if (IS_WRITTEN (our_toc_offset))
01208                 {
01209                   /* If it has been written out, it is marked with the
01210                      1 bit. Fix up our offset, but do not write it out
01211                      again.  */
01212                   MAKE_ADDR_AGAIN(our_toc_offset);
01213                 }
01214               else
01215                 {
01216                   record_toc(toc_section, our_toc_offset, pub,
01217                             strdup (name));
01218 
01219                   /* Write out the toc entry.  */
01220                   bfd_put_32 (output_bfd, val,
01221                             toc_section->contents + our_toc_offset);
01222 
01223                   MARK_AS_WRITTEN(h->toc_offset);
01224                   /* The tricky part is that this is the address that
01225                      needs a .reloc entry for it.  */
01226                   fixit = TRUE;
01227                 }
01228              }
01229 
01230            if (fixit && info->base_file)
01231              {
01232               /* So if this is non pcrelative, and is referenced
01233                  to a section or a common symbol, then it needs a reloc.  */
01234 
01235               /* Relocation to a symbol in a section which
01236                  isn't absolute - we output the address here
01237                  to a file.  */
01238               bfd_vma addr = (toc_section->output_section->vma
01239                             + toc_section->output_offset + our_toc_offset);
01240 
01241               if (coff_data (output_bfd)->pe)
01242                 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
01243 
01244               fwrite (&addr, 1,4, (FILE *) info->base_file);
01245              }
01246 
01247            /* FIXME: this test is conservative.  */
01248            if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN
01249               && (bfd_vma) our_toc_offset > toc_section->size)
01250              {
01251               (*_bfd_error_handler)
01252                 (_("%B: Relocation exceeds allocated TOC (%lx)"),
01253                  input_bfd, (unsigned long) toc_section->size);
01254               bfd_set_error (bfd_error_bad_value);
01255               return FALSE;
01256              }
01257 
01258            /* Now we know the relocation for this toc reference.  */
01259            relocation =  our_toc_offset + TOC_LOAD_ADJUSTMENT;
01260            rstat = _bfd_relocate_contents (howto, input_bfd, relocation, loc);
01261          }
01262          break;
01263        case IMAGE_REL_PPC_IFGLUE:
01264          {
01265            /* To solve this, we need to know whether or not the symbol
01266               appearing on the call instruction is a glue function or not.
01267               A glue function must announce itself via a IMGLUE reloc, and 
01268               the reloc contains the required toc restore instruction.  */
01269            bfd_vma x;
01270            const char *my_name;
01271            
01272            DUMP_RELOC2 (howto->name, rel);
01273 
01274            if (h != 0)
01275              {
01276               my_name = h->root.root.root.string;
01277               if (h->symbol_is_glue == 1)
01278                 {
01279                   x = bfd_get_32 (input_bfd, loc);
01280                   bfd_put_32 (input_bfd, (bfd_vma) h->glue_insn, loc);
01281                 }
01282              }
01283          }
01284          break;
01285        case IMAGE_REL_PPC_SECREL:
01286          /* Unimplemented: codeview debugging information.  */
01287          /* For fast access to the header of the section
01288             containing the item.  */
01289          break;
01290        case IMAGE_REL_PPC_SECTION:
01291          /* Unimplemented: codeview debugging information.  */
01292          /* Is used to indicate that the value should be relative
01293             to the beginning of the section that contains the
01294             symbol.  */
01295          break;
01296        case IMAGE_REL_PPC_ABSOLUTE:
01297          {
01298            const char *my_name;
01299 
01300            if (h == 0)
01301              my_name = (syms+symndx)->_n._n_name;
01302            else
01303              my_name = h->root.root.root.string;
01304 
01305            (*_bfd_error_handler)
01306              (_("Warning: unsupported reloc %s <file %B, section %A>\n"
01307                "sym %ld (%s), r_vaddr %ld (%lx)"),
01308               input_bfd, input_section, howto->name,
01309               rel->r_symndx, my_name, (long) rel->r_vaddr,
01310               (unsigned long) rel->r_vaddr);
01311          }
01312          break;
01313        case IMAGE_REL_PPC_IMGLUE:
01314          {
01315            /* There is nothing to do now. This reloc was noted in the first
01316               pass over the relocs, and the glue instruction extracted.  */
01317            const char *my_name;
01318 
01319            if (h->symbol_is_glue == 1)
01320              break;
01321            my_name = h->root.root.root.string;
01322 
01323            (*_bfd_error_handler)
01324              (_("%B: Out of order IMGLUE reloc for %s"), input_bfd, my_name);
01325            bfd_set_error (bfd_error_bad_value);
01326            return FALSE;
01327          }
01328 
01329        case IMAGE_REL_PPC_ADDR32NB:
01330          {
01331            const char *name = 0;
01332 
01333            DUMP_RELOC2 (howto->name, rel);
01334 
01335            if (CONST_STRNEQ (input_section->name, ".idata$2") && first_thunk_address == 0)
01336              {
01337               /* Set magic values.  */
01338               int idata5offset;
01339               struct coff_link_hash_entry *myh;
01340 
01341               myh = coff_link_hash_lookup (coff_hash_table (info),
01342                                         "__idata5_magic__",
01343                                         FALSE, FALSE, TRUE);
01344               first_thunk_address = myh->root.u.def.value +
01345                 sec->output_section->vma +
01346                   sec->output_offset -
01347                     pe_data(output_bfd)->pe_opthdr.ImageBase;
01348 
01349               idata5offset = myh->root.u.def.value;
01350               myh = coff_link_hash_lookup (coff_hash_table (info),
01351                                         "__idata6_magic__",
01352                                         FALSE, FALSE, TRUE);
01353 
01354               thunk_size = myh->root.u.def.value - idata5offset;
01355               myh = coff_link_hash_lookup (coff_hash_table (info),
01356                                         "__idata4_magic__",
01357                                         FALSE, FALSE, TRUE);
01358               import_table_size = myh->root.u.def.value;
01359              }
01360 
01361            if (h == 0)
01362              {
01363               /* It is a file local symbol.  */
01364               sym = syms + symndx;
01365               name = sym->_n._n_name;
01366              }
01367            else
01368              {
01369               char *target = 0;
01370 
01371               name = h->root.root.root.string;
01372               if (strcmp (".idata$2", name) == 0)
01373                 target = "__idata2_magic__";
01374               else if (strcmp (".idata$4", name) == 0)
01375                 target = "__idata4_magic__";
01376               else if (strcmp (".idata$5", name) == 0)
01377                 target = "__idata5_magic__";
01378 
01379               if (target != 0)
01380                 {
01381                   struct coff_link_hash_entry *myh;
01382 
01383                   myh = coff_link_hash_lookup (coff_hash_table (info),
01384                                            target,
01385                                            FALSE, FALSE, TRUE);
01386                   if (myh == 0)
01387                     {
01388                      /* Missing magic cookies. Something is very wrong.  */
01389                      abort ();
01390                     }
01391 
01392                   val = myh->root.u.def.value +
01393                     sec->output_section->vma + sec->output_offset;
01394                   if (first_thunk_address == 0)
01395                     {
01396                      int idata5offset;
01397                      myh = coff_link_hash_lookup (coff_hash_table (info),
01398                                                "__idata5_magic__",
01399                                                FALSE, FALSE, TRUE);
01400                      first_thunk_address = myh->root.u.def.value +
01401                        sec->output_section->vma +
01402                          sec->output_offset -
01403                            pe_data(output_bfd)->pe_opthdr.ImageBase;
01404 
01405                      idata5offset = myh->root.u.def.value;
01406                      myh = coff_link_hash_lookup (coff_hash_table (info),
01407                                                "__idata6_magic__",
01408                                                FALSE, FALSE, TRUE);
01409 
01410                      thunk_size = myh->root.u.def.value - idata5offset;
01411                      myh = coff_link_hash_lookup (coff_hash_table (info),
01412                                                "__idata4_magic__",
01413                                                FALSE, FALSE, TRUE);
01414                      import_table_size = myh->root.u.def.value;
01415                     }
01416                 }
01417              }
01418 
01419            rstat = _bfd_relocate_contents (howto,
01420                                        input_bfd,
01421                                        val -
01422                                        pe_data (output_bfd)->pe_opthdr.ImageBase,
01423                                        loc);
01424          }
01425          break;
01426 
01427        case IMAGE_REL_PPC_REL24:
01428          DUMP_RELOC2(howto->name, rel);
01429          val -= (input_section->output_section->vma
01430                 + input_section->output_offset);
01431 
01432          rstat = _bfd_relocate_contents (howto,
01433                                      input_bfd,
01434                                      val,
01435                                      loc);
01436          break;
01437        case IMAGE_REL_PPC_ADDR16:
01438        case IMAGE_REL_PPC_ADDR24:
01439        case IMAGE_REL_PPC_ADDR32:
01440          DUMP_RELOC2(howto->name, rel);
01441          rstat = _bfd_relocate_contents (howto,
01442                                      input_bfd,
01443                                      val,
01444                                      loc);
01445          break;
01446        }
01447 
01448       if (info->base_file)
01449        {
01450          /* So if this is non pcrelative, and is referenced
01451             to a section or a common symbol, then it needs a reloc.  */
01452          if (sym && pe_data(output_bfd)->in_reloc_p (output_bfd, howto))
01453            {
01454              /* Relocation to a symbol in a section which
01455                isn't absolute - we output the address here
01456                to a file.  */
01457              bfd_vma addr = rel->r_vaddr
01458               - input_section->vma
01459               + input_section->output_offset
01460                 + input_section->output_section->vma;
01461 
01462              if (coff_data (output_bfd)->pe)
01463               addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
01464 
01465              fwrite (&addr, 1,4, (FILE *) info->base_file);
01466            }
01467        }
01468 
01469       switch (rstat)
01470        {
01471        default:
01472          abort ();
01473        case bfd_reloc_ok:
01474          break;
01475        case bfd_reloc_overflow:
01476          {
01477            const char *name;
01478            char buf[SYMNMLEN + 1];
01479 
01480            if (symndx == -1)
01481              name = "*ABS*";
01482            else if (h != NULL)
01483              name = NULL;
01484            else if (sym == NULL)
01485              name = "*unknown*";
01486            else if (sym->_n._n_n._n_zeroes == 0
01487                    && sym->_n._n_n._n_offset != 0)
01488              name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
01489            else
01490              {
01491               strncpy (buf, sym->_n._n_name, SYMNMLEN);
01492               buf[SYMNMLEN] = '\0';
01493               name = buf;
01494              }
01495 
01496            if (! ((*info->callbacks->reloc_overflow)
01497                  (info, (h ? &h->root.root : NULL), name, howto->name,
01498                   (bfd_vma) 0, input_bfd,
01499                   input_section, rel->r_vaddr - input_section->vma)))
01500              return FALSE;
01501          }
01502        }
01503     }
01504 
01505   return TRUE;
01506 }
01507 
01508 #ifdef COFF_IMAGE_WITH_PE
01509 
01510 /* FIXME: BFD should not use global variables.  This file is compiled
01511    twice, and these variables are shared.  This is confusing and
01512    weird.  */
01513 
01514 long int global_toc_size = 4;
01515 
01516 bfd* bfd_of_toc_owner = 0;
01517 
01518 long int import_table_size;
01519 long int first_thunk_address;
01520 long int thunk_size;
01521 
01522 struct list_ele *head;
01523 struct list_ele *tail;
01524 
01525 static char *
01526 h1 = N_("\n\t\t\tTOC MAPPING\n\n");
01527 static char *
01528 h2 = N_(" TOC    disassembly  Comments       Name\n");
01529 static char *
01530 h3 = N_(" Offset  spelling                   (if present)\n");
01531 
01532 void
01533 dump_toc (vfile)
01534      PTR vfile;
01535 {
01536   FILE *file = (FILE *) vfile;
01537   struct list_ele *t;
01538 
01539   fprintf (file, _(h1));
01540   fprintf (file, _(h2));
01541   fprintf (file, _(h3));
01542 
01543   for (t = head; t != 0; t=t->next)
01544     {
01545       const char *cat = "";
01546 
01547       if (t->cat == priv)
01548        cat = _("private       ");
01549       else if (t->cat == pub)
01550        cat = _("public        ");
01551       else if (t->cat == tocdata)
01552        cat = _("data-in-toc   ");
01553 
01554       if (t->offset > global_toc_size)
01555        {
01556          if (t->offset <= global_toc_size + thunk_size)
01557            cat = _("IAT reference ");
01558          else
01559            {
01560              fprintf (file,
01561                     _("**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n"),
01562                      global_toc_size, global_toc_size,
01563                      thunk_size, thunk_size);
01564              cat = _("Out of bounds!");
01565            }
01566        }
01567 
01568       fprintf (file,
01569              " %04lx    (%d)", (unsigned long) t->offset, t->offset - 32768);
01570       fprintf (file,
01571              "    %s %s\n",
01572              cat, t->name);
01573 
01574     }
01575 
01576   fprintf (file, "\n");
01577 }
01578 
01579 bfd_boolean
01580 ppc_allocate_toc_section (info)
01581      struct bfd_link_info *info ATTRIBUTE_UNUSED;
01582 {
01583   asection *s;
01584   bfd_byte *foo;
01585   bfd_size_type amt;
01586   static char test_char = '1';
01587 
01588   if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble?  */
01589     return TRUE;
01590 
01591   if (bfd_of_toc_owner == 0)
01592     /* No toc owner? Something is very wrong.  */
01593     abort ();
01594 
01595   s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
01596   if (s == NULL)
01597     /* No toc section? Something is very wrong.  */
01598     abort ();
01599 
01600   amt = global_toc_size;
01601   foo = (bfd_byte *) bfd_alloc (bfd_of_toc_owner, amt);
01602   memset(foo, test_char, (size_t) global_toc_size);
01603 
01604   s->size = global_toc_size;
01605   s->contents = foo;
01606 
01607   return TRUE;
01608 }
01609 
01610 bfd_boolean
01611 ppc_process_before_allocation (abfd, info)
01612      bfd *abfd;
01613      struct bfd_link_info *info;
01614 {
01615   asection *sec;
01616   struct internal_reloc *i, *rel;
01617 
01618   /* Here we have a bfd that is to be included on the link. We have a hook
01619      to do reloc rummaging, before section sizes are nailed down.  */
01620   _bfd_coff_get_external_symbols (abfd);
01621 
01622   /* Rummage around all the relocs and map the toc.  */
01623   sec = abfd->sections;
01624 
01625   if (sec == 0)
01626     return TRUE;
01627 
01628   for (; sec != 0; sec = sec->next)
01629     {
01630       if (sec->reloc_count == 0)
01631        continue;
01632 
01633       /* load the relocs */
01634       /* FIXME: there may be a storage leak here */
01635       i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
01636 
01637       if (i == 0)
01638        abort ();
01639 
01640       for (rel = i; rel < i + sec->reloc_count; ++rel)
01641        {
01642          unsigned short r_type  = EXTRACT_TYPE  (rel->r_type);
01643          unsigned short r_flags = EXTRACT_FLAGS (rel->r_type);
01644          bfd_boolean ok = TRUE;
01645 
01646          DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, rel);
01647 
01648          switch(r_type)
01649            {
01650            case IMAGE_REL_PPC_TOCREL16:
01651              /* If TOCDEFN is on, ignore as someone else has allocated the
01652                toc entry.  */
01653              if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN)
01654               ok = ppc_record_toc_entry(abfd, info, sec,
01655                                      rel->r_symndx, default_toc);
01656              if (!ok)
01657               return FALSE;
01658              break;
01659            case IMAGE_REL_PPC_IMGLUE:
01660              ppc_mark_symbol_as_glue (abfd, rel->r_symndx, rel);
01661              break;
01662            default:
01663              break;
01664            }
01665        }
01666     }
01667 
01668   return TRUE;
01669 }
01670 
01671 #endif
01672 
01673 static bfd_reloc_status_type
01674 ppc_refhi_reloc (abfd, reloc_entry, symbol, data,
01675                input_section, output_bfd, error_message)
01676      bfd *abfd ATTRIBUTE_UNUSED;
01677      arelent *reloc_entry ATTRIBUTE_UNUSED;
01678      asymbol *symbol ATTRIBUTE_UNUSED;
01679      PTR data ATTRIBUTE_UNUSED;
01680      asection *input_section ATTRIBUTE_UNUSED;
01681      bfd *output_bfd;
01682      char **error_message ATTRIBUTE_UNUSED;
01683 {
01684   UN_IMPL("REFHI");
01685   DUMP_RELOC("REFHI",reloc_entry);
01686 
01687   if (output_bfd == (bfd *) NULL)
01688     return bfd_reloc_continue;
01689 
01690   return bfd_reloc_undefined;
01691 }
01692 
01693 static bfd_reloc_status_type
01694 ppc_pair_reloc (abfd, reloc_entry, symbol, data,
01695               input_section, output_bfd, error_message)
01696      bfd *abfd ATTRIBUTE_UNUSED;
01697      arelent *reloc_entry ATTRIBUTE_UNUSED;
01698      asymbol *symbol ATTRIBUTE_UNUSED;
01699      PTR data ATTRIBUTE_UNUSED;
01700      asection *input_section ATTRIBUTE_UNUSED;
01701      bfd *output_bfd;
01702      char **error_message ATTRIBUTE_UNUSED;
01703 {
01704   UN_IMPL("PAIR");
01705   DUMP_RELOC("PAIR",reloc_entry);
01706 
01707   if (output_bfd == (bfd *) NULL)
01708     return bfd_reloc_continue;
01709 
01710   return bfd_reloc_undefined;
01711 }
01712 
01713 static bfd_reloc_status_type
01714 ppc_toc16_reloc (abfd, reloc_entry, symbol, data,
01715                input_section, output_bfd, error_message)
01716      bfd *abfd ATTRIBUTE_UNUSED;
01717      arelent *reloc_entry ATTRIBUTE_UNUSED;
01718      asymbol *symbol ATTRIBUTE_UNUSED;
01719      PTR data ATTRIBUTE_UNUSED;
01720      asection *input_section ATTRIBUTE_UNUSED;
01721      bfd *output_bfd;
01722      char **error_message ATTRIBUTE_UNUSED;
01723 {
01724   UN_IMPL ("TOCREL16");
01725   DUMP_RELOC ("TOCREL16",reloc_entry);
01726 
01727   if (output_bfd == (bfd *) NULL)
01728     return bfd_reloc_continue;
01729 
01730   return bfd_reloc_ok;
01731 }
01732 
01733 static bfd_reloc_status_type
01734 ppc_secrel_reloc (abfd, reloc_entry, symbol, data,
01735                 input_section, output_bfd, error_message)
01736      bfd *abfd ATTRIBUTE_UNUSED;
01737      arelent *reloc_entry ATTRIBUTE_UNUSED;
01738      asymbol *symbol ATTRIBUTE_UNUSED;
01739      PTR data ATTRIBUTE_UNUSED;
01740      asection *input_section ATTRIBUTE_UNUSED;
01741      bfd *output_bfd;
01742      char **error_message ATTRIBUTE_UNUSED;
01743 {
01744   UN_IMPL("SECREL");
01745   DUMP_RELOC("SECREL",reloc_entry);
01746 
01747   if (output_bfd == (bfd *) NULL)
01748     return bfd_reloc_continue;
01749 
01750   return bfd_reloc_ok;
01751 }
01752 
01753 static bfd_reloc_status_type
01754 ppc_section_reloc (abfd, reloc_entry, symbol, data,
01755                  input_section, output_bfd, error_message)
01756      bfd *abfd ATTRIBUTE_UNUSED;
01757      arelent *reloc_entry ATTRIBUTE_UNUSED;
01758      asymbol *symbol ATTRIBUTE_UNUSED;
01759      PTR data ATTRIBUTE_UNUSED;
01760      asection *input_section ATTRIBUTE_UNUSED;
01761      bfd *output_bfd;
01762      char **error_message ATTRIBUTE_UNUSED;
01763 {
01764   UN_IMPL("SECTION");
01765   DUMP_RELOC("SECTION",reloc_entry);
01766 
01767   if (output_bfd == (bfd *) NULL)
01768     return bfd_reloc_continue;
01769 
01770   return bfd_reloc_ok;
01771 }
01772 
01773 static bfd_reloc_status_type
01774 ppc_imglue_reloc (abfd, reloc_entry, symbol, data,
01775                 input_section, output_bfd, error_message)
01776      bfd *abfd ATTRIBUTE_UNUSED;
01777      arelent *reloc_entry ATTRIBUTE_UNUSED;
01778      asymbol *symbol ATTRIBUTE_UNUSED;
01779      PTR data ATTRIBUTE_UNUSED;
01780      asection *input_section ATTRIBUTE_UNUSED;
01781      bfd *output_bfd;
01782      char **error_message ATTRIBUTE_UNUSED;
01783 {
01784   UN_IMPL("IMGLUE");
01785   DUMP_RELOC("IMGLUE",reloc_entry);
01786 
01787   if (output_bfd == (bfd *) NULL)
01788     return bfd_reloc_continue;
01789 
01790   return bfd_reloc_ok;
01791 }
01792 
01793 #define MAX_RELOC_INDEX  \
01794       (sizeof (ppc_coff_howto_table) / sizeof (ppc_coff_howto_table[0]) - 1)
01795 
01796 /* FIXME: There is a possibility that when we read in a reloc from a file,
01797           that there are some bits encoded in the upper portion of the
01798          type field. Not yet implemented.  */
01799 static void ppc_coff_rtype2howto PARAMS ((arelent *, struct internal_reloc *));
01800 
01801 static void
01802 ppc_coff_rtype2howto (relent, internal)
01803      arelent *relent;
01804      struct internal_reloc *internal;
01805 {
01806   /* We can encode one of three things in the type field, aside from the
01807      type:
01808      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
01809         value, rather than an addition value
01810      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
01811         the branch is expected to be taken or not.
01812      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
01813      For now, we just strip this stuff to find the type, and ignore it other
01814      than that.  */
01815   reloc_howto_type *howto;
01816   unsigned short r_type  = EXTRACT_TYPE (internal->r_type);
01817   unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
01818   unsigned short junk    = EXTRACT_JUNK (internal->r_type);
01819 
01820   /* The masking process only slices off the bottom byte for r_type.  */
01821   if ( r_type > MAX_RELOC_INDEX )
01822     abort ();
01823 
01824   /* Check for absolute crap.  */
01825   if (junk != 0)
01826     abort ();
01827 
01828   switch(r_type)
01829     {
01830     case IMAGE_REL_PPC_ADDR16:
01831     case IMAGE_REL_PPC_REL24:
01832     case IMAGE_REL_PPC_ADDR24:
01833     case IMAGE_REL_PPC_ADDR32:
01834     case IMAGE_REL_PPC_IFGLUE:
01835     case IMAGE_REL_PPC_ADDR32NB:
01836     case IMAGE_REL_PPC_SECTION:
01837     case IMAGE_REL_PPC_SECREL:
01838       DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
01839       howto = ppc_coff_howto_table + r_type;
01840       break;
01841     case IMAGE_REL_PPC_IMGLUE:
01842       DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
01843       howto = ppc_coff_howto_table + r_type;
01844       break;
01845     case IMAGE_REL_PPC_TOCREL16:
01846       DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
01847       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
01848        howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
01849       else
01850        howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
01851       break;
01852     default:
01853       fprintf (stderr,
01854              _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"),
01855              ppc_coff_howto_table[r_type].name,
01856              r_type);
01857       howto = ppc_coff_howto_table + r_type;
01858       break;
01859     }
01860 
01861   relent->howto = howto;
01862 }
01863 
01864 static reloc_howto_type *
01865 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
01866      bfd *abfd ATTRIBUTE_UNUSED;
01867      asection *sec;
01868      struct internal_reloc *rel;
01869      struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
01870      struct internal_syment *sym ATTRIBUTE_UNUSED;
01871      bfd_vma *addendp;
01872 {
01873   reloc_howto_type *howto;
01874 
01875   /* We can encode one of three things in the type field, aside from the
01876      type:
01877      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
01878         value, rather than an addition value
01879      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
01880         the branch is expected to be taken or not.
01881      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
01882      For now, we just strip this stuff to find the type, and ignore it other
01883      than that.  */
01884 
01885   unsigned short r_type  = EXTRACT_TYPE  (rel->r_type);
01886   unsigned short r_flags = EXTRACT_FLAGS (rel->r_type);
01887   unsigned short junk    = EXTRACT_JUNK  (rel->r_type);
01888 
01889   /* The masking process only slices off the bottom byte for r_type.  */
01890   if (r_type > MAX_RELOC_INDEX)
01891     abort ();
01892 
01893   /* Check for absolute crap.  */
01894   if (junk != 0)
01895     abort ();
01896 
01897   switch(r_type)
01898     {
01899     case IMAGE_REL_PPC_ADDR32NB:
01900       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
01901       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
01902       howto = ppc_coff_howto_table + r_type;
01903       break;
01904     case IMAGE_REL_PPC_TOCREL16:
01905       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
01906       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
01907        howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
01908       else
01909        howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
01910       break;
01911     case IMAGE_REL_PPC_ADDR16:
01912     case IMAGE_REL_PPC_REL24:
01913     case IMAGE_REL_PPC_ADDR24:
01914     case IMAGE_REL_PPC_ADDR32:
01915     case IMAGE_REL_PPC_IFGLUE:
01916     case IMAGE_REL_PPC_SECTION:
01917     case IMAGE_REL_PPC_SECREL:
01918       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
01919       howto = ppc_coff_howto_table + r_type;
01920       break;
01921     case IMAGE_REL_PPC_IMGLUE:
01922       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
01923       howto = ppc_coff_howto_table + r_type;
01924       break;
01925     default:
01926       fprintf (stderr,
01927              _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"),
01928              ppc_coff_howto_table[r_type].name,
01929              r_type);
01930       howto = ppc_coff_howto_table + r_type;
01931       break;
01932     }
01933 
01934   return howto;
01935 }
01936 
01937 /* A cheesy little macro to make the code a little more readable.  */
01938 #define HOW2MAP(bfd_rtype,ppc_rtype)  \
01939  case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
01940 
01941 static reloc_howto_type *ppc_coff_reloc_type_lookup
01942 PARAMS ((bfd *, bfd_reloc_code_real_type));
01943 
01944 static reloc_howto_type *
01945 ppc_coff_reloc_type_lookup (abfd, code)
01946      bfd *abfd ATTRIBUTE_UNUSED;
01947      bfd_reloc_code_real_type code;
01948 {
01949   switch (code)
01950     {
01951       HOW2MAP(BFD_RELOC_32_GOTOFF,    IMAGE_REL_PPC_IMGLUE);
01952       HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
01953       HOW2MAP(BFD_RELOC_16,           IMAGE_REL_PPC_ADDR16);
01954       HOW2MAP(BFD_RELOC_PPC_B26,      IMAGE_REL_PPC_REL24);
01955       HOW2MAP(BFD_RELOC_PPC_BA26,     IMAGE_REL_PPC_ADDR24);
01956       HOW2MAP(BFD_RELOC_PPC_TOC16,    IMAGE_REL_PPC_TOCREL16);
01957       HOW2MAP(BFD_RELOC_16_GOTOFF,    IMAGE_REL_PPC_TOCREL16_DEFN);
01958       HOW2MAP(BFD_RELOC_32,           IMAGE_REL_PPC_ADDR32);
01959       HOW2MAP(BFD_RELOC_RVA,          IMAGE_REL_PPC_ADDR32NB);
01960     default:
01961       return NULL;
01962     }
01963 }
01964 #undef HOW2MAP
01965 
01966 static reloc_howto_type *
01967 ppc_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01968                          const char *r_name)
01969 {
01970   unsigned int i;
01971 
01972   for (i = 0;
01973        i < sizeof (ppc_coff_howto_table) / sizeof (ppc_coff_howto_table[0]);
01974        i++)
01975     if (ppc_coff_howto_table[i].name != NULL
01976        && strcasecmp (ppc_coff_howto_table[i].name, r_name) == 0)
01977       return &ppc_coff_howto_table[i];
01978 
01979   return NULL;
01980 }
01981 
01982 /* Tailor coffcode.h -- macro heaven.  */
01983 
01984 #define RTYPE2HOWTO(cache_ptr, dst)  ppc_coff_rtype2howto (cache_ptr, dst)
01985 
01986 /* We use the special COFF backend linker, with our own special touch.  */
01987 
01988 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
01989 #define coff_bfd_reloc_name_lookup ppc_coff_reloc_name_lookup
01990 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
01991 #define coff_relocate_section        coff_ppc_relocate_section
01992 #define coff_bfd_final_link          ppc_bfd_coff_final_link
01993 
01994 #ifndef COFF_IMAGE_WITH_PE
01995 #endif
01996 
01997 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
01998 
01999 #define COFF_PAGE_SIZE                       0x1000
02000 
02001 /* FIXME: This controls some code that used to be in peicode.h and is
02002    now in peigen.c.  It will not control the code in peigen.c.  If
02003    anybody wants to get this working, you will need to fix that.  */
02004 #define POWERPC_LE_PE
02005 
02006 #define COFF_SECTION_ALIGNMENT_ENTRIES \
02007 { COFF_SECTION_NAME_EXACT_MATCH (".idata$2"), \
02008   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
02009 { COFF_SECTION_NAME_EXACT_MATCH (".idata$3"), \
02010   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
02011 { COFF_SECTION_NAME_EXACT_MATCH (".idata$4"), \
02012   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
02013 { COFF_SECTION_NAME_EXACT_MATCH (".idata$5"), \
02014   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
02015 { COFF_SECTION_NAME_EXACT_MATCH (".idata$6"), \
02016   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 }, \
02017 { COFF_SECTION_NAME_EXACT_MATCH (".reloc"), \
02018   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 }
02019 
02020 #include "coffcode.h"
02021 
02022 #ifndef COFF_IMAGE_WITH_PE
02023 
02024 static bfd_boolean ppc_do_last PARAMS ((bfd *));
02025 static bfd *ppc_get_last PARAMS ((void));
02026 
02027 static bfd_boolean
02028 ppc_do_last (abfd)
02029      bfd *abfd;
02030 {
02031   if (abfd == bfd_of_toc_owner)
02032     return TRUE;
02033   else
02034     return FALSE;
02035 }
02036 
02037 static bfd *
02038 ppc_get_last()
02039 {
02040   return bfd_of_toc_owner;
02041 }
02042 
02043 /* This piece of machinery exists only to guarantee that the bfd that holds
02044    the toc section is written last.
02045 
02046    This does depend on bfd_make_section attaching a new section to the
02047    end of the section list for the bfd.
02048 
02049    This is otherwise intended to be functionally the same as
02050    cofflink.c:_bfd_coff_final_link(). It is specifically different only
02051    where the POWERPC_LE_PE macro modifies the code. It is left in as a
02052    precise form of comment. krk@cygnus.com  */
02053 
02054 /* Do the final link step.  */
02055 
02056 bfd_boolean
02057 ppc_bfd_coff_final_link (abfd, info)
02058      bfd *abfd;
02059      struct bfd_link_info *info;
02060 {
02061   bfd_size_type symesz;
02062   struct coff_final_link_info finfo;
02063   bfd_boolean debug_merge_allocated;
02064   asection *o;
02065   struct bfd_link_order *p;
02066   bfd_size_type max_sym_count;
02067   bfd_size_type max_lineno_count;
02068   bfd_size_type max_reloc_count;
02069   bfd_size_type max_output_reloc_count;
02070   bfd_size_type max_contents_size;
02071   file_ptr rel_filepos;
02072   unsigned int relsz;
02073   file_ptr line_filepos;
02074   unsigned int linesz;
02075   bfd *sub;
02076   bfd_byte *external_relocs = NULL;
02077   char strbuf[STRING_SIZE_SIZE];
02078   bfd_size_type amt;
02079 
02080   symesz = bfd_coff_symesz (abfd);
02081 
02082   finfo.info = info;
02083   finfo.output_bfd = abfd;
02084   finfo.strtab = NULL;
02085   finfo.section_info = NULL;
02086   finfo.last_file_index = -1;
02087   finfo.last_bf_index = -1;
02088   finfo.internal_syms = NULL;
02089   finfo.sec_ptrs = NULL;
02090   finfo.sym_indices = NULL;
02091   finfo.outsyms = NULL;
02092   finfo.linenos = NULL;
02093   finfo.contents = NULL;
02094   finfo.external_relocs = NULL;
02095   finfo.internal_relocs = NULL;
02096   debug_merge_allocated = FALSE;
02097 
02098   coff_data (abfd)->link_info = info;
02099 
02100   finfo.strtab = _bfd_stringtab_init ();
02101   if (finfo.strtab == NULL)
02102     goto error_return;
02103 
02104   if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
02105     goto error_return;
02106   debug_merge_allocated = TRUE;
02107 
02108   /* Compute the file positions for all the sections.  */
02109   if (! abfd->output_has_begun)
02110     {
02111       if (! bfd_coff_compute_section_file_positions (abfd))
02112        return FALSE;
02113     }
02114 
02115   /* Count the line numbers and relocation entries required for the
02116      output file.  Set the file positions for the relocs.  */
02117   rel_filepos = obj_relocbase (abfd);
02118   relsz = bfd_coff_relsz (abfd);
02119   max_contents_size = 0;
02120   max_lineno_count = 0;
02121   max_reloc_count = 0;
02122 
02123   for (o = abfd->sections; o != NULL; o = o->next)
02124     {
02125       o->reloc_count = 0;
02126       o->lineno_count = 0;
02127 
02128       for (p = o->map_head.link_order; p != NULL; p = p->next)
02129        {
02130          if (p->type == bfd_indirect_link_order)
02131            {
02132              asection *sec;
02133 
02134              sec = p->u.indirect.section;
02135 
02136              /* Mark all sections which are to be included in the
02137                link.  This will normally be every section.  We need
02138                to do this so that we can identify any sections which
02139                the linker has decided to not include.  */
02140              sec->linker_mark = TRUE;
02141 
02142              if (info->strip == strip_none
02143                 || info->strip == strip_some)
02144               o->lineno_count += sec->lineno_count;
02145 
02146              if (info->relocatable)
02147               o->reloc_count += sec->reloc_count;
02148 
02149              if (sec->rawsize > max_contents_size)
02150               max_contents_size = sec->rawsize;
02151              if (sec->size > max_contents_size)
02152               max_contents_size = sec->size;
02153              if (sec->lineno_count > max_lineno_count)
02154               max_lineno_count = sec->lineno_count;
02155              if (sec->reloc_count > max_reloc_count)
02156               max_reloc_count = sec->reloc_count;
02157            }
02158          else if (info->relocatable
02159                  && (p->type == bfd_section_reloc_link_order
02160                      || p->type == bfd_symbol_reloc_link_order))
02161            ++o->reloc_count;
02162        }
02163       if (o->reloc_count == 0)
02164        o->rel_filepos = 0;
02165       else
02166        {
02167          o->flags |= SEC_RELOC;
02168          o->rel_filepos = rel_filepos;
02169          rel_filepos += o->reloc_count * relsz;
02170        }
02171     }
02172 
02173   /* If doing a relocatable link, allocate space for the pointers we
02174      need to keep.  */
02175   if (info->relocatable)
02176     {
02177       unsigned int i;
02178 
02179       /* We use section_count + 1, rather than section_count, because
02180          the target_index fields are 1 based.  */
02181       amt = abfd->section_count + 1;
02182       amt *= sizeof (struct coff_link_section_info);
02183       finfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt);
02184 
02185       if (finfo.section_info == NULL)
02186        goto error_return;
02187 
02188       for (i = 0; i <= abfd->section_count; i++)
02189        {
02190          finfo.section_info[i].relocs = NULL;
02191          finfo.section_info[i].rel_hashes = NULL;
02192        }
02193     }
02194 
02195   /* We now know the size of the relocs, so we can determine the file
02196      positions of the line numbers.  */
02197   line_filepos = rel_filepos;
02198   linesz = bfd_coff_linesz (abfd);
02199   max_output_reloc_count = 0;
02200 
02201   for (o = abfd->sections; o != NULL; o = o->next)
02202     {
02203       if (o->lineno_count == 0)
02204        o->line_filepos = 0;
02205       else
02206        {
02207          o->line_filepos = line_filepos;
02208          line_filepos += o->lineno_count * linesz;
02209        }
02210 
02211       if (o->reloc_count != 0)
02212        {
02213          /* We don't know the indices of global symbols until we have
02214              written out all the local symbols.  For each section in
02215              the output file, we keep an array of pointers to hash
02216              table entries.  Each entry in the array corresponds to a
02217              reloc.  When we find a reloc against a global symbol, we
02218              set the corresponding entry in this array so that we can
02219              fix up the symbol index after we have written out all the
02220              local symbols.
02221 
02222             Because of this problem, we also keep the relocs in
02223             memory until the end of the link.  This wastes memory,
02224             but only when doing a relocatable link, which is not the
02225             common case.  */
02226          BFD_ASSERT (info->relocatable);
02227          amt = o->reloc_count;
02228          amt *= sizeof (struct internal_reloc);
02229          finfo.section_info[o->target_index].relocs =
02230            (struct internal_reloc *) bfd_malloc (amt);
02231          amt = o->reloc_count;
02232          amt *= sizeof (struct coff_link_hash_entry *);
02233          finfo.section_info[o->target_index].rel_hashes =
02234            (struct coff_link_hash_entry **) bfd_malloc (amt);
02235          if (finfo.section_info[o->target_index].relocs == NULL
02236              || finfo.section_info[o->target_index].rel_hashes == NULL)
02237            goto error_return;
02238 
02239          if (o->reloc_count > max_output_reloc_count)
02240            max_output_reloc_count = o->reloc_count;
02241        }
02242 
02243       /* Reset the reloc and lineno counts, so that we can use them to
02244         count the number of entries we have output so far.  */
02245       o->reloc_count = 0;
02246       o->lineno_count = 0;
02247     }
02248 
02249   obj_sym_filepos (abfd) = line_filepos;
02250 
02251   /* Figure out the largest number of symbols in an input BFD.  Take
02252      the opportunity to clear the output_has_begun fields of all the
02253      input BFD's.  */
02254   max_sym_count = 0;
02255   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
02256     {
02257       bfd_size_type sz;
02258 
02259       sub->output_has_begun = FALSE;
02260       sz = obj_raw_syment_count (sub);
02261       if (sz > max_sym_count)
02262        max_sym_count = sz;
02263     }
02264 
02265   /* Allocate some buffers used while linking.  */
02266   amt = max_sym_count * sizeof (struct internal_syment);
02267   finfo.internal_syms = (struct internal_syment *) bfd_malloc (amt);
02268   amt = max_sym_count * sizeof (asection *);
02269   finfo.sec_ptrs = (asection **) bfd_malloc (amt);
02270   amt = max_sym_count * sizeof (long);
02271   finfo.sym_indices = (long *) bfd_malloc (amt);
02272   amt = (max_sym_count + 1) * symesz;
02273   finfo.outsyms = (bfd_byte *) bfd_malloc (amt);
02274   amt = max_lineno_count * bfd_coff_linesz (abfd);
02275   finfo.linenos = (bfd_byte *) bfd_malloc (amt);
02276   finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
02277   finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
02278   if (! info->relocatable)
02279     {
02280       amt = max_reloc_count * sizeof (struct internal_reloc);
02281       finfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
02282     }
02283   if ((finfo.internal_syms == NULL && max_sym_count > 0)
02284       || (finfo.sec_ptrs == NULL && max_sym_count > 0)
02285       || (finfo.sym_indices == NULL && max_sym_count > 0)
02286       || finfo.outsyms == NULL
02287       || (finfo.linenos == NULL && max_lineno_count > 0)
02288       || (finfo.contents == NULL && max_contents_size > 0)
02289       || (finfo.external_relocs == NULL && max_reloc_count > 0)
02290       || (! info->relocatable
02291          && finfo.internal_relocs == NULL
02292          && max_reloc_count > 0))
02293     goto error_return;
02294 
02295   /* We now know the position of everything in the file, except that
02296      we don't know the size of the symbol table and therefore we don't
02297      know where the string table starts.  We just build the string
02298      table in memory as we go along.  We process all the relocations
02299      for a single input file at once.  */
02300   obj_raw_syment_count (abfd) = 0;
02301 
02302   if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
02303     {
02304       if (! bfd_coff_start_final_link (abfd, info))
02305        goto error_return;
02306     }
02307 
02308   for (o = abfd->sections; o != NULL; o = o->next)
02309     {
02310       for (p = o->map_head.link_order; p != NULL; p = p->next)
02311        {
02312          if (p->type == bfd_indirect_link_order
02313              && (bfd_get_flavour (p->u.indirect.section->owner)
02314                 == bfd_target_coff_flavour))
02315            {
02316              sub = p->u.indirect.section->owner;
02317 #ifdef POWERPC_LE_PE
02318              if (! sub->output_has_begun && !ppc_do_last(sub))
02319 #else
02320              if (! sub->output_has_begun)
02321 #endif
02322               {
02323                 if (! _bfd_coff_link_input_bfd (&finfo, sub))
02324                   goto error_return;
02325                 sub->output_has_begun = TRUE;
02326               }
02327            }
02328          else if (p->type == bfd_section_reloc_link_order
02329                  || p->type == bfd_symbol_reloc_link_order)
02330            {
02331              if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
02332               goto error_return;
02333            }
02334          else
02335            {
02336              if (! _bfd_default_link_order (abfd, info, o, p))
02337               goto error_return;
02338            }
02339        }
02340     }
02341 
02342 #ifdef POWERPC_LE_PE
02343   {
02344     bfd* last_one = ppc_get_last();
02345     if (last_one)
02346       {
02347        if (! _bfd_coff_link_input_bfd (&finfo, last_one))
02348          goto error_return;
02349       }
02350     last_one->output_has_begun = TRUE;
02351   }
02352 #endif
02353 
02354   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
02355   coff_debug_merge_hash_table_free (&finfo.debug_merge);
02356   debug_merge_allocated = FALSE;
02357 
02358   if (finfo.internal_syms != NULL)
02359     {
02360       free (finfo.internal_syms);
02361       finfo.internal_syms = NULL;
02362     }
02363   if (finfo.sec_ptrs != NULL)
02364     {
02365       free (finfo.sec_ptrs);
02366       finfo.sec_ptrs = NULL;
02367     }
02368   if (finfo.sym_indices != NULL)
02369     {
02370       free (finfo.sym_indices);
02371       finfo.sym_indices = NULL;
02372     }
02373   if (finfo.linenos != NULL)
02374     {
02375       free (finfo.linenos);
02376       finfo.linenos = NULL;
02377     }
02378   if (finfo.contents != NULL)
02379     {
02380       free (finfo.contents);
02381       finfo.contents = NULL;
02382     }
02383   if (finfo.external_relocs != NULL)
02384     {
02385       free (finfo.external_relocs);
02386       finfo.external_relocs = NULL;
02387     }
02388   if (finfo.internal_relocs != NULL)
02389     {
02390       free (finfo.internal_relocs);
02391       finfo.internal_relocs = NULL;
02392     }
02393 
02394   /* The value of the last C_FILE symbol is supposed to be the symbol
02395      index of the first external symbol.  Write it out again if
02396      necessary.  */
02397   if (finfo.last_file_index != -1
02398       && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
02399     {
02400       file_ptr pos;
02401 
02402       finfo.last_file.n_value = obj_raw_syment_count (abfd);
02403       bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
02404                           (PTR) finfo.outsyms);
02405       pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
02406       if (bfd_seek (abfd, pos, SEEK_SET) != 0
02407          || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz)
02408        return FALSE;
02409     }
02410 
02411   /* Write out the global symbols.  */
02412   finfo.failed = FALSE;
02413   coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
02414                         (PTR) &finfo);
02415   if (finfo.failed)
02416     goto error_return;
02417 
02418   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
02419   if (finfo.outsyms != NULL)
02420     {
02421       free (finfo.outsyms);
02422       finfo.outsyms = NULL;
02423     }
02424 
02425   if (info->relocatable)
02426     {
02427       /* Now that we have written out all the global symbols, we know
02428         the symbol indices to use for relocs against them, and we can
02429         finally write out the relocs.  */
02430       amt = max_output_reloc_count * relsz;
02431       external_relocs = (bfd_byte *) bfd_malloc (amt);
02432       if (external_relocs == NULL)
02433        goto error_return;
02434 
02435       for (o = abfd->sections; o != NULL; o = o->next)
02436        {
02437          struct internal_reloc *irel;
02438          struct internal_reloc *irelend;
02439          struct coff_link_hash_entry **rel_hash;
02440          bfd_byte *erel;
02441 
02442          if (o->reloc_count == 0)
02443            continue;
02444 
02445          irel = finfo.section_info[o->target_index].relocs;
02446          irelend = irel + o->reloc_count;
02447          rel_hash = finfo.section_info[o->target_index].rel_hashes;
02448          erel = external_relocs;
02449          for (; irel < irelend; irel++, rel_hash++, erel += relsz)
02450            {
02451              if (*rel_hash != NULL)
02452               {
02453                 BFD_ASSERT ((*rel_hash)->indx >= 0);
02454                 irel->r_symndx = (*rel_hash)->indx;
02455               }
02456              bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
02457            }
02458 
02459          amt = relsz * o->reloc_count;
02460          if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
02461              || bfd_bwrite ((PTR) external_relocs, amt, abfd) != amt)
02462            goto error_return;
02463        }
02464 
02465       free (external_relocs);
02466       external_relocs = NULL;
02467     }
02468 
02469   /* Free up the section information.  */
02470   if (finfo.section_info != NULL)
02471     {
02472       unsigned int i;
02473 
02474       for (i = 0; i < abfd->section_count; i++)
02475        {
02476          if (finfo.section_info[i].relocs != NULL)
02477            free (finfo.section_info[i].relocs);
02478          if (finfo.section_info[i].rel_hashes != NULL)
02479            free (finfo.section_info[i].rel_hashes);
02480        }
02481       free (finfo.section_info);
02482       finfo.section_info = NULL;
02483     }
02484 
02485   /* If we have optimized stabs strings, output them.  */
02486   if (coff_hash_table (info)->stab_info.stabstr != NULL)
02487     {
02488       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
02489        return FALSE;
02490     }
02491 
02492   /* Write out the string table.  */
02493   if (obj_raw_syment_count (abfd) != 0)
02494     {
02495       file_ptr pos;
02496 
02497       pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
02498       if (bfd_seek (abfd, pos, SEEK_SET) != 0)
02499        return FALSE;
02500 
02501 #if STRING_SIZE_SIZE == 4
02502       H_PUT_32 (abfd,
02503               _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
02504               strbuf);
02505 #else
02506  #error Change H_PUT_32 above
02507 #endif
02508 
02509       if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
02510          != STRING_SIZE_SIZE)
02511        return FALSE;
02512 
02513       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
02514        return FALSE;
02515     }
02516 
02517   _bfd_stringtab_free (finfo.strtab);
02518 
02519   /* Setting bfd_get_symcount to 0 will cause write_object_contents to
02520      not try to write out the symbols.  */
02521   bfd_get_symcount (abfd) = 0;
02522 
02523   return TRUE;
02524 
02525  error_return:
02526   if (debug_merge_allocated)
02527     coff_debug_merge_hash_table_free (&finfo.debug_merge);
02528   if (finfo.strtab != NULL)
02529     _bfd_stringtab_free (finfo.strtab);
02530   if (finfo.section_info != NULL)
02531     {
02532       unsigned int i;
02533 
02534       for (i = 0; i < abfd->section_count; i++)
02535        {
02536          if (finfo.section_info[i].relocs != NULL)
02537            free (finfo.section_info[i].relocs);
02538          if (finfo.section_info[i].rel_hashes != NULL)
02539            free (finfo.section_info[i].rel_hashes);
02540        }
02541       free (finfo.section_info);
02542     }
02543   if (finfo.internal_syms != NULL)
02544     free (finfo.internal_syms);
02545   if (finfo.sec_ptrs != NULL)
02546     free (finfo.sec_ptrs);
02547   if (finfo.sym_indices != NULL)
02548     free (finfo.sym_indices);
02549   if (finfo.outsyms != NULL)
02550     free (finfo.outsyms);
02551   if (finfo.linenos != NULL)
02552     free (finfo.linenos);
02553   if (finfo.contents != NULL)
02554     free (finfo.contents);
02555   if (finfo.external_relocs != NULL)
02556     free (finfo.external_relocs);
02557   if (finfo.internal_relocs != NULL)
02558     free (finfo.internal_relocs);
02559   if (external_relocs != NULL)
02560     free (external_relocs);
02561   return FALSE;
02562 }
02563 #endif
02564 
02565 /* Forward declaration for use by alternative_target field.  */
02566 #ifdef TARGET_BIG_SYM
02567 extern const bfd_target TARGET_BIG_SYM;
02568 #endif
02569 
02570 /* The transfer vectors that lead the outside world to all of the above.  */
02571 
02572 #ifdef TARGET_LITTLE_SYM
02573 const bfd_target TARGET_LITTLE_SYM =
02574 {
02575   TARGET_LITTLE_NAME,              /* name or coff-arm-little */
02576   bfd_target_coff_flavour,
02577   BFD_ENDIAN_LITTLE,        /* data byte order is little */
02578   BFD_ENDIAN_LITTLE,        /* header byte order is little */
02579 
02580   (HAS_RELOC | EXEC_P |            /* FIXME: object flags */
02581    HAS_LINENO | HAS_DEBUG |
02582    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
02583 
02584 #ifndef COFF_WITH_PE
02585   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
02586 #else
02587   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
02588    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
02589 #endif
02590 
02591   0,                        /* leading char */
02592   '/',                      /* ar_pad_char */
02593   15,                       /* ar_max_namelen??? FIXMEmgo */
02594 
02595   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
02596   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
02597   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
02598 
02599   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
02600   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
02601   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
02602 
02603   {_bfd_dummy_target, coff_object_p,      /* bfd_check_format */
02604      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
02605   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
02606      bfd_false},
02607   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
02608      _bfd_write_archive_contents, bfd_false},
02609 
02610   BFD_JUMP_TABLE_GENERIC (coff),
02611   BFD_JUMP_TABLE_COPY (coff),
02612   BFD_JUMP_TABLE_CORE (_bfd_nocore),
02613   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
02614   BFD_JUMP_TABLE_SYMBOLS (coff),
02615   BFD_JUMP_TABLE_RELOCS (coff),
02616   BFD_JUMP_TABLE_WRITE (coff),
02617   BFD_JUMP_TABLE_LINK (coff),
02618   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
02619 
02620   /* Alternative_target.  */
02621 #ifdef TARGET_BIG_SYM
02622   & TARGET_BIG_SYM,
02623 #else
02624   NULL,
02625 #endif
02626 
02627   COFF_SWAP_TABLE
02628 };
02629 #endif
02630 
02631 #ifdef TARGET_BIG_SYM
02632 const bfd_target TARGET_BIG_SYM =
02633 {
02634   TARGET_BIG_NAME,
02635   bfd_target_coff_flavour,
02636   BFD_ENDIAN_BIG,           /* data byte order is big */
02637   BFD_ENDIAN_BIG,           /* header byte order is big */
02638 
02639   (HAS_RELOC | EXEC_P |            /* FIXME: object flags */
02640    HAS_LINENO | HAS_DEBUG |
02641    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
02642 
02643 #ifndef COFF_WITH_PE
02644   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
02645 #else
02646   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
02647    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
02648 #endif
02649 
02650   0,                        /* leading char */
02651   '/',                      /* ar_pad_char */
02652   15,                       /* ar_max_namelen??? FIXMEmgo */
02653 
02654   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
02655   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
02656   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
02657 
02658   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
02659   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
02660   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
02661 
02662   {_bfd_dummy_target, coff_object_p,      /* bfd_check_format */
02663      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
02664   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
02665      bfd_false},
02666   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
02667      _bfd_write_archive_contents, bfd_false},
02668 
02669   BFD_JUMP_TABLE_GENERIC (coff),
02670   BFD_JUMP_TABLE_COPY (coff),
02671   BFD_JUMP_TABLE_CORE (_bfd_nocore),
02672   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
02673   BFD_JUMP_TABLE_SYMBOLS (coff),
02674   BFD_JUMP_TABLE_RELOCS (coff),
02675   BFD_JUMP_TABLE_WRITE (coff),
02676   BFD_JUMP_TABLE_LINK (coff),
02677   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
02678 
02679   /* Alternative_target.  */
02680 #ifdef TARGET_LITTLE_SYM
02681   & TARGET_LITTLE_SYM,
02682 #else
02683   NULL,
02684 #endif
02685 
02686   COFF_SWAP_TABLE
02687 };
02688 
02689 #endif