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