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