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