]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gold/powerpc.cc
2009-03-23 Ian Lance Taylor <iant@google.com>
[thirdparty/binutils-gdb.git] / gold / powerpc.cc
CommitLineData
42cacb20
DE
1// powerpc.cc -- powerpc target support for gold.
2
6d03d481 3// Copyright 2008, 2009 Free Software Foundation, Inc.
42cacb20
DE
4// Written by David S. Miller <davem@davemloft.net>
5// and David Edelsohn <edelsohn@gnu.org>
6
7// This file is part of gold.
8
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; either version 3 of the License, or
12// (at your option) any later version.
13
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18
19// You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22// MA 02110-1301, USA.
23
24#include "gold.h"
25
26#include "elfcpp.h"
27#include "parameters.h"
28#include "reloc.h"
29#include "powerpc.h"
30#include "object.h"
31#include "symtab.h"
32#include "layout.h"
33#include "output.h"
34#include "copy-relocs.h"
35#include "target.h"
36#include "target-reloc.h"
37#include "target-select.h"
38#include "tls.h"
39#include "errors.h"
40
41namespace
42{
43
44using namespace gold;
45
46template<int size, bool big_endian>
47class Output_data_plt_powerpc;
48
49template<int size, bool big_endian>
50class Target_powerpc : public Sized_target<size, big_endian>
51{
52 public:
53 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Reloc_section;
54
55 Target_powerpc()
56 : Sized_target<size, big_endian>(&powerpc_info),
57 got_(NULL), got2_(NULL), toc_(NULL),
58 plt_(NULL), rela_dyn_(NULL),
59 copy_relocs_(elfcpp::R_POWERPC_COPY),
60 dynbss_(NULL), got_mod_index_offset_(-1U)
61 {
62 }
63
6d03d481
ST
64 // Process the relocations to determine unreferenced sections for
65 // garbage collection.
66 void
67 gc_process_relocs(const General_options& options,
68 Symbol_table* symtab,
69 Layout* layout,
70 Sized_relobj<size, big_endian>* object,
71 unsigned int data_shndx,
72 unsigned int sh_type,
73 const unsigned char* prelocs,
74 size_t reloc_count,
75 Output_section* output_section,
76 bool needs_special_offset_handling,
77 size_t local_symbol_count,
78 const unsigned char* plocal_symbols);
79
42cacb20
DE
80 // Scan the relocations to look for symbol adjustments.
81 void
82 scan_relocs(const General_options& options,
83 Symbol_table* symtab,
84 Layout* layout,
85 Sized_relobj<size, big_endian>* object,
86 unsigned int data_shndx,
87 unsigned int sh_type,
88 const unsigned char* prelocs,
89 size_t reloc_count,
90 Output_section* output_section,
91 bool needs_special_offset_handling,
92 size_t local_symbol_count,
93 const unsigned char* plocal_symbols);
94 // Finalize the sections.
95 void
96 do_finalize_sections(Layout*);
97
98 // Return the value to use for a dynamic which requires special
99 // treatment.
100 uint64_t
101 do_dynsym_value(const Symbol*) const;
102
103 // Relocate a section.
104 void
105 relocate_section(const Relocate_info<size, big_endian>*,
106 unsigned int sh_type,
107 const unsigned char* prelocs,
108 size_t reloc_count,
109 Output_section* output_section,
110 bool needs_special_offset_handling,
111 unsigned char* view,
112 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
113 section_size_type view_size);
114
115 // Scan the relocs during a relocatable link.
116 void
117 scan_relocatable_relocs(const General_options& options,
118 Symbol_table* symtab,
119 Layout* layout,
120 Sized_relobj<size, big_endian>* object,
121 unsigned int data_shndx,
122 unsigned int sh_type,
123 const unsigned char* prelocs,
124 size_t reloc_count,
125 Output_section* output_section,
126 bool needs_special_offset_handling,
127 size_t local_symbol_count,
128 const unsigned char* plocal_symbols,
129 Relocatable_relocs*);
130
131 // Relocate a section during a relocatable link.
132 void
133 relocate_for_relocatable(const Relocate_info<size, big_endian>*,
134 unsigned int sh_type,
135 const unsigned char* prelocs,
136 size_t reloc_count,
137 Output_section* output_section,
138 off_t offset_in_output_section,
139 const Relocatable_relocs*,
140 unsigned char* view,
141 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
142 section_size_type view_size,
143 unsigned char* reloc_view,
144 section_size_type reloc_view_size);
145
146 // Return whether SYM is defined by the ABI.
147 bool
9c2d0ef9 148 do_is_defined_by_abi(const Symbol* sym) const
42cacb20
DE
149 {
150 return strcmp(sym->name(), "___tls_get_addr") == 0;
151 }
152
153 // Return the size of the GOT section.
154 section_size_type
155 got_size()
156 {
157 gold_assert(this->got_ != NULL);
158 return this->got_->data_size();
159 }
160
161 private:
162
163 // The class which scans relocations.
164 class Scan
165 {
166 public:
167 Scan()
168 : issued_non_pic_error_(false)
169 { }
170
171 inline void
172 local(const General_options& options, Symbol_table* symtab,
173 Layout* layout, Target_powerpc* target,
174 Sized_relobj<size, big_endian>* object,
175 unsigned int data_shndx,
176 Output_section* output_section,
177 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
178 const elfcpp::Sym<size, big_endian>& lsym);
179
180 inline void
181 global(const General_options& options, Symbol_table* symtab,
182 Layout* layout, Target_powerpc* target,
183 Sized_relobj<size, big_endian>* object,
184 unsigned int data_shndx,
185 Output_section* output_section,
186 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
187 Symbol* gsym);
188
189 private:
190 static void
191 unsupported_reloc_local(Sized_relobj<size, big_endian>*,
192 unsigned int r_type);
193
194 static void
195 unsupported_reloc_global(Sized_relobj<size, big_endian>*,
196 unsigned int r_type, Symbol*);
197
198 static void
199 generate_tls_call(Symbol_table* symtab, Layout* layout,
200 Target_powerpc* target);
201
202 void
203 check_non_pic(Relobj*, unsigned int r_type);
204
205 // Whether we have issued an error about a non-PIC compilation.
206 bool issued_non_pic_error_;
207 };
208
209 // The class which implements relocation.
210 class Relocate
211 {
212 public:
213 // Do a relocation. Return false if the caller should not issue
214 // any warnings about this relocation.
215 inline bool
216 relocate(const Relocate_info<size, big_endian>*, Target_powerpc*,
031cdbed
ILT
217 Output_section*, size_t relnum,
218 const elfcpp::Rela<size, big_endian>&,
42cacb20
DE
219 unsigned int r_type, const Sized_symbol<size>*,
220 const Symbol_value<size>*,
221 unsigned char*,
222 typename elfcpp::Elf_types<size>::Elf_Addr,
223 section_size_type);
224
225 private:
226 // Do a TLS relocation.
227 inline void
228 relocate_tls(const Relocate_info<size, big_endian>*,
229 Target_powerpc* target,
230 size_t relnum, const elfcpp::Rela<size, big_endian>&,
231 unsigned int r_type, const Sized_symbol<size>*,
232 const Symbol_value<size>*,
233 unsigned char*,
234 typename elfcpp::Elf_types<size>::Elf_Addr,
235 section_size_type);
236 };
237
238 // A class which returns the size required for a relocation type,
239 // used while scanning relocs during a relocatable link.
240 class Relocatable_size_for_reloc
241 {
242 public:
243 unsigned int
244 get_size_for_reloc(unsigned int, Relobj*);
245 };
246
247 // Get the GOT section, creating it if necessary.
248 Output_data_got<size, big_endian>*
249 got_section(Symbol_table*, Layout*);
250
251 Output_data_space*
252 got2_section() const
253 {
254 gold_assert (this->got2_ != NULL);
255 return this->got2_;
256 }
257
258 // Get the TOC section.
259 Output_data_space*
260 toc_section() const
261 {
262 gold_assert (this->toc_ != NULL);
263 return this->toc_;
264 }
265
266 // Create a PLT entry for a global symbol.
267 void
268 make_plt_entry(Symbol_table*, Layout*, Symbol*);
269
270 // Create a GOT entry for the TLS module index.
271 unsigned int
272 got_mod_index_entry(Symbol_table* symtab, Layout* layout,
273 Sized_relobj<size, big_endian>* object);
274
275 // Get the PLT section.
276 const Output_data_plt_powerpc<size, big_endian>*
277 plt_section() const
278 {
279 gold_assert(this->plt_ != NULL);
280 return this->plt_;
281 }
282
283 // Get the dynamic reloc section, creating it if necessary.
284 Reloc_section*
285 rela_dyn_section(Layout*);
286
287 // Return true if the symbol may need a COPY relocation.
288 // References from an executable object to non-function symbols
289 // defined in a dynamic object may need a COPY relocation.
290 bool
291 may_need_copy_reloc(Symbol* gsym)
292 {
293 return (!parameters->options().shared()
294 && gsym->is_from_dynobj()
295 && gsym->type() != elfcpp::STT_FUNC);
296 }
297
298 // Copy a relocation against a global symbol.
299 void
ef9beddf
ILT
300 copy_reloc(Symbol_table* symtab, Layout* layout,
301 Sized_relobj<size, big_endian>* object,
42cacb20
DE
302 unsigned int shndx, Output_section* output_section,
303 Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
304 {
305 this->copy_relocs_.copy_reloc(symtab, layout,
306 symtab->get_sized_symbol<size>(sym),
307 object, shndx, output_section,
308 reloc, this->rela_dyn_section(layout));
309 }
310
311 // Information about this specific target which we pass to the
312 // general Target structure.
313 static Target::Target_info powerpc_info;
314
315 // The types of GOT entries needed for this platform.
316 enum Got_type
317 {
318 GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
319 GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset
320 GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair
321 };
322
323 // The GOT section.
324 Output_data_got<size, big_endian>* got_;
325 // The GOT2 section.
326 Output_data_space* got2_;
327 // The TOC section.
328 Output_data_space* toc_;
329 // The PLT section.
330 Output_data_plt_powerpc<size, big_endian>* plt_;
331 // The dynamic reloc section.
332 Reloc_section* rela_dyn_;
333 // Relocs saved to avoid a COPY reloc.
334 Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
335 // Space for variables copied with a COPY reloc.
336 Output_data_space* dynbss_;
337 // Offset of the GOT entry for the TLS module index;
338 unsigned int got_mod_index_offset_;
339};
340
341template<>
342Target::Target_info Target_powerpc<32, true>::powerpc_info =
343{
344 32, // size
345 true, // is_big_endian
346 elfcpp::EM_PPC, // machine_code
347 false, // has_make_symbol
348 false, // has_resolve
349 false, // has_code_fill
350 true, // is_default_stack_executable
351 '\0', // wrap_char
352 "/usr/lib/ld.so.1", // dynamic_linker
353 0x10000000, // default_text_segment_address
354 64 * 1024, // abi_pagesize (overridable by -z max-page-size)
355 4 * 1024 // common_pagesize (overridable by -z common-page-size)
356};
357
358template<>
359Target::Target_info Target_powerpc<32, false>::powerpc_info =
360{
361 32, // size
362 false, // is_big_endian
363 elfcpp::EM_PPC, // machine_code
364 false, // has_make_symbol
365 false, // has_resolve
366 false, // has_code_fill
367 true, // is_default_stack_executable
368 '\0', // wrap_char
369 "/usr/lib/ld.so.1", // dynamic_linker
370 0x10000000, // default_text_segment_address
371 64 * 1024, // abi_pagesize (overridable by -z max-page-size)
372 4 * 1024 // common_pagesize (overridable by -z common-page-size)
373};
374
375template<>
376Target::Target_info Target_powerpc<64, true>::powerpc_info =
377{
378 64, // size
379 true, // is_big_endian
380 elfcpp::EM_PPC64, // machine_code
381 false, // has_make_symbol
382 false, // has_resolve
383 false, // has_code_fill
384 true, // is_default_stack_executable
385 '\0', // wrap_char
386 "/usr/lib/ld.so.1", // dynamic_linker
387 0x10000000, // default_text_segment_address
388 64 * 1024, // abi_pagesize (overridable by -z max-page-size)
389 8 * 1024 // common_pagesize (overridable by -z common-page-size)
390};
391
392template<>
393Target::Target_info Target_powerpc<64, false>::powerpc_info =
394{
395 64, // size
396 false, // is_big_endian
397 elfcpp::EM_PPC64, // machine_code
398 false, // has_make_symbol
399 false, // has_resolve
400 false, // has_code_fill
401 true, // is_default_stack_executable
402 '\0', // wrap_char
403 "/usr/lib/ld.so.1", // dynamic_linker
404 0x10000000, // default_text_segment_address
405 64 * 1024, // abi_pagesize (overridable by -z max-page-size)
406 8 * 1024 // common_pagesize (overridable by -z common-page-size)
407};
408
409template<int size, bool big_endian>
410class Powerpc_relocate_functions
411{
412private:
413 // Do a simple relocation with the addend in the relocation.
414 template<int valsize>
415 static inline void
416 rela(unsigned char* view,
417 unsigned int right_shift,
418 elfcpp::Elf_Xword dst_mask,
419 typename elfcpp::Swap<size, big_endian>::Valtype value,
420 typename elfcpp::Swap<size, big_endian>::Valtype addend)
421 {
422 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
423 Valtype* wv = reinterpret_cast<Valtype*>(view);
424 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
425 Valtype reloc = ((value + addend) >> right_shift);
426
427 val &= ~dst_mask;
428 reloc &= dst_mask;
429
430 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
431 }
432
433 // Do a simple relocation using a symbol value with the addend in
434 // the relocation.
435 template<int valsize>
436 static inline void
437 rela(unsigned char* view,
438 unsigned int right_shift,
439 elfcpp::Elf_Xword dst_mask,
440 const Sized_relobj<size, big_endian>* object,
441 const Symbol_value<size>* psymval,
442 typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
443 {
444 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
445 Valtype* wv = reinterpret_cast<Valtype*>(view);
446 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
447 Valtype reloc = (psymval->value(object, addend) >> right_shift);
448
449 val &= ~dst_mask;
450 reloc &= dst_mask;
451
452 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
453 }
454
455 // Do a simple relocation using a symbol value with the addend in
456 // the relocation, unaligned.
457 template<int valsize>
458 static inline void
459 rela_ua(unsigned char* view, unsigned int right_shift,
460 elfcpp::Elf_Xword dst_mask,
461 const Sized_relobj<size, big_endian>* object,
462 const Symbol_value<size>* psymval,
463 typename elfcpp::Swap<size, big_endian>::Valtype addend)
464 {
465 typedef typename elfcpp::Swap_unaligned<valsize,
466 big_endian>::Valtype Valtype;
467 unsigned char* wv = view;
468 Valtype val = elfcpp::Swap_unaligned<valsize, big_endian>::readval(wv);
469 Valtype reloc = (psymval->value(object, addend) >> right_shift);
470
471 val &= ~dst_mask;
472 reloc &= dst_mask;
473
474 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv, val | reloc);
475 }
476
477 // Do a simple PC relative relocation with a Symbol_value with the
478 // addend in the relocation.
479 template<int valsize>
480 static inline void
481 pcrela(unsigned char* view, unsigned int right_shift,
482 elfcpp::Elf_Xword dst_mask,
483 const Sized_relobj<size, big_endian>* object,
484 const Symbol_value<size>* psymval,
485 typename elfcpp::Swap<size, big_endian>::Valtype addend,
486 typename elfcpp::Elf_types<size>::Elf_Addr address)
487 {
488 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
489 Valtype* wv = reinterpret_cast<Valtype*>(view);
490 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
491 Valtype reloc = ((psymval->value(object, addend) - address)
492 >> right_shift);
493
494 val &= ~dst_mask;
495 reloc &= dst_mask;
496
497 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
498 }
499
500 template<int valsize>
501 static inline void
502 pcrela_unaligned(unsigned char* view,
503 const Sized_relobj<size, big_endian>* object,
504 const Symbol_value<size>* psymval,
505 typename elfcpp::Swap<size, big_endian>::Valtype addend,
506 typename elfcpp::Elf_types<size>::Elf_Addr address)
507 {
508 typedef typename elfcpp::Swap_unaligned<valsize,
509 big_endian>::Valtype Valtype;
510 unsigned char* wv = view;
511 Valtype reloc = (psymval->value(object, addend) - address);
512
513 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv, reloc);
514 }
515
516 typedef Powerpc_relocate_functions<size, big_endian> This;
517 typedef Relocate_functions<size, big_endian> This_reloc;
518public:
519 // R_POWERPC_REL32: (Symbol + Addend - Address)
520 static inline void
521 rel32(unsigned char* view,
522 const Sized_relobj<size, big_endian>* object,
523 const Symbol_value<size>* psymval,
524 typename elfcpp::Elf_types<size>::Elf_Addr addend,
525 typename elfcpp::Elf_types<size>::Elf_Addr address)
526 { This_reloc::pcrela32(view, object, psymval, addend, address); }
527
528 // R_POWERPC_REL24: (Symbol + Addend - Address) & 0x3fffffc
529 static inline void
530 rel24(unsigned char* view,
531 const Sized_relobj<size, big_endian>* object,
532 const Symbol_value<size>* psymval,
533 typename elfcpp::Elf_types<size>::Elf_Addr addend,
534 typename elfcpp::Elf_types<size>::Elf_Addr address)
535 {
536 This::template pcrela<32>(view, 0, 0x03fffffc, object,
537 psymval, addend, address);
538 }
539
540 // R_POWERPC_REL14: (Symbol + Addend - Address) & 0xfffc
541 static inline void
542 rel14(unsigned char* view,
543 const Sized_relobj<size, big_endian>* object,
544 const Symbol_value<size>* psymval,
545 typename elfcpp::Elf_types<size>::Elf_Addr addend,
546 typename elfcpp::Elf_types<size>::Elf_Addr address)
547 {
548 This::template pcrela<32>(view, 0, 0x0000fffc, object,
549 psymval, addend, address);
550 }
551
552 // R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff
553 static inline void
554 addr16(unsigned char* view,
555 typename elfcpp::Elf_types<size>::Elf_Addr value,
556 typename elfcpp::Elf_types<size>::Elf_Addr addend)
557 { This_reloc::rela16(view, value, addend); }
558
559 static inline void
560 addr16(unsigned char* view,
561 const Sized_relobj<size, big_endian>* object,
562 const Symbol_value<size>* psymval,
563 typename elfcpp::Elf_types<size>::Elf_Addr addend)
564 { This_reloc::rela16(view, object, psymval, addend); }
565
566 // R_POWERPC_ADDR16_DS: (Symbol + Addend) & 0xfffc
567 static inline void
568 addr16_ds(unsigned char* view,
569 typename elfcpp::Elf_types<size>::Elf_Addr value,
570 typename elfcpp::Elf_types<size>::Elf_Addr addend)
571 {
572 This::template rela<16>(view, 0, 0xfffc, value, addend);
573 }
574
575 // R_POWERPC_ADDR16_LO: (Symbol + Addend) & 0xffff
576 static inline void
577 addr16_lo(unsigned char* view,
578 typename elfcpp::Elf_types<size>::Elf_Addr value,
579 typename elfcpp::Elf_types<size>::Elf_Addr addend)
580 { This_reloc::rela16(view, value, addend); }
581
582 static inline void
583 addr16_lo(unsigned char* view,
584 const Sized_relobj<size, big_endian>* object,
585 const Symbol_value<size>* psymval,
586 typename elfcpp::Elf_types<size>::Elf_Addr addend)
587 { This_reloc::rela16(view, object, psymval, addend); }
588
589 // R_POWERPC_ADDR16_HI: ((Symbol + Addend) >> 16) & 0xffff
590 static inline void
591 addr16_hi(unsigned char* view,
592 typename elfcpp::Elf_types<size>::Elf_Addr value,
593 typename elfcpp::Elf_types<size>::Elf_Addr addend)
594 {
595 This::template rela<16>(view, 16, 0xffff, value, addend);
596 }
597
598 static inline void
599 addr16_hi(unsigned char* view,
600 const Sized_relobj<size, big_endian>* object,
601 const Symbol_value<size>* psymval,
602 typename elfcpp::Elf_types<size>::Elf_Addr addend)
603 {
604 This::template rela<16>(view, 16, 0xffff, object, psymval, addend);
605 }
606
607 // R_POWERPC_ADDR16_HA: Same as R_POWERPC_ADDR16_HI except that if the
608 // final value of the low 16 bits of the
609 // relocation is negative, add one.
610 static inline void
611 addr16_ha(unsigned char* view,
612 typename elfcpp::Elf_types<size>::Elf_Addr value,
613 typename elfcpp::Elf_types<size>::Elf_Addr addend)
614 {
42cacb20
DE
615 typename elfcpp::Elf_types<size>::Elf_Addr reloc;
616
617 reloc = value + addend;
618
619 if (reloc & 0x8000)
620 reloc += 0x10000;
621 reloc >>= 16;
622
e6fde208 623 elfcpp::Swap<16, big_endian>::writeval(view, reloc);
42cacb20
DE
624 }
625
626 static inline void
627 addr16_ha(unsigned char* view,
628 const Sized_relobj<size, big_endian>* object,
629 const Symbol_value<size>* psymval,
630 typename elfcpp::Elf_types<size>::Elf_Addr addend)
631 {
42cacb20
DE
632 typename elfcpp::Elf_types<size>::Elf_Addr reloc;
633
634 reloc = psymval->value(object, addend);
635
636 if (reloc & 0x8000)
637 reloc += 0x10000;
638 reloc >>= 16;
639
e6fde208 640 elfcpp::Swap<16, big_endian>::writeval(view, reloc);
42cacb20
DE
641 }
642
643 // R_PPC_REL16: (Symbol + Addend - Address) & 0xffff
644 static inline void
645 rel16(unsigned char* view,
646 const Sized_relobj<size, big_endian>* object,
647 const Symbol_value<size>* psymval,
648 typename elfcpp::Elf_types<size>::Elf_Addr addend,
649 typename elfcpp::Elf_types<size>::Elf_Addr address)
650 { This_reloc::pcrela16(view, object, psymval, addend, address); }
651
652 // R_PPC_REL16_LO: (Symbol + Addend - Address) & 0xffff
653 static inline void
654 rel16_lo(unsigned char* view,
655 const Sized_relobj<size, big_endian>* object,
656 const Symbol_value<size>* psymval,
657 typename elfcpp::Elf_types<size>::Elf_Addr addend,
658 typename elfcpp::Elf_types<size>::Elf_Addr address)
659 { This_reloc::pcrela16(view, object, psymval, addend, address); }
660
661 // R_PPC_REL16_HI: ((Symbol + Addend - Address) >> 16) & 0xffff
662 static inline void
663 rel16_hi(unsigned char* view,
664 const Sized_relobj<size, big_endian>* object,
665 const Symbol_value<size>* psymval,
666 typename elfcpp::Elf_types<size>::Elf_Addr addend,
667 typename elfcpp::Elf_types<size>::Elf_Addr address)
668 {
669 This::template pcrela<16>(view, 16, 0xffff, object,
670 psymval, addend, address);
671 }
672
673 // R_PPC_REL16_HA: Same as R_PPC_REL16_HI except that if the
674 // final value of the low 16 bits of the
675 // relocation is negative, add one.
676 static inline void
677 rel16_ha(unsigned char* view,
678 const Sized_relobj<size, big_endian>* object,
679 const Symbol_value<size>* psymval,
680 typename elfcpp::Elf_types<size>::Elf_Addr addend,
681 typename elfcpp::Elf_types<size>::Elf_Addr address)
682 {
42cacb20
DE
683 typename elfcpp::Elf_types<size>::Elf_Addr reloc;
684
685 reloc = (psymval->value(object, addend) - address);
686 if (reloc & 0x8000)
687 reloc += 0x10000;
688 reloc >>= 16;
689
83d22aa8 690 elfcpp::Swap<16, big_endian>::writeval(view, reloc);
42cacb20
DE
691 }
692};
693
694// Get the GOT section, creating it if necessary.
695
696template<int size, bool big_endian>
697Output_data_got<size, big_endian>*
698Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
699 Layout* layout)
700{
701 if (this->got_ == NULL)
702 {
703 gold_assert(symtab != NULL && layout != NULL);
704
705 this->got_ = new Output_data_got<size, big_endian>();
706
707 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
708 elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
709 this->got_);
710
711 // Create the GOT2 or TOC in the .got section.
712 if (size == 32)
713 {
714 this->got2_ = new Output_data_space(4, "** GOT2");
715 layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS,
716 elfcpp::SHF_ALLOC
717 | elfcpp::SHF_WRITE,
718 this->got2_);
719 }
720 else
721 {
722 this->toc_ = new Output_data_space(8, "** TOC");
723 layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS,
724 elfcpp::SHF_ALLOC
725 | elfcpp::SHF_WRITE,
726 this->toc_);
727 }
728
729 // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
730 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
731 this->got_,
732 0, 0, elfcpp::STT_OBJECT,
733 elfcpp::STB_LOCAL,
734 elfcpp::STV_HIDDEN, 0,
735 false, false);
736 }
737
738 return this->got_;
739}
740
741// Get the dynamic reloc section, creating it if necessary.
742
743template<int size, bool big_endian>
744typename Target_powerpc<size, big_endian>::Reloc_section*
745Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
746{
747 if (this->rela_dyn_ == NULL)
748 {
749 gold_assert(layout != NULL);
750 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
751 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
752 elfcpp::SHF_ALLOC, this->rela_dyn_);
753 }
754 return this->rela_dyn_;
755}
756
757// A class to handle the PLT data.
758
759template<int size, bool big_endian>
760class Output_data_plt_powerpc : public Output_section_data
761{
762 public:
763 typedef Output_data_reloc<elfcpp::SHT_RELA, true,
764 size, big_endian> Reloc_section;
765
766 Output_data_plt_powerpc(Layout*);
767
768 // Add an entry to the PLT.
769 void add_entry(Symbol* gsym);
770
771 // Return the .rela.plt section data.
772 const Reloc_section* rel_plt() const
773 {
774 return this->rel_;
775 }
776
777 protected:
778 void do_adjust_output_section(Output_section* os);
779
780 private:
781 // The size of an entry in the PLT.
782 static const int base_plt_entry_size = (size == 32 ? 16 : 24);
783
784 // Set the final size.
785 void
786 set_final_data_size()
787 {
788 unsigned int full_count = this->count_ + 4;
789
790 this->set_data_size(full_count * base_plt_entry_size);
791 }
792
793 // Write out the PLT data.
794 void
795 do_write(Output_file*);
796
797 // The reloc section.
798 Reloc_section* rel_;
799 // The number of PLT entries.
800 unsigned int count_;
801};
802
803// Create the PLT section. The ordinary .got section is an argument,
804// since we need to refer to the start.
805
806template<int size, bool big_endian>
807Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layout)
808 : Output_section_data(size == 32 ? 4 : 8), count_(0)
809{
810 this->rel_ = new Reloc_section(false);
811 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
812 elfcpp::SHF_ALLOC, this->rel_);
813}
814
815template<int size, bool big_endian>
816void
817Output_data_plt_powerpc<size, big_endian>::do_adjust_output_section(Output_section* os)
818{
819 os->set_entsize(0);
820}
821
822// Add an entry to the PLT.
823
824template<int size, bool big_endian>
825void
826Output_data_plt_powerpc<size, big_endian>::add_entry(Symbol* gsym)
827{
828 gold_assert(!gsym->has_plt_offset());
829 unsigned int index = this->count_+ + 4;
830 section_offset_type plt_offset;
831
832 if (index < 8192)
833 plt_offset = index * base_plt_entry_size;
834 else
835 gold_unreachable();
836
837 gsym->set_plt_offset(plt_offset);
838
839 ++this->count_;
840
841 gsym->set_needs_dynsym_entry();
842 this->rel_->add_global(gsym, elfcpp::R_POWERPC_JMP_SLOT, this,
843 plt_offset, 0);
844}
845
846static const unsigned int addis_11_11 = 0x3d6b0000;
847static const unsigned int addis_11_30 = 0x3d7e0000;
848static const unsigned int addis_12_12 = 0x3d8c0000;
849static const unsigned int addi_11_11 = 0x396b0000;
850static const unsigned int add_0_11_11 = 0x7c0b5a14;
851static const unsigned int add_11_0_11 = 0x7d605a14;
852static const unsigned int b = 0x48000000;
853static const unsigned int bcl_20_31 = 0x429f0005;
854static const unsigned int bctr = 0x4e800420;
855static const unsigned int lis_11 = 0x3d600000;
856static const unsigned int lis_12 = 0x3d800000;
857static const unsigned int lwzu_0_12 = 0x840c0000;
858static const unsigned int lwz_0_12 = 0x800c0000;
859static const unsigned int lwz_11_11 = 0x816b0000;
860static const unsigned int lwz_11_30 = 0x817e0000;
861static const unsigned int lwz_12_12 = 0x818c0000;
862static const unsigned int mflr_0 = 0x7c0802a6;
863static const unsigned int mflr_12 = 0x7d8802a6;
864static const unsigned int mtctr_0 = 0x7c0903a6;
865static const unsigned int mtctr_11 = 0x7d6903a6;
866static const unsigned int mtlr_0 = 0x7c0803a6;
867static const unsigned int nop = 0x60000000;
868static const unsigned int sub_11_11_12 = 0x7d6c5850;
869
870static const unsigned int addis_r12_r2 = 0x3d820000; /* addis %r12,%r2,xxx@ha */
871static const unsigned int std_r2_40r1 = 0xf8410028; /* std %r2,40(%r1) */
872static const unsigned int ld_r11_0r12 = 0xe96c0000; /* ld %r11,xxx+0@l(%r12) */
873static const unsigned int ld_r2_0r12 = 0xe84c0000; /* ld %r2,xxx+8@l(%r12) */
874 /* ld %r11,xxx+16@l(%r12) */
875
876
877// Write out the PLT.
878
879template<int size, bool big_endian>
880void
881Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of)
882{
883 const off_t offset = this->offset();
884 const section_size_type oview_size =
885 convert_to_section_size_type(this->data_size());
886 unsigned char* const oview = of->get_output_view(offset, oview_size);
887 unsigned char* pov = oview;
888
889 memset(pov, 0, base_plt_entry_size * 4);
890 pov += base_plt_entry_size * 4;
891
892 unsigned int plt_offset = base_plt_entry_size * 4;
893 const unsigned int count = this->count_;
894
895 if (size == 64)
896 {
897 for (unsigned int i = 0; i < count; i++)
898 {
899 }
900 }
901 else
902 {
903 for (unsigned int i = 0; i < count; i++)
904 {
905 elfcpp::Swap<32, true>::writeval(pov + 0x00,
906 lwz_11_30 + plt_offset);
907 elfcpp::Swap<32, true>::writeval(pov + 0x04, mtctr_11);
908 elfcpp::Swap<32, true>::writeval(pov + 0x08, bctr);
ce3ac18a 909 elfcpp::Swap<32, true>::writeval(pov + 0x0c, nop);
42cacb20
DE
910 pov += base_plt_entry_size;
911 plt_offset += base_plt_entry_size;
912 }
913 }
914
915 gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
916
917 of->write_output_view(offset, oview_size, oview);
918}
919
920// Create a PLT entry for a global symbol.
921
922template<int size, bool big_endian>
923void
924Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
925 Layout* layout,
926 Symbol* gsym)
927{
928 if (gsym->has_plt_offset())
929 return;
930
931 if (this->plt_ == NULL)
932 {
933 // Create the GOT section first.
934 this->got_section(symtab, layout);
935
936 this->plt_ = new Output_data_plt_powerpc<size, big_endian>(layout);
937 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
938 (elfcpp::SHF_ALLOC
939 | elfcpp::SHF_EXECINSTR
940 | elfcpp::SHF_WRITE),
941 this->plt_);
942
943 // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
944 symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
945 this->plt_,
946 0, 0, elfcpp::STT_OBJECT,
947 elfcpp::STB_LOCAL,
948 elfcpp::STV_HIDDEN, 0,
949 false, false);
950 }
951
952 this->plt_->add_entry(gsym);
953}
954
955// Create a GOT entry for the TLS module index.
956
957template<int size, bool big_endian>
958unsigned int
959Target_powerpc<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
960 Layout* layout,
961 Sized_relobj<size, big_endian>* object)
962{
963 if (this->got_mod_index_offset_ == -1U)
964 {
965 gold_assert(symtab != NULL && layout != NULL && object != NULL);
966 Reloc_section* rela_dyn = this->rela_dyn_section(layout);
967 Output_data_got<size, big_endian>* got;
968 unsigned int got_offset;
969
970 got = this->got_section(symtab, layout);
971 got_offset = got->add_constant(0);
972 rela_dyn->add_local(object, 0, elfcpp::R_POWERPC_DTPMOD, got,
973 got_offset, 0);
974 got->add_constant(0);
975 this->got_mod_index_offset_ = got_offset;
976 }
977 return this->got_mod_index_offset_;
978}
979
980// Optimize the TLS relocation type based on what we know about the
981// symbol. IS_FINAL is true if the final address of this symbol is
982// known at link time.
983
984static tls::Tls_optimization
985optimize_tls_reloc(bool /* is_final */, int r_type)
986{
987 // If we are generating a shared library, then we can't do anything
988 // in the linker.
989 if (parameters->options().shared())
990 return tls::TLSOPT_NONE;
991 switch (r_type)
992 {
993 // XXX
994 default:
995 gold_unreachable();
996 }
997}
998
999// Report an unsupported relocation against a local symbol.
1000
1001template<int size, bool big_endian>
1002void
1003Target_powerpc<size, big_endian>::Scan::unsupported_reloc_local(
1004 Sized_relobj<size, big_endian>* object,
1005 unsigned int r_type)
1006{
1007 gold_error(_("%s: unsupported reloc %u against local symbol"),
1008 object->name().c_str(), r_type);
1009}
1010
1011// We are about to emit a dynamic relocation of type R_TYPE. If the
1012// dynamic linker does not support it, issue an error.
1013
1014template<int size, bool big_endian>
1015void
1016Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
1017 unsigned int r_type)
1018{
1019 gold_assert(r_type != elfcpp::R_POWERPC_NONE);
1020
1021 // These are the relocation types supported by glibc for both 32-bit
1022 // and 64-bit powerpc.
1023 switch (r_type)
1024 {
1025 case elfcpp::R_POWERPC_RELATIVE:
1026 case elfcpp::R_POWERPC_GLOB_DAT:
1027 case elfcpp::R_POWERPC_DTPMOD:
1028 case elfcpp::R_POWERPC_DTPREL:
1029 case elfcpp::R_POWERPC_TPREL:
1030 case elfcpp::R_POWERPC_JMP_SLOT:
1031 case elfcpp::R_POWERPC_COPY:
1032 case elfcpp::R_POWERPC_ADDR32:
1033 case elfcpp::R_POWERPC_ADDR24:
1034 case elfcpp::R_POWERPC_REL24:
1035 return;
1036
1037 default:
1038 break;
1039 }
1040
1041 if (size == 64)
1042 {
1043 switch (r_type)
1044 {
1045 // These are the relocation types supported only on 64-bit.
1046 case elfcpp::R_PPC64_ADDR64:
1047 case elfcpp::R_PPC64_TPREL16_LO_DS:
1048 case elfcpp::R_PPC64_TPREL16_DS:
1049 case elfcpp::R_POWERPC_TPREL16:
1050 case elfcpp::R_POWERPC_TPREL16_LO:
1051 case elfcpp::R_POWERPC_TPREL16_HI:
1052 case elfcpp::R_POWERPC_TPREL16_HA:
1053 case elfcpp::R_PPC64_TPREL16_HIGHER:
1054 case elfcpp::R_PPC64_TPREL16_HIGHEST:
1055 case elfcpp::R_PPC64_TPREL16_HIGHERA:
1056 case elfcpp::R_PPC64_TPREL16_HIGHESTA:
1057 case elfcpp::R_PPC64_ADDR16_LO_DS:
1058 case elfcpp::R_POWERPC_ADDR16_LO:
1059 case elfcpp::R_POWERPC_ADDR16_HI:
1060 case elfcpp::R_POWERPC_ADDR16_HA:
1061 case elfcpp::R_POWERPC_ADDR30:
1062 case elfcpp::R_PPC64_UADDR64:
1063 case elfcpp::R_POWERPC_UADDR32:
1064 case elfcpp::R_POWERPC_ADDR16:
1065 case elfcpp::R_POWERPC_UADDR16:
1066 case elfcpp::R_PPC64_ADDR16_DS:
1067 case elfcpp::R_PPC64_ADDR16_HIGHER:
1068 case elfcpp::R_PPC64_ADDR16_HIGHEST:
1069 case elfcpp::R_PPC64_ADDR16_HIGHERA:
1070 case elfcpp::R_PPC64_ADDR16_HIGHESTA:
1071 case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
1072 case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
1073 case elfcpp::R_POWERPC_REL32:
1074 case elfcpp::R_PPC64_REL64:
1075 return;
1076
1077 default:
1078 break;
1079 }
1080 }
1081 else
1082 {
1083 switch (r_type)
1084 {
1085 // These are the relocation types supported only on 32-bit.
1086
1087 default:
1088 break;
1089 }
1090 }
1091
1092 // This prevents us from issuing more than one error per reloc
1093 // section. But we can still wind up issuing more than one
1094 // error per object file.
1095 if (this->issued_non_pic_error_)
1096 return;
1097 object->error(_("requires unsupported dynamic reloc; "
1098 "recompile with -fPIC"));
1099 this->issued_non_pic_error_ = true;
1100 return;
1101}
1102
1103// Scan a relocation for a local symbol.
1104
1105template<int size, bool big_endian>
1106inline void
1107Target_powerpc<size, big_endian>::Scan::local(
1108 const General_options&,
1109 Symbol_table* symtab,
1110 Layout* layout,
1111 Target_powerpc<size, big_endian>* target,
1112 Sized_relobj<size, big_endian>* object,
1113 unsigned int data_shndx,
1114 Output_section* output_section,
1115 const elfcpp::Rela<size, big_endian>& reloc,
1116 unsigned int r_type,
1117 const elfcpp::Sym<size, big_endian>& lsym)
1118{
1119 switch (r_type)
1120 {
1121 case elfcpp::R_POWERPC_NONE:
1122 case elfcpp::R_POWERPC_GNU_VTINHERIT:
1123 case elfcpp::R_POWERPC_GNU_VTENTRY:
1124 break;
1125
1126 case elfcpp::R_PPC64_ADDR64:
1127 case elfcpp::R_POWERPC_ADDR32:
1128 case elfcpp::R_POWERPC_ADDR16_HA:
1129 case elfcpp::R_POWERPC_ADDR16_LO:
1130 // If building a shared library (or a position-independent
1131 // executable), we need to create a dynamic relocation for
1132 // this location.
1133 if (parameters->options().output_is_position_independent())
1134 {
1135 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1136
1137 check_non_pic(object, r_type);
1138 if (lsym.get_st_type() != elfcpp::STT_SECTION)
1139 {
1140 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1141 rela_dyn->add_local(object, r_sym, r_type, output_section,
1142 data_shndx, reloc.get_r_offset(),
1143 reloc.get_r_addend());
1144 }
1145 else
1146 {
1147 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1148 gold_assert(lsym.get_st_value() == 0);
1149 rela_dyn->add_local_relative(object, r_sym, r_type,
1150 output_section, data_shndx,
1151 reloc.get_r_offset(),
1152 reloc.get_r_addend());
1153 }
1154 }
1155 break;
1156
1157 case elfcpp::R_POWERPC_REL24:
1158 case elfcpp::R_PPC_LOCAL24PC:
1159 case elfcpp::R_POWERPC_REL32:
1160 case elfcpp::R_PPC_REL16_LO:
1161 case elfcpp::R_PPC_REL16_HA:
1162 break;
1163
1164 case elfcpp::R_POWERPC_GOT16:
1165 case elfcpp::R_POWERPC_GOT16_LO:
1166 case elfcpp::R_POWERPC_GOT16_HI:
1167 case elfcpp::R_POWERPC_GOT16_HA:
1168 case elfcpp::R_PPC64_TOC16:
1169 case elfcpp::R_PPC64_TOC16_LO:
1170 case elfcpp::R_PPC64_TOC16_HI:
1171 case elfcpp::R_PPC64_TOC16_HA:
1172 case elfcpp::R_PPC64_TOC16_DS:
1173 case elfcpp::R_PPC64_TOC16_LO_DS:
1174 {
1175 // The symbol requires a GOT entry.
1176 Output_data_got<size, big_endian>* got;
1177 unsigned int r_sym;
1178
1179 got = target->got_section(symtab, layout);
1180 r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1181
1182 // If we are generating a shared object, we need to add a
1183 // dynamic relocation for this symbol's GOT entry.
1184 if (parameters->options().output_is_position_independent())
1185 {
1186 if (!object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD))
1187 {
1188 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1189 unsigned int off;
1190
1191 off = got->add_constant(0);
1192 object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
1193 rela_dyn->add_local_relative(object, r_sym,
1194 elfcpp::R_POWERPC_RELATIVE,
1195 got, off, 0);
1196 }
1197 }
1198 else
1199 got->add_local(object, r_sym, GOT_TYPE_STANDARD);
1200 }
1201 break;
1202
1203 case elfcpp::R_PPC64_TOC:
1204 // We need a GOT section.
1205 target->got_section(symtab, layout);
1206 break;
1207
1208 // These are relocations which should only be seen by the
1209 // dynamic linker, and should never be seen here.
1210 case elfcpp::R_POWERPC_COPY:
1211 case elfcpp::R_POWERPC_GLOB_DAT:
1212 case elfcpp::R_POWERPC_JMP_SLOT:
1213 case elfcpp::R_POWERPC_RELATIVE:
1214 case elfcpp::R_POWERPC_DTPMOD:
1215 gold_error(_("%s: unexpected reloc %u in object file"),
1216 object->name().c_str(), r_type);
1217 break;
1218
1219 default:
1220 unsupported_reloc_local(object, r_type);
1221 break;
1222 }
1223}
1224
1225// Report an unsupported relocation against a global symbol.
1226
1227template<int size, bool big_endian>
1228void
1229Target_powerpc<size, big_endian>::Scan::unsupported_reloc_global(
1230 Sized_relobj<size, big_endian>* object,
1231 unsigned int r_type,
1232 Symbol* gsym)
1233{
1234 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
1235 object->name().c_str(), r_type, gsym->demangled_name().c_str());
1236}
1237
1238// Scan a relocation for a global symbol.
1239
1240template<int size, bool big_endian>
1241inline void
1242Target_powerpc<size, big_endian>::Scan::global(
1243 const General_options&,
1244 Symbol_table* symtab,
1245 Layout* layout,
1246 Target_powerpc<size, big_endian>* target,
1247 Sized_relobj<size, big_endian>* object,
1248 unsigned int data_shndx,
1249 Output_section* output_section,
1250 const elfcpp::Rela<size, big_endian>& reloc,
1251 unsigned int r_type,
1252 Symbol* gsym)
1253{
1254 switch (r_type)
1255 {
1256 case elfcpp::R_POWERPC_NONE:
1257 case elfcpp::R_POWERPC_GNU_VTINHERIT:
1258 case elfcpp::R_POWERPC_GNU_VTENTRY:
1259 break;
1260
1261 case elfcpp::R_PPC_PLTREL24:
1262 // If the symbol is fully resolved, this is just a PC32 reloc.
1263 // Otherwise we need a PLT entry.
1264 if (gsym->final_value_is_known())
1265 break;
1266 // If building a shared library, we can also skip the PLT entry
1267 // if the symbol is defined in the output file and is protected
1268 // or hidden.
1269 if (gsym->is_defined()
1270 && !gsym->is_from_dynobj()
1271 && !gsym->is_preemptible())
1272 break;
1273 target->make_plt_entry(symtab, layout, gsym);
1274 break;
1275
1276 case elfcpp::R_POWERPC_ADDR16:
1277 case elfcpp::R_POWERPC_ADDR16_LO:
1278 case elfcpp::R_POWERPC_ADDR16_HI:
1279 case elfcpp::R_POWERPC_ADDR16_HA:
1280 case elfcpp::R_POWERPC_ADDR32:
1281 case elfcpp::R_PPC64_ADDR64:
1282 {
1283 // Make a PLT entry if necessary.
1284 if (gsym->needs_plt_entry())
1285 {
1286 target->make_plt_entry(symtab, layout, gsym);
1287 // Since this is not a PC-relative relocation, we may be
1288 // taking the address of a function. In that case we need to
1289 // set the entry in the dynamic symbol table to the address of
1290 // the PLT entry.
1291 if (gsym->is_from_dynobj() && !parameters->options().shared())
1292 gsym->set_needs_dynsym_value();
1293 }
1294 // Make a dynamic relocation if necessary.
1295 if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
1296 {
1297 if (target->may_need_copy_reloc(gsym))
1298 {
1299 target->copy_reloc(symtab, layout, object,
1300 data_shndx, output_section, gsym, reloc);
1301 }
1302 else if ((r_type == elfcpp::R_POWERPC_ADDR32
1303 || r_type == elfcpp::R_PPC64_ADDR64)
1304 && gsym->can_use_relative_reloc(false))
1305 {
1306 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1307 rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
1308 output_section, object,
1309 data_shndx, reloc.get_r_offset(),
1310 reloc.get_r_addend());
1311 }
1312 else
1313 {
1314 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1315
1316 check_non_pic(object, r_type);
1317 if (gsym->is_from_dynobj()
1318 || gsym->is_undefined()
1319 || gsym->is_preemptible())
1320 rela_dyn->add_global(gsym, r_type, output_section,
1321 object, data_shndx,
1322 reloc.get_r_offset(),
1323 reloc.get_r_addend());
1324 else
1325 rela_dyn->add_global_relative(gsym, r_type,
1326 output_section, object,
1327 data_shndx,
1328 reloc.get_r_offset(),
1329 reloc.get_r_addend());
1330 }
1331 }
1332 }
1333 break;
1334
1335 case elfcpp::R_POWERPC_REL24:
1336 case elfcpp::R_PPC_LOCAL24PC:
1337 case elfcpp::R_PPC_REL16:
1338 case elfcpp::R_PPC_REL16_LO:
1339 case elfcpp::R_PPC_REL16_HI:
1340 case elfcpp::R_PPC_REL16_HA:
1341 {
1342 if (gsym->needs_plt_entry())
1343 target->make_plt_entry(symtab, layout, gsym);
1344 // Make a dynamic relocation if necessary.
1345 int flags = Symbol::NON_PIC_REF;
1346 if (gsym->type() == elfcpp::STT_FUNC)
1347 flags |= Symbol::FUNCTION_CALL;
1348 if (gsym->needs_dynamic_reloc(flags))
1349 {
1350 if (target->may_need_copy_reloc(gsym))
1351 {
1352 target->copy_reloc(symtab, layout, object,
1353 data_shndx, output_section, gsym,
1354 reloc);
1355 }
1356 else
1357 {
1358 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1359 check_non_pic(object, r_type);
1360 rela_dyn->add_global(gsym, r_type, output_section, object,
1361 data_shndx, reloc.get_r_offset(),
1362 reloc.get_r_addend());
1363 }
1364 }
1365 }
1366 break;
1367
1368 case elfcpp::R_POWERPC_GOT16:
1369 case elfcpp::R_POWERPC_GOT16_LO:
1370 case elfcpp::R_POWERPC_GOT16_HI:
1371 case elfcpp::R_POWERPC_GOT16_HA:
1372 case elfcpp::R_PPC64_TOC16:
1373 case elfcpp::R_PPC64_TOC16_LO:
1374 case elfcpp::R_PPC64_TOC16_HI:
1375 case elfcpp::R_PPC64_TOC16_HA:
1376 case elfcpp::R_PPC64_TOC16_DS:
1377 case elfcpp::R_PPC64_TOC16_LO_DS:
1378 {
1379 // The symbol requires a GOT entry.
1380 Output_data_got<size, big_endian>* got;
1381
1382 got = target->got_section(symtab, layout);
1383 if (gsym->final_value_is_known())
1384 got->add_global(gsym, GOT_TYPE_STANDARD);
1385 else
1386 {
1387 // If this symbol is not fully resolved, we need to add a
1388 // dynamic relocation for it.
1389 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1390 if (gsym->is_from_dynobj()
1391 || gsym->is_undefined()
1392 || gsym->is_preemptible())
1393 got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
1394 elfcpp::R_POWERPC_GLOB_DAT);
1395 else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
1396 {
1397 unsigned int off = got->add_constant(0);
1398
1399 gsym->set_got_offset(GOT_TYPE_STANDARD, off);
1400 rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
1401 got, off, 0);
1402 }
1403 }
1404 }
1405 break;
1406
1407 case elfcpp::R_PPC64_TOC:
1408 // We need a GOT section.
1409 target->got_section(symtab, layout);
1410 break;
1411
1412 case elfcpp::R_POWERPC_GOT_TPREL16:
1413 case elfcpp::R_POWERPC_TLS:
1414 // XXX TLS
1415 break;
1416
1417 // These are relocations which should only be seen by the
1418 // dynamic linker, and should never be seen here.
1419 case elfcpp::R_POWERPC_COPY:
1420 case elfcpp::R_POWERPC_GLOB_DAT:
1421 case elfcpp::R_POWERPC_JMP_SLOT:
1422 case elfcpp::R_POWERPC_RELATIVE:
1423 case elfcpp::R_POWERPC_DTPMOD:
1424 gold_error(_("%s: unexpected reloc %u in object file"),
1425 object->name().c_str(), r_type);
1426 break;
1427
1428 default:
1429 unsupported_reloc_global(object, r_type, gsym);
1430 break;
1431 }
1432}
1433
6d03d481
ST
1434// Process relocations for gc.
1435
1436template<int size, bool big_endian>
1437void
1438Target_powerpc<size, big_endian>::gc_process_relocs(
1439 const General_options& options,
1440 Symbol_table* symtab,
1441 Layout* layout,
1442 Sized_relobj<size, big_endian>* object,
1443 unsigned int data_shndx,
1444 unsigned int,
1445 const unsigned char* prelocs,
1446 size_t reloc_count,
1447 Output_section* output_section,
1448 bool needs_special_offset_handling,
1449 size_t local_symbol_count,
1450 const unsigned char* plocal_symbols)
1451{
1452 typedef Target_powerpc<size, big_endian> Powerpc;
1453 typedef typename Target_powerpc<size, big_endian>::Scan Scan;
1454
1455 gold::gc_process_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
1456 options,
1457 symtab,
1458 layout,
1459 this,
1460 object,
1461 data_shndx,
1462 prelocs,
1463 reloc_count,
1464 output_section,
1465 needs_special_offset_handling,
1466 local_symbol_count,
1467 plocal_symbols);
1468}
1469
42cacb20
DE
1470// Scan relocations for a section.
1471
1472template<int size, bool big_endian>
1473void
1474Target_powerpc<size, big_endian>::scan_relocs(
1475 const General_options& options,
1476 Symbol_table* symtab,
1477 Layout* layout,
1478 Sized_relobj<size, big_endian>* object,
1479 unsigned int data_shndx,
1480 unsigned int sh_type,
1481 const unsigned char* prelocs,
1482 size_t reloc_count,
1483 Output_section* output_section,
1484 bool needs_special_offset_handling,
1485 size_t local_symbol_count,
1486 const unsigned char* plocal_symbols)
1487{
1488 typedef Target_powerpc<size, big_endian> Powerpc;
1489 typedef typename Target_powerpc<size, big_endian>::Scan Scan;
1490 static Output_data_space* sdata;
1491
1492 if (sh_type == elfcpp::SHT_REL)
1493 {
1494 gold_error(_("%s: unsupported REL reloc section"),
1495 object->name().c_str());
1496 return;
1497 }
1498
1499 // Define _SDA_BASE_ at the start of the .sdata section.
1500 if (sdata == NULL)
1501 {
1502 // layout->find_output_section(".sdata") == NULL
1503 sdata = new Output_data_space(4, "** sdata");
1504 Output_section* os = layout->add_output_section_data(".sdata", 0,
1505 elfcpp::SHF_ALLOC
1506 | elfcpp::SHF_WRITE,
1507 sdata);
1508 symtab->define_in_output_data("_SDA_BASE_", NULL,
1509 os,
1510 32768, 0,
1511 elfcpp::STT_OBJECT,
1512 elfcpp::STB_LOCAL,
1513 elfcpp::STV_HIDDEN, 0,
1514 false, false);
1515 }
1516
1517 gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
1518 options,
1519 symtab,
1520 layout,
1521 this,
1522 object,
1523 data_shndx,
1524 prelocs,
1525 reloc_count,
1526 output_section,
1527 needs_special_offset_handling,
1528 local_symbol_count,
1529 plocal_symbols);
1530}
1531
1532// Finalize the sections.
1533
1534template<int size, bool big_endian>
1535void
1536Target_powerpc<size, big_endian>::do_finalize_sections(Layout* layout)
1537{
1538 // Fill in some more dynamic tags.
1539 Output_data_dynamic* const odyn = layout->dynamic_data();
1540 if (odyn != NULL)
1541 {
1542 if (this->plt_ != NULL)
1543 {
1544 const Output_data* od = this->plt_->rel_plt();
1545 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
1546 odyn->add_section_address(elfcpp::DT_JMPREL, od);
1547 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
1548
1549 odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
1550 }
1551
1552 if (this->rela_dyn_ != NULL)
1553 {
1554 const Output_data* od = this->rela_dyn_;
1555 odyn->add_section_address(elfcpp::DT_RELA, od);
1556 odyn->add_section_size(elfcpp::DT_RELASZ, od);
1557 odyn->add_constant(elfcpp::DT_RELAENT,
1558 elfcpp::Elf_sizes<size>::rela_size);
1559 }
1560
1561 if (!parameters->options().shared())
1562 {
1563 // The value of the DT_DEBUG tag is filled in by the dynamic
1564 // linker at run time, and used by the debugger.
1565 odyn->add_constant(elfcpp::DT_DEBUG, 0);
1566 }
1567 }
1568
1569 // Emit any relocs we saved in an attempt to avoid generating COPY
1570 // relocs.
1571 if (this->copy_relocs_.any_saved_relocs())
1572 this->copy_relocs_.emit(this->rela_dyn_section(layout));
1573}
1574
1575// Perform a relocation.
1576
1577template<int size, bool big_endian>
1578inline bool
1579Target_powerpc<size, big_endian>::Relocate::relocate(
1580 const Relocate_info<size, big_endian>* relinfo,
1581 Target_powerpc* target,
031cdbed 1582 Output_section*,
42cacb20
DE
1583 size_t relnum,
1584 const elfcpp::Rela<size, big_endian>& rela,
1585 unsigned int r_type,
1586 const Sized_symbol<size>* gsym,
1587 const Symbol_value<size>* psymval,
1588 unsigned char* view,
1589 typename elfcpp::Elf_types<size>::Elf_Addr address,
1590 section_size_type /* view_size */)
1591{
1592 const unsigned int toc_base_offset = 0x8000;
1593 typedef Powerpc_relocate_functions<size, big_endian> Reloc;
1594
1595 // Pick the value to use for symbols defined in shared objects.
1596 Symbol_value<size> symval;
1597 if (gsym != NULL
de4c45bd
ILT
1598 && gsym->use_plt_offset(r_type == elfcpp::R_POWERPC_REL24
1599 || r_type == elfcpp::R_PPC_LOCAL24PC
1600 || r_type == elfcpp::R_PPC_REL16
1601 || r_type == elfcpp::R_PPC_REL16_LO
1602 || r_type == elfcpp::R_PPC_REL16_HI
1603 || r_type == elfcpp::R_PPC_REL16_HA))
42cacb20
DE
1604 {
1605 elfcpp::Elf_Xword value;
1606
1607 value = target->plt_section()->address() + gsym->plt_offset();
1608
1609 symval.set_output_value(value);
1610
1611 psymval = &symval;
1612 }
1613
1614 const Sized_relobj<size, big_endian>* object = relinfo->object;
1615 elfcpp::Elf_Xword addend = rela.get_r_addend();
1616
1617 // Get the GOT offset if needed. Unlike i386 and x86_64, our GOT
1618 // pointer points to the beginning, not the end, of the table.
1619 // So we just use the plain offset.
1620 bool have_got_offset = false;
1621 unsigned int got_offset = 0;
1622 unsigned int got2_offset = 0;
1623 switch (r_type)
1624 {
1625 case elfcpp::R_PPC64_TOC16:
1626 case elfcpp::R_PPC64_TOC16_LO:
1627 case elfcpp::R_PPC64_TOC16_HI:
1628 case elfcpp::R_PPC64_TOC16_HA:
1629 case elfcpp::R_PPC64_TOC16_DS:
1630 case elfcpp::R_PPC64_TOC16_LO_DS:
1631 // Subtract the TOC base address.
1632 addend -= target->toc_section()->address() + toc_base_offset;
1633 /* FALLTHRU */
1634
1635 case elfcpp::R_POWERPC_GOT16:
1636 case elfcpp::R_POWERPC_GOT16_LO:
1637 case elfcpp::R_POWERPC_GOT16_HI:
1638 case elfcpp::R_POWERPC_GOT16_HA:
1639 case elfcpp::R_PPC64_GOT16_DS:
1640 case elfcpp::R_PPC64_GOT16_LO_DS:
1641 if (gsym != NULL)
1642 {
1643 gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
1644 got_offset = gsym->got_offset(GOT_TYPE_STANDARD);
1645 }
1646 else
1647 {
1648 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
1649 gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
1650 got_offset = object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
1651 }
1652 have_got_offset = true;
1653 break;
1654
1655 // R_PPC_PLTREL24 is rather special. If non-zero,
1656 // the addend specifies the GOT pointer offset within .got2.
1657 case elfcpp::R_PPC_PLTREL24:
1658 if (addend >= 32768)
1659 {
1660 Output_data_space* got2;
1661 got2 = target->got2_section();
1662 got2_offset = got2->offset();
1663 addend += got2_offset;
1664 }
1665 have_got_offset = true;
1666 break;
1667
1668 default:
1669 break;
1670 }
1671
1672 switch (r_type)
1673 {
1674 case elfcpp::R_POWERPC_NONE:
1675 case elfcpp::R_POWERPC_GNU_VTINHERIT:
1676 case elfcpp::R_POWERPC_GNU_VTENTRY:
1677 break;
1678
1679 case elfcpp::R_POWERPC_REL32:
1680 Reloc::rel32(view, object, psymval, addend, address);
1681 break;
1682
1683 case elfcpp::R_POWERPC_REL24:
1684 Reloc::rel24(view, object, psymval, addend, address);
1685 break;
1686
1687 case elfcpp::R_POWERPC_REL14:
1688 Reloc::rel14(view, object, psymval, addend, address);
1689 break;
1690
1691 case elfcpp::R_PPC_PLTREL24:
1692 Reloc::rel24(view, object, psymval, addend, address);
1693 break;
1694
1695 case elfcpp::R_PPC_LOCAL24PC:
1696 Reloc::rel24(view, object, psymval, addend, address);
1697 break;
1698
1699 case elfcpp::R_PPC64_ADDR64:
1700 if (!parameters->options().output_is_position_independent())
1701 Relocate_functions<size, big_endian>::rela64(view, object,
1702 psymval, addend);
1703 break;
1704
1705 case elfcpp::R_POWERPC_ADDR32:
1706 if (!parameters->options().output_is_position_independent())
1707 Relocate_functions<size, big_endian>::rela32(view, object,
1708 psymval, addend);
1709 break;
1710
1711 case elfcpp::R_POWERPC_ADDR16_LO:
1712 Reloc::addr16_lo(view, object, psymval, addend);
1713 break;
1714
1715 case elfcpp::R_POWERPC_ADDR16_HI:
1716 Reloc::addr16_hi(view, object, psymval, addend);
1717 break;
1718
1719 case elfcpp::R_POWERPC_ADDR16_HA:
1720 Reloc::addr16_ha(view, object, psymval, addend);
1721 break;
1722
1723 case elfcpp::R_PPC_REL16_LO:
1724 Reloc::rel16_lo(view, object, psymval, addend, address);
1725 break;
1726
1727 case elfcpp::R_PPC_REL16_HI:
1728 Reloc::rel16_lo(view, object, psymval, addend, address);
1729 break;
1730
1731 case elfcpp::R_PPC_REL16_HA:
83d22aa8 1732 Reloc::rel16_ha(view, object, psymval, addend, address);
42cacb20
DE
1733 break;
1734
1735 case elfcpp::R_POWERPC_GOT16:
1736 Reloc::addr16(view, got_offset, addend);
1737 break;
1738
1739 case elfcpp::R_POWERPC_GOT16_LO:
1740 Reloc::addr16_lo(view, got_offset, addend);
1741 break;
1742
1743 case elfcpp::R_POWERPC_GOT16_HI:
1744 Reloc::addr16_hi(view, got_offset, addend);
1745 break;
1746
1747 case elfcpp::R_POWERPC_GOT16_HA:
1748 Reloc::addr16_ha(view, got_offset, addend);
1749 break;
1750
1751 case elfcpp::R_PPC64_TOC16:
1752 Reloc::addr16(view, got_offset, addend);
1753 break;
1754
1755 case elfcpp::R_PPC64_TOC16_LO:
1756 Reloc::addr16_lo(view, got_offset, addend);
1757 break;
1758
1759 case elfcpp::R_PPC64_TOC16_HI:
1760 Reloc::addr16_hi(view, got_offset, addend);
1761 break;
1762
1763 case elfcpp::R_PPC64_TOC16_HA:
1764 Reloc::addr16_ha(view, got_offset, addend);
1765 break;
1766
1767 case elfcpp::R_PPC64_TOC16_DS:
1768 case elfcpp::R_PPC64_TOC16_LO_DS:
1769 Reloc::addr16_ds(view, got_offset, addend);
1770 break;
1771
1772 case elfcpp::R_PPC64_TOC:
1773 {
1774 elfcpp::Elf_types<64>::Elf_Addr value;
1775 value = target->toc_section()->address() + toc_base_offset;
1776 Relocate_functions<64, false>::rela64(view, value, addend);
1777 }
1778 break;
1779
1780 case elfcpp::R_POWERPC_COPY:
1781 case elfcpp::R_POWERPC_GLOB_DAT:
1782 case elfcpp::R_POWERPC_JMP_SLOT:
1783 case elfcpp::R_POWERPC_RELATIVE:
1784 // This is an outstanding tls reloc, which is unexpected when
1785 // linking.
1786 case elfcpp::R_POWERPC_DTPMOD:
1787 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
1788 _("unexpected reloc %u in object file"),
1789 r_type);
1790 break;
1791
1792 default:
1793 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
1794 _("unsupported reloc %u"),
1795 r_type);
1796 break;
1797 }
1798
1799 return true;
1800}
1801
1802// Perform a TLS relocation.
1803
1804template<int size, bool big_endian>
1805inline void
1806Target_powerpc<size, big_endian>::Relocate::relocate_tls(
1807 const Relocate_info<size, big_endian>* relinfo,
1808 Target_powerpc<size, big_endian>* target,
1809 size_t relnum,
1810 const elfcpp::Rela<size, big_endian>& rela,
1811 unsigned int r_type,
1812 const Sized_symbol<size>* gsym,
1813 const Symbol_value<size>* psymval,
1814 unsigned char* view,
1815 typename elfcpp::Elf_types<size>::Elf_Addr address,
1816 section_size_type)
1817{
1818 Output_segment* tls_segment = relinfo->layout->tls_segment();
1819 typedef Powerpc_relocate_functions<size, big_endian> Reloc;
1820 const Sized_relobj<size, big_endian>* object = relinfo->object;
1821
1822 const elfcpp::Elf_Xword addend = rela.get_r_addend();
1823 typename elfcpp::Elf_types<size>::Elf_Addr value = psymval->value(object, 0);
1824
1825 const bool is_final =
1826 (gsym == NULL
1827 ? !parameters->options().output_is_position_independent()
1828 : gsym->final_value_is_known());
1829 const tls::Tls_optimization optimized_type
1830 = optimize_tls_reloc(is_final, r_type);
1831
1832 switch (r_type)
1833 {
1834 // XXX
1835 }
1836}
1837
1838// Relocate section data.
1839
1840template<int size, bool big_endian>
1841void
1842Target_powerpc<size, big_endian>::relocate_section(
1843 const Relocate_info<size, big_endian>* relinfo,
1844 unsigned int sh_type,
1845 const unsigned char* prelocs,
1846 size_t reloc_count,
1847 Output_section* output_section,
1848 bool needs_special_offset_handling,
1849 unsigned char* view,
1850 typename elfcpp::Elf_types<size>::Elf_Addr address,
1851 section_size_type view_size)
1852{
1853 typedef Target_powerpc<size, big_endian> Powerpc;
1854 typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
1855
1856 gold_assert(sh_type == elfcpp::SHT_RELA);
1857
1858 gold::relocate_section<size, big_endian, Powerpc, elfcpp::SHT_RELA,
1859 Powerpc_relocate>(
1860 relinfo,
1861 this,
1862 prelocs,
1863 reloc_count,
1864 output_section,
1865 needs_special_offset_handling,
1866 view,
1867 address,
1868 view_size);
1869}
1870
1871// Return the size of a relocation while scanning during a relocatable
1872// link.
1873
1874template<int size, bool big_endian>
1875unsigned int
1876Target_powerpc<size, big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
1877 unsigned int,
1878 Relobj*)
1879{
1880 // We are always SHT_RELA, so we should never get here.
1881 gold_unreachable();
1882 return 0;
1883}
1884
1885// Scan the relocs during a relocatable link.
1886
1887template<int size, bool big_endian>
1888void
1889Target_powerpc<size, big_endian>::scan_relocatable_relocs(
1890 const General_options& options,
1891 Symbol_table* symtab,
1892 Layout* layout,
1893 Sized_relobj<size, big_endian>* object,
1894 unsigned int data_shndx,
1895 unsigned int sh_type,
1896 const unsigned char* prelocs,
1897 size_t reloc_count,
1898 Output_section* output_section,
1899 bool needs_special_offset_handling,
1900 size_t local_symbol_count,
1901 const unsigned char* plocal_symbols,
1902 Relocatable_relocs* rr)
1903{
1904 gold_assert(sh_type == elfcpp::SHT_RELA);
1905
1906 typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_RELA,
1907 Relocatable_size_for_reloc> Scan_relocatable_relocs;
1908
1909 gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_RELA,
1910 Scan_relocatable_relocs>(
1911 options,
1912 symtab,
1913 layout,
1914 object,
1915 data_shndx,
1916 prelocs,
1917 reloc_count,
1918 output_section,
1919 needs_special_offset_handling,
1920 local_symbol_count,
1921 plocal_symbols,
1922 rr);
1923}
1924
1925// Relocate a section during a relocatable link.
1926
1927template<int size, bool big_endian>
1928void
1929Target_powerpc<size, big_endian>::relocate_for_relocatable(
1930 const Relocate_info<size, big_endian>* relinfo,
1931 unsigned int sh_type,
1932 const unsigned char* prelocs,
1933 size_t reloc_count,
1934 Output_section* output_section,
1935 off_t offset_in_output_section,
1936 const Relocatable_relocs* rr,
1937 unsigned char* view,
1938 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
1939 section_size_type view_size,
1940 unsigned char* reloc_view,
1941 section_size_type reloc_view_size)
1942{
1943 gold_assert(sh_type == elfcpp::SHT_RELA);
1944
1945 gold::relocate_for_relocatable<size, big_endian, elfcpp::SHT_RELA>(
1946 relinfo,
1947 prelocs,
1948 reloc_count,
1949 output_section,
1950 offset_in_output_section,
1951 rr,
1952 view,
1953 view_address,
1954 view_size,
1955 reloc_view,
1956 reloc_view_size);
1957}
1958
1959// Return the value to use for a dynamic which requires special
1960// treatment. This is how we support equality comparisons of function
1961// pointers across shared library boundaries, as described in the
1962// processor specific ABI supplement.
1963
1964template<int size, bool big_endian>
1965uint64_t
1966Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
1967{
1968 gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1969 return this->plt_section()->address() + gsym->plt_offset();
1970}
1971
1972// The selector for powerpc object files.
1973
1974template<int size, bool big_endian>
1975class Target_selector_powerpc : public Target_selector
1976{
1977public:
1978 Target_selector_powerpc()
1979 : Target_selector(elfcpp::EM_NONE, size, big_endian,
1980 (size == 64 ?
1981 (big_endian ? "elf64-powerpc" : "elf64-powerpcle") :
1982 (big_endian ? "elf32-powerpc" : "elf32-powerpcle")))
1983 { }
1984
42cacb20
DE
1985 Target* do_recognize(int machine, int, int)
1986 {
1987 switch (size)
1988 {
1989 case 64:
1990 if (machine != elfcpp::EM_PPC64)
1991 return NULL;
1992 break;
1993
1994 case 32:
1995 if (machine != elfcpp::EM_PPC)
1996 return NULL;
1997 break;
1998
1999 default:
2000 return NULL;
2001 }
2002
7f055c20 2003 return this->instantiate_target();
42cacb20
DE
2004 }
2005
2006 Target* do_instantiate_target()
7f055c20 2007 { return new Target_powerpc<size, big_endian>(); }
42cacb20
DE
2008};
2009
2010Target_selector_powerpc<32, true> target_selector_ppc32;
2011Target_selector_powerpc<32, false> target_selector_ppc32le;
2012Target_selector_powerpc<64, true> target_selector_ppc64;
2013Target_selector_powerpc<64, false> target_selector_ppc64le;
2014
2015} // End anonymous namespace.