]> Git Repo - binutils.git/blob - bfd/elf32-ppc.c
* mpw-config.in: Add sh and i386 configs, remove sparc config.
[binutils.git] / bfd / elf32-ppc.c
1 /* PowerPC-specific support for 32-bit ELF
2    Copyright 1994, 1995 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor, Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* This file is based on a preliminary PowerPC ELF ABI.  The
22    information may not match the final PowerPC ELF ABI.  It includes
23    suggestions from the in-progress Embedded PowerPC ABI, and that
24    information may also not match.  */
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "libbfd.h"
29 #include "libelf.h"
30
31 static bfd_reloc_status_type ppc_elf_unsupported_reloc
32   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
33 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
34   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
35 static bfd_reloc_status_type ppc_elf_got16_reloc
36   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
37 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
38   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
39 static void powerpc_info_to_howto
40   PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
41
42 #define USE_RELA
43
44 enum reloc_type
45 {
46   R_PPC_NONE = 0,                       /*   0 */
47   R_PPC_ADDR32,                         /*   1 */
48   R_PPC_ADDR24,                         /*   2 */
49   R_PPC_ADDR16,                         /*   3 */
50   R_PPC_ADDR16_LO,                      /*   4 */
51   R_PPC_ADDR16_HI,                      /*   5 */
52   R_PPC_ADDR16_HA,                      /*   6 */
53   R_PPC_ADDR14,                         /*   7 */
54   R_PPC_ADDR14_BRTAKEN,                 /*   8 */
55   R_PPC_ADDR14_BRNTAKEN,                /*   9 */
56   R_PPC_REL24,                          /*  10 */
57   R_PPC_REL14,                          /*  11 */
58   R_PPC_REL14_BRTAKEN,                  /*  12 */
59   R_PPC_REL14_BRNTAKEN,                 /*  13 */
60   R_PPC_GOT16,                          /*  14 */
61   R_PPC_GOT16_LO,                       /*  15 */
62   R_PPC_GOT16_HI,                       /*  16 */
63   R_PPC_GOT16_HA,                       /*  17 */
64   R_PPC_PLT24,                          /*  18 */
65   R_PPC_COPY,                           /*  19 */
66   R_PPC_GLOB_DAT,                       /*  20 -- not in final System V spec */
67   R_PPC_JMP_SLOT,                       /*  21 */
68   R_PPC_RELATIVE,                       /*  22 */
69   R_PPC_LOCAL24PC,                      /*  23 */
70   R_PPC_UADDR32,                        /*  24 */
71   R_PPC_UADDR16,                        /*  25 */
72   R_PPC_REL32,                          /*  26 */
73   R_PPC_PLT32,                          /*  27 */
74   R_PPC_PLTREL32,                       /*  28 */
75   R_PPC_PLT16_LO,                       /*  29 */
76   R_PPC_PLT16_HI,                       /*  30 */
77   R_PPC_PLT16_HA,                       /*  31 */
78   R_PPC_SDAREL,                         /*  32 */
79
80   /* Relocations added by Sun. */
81   R_PPC_SECTOFF,                        /*  33 */
82   R_PPC_SECTOFF_LO,                     /*  34 */
83   R_PPC_SECTOFF_HI,                     /*  35 */
84   R_PPC_SECTOFF_HA,                     /*  36 */
85
86   /* The remaining relocs are from the Embedded ELF ABI, and are not
87      in the SVR4 ELF ABI.  */
88   R_PPC_EMB_NADDR32 = 101,              /* 101 */
89   R_PPC_EMB_NADDR16,                    /* 102 */
90   R_PPC_EMB_NADDR16_LO,                 /* 103 */
91   R_PPC_EMB_NADDR16_HI,                 /* 104 */
92   R_PPC_EMB_NADDR16_HA,                 /* 105 */
93   R_PPC_EMB_SDAI16,                     /* 106 */
94   R_PPC_EMB_SDA2I16,                    /* 107 */
95   R_PPC_EMB_SDA2REL,                    /* 108 */
96   R_PPC_EMB_SDA21,                      /* 109 */
97   R_PPC_EMB_MRKREF,                     /* 110 */
98   R_PPC_EMB_RELSEC16,                   /* 111 */
99   R_PPC_EMB_RELST_LO,                   /* 112 */
100   R_PPC_EMB_RELST_HI,                   /* 113 */
101   R_PPC_EMB_RELST_HA,                   /* 114 */
102   R_PPC_EMB_BIT_FLD,                    /* 115 */
103   R_PPC_EMB_RELSDA,                     /* 116 */
104   R_PPC_max
105 };
106
107 static reloc_howto_type elf_powerpc_howto_table[] =
108 {
109   /* This reloc does nothing.  */
110   HOWTO (R_PPC_NONE,            /* type */
111          0,                     /* rightshift */
112          2,                     /* size (0 = byte, 1 = short, 2 = long) */
113          32,                    /* bitsize */
114          false,                 /* pc_relative */
115          0,                     /* bitpos */
116          complain_overflow_bitfield, /* complain_on_overflow */
117          bfd_elf_generic_reloc, /* special_function */
118          "R_PPC_NONE",          /* name */
119          false,                 /* partial_inplace */
120          0,                     /* src_mask */
121          0,                     /* dst_mask */
122          false),                /* pcrel_offset */
123
124   /* A standard 32 bit relocation.  */
125   HOWTO (R_PPC_ADDR32,          /* type */
126          0,                     /* rightshift */
127          2,                     /* size (0 = byte, 1 = short, 2 = long) */
128          32,                    /* bitsize */
129          false,                 /* pc_relative */
130          0,                     /* bitpos */
131          complain_overflow_bitfield, /* complain_on_overflow */
132          bfd_elf_generic_reloc, /* special_function */
133          "R_PPC_ADDR32",        /* name */
134          false,                 /* partial_inplace */
135          0,                     /* src_mask */
136          0xffffffff,            /* dst_mask */
137          false),                /* pcrel_offset */
138
139   /* An absolute 26 bit branch; the lower two bits must be zero.
140      FIXME: we don't check that, we just clear them.  */
141   HOWTO (R_PPC_ADDR24,          /* type */
142          0,                     /* rightshift */
143          2,                     /* size (0 = byte, 1 = short, 2 = long) */
144          26,                    /* bitsize */
145          false,                 /* pc_relative */
146          0,                     /* bitpos */
147          complain_overflow_bitfield, /* complain_on_overflow */
148          bfd_elf_generic_reloc, /* special_function */
149          "R_PPC_ADDR24",        /* name */
150          false,                 /* partial_inplace */
151          0,                     /* src_mask */
152          0x3fffffc,             /* dst_mask */
153          false),                /* pcrel_offset */
154
155   /* A standard 16 bit relocation.  */
156   HOWTO (R_PPC_ADDR16,          /* type */
157          0,                     /* rightshift */
158          1,                     /* size (0 = byte, 1 = short, 2 = long) */
159          16,                    /* bitsize */
160          false,                 /* pc_relative */
161          0,                     /* bitpos */
162          complain_overflow_bitfield, /* complain_on_overflow */
163          bfd_elf_generic_reloc, /* special_function */
164          "R_PPC_ADDR16",        /* name */
165          false,                 /* partial_inplace */
166          0,                     /* src_mask */
167          0xffff,                /* dst_mask */
168          false),                /* pcrel_offset */
169
170   /* A 16 bit relocation without overflow.  */
171   HOWTO (R_PPC_ADDR16_LO,       /* type */
172          0,                     /* rightshift */
173          1,                     /* size (0 = byte, 1 = short, 2 = long) */
174          16,                    /* bitsize */
175          false,                 /* pc_relative */
176          0,                     /* bitpos */
177          complain_overflow_dont,/* complain_on_overflow */
178          bfd_elf_generic_reloc, /* special_function */
179          "R_PPC_ADDR16_LO",     /* name */
180          false,                 /* partial_inplace */
181          0,                     /* src_mask */
182          0xffff,                /* dst_mask */
183          false),                /* pcrel_offset */
184
185   /* The high order 16 bits of an address.  */
186   HOWTO (R_PPC_ADDR16_HI,       /* type */
187          16,                    /* rightshift */
188          1,                     /* size (0 = byte, 1 = short, 2 = long) */
189          16,                    /* bitsize */
190          false,                 /* pc_relative */
191          0,                     /* bitpos */
192          complain_overflow_dont, /* complain_on_overflow */
193          bfd_elf_generic_reloc, /* special_function */
194          "R_PPC_ADDR16_HI",     /* name */
195          false,                 /* partial_inplace */
196          0,                     /* src_mask */
197          0xffff,                /* dst_mask */
198          false),                /* pcrel_offset */
199
200   /* The high order 16 bits of an address, plus 1 if the contents of
201      the low 16 bits, treated as a signed number, is negative.  */
202   HOWTO (R_PPC_ADDR16_HA,       /* type */
203          16,                    /* rightshift */
204          1,                     /* size (0 = byte, 1 = short, 2 = long) */
205          16,                    /* bitsize */
206          false,                 /* pc_relative */
207          0,                     /* bitpos */
208          complain_overflow_dont, /* complain_on_overflow */
209          ppc_elf_addr16_ha_reloc, /* special_function */
210          "R_PPC_ADDR16_HA",     /* name */
211          false,                 /* partial_inplace */
212          0,                     /* src_mask */
213          0xffff,                /* dst_mask */
214          false),                /* pcrel_offset */
215
216   /* An absolute 16 bit branch; the lower two bits must be zero.
217      FIXME: we don't check that, we just clear them.  */
218   HOWTO (R_PPC_ADDR14,          /* type */
219          0,                     /* rightshift */
220          2,                     /* size (0 = byte, 1 = short, 2 = long) */
221          16,                    /* bitsize */
222          false,                 /* pc_relative */
223          0,                     /* bitpos */
224          complain_overflow_bitfield, /* complain_on_overflow */
225          bfd_elf_generic_reloc, /* special_function */
226          "R_PPC_ADDR14",        /* name */
227          false,                 /* partial_inplace */
228          0,                     /* src_mask */
229          0xfffc,                /* dst_mask */
230          false),                /* pcrel_offset */
231
232   /* An absolute 16 bit branch, for which bit 10 should be set to
233      indicate that the branch is expected to be taken.  The lower two
234      bits must be zero.  */
235   HOWTO (R_PPC_ADDR14_BRTAKEN,  /* type */
236          0,                     /* rightshift */
237          2,                     /* size (0 = byte, 1 = short, 2 = long) */
238          16,                    /* bitsize */
239          false,                 /* pc_relative */
240          0,                     /* bitpos */
241          complain_overflow_bitfield, /* complain_on_overflow */
242          ppc_elf_unsupported_reloc, /* special_function */
243          "R_PPC_ADDR14_BRTAKEN",/* name */
244          false,                 /* partial_inplace */
245          0,                     /* src_mask */
246          0xfffc,                /* dst_mask */
247          false),                /* pcrel_offset */
248
249   /* An absolute 16 bit branch, for which bit 10 should be set to
250      indicate that the branch is not expected to be taken.  The lower
251      two bits must be zero.  */
252   HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
253          0,                     /* rightshift */
254          2,                     /* size (0 = byte, 1 = short, 2 = long) */
255          16,                    /* bitsize */
256          false,                 /* pc_relative */
257          0,                     /* bitpos */
258          complain_overflow_bitfield, /* complain_on_overflow */
259          ppc_elf_unsupported_reloc, /* special_function */
260          "R_PPC_ADDR14_BRNTAKEN",/* name */
261          false,                 /* partial_inplace */
262          0,                     /* src_mask */
263          0xfffc,                /* dst_mask */
264          false),                /* pcrel_offset */
265
266   /* A relative 26 bit branch; the lower two bits must be zero.  */
267   HOWTO (R_PPC_REL24,           /* type */
268          0,                     /* rightshift */
269          2,                     /* size (0 = byte, 1 = short, 2 = long) */
270          26,                    /* bitsize */
271          true,                  /* pc_relative */
272          0,                     /* bitpos */
273          complain_overflow_signed, /* complain_on_overflow */
274          bfd_elf_generic_reloc, /* special_function */
275          "R_PPC_REL24",         /* name */
276          false,                 /* partial_inplace */
277          0,                     /* src_mask */
278          0x3fffffc,             /* dst_mask */
279          true),                 /* pcrel_offset */
280
281   /* A relative 16 bit branch; the lower two bits must be zero.  */
282   HOWTO (R_PPC_REL14,           /* type */
283          0,                     /* rightshift */
284          2,                     /* size (0 = byte, 1 = short, 2 = long) */
285          16,                    /* bitsize */
286          true,                  /* pc_relative */
287          0,                     /* bitpos */
288          complain_overflow_signed, /* complain_on_overflow */
289          bfd_elf_generic_reloc, /* special_function */
290          "R_PPC_REL14",         /* name */
291          false,                 /* partial_inplace */
292          0,                     /* src_mask */
293          0xfffc,                /* dst_mask */
294          true),                 /* pcrel_offset */
295
296   /* A relative 16 bit branch.  Bit 10 should be set to indicate that
297      the branch is expected to be taken.  The lower two bits must be
298      zero.  */
299   HOWTO (R_PPC_REL14_BRTAKEN,   /* type */
300          0,                     /* rightshift */
301          2,                     /* size (0 = byte, 1 = short, 2 = long) */
302          16,                    /* bitsize */
303          false,                 /* pc_relative */
304          0,                     /* bitpos */
305          complain_overflow_signed, /* complain_on_overflow */
306          ppc_elf_unsupported_reloc, /* special_function */
307          "R_PPC_REL14_BRTAKEN", /* name */
308          false,                 /* partial_inplace */
309          0,                     /* src_mask */
310          0xfffc,                /* dst_mask */
311          true),                 /* pcrel_offset */
312
313   /* A relative 16 bit branch.  Bit 10 should be set to indicate that
314      the branch is not expected to be taken.  The lower two bits must
315      be zero.  */
316   HOWTO (R_PPC_REL14_BRNTAKEN,  /* type */
317          0,                     /* rightshift */
318          2,                     /* size (0 = byte, 1 = short, 2 = long) */
319          16,                    /* bitsize */
320          false,                 /* pc_relative */
321          0,                     /* bitpos */
322          complain_overflow_signed, /* complain_on_overflow */
323          ppc_elf_unsupported_reloc, /* special_function */
324          "R_PPC_REL14_BRNTAKEN",/* name */
325          false,                 /* partial_inplace */
326          0,                     /* src_mask */
327          0xfffc,                /* dst_mask */
328          true),                 /* pcrel_offset */
329
330   /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
331      symbol.  */
332   HOWTO (R_PPC_GOT16,           /* type */
333          0,                     /* rightshift */
334          1,                     /* size (0 = byte, 1 = short, 2 = long) */
335          16,                    /* bitsize */
336          false,                 /* pc_relative */
337          0,                     /* bitpos */
338          complain_overflow_bitfield, /* complain_on_overflow */
339          ppc_elf_got16_reloc,   /* special_function */
340          "R_PPC_GOT16",         /* name */
341          false,                 /* partial_inplace */
342          0,                     /* src_mask */
343          0xffff,                /* dst_mask */
344          false),                /* pcrel_offset */
345
346   /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
347      the symbol.  */
348   HOWTO (R_PPC_GOT16_LO,        /* type */
349          0,                     /* rightshift */
350          1,                     /* size (0 = byte, 1 = short, 2 = long) */
351          16,                    /* bitsize */
352          false,                 /* pc_relative */
353          0,                     /* bitpos */
354          complain_overflow_bitfield, /* complain_on_overflow */
355          ppc_elf_got16_reloc,   /* special_function */
356          "R_PPC_GOT16_LO",      /* name */
357          false,                 /* partial_inplace */
358          0,                     /* src_mask */
359          0xffff,                /* dst_mask */
360          false),                /* pcrel_offset */
361
362   /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
363      the symbol.  */
364   HOWTO (R_PPC_GOT16_HI,        /* type */
365          16,                    /* rightshift */
366          1,                     /* size (0 = byte, 1 = short, 2 = long) */
367          16,                    /* bitsize */
368          false,                 /* pc_relative */
369          0,                     /* bitpos */
370          complain_overflow_bitfield, /* complain_on_overflow */
371          ppc_elf_got16_reloc,   /* special_function */
372          "R_PPC_GOT16_HI",      /* name */
373          false,                 /* partial_inplace */
374          0,                     /* src_mask */
375          0xffff,                /* dst_mask */
376          false),                 /* pcrel_offset */
377
378   /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
379      the symbol.  FIXME: Not supported.  */
380   HOWTO (R_PPC_GOT16_HA,        /* type */
381          0,                     /* rightshift */
382          1,                     /* size (0 = byte, 1 = short, 2 = long) */
383          16,                    /* bitsize */
384          false,                 /* pc_relative */
385          0,                     /* bitpos */
386          complain_overflow_bitfield, /* complain_on_overflow */
387          ppc_elf_unsupported_reloc, /* special_function */
388          "R_PPC_GOT16_HA",      /* name */
389          false,                 /* partial_inplace */
390          0,                     /* src_mask */
391          0xffff,                /* dst_mask */
392          false),                /* pcrel_offset */
393
394   /* Like R_PPC_REL24, but referring to the procedure linkage table
395      entry for the symbol.  FIXME: Not supported.  */
396   HOWTO (R_PPC_PLT24,           /* type */
397          0,                     /* rightshift */
398          2,                     /* size (0 = byte, 1 = short, 2 = long) */
399          26,                    /* bitsize */
400          true,                  /* pc_relative */
401          0,                     /* bitpos */
402          complain_overflow_signed, /* complain_on_overflow */
403          bfd_elf_generic_reloc, /* special_function */
404          "R_PPC_PLT24",         /* name */
405          false,                 /* partial_inplace */
406          0,                     /* src_mask */
407          0x3fffffc,             /* dst_mask */
408          true),                 /* pcrel_offset */
409
410   /* This is used only by the dynamic linker.  The symbol should exist
411      both in the object being run and in some shared library.  The
412      dynamic linker copies the data addressed by the symbol from the
413      shared library into the object.  I have no idea what the purpose
414      of this is.  */
415   HOWTO (R_PPC_COPY,            /* type */
416          0,                     /* rightshift */
417          2,                     /* size (0 = byte, 1 = short, 2 = long) */
418          32,                    /* bitsize */
419          false,                 /* pc_relative */
420          0,                     /* bitpos */
421          complain_overflow_bitfield, /* complain_on_overflow */
422          bfd_elf_generic_reloc, /* special_function */
423          "R_PPC_COPY",          /* name */
424          false,                 /* partial_inplace */
425          0,                     /* src_mask */
426          0,                     /* dst_mask */
427          false),                /* pcrel_offset */
428
429   /* Like R_PPC_ADDR32, but used when setting global offset table
430      entries.  */
431   HOWTO (R_PPC_GLOB_DAT,        /* type */
432          0,                     /* rightshift */
433          2,                     /* size (0 = byte, 1 = short, 2 = long) */
434          32,                    /* bitsize */
435          false,                 /* pc_relative */
436          0,                     /* bitpos */
437          complain_overflow_bitfield, /* complain_on_overflow */
438          bfd_elf_generic_reloc, /* special_function */
439          "R_PPC_GLOB_DAT",      /* name */
440          false,                 /* partial_inplace */
441          0,                     /* src_mask */
442          0xffffffff,            /* dst_mask */
443          false),                /* pcrel_offset */
444
445   /* Marks a procedure linkage table entry for a symbol.  */
446   HOWTO (R_PPC_JMP_SLOT,        /* type */
447          0,                     /* rightshift */
448          2,                     /* size (0 = byte, 1 = short, 2 = long) */
449          32,                    /* bitsize */
450          false,                 /* pc_relative */
451          0,                     /* bitpos */
452          complain_overflow_bitfield, /* complain_on_overflow */
453          bfd_elf_generic_reloc, /* special_function */
454          "R_PPC_JMP_SLOT",      /* name */
455          false,                 /* partial_inplace */
456          0,                     /* src_mask */
457          0,                     /* dst_mask */
458          false),                /* pcrel_offset */
459
460   /* Used only by the dynamic linker.  When the object is run, this
461      longword is set to the load address of the object, plus the
462      addend.  */
463   HOWTO (R_PPC_RELATIVE,        /* type */
464          0,                     /* rightshift */
465          2,                     /* size (0 = byte, 1 = short, 2 = long) */
466          32,                    /* bitsize */
467          false,                 /* pc_relative */
468          0,                     /* bitpos */
469          complain_overflow_bitfield, /* complain_on_overflow */
470          bfd_elf_generic_reloc, /* special_function */
471          "R_PPC_RELATIVE",      /* name */
472          false,                 /* partial_inplace */
473          0,                     /* src_mask */
474          0xffffffff,            /* dst_mask */
475          false),                /* pcrel_offset */
476
477   /* Like R_PPC_REL24, but uses the value of the symbol within the
478      object rather than the final value.  Normally used for
479      _GLOBAL_OFFSET_TABLE_.  FIXME: Not supported.  */
480   HOWTO (R_PPC_LOCAL24PC,       /* type */
481          0,                     /* rightshift */
482          2,                     /* size (0 = byte, 1 = short, 2 = long) */
483          26,                    /* bitsize */
484          true,                  /* pc_relative */
485          0,                     /* bitpos */
486          complain_overflow_signed, /* complain_on_overflow */
487          ppc_elf_unsupported_reloc, /* special_function */
488          "R_PPC_LOCAL24PC",     /* name */
489          false,                 /* partial_inplace */
490          0,                     /* src_mask */
491          0x3fffffc,             /* dst_mask */
492          true),                 /* pcrel_offset */
493
494   /* Like R_PPC_ADDR32, but may be unaligned.  */
495   HOWTO (R_PPC_UADDR32,         /* type */
496          0,                     /* rightshift */
497          2,                     /* size (0 = byte, 1 = short, 2 = long) */
498          32,                    /* bitsize */
499          false,                 /* pc_relative */
500          0,                     /* bitpos */
501          complain_overflow_bitfield, /* complain_on_overflow */
502          bfd_elf_generic_reloc, /* special_function */
503          "R_PPC_UADDR32",       /* name */
504          false,                 /* partial_inplace */
505          0,                     /* src_mask */
506          0xffffffff,            /* dst_mask */
507          false),                /* pcrel_offset */
508
509   /* Like R_PPC_ADDR16, but may be unaligned.  */
510   HOWTO (R_PPC_UADDR16,         /* type */
511          0,                     /* rightshift */
512          1,                     /* size (0 = byte, 1 = short, 2 = long) */
513          16,                    /* bitsize */
514          false,                 /* pc_relative */
515          0,                     /* bitpos */
516          complain_overflow_bitfield, /* complain_on_overflow */
517          bfd_elf_generic_reloc, /* special_function */
518          "R_PPC_UADDR16",       /* name */
519          false,                 /* partial_inplace */
520          0,                     /* src_mask */
521          0xffff,                /* dst_mask */
522          false),                /* pcrel_offset */
523
524   /* 32-bit PC relative */
525   HOWTO (R_PPC_REL32,           /* type */
526          0,                     /* rightshift */
527          2,                     /* size (0 = byte, 1 = short, 2 = long) */
528          32,                    /* bitsize */
529          true,                  /* pc_relative */
530          0,                     /* bitpos */
531          complain_overflow_bitfield, /* complain_on_overflow */
532          bfd_elf_generic_reloc, /* special_function */
533          "R_PPC_REL32",         /* name */
534          false,                 /* partial_inplace */
535          0,                     /* src_mask */
536          0xffffffff,            /* dst_mask */
537          true),                 /* pcrel_offset */
538
539   /* 32-bit relocation to the symbol's procedure linkage table.
540      FIXEME: not supported. */
541   HOWTO (R_PPC_PLT32,           /* type */
542          0,                     /* rightshift */
543          2,                     /* size (0 = byte, 1 = short, 2 = long) */
544          32,                    /* bitsize */
545          false,                 /* pc_relative */
546          0,                     /* bitpos */
547          complain_overflow_bitfield, /* complain_on_overflow */
548          ppc_elf_unsupported_reloc, /* special_function */
549          "R_PPC_PLT32",         /* name */
550          false,                 /* partial_inplace */
551          0,                     /* src_mask */
552          0,                     /* dst_mask */
553          false),                /* pcrel_offset */
554
555   /* 32-bit PC relative relocation to the symbol's procedure linkage table.
556      FIXEME: not supported. */
557   HOWTO (R_PPC_PLTREL32,        /* type */
558          0,                     /* rightshift */
559          2,                     /* size (0 = byte, 1 = short, 2 = long) */
560          32,                    /* bitsize */
561          true,                  /* pc_relative */
562          0,                     /* bitpos */
563          complain_overflow_bitfield, /* complain_on_overflow */
564          ppc_elf_unsupported_reloc, /* special_function */
565          "R_PPC_PLTREL32",      /* name */
566          false,                 /* partial_inplace */
567          0,                     /* src_mask */
568          0,                     /* dst_mask */
569          true),                 /* pcrel_offset */
570
571   /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
572      the symbol.  */
573   HOWTO (R_PPC_PLT16_LO,        /* type */
574          0,                     /* rightshift */
575          1,                     /* size (0 = byte, 1 = short, 2 = long) */
576          16,                    /* bitsize */
577          false,                 /* pc_relative */
578          0,                     /* bitpos */
579          complain_overflow_bitfield, /* complain_on_overflow */
580          ppc_elf_unsupported_reloc, /* special_function */
581          "R_PPC_PLT16_LO",      /* name */
582          false,                 /* partial_inplace */
583          0,                     /* src_mask */
584          0xffff,                /* dst_mask */
585          false),                /* pcrel_offset */
586
587   /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
588      the symbol.  */
589   HOWTO (R_PPC_PLT16_HI,        /* type */
590          16,                    /* rightshift */
591          1,                     /* size (0 = byte, 1 = short, 2 = long) */
592          16,                    /* bitsize */
593          false,                 /* pc_relative */
594          0,                     /* bitpos */
595          complain_overflow_bitfield, /* complain_on_overflow */
596          ppc_elf_unsupported_reloc, /* special_function */
597          "R_PPC_PLT16_HI",      /* name */
598          false,                 /* partial_inplace */
599          0,                     /* src_mask */
600          0xffff,                /* dst_mask */
601          false),                 /* pcrel_offset */
602
603   /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
604      the symbol.  FIXME: Not supported.  */
605   HOWTO (R_PPC_PLT16_HA,        /* type */
606          0,                     /* rightshift */
607          1,                     /* size (0 = byte, 1 = short, 2 = long) */
608          16,                    /* bitsize */
609          false,                 /* pc_relative */
610          0,                     /* bitpos */
611          complain_overflow_bitfield, /* complain_on_overflow */
612          ppc_elf_unsupported_reloc, /* special_function */
613          "R_PPC_PLT16_HA",      /* name */
614          false,                 /* partial_inplace */
615          0,                     /* src_mask */
616          0xffff,                /* dst_mask */
617          false),                /* pcrel_offset */
618
619   /* A sign-extended 16 bit value relative to _SDA_BASE, for use with
620      small data items.  */
621   HOWTO (R_PPC_SDAREL,          /* type */
622          0,                     /* rightshift */
623          2,                     /* size (0 = byte, 1 = short, 2 = long) */
624          16,                    /* bitsize */
625          false,                 /* pc_relative */
626          0,                     /* bitpos */
627          complain_overflow_bitfield, /* complain_on_overflow */
628          ppc_elf_unsupported_reloc, /* special_function */
629          "R_PPC_SDAREL",        /* name */
630          false,                 /* partial_inplace */
631          0,                     /* src_mask */
632          0xffff,                /* dst_mask */
633          false),                /* pcrel_offset */
634
635   /* These next 4 relocations were added by Sun. */
636   /* 32-bit section relative relocation. FIXME: not supported. */
637   HOWTO (R_PPC_SECTOFF,         /* type */
638          0,                     /* rightshift */
639          2,                     /* size (0 = byte, 1 = short, 2 = long) */
640          32,                    /* bitsize */
641          true,                  /* pc_relative */
642          0,                     /* bitpos */
643          complain_overflow_bitfield, /* complain_on_overflow */
644          ppc_elf_unsupported_reloc, /* special_function */
645          "R_PPC_SECTOFF",       /* name */
646          false,                 /* partial_inplace */
647          0,                     /* src_mask */
648          0,                     /* dst_mask */
649          true),                 /* pcrel_offset */
650
651   /* 16-bit lower half section relative relocation. FIXME: not supported. */
652   HOWTO (R_PPC_SECTOFF_LO,        /* type */
653          0,                     /* rightshift */
654          1,                     /* size (0 = byte, 1 = short, 2 = long) */
655          16,                    /* bitsize */
656          false,                 /* pc_relative */
657          0,                     /* bitpos */
658          complain_overflow_bitfield, /* complain_on_overflow */
659          ppc_elf_unsupported_reloc, /* special_function */
660          "R_PPC_SECTOFF_LO",    /* name */
661          false,                 /* partial_inplace */
662          0,                     /* src_mask */
663          0xffff,                /* dst_mask */
664          false),                /* pcrel_offset */
665
666   /* 16-bit upper half section relative relocation. FIXME: not supported. */
667   HOWTO (R_PPC_SECTOFF_HI,      /* type */
668          16,                    /* rightshift */
669          1,                     /* size (0 = byte, 1 = short, 2 = long) */
670          16,                    /* bitsize */
671          false,                 /* pc_relative */
672          0,                     /* bitpos */
673          complain_overflow_bitfield, /* complain_on_overflow */
674          ppc_elf_unsupported_reloc, /* special_function */
675          "R_PPC_SECTOFF_HI",    /* name */
676          false,                 /* partial_inplace */
677          0,                     /* src_mask */
678          0xffff,                /* dst_mask */
679          false),                 /* pcrel_offset */
680
681   /* 16-bit upper half adjusted section relative relocation. FIXME: not supported. */
682   HOWTO (R_PPC_SECTOFF_HA,      /* type */
683          0,                     /* rightshift */
684          1,                     /* size (0 = byte, 1 = short, 2 = long) */
685          16,                    /* bitsize */
686          false,                 /* pc_relative */
687          0,                     /* bitpos */
688          complain_overflow_bitfield, /* complain_on_overflow */
689          ppc_elf_unsupported_reloc, /* special_function */
690          "R_PPC_SECTOFF_HA",    /* name */
691          false,                 /* partial_inplace */
692          0,                     /* src_mask */
693          0xffff,                /* dst_mask */
694          false),                /* pcrel_offset */
695
696   /* The remaining relocs are from the Embedded ELF ABI, and are not
697      in the SVR4 ELF ABI.  */
698
699   /* 32 bit value resulting from the addend minus the symbol */
700   HOWTO (R_PPC_EMB_NADDR32,     /* type */
701          0,                     /* rightshift */
702          2,                     /* size (0 = byte, 1 = short, 2 = long) */
703          32,                    /* bitsize */
704          false,                 /* pc_relative */
705          0,                     /* bitpos */
706          complain_overflow_bitfield, /* complain_on_overflow */
707          ppc_elf_unsupported_reloc, /* special_function */
708          "R_PPC_EMB_NADDR32",   /* name */
709          false,                 /* partial_inplace */
710          0,                     /* src_mask */
711          0xffffffff,            /* dst_mask */
712          false),                /* pcrel_offset */
713
714   /* 16 bit value resulting from the addend minus the symbol */
715   HOWTO (R_PPC_EMB_NADDR16,     /* type */
716          0,                     /* rightshift */
717          1,                     /* size (0 = byte, 1 = short, 2 = long) */
718          16,                    /* bitsize */
719          false,                 /* pc_relative */
720          0,                     /* bitpos */
721          complain_overflow_bitfield, /* complain_on_overflow */
722          ppc_elf_unsupported_reloc, /* special_function */
723          "R_PPC_EMB_NADDR16",   /* name */
724          false,                 /* partial_inplace */
725          0,                     /* src_mask */
726          0xffff,                /* dst_mask */
727          false),                /* pcrel_offset */
728
729   /* 16 bit value resulting from the addend minus the symbol */
730   HOWTO (R_PPC_EMB_NADDR16_LO,  /* type */
731          0,                     /* rightshift */
732          1,                     /* size (0 = byte, 1 = short, 2 = long) */
733          16,                    /* bitsize */
734          false,                 /* pc_relative */
735          0,                     /* bitpos */
736          complain_overflow_dont,/* complain_on_overflow */
737          ppc_elf_unsupported_reloc, /* special_function */
738          "R_PPC_EMB_ADDR16_LO", /* name */
739          false,                 /* partial_inplace */
740          0,                     /* src_mask */
741          0xffff,                /* dst_mask */
742          false),                /* pcrel_offset */
743
744   /* The high order 16 bits of the addend minus the symbol */
745   HOWTO (R_PPC_EMB_NADDR16_HI,  /* type */
746          16,                    /* rightshift */
747          1,                     /* size (0 = byte, 1 = short, 2 = long) */
748          16,                    /* bitsize */
749          false,                 /* pc_relative */
750          0,                     /* bitpos */
751          complain_overflow_dont, /* complain_on_overflow */
752          ppc_elf_unsupported_reloc, /* special_function */
753          "R_PPC_EMB_NADDR16_HI", /* name */
754          false,                 /* partial_inplace */
755          0,                     /* src_mask */
756          0xffff,                /* dst_mask */
757          false),                /* pcrel_offset */
758
759   /* The high order 16 bits of the result of the addend minus the address,
760      plus 1 if the contents of the low 16 bits, treated as a signed number,
761      is negative.  */
762   HOWTO (R_PPC_EMB_NADDR16_HA,  /* type */
763          16,                    /* rightshift */
764          1,                     /* size (0 = byte, 1 = short, 2 = long) */
765          16,                    /* bitsize */
766          false,                 /* pc_relative */
767          0,                     /* bitpos */
768          complain_overflow_dont, /* complain_on_overflow */
769          ppc_elf_unsupported_reloc, /* special_function */
770          "R_PPC_EMB_NADDR16_HA", /* name */
771          false,                 /* partial_inplace */
772          0,                     /* src_mask */
773          0xffff,                /* dst_mask */
774          false),                /* pcrel_offset */
775 };
776
777 /* Don't pretend we can deal with unsupported relocs.  */
778
779 /*ARGSUSED*/
780 static bfd_reloc_status_type
781 ppc_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
782                            output_bfd, error_message)
783      bfd *abfd;
784      arelent *reloc_entry;
785      asymbol *symbol;
786      PTR data;
787      asection *input_section;
788      bfd *output_bfd;
789      char **error_message;
790 {
791   abort ();
792 }
793
794 /* Handle the ADDR16_HA reloc by adjusting the reloc addend.  */
795
796 static bfd_reloc_status_type
797 ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
798                          output_bfd, error_message)
799      bfd *abfd;
800      arelent *reloc_entry;
801      asymbol *symbol;
802      PTR data;
803      asection *input_section;
804      bfd *output_bfd;
805      char **error_message;
806 {
807   bfd_vma relocation;
808
809   if (output_bfd != (bfd *) NULL)
810     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
811                                   input_section, output_bfd, error_message);
812
813   if (bfd_is_com_section (symbol->section))
814     relocation = 0;
815   else
816     relocation = symbol->value;
817
818   relocation += (symbol->section->output_section->vma
819                  + symbol->section->output_offset
820                  + reloc_entry->addend);
821
822   if ((relocation & 0x8000) != 0)
823     reloc_entry->addend += 0x10000;
824
825   return bfd_reloc_continue;
826 }
827
828 /* Handle the GOT16 reloc.  We want to use the offset within the .got
829    section, not the actual VMA.  This is appropriate when generating
830    an embedded ELF object, for which the .got section acts like the
831    AIX .toc section.  When and if we support PIC code, we will have to
832    change this, perhaps by switching off on the e_type field.  */
833
834 static bfd_reloc_status_type
835 ppc_elf_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
836                      output_bfd, error_message)
837      bfd *abfd;
838      arelent *reloc_entry;
839      asymbol *symbol;
840      PTR data;
841      asection *input_section;
842      bfd *output_bfd;
843      char **error_message;
844 {
845   asection *sec;
846
847   if (output_bfd != (bfd *) NULL)
848     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
849                                   input_section, output_bfd, error_message);
850
851   sec = bfd_get_section (*reloc_entry->sym_ptr_ptr);
852   BFD_ASSERT (bfd_is_und_section (sec)
853               || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
854               || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0);
855   reloc_entry->addend -= sec->output_section->vma;
856   return bfd_reloc_continue;
857 }
858
859 /* Map BFD reloc types to PowerPC ELF reloc types.  */
860
861 struct powerpc_reloc_map
862 {
863   unsigned char bfd_reloc_val;
864   unsigned char elf_reloc_val;
865 };
866
867 static const struct powerpc_reloc_map powerpc_reloc_map[] =
868 {
869   { BFD_RELOC_NONE, R_PPC_NONE, },
870   { BFD_RELOC_32, R_PPC_ADDR32 },
871   { BFD_RELOC_32_PCREL, R_PPC_REL32 },
872   { BFD_RELOC_CTOR, R_PPC_ADDR32 },
873   { BFD_RELOC_PPC_B26, R_PPC_REL24 },
874   { BFD_RELOC_PPC_BA26, R_PPC_ADDR24 },
875   { BFD_RELOC_PPC_TOC16, R_PPC_GOT16 },
876   { BFD_RELOC_LO16, R_PPC_ADDR16_LO },
877   { BFD_RELOC_HI16, R_PPC_ADDR16_HI },
878   { BFD_RELOC_HI16_S, R_PPC_ADDR16_HA }
879 };
880
881 static reloc_howto_type *
882 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
883      bfd *abfd;
884      bfd_reloc_code_real_type code;
885 {
886   int i;
887
888   for (i = 0;
889        i < sizeof (powerpc_reloc_map) / sizeof (struct powerpc_reloc_map);
890        i++)
891     {
892       if (powerpc_reloc_map[i].bfd_reloc_val == code)
893         return &elf_powerpc_howto_table[powerpc_reloc_map[i].elf_reloc_val];
894     }
895
896   return NULL;
897 }
898
899 /* Set the howto pointer for a PowerPC ELF reloc.  */
900
901 static void
902 powerpc_info_to_howto (abfd, cache_ptr, dst)
903      bfd *abfd;
904      arelent *cache_ptr;
905      Elf32_Internal_Rela *dst;
906 {
907   BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
908   cache_ptr->howto = &elf_powerpc_howto_table[ELF32_R_TYPE (dst->r_info)];
909 }
910
911 #define TARGET_BIG_SYM          bfd_elf32_powerpc_vec
912 #define TARGET_BIG_NAME         "elf32-powerpc"
913 #define ELF_ARCH                bfd_arch_powerpc
914 #define ELF_MACHINE_CODE        EM_PPC
915 #define ELF_MAXPAGESIZE         0x10000
916 #define elf_info_to_howto       powerpc_info_to_howto
917
918 #ifdef  EM_CYGNUS_POWERPC
919 #define ELF_MACHINE_ALT1        EM_CYGNUS_POWERPC
920 #endif
921
922 #ifdef EM_PPC_OLD
923 #define ELF_MACHINE_ALT2        EM_PPC_OLD
924 #endif
925
926 #include "elf32-target.h"
This page took 0.07615 seconds and 4 git commands to generate.