Change PAGE_SIZE to TARGET_PAGE_SIZE
[platform/upstream/binutils.git] / bfd / coff-ppc.c
1 /* BFD back-end for PowerPC Microsoft Portable Executable files.
2    Copyright 1990, 1991, 1992, 1993, 1994 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 */
30
31
32 #include "bfd.h"
33 #include "sysdep.h"
34 #include "libbfd.h"
35 #include "obstack.h"
36
37 #include "coff/powerpc.h"
38 #include "coff/internal.h"
39
40 #include "coff/pe.h"
41
42 #ifdef BADMAG
43 #undef BADMAG
44 #endif
45
46 #define BADMAG(x) PPCBADMAG(x)
47
48 #include "libcoff.h"
49
50 /* The main body of code is in coffcode.h.  */
51
52 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
53
54 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
55    from smaller values.  Start with zero, widen, *then* decrement.  */
56 #define MINUS_ONE       (((bfd_vma)0) - 1)
57
58 /* these should definitely go in a header file somewhere... */
59
60 /* NOP */
61 #define IMAGE_REL_PPC_ABSOLUTE          0x0000
62
63 /* 64-bit address */
64 #define IMAGE_REL_PPC_ADDR64            0x0001
65
66 /* 32-bit address */
67 #define IMAGE_REL_PPC_ADDR32            0x0002
68
69 /* 26-bit address, shifted left 2 (branch absolute) */
70 #define IMAGE_REL_PPC_ADDR24            0x0003
71
72 /* 16-bit address */
73 #define IMAGE_REL_PPC_ADDR16            0x0004
74
75 /* 16-bit address, shifted left 2 (load doubleword) */
76 #define IMAGE_REL_PPC_ADDR14            0x0005
77
78 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
79 #define IMAGE_REL_PPC_REL24             0x0006
80
81 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
82 #define IMAGE_REL_PPC_REL14             0x0007
83
84 /* 16-bit offset from TOC base */
85 #define IMAGE_REL_PPC_TOCREL16          0x0008
86
87 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
88 #define IMAGE_REL_PPC_TOCREL14          0x0009
89
90 /* 32-bit addr w/o image base */
91 #define IMAGE_REL_PPC_ADDR32NB          0x000A
92
93 /* va of containing section (as in an image sectionhdr) */
94 #define IMAGE_REL_PPC_SECREL            0x000B
95
96 /* sectionheader number */
97 #define IMAGE_REL_PPC_SECTION           0x000C
98
99 /* substitute TOC restore instruction iff symbol is glue code */
100 #define IMAGE_REL_PPC_IFGLUE            0x000D
101
102 /* symbol is glue code; virtual address is TOC restore instruction */
103 #define IMAGE_REL_PPC_IMGLUE            0x000E
104
105 /* va of containing section (limited to 16 bits) */
106 #define IMAGE_REL_PPC_SECREL16          0x000F
107
108 /* stuff to handle immediate data when the number of bits in the */
109 /* data is greater than the number of bits in the immediate field */
110 /* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
111 #define IMAGE_REL_PPC_REFHI             0x0010
112 #define IMAGE_REL_PPC_REFLO             0x0011
113 #define IMAGE_REL_PPC_PAIR              0x0012
114
115
116 /*  Flag bits in IMAGE_RELOCATION.TYPE */
117
118 /* subtract reloc value rather than adding it */
119 #define IMAGE_REL_PPC_NEG               0x0100
120
121 /* fix branch prediction bit to predict branch taken */
122 #define IMAGE_REL_PPC_BRTAKEN           0x0200
123
124 /* fix branch prediction bit to predict branch not taken */
125 #define IMAGE_REL_PPC_BRNTAKEN          0x0400
126
127 /* toc slot defined in file (or, data in toc) */
128 #define IMAGE_REL_PPC_TOCDEFN           0x0800
129
130 /* masks to isolate above values in IMAGE_RELOCATION.Type */
131 #define IMAGE_REL_PPC_TYPEMASK          0x00FF
132 #define IMAGE_REL_PPC_FLAGMASK          0x0F00
133
134 #define EXTRACT_TYPE(x)                 ((x) & IMAGE_REL_PPC_TYPEMASK)
135 #define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
136 #define EXTRACT_JUNK(x)  \
137            ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
138
139 \f
140 /* static helper functions to make relocation work */
141 /* (Work In Progress) */
142
143 static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
144                                                       arelent *reloc,
145                                                       asymbol *symbol,
146                                                       PTR data,
147                                                       asection *section,
148                                                       bfd *output_bfd,
149                                                       char **error));
150 static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
151                                                       arelent *reloc,
152                                                       asymbol *symbol,
153                                                       PTR data,
154                                                       asection *section,
155                                                       bfd *output_bfd,
156                                                       char **error));
157 static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
158                                                      arelent *reloc,
159                                                      asymbol *symbol,
160                                                      PTR data,
161                                                      asection *section,
162                                                      bfd *output_bfd,
163                                                      char **error));
164
165 \f
166 static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
167                                                       arelent *reloc,
168                                                       asymbol *symbol,
169                                                       PTR data,
170                                                       asection *section,
171                                                       bfd *output_bfd,
172                                                       char **error));
173
174 static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
175                                                          arelent *reloc,
176                                                          asymbol *symbol,
177                                                          PTR data,
178                                                          asection *section,
179                                                          bfd *output_bfd,
180                                                          char **error));
181
182 static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
183                                                         arelent *reloc,
184                                                         asymbol *symbol,
185                                                         PTR data,
186                                                         asection *section,
187                                                         bfd *output_bfd,
188                                                         char **error));
189
190 static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
191                                                        arelent *reloc,
192                                                        asymbol *symbol,
193                                                        PTR data,
194                                                        asection *section,
195                                                        bfd *output_bfd,
196                                                        char **error));
197
198 static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
199                                                        arelent *reloc,
200                                                        asymbol *symbol,
201                                                        PTR data,
202                                                        asection *section,
203                                                        bfd *output_bfd,
204                                                        char **error));
205
206
207
208
209 \f
210 /* FIXME: It'll take a while to get through all of these. I only need a few to
211    get us started, so those I'll make sure work. Those marked FIXME are either
212    completely unverified or have a specific unknown marked in the comment */
213
214 /*---------------------------------------------------------------------------*/
215 /*                                                                           */
216 /* Relocation entries for Windows/NT on PowerPC.                             */
217 /*                                                                           */
218 /* From the document "" we find the following listed as used relocs:         */
219 /*                                                                           */
220 /*   ABSOLUTE       : The noop                                               */
221 /*   ADDR[64|32|16] : fields that hold addresses in data fields or the       */
222 /*                    16 bit displacement field on a load/store.             */
223 /*   ADDR[24|14]    : fields that hold addresses in branch and cond          */
224 /*                    branches. These represent [26|16] bit addresses.       */
225 /*                    The low order 2 bits are preserved.                    */
226 /*   REL[24|14]     : branches relative to the Instruction Address           */
227 /*                    register. These represent [26|16] bit addresses,       */
228 /*                    as before. The instruction field will be zero, and     */
229 /*                    the address of the SYM will be inserted at link time.  */
230 /*   TOCREL16       : 16 bit displacement field referring to a slot in       */
231 /*                    toc.                                                   */
232 /*   TOCREL14       : 16 bit displacement field, similar to REL14 or ADDR14. */
233 /*   ADDR32NB       : 32 bit address relative to the virtual origin.         */
234 /*                    (On the alpha, this is always a linker generated thunk)*/
235 /*                    (i.e. 32bit addr relative to the image base)           */
236 /*   SECREL         : The value is relative to the start of the section      */
237 /*                    containing the symbol.                                 */
238 /*   SECTION        : access to the header containing the item. Supports the */
239 /*                    codeview debugger.                                     */
240 /*                                                                           */
241 /* In particular, note that the document does not indicate that the          */
242 /* relocations listed in the header file are used.                           */
243 /*                                                                           */
244 /*                                                                           */
245 /*                                                                           */
246 /*---------------------------------------------------------------------------*/
247
248 static reloc_howto_type ppc_coff_howto_table[] =
249 {
250   /* IMAGE_REL_PPC_ABSOLUTE 0x0000   NOP */
251   /* Unused: */
252   HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */                                 
253          0,                      /* rightshift */                           
254          0,                      /* size (0 = byte, 1 = short, 2 = long) */ 
255          0,                      /* bitsize */                   
256          false,                  /* pc_relative */                          
257          0,                      /* bitpos */                               
258          complain_overflow_dont, /* dont complain_on_overflow */
259          0,                      /* special_function */                     
260          "ABSOLUTE",             /* name */
261          false,                  /* partial_inplace */                      
262          0x00,                   /* src_mask */                             
263          0x00,                   /* dst_mask */                             
264          false),                 /* pcrel_offset */
265
266   /* IMAGE_REL_PPC_ADDR64 0x0001  64-bit address */
267   /* Unused: */
268   HOWTO(IMAGE_REL_PPC_ADDR64,    /* type */                                 
269          0,                      /* rightshift */                           
270          3,                      /* size (0 = byte, 1 = short, 2 = long) */ 
271          64,                     /* bitsize */                   
272          false,                  /* pc_relative */                          
273          0,                      /* bitpos */                               
274          complain_overflow_bitfield,     /* complain_on_overflow */
275          0,                      /* special_function */                     
276          "ADDR64",               /* name */
277          true,                   /* partial_inplace */                      
278          MINUS_ONE,              /* src_mask */
279          MINUS_ONE,              /* dst_mask */
280          false),                 /* pcrel_offset */
281
282   /* IMAGE_REL_PPC_ADDR32 0x0002  32-bit address */
283   /* Used: */
284   HOWTO (IMAGE_REL_PPC_ADDR32,  /* type */
285          0,                     /* rightshift */                           
286          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
287          32,                    /* bitsize */                   
288          false,                 /* pc_relative */                          
289          0,                     /* bitpos */                               
290          complain_overflow_bitfield, /* complain_on_overflow */
291          0,                     /* special_function */                     
292          "ADDR32",              /* name */
293          true,                  /* partial_inplace */                      
294          0xffffffff,            /* src_mask */                             
295          0xffffffff,            /* dst_mask */                             
296          false),                /* pcrel_offset */
297
298   /* IMAGE_REL_PPC_ADDR24 0x0003  26-bit address, shifted left 2 (branch absolute) */
299   /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
300   /* Of course, That's the IBM approved bit numbering, which is not what 
301   /* anyone else uses.... The li field is in bit 2 thru 25 */ 
302   /* Used: */
303   HOWTO (IMAGE_REL_PPC_ADDR24,  /* type */
304          0,                     /* rightshift */                           
305          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
306          26,                    /* bitsize */
307          false,                 /* pc_relative */                          
308          0,                     /* bitpos */                               
309          complain_overflow_bitfield, /* complain_on_overflow */
310          0,                     /* special_function */                     
311          "ADDR24",              /* name */
312          true,                  /* partial_inplace */                      
313          0x07fffffc,            /* src_mask */                             
314          0x07fffffc,            /* dst_mask */                             
315          false),                /* pcrel_offset */
316
317   /* IMAGE_REL_PPC_ADDR16 0x0004  16-bit address */
318   /* Used: */
319   HOWTO (IMAGE_REL_PPC_ADDR16,  /* type */             
320          0,                     /* rightshift */                           
321          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
322          16,                    /* bitsize */                   
323          false,                 /* pc_relative */                          
324          0,                     /* bitpos */                               
325          complain_overflow_signed, /* complain_on_overflow */
326          0,                     /* special_function */                     
327          "ADDR16",              /* name */
328          true,                  /* partial_inplace */                      
329          0xffff,                /* src_mask */                             
330          0xffff,                /* dst_mask */                             
331          false),                /* pcrel_offset */
332
333   /* IMAGE_REL_PPC_ADDR14 0x0005 */
334   /*  16-bit address, shifted left 2 (load doubleword) */
335   /* FIXME: the mask is likely wrong, and the bit position may be as well */
336   /* Unused: */
337   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */             
338          1,                     /* rightshift */                           
339          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
340          16,                    /* bitsize */                   
341          false,                 /* pc_relative */                          
342          0,                     /* bitpos */                               
343          complain_overflow_signed, /* complain_on_overflow */
344          0,                     /* special_function */                     
345          "ADDR16",              /* name */
346          true,                  /* partial_inplace */                      
347          0xffff,                /* src_mask */                             
348          0xffff,                /* dst_mask */                             
349          false),                /* pcrel_offset */
350
351   /* IMAGE_REL_PPC_REL24 0x0006 */
352   /*   26-bit PC-relative offset, shifted left 2 (branch relative) */
353   /* Used: */
354   HOWTO (IMAGE_REL_PPC_REL24,   /* type */
355          0,                     /* rightshift */                           
356          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
357          26,                    /* bitsize */                   
358          true,                  /* pc_relative */                          
359          0,                     /* bitpos */                               
360          complain_overflow_signed, /* complain_on_overflow */
361          0,                     /* special_function */                     
362          "REL24",               /* name */
363          true,                  /* partial_inplace */                      
364          0x3fffffc,             /* src_mask */                             
365          0x3fffffc,             /* dst_mask */                             
366          false),                /* pcrel_offset */
367
368   /* IMAGE_REL_PPC_REL14 0x0007 */
369   /*   16-bit PC-relative offset, shifted left 2 (br cond relative) */
370   /* FIXME: the mask is likely wrong, and the bit position may be as well */
371   /* FIXME: how does it know how far to shift? */
372   /* Unused: */
373   HOWTO (IMAGE_REL_PPC_ADDR14,  /* type */             
374          1,                     /* rightshift */                           
375          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
376          16,                    /* bitsize */                   
377          false,                 /* pc_relative */                          
378          0,                     /* bitpos */                               
379          complain_overflow_signed, /* complain_on_overflow */
380          0,                     /* special_function */                     
381          "ADDR16",              /* name */
382          true,                  /* partial_inplace */                      
383          0xffff,                /* src_mask */                             
384          0xffff,                /* dst_mask */                             
385          true),                 /* pcrel_offset */
386
387   /* IMAGE_REL_PPC_TOCREL16 0x0008 */
388   /*   16-bit offset from TOC base */
389   /* Used: */
390   HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */             
391          0,                     /* rightshift */                           
392          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
393          16,                    /* bitsize */                   
394          false,                 /* pc_relative */                          
395          0,                     /* bitpos */                               
396          complain_overflow_dont, /* complain_on_overflow */
397          ppc_toc16_reloc,       /* special_function */                     
398          "TOCREL16",            /* name */
399          false,                 /* partial_inplace */                      
400          0xffff,                /* src_mask */                             
401          0xffff,                /* dst_mask */                             
402          false),                /* pcrel_offset */
403
404   /* IMAGE_REL_PPC_TOCREL14 0x0009 */
405   /*   16-bit offset from TOC base, shifted left 2 (load doubleword) */
406   /* Unused: */
407   HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */             
408          1,                     /* rightshift */                           
409          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
410          16,                    /* bitsize */                   
411          false,                 /* pc_relative */                          
412          0,                     /* bitpos */                               
413          complain_overflow_signed, /* complain_on_overflow */
414          0,                     /* special_function */                     
415          "TOCREL14",            /* name */
416          false,                 /* partial_inplace */                      
417          0xffff,                /* src_mask */                             
418          0xffff,                /* dst_mask */                             
419          true),                 /* pcrel_offset */
420
421   /* IMAGE_REL_PPC_ADDR32NB 0x000A */
422   /*   32-bit addr w/ image base */
423   /* Unused: */
424   HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */             
425          0,                     /* rightshift */                           
426          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
427          32,                    /* bitsize */                   
428          false,                 /* pc_relative */                          
429          0,                     /* bitpos */                               
430          complain_overflow_signed, /* complain_on_overflow */
431          ppc_addr32nb_reloc,    /* special_function */                     
432          "ADDR32NB",            /* name */
433          true,                  /* partial_inplace */                      
434          0xffffffff,            /* src_mask */                             
435          0xffffffff,            /* dst_mask */                             
436          true),                 /* pcrel_offset */
437
438   /* IMAGE_REL_PPC_SECREL 0x000B */
439   /*   va of containing section (as in an image sectionhdr) */
440   /* Unused: */
441   HOWTO (IMAGE_REL_PPC_SECREL,/* type */             
442          0,                     /* rightshift */                           
443          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
444          32,                    /* bitsize */                   
445          false,                 /* pc_relative */                          
446          0,                     /* bitpos */                               
447          complain_overflow_signed, /* complain_on_overflow */
448          ppc_secrel_reloc,      /* special_function */                     
449          "SECREL",              /* name */
450          true,                  /* partial_inplace */                      
451          0xffffffff,            /* src_mask */                             
452          0xffffffff,            /* dst_mask */                             
453          true),                 /* pcrel_offset */
454
455   /* IMAGE_REL_PPC_SECTION 0x000C */
456   /*   sectionheader number */
457   /* Unused: */
458   HOWTO (IMAGE_REL_PPC_SECTION,/* type */             
459          0,                     /* rightshift */                           
460          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
461          32,                    /* bitsize */                   
462          false,                 /* pc_relative */                          
463          0,                     /* bitpos */                               
464          complain_overflow_signed, /* complain_on_overflow */
465          ppc_section_reloc,     /* special_function */                     
466          "SECTION",             /* name */
467          true,                  /* partial_inplace */                      
468          0xffffffff,            /* src_mask */                             
469          0xffffffff,            /* dst_mask */                             
470          true),                 /* pcrel_offset */
471
472   /* IMAGE_REL_PPC_IFGLUE 0x000D */
473   /*   substitute TOC restore instruction iff symbol is glue code */
474   /* Used: */
475   HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */             
476          0,                     /* rightshift */                           
477          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
478          32,                    /* bitsize */                   
479          false,                 /* pc_relative */                          
480          0,                     /* bitpos */                               
481          complain_overflow_signed, /* complain_on_overflow */
482          0,                     /* special_function */                     
483          "IFGLUE",              /* name */
484          true,                  /* partial_inplace */                      
485          0xffffffff,            /* src_mask */                             
486          0xffffffff,            /* dst_mask */                             
487          true),                 /* pcrel_offset */
488
489   /* IMAGE_REL_PPC_IMGLUE 0x000E */
490   /*   symbol is glue code; virtual address is TOC restore instruction */
491   /* Unused: */
492   HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */             
493          0,                     /* rightshift */                           
494          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
495          32,                    /* bitsize */                   
496          false,                 /* pc_relative */                          
497          0,                     /* bitpos */                               
498          complain_overflow_dont, /* complain_on_overflow */
499          ppc_imglue_reloc,      /* special_function */                     
500          "IMGLUE",              /* name */
501          false,                 /* partial_inplace */                      
502          0xffffffff,            /* src_mask */                             
503          0xffffffff,            /* dst_mask */                             
504          false),                 /* pcrel_offset */
505
506   /* IMAGE_REL_PPC_SECREL16 0x000F */
507   /*   va of containing section (limited to 16 bits) */
508   /* Unused: */
509   HOWTO (IMAGE_REL_PPC_SECREL16,/* type */             
510          0,                     /* rightshift */                           
511          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
512          16,                    /* bitsize */                   
513          false,                 /* pc_relative */                          
514          0,                     /* bitpos */                               
515          complain_overflow_signed, /* complain_on_overflow */
516          0,                     /* special_function */                     
517          "SECREL16",            /* name */
518          true,                  /* partial_inplace */                      
519          0xffff,                /* src_mask */                             
520          0xffff,                /* dst_mask */                             
521          true),                 /* pcrel_offset */
522
523   /* IMAGE_REL_PPC_REFHI             0x0010 */
524   /* Unused: */
525   HOWTO (IMAGE_REL_PPC_REFHI,   /* type */             
526          0,                     /* rightshift */                           
527          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
528          16,                    /* bitsize */                   
529          false,                 /* pc_relative */                          
530          0,                     /* bitpos */                               
531          complain_overflow_signed, /* complain_on_overflow */
532          ppc_refhi_reloc,       /* special_function */                     
533          "REFHI",               /* name */
534          true,                  /* partial_inplace */                      
535          0xffffffff,            /* src_mask */                             
536          0xffffffff,            /* dst_mask */                             
537          false),                 /* pcrel_offset */
538
539   /* IMAGE_REL_PPC_REFLO             0x0011 */
540   /* Unused: */
541   HOWTO (IMAGE_REL_PPC_REFLO,   /* type */             
542          0,                     /* rightshift */                           
543          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
544          16,                    /* bitsize */                   
545          false,                 /* pc_relative */                          
546          0,                     /* bitpos */                               
547          complain_overflow_signed, /* complain_on_overflow */
548          ppc_refhi_reloc,       /* special_function */                     
549          "REFLO",               /* name */
550          true,                  /* partial_inplace */                      
551          0xffffffff,            /* src_mask */                             
552          0xffffffff,            /* dst_mask */                             
553          false),                /* pcrel_offset */
554
555   /* IMAGE_REL_PPC_PAIR              0x0012 */
556   /* Unused: */
557   HOWTO (IMAGE_REL_PPC_PAIR,    /* type */             
558          0,                     /* 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          ppc_pair_reloc,        /* special_function */                     
565          "PAIR",                /* name */
566          true,                  /* partial_inplace */                      
567          0xffffffff,            /* src_mask */                             
568          0xffffffff,            /* dst_mask */                             
569          false)                 /* pcrel_offset */
570 };
571
572
573 /* Provided the symbol, returns the value reffed */
574 static long get_symbol_value PARAMS ((asymbol *));
575
576 static long
577 get_symbol_value (symbol)       
578      asymbol *symbol;
579 {                                             
580   long relocation = 0;
581
582   if (bfd_is_com_section (symbol->section))
583   {
584     relocation = 0;                           
585   }
586   else 
587   {                                      
588     relocation = symbol->value +
589      symbol->section->output_section->vma +
590       symbol->section->output_offset;
591   }                                           
592
593   return(relocation);
594 }
595
596 /* this function is in charge of performing all the ppc PE relocations */
597 /* Don't yet know if we want to do this this particular way ... (krk)  */
598 /* (it is not yet enabled) */
599
600 static bfd_reloc_status_type
601 pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
602             error_message)
603      bfd *abfd;
604      arelent *reloc_entry;
605      asymbol *symbol_in;
606      PTR data;
607      asection *input_section;
608      bfd *output_bfd;
609      char **error_message;
610 {
611   /* the consth relocation comes in two parts, we have to remember
612      the state between calls, in these variables */
613   static boolean part1_consth_active = false;
614   static unsigned long part1_consth_value;
615
616   unsigned long insn;
617   unsigned long sym_value;
618   unsigned long unsigned_value;
619   unsigned short r_type;
620   long signed_value;
621
622   unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
623   bfd_byte  *hit_data =addr + (bfd_byte *)(data);
624         
625   r_type = reloc_entry->howto->type;
626
627   if (output_bfd) {
628     /* Partial linking - do nothing */
629     reloc_entry->address += input_section->output_offset;
630     return bfd_reloc_ok;
631
632   }
633
634   if (symbol_in != NULL
635       && bfd_is_und_section (symbol_in->section))
636   {
637     /* Keep the state machine happy in case we're called again */
638     if (r_type == IMAGE_REL_PPC_REFHI) 
639     {
640       part1_consth_active = true;
641       part1_consth_value  = 0;
642     }
643     return(bfd_reloc_undefined);
644   }
645
646   if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) 
647   {
648     part1_consth_active = false;
649     *error_message = (char *) "Missing PAIR";
650     return(bfd_reloc_dangerous);
651   }
652
653
654   sym_value = get_symbol_value(symbol_in);
655
656 #if 0
657
658   switch (r_type) 
659   {
660    case R_IREL:         
661     insn = bfd_get_32(abfd, hit_data); 
662     /* Take the value in the field and sign extend it */
663     signed_value = EXTRACT_HWORD(insn);
664     signed_value = SIGN_EXTEND_HWORD(signed_value);
665     signed_value <<= 2;
666     signed_value +=  sym_value + reloc_entry->addend;
667     if (((signed_value + reloc_entry->address) & ~0x3ffff) == 0)
668     {                           /* Absolute jmp/call */
669       insn |= (1<<24);          /* Make it absolute */
670       signed_value += reloc_entry->address;
671       /* FIXME: Should we change r_type to R_IABS */
672     } 
673     else 
674     {
675       /* Relative jmp/call, so subtract from the value the
676          address of the place we're coming from */
677       signed_value -= (input_section->output_section->vma
678                        + input_section->output_offset);
679       if (signed_value>0x1ffff || signed_value<-0x20000) 
680        return(bfd_reloc_overflow);
681     }
682     signed_value >>= 2;
683     insn = INSERT_HWORD(insn, signed_value);
684     bfd_put_32(abfd, insn ,hit_data); 
685     break;
686    case R_ILOHALF: 
687     insn = bfd_get_32(abfd, hit_data); 
688     unsigned_value = EXTRACT_HWORD(insn);
689     unsigned_value +=  sym_value + reloc_entry->addend;
690     insn = INSERT_HWORD(insn, unsigned_value);
691     bfd_put_32(abfd, insn, hit_data); 
692     break;
693    case R_IHIHALF:
694     insn = bfd_get_32(abfd, hit_data); 
695     /* consth, part 1 
696        Just get the symbol value that is referenced */
697     part1_consth_active = true;
698     part1_consth_value = sym_value + reloc_entry->addend;
699     /* Don't modify insn until R_IHCONST */
700     break;
701    case R_IHCONST:      
702     insn = bfd_get_32(abfd, hit_data); 
703     /* consth, part 2 
704        Now relocate the reference */
705     if (part1_consth_active == false) {
706       *error_message = (char *) "Missing IHIHALF";
707       return(bfd_reloc_dangerous);
708     }
709     /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
710     unsigned_value = 0;         /*EXTRACT_HWORD(insn) << 16;*/
711     unsigned_value += reloc_entry->addend; /* r_symndx */
712     unsigned_value += part1_consth_value;
713     unsigned_value = unsigned_value >> 16;
714     insn = INSERT_HWORD(insn, unsigned_value);
715     part1_consth_active = false;
716     bfd_put_32(abfd, insn, hit_data); 
717     break;
718    case R_BYTE:
719     insn = bfd_get_8(abfd, hit_data); 
720     unsigned_value = insn + sym_value + reloc_entry->addend;    
721     if (unsigned_value & 0xffffff00) {
722       fprintf(stderr,"Relocation problem : ");
723       fprintf(stderr,"byte value too large in module %s\n",
724               abfd->filename); 
725       return(bfd_reloc_overflow);
726     }
727     bfd_put_8(abfd, unsigned_value, hit_data); 
728     break;
729    case R_HWORD:
730     insn = bfd_get_16(abfd, hit_data); 
731     unsigned_value = insn + sym_value + reloc_entry->addend;    
732     if (unsigned_value & 0xffff0000) {
733       fprintf(stderr,"Relocation problem : ");
734       fprintf(stderr,"hword value too large in module %s\n",
735               abfd->filename); 
736       return(bfd_reloc_overflow);
737     }
738
739     bfd_put_16(abfd, insn, hit_data); 
740     break;
741    case R_WORD:
742     insn = bfd_get_32(abfd, hit_data); 
743     insn += sym_value + reloc_entry->addend;  
744     bfd_put_32(abfd, insn, hit_data);
745     break;
746    default:
747     *error_message = "Unrecognized reloc";
748     return (bfd_reloc_dangerous);
749   }
750
751 #endif
752
753   return(bfd_reloc_ok); 
754 }
755
756 /* The reloc processing routine for the optimized COFF linker.  */
757
758 static boolean
759 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
760                             contents, relocs, syms, sections)
761      bfd *output_bfd;
762      struct bfd_link_info *info;
763      bfd *input_bfd;
764      asection *input_section;
765      bfd_byte *contents;
766      struct internal_reloc *relocs;
767      struct internal_syment *syms;
768      asection **sections;
769 {
770   struct internal_reloc *rel;
771   struct internal_reloc *relend;
772   boolean hihalf;
773   bfd_vma hihalf_val;
774
775   unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
776   unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
777   unsigned short junk    = EXTRACT_JUNK (rel->r_type);
778
779
780   /* If we are performing a relocateable link, we don't need to do a
781      thing.  The caller will take care of adjusting the reloc
782      addresses and symbol indices.  */
783
784   if (info->relocateable)
785     return true;
786
787   hihalf = false;
788   hihalf_val = 0;
789
790   rel = relocs;
791   relend = rel + input_section->reloc_count;
792   for (; rel < relend; rel++)
793     {
794       long symndx;
795       bfd_byte *loc;
796       struct coff_link_hash_entry *h;
797       struct internal_syment *sym;
798       asection *sec;
799       bfd_vma val;
800       boolean overflow;
801       unsigned long insn;
802       long signed_value;
803       unsigned long unsigned_value;
804       bfd_reloc_status_type rstat;
805
806       symndx = rel->r_symndx;
807       loc = contents + rel->r_vaddr - input_section->vma;
808
809       if (symndx == -1)
810         h = NULL;
811       else
812         h = obj_coff_sym_hashes (input_bfd)[symndx];
813
814       sym = NULL;
815       sec = NULL;
816       val = 0;
817
818       overflow = false;
819
820       switch (r_type)
821         {
822         default:
823           fprintf( stderr, "unsupported reloc %s\n",
824                   ppc_coff_howto_table[r_type].name);
825           bfd_set_error (bfd_error_bad_value);
826           return false;
827         case IMAGE_REL_PPC_TOCREL16:
828         case IMAGE_REL_PPC_IFGLUE:
829         case IMAGE_REL_PPC_SECTION:
830         case IMAGE_REL_PPC_SECREL:
831         case IMAGE_REL_PPC_IMGLUE:
832         case IMAGE_REL_PPC_ABSOLUTE:
833           break;
834
835         case IMAGE_REL_PPC_ADDR16:
836         case IMAGE_REL_PPC_REL24:
837         case IMAGE_REL_PPC_ADDR24:
838         case IMAGE_REL_PPC_ADDR32:
839         case IMAGE_REL_PPC_ADDR32NB:
840           rstat = _bfd_relocate_contents (ppc_coff_howto_table + r_type,
841                                           input_bfd, val, loc);
842           if (rstat == bfd_reloc_overflow)
843             overflow = true;
844           else if (rstat != bfd_reloc_ok)
845             abort ();
846           break;
847         }
848
849       if (overflow)
850         {
851           const char *name;
852           char buf[SYMNMLEN + 1];
853
854           if (symndx == -1)
855             name = "*ABS*";
856           else if (h != NULL)
857             name = h->root.root.string;
858           else if (sym == NULL)
859             name = "*unknown*";
860           else if (sym->_n._n_n._n_zeroes == 0
861                    && sym->_n._n_n._n_offset != 0)
862             name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
863           else
864             {
865               strncpy (buf, sym->_n._n_name, SYMNMLEN);
866               buf[SYMNMLEN] = '\0';
867               name = buf;
868             }
869
870           if (! ((*info->callbacks->reloc_overflow)
871                  (info, name, ppc_coff_howto_table[r_type].name, (bfd_vma) 0,
872                   input_bfd, input_section,
873                   rel->r_vaddr - input_section->vma)))
874             return false;
875         }
876     }     
877
878   return true;
879 }
880
881 \f
882
883 /* Some really cheezy macros that can be turned on to test stderr :-) */
884
885 #ifdef DEBUG_RELOC
886 #define UN_IMPL(x)                                           \
887 {                                                            \
888    static int i;                                             \
889    if (i == 0)                                               \
890      {                                                       \
891        i = 1;                                                \
892        fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \
893      }                                                       \
894 }
895
896 #define DUMP_RELOC(n,r)                              \
897 {                                                    \
898    fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
899            n, (*(r->sym_ptr_ptr))->name,             \
900            r->address, r->addend);                   \
901 }
902
903 #define DUMP_RELOC2(n,r)                     \
904 {                                            \
905    fprintf(stderr,"%s sym %d, r_vaddr %d\n", \
906            n, r->r_symndx, r->r_vaddr);      \
907 }
908
909 #else
910 #define UN_IMPL(x)
911 #define DUMP_RELOC(n,r)
912 #define DUMP_RELOC2(n,r)
913 #endif
914
915
916 static bfd_reloc_status_type
917 ppc_refhi_reloc (abfd,
918                  reloc_entry,
919                  symbol,
920                  data,
921                  input_section,
922                  output_bfd,
923                  error_message)
924      bfd *abfd;
925      arelent *reloc_entry;
926      asymbol *symbol;
927      PTR data;
928      asection *input_section;
929      bfd *output_bfd;
930      char **error_message;
931 {
932   UN_IMPL("REFHI");
933   DUMP_RELOC("REFHI",reloc_entry);
934
935   if (output_bfd == (bfd *) NULL)
936     return bfd_reloc_continue;
937
938   return bfd_reloc_undefined;
939 }
940
941 static bfd_reloc_status_type
942 ppc_reflo_reloc (abfd,
943                  reloc_entry,
944                  symbol,
945                  data,
946                  input_section,
947                  output_bfd,
948                  error_message)
949      bfd *abfd;
950      arelent *reloc_entry;
951      asymbol *symbol;
952      PTR data;
953      asection *input_section;
954      bfd *output_bfd;
955      char **error_message;
956 {
957   UN_IMPL("REFLO");
958   DUMP_RELOC("REFLO",reloc_entry);
959
960   if (output_bfd == (bfd *) NULL)
961     return bfd_reloc_continue;
962
963   return bfd_reloc_undefined;
964 }
965
966 static bfd_reloc_status_type
967 ppc_pair_reloc (abfd,
968                 reloc_entry,
969                 symbol,
970                 data,
971                 input_section,
972                 output_bfd,
973                 error_message)
974      bfd *abfd;
975      arelent *reloc_entry;
976      asymbol *symbol;
977      PTR data;
978      asection *input_section;
979      bfd *output_bfd;
980      char **error_message;
981 {
982   UN_IMPL("PAIR");
983   DUMP_RELOC("PAIR",reloc_entry);
984
985   if (output_bfd == (bfd *) NULL)
986     return bfd_reloc_continue;
987
988   return bfd_reloc_undefined;
989 }
990
991 \f
992 static bfd_reloc_status_type
993 ppc_toc16_reloc (abfd,
994                  reloc_entry,
995                  symbol,
996                  data,
997                  input_section,
998                  output_bfd,
999                  error_message)
1000      bfd *abfd;
1001      arelent *reloc_entry;
1002      asymbol *symbol;
1003      PTR data;
1004      asection *input_section;
1005      bfd *output_bfd;
1006      char **error_message;
1007 {
1008   UN_IMPL("TOCREL16");
1009   DUMP_RELOC("TOCREL16",reloc_entry);
1010
1011   if (output_bfd == (bfd *) NULL)
1012     {
1013       return bfd_reloc_continue;
1014     }
1015
1016   return bfd_reloc_ok;
1017 }
1018
1019 /* ADDR32NB : 32 bit address relative to the virtual origin.         */
1020 /*            (On the alpha, this is always a linker generated thunk)*/
1021 /*            (i.e. 32bit addr relative to the image base)           */
1022 /*                                                                   */
1023 /*                                                                   */
1024
1025 static bfd_reloc_status_type
1026 ppc_addr32nb_reloc (abfd,
1027                     reloc_entry,
1028                     symbol,
1029                     data,
1030                     input_section,
1031                     output_bfd,
1032                     error_message)
1033      bfd *abfd;
1034      arelent *reloc_entry;
1035      asymbol *symbol;
1036      PTR data;
1037      asection *input_section;
1038      bfd *output_bfd;
1039      char **error_message;
1040 {
1041   UN_IMPL("ADDR32NB");
1042   DUMP_RELOC("ADDR32NB",reloc_entry);
1043
1044   return bfd_reloc_ok;
1045 }
1046
1047 static bfd_reloc_status_type
1048 ppc_secrel_reloc (abfd,
1049                   reloc_entry,
1050                   symbol,
1051                   data,
1052                   input_section,
1053                   output_bfd,
1054                   error_message)
1055      bfd *abfd;
1056      arelent *reloc_entry;
1057      asymbol *symbol;
1058      PTR data;
1059      asection *input_section;
1060      bfd *output_bfd;
1061      char **error_message;
1062 {
1063   UN_IMPL("SECREL");
1064   DUMP_RELOC("SECREL",reloc_entry);
1065
1066   if (output_bfd == (bfd *) NULL)
1067     return bfd_reloc_continue;
1068
1069   return bfd_reloc_ok;
1070 }
1071
1072 static bfd_reloc_status_type
1073 ppc_section_reloc (abfd,
1074                    reloc_entry,
1075                    symbol,
1076                    data,
1077                    input_section,
1078                    output_bfd,
1079                    error_message)
1080      bfd *abfd;
1081      arelent *reloc_entry;
1082      asymbol *symbol;
1083      PTR data;
1084      asection *input_section;
1085      bfd *output_bfd;
1086      char **error_message;
1087 {
1088   UN_IMPL("SECTION");
1089   DUMP_RELOC("SECTION",reloc_entry);
1090
1091   if (output_bfd == (bfd *) NULL)
1092     return bfd_reloc_continue;
1093
1094   return bfd_reloc_ok;
1095 }
1096
1097 static bfd_reloc_status_type
1098 ppc_imglue_reloc (abfd,
1099                   reloc_entry,
1100                   symbol,
1101                   data,
1102                   input_section,
1103                   output_bfd,
1104                   error_message)
1105      bfd *abfd;
1106      arelent *reloc_entry;
1107      asymbol *symbol;
1108      PTR data;
1109      asection *input_section;
1110      bfd *output_bfd;
1111      char **error_message;
1112 {
1113   UN_IMPL("IMGLUE");
1114   DUMP_RELOC("IMGLUE",reloc_entry);
1115
1116   if (output_bfd == (bfd *) NULL)
1117     return bfd_reloc_continue;
1118
1119   return bfd_reloc_ok;
1120 }
1121
1122 \f
1123
1124 #define MAX_RELOC_INDEX  \
1125       (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
1126
1127
1128 /* FIXME: There is a possiblity that when we read in a reloc from a file,
1129           that there are some bits encoded in the upper portion of the 
1130           type field. Not yet implemented.
1131 */
1132 static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
1133                                           struct internal_reloc *internal));
1134
1135 static void
1136 ppc_coff_rtype2howto (relent, internal)
1137      arelent *relent;
1138      struct internal_reloc *internal;
1139 {  
1140
1141   /* We can encode one of three things in the type field, aside from the
1142      type:
1143      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
1144         value, rather than an addition value
1145      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
1146         the branch is expected to be taken or not.
1147      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
1148      For now, we just strip this stuff to find the type, and ignore it other
1149      than that.
1150   */
1151
1152   unsigned short r_type  = EXTRACT_TYPE (internal->r_type);
1153   unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
1154   unsigned short junk    = EXTRACT_JUNK (internal->r_type);
1155
1156   /* the masking process only slices off the bottom byte for r_type. */
1157   if ( r_type > MAX_RELOC_INDEX ) 
1158     {
1159       fprintf(stderr, 
1160               "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n",
1161               internal->r_type, 0, MAX_RELOC_INDEX);
1162       abort();
1163     }
1164
1165   /* check for absolute crap */
1166   if ( junk != 0 )
1167     {
1168       fprintf(stderr, 
1169               "ppc_coff_rtype2howto: reloc index %d contains junk %d\n",
1170               internal->r_type, junk);
1171       abort();
1172     }
1173
1174 #ifdef DEBUG_RELOC
1175   /* now examine flags */
1176   if (r_flags != 0) 
1177     {
1178       fprintf (stderr, "Reloc with flags found!");
1179       if ( r_flags & IMAGE_REL_PPC_NEG ) 
1180         fprintf (stderr, " NEG");
1181       if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1182         fprintf (stderr, " BRTAKEN");
1183       if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1184         fprintf (stderr, " BRNTAKEN");
1185       if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1186         fprintf (stderr, " TOCDEFN");
1187       fprintf(stderr, "\n");
1188     }
1189 #endif
1190
1191   switch(r_type) 
1192     {
1193     case IMAGE_REL_PPC_ADDR16:
1194     case IMAGE_REL_PPC_REL24:
1195     case IMAGE_REL_PPC_ADDR24:
1196     case IMAGE_REL_PPC_TOCREL16:
1197     case IMAGE_REL_PPC_ADDR32:
1198     case IMAGE_REL_PPC_IFGLUE:
1199     case IMAGE_REL_PPC_ADDR32NB:
1200     case IMAGE_REL_PPC_SECTION:
1201     case IMAGE_REL_PPC_SECREL:
1202       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
1203       break;
1204     case IMAGE_REL_PPC_IMGLUE:
1205       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
1206       /* IMGLUE relocs have big numbers in them. Don't know what for yet. */
1207       internal->r_vaddr = 0; /* make it zero for now */
1208       break;
1209     default:
1210       fprintf(stderr, 
1211               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
1212               ppc_coff_howto_table[r_type].name,
1213               r_type);
1214       break;
1215     }
1216
1217   relent->howto = ppc_coff_howto_table + r_type;
1218
1219 }
1220
1221 static reloc_howto_type *
1222 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
1223      bfd *abfd;
1224      asection *sec;
1225      struct internal_reloc *rel;
1226      struct coff_link_hash_entry *h;
1227      struct internal_syment *sym;
1228      bfd_vma *addendp;
1229 {
1230   reloc_howto_type *howto;
1231
1232   /* We can encode one of three things in the type field, aside from the
1233      type:
1234      1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
1235         value, rather than an addition value
1236      2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
1237         the branch is expected to be taken or not.
1238      3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
1239      For now, we just strip this stuff to find the type, and ignore it other
1240      than that.
1241   */
1242
1243   unsigned short r_type  = EXTRACT_TYPE (rel->r_type);
1244   unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1245   unsigned short junk    = EXTRACT_JUNK (rel->r_type);
1246
1247   /* the masking process only slices off the bottom byte for r_type. */
1248   if ( r_type > MAX_RELOC_INDEX ) 
1249     {
1250       fprintf(stderr, 
1251               "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n",
1252               r_type, 0, MAX_RELOC_INDEX);
1253       abort();
1254     }
1255
1256   /* check for absolute crap */
1257   if ( junk != 0 )
1258     {
1259       fprintf(stderr, 
1260               "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n",
1261               rel->r_type, junk);
1262       abort();
1263     }
1264
1265 #ifdef DEBUG_RELOC
1266   /* now examine flags */
1267   if (r_flags != 0) 
1268     {
1269       fprintf (stderr, "Reloc with flags found!");
1270       if ( r_flags & IMAGE_REL_PPC_NEG ) 
1271         fprintf (stderr, " NEG");
1272       if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1273         fprintf (stderr, " BRTAKEN");
1274       if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1275         fprintf (stderr, " BRNTAKEN");
1276       if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1277         fprintf (stderr, " TOCDEFN");
1278       fprintf(stderr, "\n");
1279     }
1280 #endif
1281
1282   switch(r_type) 
1283     {
1284     case IMAGE_REL_PPC_ADDR32NB:
1285       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1286       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
1287       break;
1288     case IMAGE_REL_PPC_ADDR16:
1289     case IMAGE_REL_PPC_REL24:
1290     case IMAGE_REL_PPC_ADDR24:
1291     case IMAGE_REL_PPC_TOCREL16:
1292     case IMAGE_REL_PPC_ADDR32:
1293     case IMAGE_REL_PPC_IFGLUE:
1294     case IMAGE_REL_PPC_SECTION:
1295     case IMAGE_REL_PPC_SECREL:
1296       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1297       break;
1298     case IMAGE_REL_PPC_IMGLUE:
1299       DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1300       /* IMGLUE relocs have big numbers in them. Don't know what for yet. */
1301       rel->r_vaddr = 0; /* make it zero for now */
1302       break;
1303     default:
1304       fprintf(stderr, 
1305               "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
1306               ppc_coff_howto_table[r_type].name,
1307               r_type);
1308       break;
1309     }
1310
1311   howto = ppc_coff_howto_table + r_type;
1312   return howto;
1313 }
1314
1315
1316 /* a cheesy little macro to make the code a little more readable */
1317 #define HOW2MAP(bfd_rtype,ppc_rtype)  \
1318           case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
1319
1320 static reloc_howto_type *ppc_coff_reloc_type_lookup
1321   PARAMS ((bfd *, bfd_reloc_code_real_type));
1322
1323 static reloc_howto_type *
1324 ppc_coff_reloc_type_lookup (abfd, code)
1325      bfd *abfd;
1326      bfd_reloc_code_real_type code;
1327 {
1328
1329 #ifdef DEBUG_RELOC
1330   fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n",
1331                    bfd_get_reloc_code_name(code));
1332 #endif
1333
1334   switch (code)
1335     {
1336       HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
1337       HOW2MAP(BFD_RELOC_16,           IMAGE_REL_PPC_ADDR16);
1338       HOW2MAP(BFD_RELOC_PPC_B26,      IMAGE_REL_PPC_REL24);
1339       HOW2MAP(BFD_RELOC_PPC_BA26,     IMAGE_REL_PPC_ADDR24);
1340       HOW2MAP(BFD_RELOC_PPC_TOC16,    IMAGE_REL_PPC_TOCREL16);
1341       HOW2MAP(BFD_RELOC_32,           IMAGE_REL_PPC_ADDR32);
1342       default: return NULL;
1343     }
1344
1345   return NULL;
1346 }
1347
1348 #undef HOW2MAP
1349
1350 \f
1351 /* Tailor coffcode.h -- macro heaven. */
1352
1353 #define RTYPE2HOWTO(cache_ptr, dst)  ppc_coff_rtype2howto (cache_ptr, dst)
1354
1355 /* We use the special COFF backend linker.  */
1356 /* #define coff_relocate_section        _bfd_coff_generic_relocate_section */
1357 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
1358 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
1359 #define coff_relocate_section        coff_ppc_relocate_section
1360
1361 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
1362
1363 #define COFF_PAGE_SIZE                       0x1000
1364
1365 #include "coffcode.h"
1366
1367 /* The transfer vectors that lead the outside world to all of the above. */
1368
1369 #ifdef TARGET_LITTLE_SYM
1370 const bfd_target
1371 TARGET_LITTLE_SYM =
1372 {
1373   TARGET_LITTLE_NAME,           /* name or coff-arm-little */
1374   bfd_target_coff_flavour,
1375   false,                        /* data byte order is little */
1376   false,                        /* header byte order is little */
1377
1378   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
1379    HAS_LINENO | HAS_DEBUG |
1380    HAS_SYMS | HAS_LOCALS | WP_TEXT),
1381
1382   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1383   0,                            /* leading char */
1384   '/',                          /* ar_pad_char */
1385   15,                           /* ar_max_namelen??? FIXMEmgo */
1386
1387   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1388      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1389      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1390   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1391      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1392      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1393
1394   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
1395      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
1396   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
1397      bfd_false},
1398   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
1399      _bfd_write_archive_contents, bfd_false},
1400
1401   BFD_JUMP_TABLE_GENERIC (coff),
1402   BFD_JUMP_TABLE_COPY (coff),
1403   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1404   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1405   BFD_JUMP_TABLE_SYMBOLS (coff),
1406   BFD_JUMP_TABLE_RELOCS (coff),
1407   BFD_JUMP_TABLE_WRITE (coff),
1408   BFD_JUMP_TABLE_LINK (coff),
1409   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1410
1411   COFF_SWAP_TABLE,
1412 };
1413 #endif
1414
1415 #ifdef TARGET_BIG_SYM
1416 const bfd_target
1417 TARGET_BIG_SYM =
1418 {
1419   TARGET_BIG_NAME,
1420   bfd_target_coff_flavour,      
1421   true,                         /* data byte order is big */
1422   true,                         /* header byte order is big */
1423
1424   (HAS_RELOC | EXEC_P |         /* FIXME: object flags */
1425    HAS_LINENO | HAS_DEBUG |
1426    HAS_SYMS | HAS_LOCALS | WP_TEXT),
1427
1428   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1429   0,                            /* leading char */
1430   '/',                          /* ar_pad_char */
1431   15,                           /* ar_max_namelen??? FIXMEmgo */
1432
1433   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1434      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1435      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1436   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1437      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1438      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1439
1440   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
1441      bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
1442   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
1443      bfd_false},
1444   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
1445      _bfd_write_archive_contents, bfd_false},
1446
1447   BFD_JUMP_TABLE_GENERIC (coff),
1448   BFD_JUMP_TABLE_COPY (coff),
1449   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1450   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1451   BFD_JUMP_TABLE_SYMBOLS (coff),
1452   BFD_JUMP_TABLE_RELOCS (coff),
1453   BFD_JUMP_TABLE_WRITE (coff),
1454   BFD_JUMP_TABLE_LINK (coff),
1455   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1456
1457   COFF_SWAP_TABLE,
1458 };
1459
1460 #endif
1461
1462
1463
1464
1465
1466
1467
1468
1469