Wed Oct 18 15:53:56 1995 steve chamberlain <sac@slash.cygnus.com>
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
CommitLineData
bcbe2c71
MM
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
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
dd82c578 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
bcbe2c71
MM
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"
ede4eed4 28#include "bfdlink.h"
bcbe2c71
MM
29#include "libbfd.h"
30#include "libelf.h"
ede4eed4 31#include "elf/ppc.h"
bcbe2c71
MM
32
33static bfd_reloc_status_type ppc_elf_unsupported_reloc
34 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
ede4eed4
KR
35static bfd_reloc_status_type ppc_elf_std_reloc
36 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
37
dd82c578 38static bfd_vma ppc_elf_addr16_ha_inner PARAMS ((bfd_vma));
bcbe2c71
MM
39static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
40 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
ede4eed4 41static bfd_vma ppc_elf_got16_inner PARAMS ((asection *sec));
bcbe2c71
MM
42static bfd_reloc_status_type ppc_elf_got16_reloc
43 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
ede4eed4 44static reloc_howto_type *ppc_elf_reloc_type_lookup
bcbe2c71 45 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
ede4eed4 46static void ppc_elf_info_to_howto
bcbe2c71 47 PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
ede4eed4
KR
48static void ppc_elf_howto_init PARAMS ((void));
49static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword));
50static boolean ppc_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
51static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
52
53static boolean ppc_elf_relocate_section PARAMS ((bfd *,
54 struct bfd_link_info *info,
55 bfd *,
56 asection *,
57 bfd_byte *,
58 Elf_Internal_Rela *relocs,
59 Elf_Internal_Sym *local_syms,
60 asection **));
bcbe2c71
MM
61
62#define USE_RELA
63
64enum reloc_type
65{
66 R_PPC_NONE = 0, /* 0 */
67 R_PPC_ADDR32, /* 1 */
68 R_PPC_ADDR24, /* 2 */
69 R_PPC_ADDR16, /* 3 */
70 R_PPC_ADDR16_LO, /* 4 */
71 R_PPC_ADDR16_HI, /* 5 */
72 R_PPC_ADDR16_HA, /* 6 */
73 R_PPC_ADDR14, /* 7 */
74 R_PPC_ADDR14_BRTAKEN, /* 8 */
75 R_PPC_ADDR14_BRNTAKEN, /* 9 */
76 R_PPC_REL24, /* 10 */
77 R_PPC_REL14, /* 11 */
78 R_PPC_REL14_BRTAKEN, /* 12 */
79 R_PPC_REL14_BRNTAKEN, /* 13 */
80 R_PPC_GOT16, /* 14 */
81 R_PPC_GOT16_LO, /* 15 */
82 R_PPC_GOT16_HI, /* 16 */
83 R_PPC_GOT16_HA, /* 17 */
02f85cda 84 R_PPC_PLTREL24, /* 18 */
bcbe2c71 85 R_PPC_COPY, /* 19 */
02f85cda 86 R_PPC_GLOB_DAT, /* 20 */
bcbe2c71
MM
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 */
92 R_PPC_REL32, /* 26 */
93 R_PPC_PLT32, /* 27 */
94 R_PPC_PLTREL32, /* 28 */
95 R_PPC_PLT16_LO, /* 29 */
96 R_PPC_PLT16_HI, /* 30 */
97 R_PPC_PLT16_HA, /* 31 */
02f85cda 98 R_PPC_SDAREL16, /* 32 */
bcbe2c71
MM
99
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 */
105
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 */
124 R_PPC_max
125};
126
ede4eed4
KR
127\f
128static reloc_howto_type *ppc_elf_howto_table[ (int)R_PPC_max ];
129
130static reloc_howto_type ppc_elf_howto_raw[] =
bcbe2c71
MM
131{
132 /* This reloc does nothing. */
133 HOWTO (R_PPC_NONE, /* type */
134 0, /* rightshift */
135 2, /* size (0 = byte, 1 = short, 2 = long) */
136 32, /* bitsize */
137 false, /* pc_relative */
138 0, /* bitpos */
139 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 140 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
141 "R_PPC_NONE", /* name */
142 false, /* partial_inplace */
143 0, /* src_mask */
144 0, /* dst_mask */
145 false), /* pcrel_offset */
146
147 /* A standard 32 bit relocation. */
148 HOWTO (R_PPC_ADDR32, /* type */
149 0, /* rightshift */
150 2, /* size (0 = byte, 1 = short, 2 = long) */
151 32, /* bitsize */
152 false, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 155 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
156 "R_PPC_ADDR32", /* name */
157 false, /* partial_inplace */
158 0, /* src_mask */
159 0xffffffff, /* dst_mask */
160 false), /* pcrel_offset */
161
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 */
165 0, /* rightshift */
166 2, /* size (0 = byte, 1 = short, 2 = long) */
167 26, /* bitsize */
168 false, /* pc_relative */
169 0, /* bitpos */
170 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 171 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
172 "R_PPC_ADDR24", /* name */
173 false, /* partial_inplace */
174 0, /* src_mask */
175 0x3fffffc, /* dst_mask */
176 false), /* pcrel_offset */
177
178 /* A standard 16 bit relocation. */
179 HOWTO (R_PPC_ADDR16, /* type */
180 0, /* rightshift */
181 1, /* size (0 = byte, 1 = short, 2 = long) */
182 16, /* bitsize */
183 false, /* pc_relative */
184 0, /* bitpos */
185 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 186 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
187 "R_PPC_ADDR16", /* name */
188 false, /* partial_inplace */
189 0, /* src_mask */
190 0xffff, /* dst_mask */
191 false), /* pcrel_offset */
192
193 /* A 16 bit relocation without overflow. */
194 HOWTO (R_PPC_ADDR16_LO, /* type */
195 0, /* rightshift */
196 1, /* size (0 = byte, 1 = short, 2 = long) */
197 16, /* bitsize */
198 false, /* pc_relative */
199 0, /* bitpos */
200 complain_overflow_dont,/* complain_on_overflow */
ede4eed4 201 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
202 "R_PPC_ADDR16_LO", /* name */
203 false, /* partial_inplace */
204 0, /* src_mask */
205 0xffff, /* dst_mask */
206 false), /* pcrel_offset */
207
208 /* The high order 16 bits of an address. */
209 HOWTO (R_PPC_ADDR16_HI, /* type */
210 16, /* rightshift */
211 1, /* size (0 = byte, 1 = short, 2 = long) */
212 16, /* bitsize */
213 false, /* pc_relative */
214 0, /* bitpos */
215 complain_overflow_dont, /* complain_on_overflow */
ede4eed4 216 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
217 "R_PPC_ADDR16_HI", /* name */
218 false, /* partial_inplace */
219 0, /* src_mask */
220 0xffff, /* dst_mask */
221 false), /* pcrel_offset */
222
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 */
226 16, /* rightshift */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
228 16, /* bitsize */
229 false, /* pc_relative */
230 0, /* bitpos */
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 */
235 0, /* src_mask */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
238
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 */
242 0, /* rightshift */
cc47d19a 243 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71
MM
244 16, /* bitsize */
245 false, /* pc_relative */
246 0, /* bitpos */
247 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 248 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
249 "R_PPC_ADDR14", /* name */
250 false, /* partial_inplace */
251 0, /* src_mask */
252 0xfffc, /* dst_mask */
253 false), /* pcrel_offset */
254
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 */
259 0, /* rightshift */
cc47d19a 260 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71
MM
261 16, /* bitsize */
262 false, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_bitfield, /* complain_on_overflow */
265 ppc_elf_unsupported_reloc, /* special_function */
266 "R_PPC_ADDR14_BRTAKEN",/* name */
267 false, /* partial_inplace */
268 0, /* src_mask */
269 0xfffc, /* dst_mask */
270 false), /* pcrel_offset */
271
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 */
276 0, /* rightshift */
cc47d19a 277 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71
MM
278 16, /* bitsize */
279 false, /* pc_relative */
280 0, /* bitpos */
281 complain_overflow_bitfield, /* complain_on_overflow */
282 ppc_elf_unsupported_reloc, /* special_function */
283 "R_PPC_ADDR14_BRNTAKEN",/* name */
284 false, /* partial_inplace */
285 0, /* src_mask */
286 0xfffc, /* dst_mask */
287 false), /* pcrel_offset */
288
289 /* A relative 26 bit branch; the lower two bits must be zero. */
290 HOWTO (R_PPC_REL24, /* type */
291 0, /* rightshift */
292 2, /* size (0 = byte, 1 = short, 2 = long) */
293 26, /* bitsize */
294 true, /* pc_relative */
295 0, /* bitpos */
296 complain_overflow_signed, /* complain_on_overflow */
ede4eed4 297 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
298 "R_PPC_REL24", /* name */
299 false, /* partial_inplace */
300 0, /* src_mask */
301 0x3fffffc, /* dst_mask */
302 true), /* pcrel_offset */
303
304 /* A relative 16 bit branch; the lower two bits must be zero. */
305 HOWTO (R_PPC_REL14, /* type */
306 0, /* rightshift */
cc47d19a 307 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71
MM
308 16, /* bitsize */
309 true, /* pc_relative */
310 0, /* bitpos */
311 complain_overflow_signed, /* complain_on_overflow */
ede4eed4 312 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
313 "R_PPC_REL14", /* name */
314 false, /* partial_inplace */
315 0, /* src_mask */
316 0xfffc, /* dst_mask */
317 true), /* pcrel_offset */
318
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
321 zero. */
322 HOWTO (R_PPC_REL14_BRTAKEN, /* type */
323 0, /* rightshift */
cc47d19a 324 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71 325 16, /* bitsize */
02f85cda 326 true, /* pc_relative */
bcbe2c71
MM
327 0, /* bitpos */
328 complain_overflow_signed, /* complain_on_overflow */
02f85cda 329 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
330 "R_PPC_REL14_BRTAKEN", /* name */
331 false, /* partial_inplace */
332 0, /* src_mask */
333 0xfffc, /* dst_mask */
334 true), /* pcrel_offset */
335
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
338 be zero. */
339 HOWTO (R_PPC_REL14_BRNTAKEN, /* type */
340 0, /* rightshift */
cc47d19a 341 2, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71 342 16, /* bitsize */
02f85cda 343 true, /* pc_relative */
bcbe2c71
MM
344 0, /* bitpos */
345 complain_overflow_signed, /* complain_on_overflow */
02f85cda 346 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
347 "R_PPC_REL14_BRNTAKEN",/* name */
348 false, /* partial_inplace */
349 0, /* src_mask */
350 0xfffc, /* dst_mask */
351 true), /* pcrel_offset */
352
353 /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
354 symbol. */
355 HOWTO (R_PPC_GOT16, /* type */
356 0, /* rightshift */
357 1, /* size (0 = byte, 1 = short, 2 = long) */
358 16, /* bitsize */
359 false, /* pc_relative */
360 0, /* bitpos */
ede4eed4 361 complain_overflow_signed, /* complain_on_overflow */
bcbe2c71
MM
362 ppc_elf_got16_reloc, /* special_function */
363 "R_PPC_GOT16", /* name */
364 false, /* partial_inplace */
365 0, /* src_mask */
366 0xffff, /* dst_mask */
367 false), /* pcrel_offset */
368
369 /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
370 the symbol. */
371 HOWTO (R_PPC_GOT16_LO, /* type */
372 0, /* rightshift */
373 1, /* size (0 = byte, 1 = short, 2 = long) */
374 16, /* bitsize */
375 false, /* pc_relative */
376 0, /* bitpos */
377 complain_overflow_bitfield, /* complain_on_overflow */
378 ppc_elf_got16_reloc, /* special_function */
379 "R_PPC_GOT16_LO", /* name */
380 false, /* partial_inplace */
381 0, /* src_mask */
382 0xffff, /* dst_mask */
383 false), /* pcrel_offset */
384
385 /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
386 the symbol. */
387 HOWTO (R_PPC_GOT16_HI, /* type */
388 16, /* rightshift */
389 1, /* size (0 = byte, 1 = short, 2 = long) */
390 16, /* bitsize */
391 false, /* pc_relative */
392 0, /* bitpos */
393 complain_overflow_bitfield, /* complain_on_overflow */
394 ppc_elf_got16_reloc, /* special_function */
395 "R_PPC_GOT16_HI", /* name */
396 false, /* partial_inplace */
397 0, /* src_mask */
398 0xffff, /* dst_mask */
399 false), /* pcrel_offset */
400
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 */
404 0, /* rightshift */
405 1, /* size (0 = byte, 1 = short, 2 = long) */
406 16, /* bitsize */
407 false, /* pc_relative */
408 0, /* bitpos */
409 complain_overflow_bitfield, /* complain_on_overflow */
410 ppc_elf_unsupported_reloc, /* special_function */
411 "R_PPC_GOT16_HA", /* name */
412 false, /* partial_inplace */
413 0, /* src_mask */
414 0xffff, /* dst_mask */
415 false), /* pcrel_offset */
416
417 /* Like R_PPC_REL24, but referring to the procedure linkage table
418 entry for the symbol. FIXME: Not supported. */
02f85cda 419 HOWTO (R_PPC_PLTREL24, /* type */
bcbe2c71
MM
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 26, /* bitsize */
423 true, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_signed, /* complain_on_overflow */
ede4eed4 426 ppc_elf_std_reloc, /* special_function */
02f85cda 427 "R_PPC_PLTREL24", /* name */
bcbe2c71
MM
428 false, /* partial_inplace */
429 0, /* src_mask */
430 0x3fffffc, /* dst_mask */
431 true), /* pcrel_offset */
432
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
437 of this is. */
438 HOWTO (R_PPC_COPY, /* type */
439 0, /* rightshift */
440 2, /* size (0 = byte, 1 = short, 2 = long) */
441 32, /* bitsize */
442 false, /* pc_relative */
443 0, /* bitpos */
444 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 445 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
446 "R_PPC_COPY", /* name */
447 false, /* partial_inplace */
448 0, /* src_mask */
449 0, /* dst_mask */
450 false), /* pcrel_offset */
451
452 /* Like R_PPC_ADDR32, but used when setting global offset table
453 entries. */
454 HOWTO (R_PPC_GLOB_DAT, /* type */
455 0, /* rightshift */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
457 32, /* bitsize */
458 false, /* pc_relative */
459 0, /* bitpos */
460 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 461 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
462 "R_PPC_GLOB_DAT", /* name */
463 false, /* partial_inplace */
464 0, /* src_mask */
465 0xffffffff, /* dst_mask */
466 false), /* pcrel_offset */
467
468 /* Marks a procedure linkage table entry for a symbol. */
469 HOWTO (R_PPC_JMP_SLOT, /* type */
470 0, /* rightshift */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
472 32, /* bitsize */
473 false, /* pc_relative */
474 0, /* bitpos */
475 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 476 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
477 "R_PPC_JMP_SLOT", /* name */
478 false, /* partial_inplace */
479 0, /* src_mask */
480 0, /* dst_mask */
481 false), /* pcrel_offset */
482
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
485 addend. */
486 HOWTO (R_PPC_RELATIVE, /* type */
487 0, /* rightshift */
488 2, /* size (0 = byte, 1 = short, 2 = long) */
489 32, /* bitsize */
490 false, /* pc_relative */
491 0, /* bitpos */
492 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 493 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
494 "R_PPC_RELATIVE", /* name */
495 false, /* partial_inplace */
496 0, /* src_mask */
497 0xffffffff, /* dst_mask */
498 false), /* pcrel_offset */
499
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 */
504 0, /* rightshift */
505 2, /* size (0 = byte, 1 = short, 2 = long) */
506 26, /* bitsize */
507 true, /* pc_relative */
508 0, /* bitpos */
509 complain_overflow_signed, /* complain_on_overflow */
510 ppc_elf_unsupported_reloc, /* special_function */
511 "R_PPC_LOCAL24PC", /* name */
512 false, /* partial_inplace */
513 0, /* src_mask */
514 0x3fffffc, /* dst_mask */
515 true), /* pcrel_offset */
516
517 /* Like R_PPC_ADDR32, but may be unaligned. */
518 HOWTO (R_PPC_UADDR32, /* type */
519 0, /* rightshift */
520 2, /* size (0 = byte, 1 = short, 2 = long) */
521 32, /* bitsize */
522 false, /* pc_relative */
523 0, /* bitpos */
524 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 525 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
526 "R_PPC_UADDR32", /* name */
527 false, /* partial_inplace */
528 0, /* src_mask */
529 0xffffffff, /* dst_mask */
530 false), /* pcrel_offset */
531
532 /* Like R_PPC_ADDR16, but may be unaligned. */
533 HOWTO (R_PPC_UADDR16, /* type */
534 0, /* rightshift */
535 1, /* size (0 = byte, 1 = short, 2 = long) */
536 16, /* bitsize */
537 false, /* pc_relative */
538 0, /* bitpos */
539 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 540 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
541 "R_PPC_UADDR16", /* name */
542 false, /* partial_inplace */
543 0, /* src_mask */
544 0xffff, /* dst_mask */
545 false), /* pcrel_offset */
546
547 /* 32-bit PC relative */
548 HOWTO (R_PPC_REL32, /* type */
549 0, /* rightshift */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
551 32, /* bitsize */
552 true, /* pc_relative */
553 0, /* bitpos */
554 complain_overflow_bitfield, /* complain_on_overflow */
ede4eed4 555 ppc_elf_std_reloc, /* special_function */
bcbe2c71
MM
556 "R_PPC_REL32", /* name */
557 false, /* partial_inplace */
558 0, /* src_mask */
559 0xffffffff, /* dst_mask */
560 true), /* pcrel_offset */
561
562 /* 32-bit relocation to the symbol's procedure linkage table.
563 FIXEME: not supported. */
564 HOWTO (R_PPC_PLT32, /* type */
565 0, /* rightshift */
566 2, /* size (0 = byte, 1 = short, 2 = long) */
567 32, /* bitsize */
568 false, /* pc_relative */
569 0, /* bitpos */
570 complain_overflow_bitfield, /* complain_on_overflow */
571 ppc_elf_unsupported_reloc, /* special_function */
572 "R_PPC_PLT32", /* name */
573 false, /* partial_inplace */
574 0, /* src_mask */
575 0, /* dst_mask */
576 false), /* pcrel_offset */
577
578 /* 32-bit PC relative relocation to the symbol's procedure linkage table.
579 FIXEME: not supported. */
580 HOWTO (R_PPC_PLTREL32, /* type */
581 0, /* rightshift */
582 2, /* size (0 = byte, 1 = short, 2 = long) */
583 32, /* bitsize */
584 true, /* pc_relative */
585 0, /* bitpos */
586 complain_overflow_bitfield, /* complain_on_overflow */
587 ppc_elf_unsupported_reloc, /* special_function */
588 "R_PPC_PLTREL32", /* name */
589 false, /* partial_inplace */
590 0, /* src_mask */
591 0, /* dst_mask */
592 true), /* pcrel_offset */
593
594 /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
595 the symbol. */
596 HOWTO (R_PPC_PLT16_LO, /* type */
597 0, /* rightshift */
598 1, /* size (0 = byte, 1 = short, 2 = long) */
599 16, /* bitsize */
600 false, /* pc_relative */
601 0, /* bitpos */
602 complain_overflow_bitfield, /* complain_on_overflow */
603 ppc_elf_unsupported_reloc, /* special_function */
604 "R_PPC_PLT16_LO", /* name */
605 false, /* partial_inplace */
606 0, /* src_mask */
607 0xffff, /* dst_mask */
608 false), /* pcrel_offset */
609
610 /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
611 the symbol. */
612 HOWTO (R_PPC_PLT16_HI, /* type */
613 16, /* rightshift */
614 1, /* size (0 = byte, 1 = short, 2 = long) */
615 16, /* bitsize */
616 false, /* pc_relative */
617 0, /* bitpos */
618 complain_overflow_bitfield, /* complain_on_overflow */
619 ppc_elf_unsupported_reloc, /* special_function */
620 "R_PPC_PLT16_HI", /* name */
621 false, /* partial_inplace */
622 0, /* src_mask */
623 0xffff, /* dst_mask */
624 false), /* pcrel_offset */
625
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 */
629 0, /* rightshift */
630 1, /* size (0 = byte, 1 = short, 2 = long) */
631 16, /* bitsize */
632 false, /* pc_relative */
633 0, /* bitpos */
634 complain_overflow_bitfield, /* complain_on_overflow */
635 ppc_elf_unsupported_reloc, /* special_function */
636 "R_PPC_PLT16_HA", /* name */
637 false, /* partial_inplace */
638 0, /* src_mask */
639 0xffff, /* dst_mask */
640 false), /* pcrel_offset */
641
642 /* A sign-extended 16 bit value relative to _SDA_BASE, for use with
643 small data items. */
02f85cda 644 HOWTO (R_PPC_SDAREL16, /* type */
bcbe2c71 645 0, /* rightshift */
dd82c578 646 1, /* size (0 = byte, 1 = short, 2 = long) */
bcbe2c71
MM
647 16, /* bitsize */
648 false, /* pc_relative */
649 0, /* bitpos */
dd82c578
MM
650 complain_overflow_signed, /* complain_on_overflow */
651 ppc_elf_got16_reloc, /* special_function */
02f85cda 652 "R_PPC_SDAREL16", /* name */
bcbe2c71
MM
653 false, /* partial_inplace */
654 0, /* src_mask */
dd82c578 655 0xffff, /* dst_mask */
bcbe2c71
MM
656 false), /* pcrel_offset */
657
658 /* These next 4 relocations were added by Sun. */
659 /* 32-bit section relative relocation. FIXME: not supported. */
660 HOWTO (R_PPC_SECTOFF, /* type */
661 0, /* rightshift */
662 2, /* size (0 = byte, 1 = short, 2 = long) */
663 32, /* bitsize */
664 true, /* pc_relative */
665 0, /* bitpos */
666 complain_overflow_bitfield, /* complain_on_overflow */
667 ppc_elf_unsupported_reloc, /* special_function */
668 "R_PPC_SECTOFF", /* name */
669 false, /* partial_inplace */
670 0, /* src_mask */
671 0, /* dst_mask */
672 true), /* pcrel_offset */
673
674 /* 16-bit lower half section relative relocation. FIXME: not supported. */
675 HOWTO (R_PPC_SECTOFF_LO, /* type */
676 0, /* rightshift */
677 1, /* size (0 = byte, 1 = short, 2 = long) */
678 16, /* bitsize */
679 false, /* pc_relative */
680 0, /* bitpos */
681 complain_overflow_bitfield, /* complain_on_overflow */
682 ppc_elf_unsupported_reloc, /* special_function */
683 "R_PPC_SECTOFF_LO", /* name */
684 false, /* partial_inplace */
685 0, /* src_mask */
686 0xffff, /* dst_mask */
687 false), /* pcrel_offset */
688
689 /* 16-bit upper half section relative relocation. FIXME: not supported. */
690 HOWTO (R_PPC_SECTOFF_HI, /* type */
691 16, /* rightshift */
692 1, /* size (0 = byte, 1 = short, 2 = long) */
693 16, /* bitsize */
694 false, /* pc_relative */
695 0, /* bitpos */
696 complain_overflow_bitfield, /* complain_on_overflow */
697 ppc_elf_unsupported_reloc, /* special_function */
698 "R_PPC_SECTOFF_HI", /* name */
699 false, /* partial_inplace */
700 0, /* src_mask */
701 0xffff, /* dst_mask */
702 false), /* pcrel_offset */
703
704 /* 16-bit upper half adjusted section relative relocation. FIXME: not supported. */
705 HOWTO (R_PPC_SECTOFF_HA, /* type */
706 0, /* rightshift */
707 1, /* size (0 = byte, 1 = short, 2 = long) */
708 16, /* bitsize */
709 false, /* pc_relative */
710 0, /* bitpos */
711 complain_overflow_bitfield, /* complain_on_overflow */
712 ppc_elf_unsupported_reloc, /* special_function */
713 "R_PPC_SECTOFF_HA", /* name */
714 false, /* partial_inplace */
715 0, /* src_mask */
716 0xffff, /* dst_mask */
717 false), /* pcrel_offset */
718
719 /* The remaining relocs are from the Embedded ELF ABI, and are not
720 in the SVR4 ELF ABI. */
721
722 /* 32 bit value resulting from the addend minus the symbol */
723 HOWTO (R_PPC_EMB_NADDR32, /* type */
724 0, /* rightshift */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
726 32, /* bitsize */
727 false, /* pc_relative */
728 0, /* bitpos */
729 complain_overflow_bitfield, /* complain_on_overflow */
730 ppc_elf_unsupported_reloc, /* special_function */
731 "R_PPC_EMB_NADDR32", /* name */
732 false, /* partial_inplace */
733 0, /* src_mask */
734 0xffffffff, /* dst_mask */
735 false), /* pcrel_offset */
736
737 /* 16 bit value resulting from the addend minus the symbol */
738 HOWTO (R_PPC_EMB_NADDR16, /* type */
739 0, /* rightshift */
740 1, /* size (0 = byte, 1 = short, 2 = long) */
741 16, /* bitsize */
742 false, /* pc_relative */
743 0, /* bitpos */
744 complain_overflow_bitfield, /* complain_on_overflow */
745 ppc_elf_unsupported_reloc, /* special_function */
746 "R_PPC_EMB_NADDR16", /* name */
747 false, /* partial_inplace */
748 0, /* src_mask */
749 0xffff, /* dst_mask */
750 false), /* pcrel_offset */
751
752 /* 16 bit value resulting from the addend minus the symbol */
753 HOWTO (R_PPC_EMB_NADDR16_LO, /* type */
754 0, /* rightshift */
755 1, /* size (0 = byte, 1 = short, 2 = long) */
756 16, /* bitsize */
757 false, /* pc_relative */
758 0, /* bitpos */
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 */
763 0, /* src_mask */
764 0xffff, /* dst_mask */
765 false), /* pcrel_offset */
766
767 /* The high order 16 bits of the addend minus the symbol */
768 HOWTO (R_PPC_EMB_NADDR16_HI, /* type */
769 16, /* rightshift */
770 1, /* size (0 = byte, 1 = short, 2 = long) */
771 16, /* bitsize */
772 false, /* pc_relative */
773 0, /* bitpos */
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 */
778 0, /* src_mask */
779 0xffff, /* dst_mask */
780 false), /* pcrel_offset */
781
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,
784 is negative. */
785 HOWTO (R_PPC_EMB_NADDR16_HA, /* type */
786 16, /* rightshift */
787 1, /* size (0 = byte, 1 = short, 2 = long) */
788 16, /* bitsize */
789 false, /* pc_relative */
790 0, /* bitpos */
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 */
795 0, /* src_mask */
796 0xffff, /* dst_mask */
797 false), /* pcrel_offset */
798};
799
ede4eed4
KR
800\f
801/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
802
803static void
804ppc_elf_howto_init ()
805{
806 unsigned int i, type;
807
808 for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++)
809 {
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];
813 }
814}
815
816\f
817static reloc_howto_type *
818ppc_elf_reloc_type_lookup (abfd, code)
819 bfd *abfd;
820 bfd_reloc_code_real_type code;
821{
02f85cda
MM
822 enum reloc_type ppc_reloc = R_PPC_NONE;
823
ede4eed4
KR
824 if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */
825 ppc_elf_howto_init ();
826
827 switch ((int)code)
828 {
02f85cda
MM
829 default:
830 return (reloc_howto_type *)NULL;
831
832 case BFD_RELOC_NONE: ppc_reloc = R_PPC_NONE; break;
833 case BFD_RELOC_32: ppc_reloc = R_PPC_ADDR32; break;
834 case BFD_RELOC_PPC_BA26: ppc_reloc = R_PPC_ADDR24; break;
835 case BFD_RELOC_16: ppc_reloc = R_PPC_ADDR16; break;
836 case BFD_RELOC_LO16: ppc_reloc = R_PPC_ADDR16_LO; break;
837 case BFD_RELOC_HI16: ppc_reloc = R_PPC_ADDR16_HI; break;
838 case BFD_RELOC_HI16_S: ppc_reloc = R_PPC_ADDR16_HA; break;
839 case BFD_RELOC_PPC_BA16: ppc_reloc = R_PPC_ADDR14; break;
840 case BFD_RELOC_PPC_BA16_BRTAKEN: ppc_reloc = R_PPC_ADDR14_BRTAKEN; break;
841 case BFD_RELOC_PPC_BA16_BRNTAKEN: ppc_reloc = R_PPC_ADDR14_BRNTAKEN; break;
842 case BFD_RELOC_PPC_B26: ppc_reloc = R_PPC_REL24; break;
843 case BFD_RELOC_PPC_B16: ppc_reloc = R_PPC_REL14; break;
844 case BFD_RELOC_PPC_B16_BRTAKEN: ppc_reloc = R_PPC_REL14_BRTAKEN; break;
845 case BFD_RELOC_PPC_B16_BRNTAKEN: ppc_reloc = R_PPC_REL14_BRNTAKEN; break;
846 case BFD_RELOC_PPC_TOC16: ppc_reloc = R_PPC_GOT16; break;
847 case BFD_RELOC_LO16_GOTOFF: ppc_reloc = R_PPC_GOT16_LO; break;
848 case BFD_RELOC_HI16_GOTOFF: ppc_reloc = R_PPC_GOT16_HI; break;
849 case BFD_RELOC_HI16_S_GOTOFF: ppc_reloc = R_PPC_GOT16_HA; break;
850 case BFD_RELOC_24_PLT_PCREL: ppc_reloc = R_PPC_PLTREL24; break;
851 case BFD_RELOC_PPC_COPY: ppc_reloc = R_PPC_COPY; break;
852 case BFD_RELOC_PPC_GLOB_DAT: ppc_reloc = R_PPC_GLOB_DAT; break;
853 case BFD_RELOC_PPC_LOCAL24PC: ppc_reloc = R_PPC_LOCAL24PC; break;
854 case BFD_RELOC_32_PCREL: ppc_reloc = R_PPC_REL32; break;
855 case BFD_RELOC_32_PLTOFF: ppc_reloc = R_PPC_PLT32; break;
856 case BFD_RELOC_32_PLT_PCREL: ppc_reloc = R_PPC_PLTREL32; break;
857 case BFD_RELOC_LO16_PLTOFF: ppc_reloc = R_PPC_PLT16_LO; break;
858 case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break;
859 case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break;
860 case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break;
861 case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break;
862 case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break;
863 case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break;
864 case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break;
865 case BFD_RELOC_CTOR: ppc_reloc = R_PPC_ADDR32; break;
ede4eed4
KR
866 }
867
02f85cda 868 return ppc_elf_howto_table[ (int)ppc_reloc ];
ede4eed4
KR
869};
870
871/* Set the howto pointer for a PowerPC ELF reloc. */
872
873static void
874ppc_elf_info_to_howto (abfd, cache_ptr, dst)
875 bfd *abfd;
876 arelent *cache_ptr;
877 Elf32_Internal_Rela *dst;
878{
879 if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */
880 ppc_elf_howto_init ();
881
882 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
883 cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
884}
885
886/* Function to set whether a module needs the -mrelocatable bit set. */
887
888static boolean
889ppc_elf_set_private_flags (abfd, flags)
890 bfd *abfd;
891 flagword flags;
892{
893 BFD_ASSERT (!elf_ppc_flags_init (abfd)
894 || elf_elfheader (abfd)->e_flags == flags);
895
896 elf_elfheader (abfd)->e_flags = flags;
897 elf_ppc_flags_init (abfd) = true;
898 return true;
899}
900
901/* Copy backend specific data from one object module to another */
902static boolean
903ppc_elf_copy_private_bfd_data (ibfd, obfd)
904 bfd *ibfd;
905 bfd *obfd;
906{
907 /* This function is selected based on the input vector. We only
908 want to copy information over if the output BFD also uses Elf
909 format. */
910 if (bfd_get_flavour (obfd) != bfd_target_elf_flavour)
911 return true;
912
913 BFD_ASSERT (!elf_ppc_flags_init (obfd)
914 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
915
916 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
917 elf_ppc_flags_init (obfd) = true;
918 return true;
919}
920
921/* Merge backend specific data from an object file to the output
922 object file when linking */
923static boolean
924ppc_elf_merge_private_bfd_data (ibfd, obfd)
925 bfd *ibfd;
926 bfd *obfd;
927{
928 flagword old_flags;
929 flagword new_flags;
930
931 /* Check if we have the same endianess */
932 if (ibfd->xvec->byteorder_big_p != obfd->xvec->byteorder_big_p)
933 {
7a7fbffb
ILT
934 (*_bfd_error_handler)
935 ("%s: compiled for a %s endian system and target is %s endian.\n",
936 bfd_get_filename (ibfd),
937 (ibfd->xvec->byteorder_big_p) ? "big" : "little",
938 (obfd->xvec->byteorder_big_p) ? "big" : "little");
ede4eed4
KR
939
940 bfd_set_error (bfd_error_wrong_format);
941 return false;
942 }
943
944 /* This function is selected based on the input vector. We only
945 want to copy information over if the output BFD also uses Elf
946 format. */
947 if (bfd_get_flavour (obfd) != bfd_target_elf_flavour)
948 return true;
949
950 new_flags = elf_elfheader (ibfd)->e_flags;
951 old_flags = elf_elfheader (obfd)->e_flags;
952 if (!elf_ppc_flags_init (obfd)) /* First call, no flags set */
953 {
954 elf_ppc_flags_init (obfd) = true;
955 elf_elfheader (obfd)->e_flags = new_flags;
956 }
957
958 else if (new_flags == old_flags) /* Compatible flags are ok */
959 ;
960
961 else /* Incompatible flags */
962 {
dd82c578
MM
963 /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib to be linked
964 with either. */
965 if ((new_flags & EF_PPC_RELOCATABLE) != 0
966 && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0)
ede4eed4 967 {
7a7fbffb
ILT
968 (*_bfd_error_handler)
969 ("%s: compiled with -mrelocatable and linked with modules compiled normally\n",
970 bfd_get_filename (ibfd));
ede4eed4 971 }
08eb30b6 972 else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
dd82c578 973 && (old_flags & EF_PPC_RELOCATABLE) != 0)
ede4eed4 974 {
7a7fbffb
ILT
975 (*_bfd_error_handler)
976 ("%s: compiled normally and linked with modules compiled with -mrelocatable\n",
977 bfd_get_filename (ibfd));
ede4eed4 978 }
dd82c578
MM
979 else if ((new_flags & EF_PPC_RELOCATABLE_LIB) != 0)
980 elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE_LIB;
981
982 new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB);
983 old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB);
ede4eed4
KR
984
985 /* Warn about eabi vs. V.4 mismatch */
986 if ((new_flags & EF_PPC_EMB) != 0 && (old_flags & EF_PPC_EMB) == 0)
987 {
988 new_flags &= ~EF_PPC_EMB;
7a7fbffb
ILT
989 (*_bfd_error_handler)
990 ("%s: compiled for the eabi and linked with modules compiled for System V\n",
991 bfd_get_filename (ibfd));
ede4eed4
KR
992 }
993 else if ((new_flags & EF_PPC_EMB) == 0 && (old_flags & EF_PPC_EMB) != 0)
994 {
995 old_flags &= ~EF_PPC_EMB;
7a7fbffb
ILT
996 (*_bfd_error_handler)
997 ("%s: compiled for System V and linked with modules compiled for eabi\n",
998 bfd_get_filename (ibfd));
ede4eed4
KR
999 }
1000
1001 /* Warn about any other mismatches */
1002 if (new_flags != old_flags)
7a7fbffb
ILT
1003 (*_bfd_error_handler)
1004 ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)\n",
1005 bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
ede4eed4
KR
1006
1007 bfd_set_error (bfd_error_bad_value);
1008 return false;
1009 }
1010
1011 return true;
1012}
1013
1014\f
1015/* ELF relocs are against symbols. If we are producing relocateable
1016 output, and the reloc is against an external symbol, and nothing
1017 has given us any additional addend, the resulting reloc will also
1018 be against the same symbol. In such a case, we don't want to
1019 change anything about the way the reloc is handled, since it will
1020 all be done at final link time. Rather than put special case code
1021 into bfd_perform_relocation, all the reloc types use this howto
1022 function. It just short circuits the reloc if producing
1023 relocateable output against an external symbol. */
1024
1025/*ARGSUSED*/
1026static bfd_reloc_status_type
1027ppc_elf_std_reloc (abfd,
1028 reloc_entry,
1029 symbol,
1030 data,
1031 input_section,
1032 output_bfd,
1033 error_message)
1034 bfd *abfd;
1035 arelent *reloc_entry;
1036 asymbol *symbol;
1037 PTR data;
1038 asection *input_section;
1039 bfd *output_bfd;
1040 char **error_message;
1041{
1042 if (output_bfd != (bfd *) NULL
1043 && (symbol->flags & BSF_SECTION_SYM) == 0
1044 && (! reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
1045 {
1046 reloc_entry->address += input_section->output_offset;
1047 return bfd_reloc_ok;
1048 }
1049
1050 return bfd_reloc_continue;
1051}
1052
bcbe2c71
MM
1053/* Don't pretend we can deal with unsupported relocs. */
1054
1055/*ARGSUSED*/
1056static bfd_reloc_status_type
1057ppc_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
1058 output_bfd, error_message)
1059 bfd *abfd;
1060 arelent *reloc_entry;
1061 asymbol *symbol;
1062 PTR data;
1063 asection *input_section;
1064 bfd *output_bfd;
1065 char **error_message;
1066{
ede4eed4 1067 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
7a7fbffb
ILT
1068 (*_bfd_error_handler)
1069 ("%s: Relocation %s (%d) is not currently supported.\n",
1070 bfd_get_filename (abfd),
1071 reloc_entry->howto->name,
1072 reloc_entry->howto->type);
ede4eed4
KR
1073
1074 return bfd_reloc_notsupported;
1075}
1076
1077/* Internal function to return the adjustment to the addend for relocations
1078 that return the upper 16 bits after sign extending the lower 16 bits, ie
dd82c578 1079 for use with a ADDIS instruction followed by a memory reference using the
ede4eed4
KR
1080 bottom 16 bits. */
1081
1082INLINE
1083static bfd_vma
dd82c578
MM
1084ppc_elf_addr16_ha_inner (relocation)
1085 bfd_vma relocation;
ede4eed4 1086{
ede4eed4 1087 return (relocation & 0x8000) << 1;
bcbe2c71
MM
1088}
1089
1090/* Handle the ADDR16_HA reloc by adjusting the reloc addend. */
1091
ede4eed4 1092/*ARGSUSED*/
bcbe2c71
MM
1093static bfd_reloc_status_type
1094ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
1095 output_bfd, error_message)
1096 bfd *abfd;
1097 arelent *reloc_entry;
1098 asymbol *symbol;
1099 PTR data;
1100 asection *input_section;
1101 bfd *output_bfd;
1102 char **error_message;
1103{
dd82c578
MM
1104 bfd_vma relocation;
1105 asection *sec;
1106
bcbe2c71 1107 if (output_bfd != (bfd *) NULL)
ede4eed4
KR
1108 return ppc_elf_std_reloc (abfd, reloc_entry, symbol, data,
1109 input_section, output_bfd, error_message);
bcbe2c71 1110
dd82c578
MM
1111 sec = symbol->section;
1112 relocation = (((bfd_is_com_section (sec)) ? 0 : symbol->value)
1113 + sec->output_section->vma
1114 + sec->output_offset
1115 + reloc_entry->addend);
1116
1117 reloc_entry->addend += ppc_elf_addr16_ha_inner (relocation);
ede4eed4
KR
1118 return bfd_reloc_continue;
1119}
bcbe2c71 1120
ede4eed4
KR
1121/* Internal function to return the addjustment to the addend for GOT16
1122 entries */
bcbe2c71 1123
ede4eed4
KR
1124INLINE
1125static bfd_vma
1126ppc_elf_got16_inner (sec)
1127 asection *sec;
1128{
1129 BFD_ASSERT (bfd_is_und_section (sec)
1130 || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
dd82c578
MM
1131 || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0
1132 || strcmp (bfd_get_section_name (abfd, sec), ".sdata") == 0
1133 || strcmp (bfd_get_section_name (abfd, sec), ".sbss") == 0)
bcbe2c71 1134
ede4eed4 1135 return -(sec->output_section->vma + 0x8000);
bcbe2c71
MM
1136}
1137
1138/* Handle the GOT16 reloc. We want to use the offset within the .got
1139 section, not the actual VMA. This is appropriate when generating
1140 an embedded ELF object, for which the .got section acts like the
1141 AIX .toc section. When and if we support PIC code, we will have to
1142 change this, perhaps by switching off on the e_type field. */
1143
ede4eed4 1144/*ARGSUSED*/
bcbe2c71
MM
1145static bfd_reloc_status_type
1146ppc_elf_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1147 output_bfd, error_message)
1148 bfd *abfd;
1149 arelent *reloc_entry;
1150 asymbol *symbol;
1151 PTR data;
1152 asection *input_section;
1153 bfd *output_bfd;
1154 char **error_message;
1155{
bcbe2c71 1156 if (output_bfd != (bfd *) NULL)
ede4eed4
KR
1157 return ppc_elf_std_reloc (abfd, reloc_entry, symbol, data,
1158 input_section, output_bfd, error_message);
bcbe2c71 1159
ede4eed4 1160 reloc_entry->addend += ppc_elf_got16_inner (bfd_get_section (*reloc_entry->sym_ptr_ptr));
bcbe2c71
MM
1161 return bfd_reloc_continue;
1162}
1163
ede4eed4
KR
1164\f
1165/* The RELOCATE_SECTION function is called by the ELF backend linker
1166 to handle the relocations for a section.
bcbe2c71 1167
ede4eed4
KR
1168 The relocs are always passed as Rela structures; if the section
1169 actually uses Rel structures, the r_addend field will always be
1170 zero.
bcbe2c71 1171
ede4eed4
KR
1172 This function is responsible for adjust the section contents as
1173 necessary, and (if using Rela relocs and generating a
1174 relocateable output file) adjusting the reloc addend as
1175 necessary.
bcbe2c71 1176
ede4eed4
KR
1177 This function does not have to worry about setting the reloc
1178 address or the reloc symbol index.
1179
1180 LOCAL_SYMS is a pointer to the swapped in local symbols.
1181
1182 LOCAL_SECTIONS is an array giving the section in the input file
1183 corresponding to the st_shndx field of each local symbol.
1184
1185 The global hash table entry for the global symbols can be found
1186 via elf_sym_hashes (input_bfd).
1187
1188 When generating relocateable output, this function must handle
1189 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1190 going to be the section symbol corresponding to the output
1191 section, which means that the addend must be adjusted
1192 accordingly. */
1193
1194static boolean
1195ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1196 contents, relocs, local_syms, local_sections)
1197 bfd *output_bfd;
1198 struct bfd_link_info *info;
1199 bfd *input_bfd;
1200 asection *input_section;
1201 bfd_byte *contents;
1202 Elf_Internal_Rela *relocs;
1203 Elf_Internal_Sym *local_syms;
1204 asection **local_sections;
bcbe2c71 1205{
ede4eed4
KR
1206 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1207 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
1208 Elf_Internal_Rela *rel = relocs;
1209 Elf_Internal_Rela *relend = relocs + input_section->reloc_count;
1210 boolean ret = true;
1211
1212#ifdef DEBUG
1213 fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
1214 bfd_get_filename (input_bfd),
1215 bfd_section_name(input_bfd, input_section),
1216 (long)input_section->reloc_count,
1217 (info->relocateable) ? " (relocatable)" : "");
1218#endif
1219
1220 if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */
1221 ppc_elf_howto_init ();
bcbe2c71 1222
ede4eed4 1223 for (; rel < relend; rel++)
bcbe2c71 1224 {
ede4eed4
KR
1225 enum reloc_type r_type = (enum reloc_type)ELF32_R_TYPE (rel->r_info);
1226 bfd_vma offset = rel->r_offset;
1227 bfd_vma addend = rel->r_addend;
1228 bfd_reloc_status_type r = bfd_reloc_other;
1229 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0;
1230 asection *sec = (asection *)0;
1231 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0;
1232 reloc_howto_type *howto;
1233 unsigned long r_symndx;
1234 bfd_vma relocation;
1235
1236 /* Unknown relocation handling */
1237 if ((unsigned)r_type >= (unsigned)R_PPC_max || !ppc_elf_howto_table[(int)r_type])
1238 {
7a7fbffb
ILT
1239 (*_bfd_error_handler)
1240 ("%s: Unknown relocation type %d\n",
1241 bfd_get_filename (input_bfd),
1242 (int)r_type);
ede4eed4
KR
1243
1244 bfd_set_error (bfd_error_bad_value);
1245 ret = false;
1246 continue;
1247 }
1248
1249 howto = ppc_elf_howto_table[(int)r_type];
1250 r_symndx = ELF32_R_SYM (rel->r_info);
1251
1252 if (info->relocateable)
1253 {
1254 /* This is a relocateable link. We don't have to change
1255 anything, unless the reloc is against a section symbol,
1256 in which case we have to adjust according to where the
1257 section symbol winds up in the output section. */
1258 if (r_symndx < symtab_hdr->sh_info)
1259 {
1260 sym = local_syms + r_symndx;
1261 if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1262 {
1263 sec = local_sections[r_symndx];
1264 addend = rel->r_addend += sec->output_offset + sym->st_value;
1265 }
1266 }
1267
1268#ifdef DEBUG
1269 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
1270 howto->name,
1271 (int)r_type,
1272 r_symndx,
1273 (long)offset,
1274 (long)addend);
1275#endif
1276 continue;
1277 }
1278
1279 /* This is a final link. */
1280
1281 /* Complain about known relocation that are not yet supported */
1282 if (howto->special_function == ppc_elf_unsupported_reloc)
1283 {
7a7fbffb
ILT
1284 (*_bfd_error_handler)
1285 ("%s: Relocation %s (%d) is not currently supported.\n",
1286 bfd_get_filename (input_bfd),
1287 howto->name,
1288 (int)r_type);
ede4eed4
KR
1289
1290 bfd_set_error (bfd_error_bad_value);
1291 ret = false;
1292 continue;
1293 }
1294
1295 if (r_symndx < symtab_hdr->sh_info)
1296 {
1297 sym = local_syms + r_symndx;
1298 sec = local_sections[r_symndx];
1299 relocation = (sec->output_section->vma
1300 + sec->output_offset
1301 + sym->st_value);
1302 }
1303 else
1304 {
1305 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1306 if (h->root.type == bfd_link_hash_defined
1307 || h->root.type == bfd_link_hash_defweak)
1308 {
1309 sec = h->root.u.def.section;
1310 relocation = (h->root.u.def.value
1311 + sec->output_section->vma
1312 + sec->output_offset);
1313 }
1314 else if (h->root.type == bfd_link_hash_undefweak)
1315 relocation = 0;
1316 else if (info->shared)
1317 relocation = 0;
1318 else
1319 {
1320 (*info->callbacks->undefined_symbol)(info,
1321 h->root.root.string,
1322 input_bfd,
1323 input_section,
1324 rel->r_offset);
1325 ret = false;
1326 continue;
1327 }
1328 }
1329
1330 switch ((int)r_type)
1331 {
1332 default:
1333 break;
1334
1335 case (int)R_PPC_GOT16: /* GOT16 relocations */
1336 case (int)R_PPC_GOT16_LO:
1337 case (int)R_PPC_GOT16_HI:
02f85cda 1338 case (int)R_PPC_SDAREL16:
ede4eed4
KR
1339 BFD_ASSERT (sec != (asection *)0);
1340 addend += ppc_elf_got16_inner (sec);
1341 break;
1342
1343 case (int)R_PPC_ADDR16_HA: /* arithmetic adjust relocations */
1344 BFD_ASSERT (sec != (asection *)0);
dd82c578 1345 addend += ppc_elf_addr16_ha_inner (relocation + addend);
ede4eed4
KR
1346 break;
1347 }
1348
1349
1350#ifdef DEBUG
1351 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
1352 howto->name,
1353 (int)r_type,
1354 r_symndx,
1355 (long)offset,
1356 (long)addend);
1357#endif
1358
1359 r = _bfd_final_link_relocate (howto,
1360 input_bfd,
1361 input_section,
1362 contents,
1363 offset,
1364 relocation,
1365 addend);
1366
1367 if (r != bfd_reloc_ok)
1368 {
1369 ret = false;
1370 switch (r)
1371 {
1372 default:
1373 break;
1374
1375 case bfd_reloc_overflow:
1376 {
1377 const char *name;
1378
1379 if (h != NULL)
1380 name = h->root.root.string;
1381 else
1382 {
1383 name = bfd_elf_string_from_elf_section (input_bfd,
1384 symtab_hdr->sh_link,
1385 sym->st_name);
1386 if (name == NULL)
1387 break;
1388
1389 if (*name == '\0')
1390 name = bfd_section_name (input_bfd, sec);
1391 }
1392
1393 (*info->callbacks->reloc_overflow)(info,
1394 name,
1395 howto->name,
1396 (bfd_vma) 0,
1397 input_bfd,
1398 input_section,
1399 offset);
1400 }
1401 break;
1402
1403 }
1404 }
bcbe2c71
MM
1405 }
1406
bcbe2c71 1407
ede4eed4
KR
1408#ifdef DEBUG
1409 fprintf (stderr, "\n");
1410#endif
bcbe2c71 1411
ede4eed4 1412 return ret;
bcbe2c71
MM
1413}
1414
ede4eed4
KR
1415#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
1416#define TARGET_LITTLE_NAME "elf32-powerpcle"
bcbe2c71
MM
1417#define TARGET_BIG_SYM bfd_elf32_powerpc_vec
1418#define TARGET_BIG_NAME "elf32-powerpc"
1419#define ELF_ARCH bfd_arch_powerpc
1420#define ELF_MACHINE_CODE EM_PPC
1421#define ELF_MAXPAGESIZE 0x10000
ede4eed4 1422#define elf_info_to_howto ppc_elf_info_to_howto
bcbe2c71
MM
1423
1424#ifdef EM_CYGNUS_POWERPC
1425#define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC
1426#endif
1427
1428#ifdef EM_PPC_OLD
1429#define ELF_MACHINE_ALT2 EM_PPC_OLD
1430#endif
1431
ede4eed4
KR
1432#define bfd_elf32_bfd_copy_private_bfd_data ppc_elf_copy_private_bfd_data
1433#define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data
1434#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
1435#define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup
1436#define elf_backend_relocate_section ppc_elf_relocate_section
1437
bcbe2c71 1438#include "elf32-target.h"
This page took 0.09898 seconds and 4 git commands to generate.