This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / bfd / coff-ppc.c
1 /* BFD back-end for PowerPC Microsoft Portable Executable files.
2    Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3
4    Original version pieced together by Kim Knuttila (krk@cygnus.com)
5
6    There is nothing new under the sun. This file draws a lot on other
7    coff files, in particular, those for the rs/6000, alpha, mips, and 
8    intel backends, and the PE work for the arm.
9
10 This file is part of BFD, the Binary File Descriptor library.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
25
26 /* Current State:
27    - objdump works
28    - relocs generated by gas
29    - ld will link files, but they do not run.
30    - dlltool will not produce correct output in some .reloc cases, and will 
31      not produce the right glue code for dll function calls.
32 */
33
34
35 #include "bfd.h"
36 #include "sysdep.h"
37
38 #include "libbfd.h"
39
40 #include "coff/powerpc.h"
41 #include "coff/internal.h"
42
43 #include "coff/pe.h"
44
45 #ifdef BADMAG
46 #undef BADMAG
47 #endif
48
49 #define BADMAG(x) PPCBADMAG(x)
50
51 #include "libcoff.h"
52
53 /* The toc is a set of bfd_vma fields. We use the fact that valid         */
54 /* addresses are even (i.e. the bit representing "1" is off) to allow     */
55 /* us to encode a little extra information in the field                   */
56 /* - Unallocated addresses are intialized to 1.                           */
57 /* - Allocated addresses are even numbers.                                */
58 /* The first time we actually write a reference to the toc in the bfd,    */
59 /* we want to record that fact in a fixup file (if it is asked for), so   */
60 /* we keep track of whether or not an address has been written by marking */
61 /* the low order bit with a "1" upon writing                              */
62
63 #define SET_UNALLOCATED(x)  ((x) = 1)
64 #define IS_UNALLOCATED(x)   ((x) == 1)
65
66 #define IS_WRITTEN(x)       ((x) & 1)
67 #define MARK_AS_WRITTEN(x)  ((x) |= 1)
68 #define MAKE_ADDR_AGAIN(x)  ((x) &= ~1)
69
70
71 /* Turn on this check if you suspect something amiss in the hash tables */
72 #ifdef DEBUG_HASH
73
74 /* Need a 7 char string for an eye catcher */
75 #define EYE "krkjunk"
76
77 #define HASH_CHECK_DCL char eye_catcher[8];
78 #define HASH_CHECK_INIT(ret)      strcpy(ret->eye_catcher, EYE)
79 #define HASH_CHECK(addr) \
80  if (strcmp(addr->eye_catcher, EYE) != 0) \
81   { \
82     fprintf(stderr,\
83     "File %s, line %d, Hash check failure, bad eye %8s\n", \
84     __FILE__, __LINE__, addr->eye_catcher); \
85     abort(); \
86  }
87
88
89 #else
90
91 #define HASH_CHECK_DCL
92 #define HASH_CHECK_INIT(ret)
93 #define HASH_CHECK(addr)
94
95 #endif
96
97 /* In order not to add an int to every hash table item for every coff
98    linker, we define our own hash table, derived from the coff one */
99
100 /* PE linker hash table entries. */
101
102 struct ppc_coff_link_hash_entry
103 {
104   struct coff_link_hash_entry root; /* First entry, as required  */
105
106   /* As we wonder around the relocs, we'll keep the assigned toc_offset
107      here */
108   bfd_vma toc_offset;               /* Our addition, as required */
109   int symbol_is_glue;
110   unsigned long int glue_insn;
111
112   HASH_CHECK_DCL
113 };
114
115
116 /* PE linker hash table.  */
117
118 struct ppc_coff_link_hash_table
119 {
120   struct coff_link_hash_table root; /* First entry, as required */
121 };
122
123 static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
124   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
125            const char *));
126
127 /* Routine to create an entry in the link hash table.  */
128
129 static struct bfd_hash_entry *
130 ppc_coff_link_hash_newfunc (entry, table, string)
131      struct bfd_hash_entry *entry;
132      struct bfd_hash_table *table;
133      const char *string;
134 {
135   struct ppc_coff_link_hash_entry *ret = 
136     (struct ppc_coff_link_hash_entry *) entry;
137
138   /* Allocate the structure if it has not already been allocated by a
139      subclass.  */
140   if (ret == (struct ppc_coff_link_hash_entry *) NULL)
141     ret = (struct ppc_coff_link_hash_entry *)
142       bfd_hash_allocate (table, 
143                          sizeof (struct ppc_coff_link_hash_entry));
144
145   if (ret == (struct ppc_coff_link_hash_entry *) NULL)
146     return NULL;
147
148   /* Call the allocation method of the superclass.  */
149   ret = ((struct ppc_coff_link_hash_entry *)
150          _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret, 
151                                       table, string));
152
153   if (ret)
154     {
155       /* Initialize the local fields.  */
156       SET_UNALLOCATED(ret->toc_offset);
157       ret->symbol_is_glue = 0;
158       ret->glue_insn = 0;
159
160       HASH_CHECK_INIT(ret);
161     }
162
163   return (struct bfd_hash_entry *) ret;
164 }
165
166 /* Initialize a PE linker hash table.  */
167
168 static boolean
169 ppc_coff_link_hash_table_init (table, abfd, newfunc)
170      struct ppc_coff_link_hash_table *table;
171      bfd *abfd;
172      struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
173                                                 struct bfd_hash_table *,
174                                                 const char *));
175 {
176   return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
177 }
178
179 /* Create a PE linker hash table.  */
180
181 static struct bfd_link_hash_table *
182 ppc_coff_link_hash_table_create (abfd)
183      bfd *abfd;
184 {
185   struct ppc_coff_link_hash_table *ret;
186
187   ret = ((struct ppc_coff_link_hash_table *)
188          bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table)));
189   if (ret == NULL)
190     return NULL;
191   if (! ppc_coff_link_hash_table_init (ret, abfd,
192                                         ppc_coff_link_hash_newfunc))
193     {
194       bfd_release (abfd, ret);
195       return (struct bfd_link_hash_table *) NULL;
196     }
197   return &ret->root.root;
198 }
199
200 /* Now, tailor coffcode.h to use our hash stuff */
201
202 #define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
203
204 \f
205 /* The nt loader points the toc register to &toc + 32768, in order to */
206 /* use the complete range of a 16-bit displacement. We have to adjust */
207 /* for this when we fix up loads displaced off the toc reg.           */
208 #define TOC_LOAD_ADJUSTMENT (-32768)
209 #define TOC_SECTION_NAME ".private.toc"
210
211 /* The main body of code is in coffcode.h.  */
212
213 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
214
215 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
216    from smaller values.  Start with zero, widen, *then* decrement.  */
217 #define MINUS_ONE       (((bfd_vma)0) - 1)
218
219 /* these should definitely go in a header file somewhere... */
220
221 /* NOP */
222 #define IMAGE_REL_PPC_ABSOLUTE          0x0000
223
224 /* 64-bit address */
225 #define IMAGE_REL_PPC_ADDR64            0x0001
226
227 /* 32-bit address */
228 #define IMAGE_REL_PPC_ADDR32            0x0002
229
230 /* 26-bit address, shifted left 2 (branch absolute) */
231 #define IMAGE_REL_PPC_ADDR24            0x0003
232
233 /* 16-bit address */
234 #define IMAGE_REL_PPC_ADDR16            0x0004
235
236 /* 16-bit address, shifted left 2 (load doubleword) */
237 #define IMAGE_REL_PPC_ADDR14            0x0005
238
239 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
240 #define IMAGE_REL_PPC_REL24             0x0006
241
242 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
243 #define IMAGE_REL_PPC_REL14             0x0007
244
245 /* 16-bit offset from TOC base */
246 #define IMAGE_REL_PPC_TOCREL16          0x0008
247
248 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
249 #define IMAGE_REL_PPC_TOCREL14          0x0009
250
251 /* 32-bit addr w/o image base */
252 #define IMAGE_REL_PPC_ADDR32NB          0x000A
253
254 /* va of containing section (as in an image sectionhdr) */
255 #define IMAGE_REL_PPC_SECREL            0x000B
256
257 /* sectionheader number */
258 #define IMAGE_REL_PPC_SECTION           0x000C
259
260 /* substitute TOC restore instruction iff symbol is glue code */
261 #define IMAGE_REL_PPC_IFGLUE            0x000D
262
263 /* symbol is glue code; virtual address is TOC restore instruction */
264 #define IMAGE_REL_PPC_IMGLUE            0x000E
265
266 /* va of containing section (limited to 16 bits) */
267 #define IMAGE_REL_PPC_SECREL16          0x000F
268
269 /* stuff to handle immediate data when the number of bits in the */
270 /* data is greater than the number of bits in the immediate field */
271 /* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
272 #define IMAGE_REL_PPC_REFHI             0x0010
273 #define IMAGE_REL_PPC_REFLO             0x0011
274 #define IMAGE_REL_PPC_PAIR              0x0012
275
276 /* This is essentially the same as tocrel16, with TOCDEFN assumed */
277 #define IMAGE_REL_PPC_TOCREL16_DEFN     0x0013
278
279 /*  Flag bits in IMAGE_RELOCATION.TYPE */
280
281 /* subtract reloc value rather than adding it */
282 #define IMAGE_REL_PPC_NEG               0x0100
283
284 /* fix branch prediction bit to predict branch taken */
285 #define IMAGE_REL_PPC_BRTAKEN           0x0200
286
287 /* fix branch prediction bit to predict branch not taken */
288 #define IMAGE_REL_PPC_BRNTAKEN          0x0400
289
290 /* toc slot defined in file (or, data in toc) */
291 #define IMAGE_REL_PPC_TOCDEFN           0x0800
292
293 /* masks to isolate above values in IMAGE_RELOCATION.Type */
294 #define IMAGE_REL_PPC_TYPEMASK          0x00FF
295 #define IMAGE_REL_PPC_FLAGMASK          0x0F00
296
297 #define EXTRACT_TYPE(x)                 ((x) & IMAGE_REL_PPC_TYPEMASK)
298 #define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
299 #define EXTRACT_JUNK(x)  \
300            ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
301
302 \f
303 /* static helper functions to make relocation work */
304 /* (Work In Progress) */
305
306 static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
307                                                       arelent *reloc,
308                                                       asymbol *symbol,
309                                                       PTR data,
310                                                       asection *section,
311                                                       bfd *output_bfd,
312                                                       char **error));
313 #if 0
314 static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
315                                                       arelent *reloc,
316                                                       asymbol *symbol,
317                                                       PTR data,
318                                                       asection *section,
319                                                       bfd *output_bfd,
320                                                       char **error));
321 #endif
322 static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
323                                                      arelent *reloc,
324                                                      asymbol *symbol,
325                                                      PTR data,
326                                                      asection *section,
327                                                      bfd *output_bfd,
328                                                      char **error));
329
330 \f
331 static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
332                                                       arelent *reloc,
333                                                       asymbol *symbol,
334                                                       PTR data,
335                                                       asection *section,
336                                                       bfd *output_bfd,
337                                                       char **error));
338
339 #if 0
340 static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
341                                                          arelent *reloc,
342                                                          asymbol *symbol,
343                                                          PTR data,
344                                                          asection *section,
345                                                          bfd *output_bfd,
346                                                          char **error));
347 #endif
348 static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
349                                                         arelent *reloc,
350                                                         asymbol *symbol,
351                                                         PTR data,
352                                                         asection *section,
353                                                         bfd *output_bfd,
354                                                         char **error));
355
356 static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
357                                                        arelent *reloc,
358                                                        asymbol *symbol,
359                                                        PTR data,
360                                                        asection *section,
361                                                        bfd *output_bfd,
362                                                        char **error));
363
364 static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
365                                                        arelent *reloc,
366                                                        asymbol *symbol,
367                                                        PTR data,
368                                                        asection *section,
369                                                        bfd *output_bfd,
370                                                        char **error));
371
372
373
374 static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
375
376 \f
377 /* FIXME: It'll take a while to get through all of these. I only need a few to
378    get us started, so those I'll make sure work. Those marked FIXME are either
379    completely unverified or have a specific unknown marked in the comment */
380
381 /*---------------------------------------------------------------------------*/
382 /*                                                                           */
383 /* Relocation entries for Windows/NT on PowerPC.                             */
384 /*                                                                           */
385 /* From the document "" we find the following listed as used relocs:         */
386 /*                                                                           */
387 /*   ABSOLUTE       : The noop                                               */
388 /*   ADDR[64|32|16] : fields that hold addresses in data fields or the       */
389 /*                    16 bit displacement field on a load/store.             */
390 /*   ADDR[24|14]    : fields that hold addresses in branch and cond          */
391 /*                    branches. These represent [26|16] bit addresses.       */
392 /*                    The low order 2 bits are preserved.                    */
393 /*   REL[24|14]     : branches relative to the Instruction Address           */
394 /*                    register. These represent [26|16] bit addresses,       */
395 /*                    as before. The instruction field will be zero, and     */
396 /*                    the address of the SYM will be inserted at link time.  */
397 /*   TOCREL16       : 16 bit displacement field referring to a slot in       */
398 /*                    toc.                                                   */
399 /*   TOCREL14       : 16 bit displacement field, similar to REL14 or ADDR14. */
400 /*   ADDR32NB       : 32 bit address relative to the virtual origin.         */
401 /*                    (On the alpha, this is always a linker generated thunk)*/
402 /*                    (i.e. 32bit addr relative to the image base)           */
403 /*   SECREL         : The value is relative to the start of the section      */
404 /*                    containing the symbol.                                 */
405 /*   SECTION        : access to the header containing the item. Supports the */
406 /*                    codeview debugger.                                     */
407 /*                                                                           */
408 /* In particular, note that the document does not indicate that the          */
409 /* relocations listed in the header file are used.                           */
410 /*                                                                           */
411 /*                                                                           */
412 /*                                                                           */
413 /*---------------------------------------------------------------------------*/
414
415 static reloc_howto_type ppc_coff_howto_table[] =
416 {
417   /* IMAGE_REL_PPC_ABSOLUTE 0x0000   NOP */
418   /* Unused: */
419   HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */                                 
420          0,                      /* rightshift */                           
421          0,                      /* size (0 = byte, 1 = short, 2 = long) */ 
422          0,                      /* bitsize */                   
423          false,                  /* pc_relative */                          
424          0,                      /* bitpos */                               
425          complain_overflow_dont, /* dont complain_on_overflow */
426          0,                      /* special_function */                     
427          "ABSOLUTE",             /* name */
428          false,                  /* partial_inplace */                      
429          0x00,                   /* src_mask */                             
430          0x00,                   /* dst_mask */                             
431          false),                 /* pcrel_offset */
432   
433   /* IMAGE_REL_PPC_ADDR64 0x0001  64-bit address */
434   /* Unused: */
435   HOWTO(IMAGE_REL_PPC_ADDR64,    /* type */                                 
436         0,                       /* rightshift */                           
437         3,                       /* size (0 = byte, 1 = short, 2 = long) */ 
438         64,                      /* bitsize */                   
439         false,                   /* pc_relative */                          
440         0,                       /* bitpos */                               
441         complain_overflow_bitfield,      /* complain_on_overflow */
442         0,                       /* special_function */                     
443         "ADDR64",               /* name */
444         true,                    /* partial_inplace */                      
445         MINUS_ONE,               /* src_mask */
446         MINUS_ONE,               /* dst_mask */
447         false),                 /* pcrel_offset */
448
449   /* IMAGE_REL_PPC_ADDR32 0x0002  32-bit address */
450   /* Used: */
451   HOWTO (IMAGE_REL_PPC_ADDR32,  /* type */
452          0,                     /* rightshift */                           
453          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
454          32,                    /* bitsize */                   
455          false,                 /* pc_relative */                          
456          0,                     /* bitpos */                               
457          complain_overflow_bitfield, /* complain_on_overflow */
458          0,                     /* special_function */                     
459          "ADDR32",              /* name */
460          true,                  /* partial_inplace */                      
461          0xffffffff,            /* src_mask */                             
462          0xffffffff,            /* dst_mask */                             
463          false),                /* pcrel_offset */
464   
465   /* IMAGE_REL_PPC_ADDR24 0x0003  26-bit address, shifted left 2 (branch absolute) */
466   /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
467   /* Of course, That's the IBM approved bit numbering, which is not what */
468   /* anyone else uses.... The li field is in bit 2 thru 25 */ 
469   /* Used: */
470   HOWTO (IMAGE_REL_PPC_ADDR24,  /* type */
471          0,                     /* rightshift */                           
472          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
473          26,                    /* bitsize */
474          false,                 /* pc_relative */                          
475          0,                     /* bitpos */                               
476          complain_overflow_bitfield, /* complain_on_overflow */
477          0,                     /* special_function */                     
478          "ADDR24",              /* name */
479          true,                  /* partial_inplace */                      
480          0x07fffffc,            /* src_mask */                             
481          0x07fffffc,            /* dst_mask */                             
482          false),                /* pcrel_offset */
483   
484   /* IMAGE_REL_PPC_ADDR16 0x0004  16-bit address */
485   /* Used: */
486   HOWTO (IMAGE_REL_PPC_ADDR16,  /* type */             
487          0,                     /* rightshift */                           
488          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
489          16,                    /* bitsize */                   
490          false,                 /* pc_relative */                          
491          0,                     /* bitpos */                               
492          complain_overflow_signed, /* complain_on_overflow */
493          0,                     /* special_function */                     
494          "ADDR16",              /* name */
495          true,                  /* partial_inplace */                      
496          0xffff,                /* src_mask */                             
497          0xffff,                /* dst_mask */                             
498          false),                /* pcrel_offset */
499   
500   /* IMAGE_REL_PPC_ADDR14 0x0005 */
501   /*  16-bit address, shifted left 2 (load doubleword) */
502   /* FIXME: the mask is likely wrong, and the bit position may be as well */
503   /* Unused: */
504   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */             
505          1,                     /* rightshift */                           
506          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
507          16,                    /* bitsize */                   
508          false,                 /* pc_relative */                          
509          0,                     /* bitpos */                               
510          complain_overflow_signed, /* complain_on_overflow */
511          0,                     /* special_function */                     
512          "ADDR16",              /* name */
513          true,                  /* partial_inplace */                      
514          0xffff,                /* src_mask */                             
515          0xffff,                /* dst_mask */                             
516          false),                /* pcrel_offset */
517   
518   /* IMAGE_REL_PPC_REL24 0x0006 */
519   /*   26-bit PC-relative offset, shifted left 2 (branch relative) */
520   /* Used: */
521   HOWTO (IMAGE_REL_PPC_REL24,   /* type */
522          0,                     /* rightshift */                           
523          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
524          26,                    /* bitsize */                   
525          true,                  /* pc_relative */                          
526          0,                     /* bitpos */                               
527          complain_overflow_signed, /* complain_on_overflow */
528          0,                     /* special_function */                     
529          "REL24",               /* name */
530          true,                  /* partial_inplace */                      
531          0x3fffffc,             /* src_mask */                             
532          0x3fffffc,             /* dst_mask */                             
533          false),                /* pcrel_offset */
534   
535   /* IMAGE_REL_PPC_REL14 0x0007 */
536   /*   16-bit PC-relative offset, shifted left 2 (br cond relative) */
537   /* FIXME: the mask is likely wrong, and the bit position may be as well */
538   /* FIXME: how does it know how far to shift? */
539   /* Unused: */
540   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */             
541          1,                     /* rightshift */                           
542          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
543          16,                    /* bitsize */                   
544          false,                 /* pc_relative */                          
545          0,                     /* bitpos */                               
546          complain_overflow_signed, /* complain_on_overflow */
547          0,                     /* special_function */                     
548          "ADDR16",              /* name */
549          true,                  /* partial_inplace */                      
550          0xffff,                /* src_mask */                             
551          0xffff,                /* dst_mask */                             
552          true),                 /* pcrel_offset */
553   
554   /* IMAGE_REL_PPC_TOCREL16 0x0008 */
555   /*   16-bit offset from TOC base */
556   /* Used: */
557   HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */             
558          0,                     /* rightshift */                           
559          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
560          16,                    /* bitsize */                   
561          false,                 /* pc_relative */                          
562          0,                     /* bitpos */                               
563          complain_overflow_dont, /* complain_on_overflow */
564          ppc_toc16_reloc,       /* special_function */                     
565          "TOCREL16",            /* name */
566          false,                 /* partial_inplace */                      
567          0xffff,                /* src_mask */                             
568          0xffff,                /* dst_mask */                             
569          false),                /* pcrel_offset */
570   
571   /* IMAGE_REL_PPC_TOCREL14 0x0009 */
572   /*   16-bit offset from TOC base, shifted left 2 (load doubleword) */
573   /* Unused: */
574   HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */             
575          1,                     /* rightshift */                           
576          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
577          16,                    /* bitsize */                   
578          false,                 /* pc_relative */                          
579          0,                     /* bitpos */                               
580          complain_overflow_signed, /* complain_on_overflow */
581          0,                     /* special_function */                     
582          "TOCREL14",            /* name */
583          false,                 /* partial_inplace */                      
584          0xffff,                /* src_mask */                             
585          0xffff,                /* dst_mask */                             
586          false),                /* pcrel_offset */
587   
588   /* IMAGE_REL_PPC_ADDR32NB 0x000A */
589   /*   32-bit addr w/ image base */
590   /* Unused: */
591   HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */             
592          0,                     /* rightshift */                           
593          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
594          32,                    /* bitsize */                   
595          false,                 /* pc_relative */                          
596          0,                     /* bitpos */                               
597          complain_overflow_signed, /* complain_on_overflow */
598          0,                     /* special_function */                     
599          "ADDR32NB",            /* name */
600          true,                  /* partial_inplace */                      
601          0xffffffff,            /* src_mask */                             
602          0xffffffff,            /* dst_mask */                             
603          false),                 /* pcrel_offset */
604   
605   /* IMAGE_REL_PPC_SECREL 0x000B */
606   /*   va of containing section (as in an image sectionhdr) */
607   /* Unused: */
608   HOWTO (IMAGE_REL_PPC_SECREL,/* type */             
609          0,                     /* rightshift */                           
610          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
611          32,                    /* bitsize */                   
612          false,                 /* pc_relative */                          
613          0,                     /* bitpos */                               
614          complain_overflow_signed, /* complain_on_overflow */
615          ppc_secrel_reloc,      /* special_function */                     
616          "SECREL",              /* name */
617          true,                  /* partial_inplace */                      
618          0xffffffff,            /* src_mask */                             
619          0xffffffff,            /* dst_mask */                             
620          true),                 /* pcrel_offset */
621
622   /* IMAGE_REL_PPC_SECTION 0x000C */
623   /*   sectionheader number */
624   /* Unused: */
625   HOWTO (IMAGE_REL_PPC_SECTION,/* type */             
626          0,                     /* rightshift */                           
627          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
628          32,                    /* bitsize */                   
629          false,                 /* pc_relative */                          
630          0,                     /* bitpos */                               
631          complain_overflow_signed, /* complain_on_overflow */
632          ppc_section_reloc,     /* special_function */                     
633          "SECTION",             /* name */
634          true,                  /* partial_inplace */                      
635          0xffffffff,            /* src_mask */                             
636          0xffffffff,            /* dst_mask */                             
637          true),                 /* pcrel_offset */
638
639   /* IMAGE_REL_PPC_IFGLUE 0x000D */
640   /*   substitute TOC restore instruction iff symbol is glue code */
641   /* Used: */
642   HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */             
643          0,                     /* rightshift */                           
644          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
645          32,                    /* bitsize */                   
646          false,                 /* pc_relative */                          
647          0,                     /* bitpos */                               
648          complain_overflow_signed, /* complain_on_overflow */
649          0,                     /* special_function */                     
650          "IFGLUE",              /* name */
651          true,                  /* partial_inplace */                      
652          0xffffffff,            /* src_mask */                             
653          0xffffffff,            /* dst_mask */                             
654          false),                /* pcrel_offset */
655
656   /* IMAGE_REL_PPC_IMGLUE 0x000E */
657   /*   symbol is glue code; virtual address is TOC restore instruction */
658   /* Unused: */
659   HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */             
660          0,                     /* rightshift */                           
661          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
662          32,                    /* bitsize */                   
663          false,                 /* pc_relative */                          
664          0,                     /* bitpos */                               
665          complain_overflow_dont, /* complain_on_overflow */
666          ppc_imglue_reloc,      /* special_function */                     
667          "IMGLUE",              /* name */
668          false,                 /* partial_inplace */                      
669          0xffffffff,            /* src_mask */                             
670          0xffffffff,            /* dst_mask */                             
671          false),                 /* pcrel_offset */
672
673   /* IMAGE_REL_PPC_SECREL16 0x000F */
674   /*   va of containing section (limited to 16 bits) */
675   /* Unused: */
676   HOWTO (IMAGE_REL_PPC_SECREL16,/* type */             
677          0,                     /* rightshift */                           
678          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
679          16,                    /* bitsize */                   
680          false,                 /* pc_relative */                          
681          0,                     /* bitpos */                               
682          complain_overflow_signed, /* complain_on_overflow */
683          0,                     /* special_function */                     
684          "SECREL16",            /* name */
685          true,                  /* partial_inplace */                      
686          0xffff,                /* src_mask */                             
687          0xffff,                /* dst_mask */                             
688          true),                 /* pcrel_offset */
689
690   /* IMAGE_REL_PPC_REFHI             0x0010 */
691   /* Unused: */
692   HOWTO (IMAGE_REL_PPC_REFHI,   /* type */             
693          0,                     /* rightshift */                           
694          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
695          16,                    /* bitsize */                   
696          false,                 /* pc_relative */                          
697          0,                     /* bitpos */                               
698          complain_overflow_signed, /* complain_on_overflow */
699          ppc_refhi_reloc,       /* special_function */                     
700          "REFHI",               /* name */
701          true,                  /* partial_inplace */                      
702          0xffffffff,            /* src_mask */                             
703          0xffffffff,            /* dst_mask */                             
704          false),                 /* pcrel_offset */
705
706   /* IMAGE_REL_PPC_REFLO             0x0011 */
707   /* Unused: */
708   HOWTO (IMAGE_REL_PPC_REFLO,   /* type */             
709          0,                     /* rightshift */                           
710          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
711          16,                    /* bitsize */                   
712          false,                 /* pc_relative */                          
713          0,                     /* bitpos */                               
714          complain_overflow_signed, /* complain_on_overflow */
715          ppc_refhi_reloc,       /* special_function */                     
716          "REFLO",               /* name */
717          true,                  /* partial_inplace */                      
718          0xffffffff,            /* src_mask */                             
719          0xffffffff,            /* dst_mask */                             
720          false),                /* pcrel_offset */
721
722   /* IMAGE_REL_PPC_PAIR              0x0012 */
723   /* Unused: */
724   HOWTO (IMAGE_REL_PPC_PAIR,    /* type */             
725          0,                     /* rightshift */                           
726          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
727          16,                    /* bitsize */                   
728          false,                 /* pc_relative */                          
729          0,                     /* bitpos */                               
730          complain_overflow_signed, /* complain_on_overflow */
731          ppc_pair_reloc,        /* special_function */                     
732          "PAIR",                /* name */
733          true,                  /* partial_inplace */                      
734          0xffffffff,            /* src_mask */                             
735          0xffffffff,            /* dst_mask */                             
736          false),                /* pcrel_offset */
737
738   /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */
739   /*   16-bit offset from TOC base, without causing a definition */
740   /* Used: */
741   HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */ 
742          0,                     /* rightshift */                           
743          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
744          16,                    /* bitsize */                   
745          false,                 /* pc_relative */                          
746          0,                     /* bitpos */                               
747          complain_overflow_dont, /* complain_on_overflow */
748          0,                     /* special_function */                     
749          "TOCREL16, TOCDEFN",   /* name */
750          false,                 /* partial_inplace */                      
751          0xffff,                /* src_mask */                             
752          0xffff,                /* dst_mask */                             
753          false),                /* pcrel_offset */
754
755 };
756
757
758 \f
759
760 /* Some really cheezy macros that can be turned on to test stderr :-) */
761
762 #ifdef DEBUG_RELOC
763 #define UN_IMPL(x)                                           \
764 {                                                            \
765    static int i;                                             \
766    if (i == 0)                                               \
767      {                                                       \
768        i = 1;                                                \
769        fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \
770      }                                                       \
771 }
772
773 #define DUMP_RELOC(n,r)                              \
774 {                                                    \
775    fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
776            n, (*(r->sym_ptr_ptr))->name,             \
777            r->address, r->addend);                   \
778 }
779
780 /* Given a reloc name, n, and a pointer to an internal_reloc, 
781    dump out interesting information on the contents 
782
783 #define n_name          _n._n_name
784 #define n_zeroes        _n._n_n._n_zeroes
785 #define n_offset        _n._n_n._n_offset
786
787 */
788
789 #define DUMP_RELOC2(n,r)                     \
790 {                                            \
791    fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \
792            n, r->r_symndx, r->r_vaddr,\
793            (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
794            ?" ":" TOCDEFN"  );      \
795 }
796
797 #else
798 #define UN_IMPL(x)
799 #define DUMP_RELOC(n,r)
800 #define DUMP_RELOC2(n,r)
801 #endif
802
803
804 \f
805 /* toc construction and management routines */
806 extern bfd* bfd_of_toc_owner;
807 extern long int global_toc_size;
808
809 extern long int import_table_size;
810 extern long int first_thunk_address;
811 extern long int thunk_size;
812
813 enum toc_type
814 {
815   default_toc,
816   toc_32,
817   toc_64
818 };
819
820 enum ref_category
821 {
822   priv,
823   pub,
824   data
825 };
826
827 struct list_ele
828 {
829   struct list_ele *next;
830   bfd_vma addr;
831   enum ref_category cat;
832   int offset;
833   const char *name;
834 };
835
836 extern struct list_ele *head;
837 extern struct list_ele *tail;
838
839 static void
840 record_toc(toc_section, our_toc_offset, cat, name)
841      asection *toc_section;
842      int our_toc_offset;
843      enum ref_category cat;
844      const char *name;
845 {
846   /* add this entry to our toc addr-offset-name list */
847   struct list_ele *t;
848   t = (struct list_ele *) bfd_malloc (sizeof (struct list_ele));
849   if (t == NULL)
850     abort ();
851   t->next = 0;
852   t->offset = our_toc_offset;
853   t->name = name;
854   t->cat = cat;
855   t->addr = toc_section->output_offset + our_toc_offset;
856
857   if (head == 0)
858     {
859       head = t;
860       tail = t;
861     }
862   else
863     {
864       tail->next = t;
865       tail = t;
866     }
867 }
868
869 #ifdef COFF_IMAGE_WITH_PE
870
871 /* record a toc offset against a symbol */
872 static boolean
873 ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
874      bfd *abfd;
875      struct bfd_link_info *info;
876      asection *sec;
877      int sym;
878      enum toc_type toc_kind;
879 {
880   struct ppc_coff_link_hash_entry *h;
881   const char *name;
882
883   int *local_syms;
884
885   h = 0;
886
887   h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
888   if (h != 0)
889     {
890       HASH_CHECK(h);
891     }
892
893   if (h == 0) 
894     { 
895       local_syms = obj_coff_local_toc_table(abfd);
896       if (local_syms == 0)
897         {
898           int i;
899           /* allocate a table */
900           local_syms = 
901             (int *) bfd_zalloc (abfd, 
902                                 obj_raw_syment_count(abfd) * sizeof(int));
903           if (local_syms == 0)
904             return false;
905           obj_coff_local_toc_table(abfd) = local_syms;
906           for (i = 0; i < obj_raw_syment_count(abfd); ++i)
907             {
908               SET_UNALLOCATED(local_syms[i]);
909             }
910         }
911
912       if (IS_UNALLOCATED(local_syms[sym])) 
913         {
914           local_syms[sym] = global_toc_size;
915           global_toc_size += 4;
916
917           /* The size must fit in a 16bit displacment */
918           if (global_toc_size > 65535)
919             {
920               (*_bfd_error_handler) ("TOC overflow");
921               bfd_set_error (bfd_error_file_too_big);
922               return false;
923             }
924         }
925     }
926   else
927     {
928       name = h->root.root.root.string;
929
930       /* check to see if there's a toc slot allocated. If not, do it
931          here. It will be used in relocate_section */
932       if (IS_UNALLOCATED(h->toc_offset))
933         {
934           h->toc_offset = global_toc_size;
935           global_toc_size += 4;
936
937           /* The size must fit in a 16bit displacment */
938           if (global_toc_size >= 65535)
939             {
940               (*_bfd_error_handler) ("TOC overflow");
941               bfd_set_error (bfd_error_file_too_big);
942               return false;
943             }
944         }
945     }
946
947   return true;
948 }
949
950 /* record a toc offset against a symbol */
951 static void
952 ppc_mark_symbol_as_glue(abfd, sym, rel)
953      bfd *abfd;
954      int sym;
955      struct internal_reloc *rel;
956 {
957   struct ppc_coff_link_hash_entry *h;
958
959   h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
960
961   HASH_CHECK(h);
962
963   h->symbol_is_glue = 1;
964   h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
965
966   return;
967 }
968
969 #endif /* COFF_IMAGE_WITH_PE */
970 \f
971
972 /* Return true if this relocation should
973    appear in the output .reloc section. */
974
975 static boolean in_reloc_p(abfd, howto)
976      bfd * abfd;
977      reloc_howto_type *howto;
978 {
979   return 
980     (! howto->pc_relative) 
981       && (howto->type != IMAGE_REL_PPC_ADDR32NB)
982       && (howto->type != IMAGE_REL_PPC_TOCREL16)
983       && (howto->type != IMAGE_REL_PPC_IMGLUE)
984       && (howto->type != IMAGE_REL_PPC_IFGLUE) 
985       && (howto->type != IMAGE_REL_PPC_SECREL)
986       && (howto->type != IMAGE_REL_PPC_SECTION)
987       && (howto->type != IMAGE_REL_PPC_SECREL16)
988       && (howto->type != IMAGE_REL_PPC_REFHI)
989       && (howto->type != IMAGE_REL_PPC_REFLO)
990       && (howto->type != IMAGE_REL_PPC_PAIR)
991       && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
992 }     
993
994 #if 0
995
996 /* this function is in charge of performing all the ppc PE relocations */
997 /* Don't yet know if we want to do this this particular way ... (krk)  */
998 /* FIXME: (it is not yet enabled) */
999
1000 static bfd_reloc_status_type
1001 pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
1002               error_message)
1003      bfd *abfd;
1004      arelent *reloc_entry;
1005      asymbol *symbol_in;
1006      PTR data;
1007      asection *input_section;
1008      bfd *output_bfd;
1009      char **error_message;
1010 {
1011   /* the consth relocation comes in two parts, we have to remember
1012      the state between calls, in these variables */
1013   static boolean part1_consth_active = false;
1014   static unsigned long part1_consth_value;
1015
1016   unsigned long sym_value;
1017   unsigned short r_type;
1018   unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
1019         
1020   r_type = reloc_entry->howto->type;
1021
1022   if (output_bfd) 
1023     {
1024       /* Partial linking - do nothing */
1025       reloc_entry->address += input_section->output_offset;
1026       return bfd_reloc_ok; 
1027     }
1028
1029   if (symbol_in != NULL
1030       && bfd_is_und_section (symbol_in->section))
1031     {
1032       /* Keep the state machine happy in case we're called again */
1033       if (r_type == IMAGE_REL_PPC_REFHI) 
1034         {
1035           part1_consth_active = true;
1036           part1_consth_value  = 0;
1037         }
1038       return(bfd_reloc_undefined);
1039     }
1040   
1041   if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) 
1042     {
1043       part1_consth_active = false;
1044       *error_message = (char *) "Missing PAIR";
1045       return(bfd_reloc_dangerous);
1046     }
1047
1048
1049   sym_value = get_symbol_value(symbol_in);
1050   
1051   return(bfd_reloc_ok); 
1052 }
1053
1054 #endif /* 0 */
1055
1056 /* The reloc processing routine for the optimized COFF linker.  */
1057
1058 static boolean
1059 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
1060                            contents, relocs, syms, sections)
1061      bfd *output_bfd;
1062      struct bfd_link_info *info;
1063      bfd *input_bfd;
1064      asection *input_section;
1065      bfd_byte *contents;
1066      struct internal_reloc *relocs;
1067      struct internal_syment *syms;
1068      asection **sections;
1069 {
1070   struct internal_reloc *rel;
1071   struct internal_reloc *relend;
1072   boolean hihalf;
1073   bfd_vma hihalf_val;
1074   asection *toc_section = 0;
1075   bfd_vma relocation;
1076   reloc_howto_type *howto = 0;
1077   
1078   /* If we are performing a relocateable link, we don't need to do a
1079      thing.  The caller will take care of adjusting the reloc
1080      addresses and symbol indices.  */
1081   if (info->relocateable)
1082     return true;
1083   
1084   hihalf = false;
1085   hihalf_val = 0;
1086
1087   rel = relocs;
1088   relend = rel + input_section->reloc_count;
1089   for (; rel < relend; rel++)
1090     {
1091       long symndx;
1092       struct ppc_coff_link_hash_entry *h;
1093       struct internal_syment *sym;
1094       bfd_vma val;
1095
1096       asection *sec;
1097       bfd_reloc_status_type rstat;
1098       bfd_byte *loc;
1099
1100       unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
1101       unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1102   
1103       symndx = rel->r_symndx;
1104       loc = contents + rel->r_vaddr - input_section->vma;
1105
1106       /* FIXME: check bounds on r_type */
1107       howto = ppc_coff_howto_table + r_type;
1108
1109       if (symndx == -1)
1110         {
1111           h = NULL;
1112           sym = NULL;
1113         }
1114       else
1115         {
1116           h = (struct ppc_coff_link_hash_entry *) 
1117             (obj_coff_sym_hashes (input_bfd)[symndx]);
1118           if (h != 0) 
1119             {
1120               HASH_CHECK(h);
1121             }
1122
1123           sym = syms + symndx;
1124         }
1125
1126       if (r_type == IMAGE_REL_PPC_IMGLUE && h == 0)
1127         {
1128           /* An IMGLUE reloc must have a name. Something is very wrong. */
1129           abort();
1130         }
1131
1132       sec = NULL;
1133       val = 0;
1134
1135       /* FIXME: PAIR unsupported in the following code */
1136       if (h == NULL)
1137         {
1138           if (symndx == -1)
1139             sec = bfd_abs_section_ptr;
1140           else
1141             {
1142               sec = sections[symndx];
1143               val = (sec->output_section->vma
1144                      + sec->output_offset
1145                      + sym->n_value
1146                      - sec->vma);
1147             }
1148         }
1149       else
1150         {
1151           HASH_CHECK(h);
1152
1153           if (h->root.root.type == bfd_link_hash_defined
1154               || h->root.root.type == bfd_link_hash_defweak)
1155             {
1156               sec = h->root.root.u.def.section;
1157               val = (h->root.root.u.def.value
1158                      + sec->output_section->vma
1159                      + sec->output_offset);
1160             }
1161           else
1162             {
1163               if (! ((*info->callbacks->undefined_symbol)
1164                      (info, h->root.root.root.string, input_bfd, input_section,
1165                       rel->r_vaddr - input_section->vma)))
1166                 return false;
1167             }
1168         }
1169
1170       rstat = bfd_reloc_ok;
1171       
1172       /* Each case must do its own relocation, setting rstat appropriately */
1173       switch (r_type)
1174         {
1175         default:
1176           (*_bfd_error_handler)
1177             ("%s: unsupported relocation type 0x%02x",
1178              bfd_get_filename (input_bfd), r_type);
1179           bfd_set_error (bfd_error_bad_value);
1180           return false;
1181         case IMAGE_REL_PPC_TOCREL16:
1182           {
1183             bfd_vma our_toc_offset;
1184             int fixit;
1185
1186             DUMP_RELOC2(howto->name, rel);
1187
1188             if (toc_section == 0) 
1189               {
1190                 toc_section = bfd_get_section_by_name (bfd_of_toc_owner, 
1191                                                        TOC_SECTION_NAME);
1192
1193                 if ( toc_section == NULL ) 
1194                   {
1195                     /* There is no toc section. Something is very wrong. */
1196                     abort();
1197                   }
1198               }
1199
1200             /* 
1201              *  Amazing bit tricks present. As we may have seen earlier, we
1202              *  use the 1 bit to tell us whether or not a toc offset has been
1203              *  allocated. Now that they've all been allocated, we will use
1204              *  the 1 bit to tell us if we've written this particular toc
1205              *  entry out.
1206              */
1207             fixit = false;
1208             if (h == 0)
1209               { /* it is a file local symbol */
1210                 int *local_toc_table;
1211                 const char *name;
1212
1213                 sym = syms + symndx;
1214                 name = sym->_n._n_name;
1215
1216                 local_toc_table = obj_coff_local_toc_table(input_bfd);
1217                 our_toc_offset = local_toc_table[symndx];
1218
1219                 if (IS_WRITTEN(our_toc_offset))
1220                   {
1221                     /* if it has been written out, it is marked with the 
1222                        1 bit. Fix up our offset, but do not write it out
1223                        again.
1224                      */
1225                     MAKE_ADDR_AGAIN(our_toc_offset);
1226                   }
1227                 else
1228                   {
1229                     /* write out the toc entry */
1230                     record_toc(toc_section, 
1231                                our_toc_offset, 
1232                                priv, 
1233                                strdup(name));
1234
1235                     bfd_put_32(output_bfd,
1236                                val,
1237                                toc_section->contents + our_toc_offset);
1238
1239                     MARK_AS_WRITTEN(local_toc_table[symndx]);
1240                     fixit = true;
1241                   }
1242               }
1243             else
1244               {
1245                 const char *name = h->root.root.root.string;
1246                 our_toc_offset = h->toc_offset;
1247
1248                 if ((r_flags & IMAGE_REL_PPC_TOCDEFN) 
1249                     == IMAGE_REL_PPC_TOCDEFN )
1250                   {
1251                     /* This is unbelievable cheese. Some knowledgable asm 
1252                        hacker has decided to use r2 as a base for loading 
1253                        a value. He/She does this by setting the tocdefn bit, 
1254                        and not supplying a toc definition. The behaviour is 
1255                        then to use the difference between the value of the 
1256                        symbol and the actual location of the toc as the toc 
1257                        index. 
1258
1259                        In fact, what is usually happening is, because the
1260                        Import Address Table is mapped immediately following
1261                        the toc, some trippy library code trying for speed on
1262                        dll linkage, takes advantage of that and considers 
1263                        the IAT to be part of the toc, thus saving a load.
1264                     */
1265
1266                     our_toc_offset = val - 
1267                       (toc_section->output_section->vma + 
1268                        toc_section->output_offset);
1269
1270                     /* The size must still fit in a 16bit displacment */
1271                     if (our_toc_offset >= 65535)
1272                       {
1273                         (*_bfd_error_handler)
1274                           ("%s: Relocation for %s of %x exceeds Toc size limit", 
1275                            bfd_get_filename (input_bfd), name, our_toc_offset);
1276                         bfd_set_error (bfd_error_bad_value);
1277                         return false;
1278                       }
1279
1280                     record_toc(toc_section, our_toc_offset, pub, strdup(name));
1281                   }
1282                 else if (IS_WRITTEN(our_toc_offset))
1283                   {
1284                     /* if it has been written out, it is marked with the 
1285                        1 bit. Fix up our offset, but do not write it out
1286                        again.
1287                      */
1288                     MAKE_ADDR_AGAIN(our_toc_offset);
1289                   }
1290                 else
1291                   {
1292                     record_toc(toc_section, our_toc_offset, pub, strdup(name));
1293
1294                     /* write out the toc entry */
1295                     bfd_put_32(output_bfd,
1296                                val,
1297                                toc_section->contents + our_toc_offset);
1298
1299                     MARK_AS_WRITTEN(h->toc_offset);
1300                     /* The tricky part is that this is the address that */
1301                     /* needs a .reloc entry for it */
1302                     fixit = true;
1303                   }
1304               }
1305
1306             if (fixit && info->base_file) 
1307               {
1308                 /* So if this is non pcrelative, and is referenced
1309                    to a section or a common symbol, then it needs a reloc */
1310
1311                 /* relocation to a symbol in a section which
1312                    isn't absolute - we output the address here 
1313                    to a file */
1314
1315                 bfd_vma addr =  toc_section->output_section->vma
1316                   + toc_section->output_offset + our_toc_offset;
1317                     
1318                 if (coff_data(output_bfd)->pe)
1319                   addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1320
1321                 fwrite (&addr, 1,4, (FILE *) info->base_file);
1322               }
1323
1324
1325             /* FIXME: this test is conservative */
1326             if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&
1327                 our_toc_offset > toc_section->_raw_size)
1328               {
1329                 (*_bfd_error_handler)
1330                   ("%s: Relocation exceeds allocated TOC (%x)", 
1331                    bfd_get_filename (input_bfd),
1332                    toc_section->_raw_size);
1333                 bfd_set_error (bfd_error_bad_value);
1334                 return false;
1335               }
1336
1337             /* Now we know the relocation for this toc reference */
1338             relocation =  our_toc_offset + TOC_LOAD_ADJUSTMENT;
1339             rstat = _bfd_relocate_contents (howto,
1340                                             input_bfd, 
1341                                             relocation, 
1342                                             loc);
1343           }
1344           break;
1345         case IMAGE_REL_PPC_IFGLUE:
1346           {
1347             /* To solve this, we need to know whether or not the symbol */
1348             /* appearing on the call instruction is a glue function or not. */
1349             /* A glue function must announce itself via a IMGLUE reloc, and */
1350             /* the reloc contains the required toc restore instruction */
1351           
1352             bfd_vma x;
1353             const char *my_name;
1354             DUMP_RELOC2(howto->name, rel);
1355
1356             if (h != 0)
1357               {
1358                 my_name = h->root.root.root.string;
1359                 if (h->symbol_is_glue == 1) 
1360                   {
1361                     x = bfd_get_32(input_bfd, loc);
1362                     bfd_put_32(input_bfd, h->glue_insn, loc);
1363                   }
1364               }
1365           }
1366           break;
1367         case IMAGE_REL_PPC_SECREL:
1368           /* Unimplemented: codeview debugging information */
1369           /* For fast access to the header of the section 
1370              containing the item. */
1371           break;
1372         case IMAGE_REL_PPC_SECTION:
1373           /* Unimplemented: codeview debugging information */
1374           /* Is used to indicate that the value should be relative
1375              to the beginning of the section that contains the
1376              symbol */
1377           break;
1378         case IMAGE_REL_PPC_ABSOLUTE:
1379           {
1380             const char *my_name;
1381             if (h == 0)
1382                 my_name = (syms+symndx)->_n._n_name;
1383             else
1384               {
1385                 my_name = h->root.root.root.string;
1386               }
1387
1388             fprintf(stderr, 
1389                     "Warning: unsupported reloc %s <file %s, section %s>\n", 
1390                     howto->name,
1391                     bfd_get_filename(input_bfd),
1392                     input_section->name);
1393
1394             fprintf(stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", 
1395                     rel->r_symndx, my_name, (long) rel->r_vaddr,
1396                     (unsigned long) rel->r_vaddr);  
1397           }
1398           break;
1399         case IMAGE_REL_PPC_IMGLUE:
1400           {
1401             /* There is nothing to do now. This reloc was noted in the first
1402                pass over the relocs, and the glue instruction extracted */
1403             const char *my_name;
1404             if (h->symbol_is_glue == 1) 
1405               break;
1406             my_name = h->root.root.root.string;
1407
1408             (*_bfd_error_handler)
1409               ("%s: Out of order IMGLUE reloc for %s", 
1410                bfd_get_filename (input_bfd), my_name);
1411             bfd_set_error (bfd_error_bad_value);
1412             return false;
1413           }
1414
1415         case IMAGE_REL_PPC_ADDR32NB:
1416           {
1417             struct coff_link_hash_entry *myh = 0;
1418             const char *name = 0;
1419             DUMP_RELOC2(howto->name, rel);
1420
1421             if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
1422               {
1423                 /* set magic values */
1424                 int idata5offset;
1425                 struct coff_link_hash_entry *myh = 0;
1426                 myh = coff_link_hash_lookup (coff_hash_table (info),
1427                                              "__idata5_magic__",
1428                                              false, false, true);
1429                 first_thunk_address = myh->root.u.def.value + 
1430                   sec->output_section->vma + 
1431                     sec->output_offset - 
1432                       pe_data(output_bfd)->pe_opthdr.ImageBase;
1433                 
1434                 idata5offset = myh->root.u.def.value;
1435                 myh = coff_link_hash_lookup (coff_hash_table (info),
1436                                              "__idata6_magic__",
1437                                              false, false, true);
1438                 
1439                 thunk_size = myh->root.u.def.value - idata5offset;
1440                 myh = coff_link_hash_lookup (coff_hash_table (info),
1441                                              "__idata4_magic__",
1442                                              false, false, true);
1443                 import_table_size = myh->root.u.def.value;
1444               }
1445
1446             if (h == 0)
1447               { /* it is a file local symbol */
1448                 sym = syms + symndx;
1449                 name = sym->_n._n_name;
1450               }
1451             else
1452               {
1453                 char *target = 0;
1454
1455                 name = h->root.root.root.string;
1456                 if (strcmp(".idata$2", name) == 0)
1457                   target = "__idata2_magic__";
1458                 else if (strcmp(".idata$4", name) == 0)
1459                   target = "__idata4_magic__";
1460                 else if (strcmp(".idata$5", name) == 0)
1461                   target = "__idata5_magic__";
1462
1463                 if (target != 0)
1464                   {
1465                     myh = 0;
1466
1467                     myh = coff_link_hash_lookup (coff_hash_table (info),
1468                                                  target,
1469                                                  false, false, true);
1470                     if (myh == 0) 
1471                       {
1472                         /* Missing magic cookies. Something is very wrong. */
1473                         abort();
1474                       }
1475                     
1476                     val = myh->root.u.def.value + 
1477                       sec->output_section->vma + sec->output_offset;
1478                     if (first_thunk_address == 0)
1479                       {
1480                         int idata5offset;
1481                         myh = coff_link_hash_lookup (coff_hash_table (info),
1482                                                      "__idata5_magic__",
1483                                                      false, false, true);
1484                         first_thunk_address = myh->root.u.def.value + 
1485                           sec->output_section->vma + 
1486                             sec->output_offset - 
1487                               pe_data(output_bfd)->pe_opthdr.ImageBase;
1488                         
1489                         idata5offset = myh->root.u.def.value;
1490                         myh = coff_link_hash_lookup (coff_hash_table (info),
1491                                                      "__idata6_magic__",
1492                                                      false, false, true);
1493                         
1494                         thunk_size = myh->root.u.def.value - idata5offset;
1495                         myh = coff_link_hash_lookup (coff_hash_table (info),
1496                                                      "__idata4_magic__",
1497                                                      false, false, true);
1498                         import_table_size = myh->root.u.def.value;
1499                       }
1500                   }
1501               }
1502
1503             rstat = _bfd_relocate_contents (howto,
1504                               input_bfd, 
1505                               val - 
1506                               pe_data(output_bfd)->pe_opthdr.ImageBase,
1507                               loc);
1508           }
1509           break;
1510
1511         case IMAGE_REL_PPC_REL24:
1512           DUMP_RELOC2(howto->name, rel);
1513           val -= (input_section->output_section->vma
1514                   + input_section->output_offset);
1515
1516           rstat = _bfd_relocate_contents (howto,
1517                                           input_bfd, 
1518                                           val, 
1519                                           loc);
1520           break;
1521         case IMAGE_REL_PPC_ADDR16:
1522         case IMAGE_REL_PPC_ADDR24:
1523         case IMAGE_REL_PPC_ADDR32:
1524           DUMP_RELOC2(howto->name, rel);
1525           rstat = _bfd_relocate_contents (howto,
1526                                           input_bfd, 
1527                                           val, 
1528                                           loc);
1529           break;
1530         }
1531
1532       if ( info->base_file )
1533         {
1534           /* So if this is non pcrelative, and is referenced
1535              to a section or a common symbol, then it needs a reloc */
1536           if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1537             {
1538               /* relocation to a symbol in a section which
1539                  isn't absolute - we output the address here 
1540                  to a file */
1541               bfd_vma addr = rel->r_vaddr 
1542                 - input_section->vma 
1543                 + input_section->output_offset 
1544                   + input_section->output_section->vma;
1545
1546               if (coff_data(output_bfd)->pe)
1547                 {
1548                   addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1549                 }
1550               fwrite (&addr, 1,4, (FILE *) info->base_file);
1551             }
1552         }
1553
1554       switch (rstat)
1555         {
1556         default:
1557           abort ();
1558         case bfd_reloc_ok:
1559           break;
1560         case bfd_reloc_overflow:
1561           {
1562             const char *name;
1563             char buf[SYMNMLEN + 1];
1564
1565             if (symndx == -1)
1566               name = "*ABS*";
1567             else if (h != NULL)
1568               name = h->root.root.root.string;
1569             else if (sym == NULL)
1570               name = "*unknown*";
1571             else if (sym->_n._n_n._n_zeroes == 0
1572                      && sym->_n._n_n._n_offset != 0)
1573               name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
1574             else
1575               {
1576                 strncpy (buf, sym->_n._n_name, SYMNMLEN);
1577                 buf[SYMNMLEN] = '\0';
1578                 name = buf;
1579               }
1580
1581             if (! ((*info->callbacks->reloc_overflow)
1582                    (info, name, howto->name, 
1583                     (bfd_vma) 0, input_bfd,
1584                     input_section, rel->r_vaddr - input_section->vma)))
1585               {
1586                 return false;
1587               }
1588           }
1589         }
1590
1591     }     
1592
1593   return true;
1594 }
1595
1596
1597 #ifdef COFF_IMAGE_WITH_PE
1598
1599 long int global_toc_size = 4;
1600
1601 bfd* bfd_of_toc_owner = 0;
1602
1603 long int import_table_size;
1604 long int first_thunk_address;
1605 long int thunk_size;
1606
1607 struct list_ele *head;
1608 struct list_ele *tail;
1609
1610 static char *
1611 h1 = "\n\t\t\tTOC MAPPING\n\n";
1612 static char *
1613 h2 = " TOC    disassembly  Comments       Name\n";
1614 static char *
1615 h3 = " Offset  spelling                   (if present)\n";
1616
1617 void
1618 dump_toc(vfile)
1619      void *vfile;
1620 {
1621   FILE *file = vfile;
1622   struct list_ele *t;
1623
1624   fprintf(file, h1);
1625   fprintf(file, h2);
1626   fprintf(file, h3);
1627
1628   for(t = head; t != 0; t=t->next)
1629     {
1630       char *cat;
1631
1632       if (t->cat == priv)
1633         cat = "private       ";
1634       else if (t->cat == pub)
1635         cat = "public        ";
1636       else if (t->cat == data)
1637         cat = "data-in-toc   ";
1638
1639       if (t->offset > global_toc_size)
1640         {
1641           if (t->offset <= global_toc_size + thunk_size)
1642             cat = "IAT reference ";
1643           else
1644             {
1645               fprintf(file,
1646                       "**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n",
1647                       global_toc_size, global_toc_size, thunk_size, thunk_size);
1648               cat = "Out of bounds!";
1649             }
1650         }
1651
1652       fprintf(file,
1653               " %04lx    (%d)", (unsigned long) t->offset, t->offset - 32768);
1654       fprintf(file,
1655               "    %s %s\n",
1656               cat, t->name);
1657
1658     }
1659
1660   fprintf(file, "\n");
1661 }
1662
1663 boolean
1664 ppc_allocate_toc_section (info) 
1665      struct bfd_link_info *info;
1666 {
1667   asection *s;
1668   bfd_byte *foo;
1669   static char test_char = '1';
1670
1671   if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
1672     return true;
1673
1674   if (bfd_of_toc_owner == 0)
1675     {
1676       /* No toc owner? Something is very wrong. */
1677       abort();
1678     }
1679
1680   s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
1681   if (s == NULL) 
1682     {
1683       /* No toc section? Something is very wrong. */
1684       abort();
1685     }
1686
1687   foo = (bfd_byte *) bfd_alloc(bfd_of_toc_owner, global_toc_size);
1688   memset(foo, test_char, global_toc_size);
1689
1690   s->_raw_size = s->_cooked_size = global_toc_size;
1691   s->contents = foo;
1692
1693   return true;
1694 }
1695
1696 boolean
1697 ppc_process_before_allocation (abfd, info)
1698      bfd *abfd;
1699      struct bfd_link_info *info;
1700 {
1701   asection *sec;
1702   struct internal_reloc *i, *rel;
1703
1704   /* here we have a bfd that is to be included on the link. We have a hook
1705      to do reloc rummaging, before section sizes are nailed down. */
1706
1707   _bfd_coff_get_external_symbols(abfd);
1708
1709   /* rummage around all the relocs and map the toc */
1710   sec = abfd->sections;
1711
1712   if (sec == 0)
1713     {
1714       return true;
1715     }
1716
1717   for (; sec != 0; sec = sec->next)
1718   {
1719     if (sec->reloc_count == 0) 
1720       continue;
1721
1722     /* load the relocs */
1723     /* FIXME: there may be a storage leak here */
1724     i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
1725     
1726     if (i == 0)
1727       abort();
1728
1729     for (rel=i;rel<i+sec->reloc_count;++rel) 
1730       {
1731         unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
1732         unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1733         boolean ok = true;
1734
1735         DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1736
1737         switch(r_type) 
1738           {
1739           case IMAGE_REL_PPC_TOCREL16:
1740             /* if TOCDEFN is on, ignore as someone else has allocated the
1741                toc entry */
1742             if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN )
1743               ok = ppc_record_toc_entry(abfd, info, sec, 
1744                                         rel->r_symndx, default_toc);
1745             if (!ok)
1746               return false;
1747             break;
1748           case IMAGE_REL_PPC_IMGLUE:
1749             ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
1750             break;
1751           default:
1752             break;
1753           }
1754       }
1755   }
1756
1757   return true;
1758 }
1759
1760 #endif
1761
1762
1763 static bfd_reloc_status_type
1764 ppc_refhi_reloc (abfd,
1765                  reloc_entry,
1766                  symbol,
1767                  data,
1768                  input_section,
1769                  output_bfd,
1770                  error_message)
1771      bfd *abfd;
1772      arelent *reloc_entry;
1773      asymbol *symbol;
1774      PTR data;
1775      asection *input_section;
1776      bfd *output_bfd;
1777      char **error_message;
1778 {
1779   UN_IMPL("REFHI");
1780   DUMP_RELOC("REFHI",reloc_entry);
1781
1782   if (output_bfd == (bfd *) NULL)
1783     return bfd_reloc_continue;
1784
1785   return bfd_reloc_undefined;
1786 }
1787
1788 #if 0
1789
1790 static bfd_reloc_status_type
1791 ppc_reflo_reloc (abfd,
1792                  reloc_entry,
1793                  symbol,
1794                  data,
1795                  input_section,
1796                  output_bfd,
1797                  error_message)
1798      bfd *abfd;
1799      arelent *reloc_entry;
1800      asymbol *symbol;
1801      PTR data;
1802      asection *input_section;
1803      bfd *output_bfd;
1804      char **error_message;
1805 {
1806   UN_IMPL("REFLO");
1807   DUMP_RELOC("REFLO",reloc_entry);
1808
1809   if (output_bfd == (bfd *) NULL)
1810     return bfd_reloc_continue;
1811
1812   return bfd_reloc_undefined;
1813 }
1814
1815 #endif
1816
1817 static bfd_reloc_status_type
1818 ppc_pair_reloc (abfd,
1819                 reloc_entry,
1820                 symbol,
1821                 data,
1822                 input_section,
1823                 output_bfd,
1824                 error_message)
1825      bfd *abfd;
1826      arelent *reloc_entry;
1827      asymbol *symbol;
1828      PTR data;
1829      asection *input_section;
1830      bfd *output_bfd;
1831      char **error_message;
1832 {
1833   UN_IMPL("PAIR");
1834   DUMP_RELOC("PAIR",reloc_entry);
1835
1836   if (output_bfd == (bfd *) NULL)
1837     return bfd_reloc_continue;
1838
1839   return bfd_reloc_undefined;
1840 }
1841
1842 \f
1843 static bfd_reloc_status_type
1844 ppc_toc16_reloc (abfd,
1845                  reloc_entry,
1846                  symbol,
1847                  data,
1848                  input_section,
1849                  output_bfd,
1850                  error_message)
1851      bfd *abfd;
1852      arelent *reloc_entry;
1853      asymbol *symbol;
1854      PTR data;
1855      asection *input_section;
1856      bfd *output_bfd;
1857      char **error_message;
1858 {
1859   UN_IMPL("TOCREL16");
1860   DUMP_RELOC("TOCREL16",reloc_entry);
1861
1862   if (output_bfd == (bfd *) NULL)
1863     {
1864       return bfd_reloc_continue;
1865     }
1866
1867   return bfd_reloc_ok;
1868 }
1869
1870 #if 0
1871
1872 /* ADDR32NB : 32 bit address relative to the virtual origin.         */
1873 /*            (On the alpha, this is always a linker generated thunk)*/
1874 /*            (i.e. 32bit addr relative to the image base)           */
1875 /*                                                                   */
1876 /*                                                                   */
1877
1878 static bfd_reloc_status_type
1879 ppc_addr32nb_reloc (abfd,
1880                     reloc_entry,
1881                     symbol,
1882                     data,
1883                     input_section,
1884                     output_bfd,
1885                     error_message)
1886      bfd *abfd;
1887      arelent *reloc_entry;
1888      asymbol *symbol;
1889      PTR data;
1890      asection *input_section;
1891      bfd *output_bfd;
1892      char **error_message;
1893 {
1894   UN_IMPL("ADDR32NB");
1895   DUMP_RELOC("ADDR32NB",reloc_entry);
1896
1897   return bfd_reloc_ok;
1898 }
1899
1900 #endif
1901
1902 static bfd_reloc_status_type
1903 ppc_secrel_reloc (abfd,
1904                   reloc_entry,
1905                   symbol,
1906                   data,
1907                   input_section,
1908                   output_bfd,
1909                   error_message)
1910      bfd *abfd;
1911      arelent *reloc_entry;
1912      asymbol *symbol;
1913      PTR data;
1914      asection *input_section;
1915      bfd *output_bfd;
1916      char **error_message;
1917 {
1918   UN_IMPL("SECREL");
1919   DUMP_RELOC("SECREL",reloc_entry);
1920
1921   if (output_bfd == (bfd *) NULL)
1922     return bfd_reloc_continue;
1923
1924   return bfd_reloc_ok;
1925 }
1926
1927 static bfd_reloc_status_type
1928 ppc_section_reloc (abfd,
1929                    reloc_entry,
1930                    symbol,
1931                    data,
1932                    input_section,
1933                    output_bfd,
1934                    error_message)
1935      bfd *abfd;
1936      arelent *reloc_entry;
1937      asymbol *symbol;
1938      PTR data;
1939      asection *input_section;
1940      bfd *output_bfd;
1941      char **error_message;
1942 {
1943   UN_IMPL("SECTION");
1944   DUMP_RELOC("SECTION",reloc_entry);
1945
1946   if (output_bfd == (bfd *) NULL)
1947     return bfd_reloc_continue;
1948
1949   return bfd_reloc_ok;
1950 }
1951
1952 static bfd_reloc_status_type
1953 ppc_imglue_reloc (abfd,
1954                   reloc_entry,
1955                   symbol,
1956                   data,
1957                   input_section,
1958                   output_bfd,
1959                   error_message)
1960      bfd *abfd;
1961      arelent *reloc_entry;
1962      asymbol *symbol;
1963      PTR data;
1964      asection *input_section;
1965      bfd *output_bfd;
1966      char **error_message;
1967 {
1968   UN_IMPL("IMGLUE");
1969   DUMP_RELOC("IMGLUE",reloc_entry);
1970
1971   if (output_bfd == (bfd *) NULL)
1972     return bfd_reloc_continue;
1973
1974   return bfd_reloc_ok;
1975 }
1976
1977 \f
1978
1979 #define MAX_RELOC_INDEX  \
1980       (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
1981
1982
1983 /* FIXME: There is a possiblity that when we read in a reloc from a file,
1984           that there are some bits encoded in the upper portion of the 
1985           type field. Not yet implemented.
1986 */
1987 static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
1988                                           struct internal_reloc *internal));
1989
1990 static void
1991 ppc_coff_rtype2howto (relent, internal)
1992      arelent *relent;
1993      struct internal_reloc *internal;
1994 {  
1995
1996   /* We can encode one of three things in the type field, aside from the
1997      type:
1998      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
1999         value, rather than an addition value
2000      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2001         the branch is expected to be taken or not.
2002      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2003      For now, we just strip this stuff to find the type, and ignore it other
2004      than that.
2005   */
2006   reloc_howto_type *howto;
2007   unsigned short r_type  = EXTRACT_TYPE (internal->r_type);
2008   unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
2009   unsigned short junk    = EXTRACT_JUNK (internal->r_type);
2010
2011   /* the masking process only slices off the bottom byte for r_type. */
2012   if ( r_type > MAX_RELOC_INDEX ) 
2013     abort();
2014
2015   /* check for absolute crap */
2016   if ( junk != 0 )
2017     abort();
2018
2019   switch(r_type) 
2020     {
2021     case IMAGE_REL_PPC_ADDR16:
2022     case IMAGE_REL_PPC_REL24:
2023     case IMAGE_REL_PPC_ADDR24:
2024     case IMAGE_REL_PPC_ADDR32:
2025     case IMAGE_REL_PPC_IFGLUE:
2026     case IMAGE_REL_PPC_ADDR32NB:
2027     case IMAGE_REL_PPC_SECTION:
2028     case IMAGE_REL_PPC_SECREL:
2029       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2030       howto = ppc_coff_howto_table + r_type;
2031       break;
2032     case IMAGE_REL_PPC_IMGLUE:
2033       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2034       howto = ppc_coff_howto_table + r_type;
2035       break;
2036     case IMAGE_REL_PPC_TOCREL16:
2037       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2038       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2039         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2040       else
2041         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
2042       break;
2043     default:
2044       fprintf(stderr, 
2045               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2046               ppc_coff_howto_table[r_type].name,
2047               r_type);
2048       howto = ppc_coff_howto_table + r_type;      
2049       break;
2050     }
2051   
2052   relent->howto = howto;
2053   
2054 }
2055
2056 static reloc_howto_type *
2057 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
2058      bfd *abfd;
2059      asection *sec;
2060      struct internal_reloc *rel;
2061      struct coff_link_hash_entry *h;
2062      struct internal_syment *sym;
2063      bfd_vma *addendp;
2064 {
2065   reloc_howto_type *howto;
2066
2067   /* We can encode one of three things in the type field, aside from the
2068      type:
2069      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2070         value, rather than an addition value
2071      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2072         the branch is expected to be taken or not.
2073      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2074      For now, we just strip this stuff to find the type, and ignore it other
2075      than that.
2076   */
2077
2078   unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
2079   unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2080   unsigned short junk    = EXTRACT_JUNK (rel->r_type);
2081
2082   /* the masking process only slices off the bottom byte for r_type. */
2083   if ( r_type > MAX_RELOC_INDEX ) 
2084     abort();
2085   
2086   /* check for absolute crap */
2087   if ( junk != 0 )
2088     abort();
2089     
2090   switch(r_type) 
2091     {
2092     case IMAGE_REL_PPC_ADDR32NB:
2093       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2094       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
2095       howto = ppc_coff_howto_table + r_type;
2096       break;
2097     case IMAGE_REL_PPC_TOCREL16:
2098       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2099       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2100         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2101       else
2102         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
2103       break;
2104     case IMAGE_REL_PPC_ADDR16:
2105     case IMAGE_REL_PPC_REL24:
2106     case IMAGE_REL_PPC_ADDR24:
2107     case IMAGE_REL_PPC_ADDR32:
2108     case IMAGE_REL_PPC_IFGLUE:
2109     case IMAGE_REL_PPC_SECTION:
2110     case IMAGE_REL_PPC_SECREL:
2111       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2112       howto = ppc_coff_howto_table + r_type;
2113       break;
2114     case IMAGE_REL_PPC_IMGLUE:
2115       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2116       howto = ppc_coff_howto_table + r_type;
2117       break;
2118     default:
2119       fprintf(stderr, 
2120               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2121               ppc_coff_howto_table[r_type].name,
2122               r_type);
2123       howto = ppc_coff_howto_table + r_type;
2124       break;
2125     }
2126   
2127   return howto;
2128 }
2129
2130
2131 /* a cheesy little macro to make the code a little more readable */
2132 #define HOW2MAP(bfd_rtype,ppc_rtype)  \
2133  case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
2134
2135 static reloc_howto_type *ppc_coff_reloc_type_lookup
2136 PARAMS ((bfd *, bfd_reloc_code_real_type));
2137
2138 static reloc_howto_type *
2139 ppc_coff_reloc_type_lookup (abfd, code)
2140      bfd *abfd;
2141      bfd_reloc_code_real_type code;
2142 {
2143   switch (code)
2144     {
2145       HOW2MAP(BFD_RELOC_32_GOTOFF,    IMAGE_REL_PPC_IMGLUE);
2146       HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
2147       HOW2MAP(BFD_RELOC_16,           IMAGE_REL_PPC_ADDR16);
2148       HOW2MAP(BFD_RELOC_PPC_B26,      IMAGE_REL_PPC_REL24);
2149       HOW2MAP(BFD_RELOC_PPC_BA26,     IMAGE_REL_PPC_ADDR24);
2150       HOW2MAP(BFD_RELOC_PPC_TOC16,    IMAGE_REL_PPC_TOCREL16);
2151       HOW2MAP(BFD_RELOC_16_GOTOFF,    IMAGE_REL_PPC_TOCREL16_DEFN);
2152       HOW2MAP(BFD_RELOC_32,           IMAGE_REL_PPC_ADDR32);
2153       HOW2MAP(BFD_RELOC_RVA,          IMAGE_REL_PPC_ADDR32NB);
2154     default: 
2155       return NULL;
2156     }
2157   /*NOTREACHED*/
2158 }
2159
2160 #undef HOW2MAP
2161
2162 \f
2163 /* Tailor coffcode.h -- macro heaven. */
2164
2165 #define RTYPE2HOWTO(cache_ptr, dst)  ppc_coff_rtype2howto (cache_ptr, dst)
2166
2167 #ifndef COFF_IMAGE_WITH_PE
2168 static void
2169 ppc_coff_swap_sym_in_hook ();
2170 #endif
2171
2172 /* We use the special COFF backend linker, with our own special touch.  */
2173
2174 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
2175 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
2176 #define coff_relocate_section        coff_ppc_relocate_section
2177 #define coff_bfd_final_link          ppc_bfd_coff_final_link 
2178
2179 #ifndef COFF_IMAGE_WITH_PE
2180 #define coff_swap_sym_in_hook        ppc_coff_swap_sym_in_hook
2181 #endif
2182
2183 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
2184
2185 #define COFF_PAGE_SIZE                       0x1000
2186
2187 #define POWERPC_LE_PE
2188
2189 #include "coffcode.h"
2190
2191 \f
2192
2193 #ifndef COFF_IMAGE_WITH_PE
2194 /* FIXME:
2195    What we're trying to do here is allocate a toc section (early), and attach 
2196    it to the last bfd to be processed. This avoids the problem of having a toc
2197    written out before all files have been processed. This code allocates
2198    a toc section for every file, and records the last one seen. There are
2199    at least two problems with this approach:
2200    1. We allocate whole bunches of toc sections that are ignored, but at
2201       at least we will not allocate a toc if no .toc is present.
2202    2. It's not clear to me that being the last bfd read necessarily means
2203       that you are the last bfd closed.
2204    3. Doing it on a "swap in" hook depends on when the "swap in" is called,
2205       and how often, etc. It's not clear to me that there isn't a hole here.
2206 */
2207
2208 static void
2209 ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
2210      bfd            *abfd;
2211      PTR ext1;
2212      PTR in1;
2213 {
2214   struct internal_syment      *in = (struct internal_syment *)in1;
2215
2216   if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
2217     return;
2218
2219   if (strcmp(in->_n._n_name, ".toc") == 0)
2220     {
2221       flagword flags;
2222       register asection *s;
2223
2224       s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
2225       if (s != NULL) 
2226         {
2227           return;
2228         }
2229
2230       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2231
2232       s = bfd_make_section (abfd, TOC_SECTION_NAME);
2233
2234       if (s == NULL
2235           || !bfd_set_section_flags (abfd, s, flags)
2236           || !bfd_set_section_alignment (abfd, s, 2))
2237         {
2238           /* FIXME: set appropriate bfd error */
2239           abort();
2240         }
2241
2242       /* save the bfd for later allocation */
2243       bfd_of_toc_owner = abfd;
2244     }
2245
2246   return;
2247 }
2248 #endif
2249
2250 boolean
2251 ppc_bfd_coff_final_link ();
2252
2253 #ifndef COFF_IMAGE_WITH_PE
2254
2255 static boolean
2256 ppc_do_last(abfd)
2257      bfd *abfd;
2258 {
2259   if (abfd == bfd_of_toc_owner)
2260     return true;
2261   else
2262     return false;
2263 }
2264
2265 static bfd *
2266 ppc_get_last()
2267 {
2268   return bfd_of_toc_owner;
2269 }
2270
2271 /* this piece of machinery exists only to guarantee that the bfd that holds
2272    the toc section is written last. 
2273
2274    This does depend on bfd_make_section attaching a new section to the
2275    end of the section list for the bfd. 
2276
2277    This is otherwise intended to be functionally the same as 
2278    cofflink.c:_bfd_coff_final_link(). It is specifically different only 
2279    where the POWERPC_LE_PE macro modifies the code. It is left in as a 
2280    precise form of comment. krk@cygnus.com
2281 */
2282 #define POWERPC_LE_PE
2283
2284
2285 /* Do the final link step.  */
2286
2287 boolean
2288 ppc_bfd_coff_final_link (abfd, info)
2289      bfd *abfd;
2290      struct bfd_link_info *info;
2291 {
2292   bfd_size_type symesz;
2293   struct coff_final_link_info finfo;
2294   boolean debug_merge_allocated;
2295   asection *o;
2296   struct bfd_link_order *p;
2297   size_t max_sym_count;
2298   size_t max_lineno_count;
2299   size_t max_reloc_count;
2300   size_t max_output_reloc_count;
2301   size_t max_contents_size;
2302   file_ptr rel_filepos;
2303   unsigned int relsz;
2304   file_ptr line_filepos;
2305   unsigned int linesz;
2306   bfd *sub;
2307   bfd_byte *external_relocs = NULL;
2308   char strbuf[STRING_SIZE_SIZE];
2309
2310   symesz = bfd_coff_symesz (abfd);
2311
2312   finfo.info = info;
2313   finfo.output_bfd = abfd;
2314   finfo.strtab = NULL;
2315   finfo.section_info = NULL;
2316   finfo.last_file_index = -1;
2317   finfo.last_bf_index = -1;
2318   finfo.internal_syms = NULL;
2319   finfo.sec_ptrs = NULL;
2320   finfo.sym_indices = NULL;
2321   finfo.outsyms = NULL;
2322   finfo.linenos = NULL;
2323   finfo.contents = NULL;
2324   finfo.external_relocs = NULL;
2325   finfo.internal_relocs = NULL;
2326   debug_merge_allocated = false;
2327
2328   coff_data (abfd)->link_info = info;
2329
2330   finfo.strtab = _bfd_stringtab_init ();
2331   if (finfo.strtab == NULL)
2332     goto error_return;
2333
2334   if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
2335     goto error_return;
2336   debug_merge_allocated = true;
2337
2338   /* Compute the file positions for all the sections.  */
2339   if (! abfd->output_has_begun)
2340     {
2341       if (! bfd_coff_compute_section_file_positions (abfd))
2342         return false;
2343     }
2344
2345   /* Count the line numbers and relocation entries required for the
2346      output file.  Set the file positions for the relocs.  */
2347   rel_filepos = obj_relocbase (abfd);
2348   relsz = bfd_coff_relsz (abfd);
2349   max_contents_size = 0;
2350   max_lineno_count = 0;
2351   max_reloc_count = 0;
2352
2353   for (o = abfd->sections; o != NULL; o = o->next)
2354     {
2355       o->reloc_count = 0;
2356       o->lineno_count = 0;
2357       for (p = o->link_order_head; p != NULL; p = p->next)
2358         {
2359
2360           if (p->type == bfd_indirect_link_order)
2361             {
2362               asection *sec;
2363
2364               sec = p->u.indirect.section;
2365
2366               /* Mark all sections which are to be included in the
2367                  link.  This will normally be every section.  We need
2368                  to do this so that we can identify any sections which
2369                  the linker has decided to not include.  */
2370               sec->linker_mark = true;
2371
2372               if (info->strip == strip_none
2373                   || info->strip == strip_some)
2374                 o->lineno_count += sec->lineno_count;
2375
2376               if (info->relocateable)
2377                 o->reloc_count += sec->reloc_count;
2378
2379               if (sec->_raw_size > max_contents_size)
2380                 max_contents_size = sec->_raw_size;
2381               if (sec->lineno_count > max_lineno_count)
2382                 max_lineno_count = sec->lineno_count;
2383               if (sec->reloc_count > max_reloc_count)
2384                 max_reloc_count = sec->reloc_count;
2385             }
2386           else if (info->relocateable
2387                    && (p->type == bfd_section_reloc_link_order
2388                        || p->type == bfd_symbol_reloc_link_order))
2389             ++o->reloc_count;
2390         }
2391       if (o->reloc_count == 0)
2392         o->rel_filepos = 0;
2393       else
2394         {
2395           o->flags |= SEC_RELOC;
2396           o->rel_filepos = rel_filepos;
2397           rel_filepos += o->reloc_count * relsz;
2398         }
2399     }
2400
2401   /* If doing a relocateable link, allocate space for the pointers we
2402      need to keep.  */
2403   if (info->relocateable)
2404     {
2405       unsigned int i;
2406
2407       /* We use section_count + 1, rather than section_count, because
2408          the target_index fields are 1 based.  */
2409       finfo.section_info =
2410         ((struct coff_link_section_info *)
2411          bfd_malloc ((abfd->section_count + 1)
2412                      * sizeof (struct coff_link_section_info)));
2413       if (finfo.section_info == NULL)
2414         goto error_return;
2415       for (i = 0; i <= abfd->section_count; i++)
2416         {
2417           finfo.section_info[i].relocs = NULL;
2418           finfo.section_info[i].rel_hashes = NULL;
2419         }
2420     }
2421
2422   /* We now know the size of the relocs, so we can determine the file
2423      positions of the line numbers.  */
2424   line_filepos = rel_filepos;
2425   linesz = bfd_coff_linesz (abfd);
2426   max_output_reloc_count = 0;
2427   for (o = abfd->sections; o != NULL; o = o->next)
2428     {
2429       if (o->lineno_count == 0)
2430         o->line_filepos = 0;
2431       else
2432         {
2433           o->line_filepos = line_filepos;
2434           line_filepos += o->lineno_count * linesz;
2435         }
2436
2437       if (o->reloc_count != 0)
2438         {
2439           /* We don't know the indices of global symbols until we have
2440              written out all the local symbols.  For each section in
2441              the output file, we keep an array of pointers to hash
2442              table entries.  Each entry in the array corresponds to a
2443              reloc.  When we find a reloc against a global symbol, we
2444              set the corresponding entry in this array so that we can
2445              fix up the symbol index after we have written out all the
2446              local symbols.
2447
2448              Because of this problem, we also keep the relocs in
2449              memory until the end of the link.  This wastes memory,
2450              but only when doing a relocateable link, which is not the
2451              common case.  */
2452           BFD_ASSERT (info->relocateable);
2453           finfo.section_info[o->target_index].relocs =
2454             ((struct internal_reloc *)
2455              bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
2456           finfo.section_info[o->target_index].rel_hashes =
2457             ((struct coff_link_hash_entry **)
2458              bfd_malloc (o->reloc_count
2459                      * sizeof (struct coff_link_hash_entry *)));
2460           if (finfo.section_info[o->target_index].relocs == NULL
2461               || finfo.section_info[o->target_index].rel_hashes == NULL)
2462             goto error_return;
2463
2464           if (o->reloc_count > max_output_reloc_count)
2465             max_output_reloc_count = o->reloc_count;
2466         }
2467
2468       /* Reset the reloc and lineno counts, so that we can use them to
2469          count the number of entries we have output so far.  */
2470       o->reloc_count = 0;
2471       o->lineno_count = 0;
2472     }
2473
2474   obj_sym_filepos (abfd) = line_filepos;
2475
2476   /* Figure out the largest number of symbols in an input BFD.  Take
2477      the opportunity to clear the output_has_begun fields of all the
2478      input BFD's.  */
2479   max_sym_count = 0;
2480   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
2481     {
2482       size_t sz;
2483
2484       sub->output_has_begun = false;
2485       sz = obj_raw_syment_count (sub);
2486       if (sz > max_sym_count)
2487         max_sym_count = sz;
2488     }
2489
2490   /* Allocate some buffers used while linking.  */
2491   finfo.internal_syms = ((struct internal_syment *)
2492                          bfd_malloc (max_sym_count
2493                                      * sizeof (struct internal_syment)));
2494   finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
2495                                              * sizeof (asection *));
2496   finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
2497   finfo.outsyms = ((bfd_byte *)
2498                    bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
2499   finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
2500                                        * bfd_coff_linesz (abfd));
2501   finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
2502   finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
2503   if (! info->relocateable)
2504     finfo.internal_relocs = ((struct internal_reloc *)
2505                              bfd_malloc (max_reloc_count
2506                                          * sizeof (struct internal_reloc)));
2507   if ((finfo.internal_syms == NULL && max_sym_count > 0)
2508       || (finfo.sec_ptrs == NULL && max_sym_count > 0)
2509       || (finfo.sym_indices == NULL && max_sym_count > 0)
2510       || finfo.outsyms == NULL
2511       || (finfo.linenos == NULL && max_lineno_count > 0)
2512       || (finfo.contents == NULL && max_contents_size > 0)
2513       || (finfo.external_relocs == NULL && max_reloc_count > 0)
2514       || (! info->relocateable
2515           && finfo.internal_relocs == NULL
2516           && max_reloc_count > 0))
2517     goto error_return;
2518
2519   /* We now know the position of everything in the file, except that
2520      we don't know the size of the symbol table and therefore we don't
2521      know where the string table starts.  We just build the string
2522      table in memory as we go along.  We process all the relocations
2523      for a single input file at once.  */
2524   obj_raw_syment_count (abfd) = 0;
2525
2526   if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
2527     {
2528       if (! bfd_coff_start_final_link (abfd, info))
2529         goto error_return;
2530     }
2531
2532   for (o = abfd->sections; o != NULL; o = o->next)
2533     {
2534       for (p = o->link_order_head; p != NULL; p = p->next)
2535         {
2536           if (p->type == bfd_indirect_link_order
2537               && (bfd_get_flavour (p->u.indirect.section->owner)
2538                   == bfd_target_coff_flavour))
2539             {
2540               sub = p->u.indirect.section->owner;
2541 #ifdef POWERPC_LE_PE
2542               if (! sub->output_has_begun && !ppc_do_last(sub))
2543 #else
2544               if (! sub->output_has_begun)
2545 #endif
2546                 {
2547                   if (! _bfd_coff_link_input_bfd (&finfo, sub))
2548                     goto error_return;
2549                   sub->output_has_begun = true;
2550                 }
2551             }
2552           else if (p->type == bfd_section_reloc_link_order
2553                    || p->type == bfd_symbol_reloc_link_order)
2554             {
2555               if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
2556                 goto error_return;
2557             }
2558           else
2559             {
2560               if (! _bfd_default_link_order (abfd, info, o, p))
2561                 goto error_return;
2562             }
2563         }
2564     }
2565
2566 #ifdef POWERPC_LE_PE
2567   {
2568     extern bfd* ppc_get_last();
2569     bfd* last_one = ppc_get_last();
2570     if (last_one)
2571       {
2572         if (! _bfd_coff_link_input_bfd (&finfo, last_one))
2573           goto error_return;
2574       }
2575     last_one->output_has_begun = true;
2576   }
2577 #endif
2578
2579   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
2580
2581   coff_debug_merge_hash_table_free (&finfo.debug_merge);
2582   debug_merge_allocated = false;
2583
2584   if (finfo.internal_syms != NULL)
2585     {
2586       free (finfo.internal_syms);
2587       finfo.internal_syms = NULL;
2588     }
2589   if (finfo.sec_ptrs != NULL)
2590     {
2591       free (finfo.sec_ptrs);
2592       finfo.sec_ptrs = NULL;
2593     }
2594   if (finfo.sym_indices != NULL)
2595     {
2596       free (finfo.sym_indices);
2597       finfo.sym_indices = NULL;
2598     }
2599   if (finfo.linenos != NULL)
2600     {
2601       free (finfo.linenos);
2602       finfo.linenos = NULL;
2603     }
2604   if (finfo.contents != NULL)
2605     {
2606       free (finfo.contents);
2607       finfo.contents = NULL;
2608     }
2609   if (finfo.external_relocs != NULL)
2610     {
2611       free (finfo.external_relocs);
2612       finfo.external_relocs = NULL;
2613     }
2614   if (finfo.internal_relocs != NULL)
2615     {
2616       free (finfo.internal_relocs);
2617       finfo.internal_relocs = NULL;
2618     }
2619
2620   /* The value of the last C_FILE symbol is supposed to be the symbol
2621      index of the first external symbol.  Write it out again if
2622      necessary.  */
2623   if (finfo.last_file_index != -1
2624       && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
2625     {
2626       finfo.last_file.n_value = obj_raw_syment_count (abfd);
2627       bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
2628                              (PTR) finfo.outsyms);
2629       if (bfd_seek (abfd,
2630                     (obj_sym_filepos (abfd)
2631                      + finfo.last_file_index * symesz),
2632                     SEEK_SET) != 0
2633           || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
2634         return false;
2635     }
2636
2637   /* Write out the global symbols.  */
2638   finfo.failed = false;
2639   coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
2640                            (PTR) &finfo);
2641   if (finfo.failed)
2642     goto error_return;
2643
2644   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
2645   if (finfo.outsyms != NULL)
2646     {
2647       free (finfo.outsyms);
2648       finfo.outsyms = NULL;
2649     }
2650
2651   if (info->relocateable)
2652     {
2653       /* Now that we have written out all the global symbols, we know
2654          the symbol indices to use for relocs against them, and we can
2655          finally write out the relocs.  */
2656       external_relocs = ((bfd_byte *)
2657                          bfd_malloc (max_output_reloc_count * relsz));
2658       if (external_relocs == NULL)
2659         goto error_return;
2660
2661       for (o = abfd->sections; o != NULL; o = o->next)
2662         {
2663           struct internal_reloc *irel;
2664           struct internal_reloc *irelend;
2665           struct coff_link_hash_entry **rel_hash;
2666           bfd_byte *erel;
2667
2668           if (o->reloc_count == 0)
2669             continue;
2670
2671           irel = finfo.section_info[o->target_index].relocs;
2672           irelend = irel + o->reloc_count;
2673           rel_hash = finfo.section_info[o->target_index].rel_hashes;
2674           erel = external_relocs;
2675           for (; irel < irelend; irel++, rel_hash++, erel += relsz)
2676             {
2677               if (*rel_hash != NULL)
2678                 {
2679                   BFD_ASSERT ((*rel_hash)->indx >= 0);
2680                   irel->r_symndx = (*rel_hash)->indx;
2681                 }
2682               bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
2683             }
2684
2685           if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
2686               || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
2687                             abfd) != relsz * o->reloc_count)
2688             goto error_return;
2689         }
2690
2691       free (external_relocs);
2692       external_relocs = NULL;
2693     }
2694
2695   /* Free up the section information.  */
2696   if (finfo.section_info != NULL)
2697     {
2698       unsigned int i;
2699
2700       for (i = 0; i < abfd->section_count; i++)
2701         {
2702           if (finfo.section_info[i].relocs != NULL)
2703             free (finfo.section_info[i].relocs);
2704           if (finfo.section_info[i].rel_hashes != NULL)
2705             free (finfo.section_info[i].rel_hashes);
2706         }
2707       free (finfo.section_info);
2708       finfo.section_info = NULL;
2709     }
2710
2711   /* If we have optimized stabs strings, output them.  */
2712   if (coff_hash_table (info)->stab_info != NULL)
2713     {
2714       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
2715         return false;
2716     }
2717
2718   /* Write out the string table.  */
2719   if (obj_raw_syment_count (abfd) != 0)
2720     {
2721       if (bfd_seek (abfd,
2722                     (obj_sym_filepos (abfd)
2723                      + obj_raw_syment_count (abfd) * symesz),
2724                     SEEK_SET) != 0)
2725         return false;
2726
2727 #if STRING_SIZE_SIZE == 4
2728       bfd_h_put_32 (abfd,
2729                     _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
2730                     (bfd_byte *) strbuf);
2731 #else
2732  #error Change bfd_h_put_32
2733 #endif
2734
2735       if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
2736         return false;
2737
2738       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
2739         return false;
2740     }
2741
2742   _bfd_stringtab_free (finfo.strtab);
2743
2744   /* Setting bfd_get_symcount to 0 will cause write_object_contents to
2745      not try to write out the symbols.  */
2746   bfd_get_symcount (abfd) = 0;
2747
2748   return true;
2749
2750  error_return:
2751   if (debug_merge_allocated)
2752     coff_debug_merge_hash_table_free (&finfo.debug_merge);
2753   if (finfo.strtab != NULL)
2754     _bfd_stringtab_free (finfo.strtab);
2755   if (finfo.section_info != NULL)
2756     {
2757       unsigned int i;
2758
2759       for (i = 0; i < abfd->section_count; i++)
2760         {
2761           if (finfo.section_info[i].relocs != NULL)
2762             free (finfo.section_info[i].relocs);
2763           if (finfo.section_info[i].rel_hashes != NULL)
2764             free (finfo.section_info[i].rel_hashes);
2765         }
2766       free (finfo.section_info);
2767     }
2768   if (finfo.internal_syms != NULL)
2769     free (finfo.internal_syms);
2770   if (finfo.sec_ptrs != NULL)
2771     free (finfo.sec_ptrs);
2772   if (finfo.sym_indices != NULL)
2773     free (finfo.sym_indices);
2774   if (finfo.outsyms != NULL)
2775     free (finfo.outsyms);
2776   if (finfo.linenos != NULL)
2777     free (finfo.linenos);
2778   if (finfo.contents != NULL)
2779     free (finfo.contents);
2780   if (finfo.external_relocs != NULL)
2781     free (finfo.external_relocs);
2782   if (finfo.internal_relocs != NULL)
2783     free (finfo.internal_relocs);
2784   if (external_relocs != NULL)
2785     free (external_relocs);
2786   return false;
2787 }
2788 #endif
2789 \f
2790
2791 /* The transfer vectors that lead the outside world to all of the above. */
2792
2793 #ifdef TARGET_LITTLE_SYM
2794 const bfd_target
2795 TARGET_LITTLE_SYM =
2796 {
2797   TARGET_LITTLE_NAME,           /* name or coff-arm-little */
2798   bfd_target_coff_flavour,
2799   BFD_ENDIAN_LITTLE,            /* data byte order is little */
2800   BFD_ENDIAN_LITTLE,            /* header byte order is little */
2801
2802   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
2803    HAS_LINENO | HAS_DEBUG |
2804    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2805   
2806 #ifndef COFF_WITH_PE
2807   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2808 #else
2809   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
2810    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
2811 #endif
2812
2813   0,                            /* leading char */
2814   '/',                          /* ar_pad_char */
2815   15,                           /* ar_max_namelen??? FIXMEmgo */
2816
2817   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2818   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2819   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2820
2821   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2822   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2823   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2824   
2825   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
2826      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2827   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2828      bfd_false},
2829   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
2830      _bfd_write_archive_contents, bfd_false},
2831   
2832   BFD_JUMP_TABLE_GENERIC (coff),
2833   BFD_JUMP_TABLE_COPY (coff),
2834   BFD_JUMP_TABLE_CORE (_bfd_nocore),
2835   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2836   BFD_JUMP_TABLE_SYMBOLS (coff),
2837   BFD_JUMP_TABLE_RELOCS (coff),
2838   BFD_JUMP_TABLE_WRITE (coff),
2839   BFD_JUMP_TABLE_LINK (coff),
2840   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2841   
2842   COFF_SWAP_TABLE,
2843 };
2844 #endif
2845
2846 #ifdef TARGET_BIG_SYM
2847 const bfd_target
2848 TARGET_BIG_SYM =
2849 {
2850   TARGET_BIG_NAME,
2851   bfd_target_coff_flavour,      
2852   BFD_ENDIAN_BIG,               /* data byte order is big */
2853   BFD_ENDIAN_BIG,               /* header byte order is big */
2854
2855   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
2856    HAS_LINENO | HAS_DEBUG |
2857    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2858
2859 #ifndef COFF_WITH_PE
2860   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2861 #else
2862   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
2863    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
2864 #endif
2865
2866   0,                            /* leading char */
2867   '/',                          /* ar_pad_char */
2868   15,                           /* ar_max_namelen??? FIXMEmgo */
2869
2870   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2871   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2872   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
2873
2874   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2875   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2876   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
2877
2878   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
2879      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2880   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2881      bfd_false},
2882   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
2883      _bfd_write_archive_contents, bfd_false},
2884
2885   BFD_JUMP_TABLE_GENERIC (coff),
2886   BFD_JUMP_TABLE_COPY (coff),
2887   BFD_JUMP_TABLE_CORE (_bfd_nocore),
2888   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2889   BFD_JUMP_TABLE_SYMBOLS (coff),
2890   BFD_JUMP_TABLE_RELOCS (coff),
2891   BFD_JUMP_TABLE_WRITE (coff),
2892   BFD_JUMP_TABLE_LINK (coff),
2893   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2894
2895   COFF_SWAP_TABLE,
2896 };
2897
2898 #endif