daily update
[deliverable/binutils-gdb.git] / gold / aarch64.cc
CommitLineData
053a4d68
JY
1// aarch64.cc -- aarch64 target support for gold.
2
3// Copyright (C) 2014 Free Software Foundation, Inc.
4// Written by Jing Yu <jingyu@google.com>.
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#include "gold.h"
24
25#include <cstring>
26
27#include "elfcpp.h"
28#include "dwarf.h"
29#include "parameters.h"
30#include "reloc.h"
31#include "aarch64.h"
32#include "object.h"
33#include "symtab.h"
34#include "layout.h"
35#include "output.h"
36#include "copy-relocs.h"
37#include "target.h"
38#include "target-reloc.h"
39#include "target-select.h"
40#include "tls.h"
41#include "freebsd.h"
42#include "nacl.h"
43#include "gc.h"
44#include "icf.h"
45
46// The first three .got.plt entries are reserved.
47const int32_t AARCH64_GOTPLT_RESERVE_COUNT = 3;
48
49namespace
50{
51
52using namespace gold;
53
54template<int size, bool big_endian>
55class Output_data_plt_aarch64;
56
57template<int size, bool big_endian>
58class Output_data_plt_aarch64_standard;
59
60template<int size, bool big_endian>
61class Target_aarch64;
62
63// Output_data_got_aarch64 class.
64
65template<int size, bool big_endian>
66class Output_data_got_aarch64 : public Output_data_got<size, big_endian>
67{
68 public:
69 typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
70 Output_data_got_aarch64(Symbol_table* symtab, Layout* layout)
71 : Output_data_got<size, big_endian>(), layout_(layout)
72 { }
73
74 protected:
75 // Write out the GOT table.
76 void
77 do_write(Output_file* of) {
78 // The first entry in the GOT is the address of the .dynamic section.
79 gold_assert(this->data_size() >= size / 8);
80 Output_section* dynamic = this->layout_->dynamic_section();
81 Valtype dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
82 this->replace_constant(0, dynamic_addr);
83 Output_data_got<size, big_endian>::do_write(of);
84 }
85
86 private:
87 // A pointer to the Layout class, so that we can find the .dynamic
88 // section when we write out the GOT section.
89 Layout* layout_;
90};
91
92// The aarch64 target class.
93// See the ABI at
94// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
95template<int size, bool big_endian>
96class Target_aarch64 : public Sized_target<size, big_endian>
97{
98 public:
99 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
100 Reloc_section;
101 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
102
103 Target_aarch64(const Target::Target_info* info = &aarch64_info)
104 : Sized_target<size, big_endian>(info),
105 got_(NULL), plt_(NULL), got_plt_(NULL),
106 global_offset_table_(NULL), rela_dyn_(NULL),
107 copy_relocs_(elfcpp::R_AARCH64_COPY)
108 { }
109
110 // Scan the relocations to determine unreferenced sections for
111 // garbage collection.
112 void
113 gc_process_relocs(Symbol_table* symtab,
114 Layout* layout,
115 Sized_relobj_file<size, big_endian>* object,
116 unsigned int data_shndx,
117 unsigned int sh_type,
118 const unsigned char* prelocs,
119 size_t reloc_count,
120 Output_section* output_section,
121 bool needs_special_offset_handling,
122 size_t local_symbol_count,
123 const unsigned char* plocal_symbols);
124
125 // Scan the relocations to look for symbol adjustments.
126 void
127 scan_relocs(Symbol_table* symtab,
128 Layout* layout,
129 Sized_relobj_file<size, big_endian>* object,
130 unsigned int data_shndx,
131 unsigned int sh_type,
132 const unsigned char* prelocs,
133 size_t reloc_count,
134 Output_section* output_section,
135 bool needs_special_offset_handling,
136 size_t local_symbol_count,
137 const unsigned char* plocal_symbols);
138
139 // Finalize the sections.
140 void
141 do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
142
143 // Relocate a section.
144 void
145 relocate_section(const Relocate_info<size, big_endian>*,
146 unsigned int sh_type,
147 const unsigned char* prelocs,
148 size_t reloc_count,
149 Output_section* output_section,
150 bool needs_special_offset_handling,
151 unsigned char* view,
152 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
153 section_size_type view_size,
154 const Reloc_symbol_changes*);
155
156 // Scan the relocs during a relocatable link.
157 void
158 scan_relocatable_relocs(Symbol_table* symtab,
159 Layout* layout,
160 Sized_relobj_file<size, big_endian>* object,
161 unsigned int data_shndx,
162 unsigned int sh_type,
163 const unsigned char* prelocs,
164 size_t reloc_count,
165 Output_section* output_section,
166 bool needs_special_offset_handling,
167 size_t local_symbol_count,
168 const unsigned char* plocal_symbols,
169 Relocatable_relocs*);
170
171 // Relocate a section during a relocatable link.
172 void
173 relocate_relocs(
174 const Relocate_info<size, big_endian>*,
175 unsigned int sh_type,
176 const unsigned char* prelocs,
177 size_t reloc_count,
178 Output_section* output_section,
179 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
180 const Relocatable_relocs*,
181 unsigned char* view,
182 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
183 section_size_type view_size,
184 unsigned char* reloc_view,
185 section_size_type reloc_view_size);
186
187 // Return the number of entries in the PLT.
188 unsigned int
189 plt_entry_count() const;
190
191 //Return the offset of the first non-reserved PLT entry.
192 unsigned int
193 first_plt_entry_offset() const;
194
195 // Return the size of each PLT entry.
196 unsigned int
197 plt_entry_size() const;
198
199 private:
200 // The class which scans relocations.
201 class Scan
202 {
203 public:
204 Scan()
205 : issued_non_pic_error_(false)
206 { }
207
208 static inline int
209 get_reference_flags(unsigned int r_type);
210
211 inline void
212 local(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
213 Sized_relobj_file<size, big_endian>* object,
214 unsigned int data_shndx,
215 Output_section* output_section,
216 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
217 const elfcpp::Sym<size, big_endian>& lsym,
218 bool is_discarded);
219
220 inline void
221 global(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
222 Sized_relobj_file<size, big_endian>* object,
223 unsigned int data_shndx,
224 Output_section* output_section,
225 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
226 Symbol* gsym);
227
228 inline bool
229 local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
230 Target_aarch64<size, big_endian>* ,
231 Sized_relobj_file<size, big_endian>* ,
232 unsigned int ,
233 Output_section* ,
234 const elfcpp::Rela<size, big_endian>& ,
235 unsigned int r_type,
236 const elfcpp::Sym<size, big_endian>&);
237
238 inline bool
239 global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
240 Target_aarch64<size, big_endian>* ,
241 Sized_relobj_file<size, big_endian>* ,
242 unsigned int ,
243 Output_section* ,
244 const elfcpp::Rela<size, big_endian>& ,
245 unsigned int r_type,
246 Symbol* gsym);
247
248 private:
249 static void
250 unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
251 unsigned int r_type);
252
253 static void
254 unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
255 unsigned int r_type, Symbol*);
256
257 inline bool
258 possible_function_pointer_reloc(unsigned int r_type);
259
260 void
261 check_non_pic(Relobj*, unsigned int r_type);
262
263 // Whether we have issued an error about a non-PIC compilation.
264 bool issued_non_pic_error_;
265 };
266
267 // The class which implements relocation.
268 class Relocate
269 {
270 public:
271 Relocate()
272 { }
273
274 ~Relocate()
275 { }
276
277 // Do a relocation. Return false if the caller should not issue
278 // any warnings about this relocation.
279 inline bool
280 relocate(const Relocate_info<size, big_endian>*, Target_aarch64*,
281 Output_section*,
282 size_t relnum, const elfcpp::Rela<size, big_endian>&,
283 unsigned int r_type, const Sized_symbol<size>*,
284 const Symbol_value<size>*,
285 unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
286 section_size_type);
287
288 };
289
290 // A class which returns the size required for a relocation type,
291 // used while scanning relocs during a relocatable link.
292 class Relocatable_size_for_reloc
293 {
294 public:
295 unsigned int
296 get_size_for_reloc(unsigned int, Relobj*);
297 };
298
299 // Adjust TLS relocation type based on the options and whether this
300 // is a local symbol.
301 static tls::Tls_optimization
302 optimize_tls_reloc(bool is_final, int r_type);
303
304 // Get the GOT section, creating it if necessary.
305 Output_data_got_aarch64<size, big_endian>*
306 got_section(Symbol_table*, Layout*);
307
308 // Get the GOT PLT section.
309 Output_data_space*
310 got_plt_section() const
311 {
312 gold_assert(this->got_plt_ != NULL);
313 return this->got_plt_;
314 }
315
316 // Create the PLT section.
317 void
318 make_plt_section(Symbol_table* symtab, Layout* layout);
319
320 // Create a PLT entry for a global symbol.
321 void
322 make_plt_entry(Symbol_table*, Layout*, Symbol*);
323
324 // Get the PLT section.
325 Output_data_plt_aarch64<size, big_endian>*
326 plt_section() const
327 {
328 gold_assert(this->plt_ != NULL);
329 return this->plt_;
330 }
331
332 // Get the dynamic reloc section, creating it if necessary.
333 Reloc_section*
334 rela_dyn_section(Layout*);
335
336 // Add a potential copy relocation.
337 void
338 copy_reloc(Symbol_table* symtab, Layout* layout,
339 Sized_relobj_file<size, big_endian>* object,
340 unsigned int shndx, Output_section* output_section,
341 Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
342 {
343 this->copy_relocs_.copy_reloc(symtab, layout,
344 symtab->get_sized_symbol<size>(sym),
345 object, shndx, output_section,
346 reloc, this->rela_dyn_section(layout));
347 }
348
349 // Information about this specific target which we pass to the
350 // general Target structure.
351 static const Target::Target_info aarch64_info;
352
353 // The types of GOT entries needed for this platform.
354 // These values are exposed to the ABI in an incremental link.
355 // Do not renumber existing values without changing the version
356 // number of the .gnu_incremental_inputs section.
357 enum Got_type
358 {
359 GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
360 GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset
361 GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair
362 GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair
363 };
364
365 // The GOT section.
366 Output_data_got_aarch64<size, big_endian>* got_;
367 // The PLT section.
368 Output_data_plt_aarch64<size, big_endian>* plt_;
369 // The GOT PLT section.
370 Output_data_space* got_plt_;
371 // The _GLOBAL_OFFSET_TABLE_ symbol.
372 Symbol* global_offset_table_;
373 // The dynamic reloc section.
374 Reloc_section* rela_dyn_;
375 // Relocs saved to avoid a COPY reloc.
376 Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
377};
378
379template<>
380const Target::Target_info Target_aarch64<64, false>::aarch64_info =
381{
382 64, // size
383 false, // is_big_endian
384 elfcpp::EM_AARCH64, // machine_code
385 false, // has_make_symbol
386 false, // has_resolve
387 false, // has_code_fill
388 true, // is_default_stack_executable
389 false, // can_icf_inline_merge_sections
390 '\0', // wrap_char
391 "/lib/ld.so.1", // program interpreter
392 0x400000, // default_text_segment_address
393 0x1000, // abi_pagesize (overridable by -z max-page-size)
394 0x1000, // common_pagesize (overridable by -z common-page-size)
395 false, // isolate_execinstr
396 0, // rosegment_gap
397 elfcpp::SHN_UNDEF, // small_common_shndx
398 elfcpp::SHN_UNDEF, // large_common_shndx
399 0, // small_common_section_flags
400 0, // large_common_section_flags
401 NULL, // attributes_section
402 NULL, // attributes_vendor
403 "_start" // entry_symbol_name
404};
405
406template<>
407const Target::Target_info Target_aarch64<32, false>::aarch64_info =
408{
409 32, // size
410 false, // is_big_endian
411 elfcpp::EM_AARCH64, // machine_code
412 false, // has_make_symbol
413 false, // has_resolve
414 false, // has_code_fill
415 true, // is_default_stack_executable
416 false, // can_icf_inline_merge_sections
417 '\0', // wrap_char
418 "/lib/ld.so.1", // program interpreter
419 0x400000, // default_text_segment_address
420 0x1000, // abi_pagesize (overridable by -z max-page-size)
421 0x1000, // common_pagesize (overridable by -z common-page-size)
422 false, // isolate_execinstr
423 0, // rosegment_gap
424 elfcpp::SHN_UNDEF, // small_common_shndx
425 elfcpp::SHN_UNDEF, // large_common_shndx
426 0, // small_common_section_flags
427 0, // large_common_section_flags
428 NULL, // attributes_section
429 NULL, // attributes_vendor
430 "_start" // entry_symbol_name
431};
432
433template<>
434const Target::Target_info Target_aarch64<64, true>::aarch64_info =
435{
436 64, // size
437 true, // is_big_endian
438 elfcpp::EM_AARCH64, // machine_code
439 false, // has_make_symbol
440 false, // has_resolve
441 false, // has_code_fill
442 true, // is_default_stack_executable
443 false, // can_icf_inline_merge_sections
444 '\0', // wrap_char
445 "/lib/ld.so.1", // program interpreter
446 0x400000, // default_text_segment_address
447 0x1000, // abi_pagesize (overridable by -z max-page-size)
448 0x1000, // common_pagesize (overridable by -z common-page-size)
449 false, // isolate_execinstr
450 0, // rosegment_gap
451 elfcpp::SHN_UNDEF, // small_common_shndx
452 elfcpp::SHN_UNDEF, // large_common_shndx
453 0, // small_common_section_flags
454 0, // large_common_section_flags
455 NULL, // attributes_section
456 NULL, // attributes_vendor
457 "_start" // entry_symbol_name
458};
459
460template<>
461const Target::Target_info Target_aarch64<32, true>::aarch64_info =
462{
463 32, // size
464 true, // is_big_endian
465 elfcpp::EM_AARCH64, // machine_code
466 false, // has_make_symbol
467 false, // has_resolve
468 false, // has_code_fill
469 true, // is_default_stack_executable
470 false, // can_icf_inline_merge_sections
471 '\0', // wrap_char
472 "/lib/ld.so.1", // program interpreter
473 0x400000, // default_text_segment_address
474 0x1000, // abi_pagesize (overridable by -z max-page-size)
475 0x1000, // common_pagesize (overridable by -z common-page-size)
476 false, // isolate_execinstr
477 0, // rosegment_gap
478 elfcpp::SHN_UNDEF, // small_common_shndx
479 elfcpp::SHN_UNDEF, // large_common_shndx
480 0, // small_common_section_flags
481 0, // large_common_section_flags
482 NULL, // attributes_section
483 NULL, // attributes_vendor
484 "_start" // entry_symbol_name
485};
486
487// Get the GOT section, creating it if necessary.
488
489template<int size, bool big_endian>
490Output_data_got_aarch64<size, big_endian>*
491Target_aarch64<size, big_endian>::got_section(Symbol_table* symtab,
492 Layout* layout)
493{
494 if (this->got_ == NULL)
495 {
496 gold_assert(symtab != NULL && layout != NULL);
497
498 // When using -z now, we can treat .got.plt as a relro section.
499 // Without -z now, it is modified after program startup by lazy
500 // PLT relocations.
501 bool is_got_plt_relro = parameters->options().now();
502 Output_section_order got_order = (is_got_plt_relro
503 ? ORDER_RELRO
504 : ORDER_RELRO_LAST);
505 Output_section_order got_plt_order = (is_got_plt_relro
506 ? ORDER_RELRO
507 : ORDER_NON_RELRO_FIRST);
508
509 // Layout of .got and .got.plt sections.
510 // .got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
511 // ...
512 // .gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
513 // .gotplt[1] reserved for ld.so (resolver)
514 // .gotplt[2] reserved
515
516 // Generate .got section.
517 this->got_ = new Output_data_got_aarch64<size, big_endian>(symtab,
518 layout);
519 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
520 (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
521 this->got_, got_order, true);
522 // The first word of GOT is reserved for the address of .dynamic.
523 // We put 0 here now. The value will be replaced later in
524 // Output_data_got_aarch64::do_write.
525 this->got_->add_constant(0);
526
527 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
528 // _GLOBAL_OFFSET_TABLE_ value points to the start of the .got section,
529 // even if there is a .got.plt section.
530 this->global_offset_table_ =
531 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
532 Symbol_table::PREDEFINED,
533 this->got_,
534 0, 0, elfcpp::STT_OBJECT,
535 elfcpp::STB_LOCAL,
536 elfcpp::STV_HIDDEN, 0,
537 false, false);
538
539 // Generate .got.plt section.
540 this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT");
541 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
542 (elfcpp::SHF_ALLOC
543 | elfcpp::SHF_WRITE),
544 this->got_plt_, got_plt_order,
545 is_got_plt_relro);
546
547 // The first three entries are reserved.
548 this->got_plt_->set_current_data_size
549 (AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
550
551 if (!is_got_plt_relro)
552 {
553 // Those bytes can go into the relro segment.
554 layout->increase_relro
555 (AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
556 }
557
558 }
559 return this->got_;
560}
561
562// Get the dynamic reloc section, creating it if necessary.
563
564template<int size, bool big_endian>
565typename Target_aarch64<size, big_endian>::Reloc_section*
566Target_aarch64<size, big_endian>::rela_dyn_section(Layout* layout)
567{
568 if (this->rela_dyn_ == NULL)
569 {
570 gold_assert(layout != NULL);
571 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
572 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
573 elfcpp::SHF_ALLOC, this->rela_dyn_,
574 ORDER_DYNAMIC_RELOCS, false);
575 }
576 return this->rela_dyn_;
577}
578
579// A class to handle the PLT data.
580// This is an abstract base class that handles most of the linker details
581// but does not know the actual contents of PLT entries. The derived
582// classes below fill in those details.
583
584template<int size, bool big_endian>
585class Output_data_plt_aarch64 : public Output_section_data
586{
587 public:
588 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
589 Reloc_section;
590 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
591
592 Output_data_plt_aarch64(Layout* layout,
593 uint64_t addralign,
594 Output_data_space* got_plt)
595 : Output_section_data(addralign),
596 got_plt_(got_plt),
597 count_(0)
598 { this->init(layout); }
599
600 // Initialize the PLT section.
601 void
602 init(Layout* layout);
603
604 // Add an entry to the PLT.
605 void
606 add_entry(Symbol* gsym);
607
608 // Return the .rela.plt section data.
609 Reloc_section*
610 rela_plt()
611 { return this->rel_; }
612
613 // Return the number of PLT entries.
614 unsigned int
615 entry_count() const
616 { return this->count_; }
617
618 // Return the offset of the first non-reserved PLT entry.
619 unsigned int
620 first_plt_entry_offset()
621 { return this->do_first_plt_entry_offset(); }
622
623 // Return the size of a PLT entry.
624 unsigned int
625 get_plt_entry_size() const
626 { return this->do_get_plt_entry_size(); }
627
628 protected:
629 // Fill in the first PLT entry.
630 void
631 fill_first_plt_entry(unsigned char* pov,
632 Address got_address,
633 Address plt_address)
634 { this->do_fill_first_plt_entry(pov, got_address, plt_address); }
635
636 // Fill in a normal PLT entry.
637 void
638 fill_plt_entry(unsigned char* pov,
639 Address got_address,
640 Address plt_address,
641 unsigned int got_offset,
642 unsigned int plt_offset)
643 {
644 this->do_fill_plt_entry(pov, got_address, plt_address,
645 got_offset, plt_offset);
646 }
647
648 virtual unsigned int
649 do_first_plt_entry_offset() const = 0;
650
651 virtual unsigned int
652 do_get_plt_entry_size() const = 0;
653
654 virtual void
655 do_fill_first_plt_entry(unsigned char* pov,
656 Address got_addr,
657 Address plt_addr) = 0;
658
659 virtual void
660 do_fill_plt_entry(unsigned char* pov,
661 Address got_address,
662 Address plt_address,
663 unsigned int got_offset,
664 unsigned int plt_offset) = 0;
665
666 void
667 do_adjust_output_section(Output_section* os);
668
669 // Write to a map file.
670 void
671 do_print_to_mapfile(Mapfile* mapfile) const
672 { mapfile->print_output_data(this, _("** PLT")); }
673
674 private:
675 // Set the final size.
676 void
677 set_final_data_size();
678
679 // Write out the PLT data.
680 void
681 do_write(Output_file*);
682
683 // The reloc section.
684 Reloc_section* rel_;
685 // The .got section.
686 Output_data_got_aarch64<size, big_endian>* got_;
687 // The .got.plt section.
688 Output_data_space* got_plt_;
689 // The number of PLT entries.
690 unsigned int count_;
691};
692
693// Initialize the PLT section.
694
695template<int size, bool big_endian>
696void
697Output_data_plt_aarch64<size, big_endian>::init(Layout* layout)
698{
699 this->rel_ = new Reloc_section(false);
700 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
701 elfcpp::SHF_ALLOC, this->rel_,
702 ORDER_DYNAMIC_PLT_RELOCS, false);
703}
704
705template<int size, bool big_endian>
706void
707Output_data_plt_aarch64<size, big_endian>::do_adjust_output_section(
708 Output_section* os)
709{
710 os->set_entsize(this->get_plt_entry_size());
711}
712
713// Add an entry to the PLT.
714
715template<int size, bool big_endian>
716void
717Output_data_plt_aarch64<size, big_endian>::add_entry(Symbol* gsym)
718{
719 gold_assert(!gsym->has_plt_offset());
720 //TODO
721}
722
723// Set the final size.
724template<int size, bool big_endian>
725void
726Output_data_plt_aarch64<size, big_endian>::set_final_data_size()
727{
728 this->set_data_size(this->first_plt_entry_offset()
729 + this->count * this->get_plt_entry_size());
730}
731
732template<int size, bool big_endian>
733class Output_data_plt_aarch64_standard :
734 public Output_data_plt_aarch64<size, big_endian>
735{
736 public:
737 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
738 Output_data_plt_aarch64_standard(Layout* layout, Output_data_space* got_plt)
739 : Output_data_plt_aarch64<size, big_endian>(layout,
740 size == 32 ? 4 : 8,
741 got_plt)
742 { }
743
744 protected:
745 // Return the offset of the first non-reserved PLT entry.
746 virtual unsigned int
747 do_first_plt_entry_offset() const
748 { return this->first_plt_entry_size; }
749
750 // Return the size of a PLT entry
751 virtual unsigned int
752 do_get_plt_entry_size() const
753 { return this->plt_entry_size; }
754
755 virtual void
756 do_fill_first_plt_entry(unsigned char* pov,
757 Address got_address,
758 Address plt_address);
759
760 virtual void
761 do_fill_plt_entry(unsigned char* pov,
762 Address got_address,
763 Address plt_address,
764 unsigned int got_offset,
765 unsigned int plt_offset);
766
767 private:
768 // The size of the first plt entry size.
769 static const int first_plt_entry_size = 32;
770 // The size of the plt entry size.
771 static const int plt_entry_size = 16;
772 // Template for the first PLT entry.
773 static const uint32_t first_plt_entry[first_plt_entry_size / 4];
774 // Template for subsequent PLT entries.
775 static const uint32_t plt_entry[plt_entry_size / 4];
776};
777
778// The first entry in the PLT for an executable.
779
780template<>
781const uint32_t
782Output_data_plt_aarch64_standard<32, false>::
783 first_plt_entry[first_plt_entry_size / 4] =
784{
785 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
786 0x90000010, /* adrp x16, PLT_GOT+0x8 */
787 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
788 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
789 0xd61f0220, /* br x17 */
790 0xd503201f, /* nop */
791 0xd503201f, /* nop */
792 0xd503201f, /* nop */
793};
794
795template<>
796const uint32_t
797Output_data_plt_aarch64_standard<32, true>::
798 first_plt_entry[first_plt_entry_size / 4] =
799{
800 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
801 0x90000010, /* adrp x16, PLT_GOT+0x8 */
802 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
803 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
804 0xd61f0220, /* br x17 */
805 0xd503201f, /* nop */
806 0xd503201f, /* nop */
807 0xd503201f, /* nop */
808};
809
810template<>
811const uint32_t
812Output_data_plt_aarch64_standard<64, false>::
813 first_plt_entry[first_plt_entry_size / 4] =
814{
815 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
816 0x90000010, /* adrp x16, PLT_GOT+16 */
817 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
818 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
819 0xd61f0220, /* br x17 */
820 0xd503201f, /* nop */
821 0xd503201f, /* nop */
822 0xd503201f, /* nop */
823};
824
825template<>
826const uint32_t
827Output_data_plt_aarch64_standard<64, true>::
828 first_plt_entry[first_plt_entry_size / 4] =
829{
830 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
831 0x90000010, /* adrp x16, PLT_GOT+16 */
832 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
833 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
834 0xd61f0220, /* br x17 */
835 0xd503201f, /* nop */
836 0xd503201f, /* nop */
837 0xd503201f, /* nop */
838};
839
840template<>
841const uint32_t
842Output_data_plt_aarch64_standard<32, false>::
843 plt_entry[plt_entry_size / 4] =
844{
845 0x90000010, /* adrp x16, PLTGOT + n * 4 */
846 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
847 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
848 0xd61f0220, /* br x17. */
849};
850
851template<>
852const uint32_t
853Output_data_plt_aarch64_standard<32, true>::
854 plt_entry[plt_entry_size / 4] =
855{
856 0x90000010, /* adrp x16, PLTGOT + n * 4 */
857 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
858 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
859 0xd61f0220, /* br x17. */
860};
861
862template<>
863const uint32_t
864Output_data_plt_aarch64_standard<64, false>::
865 plt_entry[plt_entry_size / 4] =
866{
867 0x90000010, /* adrp x16, PLTGOT + n * 8 */
868 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
869 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
870 0xd61f0220, /* br x17. */
871};
872
873template<>
874const uint32_t
875Output_data_plt_aarch64_standard<64, true>::
876 plt_entry[plt_entry_size / 4] =
877{
878 0x90000010, /* adrp x16, PLTGOT + n * 8 */
879 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
880 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
881 0xd61f0220, /* br x17. */
882};
883
884template<int size, bool big_endian>
885void
886Output_data_plt_aarch64_standard<size, big_endian>::do_fill_first_plt_entry(
887 unsigned char* pov,
888 Address /* got_address */,
889 Address /* plt_address */)
890{
891 // PLT0 of the small PLT looks like this in ELF64 -
892 // stp x16, x30, [sp, #-16]! Save the reloc and lr on stack.
893 // adrp x16, PLT_GOT + 16 Get the page base of the GOTPLT
894 // ldr x17, [x16, #:lo12:PLT_GOT+16] Load the address of the
895 // symbol resolver
896 // add x16, x16, #:lo12:PLT_GOT+16 Load the lo12 bits of the
897 // GOTPLT entry for this.
898 // br x17
899 // PLT0 will be slightly different in ELF32 due to different got entry
900 // size.
901 memcpy(pov, this->first_plt_entry, this->first_plt_entry_size);
902 // TODO
903}
904
905// Subsequent entries in the PLT for an executable.
906
907template<int size, bool big_endian>
908void
909Output_data_plt_aarch64_standard<size, big_endian>::do_fill_plt_entry(
910 unsigned char* pov,
911 Address /* got_address*/,
912 Address /* plt_address */,
913 unsigned int /* got_offset */,
914 unsigned int /* plt_offset */)
915{
916 memcpy(pov, this->plt_entry, this->plt_entry_size);
917 //TODO
918}
919
920// Write out the PLT. This uses the hand-coded instructions above,
921// and adjusts them as needed. This is specified by the AMD64 ABI.
922
923template<int size, bool big_endian>
924void
925Output_data_plt_aarch64<size, big_endian>::do_write(Output_file* of)
926{
927 const off_t offset = this->offset();
928 const section_size_type oview_size =
929 convert_to_section_size_type(this->data_size());
930 unsigned char* const oview = of->get_output_view(offset, oview_size);
931
932 const off_t got_file_offset = this->got_plt_->offset();
933 const section_size_type got_size =
934 convert_to_section_size_type(this->got_plt_->data_size());
935 unsigned char* const got_view = of->get_output_view(got_file_offset,
936 got_size);
937
938 unsigned char* pov = oview;
939
940 // The base address of the .plt section.
941 typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
942 // The base address of the .got section.
943 typename elfcpp::Elf_types<size>::Elf_Addr got_base = this->got_->address();
944 // The base address of the PLT portion of the .got section.
945 typename elfcpp::Elf_types<size>::Elf_Addr got_address
946 = this->got_plt_->address();
947
948 this->fill_first_plt_entry(pov, got_address, plt_address);
949 pov += this->first_plt_entry_offset();
950
951 // The first three entries in .got.plt are reserved.
952 unsigned char* got_pov = got_view;
953 memset(got_pov, 0, size / 8 * AARCH64_GOTPLT_RESERVE_COUNT);
954 got_pov += (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
955
956 unsigned int plt_offset = this->first_plt_entry_offset();
957 unsigned int got_offset = (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
958 const unsigned int count = this->count_;
959 for (unsigned int plt_index = 0;
960 plt_index < count;
961 ++plt_index,
962 pov += this->get_plt_entry_size(),
963 got_pov += size / 8,
964 plt_offset += this->get_plt_entry_size(),
965 got_offset += size / 8)
966 {
967 // Set and adjust the PLT entry itself.
968 this->fill_plt_entry(pov, got_address, plt_address,
969 got_offset, plt_offset);
970
971 // Set the entry in the GOT.
972 elfcpp::Swap<size, big_endian>::writeval(got_pov,
973 plt_address + plt_offset);
974 }
975
976 gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
977 gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
978
979 of->write_output_view(offset, oview_size, oview);
980 of->write_output_view(got_file_offset, got_size, got_view);
981}
982
983// Return the number of entries in the PLT.
984
985template<int size, bool big_endian>
986unsigned int
987Target_aarch64<size, big_endian>::plt_entry_count() const
988{
989 if (this->plt_ == NULL)
990 return 0;
991 return this->plt_->entry_count();
992}
993
994// Return the offset of the first non-reserved PLT entry.
995
996template<int size, bool big_endian>
997unsigned int
998Target_aarch64<size, big_endian>::first_plt_entry_offset() const
999{
1000 return this->plt_->first_plt_entry_offset();
1001}
1002
1003// Return the size of each PLT entry.
1004
1005template<int size, bool big_endian>
1006unsigned int
1007Target_aarch64<size, big_endian>::plt_entry_size() const
1008{
1009 return this->plt_->get_plt_entry_size();
1010}
1011
1012// Optimize the TLS relocation type based on what we know about the
1013// symbol. IS_FINAL is true if the final address of this symbol is
1014// known at link time.
1015
1016template<int size, bool big_endian>
1017tls::Tls_optimization
1018Target_aarch64<size, big_endian>::optimize_tls_reloc(bool /* is_final */,
1019 int /* r_type */)
1020{
1021 //TODO
1022 return tls::TLSOPT_NONE;
1023}
1024
1025// Get the Reference_flags for a particular relocation.
1026template<int size, bool big_endian>
1027int
1028Target_aarch64<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
1029{
1030 switch (r_type)
1031 {
1032 case elfcpp::R_AARCH64_NONE:
1033 // No symbol reference.
1034 return 0;
1035 //TODO
1036 default:
1037 // Not expected. We will give an error later.
1038 return 0;
1039 }
1040}
1041
1042// Returns true if this relocation type could be that of a function pointer.
1043
1044template<int size, bool big_endian>
1045inline bool
1046Target_aarch64<size, big_endian>::Scan::possible_function_pointer_reloc(
1047 unsigned int r_type)
1048{
1049 switch (r_type)
1050 {
1051 case elfcpp::R_AARCH64_ABS64:
1052 //TODO
1053 {
1054 return true;
1055 }
1056 }
1057 return false;
1058}
1059
1060// For safe ICF, scan a relocation for a local symbol to check if it
1061// corresponds to a function pointer being taken. In that case mark
1062// the function whose pointer was taken as not foldable.
1063
1064template<int size, bool big_endian>
1065inline bool
1066Target_aarch64<size, big_endian>::Scan::local_reloc_may_be_function_pointer(
1067 Symbol_table* ,
1068 Layout* ,
1069 Target_aarch64<size, big_endian>* ,
1070 Sized_relobj_file<size, big_endian>* ,
1071 unsigned int ,
1072 Output_section* ,
1073 const elfcpp::Rela<size, big_endian>& ,
1074 unsigned int r_type,
1075 const elfcpp::Sym<size, big_endian>&)
1076{
1077 // When building a shared library, do not fold any local symbols as it is
1078 // not possible to distinguish pointer taken versus a call by looking at
1079 // the relocation types.
1080 return (parameters->options().shared()
1081 || possible_function_pointer_reloc(r_type));
1082}
1083
1084// For safe ICF, scan a relocation for a global symbol to check if it
1085// corresponds to a function pointer being taken. In that case mark
1086// the function whose pointer was taken as not foldable.
1087
1088template<int size, bool big_endian>
1089inline bool
1090Target_aarch64<size, big_endian>::Scan::global_reloc_may_be_function_pointer(
1091 Symbol_table* ,
1092 Layout* ,
1093 Target_aarch64<size, big_endian>* ,
1094 Sized_relobj_file<size, big_endian>* ,
1095 unsigned int ,
1096 Output_section* ,
1097 const elfcpp::Rela<size, big_endian>& ,
1098 unsigned int r_type,
1099 Symbol* gsym)
1100{
1101 // When building a shared library, do not fold symbols whose visibility
1102 // is hidden, internal or protected.
1103 return ((parameters->options().shared()
1104 && (gsym->visibility() == elfcpp::STV_INTERNAL
1105 || gsym->visibility() == elfcpp::STV_PROTECTED
1106 || gsym->visibility() == elfcpp::STV_HIDDEN))
1107 || possible_function_pointer_reloc(r_type));
1108}
1109
1110// Report an unsupported relocation against a local symbol.
1111
1112template<int size, bool big_endian>
1113void
1114Target_aarch64<size, big_endian>::Scan::unsupported_reloc_local(
1115 Sized_relobj_file<size, big_endian>* object,
1116 unsigned int r_type)
1117{
1118 gold_error(_("%s: unsupported reloc %u against local symbol"),
1119 object->name().c_str(), r_type);
1120}
1121
1122// We are about to emit a dynamic relocation of type R_TYPE. If the
1123// dynamic linker does not support it, issue an error.
1124
1125template<int size, bool big_endian>
1126void
1127Target_aarch64<size, big_endian>::Scan::check_non_pic(Relobj* object,
1128 unsigned int r_type)
1129{
1130 gold_assert(r_type != elfcpp::R_AARCH64_NONE);
1131
1132 switch (r_type)
1133 {
1134 // These are the relocation types supported by glibc for AARCH64.
1135 case elfcpp::R_AARCH64_NONE:
1136 case elfcpp::R_AARCH64_COPY:
1137 case elfcpp::R_AARCH64_GLOB_DAT:
1138 case elfcpp::R_AARCH64_JUMP_SLOT:
1139 case elfcpp::R_AARCH64_RELATIVE:
1140 case elfcpp::R_AARCH64_TLS_DTPREL64:
1141 case elfcpp::R_AARCH64_TLS_DTPMOD64:
1142 case elfcpp::R_AARCH64_TLS_TPREL64:
1143 case elfcpp::R_AARCH64_TLSDESC:
1144 case elfcpp::R_AARCH64_IRELATIVE:
1145 case elfcpp::R_AARCH64_ABS32:
1146 case elfcpp::R_AARCH64_ABS64:
1147 return;
1148
1149 default:
1150 break;
1151 }
1152
1153 // This prevents us from issuing more than one error per reloc
1154 // section. But we can still wind up issuing more than one
1155 // error per object file.
1156 if (this->issued_non_pic_error_)
1157 return;
1158 gold_assert(parameters->options().output_is_position_independent());
1159 object->error(_("requires unsupported dynamic reloc; "
1160 "recompile with -fPIC"));
1161 this->issued_non_pic_error_ = true;
1162 return;
1163}
1164
1165// Scan a relocation for a local symbol.
1166
1167template<int size, bool big_endian>
1168inline void
1169Target_aarch64<size, big_endian>::Scan::local(
1170 Symbol_table* /* symtab */,
1171 Layout* /* layout */,
1172 Target_aarch64<size, big_endian>* /* target */,
1173 Sized_relobj_file<size, big_endian>* /* object */,
1174 unsigned int /* data_shndx */,
1175 Output_section* /* output_section */,
1176 const elfcpp::Rela<size, big_endian>& /* reloc */,
1177 unsigned int r_type,
1178 const elfcpp::Sym<size, big_endian>& /* lsym */,
1179 bool is_discarded)
1180{
1181 if (is_discarded)
1182 return;
1183
1184 switch (r_type)
1185 {
1186 case elfcpp::R_AARCH64_NONE:
1187 break;
1188
1189 //TODO
1190 }
1191}
1192
1193
1194// Report an unsupported relocation against a global symbol.
1195
1196template<int size, bool big_endian>
1197void
1198Target_aarch64<size, big_endian>::Scan::unsupported_reloc_global(
1199 Sized_relobj_file<size, big_endian>* object,
1200 unsigned int r_type,
1201 Symbol* gsym)
1202{
1203 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
1204 object->name().c_str(), r_type, gsym->demangled_name().c_str());
1205}
1206
1207template<int size, bool big_endian>
1208inline void
1209Target_aarch64<size, big_endian>::Scan::global(
1210 Symbol_table* /* symtab */,
1211 Layout* /* layout */,
1212 Target_aarch64<size, big_endian>* /* target */,
1213 Sized_relobj_file<size, big_endian>* /* object */,
1214 unsigned int /* data_shndx */,
1215 Output_section* /* output_section */,
1216 const elfcpp::Rela<size, big_endian>& /* reloc */,
1217 unsigned int /* r_type */,
1218 Symbol* /* gsym */)
1219{
1220 //TODO
1221 return;
1222}
1223
1224template<int size, bool big_endian>
1225void
1226Target_aarch64<size, big_endian>::gc_process_relocs(
1227 Symbol_table* symtab,
1228 Layout* layout,
1229 Sized_relobj_file<size, big_endian>* object,
1230 unsigned int data_shndx,
1231 unsigned int sh_type,
1232 const unsigned char* prelocs,
1233 size_t reloc_count,
1234 Output_section* output_section,
1235 bool needs_special_offset_handling,
1236 size_t local_symbol_count,
1237 const unsigned char* plocal_symbols)
1238{
1239 if (sh_type == elfcpp::SHT_REL)
1240 {
1241 return;
1242 }
1243
1244 gold::gc_process_relocs<size, big_endian,
1245 Target_aarch64<size, big_endian>,
1246 elfcpp::SHT_RELA,
1247 typename Target_aarch64<size, big_endian>::Scan,
1248 typename Target_aarch64<size, big_endian>::Relocatable_size_for_reloc>(
1249 symtab,
1250 layout,
1251 this,
1252 object,
1253 data_shndx,
1254 prelocs,
1255 reloc_count,
1256 output_section,
1257 needs_special_offset_handling,
1258 local_symbol_count,
1259 plocal_symbols);
1260}
1261
1262// Scan relocations for a section.
1263
1264template<int size, bool big_endian>
1265void
1266Target_aarch64<size, big_endian>::scan_relocs(
1267 Symbol_table* symtab,
1268 Layout* layout,
1269 Sized_relobj_file<size, big_endian>* object,
1270 unsigned int data_shndx,
1271 unsigned int sh_type,
1272 const unsigned char* prelocs,
1273 size_t reloc_count,
1274 Output_section* output_section,
1275 bool needs_special_offset_handling,
1276 size_t local_symbol_count,
1277 const unsigned char* plocal_symbols)
1278{
1279 if (sh_type == elfcpp::SHT_REL)
1280 {
1281 gold_error(_("%s: unsupported REL reloc section"),
1282 object->name().c_str());
1283 return;
1284 }
1285
1286 gold::scan_relocs<size, big_endian, Target_aarch64<size, big_endian>,
1287 elfcpp::SHT_RELA,
1288 typename Target_aarch64<size, big_endian>::Scan>(
1289 symtab,
1290 layout,
1291 this,
1292 object,
1293 data_shndx,
1294 prelocs,
1295 reloc_count,
1296 output_section,
1297 needs_special_offset_handling,
1298 local_symbol_count,
1299 plocal_symbols);
1300}
1301
1302// Finalize the sections.
1303
1304template<int size, bool big_endian>
1305void
1306Target_aarch64<size, big_endian>::do_finalize_sections(
1307 Layout* /* layout */,
1308 const Input_objects*,
1309 Symbol_table* /* symtab */)
1310{
1311 //TODO
1312 return;
1313}
1314
1315// Perform a relocation.
1316
1317template<int size, bool big_endian>
1318inline bool
1319Target_aarch64<size, big_endian>::Relocate::relocate(
1320 const Relocate_info<size, big_endian>* /* relinfo */,
1321 Target_aarch64<size, big_endian>* /* target */,
1322 Output_section* ,
1323 size_t /* relnum */,
1324 const elfcpp::Rela<size, big_endian>& /* rela */,
1325 unsigned int /* r_type */,
1326 const Sized_symbol<size>* /* gsym */,
1327 const Symbol_value<size>* /* psymval */,
1328 unsigned char* /* view */,
1329 typename elfcpp::Elf_types<size>::Elf_Addr /* address */,
1330 section_size_type /* view_size */)
1331{
1332 //TODO
1333 return true;
1334}
1335
1336// Relocate section data.
1337
1338template<int size, bool big_endian>
1339void
1340Target_aarch64<size, big_endian>::relocate_section(
1341 const Relocate_info<size, big_endian>* /* relinfo */,
1342 unsigned int sh_type,
1343 const unsigned char* /* prelocs */,
1344 size_t /* reloc_count */,
1345 Output_section* /* output_section */,
1346 bool /*needs_special_offset_handling */,
1347 unsigned char* /* view */,
1348 typename elfcpp::Elf_types<size>::Elf_Addr /* address */,
1349 section_size_type /* view_size */,
1350 const Reloc_symbol_changes* /* reloc_symbol_changes */)
1351{
1352 //TODO
1353 gold_assert(sh_type == elfcpp::SHT_RELA);
1354}
1355
1356// Return the size of a relocation while scanning during a relocatable
1357// link.
1358
1359template<int size, bool big_endian>
1360unsigned int
1361Target_aarch64<size, big_endian>::Relocatable_size_for_reloc::
1362get_size_for_reloc(
1363 unsigned int ,
1364 Relobj* )
1365{
1366 // We will never support SHT_REL relocations.
1367 gold_unreachable();
1368 return 0;
1369}
1370
1371// Scan the relocs during a relocatable link.
1372
1373template<int size, bool big_endian>
1374void
1375Target_aarch64<size, big_endian>::scan_relocatable_relocs(
1376 Symbol_table* /* symtab */,
1377 Layout* /* layout */,
1378 Sized_relobj_file<size, big_endian>* /* object */,
1379 unsigned int /* data_shndx */,
1380 unsigned int sh_type,
1381 const unsigned char* /* prelocs */,
1382 size_t /* reloc_count */,
1383 Output_section* /* output_section */,
1384 bool /* needs_special_offset_handling */,
1385 size_t /* local_symbol_count */,
1386 const unsigned char* /* plocal_symbols */,
1387 Relocatable_relocs* /* rr */)
1388{
1389 //TODO
1390 gold_assert(sh_type == elfcpp::SHT_RELA);
1391}
1392
1393// Relocate a section during a relocatable link.
1394
1395template<int size, bool big_endian>
1396void
1397Target_aarch64<size, big_endian>::relocate_relocs(
1398 const Relocate_info<size, big_endian>* /* relinfo */,
1399 unsigned int sh_type,
1400 const unsigned char* /* prelocs */,
1401 size_t /* reloc_count */,
1402 Output_section* /* output_section */,
1403 typename elfcpp::Elf_types<size>::Elf_Off /* offset_in_output_section */,
1404 const Relocatable_relocs* /* rr */,
1405 unsigned char* /* view */,
1406 typename elfcpp::Elf_types<size>::Elf_Addr /* view_address */,
1407 section_size_type /* view_size */,
1408 unsigned char* /* reloc_view */,
1409 section_size_type /* reloc_view_size */)
1410{
1411 //TODO
1412 gold_assert(sh_type == elfcpp::SHT_RELA);
1413}
1414
1415
1416// The selector for aarch64 object files.
1417
1418template<int size, bool big_endian>
1419class Target_selector_aarch64 : public Target_selector
1420{
1421 public:
1422 Target_selector_aarch64()
1423 : Target_selector(elfcpp::EM_AARCH64, size, big_endian,
1424 (size == 64
1425 ? (big_endian ? "elf64-bigaarch64"
1426 : "elf64-littleaarch64")
1427 : (big_endian ? "elf32-bigaarch64"
1428 : "elf32-littleaarch64")),
1429 (size == 64
1430 ? (big_endian ? "aarch64_elf64_be_vec"
1431 : "aarch64_elf64_le_vec")
1432 : (big_endian ? "aarch64_elf32_be_vec"
1433 : "aarch64_elf32_le_vec")))
1434 { }
1435
1436 virtual Target*
1437 do_instantiate_target()
1438 { return new Target_aarch64<size, big_endian>(); }
1439};
1440
1441Target_selector_aarch64<32, true> target_selector_aarch64elf32b;
1442Target_selector_aarch64<32, false> target_selector_aarch64elf32;
1443Target_selector_aarch64<64, true> target_selector_aarch64elfb;
1444Target_selector_aarch64<64, false> target_selector_aarch64elf;
1445
1446
1447} // End anonymous namespace.
This page took 0.08592 seconds and 4 git commands to generate.