1 /* PowerPC-specific support for 32-bit ELF
2 Copyright 1994, 1995 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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. */
33 static bfd_reloc_status_type ppc_elf_unsupported_reloc
34 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
35 static bfd_reloc_status_type ppc_elf_std_reloc
36 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
38 static bfd_vma ppc_elf_addr16_ha_inner
PARAMS ((asection
*, bfd_vma
, bfd_vma
));
39 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
40 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
41 static bfd_vma ppc_elf_got16_inner
PARAMS ((asection
*sec
));
42 static bfd_reloc_status_type ppc_elf_got16_reloc
43 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
44 static reloc_howto_type
*ppc_elf_reloc_type_lookup
45 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type code
));
46 static void ppc_elf_info_to_howto
47 PARAMS ((bfd
*abfd
, arelent
*cache_ptr
, Elf32_Internal_Rela
*dst
));
48 static void ppc_elf_howto_init
PARAMS ((void));
49 static boolean ppc_elf_set_private_flags
PARAMS ((bfd
*, flagword
));
50 static boolean ppc_elf_copy_private_bfd_data
PARAMS ((bfd
*, bfd
*));
51 static boolean ppc_elf_merge_private_bfd_data
PARAMS ((bfd
*, bfd
*));
53 static boolean ppc_elf_relocate_section
PARAMS ((bfd
*,
54 struct bfd_link_info
*info
,
58 Elf_Internal_Rela
*relocs
,
59 Elf_Internal_Sym
*local_syms
,
66 R_PPC_NONE
= 0, /* 0 */
70 R_PPC_ADDR16_LO
, /* 4 */
71 R_PPC_ADDR16_HI
, /* 5 */
72 R_PPC_ADDR16_HA
, /* 6 */
74 R_PPC_ADDR14_BRTAKEN
, /* 8 */
75 R_PPC_ADDR14_BRNTAKEN
, /* 9 */
78 R_PPC_REL14_BRTAKEN
, /* 12 */
79 R_PPC_REL14_BRNTAKEN
, /* 13 */
81 R_PPC_GOT16_LO
, /* 15 */
82 R_PPC_GOT16_HI
, /* 16 */
83 R_PPC_GOT16_HA
, /* 17 */
86 R_PPC_GLOB_DAT
, /* 20 -- not in final System V spec */
87 R_PPC_JMP_SLOT
, /* 21 */
88 R_PPC_RELATIVE
, /* 22 */
89 R_PPC_LOCAL24PC
, /* 23 */
90 R_PPC_UADDR32
, /* 24 */
91 R_PPC_UADDR16
, /* 25 */
94 R_PPC_PLTREL32
, /* 28 */
95 R_PPC_PLT16_LO
, /* 29 */
96 R_PPC_PLT16_HI
, /* 30 */
97 R_PPC_PLT16_HA
, /* 31 */
98 R_PPC_SDAREL
, /* 32 */
100 /* Relocations added by Sun. */
101 R_PPC_SECTOFF
, /* 33 */
102 R_PPC_SECTOFF_LO
, /* 34 */
103 R_PPC_SECTOFF_HI
, /* 35 */
104 R_PPC_SECTOFF_HA
, /* 36 */
106 /* The remaining relocs are from the Embedded ELF ABI, and are not
107 in the SVR4 ELF ABI. */
108 R_PPC_EMB_NADDR32
= 101, /* 101 */
109 R_PPC_EMB_NADDR16
, /* 102 */
110 R_PPC_EMB_NADDR16_LO
, /* 103 */
111 R_PPC_EMB_NADDR16_HI
, /* 104 */
112 R_PPC_EMB_NADDR16_HA
, /* 105 */
113 R_PPC_EMB_SDAI16
, /* 106 */
114 R_PPC_EMB_SDA2I16
, /* 107 */
115 R_PPC_EMB_SDA2REL
, /* 108 */
116 R_PPC_EMB_SDA21
, /* 109 */
117 R_PPC_EMB_MRKREF
, /* 110 */
118 R_PPC_EMB_RELSEC16
, /* 111 */
119 R_PPC_EMB_RELST_LO
, /* 112 */
120 R_PPC_EMB_RELST_HI
, /* 113 */
121 R_PPC_EMB_RELST_HA
, /* 114 */
122 R_PPC_EMB_BIT_FLD
, /* 115 */
123 R_PPC_EMB_RELSDA
, /* 116 */
128 static reloc_howto_type
*ppc_elf_howto_table
[ (int)R_PPC_max
];
130 static reloc_howto_type ppc_elf_howto_raw
[] =
132 /* This reloc does nothing. */
133 HOWTO (R_PPC_NONE
, /* type */
135 2, /* size (0 = byte, 1 = short, 2 = long) */
137 false, /* pc_relative */
139 complain_overflow_bitfield
, /* complain_on_overflow */
140 ppc_elf_std_reloc
, /* special_function */
141 "R_PPC_NONE", /* name */
142 false, /* partial_inplace */
145 false), /* pcrel_offset */
147 /* A standard 32 bit relocation. */
148 HOWTO (R_PPC_ADDR32
, /* type */
150 2, /* size (0 = byte, 1 = short, 2 = long) */
152 false, /* pc_relative */
154 complain_overflow_bitfield
, /* complain_on_overflow */
155 ppc_elf_std_reloc
, /* special_function */
156 "R_PPC_ADDR32", /* name */
157 false, /* partial_inplace */
159 0xffffffff, /* dst_mask */
160 false), /* pcrel_offset */
162 /* An absolute 26 bit branch; the lower two bits must be zero.
163 FIXME: we don't check that, we just clear them. */
164 HOWTO (R_PPC_ADDR24
, /* type */
166 2, /* size (0 = byte, 1 = short, 2 = long) */
168 false, /* pc_relative */
170 complain_overflow_bitfield
, /* complain_on_overflow */
171 ppc_elf_std_reloc
, /* special_function */
172 "R_PPC_ADDR24", /* name */
173 false, /* partial_inplace */
175 0x3fffffc, /* dst_mask */
176 false), /* pcrel_offset */
178 /* A standard 16 bit relocation. */
179 HOWTO (R_PPC_ADDR16
, /* type */
181 1, /* size (0 = byte, 1 = short, 2 = long) */
183 false, /* pc_relative */
185 complain_overflow_bitfield
, /* complain_on_overflow */
186 ppc_elf_std_reloc
, /* special_function */
187 "R_PPC_ADDR16", /* name */
188 false, /* partial_inplace */
190 0xffff, /* dst_mask */
191 false), /* pcrel_offset */
193 /* A 16 bit relocation without overflow. */
194 HOWTO (R_PPC_ADDR16_LO
, /* type */
196 1, /* size (0 = byte, 1 = short, 2 = long) */
198 false, /* pc_relative */
200 complain_overflow_dont
,/* complain_on_overflow */
201 ppc_elf_std_reloc
, /* special_function */
202 "R_PPC_ADDR16_LO", /* name */
203 false, /* partial_inplace */
205 0xffff, /* dst_mask */
206 false), /* pcrel_offset */
208 /* The high order 16 bits of an address. */
209 HOWTO (R_PPC_ADDR16_HI
, /* type */
211 1, /* size (0 = byte, 1 = short, 2 = long) */
213 false, /* pc_relative */
215 complain_overflow_dont
, /* complain_on_overflow */
216 ppc_elf_std_reloc
, /* special_function */
217 "R_PPC_ADDR16_HI", /* name */
218 false, /* partial_inplace */
220 0xffff, /* dst_mask */
221 false), /* pcrel_offset */
223 /* The high order 16 bits of an address, plus 1 if the contents of
224 the low 16 bits, treated as a signed number, is negative. */
225 HOWTO (R_PPC_ADDR16_HA
, /* type */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
229 false, /* pc_relative */
231 complain_overflow_dont
, /* complain_on_overflow */
232 ppc_elf_addr16_ha_reloc
, /* special_function */
233 "R_PPC_ADDR16_HA", /* name */
234 false, /* partial_inplace */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
239 /* An absolute 16 bit branch; the lower two bits must be zero.
240 FIXME: we don't check that, we just clear them. */
241 HOWTO (R_PPC_ADDR14
, /* type */
243 2, /* size (0 = byte, 1 = short, 2 = long) */
245 false, /* pc_relative */
247 complain_overflow_bitfield
, /* complain_on_overflow */
248 ppc_elf_std_reloc
, /* special_function */
249 "R_PPC_ADDR14", /* name */
250 false, /* partial_inplace */
252 0xfffc, /* dst_mask */
253 false), /* pcrel_offset */
255 /* An absolute 16 bit branch, for which bit 10 should be set to
256 indicate that the branch is expected to be taken. The lower two
257 bits must be zero. */
258 HOWTO (R_PPC_ADDR14_BRTAKEN
, /* type */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
262 false, /* pc_relative */
264 complain_overflow_bitfield
, /* complain_on_overflow */
265 ppc_elf_unsupported_reloc
, /* special_function */
266 "R_PPC_ADDR14_BRTAKEN",/* name */
267 false, /* partial_inplace */
269 0xfffc, /* dst_mask */
270 false), /* pcrel_offset */
272 /* An absolute 16 bit branch, for which bit 10 should be set to
273 indicate that the branch is not expected to be taken. The lower
274 two bits must be zero. */
275 HOWTO (R_PPC_ADDR14_BRNTAKEN
, /* type */
277 2, /* size (0 = byte, 1 = short, 2 = long) */
279 false, /* pc_relative */
281 complain_overflow_bitfield
, /* complain_on_overflow */
282 ppc_elf_unsupported_reloc
, /* special_function */
283 "R_PPC_ADDR14_BRNTAKEN",/* name */
284 false, /* partial_inplace */
286 0xfffc, /* dst_mask */
287 false), /* pcrel_offset */
289 /* A relative 26 bit branch; the lower two bits must be zero. */
290 HOWTO (R_PPC_REL24
, /* type */
292 2, /* size (0 = byte, 1 = short, 2 = long) */
294 true, /* pc_relative */
296 complain_overflow_signed
, /* complain_on_overflow */
297 ppc_elf_std_reloc
, /* special_function */
298 "R_PPC_REL24", /* name */
299 false, /* partial_inplace */
301 0x3fffffc, /* dst_mask */
302 true), /* pcrel_offset */
304 /* A relative 16 bit branch; the lower two bits must be zero. */
305 HOWTO (R_PPC_REL14
, /* type */
307 2, /* size (0 = byte, 1 = short, 2 = long) */
309 true, /* pc_relative */
311 complain_overflow_signed
, /* complain_on_overflow */
312 ppc_elf_std_reloc
, /* special_function */
313 "R_PPC_REL14", /* name */
314 false, /* partial_inplace */
316 0xfffc, /* dst_mask */
317 true), /* pcrel_offset */
319 /* A relative 16 bit branch. Bit 10 should be set to indicate that
320 the branch is expected to be taken. The lower two bits must be
322 HOWTO (R_PPC_REL14_BRTAKEN
, /* type */
324 2, /* size (0 = byte, 1 = short, 2 = long) */
326 false, /* pc_relative */
328 complain_overflow_signed
, /* complain_on_overflow */
329 ppc_elf_unsupported_reloc
, /* special_function */
330 "R_PPC_REL14_BRTAKEN", /* name */
331 false, /* partial_inplace */
333 0xfffc, /* dst_mask */
334 true), /* pcrel_offset */
336 /* A relative 16 bit branch. Bit 10 should be set to indicate that
337 the branch is not expected to be taken. The lower two bits must
339 HOWTO (R_PPC_REL14_BRNTAKEN
, /* type */
341 2, /* size (0 = byte, 1 = short, 2 = long) */
343 false, /* pc_relative */
345 complain_overflow_signed
, /* complain_on_overflow */
346 ppc_elf_unsupported_reloc
, /* special_function */
347 "R_PPC_REL14_BRNTAKEN",/* name */
348 false, /* partial_inplace */
350 0xfffc, /* dst_mask */
351 true), /* pcrel_offset */
353 /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
355 HOWTO (R_PPC_GOT16
, /* type */
357 1, /* size (0 = byte, 1 = short, 2 = long) */
359 false, /* pc_relative */
361 complain_overflow_signed
, /* complain_on_overflow */
362 ppc_elf_got16_reloc
, /* special_function */
363 "R_PPC_GOT16", /* name */
364 false, /* partial_inplace */
366 0xffff, /* dst_mask */
367 false), /* pcrel_offset */
369 /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
371 HOWTO (R_PPC_GOT16_LO
, /* type */
373 1, /* size (0 = byte, 1 = short, 2 = long) */
375 false, /* pc_relative */
377 complain_overflow_bitfield
, /* complain_on_overflow */
378 ppc_elf_got16_reloc
, /* special_function */
379 "R_PPC_GOT16_LO", /* name */
380 false, /* partial_inplace */
382 0xffff, /* dst_mask */
383 false), /* pcrel_offset */
385 /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
387 HOWTO (R_PPC_GOT16_HI
, /* type */
389 1, /* size (0 = byte, 1 = short, 2 = long) */
391 false, /* pc_relative */
393 complain_overflow_bitfield
, /* complain_on_overflow */
394 ppc_elf_got16_reloc
, /* special_function */
395 "R_PPC_GOT16_HI", /* name */
396 false, /* partial_inplace */
398 0xffff, /* dst_mask */
399 false), /* pcrel_offset */
401 /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
402 the symbol. FIXME: Not supported. */
403 HOWTO (R_PPC_GOT16_HA
, /* type */
405 1, /* size (0 = byte, 1 = short, 2 = long) */
407 false, /* pc_relative */
409 complain_overflow_bitfield
, /* complain_on_overflow */
410 ppc_elf_unsupported_reloc
, /* special_function */
411 "R_PPC_GOT16_HA", /* name */
412 false, /* partial_inplace */
414 0xffff, /* dst_mask */
415 false), /* pcrel_offset */
417 /* Like R_PPC_REL24, but referring to the procedure linkage table
418 entry for the symbol. FIXME: Not supported. */
419 HOWTO (R_PPC_PLT24
, /* type */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 true, /* pc_relative */
425 complain_overflow_signed
, /* complain_on_overflow */
426 ppc_elf_std_reloc
, /* special_function */
427 "R_PPC_PLT24", /* name */
428 false, /* partial_inplace */
430 0x3fffffc, /* dst_mask */
431 true), /* pcrel_offset */
433 /* This is used only by the dynamic linker. The symbol should exist
434 both in the object being run and in some shared library. The
435 dynamic linker copies the data addressed by the symbol from the
436 shared library into the object. I have no idea what the purpose
438 HOWTO (R_PPC_COPY
, /* type */
440 2, /* size (0 = byte, 1 = short, 2 = long) */
442 false, /* pc_relative */
444 complain_overflow_bitfield
, /* complain_on_overflow */
445 ppc_elf_std_reloc
, /* special_function */
446 "R_PPC_COPY", /* name */
447 false, /* partial_inplace */
450 false), /* pcrel_offset */
452 /* Like R_PPC_ADDR32, but used when setting global offset table
454 HOWTO (R_PPC_GLOB_DAT
, /* type */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
458 false, /* pc_relative */
460 complain_overflow_bitfield
, /* complain_on_overflow */
461 ppc_elf_std_reloc
, /* special_function */
462 "R_PPC_GLOB_DAT", /* name */
463 false, /* partial_inplace */
465 0xffffffff, /* dst_mask */
466 false), /* pcrel_offset */
468 /* Marks a procedure linkage table entry for a symbol. */
469 HOWTO (R_PPC_JMP_SLOT
, /* type */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 false, /* pc_relative */
475 complain_overflow_bitfield
, /* complain_on_overflow */
476 ppc_elf_std_reloc
, /* special_function */
477 "R_PPC_JMP_SLOT", /* name */
478 false, /* partial_inplace */
481 false), /* pcrel_offset */
483 /* Used only by the dynamic linker. When the object is run, this
484 longword is set to the load address of the object, plus the
486 HOWTO (R_PPC_RELATIVE
, /* type */
488 2, /* size (0 = byte, 1 = short, 2 = long) */
490 false, /* pc_relative */
492 complain_overflow_bitfield
, /* complain_on_overflow */
493 ppc_elf_std_reloc
, /* special_function */
494 "R_PPC_RELATIVE", /* name */
495 false, /* partial_inplace */
497 0xffffffff, /* dst_mask */
498 false), /* pcrel_offset */
500 /* Like R_PPC_REL24, but uses the value of the symbol within the
501 object rather than the final value. Normally used for
502 _GLOBAL_OFFSET_TABLE_. FIXME: Not supported. */
503 HOWTO (R_PPC_LOCAL24PC
, /* type */
505 2, /* size (0 = byte, 1 = short, 2 = long) */
507 true, /* pc_relative */
509 complain_overflow_signed
, /* complain_on_overflow */
510 ppc_elf_unsupported_reloc
, /* special_function */
511 "R_PPC_LOCAL24PC", /* name */
512 false, /* partial_inplace */
514 0x3fffffc, /* dst_mask */
515 true), /* pcrel_offset */
517 /* Like R_PPC_ADDR32, but may be unaligned. */
518 HOWTO (R_PPC_UADDR32
, /* type */
520 2, /* size (0 = byte, 1 = short, 2 = long) */
522 false, /* pc_relative */
524 complain_overflow_bitfield
, /* complain_on_overflow */
525 ppc_elf_std_reloc
, /* special_function */
526 "R_PPC_UADDR32", /* name */
527 false, /* partial_inplace */
529 0xffffffff, /* dst_mask */
530 false), /* pcrel_offset */
532 /* Like R_PPC_ADDR16, but may be unaligned. */
533 HOWTO (R_PPC_UADDR16
, /* type */
535 1, /* size (0 = byte, 1 = short, 2 = long) */
537 false, /* pc_relative */
539 complain_overflow_bitfield
, /* complain_on_overflow */
540 ppc_elf_std_reloc
, /* special_function */
541 "R_PPC_UADDR16", /* name */
542 false, /* partial_inplace */
544 0xffff, /* dst_mask */
545 false), /* pcrel_offset */
547 /* 32-bit PC relative */
548 HOWTO (R_PPC_REL32
, /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 true, /* pc_relative */
554 complain_overflow_bitfield
, /* complain_on_overflow */
555 ppc_elf_std_reloc
, /* special_function */
556 "R_PPC_REL32", /* name */
557 false, /* partial_inplace */
559 0xffffffff, /* dst_mask */
560 true), /* pcrel_offset */
562 /* 32-bit relocation to the symbol's procedure linkage table.
563 FIXEME: not supported. */
564 HOWTO (R_PPC_PLT32
, /* type */
566 2, /* size (0 = byte, 1 = short, 2 = long) */
568 false, /* pc_relative */
570 complain_overflow_bitfield
, /* complain_on_overflow */
571 ppc_elf_unsupported_reloc
, /* special_function */
572 "R_PPC_PLT32", /* name */
573 false, /* partial_inplace */
576 false), /* pcrel_offset */
578 /* 32-bit PC relative relocation to the symbol's procedure linkage table.
579 FIXEME: not supported. */
580 HOWTO (R_PPC_PLTREL32
, /* type */
582 2, /* size (0 = byte, 1 = short, 2 = long) */
584 true, /* pc_relative */
586 complain_overflow_bitfield
, /* complain_on_overflow */
587 ppc_elf_unsupported_reloc
, /* special_function */
588 "R_PPC_PLTREL32", /* name */
589 false, /* partial_inplace */
592 true), /* pcrel_offset */
594 /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
596 HOWTO (R_PPC_PLT16_LO
, /* type */
598 1, /* size (0 = byte, 1 = short, 2 = long) */
600 false, /* pc_relative */
602 complain_overflow_bitfield
, /* complain_on_overflow */
603 ppc_elf_unsupported_reloc
, /* special_function */
604 "R_PPC_PLT16_LO", /* name */
605 false, /* partial_inplace */
607 0xffff, /* dst_mask */
608 false), /* pcrel_offset */
610 /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
612 HOWTO (R_PPC_PLT16_HI
, /* type */
614 1, /* size (0 = byte, 1 = short, 2 = long) */
616 false, /* pc_relative */
618 complain_overflow_bitfield
, /* complain_on_overflow */
619 ppc_elf_unsupported_reloc
, /* special_function */
620 "R_PPC_PLT16_HI", /* name */
621 false, /* partial_inplace */
623 0xffff, /* dst_mask */
624 false), /* pcrel_offset */
626 /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
627 the symbol. FIXME: Not supported. */
628 HOWTO (R_PPC_PLT16_HA
, /* type */
630 1, /* size (0 = byte, 1 = short, 2 = long) */
632 false, /* pc_relative */
634 complain_overflow_bitfield
, /* complain_on_overflow */
635 ppc_elf_unsupported_reloc
, /* special_function */
636 "R_PPC_PLT16_HA", /* name */
637 false, /* partial_inplace */
639 0xffff, /* dst_mask */
640 false), /* pcrel_offset */
642 /* A sign-extended 16 bit value relative to _SDA_BASE, for use with
644 HOWTO (R_PPC_SDAREL
, /* type */
646 2, /* size (0 = byte, 1 = short, 2 = long) */
648 false, /* pc_relative */
650 complain_overflow_bitfield
, /* complain_on_overflow */
651 ppc_elf_unsupported_reloc
, /* special_function */
652 "R_PPC_SDAREL", /* name */
653 false, /* partial_inplace */
655 0xffff, /* dst_mask */
656 false), /* pcrel_offset */
658 /* These next 4 relocations were added by Sun. */
659 /* 32-bit section relative relocation. FIXME: not supported. */
660 HOWTO (R_PPC_SECTOFF
, /* type */
662 2, /* size (0 = byte, 1 = short, 2 = long) */
664 true, /* pc_relative */
666 complain_overflow_bitfield
, /* complain_on_overflow */
667 ppc_elf_unsupported_reloc
, /* special_function */
668 "R_PPC_SECTOFF", /* name */
669 false, /* partial_inplace */
672 true), /* pcrel_offset */
674 /* 16-bit lower half section relative relocation. FIXME: not supported. */
675 HOWTO (R_PPC_SECTOFF_LO
, /* type */
677 1, /* size (0 = byte, 1 = short, 2 = long) */
679 false, /* pc_relative */
681 complain_overflow_bitfield
, /* complain_on_overflow */
682 ppc_elf_unsupported_reloc
, /* special_function */
683 "R_PPC_SECTOFF_LO", /* name */
684 false, /* partial_inplace */
686 0xffff, /* dst_mask */
687 false), /* pcrel_offset */
689 /* 16-bit upper half section relative relocation. FIXME: not supported. */
690 HOWTO (R_PPC_SECTOFF_HI
, /* type */
692 1, /* size (0 = byte, 1 = short, 2 = long) */
694 false, /* pc_relative */
696 complain_overflow_bitfield
, /* complain_on_overflow */
697 ppc_elf_unsupported_reloc
, /* special_function */
698 "R_PPC_SECTOFF_HI", /* name */
699 false, /* partial_inplace */
701 0xffff, /* dst_mask */
702 false), /* pcrel_offset */
704 /* 16-bit upper half adjusted section relative relocation. FIXME: not supported. */
705 HOWTO (R_PPC_SECTOFF_HA
, /* type */
707 1, /* size (0 = byte, 1 = short, 2 = long) */
709 false, /* pc_relative */
711 complain_overflow_bitfield
, /* complain_on_overflow */
712 ppc_elf_unsupported_reloc
, /* special_function */
713 "R_PPC_SECTOFF_HA", /* name */
714 false, /* partial_inplace */
716 0xffff, /* dst_mask */
717 false), /* pcrel_offset */
719 /* The remaining relocs are from the Embedded ELF ABI, and are not
720 in the SVR4 ELF ABI. */
722 /* 32 bit value resulting from the addend minus the symbol */
723 HOWTO (R_PPC_EMB_NADDR32
, /* type */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
727 false, /* pc_relative */
729 complain_overflow_bitfield
, /* complain_on_overflow */
730 ppc_elf_unsupported_reloc
, /* special_function */
731 "R_PPC_EMB_NADDR32", /* name */
732 false, /* partial_inplace */
734 0xffffffff, /* dst_mask */
735 false), /* pcrel_offset */
737 /* 16 bit value resulting from the addend minus the symbol */
738 HOWTO (R_PPC_EMB_NADDR16
, /* type */
740 1, /* size (0 = byte, 1 = short, 2 = long) */
742 false, /* pc_relative */
744 complain_overflow_bitfield
, /* complain_on_overflow */
745 ppc_elf_unsupported_reloc
, /* special_function */
746 "R_PPC_EMB_NADDR16", /* name */
747 false, /* partial_inplace */
749 0xffff, /* dst_mask */
750 false), /* pcrel_offset */
752 /* 16 bit value resulting from the addend minus the symbol */
753 HOWTO (R_PPC_EMB_NADDR16_LO
, /* type */
755 1, /* size (0 = byte, 1 = short, 2 = long) */
757 false, /* pc_relative */
759 complain_overflow_dont
,/* complain_on_overflow */
760 ppc_elf_unsupported_reloc
, /* special_function */
761 "R_PPC_EMB_ADDR16_LO", /* name */
762 false, /* partial_inplace */
764 0xffff, /* dst_mask */
765 false), /* pcrel_offset */
767 /* The high order 16 bits of the addend minus the symbol */
768 HOWTO (R_PPC_EMB_NADDR16_HI
, /* type */
770 1, /* size (0 = byte, 1 = short, 2 = long) */
772 false, /* pc_relative */
774 complain_overflow_dont
, /* complain_on_overflow */
775 ppc_elf_unsupported_reloc
, /* special_function */
776 "R_PPC_EMB_NADDR16_HI", /* name */
777 false, /* partial_inplace */
779 0xffff, /* dst_mask */
780 false), /* pcrel_offset */
782 /* The high order 16 bits of the result of the addend minus the address,
783 plus 1 if the contents of the low 16 bits, treated as a signed number,
785 HOWTO (R_PPC_EMB_NADDR16_HA
, /* type */
787 1, /* size (0 = byte, 1 = short, 2 = long) */
789 false, /* pc_relative */
791 complain_overflow_dont
, /* complain_on_overflow */
792 ppc_elf_unsupported_reloc
, /* special_function */
793 "R_PPC_EMB_NADDR16_HA", /* name */
794 false, /* partial_inplace */
796 0xffff, /* dst_mask */
797 false), /* pcrel_offset */
801 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
804 ppc_elf_howto_init ()
806 unsigned int i
, type
;
808 for (i
= 0; i
< sizeof (ppc_elf_howto_raw
) / sizeof (ppc_elf_howto_raw
[0]); i
++)
810 type
= ppc_elf_howto_raw
[i
].type
;
811 BFD_ASSERT (type
< sizeof(ppc_elf_howto_table
) / sizeof(ppc_elf_howto_table
[0]));
812 ppc_elf_howto_table
[type
] = &ppc_elf_howto_raw
[i
];
817 static reloc_howto_type
*
818 ppc_elf_reloc_type_lookup (abfd
, code
)
820 bfd_reloc_code_real_type code
;
822 if (!ppc_elf_howto_table
[ R_PPC_ADDR32
]) /* Initialize howto table if needed */
823 ppc_elf_howto_init ();
827 case BFD_RELOC_NONE
: return ppc_elf_howto_table
[ (int) R_PPC_NONE
];
828 case BFD_RELOC_32
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR32
];
829 case BFD_RELOC_32_PCREL
: return ppc_elf_howto_table
[ (int) R_PPC_REL32
];
830 case BFD_RELOC_CTOR
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR32
];
831 case BFD_RELOC_PPC_B26
: return ppc_elf_howto_table
[ (int) R_PPC_REL24
];
832 case BFD_RELOC_PPC_BA26
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR24
];
833 case BFD_RELOC_PPC_TOC16
: return ppc_elf_howto_table
[ (int) R_PPC_GOT16
];
834 case BFD_RELOC_LO16
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR16_LO
];
835 case BFD_RELOC_HI16
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR16_HI
];
836 case BFD_RELOC_HI16_S
: return ppc_elf_howto_table
[ (int) R_PPC_ADDR16_HA
];
839 return (reloc_howto_type
*)NULL
;
842 /* Set the howto pointer for a PowerPC ELF reloc. */
845 ppc_elf_info_to_howto (abfd
, cache_ptr
, dst
)
848 Elf32_Internal_Rela
*dst
;
850 if (!ppc_elf_howto_table
[ R_PPC_ADDR32
]) /* Initialize howto table if needed */
851 ppc_elf_howto_init ();
853 BFD_ASSERT (ELF32_R_TYPE (dst
->r_info
) < (unsigned int) R_PPC_max
);
854 cache_ptr
->howto
= ppc_elf_howto_table
[ELF32_R_TYPE (dst
->r_info
)];
857 /* Function to set whether a module needs the -mrelocatable bit set. */
860 ppc_elf_set_private_flags (abfd
, flags
)
864 BFD_ASSERT (!elf_ppc_flags_init (abfd
)
865 || elf_elfheader (abfd
)->e_flags
== flags
);
867 elf_elfheader (abfd
)->e_flags
= flags
;
868 elf_ppc_flags_init (abfd
) = true;
872 /* Copy backend specific data from one object module to another */
874 ppc_elf_copy_private_bfd_data (ibfd
, obfd
)
878 /* This function is selected based on the input vector. We only
879 want to copy information over if the output BFD also uses Elf
881 if (bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
884 BFD_ASSERT (!elf_ppc_flags_init (obfd
)
885 || elf_elfheader (obfd
)->e_flags
== elf_elfheader (ibfd
)->e_flags
);
887 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
888 elf_ppc_flags_init (obfd
) = true;
892 /* Merge backend specific data from an object file to the output
893 object file when linking */
895 ppc_elf_merge_private_bfd_data (ibfd
, obfd
)
902 /* Check if we have the same endianess */
903 if (ibfd
->xvec
->byteorder_big_p
!= obfd
->xvec
->byteorder_big_p
)
906 "%s: compiled for a %s endian system and target is %s endian.\n",
907 bfd_get_filename (ibfd
),
908 (ibfd
->xvec
->byteorder_big_p
) ? "big" : "little",
909 (obfd
->xvec
->byteorder_big_p
) ? "big" : "little");
911 bfd_set_error (bfd_error_wrong_format
);
915 /* This function is selected based on the input vector. We only
916 want to copy information over if the output BFD also uses Elf
918 if (bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
921 new_flags
= elf_elfheader (ibfd
)->e_flags
;
922 old_flags
= elf_elfheader (obfd
)->e_flags
;
923 if (!elf_ppc_flags_init (obfd
)) /* First call, no flags set */
925 elf_ppc_flags_init (obfd
) = true;
926 elf_elfheader (obfd
)->e_flags
= new_flags
;
929 else if (new_flags
== old_flags
) /* Compatible flags are ok */
932 else /* Incompatible flags */
934 /* Warn about -mrelocatable mismatch */
935 if ((new_flags
& EF_PPC_RELOCATABLE
) != 0 && (old_flags
& EF_PPC_RELOCATABLE
) == 0)
937 new_flags
&= ~EF_PPC_RELOCATABLE
;
939 "%s: compiled with -mrelocatable and linked with modules compiled normally\n",
940 bfd_get_filename (ibfd
));
942 else if ((new_flags
& EF_PPC_RELOCATABLE
) == 0 && (old_flags
& EF_PPC_RELOCATABLE
) != 0)
944 old_flags
&= ~EF_PPC_RELOCATABLE
;
946 "%s: compiled normally and linked with modules compiled with -mrelocatable\n",
947 bfd_get_filename (ibfd
));
950 /* Warn about eabi vs. V.4 mismatch */
951 if ((new_flags
& EF_PPC_EMB
) != 0 && (old_flags
& EF_PPC_EMB
) == 0)
953 new_flags
&= ~EF_PPC_EMB
;
955 "%s: compiled for the eabi and linked with modules compiled for System V\n",
956 bfd_get_filename (ibfd
));
958 else if ((new_flags
& EF_PPC_EMB
) == 0 && (old_flags
& EF_PPC_EMB
) != 0)
960 old_flags
&= ~EF_PPC_EMB
;
962 "%s: compiled for System V and linked with modules compiled for eabi\n",
963 bfd_get_filename (ibfd
));
966 /* Warn about any other mismatches */
967 if (new_flags
!= old_flags
)
969 "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)\n",
970 bfd_get_filename (ibfd
), (long)new_flags
, (long)old_flags
);
972 bfd_set_error (bfd_error_bad_value
);
980 /* ELF relocs are against symbols. If we are producing relocateable
981 output, and the reloc is against an external symbol, and nothing
982 has given us any additional addend, the resulting reloc will also
983 be against the same symbol. In such a case, we don't want to
984 change anything about the way the reloc is handled, since it will
985 all be done at final link time. Rather than put special case code
986 into bfd_perform_relocation, all the reloc types use this howto
987 function. It just short circuits the reloc if producing
988 relocateable output against an external symbol. */
991 static bfd_reloc_status_type
992 ppc_elf_std_reloc (abfd
,
1000 arelent
*reloc_entry
;
1003 asection
*input_section
;
1005 char **error_message
;
1007 if (output_bfd
!= (bfd
*) NULL
1008 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1009 && (! reloc_entry
->howto
->partial_inplace
|| reloc_entry
->addend
== 0))
1011 reloc_entry
->address
+= input_section
->output_offset
;
1012 return bfd_reloc_ok
;
1015 return bfd_reloc_continue
;
1018 /* Don't pretend we can deal with unsupported relocs. */
1021 static bfd_reloc_status_type
1022 ppc_elf_unsupported_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1023 output_bfd
, error_message
)
1025 arelent
*reloc_entry
;
1028 asection
*input_section
;
1030 char **error_message
;
1032 BFD_ASSERT (reloc_entry
->howto
!= (reloc_howto_type
*)0);
1034 "%s: Relocation %s (%d) is not currently supported.\n",
1035 bfd_get_filename (abfd
),
1036 reloc_entry
->howto
->name
,
1037 reloc_entry
->howto
->type
);
1039 return bfd_reloc_notsupported
;
1042 /* Internal function to return the adjustment to the addend for relocations
1043 that return the upper 16 bits after sign extending the lower 16 bits, ie
1044 for use with a ORIS instruction followed by a memory reference using the
1049 ppc_elf_addr16_ha_inner (sec
, value
, addend
)
1054 bfd_vma relocation
= (value
1055 + sec
->output_section
->vma
1056 + sec
->output_offset
1059 return (relocation
& 0x8000) << 1;
1062 /* Handle the ADDR16_HA reloc by adjusting the reloc addend. */
1065 static bfd_reloc_status_type
1066 ppc_elf_addr16_ha_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1067 output_bfd
, error_message
)
1069 arelent
*reloc_entry
;
1072 asection
*input_section
;
1074 char **error_message
;
1076 if (output_bfd
!= (bfd
*) NULL
)
1077 return ppc_elf_std_reloc (abfd
, reloc_entry
, symbol
, data
,
1078 input_section
, output_bfd
, error_message
);
1080 reloc_entry
->addend
+= ppc_elf_addr16_ha_inner (symbol
->section
,
1081 (bfd_is_com_section (symbol
->section
)) ? 0 : symbol
->value
,
1082 reloc_entry
->addend
);
1083 return bfd_reloc_continue
;
1086 /* Internal function to return the addjustment to the addend for GOT16
1091 ppc_elf_got16_inner (sec
)
1094 BFD_ASSERT (bfd_is_und_section (sec
)
1095 || strcmp (bfd_get_section_name (abfd
, sec
), ".got") == 0
1096 || strcmp (bfd_get_section_name (abfd
, sec
), ".cgot") == 0);
1098 return -(sec
->output_section
->vma
+ 0x8000);
1101 /* Handle the GOT16 reloc. We want to use the offset within the .got
1102 section, not the actual VMA. This is appropriate when generating
1103 an embedded ELF object, for which the .got section acts like the
1104 AIX .toc section. When and if we support PIC code, we will have to
1105 change this, perhaps by switching off on the e_type field. */
1108 static bfd_reloc_status_type
1109 ppc_elf_got16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1110 output_bfd
, error_message
)
1112 arelent
*reloc_entry
;
1115 asection
*input_section
;
1117 char **error_message
;
1119 if (output_bfd
!= (bfd
*) NULL
)
1120 return ppc_elf_std_reloc (abfd
, reloc_entry
, symbol
, data
,
1121 input_section
, output_bfd
, error_message
);
1123 reloc_entry
->addend
+= ppc_elf_got16_inner (bfd_get_section (*reloc_entry
->sym_ptr_ptr
));
1124 return bfd_reloc_continue
;
1128 /* The RELOCATE_SECTION function is called by the ELF backend linker
1129 to handle the relocations for a section.
1131 The relocs are always passed as Rela structures; if the section
1132 actually uses Rel structures, the r_addend field will always be
1135 This function is responsible for adjust the section contents as
1136 necessary, and (if using Rela relocs and generating a
1137 relocateable output file) adjusting the reloc addend as
1140 This function does not have to worry about setting the reloc
1141 address or the reloc symbol index.
1143 LOCAL_SYMS is a pointer to the swapped in local symbols.
1145 LOCAL_SECTIONS is an array giving the section in the input file
1146 corresponding to the st_shndx field of each local symbol.
1148 The global hash table entry for the global symbols can be found
1149 via elf_sym_hashes (input_bfd).
1151 When generating relocateable output, this function must handle
1152 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1153 going to be the section symbol corresponding to the output
1154 section, which means that the addend must be adjusted
1158 ppc_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1159 contents
, relocs
, local_syms
, local_sections
)
1161 struct bfd_link_info
*info
;
1163 asection
*input_section
;
1165 Elf_Internal_Rela
*relocs
;
1166 Elf_Internal_Sym
*local_syms
;
1167 asection
**local_sections
;
1169 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1170 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
1171 Elf_Internal_Rela
*rel
= relocs
;
1172 Elf_Internal_Rela
*relend
= relocs
+ input_section
->reloc_count
;
1176 fprintf (stderr
, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
1177 bfd_get_filename (input_bfd
),
1178 bfd_section_name(input_bfd
, input_section
),
1179 (long)input_section
->reloc_count
,
1180 (info
->relocateable
) ? " (relocatable)" : "");
1183 if (!ppc_elf_howto_table
[ R_PPC_ADDR32
]) /* Initialize howto table if needed */
1184 ppc_elf_howto_init ();
1186 for (; rel
< relend
; rel
++)
1188 enum reloc_type r_type
= (enum reloc_type
)ELF32_R_TYPE (rel
->r_info
);
1189 bfd_vma offset
= rel
->r_offset
;
1190 bfd_vma addend
= rel
->r_addend
;
1191 bfd_reloc_status_type r
= bfd_reloc_other
;
1192 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)0;
1193 asection
*sec
= (asection
*)0;
1194 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*)0;
1195 reloc_howto_type
*howto
;
1196 unsigned long r_symndx
;
1199 /* Unknown relocation handling */
1200 if ((unsigned)r_type
>= (unsigned)R_PPC_max
|| !ppc_elf_howto_table
[(int)r_type
])
1203 "%s: Unknown relocation type %d\n",
1204 bfd_get_filename (input_bfd
),
1207 bfd_set_error (bfd_error_bad_value
);
1212 howto
= ppc_elf_howto_table
[(int)r_type
];
1213 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1215 if (info
->relocateable
)
1217 /* This is a relocateable link. We don't have to change
1218 anything, unless the reloc is against a section symbol,
1219 in which case we have to adjust according to where the
1220 section symbol winds up in the output section. */
1221 if (r_symndx
< symtab_hdr
->sh_info
)
1223 sym
= local_syms
+ r_symndx
;
1224 if ((unsigned)ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1226 sec
= local_sections
[r_symndx
];
1227 addend
= rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1232 fprintf (stderr
, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
1242 /* This is a final link. */
1244 /* Complain about known relocation that are not yet supported */
1245 if (howto
->special_function
== ppc_elf_unsupported_reloc
)
1248 "%s: Relocation %s (%d) is not currently supported.\n",
1249 bfd_get_filename (input_bfd
),
1253 bfd_set_error (bfd_error_bad_value
);
1258 if (r_symndx
< symtab_hdr
->sh_info
)
1260 sym
= local_syms
+ r_symndx
;
1261 sec
= local_sections
[r_symndx
];
1262 relocation
= (sec
->output_section
->vma
1263 + sec
->output_offset
1268 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1269 if (h
->root
.type
== bfd_link_hash_defined
1270 || h
->root
.type
== bfd_link_hash_defweak
)
1272 sec
= h
->root
.u
.def
.section
;
1273 relocation
= (h
->root
.u
.def
.value
1274 + sec
->output_section
->vma
1275 + sec
->output_offset
);
1277 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1279 else if (info
->shared
)
1283 (*info
->callbacks
->undefined_symbol
)(info
,
1284 h
->root
.root
.string
,
1293 switch ((int)r_type
)
1298 case (int)R_PPC_GOT16
: /* GOT16 relocations */
1299 case (int)R_PPC_GOT16_LO
:
1300 case (int)R_PPC_GOT16_HI
:
1301 BFD_ASSERT (sec
!= (asection
*)0);
1302 addend
+= ppc_elf_got16_inner (sec
);
1305 case (int)R_PPC_ADDR16_HA
: /* arithmetic adjust relocations */
1306 BFD_ASSERT (sec
!= (asection
*)0);
1307 addend
+= ppc_elf_addr16_ha_inner (sec
, relocation
, addend
);
1313 fprintf (stderr
, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
1321 r
= _bfd_final_link_relocate (howto
,
1329 if (r
!= bfd_reloc_ok
)
1337 case bfd_reloc_overflow
:
1342 name
= h
->root
.root
.string
;
1345 name
= bfd_elf_string_from_elf_section (input_bfd
,
1346 symtab_hdr
->sh_link
,
1352 name
= bfd_section_name (input_bfd
, sec
);
1355 (*info
->callbacks
->reloc_overflow
)(info
,
1371 fprintf (stderr
, "\n");
1377 #define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
1378 #define TARGET_LITTLE_NAME "elf32-powerpcle"
1379 #define TARGET_BIG_SYM bfd_elf32_powerpc_vec
1380 #define TARGET_BIG_NAME "elf32-powerpc"
1381 #define ELF_ARCH bfd_arch_powerpc
1382 #define ELF_MACHINE_CODE EM_PPC
1383 #define ELF_MAXPAGESIZE 0x10000
1384 #define elf_info_to_howto ppc_elf_info_to_howto
1386 #ifdef EM_CYGNUS_POWERPC
1387 #define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC
1391 #define ELF_MACHINE_ALT2 EM_PPC_OLD
1394 #define bfd_elf32_bfd_copy_private_bfd_data ppc_elf_copy_private_bfd_data
1395 #define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data
1396 #define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
1397 #define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup
1398 #define elf_backend_relocate_section ppc_elf_relocate_section
1400 #include "elf32-target.h"