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