Remove SEC_LINKER_MARK, and add a linker_mark bitfield to the asection
[external/binutils.git] / bfd / coff-ppc.c
1 /* BFD back-end for PowerPC Microsoft Portable Executable files.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 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 = 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
1095   CHECK_EYE(h->eye_catcher);
1096
1097   h->symbol_is_glue = 1;
1098   h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
1099
1100   return;
1101 }
1102
1103 #endif /* COFF_IMAGE_WITH_PE */
1104 \f
1105 #if 0
1106
1107 /* Provided the symbol, returns the value reffed */
1108 static long get_symbol_value PARAMS ((asymbol *));
1109
1110 static long
1111 get_symbol_value (symbol)       
1112      asymbol *symbol;
1113 {                                             
1114   long relocation = 0;
1115
1116   if (bfd_is_com_section (symbol->section))
1117     {
1118       relocation = 0;                           
1119     }
1120   else 
1121     {                                      
1122       relocation = symbol->value +
1123         symbol->section->output_section->vma +
1124           symbol->section->output_offset;
1125     }                                           
1126
1127   return(relocation);
1128 }
1129
1130 #endif /* 0 */
1131
1132 /* Return true if this relocation should
1133    appear in the output .reloc section. */
1134
1135 static boolean in_reloc_p(abfd, howto)
1136      bfd * abfd;
1137      reloc_howto_type *howto;
1138 {
1139   return 
1140     (! howto->pc_relative) 
1141       && (howto->type != IMAGE_REL_PPC_ADDR32NB)
1142       && (howto->type != IMAGE_REL_PPC_TOCREL16)
1143       && (howto->type != IMAGE_REL_PPC_IMGLUE)
1144       && (howto->type != IMAGE_REL_PPC_IFGLUE) 
1145       && (howto->type != IMAGE_REL_PPC_SECREL)
1146       && (howto->type != IMAGE_REL_PPC_SECTION)
1147       && (howto->type != IMAGE_REL_PPC_SECREL16)
1148       && (howto->type != IMAGE_REL_PPC_REFHI)
1149       && (howto->type != IMAGE_REL_PPC_REFLO)
1150       && (howto->type != IMAGE_REL_PPC_PAIR)
1151       && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
1152 }     
1153
1154 #if 0
1155
1156 /* this function is in charge of performing all the ppc PE relocations */
1157 /* Don't yet know if we want to do this this particular way ... (krk)  */
1158 /* FIXME: (it is not yet enabled) */
1159
1160 static bfd_reloc_status_type
1161 pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
1162               error_message)
1163      bfd *abfd;
1164      arelent *reloc_entry;
1165      asymbol *symbol_in;
1166      PTR data;
1167      asection *input_section;
1168      bfd *output_bfd;
1169      char **error_message;
1170 {
1171   /* the consth relocation comes in two parts, we have to remember
1172      the state between calls, in these variables */
1173   static boolean part1_consth_active = false;
1174   static unsigned long part1_consth_value;
1175
1176   unsigned long sym_value;
1177   unsigned short r_type;
1178   unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
1179         
1180   fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME);
1181
1182   r_type = reloc_entry->howto->type;
1183
1184   if (output_bfd) 
1185     {
1186       /* Partial linking - do nothing */
1187       reloc_entry->address += input_section->output_offset;
1188       return bfd_reloc_ok; 
1189     }
1190
1191   if (symbol_in != NULL
1192       && bfd_is_und_section (symbol_in->section))
1193     {
1194       /* Keep the state machine happy in case we're called again */
1195       if (r_type == IMAGE_REL_PPC_REFHI) 
1196         {
1197           part1_consth_active = true;
1198           part1_consth_value  = 0;
1199         }
1200       return(bfd_reloc_undefined);
1201     }
1202   
1203   if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) 
1204     {
1205       part1_consth_active = false;
1206       *error_message = (char *) "Missing PAIR";
1207       return(bfd_reloc_dangerous);
1208     }
1209
1210
1211   sym_value = get_symbol_value(symbol_in);
1212   
1213   return(bfd_reloc_ok); 
1214 }
1215
1216 #endif /* 0 */
1217
1218 /* The reloc processing routine for the optimized COFF linker.  */
1219
1220 static boolean
1221 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
1222                            contents, relocs, syms, sections)
1223      bfd *output_bfd;
1224      struct bfd_link_info *info;
1225      bfd *input_bfd;
1226      asection *input_section;
1227      bfd_byte *contents;
1228      struct internal_reloc *relocs;
1229      struct internal_syment *syms;
1230      asection **sections;
1231 {
1232   struct internal_reloc *rel;
1233   struct internal_reloc *relend;
1234   boolean hihalf;
1235   bfd_vma hihalf_val;
1236   asection *toc_section = 0;
1237   bfd_vma relocation;
1238   reloc_howto_type *howto = 0;
1239   
1240 #ifdef DEBUG_RELOC
1241   fprintf(stderr, 
1242           "pe_ppc_relocate_section (%s) for %s in bfd %s\n", 
1243           TARGET_LITTLE_NAME,
1244           input_section->name,
1245           input_bfd->filename);
1246   
1247 #endif  
1248
1249   /* If we are performing a relocateable link, we don't need to do a
1250      thing.  The caller will take care of adjusting the reloc
1251      addresses and symbol indices.  */
1252   if (info->relocateable)
1253     return true;
1254   
1255   hihalf = false;
1256   hihalf_val = 0;
1257
1258   rel = relocs;
1259   relend = rel + input_section->reloc_count;
1260   for (; rel < relend; rel++)
1261     {
1262       long symndx;
1263       struct ppc_coff_link_hash_entry *h;
1264       struct internal_syment *sym;
1265       bfd_vma val;
1266
1267       asection *sec;
1268       bfd_reloc_status_type rstat;
1269       bfd_byte *loc;
1270
1271       unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
1272       unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1273   
1274 #ifdef DEBUG_RELOC
1275       /* now examine flags */
1276       if (r_flags != 0) 
1277         {
1278           fprintf (stderr, "Reloc with flags found!");
1279           if ( r_flags & IMAGE_REL_PPC_NEG ) 
1280             fprintf (stderr, " NEG");
1281           if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1282             fprintf (stderr, " BRTAKEN");
1283           if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1284             fprintf (stderr, " BRNTAKEN");
1285           if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1286             fprintf (stderr, " TOCDEFN");
1287           fprintf(stderr, "\n");
1288         }
1289 #endif
1290
1291       symndx = rel->r_symndx;
1292       loc = contents + rel->r_vaddr - input_section->vma;
1293
1294       /* FIXME: check bounds on r_type */
1295       howto = ppc_coff_howto_table + r_type;
1296
1297       if (symndx == -1)
1298         {
1299           h = NULL;
1300           sym = NULL;
1301         }
1302       else
1303         {
1304           h = (struct ppc_coff_link_hash_entry *) 
1305             (obj_coff_sym_hashes (input_bfd)[symndx]);
1306           if (h != 0) 
1307             {
1308               CHECK_EYE(h->eye_catcher);
1309             }
1310
1311           sym = syms + symndx;
1312         }
1313
1314       sec = NULL;
1315       val = 0;
1316
1317       /* FIXME: PAIR unsupported in the following code */
1318       if (h == NULL)
1319         {
1320           if (symndx == -1)
1321             sec = bfd_abs_section_ptr;
1322           else
1323             {
1324               sec = sections[symndx];
1325               val = (sec->output_section->vma
1326                      + sec->output_offset
1327                      + sym->n_value
1328                      - sec->vma);
1329             }
1330         }
1331       else
1332         {
1333           CHECK_EYE(h->eye_catcher);
1334
1335           if (h->root.root.type == bfd_link_hash_defined
1336               || h->root.root.type == bfd_link_hash_defweak)
1337             {
1338               sec = h->root.root.u.def.section;
1339               val = (h->root.root.u.def.value
1340                      + sec->output_section->vma
1341                      + sec->output_offset);
1342             }
1343           else
1344             {
1345 fprintf(stderr,
1346         "missing %s\n",h->root.root.root.string);
1347               if (! ((*info->callbacks->undefined_symbol)
1348                      (info, h->root.root.root.string, input_bfd, input_section,
1349                       rel->r_vaddr - input_section->vma)))
1350                 return false;
1351             }
1352         }
1353
1354       rstat = bfd_reloc_ok;
1355       
1356       /* Each case must do its own relocation, setting rstat appropriately */
1357       switch (r_type)
1358         {
1359         default:
1360           fprintf( stderr, 
1361                   "ERROR: during reloc processing -- unsupported reloc %s\n", 
1362                   howto->name);
1363           bfd_set_error (bfd_error_bad_value);
1364           abort();
1365           return false;
1366         case IMAGE_REL_PPC_TOCREL16:
1367           {
1368             bfd_vma our_toc_offset;
1369             int fixit;
1370
1371             DUMP_RELOC2(howto->name, rel);
1372
1373             if (toc_section == 0) 
1374               {
1375                 toc_section = bfd_get_section_by_name (bfd_of_toc_owner, 
1376                                                        TOC_SECTION_NAME);
1377 #ifdef TOC_DEBUG
1378
1379                 fprintf(stderr,
1380                         "BFD of toc owner %p (%s), section addr of %s %p\n",
1381                          bfd_of_toc_owner, bfd_of_toc_owner->filename, 
1382                         TOC_SECTION_NAME, toc_section);
1383 #endif
1384
1385                 if ( toc_section == NULL ) 
1386                   {
1387                     fprintf(stderr, "No Toc section!\n");
1388                     abort();
1389                   }
1390               }
1391
1392             /* 
1393              *  Amazing bit tricks present. As we may have seen earlier, we
1394              *  use the 1 bit to tell us whether or not a toc offset has been
1395              *  allocated. Now that they've all been allocated, we will use
1396              *  the 1 bit to tell us if we've written this particular toc
1397              *  entry out.
1398              */
1399             fixit = false;
1400             if (h == 0)
1401               { /* it is a file local symbol */
1402                 int *local_toc_table;
1403                 const char *name;
1404
1405                 sym = syms + symndx;
1406                 name = sym->_n._n_name;
1407
1408                 local_toc_table = obj_coff_local_toc_table(input_bfd);
1409                 our_toc_offset = local_toc_table[symndx];
1410
1411                 if (IS_WRITTEN(our_toc_offset))
1412                   {
1413                     /* if it has been written out, it is marked with the 
1414                        1 bit. Fix up our offset, but do not write it out
1415                        again.
1416                      */
1417                     MAKE_ADDR_AGAIN(our_toc_offset);
1418 #ifdef TOC_DEBUG
1419
1420                     fprintf(stderr,
1421                             "Not writing out toc_offset of %d for %s\n", 
1422                             our_toc_offset, name);
1423 #endif
1424                   }
1425                 else
1426                   {
1427                     /* write out the toc entry */
1428                     record_toc(toc_section, our_toc_offset, priv, strdup(name));
1429 #ifdef TOC_DEBUG
1430                     fprintf(stderr,
1431                             "Writing out toc_offset "
1432                             "toc_section (%p,%p)+%d val %d for %s\n", 
1433                             toc_section,
1434                             toc_section->contents,
1435                             our_toc_offset, 
1436                             val,
1437                             name);
1438 #endif
1439
1440                     bfd_put_32(output_bfd,
1441                                val,
1442                                toc_section->contents + our_toc_offset);
1443
1444                     MARK_AS_WRITTEN(local_toc_table[symndx]);
1445                     fixit = true;
1446                   }
1447               }
1448             else
1449               {
1450                 const char *name = h->root.root.root.string;
1451                 our_toc_offset = h->toc_offset;
1452
1453                 if ((r_flags & IMAGE_REL_PPC_TOCDEFN) 
1454                     == IMAGE_REL_PPC_TOCDEFN )
1455 #if 0
1456                   /* This is wrong. If tocdefn is on, we must unconditionally
1457                      assume the following path */
1458                     && IS_UNALLOCATED(our_toc_offset))
1459 #endif
1460                   {
1461                     /* This is unbelievable cheese. Some knowledgable asm 
1462                        hacker has decided to use r2 as a base for loading 
1463                        a value. He/She does this by setting the tocdefn bit, 
1464                        and not supplying a toc definition. The behaviour is 
1465                        then to use the difference between the value of the 
1466                        symbol and the actual location of the toc as the toc 
1467                        index. 
1468
1469                        In fact, what is usually happening is, because the
1470                        Import Address Table is mapped immediately following
1471                        the toc, some trippy library code trying for speed on
1472                        dll linkage, takes advantage of that and considers 
1473                        the IAT to be part of the toc, thus saving a load.
1474                     */
1475 #ifdef DEBUG_RELOC
1476                     fprintf(stderr,
1477                             "TOCDEFN is on, (%s) (%p) our_toc_offset = %x\n", 
1478                             name, h, our_toc_offset);
1479 #endif
1480
1481                     our_toc_offset = val - 
1482                       (toc_section->output_section->vma + 
1483                        toc_section->output_offset);
1484
1485 #ifdef DEBUG_RELOC
1486                     fprintf(stderr,
1487                             "               our_toc_offset set to %x\n", our_toc_offset);
1488 #endif
1489
1490                     /* The size must still fit in a 16bit displacment */
1491                     if (our_toc_offset >= 65535)
1492                       {
1493                         fprintf(stderr,
1494                                 "TOCDEFN Relocation exceeded "
1495                                 "displacment of 65535\n");
1496                         abort();
1497                       }
1498
1499                     record_toc(toc_section, our_toc_offset, pub, strdup(name));
1500                   }
1501                 else if (IS_WRITTEN(our_toc_offset))
1502                   {
1503                     /* if it has been written out, it is marked with the 
1504                        1 bit. Fix up our offset, but do not write it out
1505                        again.
1506                      */
1507                     MAKE_ADDR_AGAIN(our_toc_offset);
1508 #ifdef TOC_DEBUG
1509                     fprintf(stderr,
1510                             "Not writing out toc_offset of %d for %s\n", 
1511                             our_toc_offset, name);
1512 #endif
1513                   }
1514                 else
1515                   {
1516                     record_toc(toc_section, our_toc_offset, pub, strdup(name));
1517
1518 #ifdef TOC_DEBUG
1519                     /* write out the toc entry */
1520                     fprintf(stderr,
1521                             "Writing out toc_offset "
1522                             "toc_section (%p,%p)+%d val %d for %s\n", 
1523                             toc_section,
1524                             toc_section->contents,
1525                             our_toc_offset, 
1526                             val,
1527                             name);
1528 #endif
1529
1530                     /* write out the toc entry */
1531                     bfd_put_32(output_bfd,
1532                                val,
1533                                toc_section->contents + our_toc_offset);
1534
1535                     MARK_AS_WRITTEN(h->toc_offset);
1536                     /* The tricky part is that this is the address that */
1537                     /* needs a .reloc entry for it */
1538                     fixit = true;
1539                   }
1540               }
1541
1542             if (fixit && info->base_file) 
1543               {
1544                 /* So if this is non pcrelative, and is referenced
1545                    to a section or a common symbol, then it needs a reloc */
1546
1547                 /* relocation to a symbol in a section which
1548                    isn't absolute - we output the address here 
1549                    to a file */
1550
1551                 bfd_vma addr =  toc_section->output_section->vma
1552                   + toc_section->output_offset + our_toc_offset;
1553                     
1554                 if (coff_data(output_bfd)->pe)
1555                   addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1556
1557 #ifdef DEBUG_RELOC
1558                 fprintf(stderr,
1559                         "  Toc Section .reloc candidate addr = %x\n", addr);
1560 #endif
1561                 fwrite (&addr, 1,4, (FILE *) info->base_file);
1562               }
1563
1564
1565             /* FIXME: this test is conservative */
1566             if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&
1567                 our_toc_offset > toc_section->_raw_size)
1568               {
1569                 fprintf(stderr,
1570                         "reloc offset is bigger than the toc size!\n");
1571                 abort();
1572               }
1573
1574             /* Now we know the relocation for this toc reference */
1575             relocation =  our_toc_offset + TOC_LOAD_ADJUSTMENT;
1576             rstat = _bfd_relocate_contents (howto,
1577                                             input_bfd, 
1578                                             relocation, 
1579                                             loc);
1580           }
1581           break;
1582         case IMAGE_REL_PPC_IFGLUE:
1583           {
1584             /* To solve this, we need to know whether or not the symbol */
1585             /* appearing on the call instruction is a glue function or not. */
1586             /* A glue function must announce itself via a IMGLUE reloc, and */
1587             /* the reloc contains the required toc restore instruction */
1588           
1589             bfd_vma x;
1590             const char *my_name;
1591             DUMP_RELOC2(howto->name, rel);
1592
1593             if (h != 0)
1594               {
1595                 my_name = h->root.root.root.string;
1596                 if (h->symbol_is_glue == 1) 
1597                   {
1598                     x = bfd_get_32(input_bfd, loc);
1599                     bfd_put_32(input_bfd, h->glue_insn, loc);
1600                   }
1601               }
1602           }
1603           break;
1604         case IMAGE_REL_PPC_SECREL:
1605           /* Unimplemented: codeview debugging information */
1606           /* For fast access to the header of the section 
1607              containing the item. */
1608           break;
1609         case IMAGE_REL_PPC_SECTION:
1610           /* Unimplemented: codeview debugging information */
1611           /* Is used to indicate that the value should be relative
1612              to the beginning of the section that contains the
1613              symbol */
1614           break;
1615         case IMAGE_REL_PPC_ABSOLUTE:
1616           {
1617             const char *my_name;
1618             if (h == 0)
1619                 my_name = (syms+symndx)->_n._n_name;
1620             else
1621               {
1622                 my_name = h->root.root.root.string;
1623               }
1624
1625             fprintf(stderr, 
1626                     "Warning: unsupported reloc %s <file %s, section %s>\n", 
1627                     howto->name,
1628                     bfd_get_filename(input_bfd),
1629                     input_section->name);
1630
1631             fprintf(stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", 
1632                     rel->r_symndx, my_name, (long) rel->r_vaddr,
1633                     (unsigned long) rel->r_vaddr);  
1634           }
1635           break;
1636         case IMAGE_REL_PPC_IMGLUE:
1637           {
1638             /* There is nothing to do now. This reloc was noted in the first
1639                pass over the relocs, and the glue instruction extracted */
1640             const char *my_name;
1641             if (h->symbol_is_glue == 1) 
1642               break;
1643             my_name = h->root.root.root.string;
1644             fprintf(stderr, 
1645                     "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n", 
1646                     howto->name,
1647                     bfd_get_filename(input_bfd),
1648                     input_section->name);
1649             break;
1650
1651           }
1652           break;
1653
1654         case IMAGE_REL_PPC_ADDR32NB:
1655           {
1656             struct coff_link_hash_entry *myh = 0;
1657             const char *name = 0;
1658             DUMP_RELOC2(howto->name, rel);
1659
1660             if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
1661               {
1662                 /* set magic values */
1663                 int idata5offset;
1664                 struct coff_link_hash_entry *myh = 0;
1665                 myh = coff_link_hash_lookup (coff_hash_table (info),
1666                                              "__idata5_magic__",
1667                                              false, false, true);
1668                 first_thunk_address = myh->root.u.def.value + 
1669                   sec->output_section->vma + 
1670                     sec->output_offset - 
1671                       pe_data(output_bfd)->pe_opthdr.ImageBase;
1672                 
1673                 idata5offset = myh->root.u.def.value;
1674                 myh = coff_link_hash_lookup (coff_hash_table (info),
1675                                              "__idata6_magic__",
1676                                              false, false, true);
1677                 
1678                 thunk_size = myh->root.u.def.value - idata5offset;
1679                 myh = coff_link_hash_lookup (coff_hash_table (info),
1680                                              "__idata4_magic__",
1681                                              false, false, true);
1682                 import_table_size = myh->root.u.def.value;
1683 #ifdef DEBUG_RELOC
1684                 fprintf(stderr,
1685                         "first computation triggered fta %x, ts %d(%x), its %d(%x)\n",
1686                         first_thunk_address, thunk_size, thunk_size, import_table_size,
1687                         import_table_size);
1688 #endif
1689               }
1690
1691             if (h == 0)
1692               { /* it is a file local symbol */
1693                 sym = syms + symndx;
1694                 name = sym->_n._n_name;
1695               }
1696             else
1697               {
1698                 char *target = 0;
1699
1700                 name = h->root.root.root.string;
1701                 if (strcmp(".idata$2", name) == 0)
1702                   target = "__idata2_magic__";
1703                 else if (strcmp(".idata$4", name) == 0)
1704                   target = "__idata4_magic__";
1705                 else if (strcmp(".idata$5", name) == 0)
1706                   target = "__idata5_magic__";
1707
1708                 if (target != 0)
1709                   {
1710                     myh = 0;
1711
1712                     myh = coff_link_hash_lookup (coff_hash_table (info),
1713                                                  target,
1714                                                  false, false, true);
1715                     if (myh == 0) 
1716                       {
1717                         fprintf(stderr, "Missing idata magic cookies, "
1718                                 "this cannot work anyway...\n");
1719                         abort();
1720                       }
1721                     
1722                     val = myh->root.u.def.value + 
1723                       sec->output_section->vma + sec->output_offset;
1724                     if (first_thunk_address == 0)
1725                       {
1726                         int idata5offset;
1727                         myh = coff_link_hash_lookup (coff_hash_table (info),
1728                                                      "__idata5_magic__",
1729                                                      false, false, true);
1730                         first_thunk_address = myh->root.u.def.value + 
1731                           sec->output_section->vma + 
1732                             sec->output_offset - 
1733                               pe_data(output_bfd)->pe_opthdr.ImageBase;
1734                         
1735                         idata5offset = myh->root.u.def.value;
1736                         myh = coff_link_hash_lookup (coff_hash_table (info),
1737                                                      "__idata6_magic__",
1738                                                      false, false, true);
1739                         
1740                         thunk_size = myh->root.u.def.value - idata5offset;
1741                         myh = coff_link_hash_lookup (coff_hash_table (info),
1742                                                      "__idata4_magic__",
1743                                                      false, false, true);
1744                         import_table_size = myh->root.u.def.value;
1745 #ifdef DEBUG_RELOC
1746
1747                         fprintf(stderr,
1748                                 "second computation triggered fta %x, ts %d(%x), its %d(%x)\n",
1749                                 first_thunk_address, thunk_size, thunk_size, import_table_size,
1750                                 import_table_size);
1751 #endif
1752                       }
1753                   }
1754               }
1755
1756             rstat = _bfd_relocate_contents (howto,
1757                               input_bfd, 
1758                               val - 
1759                               pe_data(output_bfd)->pe_opthdr.ImageBase,
1760                               loc);
1761           }
1762           break;
1763
1764         case IMAGE_REL_PPC_REL24:
1765           DUMP_RELOC2(howto->name, rel);
1766           val -= (input_section->output_section->vma
1767                   + input_section->output_offset);
1768
1769           rstat = _bfd_relocate_contents (howto,
1770                                           input_bfd, 
1771                                           val, 
1772                                           loc);
1773           break;
1774         case IMAGE_REL_PPC_ADDR16:
1775         case IMAGE_REL_PPC_ADDR24:
1776         case IMAGE_REL_PPC_ADDR32:
1777           DUMP_RELOC2(howto->name, rel);
1778           rstat = _bfd_relocate_contents (howto,
1779                                           input_bfd, 
1780                                           val, 
1781                                           loc);
1782           break;
1783         }
1784
1785       if ( info->base_file )
1786         {
1787           /* So if this is non pcrelative, and is referenced
1788              to a section or a common symbol, then it needs a reloc */
1789           if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1790             {
1791               /* relocation to a symbol in a section which
1792                  isn't absolute - we output the address here 
1793                  to a file */
1794               bfd_vma addr = rel->r_vaddr 
1795                 - input_section->vma 
1796                 + input_section->output_offset 
1797                   + input_section->output_section->vma;
1798
1799               if (coff_data(output_bfd)->pe)
1800                 {
1801 #ifdef DEBUG_RELOC
1802                   bfd_vma before_addr = addr;
1803 #endif
1804                   addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1805 #ifdef DEBUG_RELOC
1806                   fprintf(stderr,
1807                           " adjusted down from %x to %x", before_addr, addr);
1808 #endif
1809                 }
1810 #ifdef DEBUG_RELOC
1811               fprintf(stderr, "\n");
1812 #endif
1813
1814               fwrite (&addr, 1,4, (FILE *) info->base_file);
1815             }
1816         }
1817
1818       switch (rstat)
1819         {
1820         default:
1821           abort ();
1822         case bfd_reloc_ok:
1823           break;
1824         case bfd_reloc_overflow:
1825           {
1826             const char *name;
1827             char buf[SYMNMLEN + 1];
1828
1829             if (symndx == -1)
1830               name = "*ABS*";
1831             else if (h != NULL)
1832               name = h->root.root.root.string;
1833             else if (sym == NULL)
1834               name = "*unknown*";
1835             else if (sym->_n._n_n._n_zeroes == 0
1836                      && sym->_n._n_n._n_offset != 0)
1837               name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
1838             else
1839               {
1840                 strncpy (buf, sym->_n._n_name, SYMNMLEN);
1841                 buf[SYMNMLEN] = '\0';
1842                 name = buf;
1843               }
1844 #if 0
1845             else
1846               {
1847                 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1848                 if (name == NULL)
1849                   return false;
1850               }
1851 #endif
1852
1853             if (! ((*info->callbacks->reloc_overflow)
1854                    (info, name, howto->name, 
1855                     (bfd_vma) 0, input_bfd,
1856                     input_section, rel->r_vaddr - input_section->vma)))
1857               {
1858 #ifdef DEBUG_RELOC
1859                 fprintf(stderr, 
1860                         "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", 
1861                         TARGET_LITTLE_NAME,
1862                         input_section->name,
1863                         input_bfd->filename);
1864   
1865 #endif  
1866                 return false;
1867               }
1868           }
1869         }
1870
1871     }     
1872
1873 #ifdef DEBUG_RELOC
1874   fprintf(stderr, 
1875           "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", 
1876           TARGET_LITTLE_NAME,
1877           input_section->name,
1878           input_bfd->filename);
1879   
1880 #endif  
1881
1882   return true;
1883 }
1884
1885
1886 #ifdef COFF_IMAGE_WITH_PE
1887
1888 long int global_toc_size = 4;
1889
1890 bfd* bfd_of_toc_owner = 0;
1891
1892 long int import_table_size;
1893 long int first_thunk_address;
1894 long int thunk_size;
1895
1896 struct list_ele *head;
1897 struct list_ele *tail;
1898
1899 static char *
1900 h1 = "\n\t\t\tTOC MAPPING\n\n";
1901 static char *
1902 h2 = " TOC    disassembly  Comments       Name\n";
1903 static char *
1904 h3 = " Offset  spelling                   (if present)\n";
1905
1906 void
1907 dump_toc(vfile)
1908      void *vfile;
1909 {
1910   FILE *file = vfile;
1911   struct list_ele *t;
1912
1913   fprintf(file, h1);
1914   fprintf(file, h2);
1915   fprintf(file, h3);
1916
1917   for(t = head; t != 0; t=t->next)
1918     {
1919       char *cat;
1920
1921       if (t->cat == priv)
1922         cat = "private       ";
1923       else if (t->cat == pub)
1924         cat = "public        ";
1925       else if (t->cat == data)
1926         cat = "data-in-toc   ";
1927
1928       if (t->offset > global_toc_size)
1929         {
1930           if (t->offset <= global_toc_size + thunk_size)
1931             cat = "IAT reference ";
1932           else
1933             {
1934               fprintf(file,
1935                       "**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n",
1936                       global_toc_size, global_toc_size, thunk_size, thunk_size);
1937               cat = "Out of bounds!";
1938             }
1939         }
1940
1941       fprintf(file,
1942               " %04lx    (%d)", (unsigned long) t->offset, t->offset - 32768);
1943       fprintf(file,
1944               "    %s %s\n",
1945               cat, t->name);
1946
1947     }
1948
1949   fprintf(file, "\n");
1950 }
1951
1952 boolean
1953 ppc_allocate_toc_section (info) 
1954      struct bfd_link_info *info;
1955 {
1956   asection *s;
1957   bfd_byte *foo;
1958   static char test_char = '1';
1959
1960   if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
1961     return true;
1962
1963   if (bfd_of_toc_owner == 0)
1964     {
1965       fprintf(stderr,
1966               "There is no bfd that owns the toc section!\n");
1967       abort();
1968     }
1969
1970   s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
1971   if (s == NULL) 
1972     {
1973       fprintf(stderr, "No Toc section!\n");
1974       abort();
1975     }
1976
1977   foo = bfd_alloc(bfd_of_toc_owner, global_toc_size);
1978   memset(foo, test_char, global_toc_size);
1979
1980   s->_raw_size = s->_cooked_size = global_toc_size;
1981   s->contents = foo;
1982
1983   return true;
1984 }
1985
1986 boolean
1987 ppc_process_before_allocation (abfd, info)
1988      bfd *abfd;
1989      struct bfd_link_info *info;
1990 {
1991   asection *sec;
1992   struct internal_reloc *i, *rel;
1993
1994 #ifdef DEBUG_RELOC
1995   fprintf(stderr, 
1996           "ppc_process_before_allocation: BFD %s\n", 
1997           bfd_get_filename(abfd));
1998 #endif
1999
2000   /* here we have a bfd that is to be included on the link. We have a hook
2001      to do reloc rummaging, before section sizes are nailed down. */
2002
2003   _bfd_coff_get_external_symbols(abfd);
2004
2005   /* rummage around all the relocs and map the toc */
2006   sec = abfd->sections;
2007
2008   if (sec == 0)
2009     {
2010       return true;
2011     }
2012
2013   for (; sec != 0; sec = sec->next)
2014   {
2015     int toc_offset;
2016
2017 #ifdef DEBUG_RELOC
2018     fprintf(stderr, 
2019             "  section %s reloc count %d\n", 
2020             sec->name, 
2021             sec->reloc_count);
2022 #endif
2023
2024     if (sec->reloc_count == 0) 
2025       continue;
2026
2027     /* load the relocs */
2028     /* FIXME: there may be a storage leak here */
2029     i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
2030     
2031     if (i == 0)
2032       abort();
2033
2034     for (rel=i;rel<i+sec->reloc_count;++rel) 
2035       {
2036         unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
2037         unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2038
2039 #ifdef DEBUG_RELOC
2040         /* now examine flags */
2041         if (r_flags != 0) 
2042           {
2043             fprintf (stderr, "Reloc with flags found!");
2044             if ( r_flags & IMAGE_REL_PPC_NEG ) 
2045               fprintf (stderr, " NEG");
2046             if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2047               fprintf (stderr, " BRTAKEN");
2048             if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2049               fprintf (stderr, " BRNTAKEN");
2050             if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2051                 fprintf (stderr, " TOCDEFN");
2052             fprintf(stderr, "\n");
2053           }
2054 #endif
2055         
2056         DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2057
2058         switch(r_type) 
2059           {
2060           case IMAGE_REL_PPC_TOCREL16:
2061 #if 0
2062             /* FIXME:
2063                This remains unimplemented for now, as it currently adds
2064                un-necessary elements to the toc. All we need to do today
2065                is not do anything if TOCDEFN is on.
2066             */
2067             if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2068               toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec, 
2069                                                         rel->r_symndx, 
2070                                                         default_toc);
2071             else
2072               toc_offset = ppc_record_toc_entry(abfd, info, sec, 
2073                                                 rel->r_symndx, default_toc);
2074 #endif
2075             if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN )
2076               toc_offset = ppc_record_toc_entry(abfd, info, sec, 
2077                                                 rel->r_symndx, default_toc);
2078             break;
2079           case IMAGE_REL_PPC_IMGLUE:
2080             ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
2081             break;
2082           default:
2083             break;
2084           }
2085       }
2086   }
2087
2088   return true;
2089 }
2090
2091 #endif
2092
2093
2094 static bfd_reloc_status_type
2095 ppc_refhi_reloc (abfd,
2096                  reloc_entry,
2097                  symbol,
2098                  data,
2099                  input_section,
2100                  output_bfd,
2101                  error_message)
2102      bfd *abfd;
2103      arelent *reloc_entry;
2104      asymbol *symbol;
2105      PTR data;
2106      asection *input_section;
2107      bfd *output_bfd;
2108      char **error_message;
2109 {
2110   UN_IMPL("REFHI");
2111   DUMP_RELOC("REFHI",reloc_entry);
2112
2113   if (output_bfd == (bfd *) NULL)
2114     return bfd_reloc_continue;
2115
2116   return bfd_reloc_undefined;
2117 }
2118
2119 #if 0
2120
2121 static bfd_reloc_status_type
2122 ppc_reflo_reloc (abfd,
2123                  reloc_entry,
2124                  symbol,
2125                  data,
2126                  input_section,
2127                  output_bfd,
2128                  error_message)
2129      bfd *abfd;
2130      arelent *reloc_entry;
2131      asymbol *symbol;
2132      PTR data;
2133      asection *input_section;
2134      bfd *output_bfd;
2135      char **error_message;
2136 {
2137   UN_IMPL("REFLO");
2138   DUMP_RELOC("REFLO",reloc_entry);
2139
2140   if (output_bfd == (bfd *) NULL)
2141     return bfd_reloc_continue;
2142
2143   return bfd_reloc_undefined;
2144 }
2145
2146 #endif
2147
2148 static bfd_reloc_status_type
2149 ppc_pair_reloc (abfd,
2150                 reloc_entry,
2151                 symbol,
2152                 data,
2153                 input_section,
2154                 output_bfd,
2155                 error_message)
2156      bfd *abfd;
2157      arelent *reloc_entry;
2158      asymbol *symbol;
2159      PTR data;
2160      asection *input_section;
2161      bfd *output_bfd;
2162      char **error_message;
2163 {
2164   UN_IMPL("PAIR");
2165   DUMP_RELOC("PAIR",reloc_entry);
2166
2167   if (output_bfd == (bfd *) NULL)
2168     return bfd_reloc_continue;
2169
2170   return bfd_reloc_undefined;
2171 }
2172
2173 \f
2174 static bfd_reloc_status_type
2175 ppc_toc16_reloc (abfd,
2176                  reloc_entry,
2177                  symbol,
2178                  data,
2179                  input_section,
2180                  output_bfd,
2181                  error_message)
2182      bfd *abfd;
2183      arelent *reloc_entry;
2184      asymbol *symbol;
2185      PTR data;
2186      asection *input_section;
2187      bfd *output_bfd;
2188      char **error_message;
2189 {
2190   UN_IMPL("TOCREL16");
2191   DUMP_RELOC("TOCREL16",reloc_entry);
2192
2193   if (output_bfd == (bfd *) NULL)
2194     {
2195       return bfd_reloc_continue;
2196     }
2197
2198   return bfd_reloc_ok;
2199 }
2200
2201 #if 0
2202
2203 /* ADDR32NB : 32 bit address relative to the virtual origin.         */
2204 /*            (On the alpha, this is always a linker generated thunk)*/
2205 /*            (i.e. 32bit addr relative to the image base)           */
2206 /*                                                                   */
2207 /*                                                                   */
2208
2209 static bfd_reloc_status_type
2210 ppc_addr32nb_reloc (abfd,
2211                     reloc_entry,
2212                     symbol,
2213                     data,
2214                     input_section,
2215                     output_bfd,
2216                     error_message)
2217      bfd *abfd;
2218      arelent *reloc_entry;
2219      asymbol *symbol;
2220      PTR data;
2221      asection *input_section;
2222      bfd *output_bfd;
2223      char **error_message;
2224 {
2225   UN_IMPL("ADDR32NB");
2226   DUMP_RELOC("ADDR32NB",reloc_entry);
2227
2228   return bfd_reloc_ok;
2229 }
2230
2231 #endif
2232
2233 static bfd_reloc_status_type
2234 ppc_secrel_reloc (abfd,
2235                   reloc_entry,
2236                   symbol,
2237                   data,
2238                   input_section,
2239                   output_bfd,
2240                   error_message)
2241      bfd *abfd;
2242      arelent *reloc_entry;
2243      asymbol *symbol;
2244      PTR data;
2245      asection *input_section;
2246      bfd *output_bfd;
2247      char **error_message;
2248 {
2249   UN_IMPL("SECREL");
2250   DUMP_RELOC("SECREL",reloc_entry);
2251
2252   if (output_bfd == (bfd *) NULL)
2253     return bfd_reloc_continue;
2254
2255   return bfd_reloc_ok;
2256 }
2257
2258 static bfd_reloc_status_type
2259 ppc_section_reloc (abfd,
2260                    reloc_entry,
2261                    symbol,
2262                    data,
2263                    input_section,
2264                    output_bfd,
2265                    error_message)
2266      bfd *abfd;
2267      arelent *reloc_entry;
2268      asymbol *symbol;
2269      PTR data;
2270      asection *input_section;
2271      bfd *output_bfd;
2272      char **error_message;
2273 {
2274   UN_IMPL("SECTION");
2275   DUMP_RELOC("SECTION",reloc_entry);
2276
2277   if (output_bfd == (bfd *) NULL)
2278     return bfd_reloc_continue;
2279
2280   return bfd_reloc_ok;
2281 }
2282
2283 static bfd_reloc_status_type
2284 ppc_imglue_reloc (abfd,
2285                   reloc_entry,
2286                   symbol,
2287                   data,
2288                   input_section,
2289                   output_bfd,
2290                   error_message)
2291      bfd *abfd;
2292      arelent *reloc_entry;
2293      asymbol *symbol;
2294      PTR data;
2295      asection *input_section;
2296      bfd *output_bfd;
2297      char **error_message;
2298 {
2299   UN_IMPL("IMGLUE");
2300   DUMP_RELOC("IMGLUE",reloc_entry);
2301
2302   if (output_bfd == (bfd *) NULL)
2303     return bfd_reloc_continue;
2304
2305   return bfd_reloc_ok;
2306 }
2307
2308 \f
2309
2310 #define MAX_RELOC_INDEX  \
2311       (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
2312
2313
2314 /* FIXME: There is a possiblity that when we read in a reloc from a file,
2315           that there are some bits encoded in the upper portion of the 
2316           type field. Not yet implemented.
2317 */
2318 static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
2319                                           struct internal_reloc *internal));
2320
2321 static void
2322 ppc_coff_rtype2howto (relent, internal)
2323      arelent *relent;
2324      struct internal_reloc *internal;
2325 {  
2326
2327   /* We can encode one of three things in the type field, aside from the
2328      type:
2329      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2330         value, rather than an addition value
2331      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2332         the branch is expected to be taken or not.
2333      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2334      For now, we just strip this stuff to find the type, and ignore it other
2335      than that.
2336   */
2337   reloc_howto_type *howto;
2338   unsigned short r_type  = EXTRACT_TYPE (internal->r_type);
2339   unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
2340   unsigned short junk    = EXTRACT_JUNK (internal->r_type);
2341
2342   /* the masking process only slices off the bottom byte for r_type. */
2343   if ( r_type > MAX_RELOC_INDEX ) 
2344     {
2345       fprintf(stderr, 
2346               "ppc_coff_rtype2howto: reloc index %d out of range [%d, %ld]\n",
2347               internal->r_type, 0, (long) MAX_RELOC_INDEX);
2348       abort();
2349     }
2350
2351   /* check for absolute crap */
2352   if ( junk != 0 )
2353     {
2354       fprintf(stderr, 
2355               "ppc_coff_rtype2howto: reloc index %d contains junk %d\n",
2356               internal->r_type, junk);
2357       abort();
2358     }
2359
2360 #ifdef DEBUG_RELOC
2361   /* now examine flags */
2362   if (r_flags != 0) 
2363     {
2364       fprintf (stderr, "Reloc with flags found!");
2365       if ( r_flags & IMAGE_REL_PPC_NEG ) 
2366         fprintf (stderr, " NEG");
2367       if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2368         fprintf (stderr, " BRTAKEN");
2369       if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2370         fprintf (stderr, " BRNTAKEN");
2371       if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2372         fprintf (stderr, " TOCDEFN");
2373       fprintf(stderr, "\n");
2374     }
2375 #endif
2376
2377   switch(r_type) 
2378     {
2379     case IMAGE_REL_PPC_ADDR16:
2380     case IMAGE_REL_PPC_REL24:
2381     case IMAGE_REL_PPC_ADDR24:
2382     case IMAGE_REL_PPC_ADDR32:
2383     case IMAGE_REL_PPC_IFGLUE:
2384     case IMAGE_REL_PPC_ADDR32NB:
2385     case IMAGE_REL_PPC_SECTION:
2386     case IMAGE_REL_PPC_SECREL:
2387       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2388       howto = ppc_coff_howto_table + r_type;
2389       break;
2390     case IMAGE_REL_PPC_IMGLUE:
2391       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2392       howto = ppc_coff_howto_table + r_type;
2393       break;
2394     case IMAGE_REL_PPC_TOCREL16:
2395       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2396       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2397         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2398       else
2399         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
2400       break;
2401     default:
2402       fprintf(stderr, 
2403               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2404               ppc_coff_howto_table[r_type].name,
2405               r_type);
2406       howto = ppc_coff_howto_table + r_type;      
2407       break;
2408     }
2409   
2410   relent->howto = howto;
2411   
2412 }
2413
2414 static reloc_howto_type *
2415 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
2416      bfd *abfd;
2417      asection *sec;
2418      struct internal_reloc *rel;
2419      struct coff_link_hash_entry *h;
2420      struct internal_syment *sym;
2421      bfd_vma *addendp;
2422 {
2423   reloc_howto_type *howto;
2424
2425   /* We can encode one of three things in the type field, aside from the
2426      type:
2427      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2428         value, rather than an addition value
2429      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2430         the branch is expected to be taken or not.
2431      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2432      For now, we just strip this stuff to find the type, and ignore it other
2433      than that.
2434   */
2435
2436   unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
2437   unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2438   unsigned short junk    = EXTRACT_JUNK (rel->r_type);
2439
2440   /* the masking process only slices off the bottom byte for r_type. */
2441   if ( r_type > MAX_RELOC_INDEX ) 
2442     {
2443       fprintf(stderr, 
2444               "coff_ppc_rtype_to_howto: index %d out of range [%d, %ld]\n",
2445               r_type, 0, (long) MAX_RELOC_INDEX);
2446       abort();
2447     }
2448   
2449   /* check for absolute crap */
2450   if ( junk != 0 )
2451     {
2452       fprintf(stderr, 
2453               "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n",
2454               rel->r_type, junk);
2455       abort();
2456     }
2457   
2458 #ifdef DEBUG_RELOC
2459   /* now examine flags */
2460   if (r_flags != 0) 
2461     {
2462       fprintf (stderr, "Reloc with flags found!");
2463       if ( r_flags & IMAGE_REL_PPC_NEG ) 
2464         fprintf (stderr, " NEG");
2465       if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2466         fprintf (stderr, " BRTAKEN");
2467       if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2468         fprintf (stderr, " BRNTAKEN");
2469       if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2470         fprintf (stderr, " TOCDEFN");
2471       fprintf(stderr, "\n");
2472     }
2473 #endif
2474   
2475   switch(r_type) 
2476     {
2477     case IMAGE_REL_PPC_ADDR32NB:
2478       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2479       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
2480       howto = ppc_coff_howto_table + r_type;
2481       break;
2482     case IMAGE_REL_PPC_TOCREL16:
2483       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2484       if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2485         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2486       else
2487         howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
2488       break;
2489     case IMAGE_REL_PPC_ADDR16:
2490     case IMAGE_REL_PPC_REL24:
2491     case IMAGE_REL_PPC_ADDR24:
2492     case IMAGE_REL_PPC_ADDR32:
2493     case IMAGE_REL_PPC_IFGLUE:
2494     case IMAGE_REL_PPC_SECTION:
2495     case IMAGE_REL_PPC_SECREL:
2496       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2497       howto = ppc_coff_howto_table + r_type;
2498       break;
2499     case IMAGE_REL_PPC_IMGLUE:
2500       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2501       howto = ppc_coff_howto_table + r_type;
2502       break;
2503     default:
2504       fprintf(stderr, 
2505               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2506               ppc_coff_howto_table[r_type].name,
2507               r_type);
2508       howto = ppc_coff_howto_table + r_type;
2509       break;
2510     }
2511   
2512   return howto;
2513 }
2514
2515
2516 /* a cheesy little macro to make the code a little more readable */
2517 #define HOW2MAP(bfd_rtype,ppc_rtype)  \
2518  case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
2519
2520 static reloc_howto_type *ppc_coff_reloc_type_lookup
2521 PARAMS ((bfd *, bfd_reloc_code_real_type));
2522
2523 static reloc_howto_type *
2524 ppc_coff_reloc_type_lookup (abfd, code)
2525      bfd *abfd;
2526      bfd_reloc_code_real_type code;
2527 {
2528   
2529 #ifdef DEBUG_RELOC
2530   fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n",
2531           bfd_get_reloc_code_name(code));
2532 #endif
2533
2534   switch (code)
2535     {
2536       HOW2MAP(BFD_RELOC_32_GOTOFF,    IMAGE_REL_PPC_IMGLUE);
2537       HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
2538       HOW2MAP(BFD_RELOC_16,           IMAGE_REL_PPC_ADDR16);
2539       HOW2MAP(BFD_RELOC_PPC_B26,      IMAGE_REL_PPC_REL24);
2540       HOW2MAP(BFD_RELOC_PPC_BA26,     IMAGE_REL_PPC_ADDR24);
2541       HOW2MAP(BFD_RELOC_PPC_TOC16,    IMAGE_REL_PPC_TOCREL16);
2542       HOW2MAP(BFD_RELOC_16_GOTOFF,    IMAGE_REL_PPC_TOCREL16_DEFN);
2543       HOW2MAP(BFD_RELOC_32,           IMAGE_REL_PPC_ADDR32);
2544       HOW2MAP(BFD_RELOC_RVA,          IMAGE_REL_PPC_ADDR32NB);
2545     default: 
2546       return NULL;
2547     }
2548   
2549   return NULL;
2550 }
2551
2552 #undef HOW2MAP
2553
2554 \f
2555 /* Tailor coffcode.h -- macro heaven. */
2556
2557 #define RTYPE2HOWTO(cache_ptr, dst)  ppc_coff_rtype2howto (cache_ptr, dst)
2558
2559 #ifndef COFF_IMAGE_WITH_PE
2560 static void
2561 ppc_coff_swap_sym_in_hook ();
2562 #endif
2563
2564 /* We use the special COFF backend linker, with our own special touch.  */
2565
2566 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
2567 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
2568 #define coff_relocate_section        coff_ppc_relocate_section
2569 #define coff_bfd_final_link          ppc_bfd_coff_final_link 
2570
2571 #ifndef COFF_IMAGE_WITH_PE
2572 #define coff_swap_sym_in_hook        ppc_coff_swap_sym_in_hook
2573 #endif
2574
2575 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
2576
2577 #define COFF_PAGE_SIZE                       0x1000
2578
2579 #define POWERPC_LE_PE
2580
2581 #include "coffcode.h"
2582
2583 \f
2584
2585 #ifndef COFF_IMAGE_WITH_PE
2586 /* FIXME:
2587    What we're trying to do here is allocate a toc section (early), and attach 
2588    it to the last bfd to be processed. This avoids the problem of having a toc
2589    written out before all files have been processed. This code allocates
2590    a toc section for every file, and records the last one seen. There are
2591    at least two problems with this approach:
2592    1. We allocate whole bunches of toc sections that are ignored, but at
2593       at least we will not allocate a toc if no .toc is present.
2594    2. It's not clear to me that being the last bfd read necessarily means
2595       that you are the last bfd closed.
2596    3. Doing it on a "swap in" hook depends on when the "swap in" is called,
2597       and how often, etc. It's not clear to me that there isn't a hole here.
2598 */
2599
2600 static void
2601 ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
2602      bfd            *abfd;
2603      PTR ext1;
2604      PTR in1;
2605 {
2606   struct internal_syment      *in = (struct internal_syment *)in1;
2607
2608   if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
2609     return;
2610
2611   if (strcmp(in->_n._n_name, ".toc") == 0)
2612     {
2613       flagword flags;
2614       register asection *s;
2615
2616       s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
2617       if (s != NULL) 
2618         {
2619           return;
2620         }
2621
2622       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2623
2624 #ifdef TOC_DEBUG
2625       fprintf(stderr,
2626               "ppc_coff_swap_sym_in_hook: about to create the %s section\n",
2627               TOC_SECTION_NAME);
2628 #endif
2629
2630       s = bfd_make_section (abfd, TOC_SECTION_NAME);
2631
2632       if (s == NULL
2633           || !bfd_set_section_flags (abfd, s, flags)
2634           || !bfd_set_section_alignment (abfd, s, 2))
2635         {
2636           fprintf(stderr,
2637                   "toc section allocation failed!\n");
2638           abort();
2639         }
2640
2641       /* save the bfd for later allocation */
2642       bfd_of_toc_owner = abfd;
2643     }
2644
2645   return;
2646 }
2647 #endif
2648
2649 boolean
2650 ppc_bfd_coff_final_link ();
2651
2652 #ifndef COFF_IMAGE_WITH_PE
2653
2654 static boolean
2655 ppc_do_last(abfd)
2656      bfd *abfd;
2657 {
2658   if (abfd == bfd_of_toc_owner)
2659     return true;
2660   else
2661     return false;
2662 }
2663
2664 static bfd *
2665 ppc_get_last()
2666 {
2667   return bfd_of_toc_owner;
2668 }
2669
2670 /* this piece of machinery exists only to guarantee that the bfd that holds
2671    the toc section is written last. 
2672
2673    This does depend on bfd_make_section attaching a new section to the
2674    end of the section list for the bfd. 
2675
2676    This is otherwise intended to be functionally the same as 
2677    cofflink.c:_bfd_coff_final_link(). It is specifically different only 
2678    where the POWERPC_LE_PE macro modifies the code. It is left in as a 
2679    precise form of comment. krk@cygnus.com
2680 */
2681 #define POWERPC_LE_PE
2682
2683
2684 /* Do the final link step.  */
2685
2686 boolean
2687 ppc_bfd_coff_final_link (abfd, info)
2688      bfd *abfd;
2689      struct bfd_link_info *info;
2690 {
2691   bfd_size_type symesz;
2692   struct coff_final_link_info finfo;
2693   boolean debug_merge_allocated;
2694   asection *o;
2695   struct bfd_link_order *p;
2696   size_t max_sym_count;
2697   size_t max_lineno_count;
2698   size_t max_reloc_count;
2699   size_t max_output_reloc_count;
2700   size_t max_contents_size;
2701   file_ptr rel_filepos;
2702   unsigned int relsz;
2703   file_ptr line_filepos;
2704   unsigned int linesz;
2705   bfd *sub;
2706   bfd_byte *external_relocs = NULL;
2707   char strbuf[STRING_SIZE_SIZE];
2708
2709   symesz = bfd_coff_symesz (abfd);
2710
2711   finfo.info = info;
2712   finfo.output_bfd = abfd;
2713   finfo.strtab = NULL;
2714   finfo.section_info = NULL;
2715   finfo.last_file_index = -1;
2716   finfo.internal_syms = NULL;
2717   finfo.sec_ptrs = NULL;
2718   finfo.sym_indices = NULL;
2719   finfo.outsyms = NULL;
2720   finfo.linenos = NULL;
2721   finfo.contents = NULL;
2722   finfo.external_relocs = NULL;
2723   finfo.internal_relocs = NULL;
2724   debug_merge_allocated = false;
2725
2726   coff_data (abfd)->link_info = info;
2727
2728   finfo.strtab = _bfd_stringtab_init ();
2729   if (finfo.strtab == NULL)
2730     goto error_return;
2731
2732   if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
2733     goto error_return;
2734   debug_merge_allocated = true;
2735
2736   /* Compute the file positions for all the sections.  */
2737   if (! abfd->output_has_begun)
2738     bfd_coff_compute_section_file_positions (abfd);
2739
2740   /* Count the line numbers and relocation entries required for the
2741      output file.  Set the file positions for the relocs.  */
2742   rel_filepos = obj_relocbase (abfd);
2743   relsz = bfd_coff_relsz (abfd);
2744   max_contents_size = 0;
2745   max_lineno_count = 0;
2746   max_reloc_count = 0;
2747
2748   for (o = abfd->sections; o != NULL; o = o->next)
2749     {
2750       o->reloc_count = 0;
2751       o->lineno_count = 0;
2752       for (p = o->link_order_head; p != NULL; p = p->next)
2753         {
2754
2755           if (p->type == bfd_indirect_link_order)
2756             {
2757               asection *sec;
2758
2759               sec = p->u.indirect.section;
2760
2761               /* Mark all sections which are to be included in the
2762                  link.  This will normally be every section.  We need
2763                  to do this so that we can identify any sections which
2764                  the linker has decided to not include.  */
2765               sec->linker_mark = true;
2766
2767               if (info->strip == strip_none
2768                   || info->strip == strip_some)
2769                 o->lineno_count += sec->lineno_count;
2770
2771               if (info->relocateable)
2772                 o->reloc_count += sec->reloc_count;
2773
2774               if (sec->_raw_size > max_contents_size)
2775                 max_contents_size = sec->_raw_size;
2776               if (sec->lineno_count > max_lineno_count)
2777                 max_lineno_count = sec->lineno_count;
2778               if (sec->reloc_count > max_reloc_count)
2779                 max_reloc_count = sec->reloc_count;
2780             }
2781           else if (info->relocateable
2782                    && (p->type == bfd_section_reloc_link_order
2783                        || p->type == bfd_symbol_reloc_link_order))
2784             ++o->reloc_count;
2785         }
2786       if (o->reloc_count == 0)
2787         o->rel_filepos = 0;
2788       else
2789         {
2790           o->flags |= SEC_RELOC;
2791           o->rel_filepos = rel_filepos;
2792           rel_filepos += o->reloc_count * relsz;
2793         }
2794     }
2795
2796   /* If doing a relocateable link, allocate space for the pointers we
2797      need to keep.  */
2798   if (info->relocateable)
2799     {
2800       unsigned int i;
2801
2802       /* We use section_count + 1, rather than section_count, because
2803          the target_index fields are 1 based.  */
2804       finfo.section_info =
2805         ((struct coff_link_section_info *)
2806          bfd_malloc ((abfd->section_count + 1)
2807                      * sizeof (struct coff_link_section_info)));
2808       if (finfo.section_info == NULL)
2809         goto error_return;
2810       for (i = 0; i <= abfd->section_count; i++)
2811         {
2812           finfo.section_info[i].relocs = NULL;
2813           finfo.section_info[i].rel_hashes = NULL;
2814         }
2815     }
2816
2817   /* We now know the size of the relocs, so we can determine the file
2818      positions of the line numbers.  */
2819   line_filepos = rel_filepos;
2820   linesz = bfd_coff_linesz (abfd);
2821   max_output_reloc_count = 0;
2822   for (o = abfd->sections; o != NULL; o = o->next)
2823     {
2824       if (o->lineno_count == 0)
2825         o->line_filepos = 0;
2826       else
2827         {
2828           o->line_filepos = line_filepos;
2829           line_filepos += o->lineno_count * linesz;
2830         }
2831
2832       if (o->reloc_count != 0)
2833         {
2834           /* We don't know the indices of global symbols until we have
2835              written out all the local symbols.  For each section in
2836              the output file, we keep an array of pointers to hash
2837              table entries.  Each entry in the array corresponds to a
2838              reloc.  When we find a reloc against a global symbol, we
2839              set the corresponding entry in this array so that we can
2840              fix up the symbol index after we have written out all the
2841              local symbols.
2842
2843              Because of this problem, we also keep the relocs in
2844              memory until the end of the link.  This wastes memory,
2845              but only when doing a relocateable link, which is not the
2846              common case.  */
2847           BFD_ASSERT (info->relocateable);
2848           finfo.section_info[o->target_index].relocs =
2849             ((struct internal_reloc *)
2850              bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
2851           finfo.section_info[o->target_index].rel_hashes =
2852             ((struct coff_link_hash_entry **)
2853              bfd_malloc (o->reloc_count
2854                      * sizeof (struct coff_link_hash_entry *)));
2855           if (finfo.section_info[o->target_index].relocs == NULL
2856               || finfo.section_info[o->target_index].rel_hashes == NULL)
2857             goto error_return;
2858
2859           if (o->reloc_count > max_output_reloc_count)
2860             max_output_reloc_count = o->reloc_count;
2861         }
2862
2863       /* Reset the reloc and lineno counts, so that we can use them to
2864          count the number of entries we have output so far.  */
2865       o->reloc_count = 0;
2866       o->lineno_count = 0;
2867     }
2868
2869   obj_sym_filepos (abfd) = line_filepos;
2870
2871   /* Figure out the largest number of symbols in an input BFD.  Take
2872      the opportunity to clear the output_has_begun fields of all the
2873      input BFD's.  */
2874   max_sym_count = 0;
2875   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
2876     {
2877       size_t sz;
2878
2879       sub->output_has_begun = false;
2880       sz = obj_raw_syment_count (sub);
2881       if (sz > max_sym_count)
2882         max_sym_count = sz;
2883     }
2884
2885   /* Allocate some buffers used while linking.  */
2886   finfo.internal_syms = ((struct internal_syment *)
2887                          bfd_malloc (max_sym_count
2888                                      * sizeof (struct internal_syment)));
2889   finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
2890                                              * sizeof (asection *));
2891   finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
2892   finfo.outsyms = ((bfd_byte *)
2893                    bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
2894   finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
2895                                        * bfd_coff_linesz (abfd));
2896   finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
2897   finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
2898   if (! info->relocateable)
2899     finfo.internal_relocs = ((struct internal_reloc *)
2900                              bfd_malloc (max_reloc_count
2901                                          * sizeof (struct internal_reloc)));
2902   if ((finfo.internal_syms == NULL && max_sym_count > 0)
2903       || (finfo.sec_ptrs == NULL && max_sym_count > 0)
2904       || (finfo.sym_indices == NULL && max_sym_count > 0)
2905       || finfo.outsyms == NULL
2906       || (finfo.linenos == NULL && max_lineno_count > 0)
2907       || (finfo.contents == NULL && max_contents_size > 0)
2908       || (finfo.external_relocs == NULL && max_reloc_count > 0)
2909       || (! info->relocateable
2910           && finfo.internal_relocs == NULL
2911           && max_reloc_count > 0))
2912     goto error_return;
2913
2914   /* We now know the position of everything in the file, except that
2915      we don't know the size of the symbol table and therefore we don't
2916      know where the string table starts.  We just build the string
2917      table in memory as we go along.  We process all the relocations
2918      for a single input file at once.  */
2919   obj_raw_syment_count (abfd) = 0;
2920
2921   if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
2922     {
2923       if (! bfd_coff_start_final_link (abfd, info))
2924         goto error_return;
2925     }
2926
2927   for (o = abfd->sections; o != NULL; o = o->next)
2928     {
2929       for (p = o->link_order_head; p != NULL; p = p->next)
2930         {
2931           if (p->type == bfd_indirect_link_order
2932               && (bfd_get_flavour (p->u.indirect.section->owner)
2933                   == bfd_target_coff_flavour))
2934             {
2935               sub = p->u.indirect.section->owner;
2936 #ifdef POWERPC_LE_PE
2937               if (! sub->output_has_begun && !ppc_do_last(sub))
2938 #else
2939               if (! sub->output_has_begun)
2940 #endif
2941                 {
2942                   if (! _bfd_coff_link_input_bfd (&finfo, sub))
2943                     goto error_return;
2944                   sub->output_has_begun = true;
2945                 }
2946             }
2947           else if (p->type == bfd_section_reloc_link_order
2948                    || p->type == bfd_symbol_reloc_link_order)
2949             {
2950               if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
2951                 goto error_return;
2952             }
2953           else
2954             {
2955               if (! _bfd_default_link_order (abfd, info, o, p))
2956                 goto error_return;
2957             }
2958         }
2959     }
2960
2961 #ifdef POWERPC_LE_PE
2962   {
2963     extern bfd* ppc_get_last();
2964     bfd* last_one = ppc_get_last();
2965     if (last_one)
2966       {
2967         if (! _bfd_coff_link_input_bfd (&finfo, last_one))
2968           goto error_return;
2969       }
2970     last_one->output_has_begun = true;
2971   }
2972 #endif
2973
2974   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
2975
2976   coff_debug_merge_hash_table_free (&finfo.debug_merge);
2977   debug_merge_allocated = false;
2978
2979   if (finfo.internal_syms != NULL)
2980     {
2981       free (finfo.internal_syms);
2982       finfo.internal_syms = NULL;
2983     }
2984   if (finfo.sec_ptrs != NULL)
2985     {
2986       free (finfo.sec_ptrs);
2987       finfo.sec_ptrs = NULL;
2988     }
2989   if (finfo.sym_indices != NULL)
2990     {
2991       free (finfo.sym_indices);
2992       finfo.sym_indices = NULL;
2993     }
2994   if (finfo.linenos != NULL)
2995     {
2996       free (finfo.linenos);
2997       finfo.linenos = NULL;
2998     }
2999   if (finfo.contents != NULL)
3000     {
3001       free (finfo.contents);
3002       finfo.contents = NULL;
3003     }
3004   if (finfo.external_relocs != NULL)
3005     {
3006       free (finfo.external_relocs);
3007       finfo.external_relocs = NULL;
3008     }
3009   if (finfo.internal_relocs != NULL)
3010     {
3011       free (finfo.internal_relocs);
3012       finfo.internal_relocs = NULL;
3013     }
3014
3015   /* The value of the last C_FILE symbol is supposed to be the symbol
3016      index of the first external symbol.  Write it out again if
3017      necessary.  */
3018   if (finfo.last_file_index != -1
3019       && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
3020     {
3021       finfo.last_file.n_value = obj_raw_syment_count (abfd);
3022       bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
3023                              (PTR) finfo.outsyms);
3024       if (bfd_seek (abfd,
3025                     (obj_sym_filepos (abfd)
3026                      + finfo.last_file_index * symesz),
3027                     SEEK_SET) != 0
3028           || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
3029         return false;
3030     }
3031
3032   /* Write out the global symbols.  */
3033   finfo.failed = false;
3034   coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
3035                            (PTR) &finfo);
3036   if (finfo.failed)
3037     goto error_return;
3038
3039   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
3040   if (finfo.outsyms != NULL)
3041     {
3042       free (finfo.outsyms);
3043       finfo.outsyms = NULL;
3044     }
3045
3046   if (info->relocateable)
3047     {
3048       /* Now that we have written out all the global symbols, we know
3049          the symbol indices to use for relocs against them, and we can
3050          finally write out the relocs.  */
3051       external_relocs = ((bfd_byte *)
3052                          bfd_malloc (max_output_reloc_count * relsz));
3053       if (external_relocs == NULL)
3054         goto error_return;
3055
3056       for (o = abfd->sections; o != NULL; o = o->next)
3057         {
3058           struct internal_reloc *irel;
3059           struct internal_reloc *irelend;
3060           struct coff_link_hash_entry **rel_hash;
3061           bfd_byte *erel;
3062
3063           if (o->reloc_count == 0)
3064             continue;
3065
3066           irel = finfo.section_info[o->target_index].relocs;
3067           irelend = irel + o->reloc_count;
3068           rel_hash = finfo.section_info[o->target_index].rel_hashes;
3069           erel = external_relocs;
3070           for (; irel < irelend; irel++, rel_hash++, erel += relsz)
3071             {
3072               if (*rel_hash != NULL)
3073                 {
3074                   BFD_ASSERT ((*rel_hash)->indx >= 0);
3075                   irel->r_symndx = (*rel_hash)->indx;
3076                 }
3077               bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
3078             }
3079
3080           if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
3081               || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
3082                             abfd) != relsz * o->reloc_count)
3083             goto error_return;
3084         }
3085
3086       free (external_relocs);
3087       external_relocs = NULL;
3088     }
3089
3090   /* Free up the section information.  */
3091   if (finfo.section_info != NULL)
3092     {
3093       unsigned int i;
3094
3095       for (i = 0; i < abfd->section_count; i++)
3096         {
3097           if (finfo.section_info[i].relocs != NULL)
3098             free (finfo.section_info[i].relocs);
3099           if (finfo.section_info[i].rel_hashes != NULL)
3100             free (finfo.section_info[i].rel_hashes);
3101         }
3102       free (finfo.section_info);
3103       finfo.section_info = NULL;
3104     }
3105
3106   /* Write out the string table.  */
3107   if (obj_raw_syment_count (abfd) != 0)
3108     {
3109       if (bfd_seek (abfd,
3110                     (obj_sym_filepos (abfd)
3111                      + obj_raw_syment_count (abfd) * symesz),
3112                     SEEK_SET) != 0)
3113         return false;
3114
3115 #if STRING_SIZE_SIZE == 4
3116       bfd_h_put_32 (abfd,
3117                     _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
3118                     (bfd_byte *) strbuf);
3119 #else
3120  #error Change bfd_h_put_32
3121 #endif
3122
3123       if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
3124         return false;
3125
3126       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
3127         return false;
3128     }
3129
3130   _bfd_stringtab_free (finfo.strtab);
3131
3132   /* Setting bfd_get_symcount to 0 will cause write_object_contents to
3133      not try to write out the symbols.  */
3134   bfd_get_symcount (abfd) = 0;
3135
3136   return true;
3137
3138  error_return:
3139   if (debug_merge_allocated)
3140     coff_debug_merge_hash_table_free (&finfo.debug_merge);
3141   if (finfo.strtab != NULL)
3142     _bfd_stringtab_free (finfo.strtab);
3143   if (finfo.section_info != NULL)
3144     {
3145       unsigned int i;
3146
3147       for (i = 0; i < abfd->section_count; i++)
3148         {
3149           if (finfo.section_info[i].relocs != NULL)
3150             free (finfo.section_info[i].relocs);
3151           if (finfo.section_info[i].rel_hashes != NULL)
3152             free (finfo.section_info[i].rel_hashes);
3153         }
3154       free (finfo.section_info);
3155     }
3156   if (finfo.internal_syms != NULL)
3157     free (finfo.internal_syms);
3158   if (finfo.sec_ptrs != NULL)
3159     free (finfo.sec_ptrs);
3160   if (finfo.sym_indices != NULL)
3161     free (finfo.sym_indices);
3162   if (finfo.outsyms != NULL)
3163     free (finfo.outsyms);
3164   if (finfo.linenos != NULL)
3165     free (finfo.linenos);
3166   if (finfo.contents != NULL)
3167     free (finfo.contents);
3168   if (finfo.external_relocs != NULL)
3169     free (finfo.external_relocs);
3170   if (finfo.internal_relocs != NULL)
3171     free (finfo.internal_relocs);
3172   if (external_relocs != NULL)
3173     free (external_relocs);
3174   return false;
3175 }
3176 #endif
3177 \f
3178
3179 /* The transfer vectors that lead the outside world to all of the above. */
3180
3181 #ifdef TARGET_LITTLE_SYM
3182 const bfd_target
3183 TARGET_LITTLE_SYM =
3184 {
3185   TARGET_LITTLE_NAME,           /* name or coff-arm-little */
3186   bfd_target_coff_flavour,
3187   BFD_ENDIAN_LITTLE,            /* data byte order is little */
3188   BFD_ENDIAN_LITTLE,            /* header byte order is little */
3189
3190   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
3191    HAS_LINENO | HAS_DEBUG |
3192    HAS_SYMS | HAS_LOCALS | WP_TEXT),
3193   
3194   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
3195   0,                            /* leading char */
3196   '/',                          /* ar_pad_char */
3197   15,                           /* ar_max_namelen??? FIXMEmgo */
3198
3199   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
3200   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3201   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
3202
3203   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
3204   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3205   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
3206   
3207   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
3208      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
3209   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3210      bfd_false},
3211   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
3212      _bfd_write_archive_contents, bfd_false},
3213   
3214   BFD_JUMP_TABLE_GENERIC (coff),
3215   BFD_JUMP_TABLE_COPY (coff),
3216   BFD_JUMP_TABLE_CORE (_bfd_nocore),
3217   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3218   BFD_JUMP_TABLE_SYMBOLS (coff),
3219   BFD_JUMP_TABLE_RELOCS (coff),
3220   BFD_JUMP_TABLE_WRITE (coff),
3221   BFD_JUMP_TABLE_LINK (coff),
3222   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3223   
3224   COFF_SWAP_TABLE,
3225 };
3226 #endif
3227
3228 #ifdef TARGET_BIG_SYM
3229 const bfd_target
3230 TARGET_BIG_SYM =
3231 {
3232   TARGET_BIG_NAME,
3233   bfd_target_coff_flavour,      
3234   BFD_ENDIAN_BIG,               /* data byte order is big */
3235   BFD_ENDIAN_BIG,               /* header byte order is big */
3236
3237   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
3238    HAS_LINENO | HAS_DEBUG |
3239    HAS_SYMS | HAS_LOCALS | WP_TEXT),
3240
3241   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
3242   0,                            /* leading char */
3243   '/',                          /* ar_pad_char */
3244   15,                           /* ar_max_namelen??? FIXMEmgo */
3245
3246   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3247   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3248   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
3249
3250   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3251   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3252   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
3253
3254   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
3255      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
3256   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3257      bfd_false},
3258   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
3259      _bfd_write_archive_contents, bfd_false},
3260
3261   BFD_JUMP_TABLE_GENERIC (coff),
3262   BFD_JUMP_TABLE_COPY (coff),
3263   BFD_JUMP_TABLE_CORE (_bfd_nocore),
3264   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3265   BFD_JUMP_TABLE_SYMBOLS (coff),
3266   BFD_JUMP_TABLE_RELOCS (coff),
3267   BFD_JUMP_TABLE_WRITE (coff),
3268   BFD_JUMP_TABLE_LINK (coff),
3269   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3270
3271   COFF_SWAP_TABLE,
3272 };
3273
3274 #endif