]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gold/aarch64.cc
gold aarch64 patch to enable linking hello_wolrd.
[thirdparty/binutils-gdb.git] / gold / aarch64.cc
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> and Han Shen <shenhan@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 #include "aarch64-reloc-property.h"
46
47 // The first three .got.plt entries are reserved.
48 const int32_t AARCH64_GOTPLT_RESERVE_COUNT = 3;
49
50 namespace
51 {
52
53 using namespace gold;
54
55 template<int size, bool big_endian>
56 class Output_data_plt_aarch64;
57
58 template<int size, bool big_endian>
59 class Output_data_plt_aarch64_standard;
60
61 template<int size, bool big_endian>
62 class Target_aarch64;
63
64 template<int size, bool big_endian>
65 class AArch64_relocate_functions;
66
67 // Output_data_got_aarch64 class.
68
69 template<int size, bool big_endian>
70 class Output_data_got_aarch64 : public Output_data_got<size, big_endian>
71 {
72 public:
73 typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
74 Output_data_got_aarch64(Symbol_table* symtab, Layout* layout)
75 : Output_data_got<size, big_endian>(),
76 symbol_table_(symtab), layout_(layout)
77 { }
78
79 protected:
80 // Write out the GOT table.
81 void
82 do_write(Output_file* of) {
83 // The first entry in the GOT is the address of the .dynamic section.
84 gold_assert(this->data_size() >= size / 8);
85 Output_section* dynamic = this->layout_->dynamic_section();
86 Valtype dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
87 this->replace_constant(0, dynamic_addr);
88 Output_data_got<size, big_endian>::do_write(of);
89 }
90
91 private:
92 // Symbol table of the output object.
93 Symbol_table* symbol_table_;
94 // A pointer to the Layout class, so that we can find the .dynamic
95 // section when we write out the GOT section.
96 Layout* layout_;
97 };
98
99 AArch64_reloc_property_table* aarch64_reloc_property_table = NULL;
100
101 // The aarch64 target class.
102 // See the ABI at
103 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
104 template<int size, bool big_endian>
105 class Target_aarch64 : public Sized_target<size, big_endian>
106 {
107 public:
108 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
109 Reloc_section;
110 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
111
112 Target_aarch64(const Target::Target_info* info = &aarch64_info)
113 : Sized_target<size, big_endian>(info),
114 got_(NULL), plt_(NULL), got_plt_(NULL),
115 global_offset_table_(NULL), rela_dyn_(NULL),
116 copy_relocs_(elfcpp::R_AARCH64_COPY)
117 { }
118
119 // Scan the relocations to determine unreferenced sections for
120 // garbage collection.
121 void
122 gc_process_relocs(Symbol_table* symtab,
123 Layout* layout,
124 Sized_relobj_file<size, big_endian>* object,
125 unsigned int data_shndx,
126 unsigned int sh_type,
127 const unsigned char* prelocs,
128 size_t reloc_count,
129 Output_section* output_section,
130 bool needs_special_offset_handling,
131 size_t local_symbol_count,
132 const unsigned char* plocal_symbols);
133
134 // Scan the relocations to look for symbol adjustments.
135 void
136 scan_relocs(Symbol_table* symtab,
137 Layout* layout,
138 Sized_relobj_file<size, big_endian>* object,
139 unsigned int data_shndx,
140 unsigned int sh_type,
141 const unsigned char* prelocs,
142 size_t reloc_count,
143 Output_section* output_section,
144 bool needs_special_offset_handling,
145 size_t local_symbol_count,
146 const unsigned char* plocal_symbols);
147
148 // Finalize the sections.
149 void
150 do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
151
152 // Relocate a section.
153 void
154 relocate_section(const Relocate_info<size, big_endian>*,
155 unsigned int sh_type,
156 const unsigned char* prelocs,
157 size_t reloc_count,
158 Output_section* output_section,
159 bool needs_special_offset_handling,
160 unsigned char* view,
161 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
162 section_size_type view_size,
163 const Reloc_symbol_changes*);
164
165 // Scan the relocs during a relocatable link.
166 void
167 scan_relocatable_relocs(Symbol_table* symtab,
168 Layout* layout,
169 Sized_relobj_file<size, big_endian>* object,
170 unsigned int data_shndx,
171 unsigned int sh_type,
172 const unsigned char* prelocs,
173 size_t reloc_count,
174 Output_section* output_section,
175 bool needs_special_offset_handling,
176 size_t local_symbol_count,
177 const unsigned char* plocal_symbols,
178 Relocatable_relocs*);
179
180 // Relocate a section during a relocatable link.
181 void
182 relocate_relocs(
183 const Relocate_info<size, big_endian>*,
184 unsigned int sh_type,
185 const unsigned char* prelocs,
186 size_t reloc_count,
187 Output_section* output_section,
188 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
189 const Relocatable_relocs*,
190 unsigned char* view,
191 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
192 section_size_type view_size,
193 unsigned char* reloc_view,
194 section_size_type reloc_view_size);
195
196 // Return the PLT section.
197 uint64_t
198 do_plt_address_for_global(const Symbol* gsym) const
199 { return this->plt_section()->address_for_global(gsym); }
200
201 uint64_t
202 do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
203 { return this->plt_section()->address_for_local(relobj, symndx); }
204
205 // Return the number of entries in the PLT.
206 unsigned int
207 plt_entry_count() const;
208
209 //Return the offset of the first non-reserved PLT entry.
210 unsigned int
211 first_plt_entry_offset() const;
212
213 // Return the size of each PLT entry.
214 unsigned int
215 plt_entry_size() const;
216
217 protected:
218 void
219 do_select_as_default_target()
220 {
221 gold_assert(aarch64_reloc_property_table == NULL);
222 aarch64_reloc_property_table = new AArch64_reloc_property_table();
223 }
224
225 virtual Output_data_plt_aarch64<size, big_endian>*
226 do_make_data_plt(Layout* layout, Output_data_space* got_plt)
227 {
228 return new Output_data_plt_aarch64_standard<size, big_endian>(layout,
229 got_plt);
230 }
231
232 Output_data_plt_aarch64<size, big_endian>*
233 make_data_plt(Layout* layout, Output_data_space* got_plt)
234 {
235 return this->do_make_data_plt(layout, got_plt);
236 }
237
238 private:
239 // The class which scans relocations.
240 class Scan
241 {
242 public:
243 Scan()
244 : issued_non_pic_error_(false)
245 { }
246
247 inline void
248 local(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
249 Sized_relobj_file<size, big_endian>* object,
250 unsigned int data_shndx,
251 Output_section* output_section,
252 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
253 const elfcpp::Sym<size, big_endian>& lsym,
254 bool is_discarded);
255
256 inline void
257 global(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
258 Sized_relobj_file<size, big_endian>* object,
259 unsigned int data_shndx,
260 Output_section* output_section,
261 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
262 Symbol* gsym);
263
264 inline bool
265 local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
266 Target_aarch64<size, big_endian>* ,
267 Sized_relobj_file<size, big_endian>* ,
268 unsigned int ,
269 Output_section* ,
270 const elfcpp::Rela<size, big_endian>& ,
271 unsigned int r_type,
272 const elfcpp::Sym<size, big_endian>&);
273
274 inline bool
275 global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
276 Target_aarch64<size, big_endian>* ,
277 Sized_relobj_file<size, big_endian>* ,
278 unsigned int ,
279 Output_section* ,
280 const elfcpp::Rela<size, big_endian>& ,
281 unsigned int r_type,
282 Symbol* gsym);
283
284 private:
285 static void
286 unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
287 unsigned int r_type);
288
289 static void
290 unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
291 unsigned int r_type, Symbol*);
292
293 inline bool
294 possible_function_pointer_reloc(unsigned int r_type);
295
296 void
297 check_non_pic(Relobj*, unsigned int r_type);
298
299 // Whether we have issued an error about a non-PIC compilation.
300 bool issued_non_pic_error_;
301 };
302
303 // The class which implements relocation.
304 class Relocate
305 {
306 public:
307 Relocate()
308 { }
309
310 ~Relocate()
311 { }
312
313 // Do a relocation. Return false if the caller should not issue
314 // any warnings about this relocation.
315 inline bool
316 relocate(const Relocate_info<size, big_endian>*, Target_aarch64*,
317 Output_section*,
318 size_t relnum, const elfcpp::Rela<size, big_endian>&,
319 unsigned int r_type, const Sized_symbol<size>*,
320 const Symbol_value<size>*,
321 unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
322 section_size_type);
323
324 };
325
326 // A class which returns the size required for a relocation type,
327 // used while scanning relocs during a relocatable link.
328 class Relocatable_size_for_reloc
329 {
330 public:
331 unsigned int
332 get_size_for_reloc(unsigned int, Relobj*);
333 };
334
335 // Adjust TLS relocation type based on the options and whether this
336 // is a local symbol.
337 static tls::Tls_optimization
338 optimize_tls_reloc(bool is_final, int r_type);
339
340 // Get the GOT section, creating it if necessary.
341 Output_data_got_aarch64<size, big_endian>*
342 got_section(Symbol_table*, Layout*);
343
344 // Get the GOT PLT section.
345 Output_data_space*
346 got_plt_section() const
347 {
348 gold_assert(this->got_plt_ != NULL);
349 return this->got_plt_;
350 }
351
352 // Create the PLT section.
353 void
354 make_plt_section(Symbol_table* symtab, Layout* layout);
355
356 // Create a PLT entry for a global symbol.
357 void
358 make_plt_entry(Symbol_table*, Layout*, Symbol*);
359
360 // Get the PLT section.
361 Output_data_plt_aarch64<size, big_endian>*
362 plt_section() const
363 {
364 gold_assert(this->plt_ != NULL);
365 return this->plt_;
366 }
367
368 // Get the dynamic reloc section, creating it if necessary.
369 Reloc_section*
370 rela_dyn_section(Layout*);
371
372 // Add a potential copy relocation.
373 void
374 copy_reloc(Symbol_table* symtab, Layout* layout,
375 Sized_relobj_file<size, big_endian>* object,
376 unsigned int shndx, Output_section* output_section,
377 Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
378 {
379 this->copy_relocs_.copy_reloc(symtab, layout,
380 symtab->get_sized_symbol<size>(sym),
381 object, shndx, output_section,
382 reloc, this->rela_dyn_section(layout));
383 }
384
385 // Information about this specific target which we pass to the
386 // general Target structure.
387 static const Target::Target_info aarch64_info;
388
389 // The types of GOT entries needed for this platform.
390 // These values are exposed to the ABI in an incremental link.
391 // Do not renumber existing values without changing the version
392 // number of the .gnu_incremental_inputs section.
393 enum Got_type
394 {
395 GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
396 GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset
397 GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair
398 GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair
399 };
400
401 // The GOT section.
402 Output_data_got_aarch64<size, big_endian>* got_;
403 // The PLT section.
404 Output_data_plt_aarch64<size, big_endian>* plt_;
405 // The GOT PLT section.
406 Output_data_space* got_plt_;
407 // The _GLOBAL_OFFSET_TABLE_ symbol.
408 Symbol* global_offset_table_;
409 // The dynamic reloc section.
410 Reloc_section* rela_dyn_;
411 // Relocs saved to avoid a COPY reloc.
412 Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
413 };
414
415 template<>
416 const Target::Target_info Target_aarch64<64, false>::aarch64_info =
417 {
418 64, // size
419 false, // is_big_endian
420 elfcpp::EM_AARCH64, // machine_code
421 false, // has_make_symbol
422 false, // has_resolve
423 false, // has_code_fill
424 true, // is_default_stack_executable
425 false, // can_icf_inline_merge_sections
426 '\0', // wrap_char
427 "/lib/ld.so.1", // program interpreter
428 0x400000, // default_text_segment_address
429 0x1000, // abi_pagesize (overridable by -z max-page-size)
430 0x1000, // common_pagesize (overridable by -z common-page-size)
431 false, // isolate_execinstr
432 0, // rosegment_gap
433 elfcpp::SHN_UNDEF, // small_common_shndx
434 elfcpp::SHN_UNDEF, // large_common_shndx
435 0, // small_common_section_flags
436 0, // large_common_section_flags
437 NULL, // attributes_section
438 NULL, // attributes_vendor
439 "_start" // entry_symbol_name
440 };
441
442 template<>
443 const Target::Target_info Target_aarch64<32, false>::aarch64_info =
444 {
445 32, // size
446 false, // is_big_endian
447 elfcpp::EM_AARCH64, // machine_code
448 false, // has_make_symbol
449 false, // has_resolve
450 false, // has_code_fill
451 true, // is_default_stack_executable
452 false, // can_icf_inline_merge_sections
453 '\0', // wrap_char
454 "/lib/ld.so.1", // program interpreter
455 0x400000, // default_text_segment_address
456 0x1000, // abi_pagesize (overridable by -z max-page-size)
457 0x1000, // common_pagesize (overridable by -z common-page-size)
458 false, // isolate_execinstr
459 0, // rosegment_gap
460 elfcpp::SHN_UNDEF, // small_common_shndx
461 elfcpp::SHN_UNDEF, // large_common_shndx
462 0, // small_common_section_flags
463 0, // large_common_section_flags
464 NULL, // attributes_section
465 NULL, // attributes_vendor
466 "_start" // entry_symbol_name
467 };
468
469 template<>
470 const Target::Target_info Target_aarch64<64, true>::aarch64_info =
471 {
472 64, // size
473 true, // is_big_endian
474 elfcpp::EM_AARCH64, // machine_code
475 false, // has_make_symbol
476 false, // has_resolve
477 false, // has_code_fill
478 true, // is_default_stack_executable
479 false, // can_icf_inline_merge_sections
480 '\0', // wrap_char
481 "/lib/ld.so.1", // program interpreter
482 0x400000, // default_text_segment_address
483 0x1000, // abi_pagesize (overridable by -z max-page-size)
484 0x1000, // common_pagesize (overridable by -z common-page-size)
485 false, // isolate_execinstr
486 0, // rosegment_gap
487 elfcpp::SHN_UNDEF, // small_common_shndx
488 elfcpp::SHN_UNDEF, // large_common_shndx
489 0, // small_common_section_flags
490 0, // large_common_section_flags
491 NULL, // attributes_section
492 NULL, // attributes_vendor
493 "_start" // entry_symbol_name
494 };
495
496 template<>
497 const Target::Target_info Target_aarch64<32, true>::aarch64_info =
498 {
499 32, // size
500 true, // is_big_endian
501 elfcpp::EM_AARCH64, // machine_code
502 false, // has_make_symbol
503 false, // has_resolve
504 false, // has_code_fill
505 true, // is_default_stack_executable
506 false, // can_icf_inline_merge_sections
507 '\0', // wrap_char
508 "/lib/ld.so.1", // program interpreter
509 0x400000, // default_text_segment_address
510 0x1000, // abi_pagesize (overridable by -z max-page-size)
511 0x1000, // common_pagesize (overridable by -z common-page-size)
512 false, // isolate_execinstr
513 0, // rosegment_gap
514 elfcpp::SHN_UNDEF, // small_common_shndx
515 elfcpp::SHN_UNDEF, // large_common_shndx
516 0, // small_common_section_flags
517 0, // large_common_section_flags
518 NULL, // attributes_section
519 NULL, // attributes_vendor
520 "_start" // entry_symbol_name
521 };
522
523 // Get the GOT section, creating it if necessary.
524
525 template<int size, bool big_endian>
526 Output_data_got_aarch64<size, big_endian>*
527 Target_aarch64<size, big_endian>::got_section(Symbol_table* symtab,
528 Layout* layout)
529 {
530 if (this->got_ == NULL)
531 {
532 gold_assert(symtab != NULL && layout != NULL);
533
534 // When using -z now, we can treat .got.plt as a relro section.
535 // Without -z now, it is modified after program startup by lazy
536 // PLT relocations.
537 bool is_got_plt_relro = parameters->options().now();
538 Output_section_order got_order = (is_got_plt_relro
539 ? ORDER_RELRO
540 : ORDER_RELRO_LAST);
541 Output_section_order got_plt_order = (is_got_plt_relro
542 ? ORDER_RELRO
543 : ORDER_NON_RELRO_FIRST);
544
545 // Layout of .got and .got.plt sections.
546 // .got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
547 // ...
548 // .gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
549 // .gotplt[1] reserved for ld.so (resolver)
550 // .gotplt[2] reserved
551
552 // Generate .got section.
553 this->got_ = new Output_data_got_aarch64<size, big_endian>(symtab,
554 layout);
555 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
556 (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
557 this->got_, got_order, true);
558 // The first word of GOT is reserved for the address of .dynamic.
559 // We put 0 here now. The value will be replaced later in
560 // Output_data_got_aarch64::do_write.
561 this->got_->add_constant(0);
562
563 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
564 // _GLOBAL_OFFSET_TABLE_ value points to the start of the .got section,
565 // even if there is a .got.plt section.
566 this->global_offset_table_ =
567 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
568 Symbol_table::PREDEFINED,
569 this->got_,
570 0, 0, elfcpp::STT_OBJECT,
571 elfcpp::STB_LOCAL,
572 elfcpp::STV_HIDDEN, 0,
573 false, false);
574
575 // Generate .got.plt section.
576 this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT");
577 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
578 (elfcpp::SHF_ALLOC
579 | elfcpp::SHF_WRITE),
580 this->got_plt_, got_plt_order,
581 is_got_plt_relro);
582
583 // The first three entries are reserved.
584 this->got_plt_->set_current_data_size(
585 AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
586
587 if (!is_got_plt_relro)
588 {
589 // Those bytes can go into the relro segment.
590 layout->increase_relro(
591 AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
592 }
593
594 }
595 return this->got_;
596 }
597
598 // Get the dynamic reloc section, creating it if necessary.
599
600 template<int size, bool big_endian>
601 typename Target_aarch64<size, big_endian>::Reloc_section*
602 Target_aarch64<size, big_endian>::rela_dyn_section(Layout* layout)
603 {
604 if (this->rela_dyn_ == NULL)
605 {
606 gold_assert(layout != NULL);
607 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
608 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
609 elfcpp::SHF_ALLOC, this->rela_dyn_,
610 ORDER_DYNAMIC_RELOCS, false);
611 }
612 return this->rela_dyn_;
613 }
614
615 // A class to handle the PLT data.
616 // This is an abstract base class that handles most of the linker details
617 // but does not know the actual contents of PLT entries. The derived
618 // classes below fill in those details.
619
620 template<int size, bool big_endian>
621 class Output_data_plt_aarch64 : public Output_section_data
622 {
623 public:
624 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
625 Reloc_section;
626 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
627
628 Output_data_plt_aarch64(Layout* layout,
629 uint64_t addralign,
630 Output_data_space* got_plt)
631 : Output_section_data(addralign),
632 got_plt_(got_plt),
633 count_(0)
634 { this->init(layout); }
635
636 // Initialize the PLT section.
637 void
638 init(Layout* layout);
639
640 // Add an entry to the PLT.
641 void
642 add_entry(Symbol* gsym);
643
644 // Return the .rela.plt section data.
645 Reloc_section*
646 rela_plt()
647 { return this->rel_; }
648
649 // Return whether we created a section for IRELATIVE relocations.
650 bool
651 has_irelative_section() const
652 { return this->irelative_rel_ != NULL; }
653
654 // Return the number of PLT entries.
655 unsigned int
656 entry_count() const
657 { return this->count_; }
658
659 // Return the offset of the first non-reserved PLT entry.
660 unsigned int
661 first_plt_entry_offset()
662 { return this->do_first_plt_entry_offset(); }
663
664 // Return the size of a PLT entry.
665 unsigned int
666 get_plt_entry_size() const
667 { return this->do_get_plt_entry_size(); }
668
669 // Return the PLT address to use for a global symbol.
670 uint64_t
671 address_for_global(const Symbol*);
672
673 // Return the PLT address to use for a local symbol.
674 uint64_t
675 address_for_local(const Relobj*, unsigned int symndx);
676
677 protected:
678 // Fill in the first PLT entry.
679 void
680 fill_first_plt_entry(unsigned char* pov,
681 Address got_address,
682 Address plt_address)
683 { this->do_fill_first_plt_entry(pov, got_address, plt_address); }
684
685 // Fill in a normal PLT entry.
686 void
687 fill_plt_entry(unsigned char* pov,
688 Address got_address,
689 Address plt_address,
690 unsigned int got_offset,
691 unsigned int plt_offset)
692 {
693 this->do_fill_plt_entry(pov, got_address, plt_address,
694 got_offset, plt_offset);
695 }
696
697 virtual unsigned int
698 do_first_plt_entry_offset() const = 0;
699
700 virtual unsigned int
701 do_get_plt_entry_size() const = 0;
702
703 virtual void
704 do_fill_first_plt_entry(unsigned char* pov,
705 Address got_addr,
706 Address plt_addr) = 0;
707
708 virtual void
709 do_fill_plt_entry(unsigned char* pov,
710 Address got_address,
711 Address plt_address,
712 unsigned int got_offset,
713 unsigned int plt_offset) = 0;
714
715 void
716 do_adjust_output_section(Output_section* os);
717
718 // Write to a map file.
719 void
720 do_print_to_mapfile(Mapfile* mapfile) const
721 { mapfile->print_output_data(this, _("** PLT")); }
722
723 private:
724 // Set the final size.
725 void
726 set_final_data_size();
727
728 // Write out the PLT data.
729 void
730 do_write(Output_file*);
731
732 // The reloc section.
733 Reloc_section* rel_;
734 // The IRELATIVE relocs, if necessary. These must follow the
735 // regular PLT relocations.
736 Reloc_section* irelative_rel_;
737 // The .got section.
738 Output_data_got_aarch64<size, big_endian>* got_;
739 // The .got.plt section.
740 Output_data_space* got_plt_;
741 // The number of PLT entries.
742 unsigned int count_;
743 };
744
745 // Initialize the PLT section.
746
747 template<int size, bool big_endian>
748 void
749 Output_data_plt_aarch64<size, big_endian>::init(Layout* layout)
750 {
751 this->rel_ = new Reloc_section(false);
752 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
753 elfcpp::SHF_ALLOC, this->rel_,
754 ORDER_DYNAMIC_PLT_RELOCS, false);
755 }
756
757 template<int size, bool big_endian>
758 void
759 Output_data_plt_aarch64<size, big_endian>::do_adjust_output_section(
760 Output_section* os)
761 {
762 os->set_entsize(this->get_plt_entry_size());
763 }
764
765 // Add an entry to the PLT.
766
767 template<int size, bool big_endian>
768 void
769 Output_data_plt_aarch64<size, big_endian>::add_entry(Symbol* gsym)
770 {
771 gold_assert(!gsym->has_plt_offset());
772
773 gsym->set_plt_offset((this->count_) * this->get_plt_entry_size()
774 + this->first_plt_entry_offset());
775
776 ++this->count_;
777
778 section_offset_type got_offset = this->got_plt_->current_data_size();
779
780 // Every PLT entry needs a GOT entry which points back to the PLT
781 // entry (this will be changed by the dynamic linker, normally
782 // lazily when the function is called).
783 this->got_plt_->set_current_data_size(got_offset + size / 8);
784
785 // Every PLT entry needs a reloc.
786 gsym->set_needs_dynsym_entry();
787 this->rel_->add_global(gsym, elfcpp::R_AARCH64_JUMP_SLOT,
788 this->got_plt_, got_offset, 0);
789
790 // Note that we don't need to save the symbol. The contents of the
791 // PLT are independent of which symbols are used. The symbols only
792 // appear in the relocations.
793 }
794
795 // Return the PLT address to use for a global symbol.
796
797 template<int size, bool big_endian>
798 uint64_t
799 Output_data_plt_aarch64<size, big_endian>::address_for_global(
800 const Symbol* gsym)
801 {
802 uint64_t offset = 0;
803 if (gsym->type() == elfcpp::STT_GNU_IFUNC
804 && gsym->can_use_relative_reloc(false))
805 offset = (this->first_plt_entry_offset() +
806 this->count_ * this->get_plt_entry_size());
807 return this->address() + offset + gsym->plt_offset();
808 }
809
810 // Return the PLT address to use for a local symbol. These are always
811 // IRELATIVE relocs.
812
813 template<int size, bool big_endian>
814 uint64_t
815 Output_data_plt_aarch64<size, big_endian>::address_for_local(
816 const Relobj* object,
817 unsigned int r_sym)
818 {
819 return (this->address()
820 + this->first_plt_entry_offset()
821 + this->count_ * this->get_plt_entry_size()
822 + object->local_plt_offset(r_sym));
823 }
824
825 // Set the final size.
826
827 template<int size, bool big_endian>
828 void
829 Output_data_plt_aarch64<size, big_endian>::set_final_data_size()
830 {
831 this->set_data_size(this->first_plt_entry_offset()
832 + this->count_ * this->get_plt_entry_size());
833 }
834
835 template<int size, bool big_endian>
836 class Output_data_plt_aarch64_standard :
837 public Output_data_plt_aarch64<size, big_endian>
838 {
839 public:
840 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
841 Output_data_plt_aarch64_standard(Layout* layout, Output_data_space* got_plt)
842 : Output_data_plt_aarch64<size, big_endian>(layout,
843 size == 32 ? 4 : 8,
844 got_plt)
845 { }
846
847 protected:
848 // Return the offset of the first non-reserved PLT entry.
849 virtual unsigned int
850 do_first_plt_entry_offset() const
851 { return this->first_plt_entry_size; }
852
853 // Return the size of a PLT entry
854 virtual unsigned int
855 do_get_plt_entry_size() const
856 { return this->plt_entry_size; }
857
858 virtual void
859 do_fill_first_plt_entry(unsigned char* pov,
860 Address got_address,
861 Address plt_address);
862
863 virtual void
864 do_fill_plt_entry(unsigned char* pov,
865 Address got_address,
866 Address plt_address,
867 unsigned int got_offset,
868 unsigned int plt_offset);
869
870 private:
871 // The size of the first plt entry size.
872 static const int first_plt_entry_size = 32;
873 // The size of the plt entry size.
874 static const int plt_entry_size = 16;
875 // Template for the first PLT entry.
876 static const uint32_t first_plt_entry[first_plt_entry_size / 4];
877 // Template for subsequent PLT entries.
878 static const uint32_t plt_entry[plt_entry_size / 4];
879 };
880
881 // The first entry in the PLT for an executable.
882
883 template<>
884 const uint32_t
885 Output_data_plt_aarch64_standard<32, false>::
886 first_plt_entry[first_plt_entry_size / 4] =
887 {
888 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
889 0x90000010, /* adrp x16, PLT_GOT+0x8 */
890 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
891 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
892 0xd61f0220, /* br x17 */
893 0xd503201f, /* nop */
894 0xd503201f, /* nop */
895 0xd503201f, /* nop */
896 };
897
898 template<>
899 const uint32_t
900 Output_data_plt_aarch64_standard<32, true>::
901 first_plt_entry[first_plt_entry_size / 4] =
902 {
903 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
904 0x90000010, /* adrp x16, PLT_GOT+0x8 */
905 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
906 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
907 0xd61f0220, /* br x17 */
908 0xd503201f, /* nop */
909 0xd503201f, /* nop */
910 0xd503201f, /* nop */
911 };
912
913 template<>
914 const uint32_t
915 Output_data_plt_aarch64_standard<64, false>::
916 first_plt_entry[first_plt_entry_size / 4] =
917 {
918 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
919 0x90000010, /* adrp x16, PLT_GOT+16 */
920 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
921 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
922 0xd61f0220, /* br x17 */
923 0xd503201f, /* nop */
924 0xd503201f, /* nop */
925 0xd503201f, /* nop */
926 };
927
928 template<>
929 const uint32_t
930 Output_data_plt_aarch64_standard<64, true>::
931 first_plt_entry[first_plt_entry_size / 4] =
932 {
933 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
934 0x90000010, /* adrp x16, PLT_GOT+16 */
935 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
936 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
937 0xd61f0220, /* br x17 */
938 0xd503201f, /* nop */
939 0xd503201f, /* nop */
940 0xd503201f, /* nop */
941 };
942
943 template<>
944 const uint32_t
945 Output_data_plt_aarch64_standard<32, false>::
946 plt_entry[plt_entry_size / 4] =
947 {
948 0x90000010, /* adrp x16, PLTGOT + n * 4 */
949 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
950 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
951 0xd61f0220, /* br x17. */
952 };
953
954 template<>
955 const uint32_t
956 Output_data_plt_aarch64_standard<32, true>::
957 plt_entry[plt_entry_size / 4] =
958 {
959 0x90000010, /* adrp x16, PLTGOT + n * 4 */
960 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
961 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
962 0xd61f0220, /* br x17. */
963 };
964
965 template<>
966 const uint32_t
967 Output_data_plt_aarch64_standard<64, false>::
968 plt_entry[plt_entry_size / 4] =
969 {
970 0x90000010, /* adrp x16, PLTGOT + n * 8 */
971 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
972 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
973 0xd61f0220, /* br x17. */
974 };
975
976 template<>
977 const uint32_t
978 Output_data_plt_aarch64_standard<64, true>::
979 plt_entry[plt_entry_size / 4] =
980 {
981 0x90000010, /* adrp x16, PLTGOT + n * 8 */
982 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
983 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
984 0xd61f0220, /* br x17. */
985 };
986
987 template<int size, bool big_endian>
988 void
989 Output_data_plt_aarch64_standard<size, big_endian>::do_fill_first_plt_entry(
990 unsigned char* pov,
991 Address got_address,
992 Address plt_address)
993 {
994 // PLT0 of the small PLT looks like this in ELF64 -
995 // stp x16, x30, [sp, #-16]! Save the reloc and lr on stack.
996 // adrp x16, PLT_GOT + 16 Get the page base of the GOTPLT
997 // ldr x17, [x16, #:lo12:PLT_GOT+16] Load the address of the
998 // symbol resolver
999 // add x16, x16, #:lo12:PLT_GOT+16 Load the lo12 bits of the
1000 // GOTPLT entry for this.
1001 // br x17
1002 // PLT0 will be slightly different in ELF32 due to different got entry
1003 // size.
1004 memcpy(pov, this->first_plt_entry, this->first_plt_entry_size);
1005 Address gotplt_2nd_ent = got_address + (size / 8) * 2;
1006
1007 // Fill in the top 21 bits for this: ADRP x16, PLT_GOT + 8 * 2.
1008 // ADRP: (PG(S+A)-PG(P)) >> 12) & 0x1fffff.
1009 // FIXME: This only works for 64bit
1010 AArch64_relocate_functions<size, big_endian>::adrp(pov + 4,
1011 gotplt_2nd_ent, plt_address + 4);
1012
1013 // Fill in R_AARCH64_LDST8_LO12
1014 elfcpp::Swap<32, big_endian>::writeval(
1015 pov + 8,
1016 ((this->first_plt_entry[2] & 0xffc003ff)
1017 | ((gotplt_2nd_ent & 0xff8) << 7)));
1018
1019 // Fill in R_AARCH64_ADD_ABS_LO12
1020 elfcpp::Swap<32, big_endian>::writeval(
1021 pov + 12,
1022 ((this->first_plt_entry[3] & 0xffc003ff)
1023 | ((gotplt_2nd_ent & 0xfff) << 10)));
1024 }
1025
1026 // Subsequent entries in the PLT for an executable.
1027 // FIXME: This only works for 64bit
1028
1029 template<int size, bool big_endian>
1030 void
1031 Output_data_plt_aarch64_standard<size, big_endian>::do_fill_plt_entry(
1032 unsigned char* pov,
1033 Address got_address,
1034 Address plt_address,
1035 unsigned int got_offset,
1036 unsigned int plt_offset)
1037 {
1038 memcpy(pov, this->plt_entry, this->plt_entry_size);
1039
1040 Address gotplt_entry_address = got_address + got_offset;
1041 Address plt_entry_address = plt_address + plt_offset;
1042
1043 // Fill in R_AARCH64_PCREL_ADR_HI21
1044 AArch64_relocate_functions<size, big_endian>::adrp(
1045 pov,
1046 gotplt_entry_address,
1047 plt_entry_address);
1048
1049 // Fill in R_AARCH64_LDST64_ABS_LO12
1050 elfcpp::Swap<32, big_endian>::writeval(
1051 pov + 4,
1052 ((this->plt_entry[1] & 0xffc003ff)
1053 | ((gotplt_entry_address & 0xff8) << 7)));
1054
1055 // Fill in R_AARCH64_ADD_ABS_LO12
1056 elfcpp::Swap<32, big_endian>::writeval(
1057 pov + 8,
1058 ((this->plt_entry[2] & 0xffc003ff)
1059 | ((gotplt_entry_address & 0xfff) <<10)));
1060
1061 }
1062
1063 // Write out the PLT. This uses the hand-coded instructions above,
1064 // and adjusts them as needed. This is specified by the AMD64 ABI.
1065
1066 template<int size, bool big_endian>
1067 void
1068 Output_data_plt_aarch64<size, big_endian>::do_write(Output_file* of)
1069 {
1070 const off_t offset = this->offset();
1071 const section_size_type oview_size =
1072 convert_to_section_size_type(this->data_size());
1073 unsigned char* const oview = of->get_output_view(offset, oview_size);
1074
1075 const off_t got_file_offset = this->got_plt_->offset();
1076 const section_size_type got_size =
1077 convert_to_section_size_type(this->got_plt_->data_size());
1078 unsigned char* const got_view = of->get_output_view(got_file_offset,
1079 got_size);
1080
1081 unsigned char* pov = oview;
1082
1083 // The base address of the .plt section.
1084 typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
1085 // The base address of the PLT portion of the .got section.
1086 typename elfcpp::Elf_types<size>::Elf_Addr got_address
1087 = this->got_plt_->address();
1088
1089 this->fill_first_plt_entry(pov, got_address, plt_address);
1090 pov += this->first_plt_entry_offset();
1091
1092 // The first three entries in .got.plt are reserved.
1093 unsigned char* got_pov = got_view;
1094 memset(got_pov, 0, size / 8 * AARCH64_GOTPLT_RESERVE_COUNT);
1095 got_pov += (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
1096
1097 unsigned int plt_offset = this->first_plt_entry_offset();
1098 unsigned int got_offset = (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
1099 const unsigned int count = this->count_;
1100 for (unsigned int plt_index = 0;
1101 plt_index < count;
1102 ++plt_index,
1103 pov += this->get_plt_entry_size(),
1104 got_pov += size / 8,
1105 plt_offset += this->get_plt_entry_size(),
1106 got_offset += size / 8)
1107 {
1108 // Set and adjust the PLT entry itself.
1109 this->fill_plt_entry(pov, got_address, plt_address,
1110 got_offset, plt_offset);
1111
1112 // Set the entry in the GOT, which points to plt0.
1113 elfcpp::Swap<size, big_endian>::writeval(got_pov, plt_address);
1114 }
1115
1116 gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
1117 gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
1118
1119 of->write_output_view(offset, oview_size, oview);
1120 of->write_output_view(got_file_offset, got_size, got_view);
1121 }
1122
1123 // Telling how to update the immediate field of an instruction.
1124 struct AArch64_howto
1125 {
1126 // The immediate field mask.
1127 elfcpp::Elf_Xword dst_mask;
1128
1129 // The offset to apply relocation immediate
1130 int doffset;
1131
1132 // The second part offset, if the immediate field has two parts.
1133 // -1 if the immediate field has only one part.
1134 int doffset2;
1135 };
1136
1137 static const AArch64_howto aarch64_howto[AArch64_reloc_property::INST_NUM] =
1138 {
1139 {0, -1, -1}, // DATA
1140 {0x1fffe0, 5, -1}, // MOVW [20:5]-imm16
1141 {0xffffe0, 5, -1}, // LD [23:5]-imm19
1142 {0x60ffffe0, 29, 5}, // ADR [30:29]-immlo [23:5]-immhi
1143 {0x60ffffe0, 29, 5}, // ADRP [30:29]-immlo [23:5]-immhi
1144 {0x3ffc00, 10, -1}, // ADD [21:10]-imm12
1145 {0x3ffc00, 10, -1}, // LDST [21:10]-imm12
1146 {0x7ffe0, 5, -1}, // TBZNZ [18:5]-imm14
1147 {0xffffe0, 5, -1}, // CONDB [23:5]-imm19
1148 {0x3ffffff, 0, -1}, // B [25:0]-imm26
1149 {0x3ffffff, 0, -1}, // CALL [25:0]-imm26
1150 };
1151
1152 // AArch64 relocate function class
1153
1154 template<int size, bool big_endian>
1155 class AArch64_relocate_functions
1156 {
1157 public:
1158 typedef enum
1159 {
1160 STATUS_OKAY, // No error during relocation.
1161 STATUS_OVERFLOW, // Relocation overflow.
1162 STATUS_BAD_RELOC, // Relocation cannot be applied.
1163 } Status;
1164
1165 private:
1166 typedef AArch64_relocate_functions<size, big_endian> This;
1167 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
1168
1169 // Return the page address of the address.
1170 // Page(address) = address & ~0xFFF
1171
1172 static inline typename elfcpp::Swap<size, big_endian>::Valtype
1173 Page(Address address)
1174 {
1175 return (address & (~static_cast<Address>(0xFFF)));
1176 }
1177
1178 // Update instruction (pointed by view) with selected bits (immed).
1179 // val = (val & ~dst_mask) | (immed << doffset)
1180
1181 template<int valsize>
1182 static inline void
1183 update_view(unsigned char* view,
1184 typename elfcpp::Swap<size, big_endian>::Valtype immed,
1185 elfcpp::Elf_Xword doffset,
1186 elfcpp::Elf_Xword dst_mask)
1187 {
1188 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
1189 Valtype* wv = reinterpret_cast<Valtype*>(view);
1190 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
1191
1192 // Clear immediate fields.
1193 val &= ~dst_mask;
1194 elfcpp::Swap<valsize, big_endian>::writeval(wv,
1195 static_cast<Valtype>(val | (immed << doffset)));
1196 }
1197
1198 // Update two parts of an instruction (pointed by view) with selected
1199 // bits (immed1 and immed2).
1200 // val = (val & ~dst_mask) | (immed1 << doffset1) | (immed2 << doffset2)
1201
1202 template<int valsize>
1203 static inline void
1204 update_view_two_parts(
1205 unsigned char* view,
1206 typename elfcpp::Swap<size, big_endian>::Valtype immed1,
1207 typename elfcpp::Swap<size, big_endian>::Valtype immed2,
1208 elfcpp::Elf_Xword doffset1,
1209 elfcpp::Elf_Xword doffset2,
1210 elfcpp::Elf_Xword dst_mask)
1211 {
1212 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
1213 Valtype* wv = reinterpret_cast<Valtype*>(view);
1214 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
1215 val &= ~dst_mask;
1216 elfcpp::Swap<valsize, big_endian>::writeval(wv,
1217 static_cast<Valtype>(val | (immed1 << doffset1) |
1218 (immed2 << doffset2)));
1219 }
1220
1221 // Update adr or adrp instruction with [32:12] of X.
1222 // In adr and adrp: [30:29] immlo [23:5] immhi
1223
1224 static inline void
1225 update_adr(unsigned char* view,
1226 typename elfcpp::Swap<size, big_endian>::Valtype x,
1227 const AArch64_reloc_property* /* reloc_property */)
1228 {
1229 elfcpp::Elf_Xword dst_mask = (0x3 << 29) | (0x7ffff << 5);
1230 typename elfcpp::Swap<32, big_endian>::Valtype immed =
1231 (x >> 12) & 0x1fffff;
1232 This::template update_view_two_parts<32>(
1233 view,
1234 immed & 0x3,
1235 (immed & 0x1ffffc) >> 2,
1236 29,
1237 5,
1238 dst_mask);
1239 }
1240
1241 public:
1242
1243 // Do a simple rela relocation at unaligned addresses.
1244
1245 template<int valsize>
1246 static inline typename This::Status
1247 rela_ua(unsigned char* view,
1248 const Sized_relobj_file<size, big_endian>* object,
1249 const Symbol_value<size>* psymval,
1250 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1251 const AArch64_reloc_property* reloc_property)
1252 {
1253 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
1254 Valtype;
1255 typename elfcpp::Elf_types<size>::Elf_Addr x =
1256 psymval->value(object, addend);
1257 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
1258 static_cast<Valtype>(x));
1259 return (reloc_property->checkup_x_value(x)
1260 ? This::STATUS_OKAY
1261 : This::STATUS_OVERFLOW);
1262 }
1263
1264 // Do a simple pc-relative relocation at unaligned addresses.
1265
1266 template<int valsize>
1267 static inline typename This::Status
1268 pcrela_ua(unsigned char* view,
1269 const Sized_relobj_file<size, big_endian>* object,
1270 const Symbol_value<size>* psymval,
1271 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1272 Address address,
1273 const AArch64_reloc_property* reloc_property)
1274 {
1275 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
1276 Valtype;
1277 Address x = psymval->value(object, addend) - address;
1278 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
1279 static_cast<Valtype>(x));
1280 return (reloc_property->checkup_x_value(x)
1281 ? This::STATUS_OKAY
1282 : This::STATUS_OVERFLOW);
1283 }
1284
1285 // Do a simple rela relocation at aligned addresses.
1286
1287 template<int valsize>
1288 static inline typename This::Status
1289 rela(
1290 unsigned char* view,
1291 const Sized_relobj_file<size, big_endian>* object,
1292 const Symbol_value<size>* psymval,
1293 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1294 const AArch64_reloc_property* reloc_property)
1295 {
1296 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype
1297 Valtype;
1298 Valtype* wv = reinterpret_cast<Valtype*>(view);
1299 Address x = psymval->value(object, addend);
1300 elfcpp::Swap<valsize, big_endian>::writeval(wv,
1301 static_cast<Valtype>(x));
1302 return (reloc_property->checkup_x_value(x)
1303 ? This::STATUS_OKAY
1304 : This::STATUS_OVERFLOW);
1305 }
1306
1307 // Do relocate. Update selected bits in text.
1308 // new_val = (val & ~dst_mask) | (immed << doffset)
1309
1310 template<int valsize>
1311 static inline typename This::Status
1312 rela_general(unsigned char* view,
1313 const Sized_relobj_file<size, big_endian>* object,
1314 const Symbol_value<size>* psymval,
1315 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1316 const AArch64_reloc_property* reloc_property)
1317 {
1318 // Calculate relocation.
1319 Address x = psymval->value(object, addend);
1320
1321 // Select bits from X.
1322 Address immed = reloc_property->select_x_value(x);
1323
1324 // Update view.
1325 const AArch64_reloc_property::Reloc_inst inst =
1326 reloc_property->reloc_inst();
1327 // If it is a data relocation or instruction has 2 parts of immediate
1328 // fields, you should not call rela_general.
1329 gold_assert(aarch64_howto[inst].doffset2 == -1 &&
1330 aarch64_howto[inst].doffset != -1);
1331 This::template update_view<valsize>(view, immed,
1332 aarch64_howto[inst].doffset,
1333 aarch64_howto[inst].dst_mask);
1334
1335 // Do check overflow or alignment if needed.
1336 return (reloc_property->checkup_x_value(x)
1337 ? This::STATUS_OKAY
1338 : This::STATUS_OVERFLOW);
1339 }
1340
1341 // Do relocate. Update selected bits in text.
1342 // new val = (val & ~dst_mask) | (immed << doffset)
1343
1344 template<int valsize>
1345 static inline typename This::Status
1346 rela_general(
1347 unsigned char* view,
1348 typename elfcpp::Swap<size, big_endian>::Valtype s,
1349 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1350 const AArch64_reloc_property* reloc_property)
1351 {
1352 // Calculate relocation.
1353 Address x = s + addend;
1354
1355 // Select bits from X.
1356 Address immed = reloc_property->select_x_value(x);
1357
1358 // Update view.
1359 const AArch64_reloc_property::Reloc_inst inst =
1360 reloc_property->reloc_inst();
1361 // If it is a data relocation or instruction has 2 parts of immediate
1362 // fields, you should not call rela_general.
1363 gold_assert(aarch64_howto[inst].doffset2 == -1 &&
1364 aarch64_howto[inst].doffset != -1);
1365 This::template update_view<valsize>(view, immed,
1366 aarch64_howto[inst].doffset,
1367 aarch64_howto[inst].dst_mask);
1368
1369 // Do check overflow or alignment if needed.
1370 return (reloc_property->checkup_x_value(x)
1371 ? This::STATUS_OKAY
1372 : This::STATUS_OVERFLOW);
1373 }
1374
1375 // Do address relative relocate. Update selected bits in text.
1376 // new val = (val & ~dst_mask) | (immed << doffset)
1377
1378 template<int valsize>
1379 static inline typename This::Status
1380 pcrela_general(
1381 unsigned char* view,
1382 const Sized_relobj_file<size, big_endian>* object,
1383 const Symbol_value<size>* psymval,
1384 typename elfcpp::Swap<size, big_endian>::Valtype addend,
1385 Address address,
1386 const AArch64_reloc_property* reloc_property)
1387 {
1388 // Calculate relocation.
1389 Address x = psymval->value(object, addend) - address;
1390
1391 // Select bits from X.
1392 Address immed = reloc_property->select_x_value(x);
1393
1394 // Update view.
1395 const AArch64_reloc_property::Reloc_inst inst =
1396 reloc_property->reloc_inst();
1397 // If it is a data relocation or instruction has 2 parts of immediate
1398 // fields, you should not call pcrela_general.
1399 gold_assert(aarch64_howto[inst].doffset2 == -1 &&
1400 aarch64_howto[inst].doffset != -1);
1401 This::template update_view<valsize>(view, immed,
1402 aarch64_howto[inst].doffset,
1403 aarch64_howto[inst].dst_mask);
1404
1405 // Do check overflow or alignment if needed.
1406 return (reloc_property->checkup_x_value(x)
1407 ? This::STATUS_OKAY
1408 : This::STATUS_OVERFLOW);
1409 }
1410
1411 // Calculate PG(S+A) - PG(address), update adrp instruction.
1412 // R_AARCH64_ADR_PREL_PG_HI21
1413
1414 static inline typename This::Status
1415 adrp(
1416 unsigned char* view,
1417 Address sa,
1418 Address address)
1419 {
1420 typename elfcpp::Swap<size, big_endian>::Valtype x =
1421 This::Page(sa) - This::Page(address);
1422 update_adr(view, x, NULL);
1423 return (size == 64 && Bits<32>::has_overflow(x)
1424 ? This::STATUS_OVERFLOW
1425 : This::STATUS_OKAY);
1426 }
1427
1428 // Calculate PG(S+A) - PG(address), update adrp instruction.
1429 // R_AARCH64_ADR_PREL_PG_HI21
1430
1431 static inline typename This::Status
1432 adrp(unsigned char* view,
1433 const Sized_relobj_file<size, big_endian>* object,
1434 const Symbol_value<size>* psymval,
1435 Address addend,
1436 Address address,
1437 const AArch64_reloc_property* reloc_property)
1438 {
1439 Address sa = psymval->value(object, addend);
1440 typename elfcpp::Swap<size, big_endian>::Valtype x =
1441 This::Page(sa) - This::Page(address);
1442 update_adr(view, x, reloc_property);
1443 return (reloc_property->checkup_x_value(x)
1444 ? This::STATUS_OKAY
1445 : This::STATUS_OVERFLOW);
1446 }
1447
1448 };
1449
1450 // Return the number of entries in the PLT.
1451
1452 template<int size, bool big_endian>
1453 unsigned int
1454 Target_aarch64<size, big_endian>::plt_entry_count() const
1455 {
1456 if (this->plt_ == NULL)
1457 return 0;
1458 return this->plt_->entry_count();
1459 }
1460
1461 // Return the offset of the first non-reserved PLT entry.
1462
1463 template<int size, bool big_endian>
1464 unsigned int
1465 Target_aarch64<size, big_endian>::first_plt_entry_offset() const
1466 {
1467 return this->plt_->first_plt_entry_offset();
1468 }
1469
1470 // Return the size of each PLT entry.
1471
1472 template<int size, bool big_endian>
1473 unsigned int
1474 Target_aarch64<size, big_endian>::plt_entry_size() const
1475 {
1476 return this->plt_->get_plt_entry_size();
1477 }
1478
1479 // Optimize the TLS relocation type based on what we know about the
1480 // symbol. IS_FINAL is true if the final address of this symbol is
1481 // known at link time.
1482
1483 template<int size, bool big_endian>
1484 tls::Tls_optimization
1485 Target_aarch64<size, big_endian>::optimize_tls_reloc(bool /* is_final */,
1486 int /* r_type */)
1487 {
1488 //TODO
1489 return tls::TLSOPT_NONE;
1490 }
1491
1492 // Returns true if this relocation type could be that of a function pointer.
1493
1494 template<int size, bool big_endian>
1495 inline bool
1496 Target_aarch64<size, big_endian>::Scan::possible_function_pointer_reloc(
1497 unsigned int r_type)
1498 {
1499 switch (r_type)
1500 {
1501 case elfcpp::R_AARCH64_ABS64:
1502 //TODO
1503 {
1504 return true;
1505 }
1506 }
1507 return false;
1508 }
1509
1510 // For safe ICF, scan a relocation for a local symbol to check if it
1511 // corresponds to a function pointer being taken. In that case mark
1512 // the function whose pointer was taken as not foldable.
1513
1514 template<int size, bool big_endian>
1515 inline bool
1516 Target_aarch64<size, big_endian>::Scan::local_reloc_may_be_function_pointer(
1517 Symbol_table* ,
1518 Layout* ,
1519 Target_aarch64<size, big_endian>* ,
1520 Sized_relobj_file<size, big_endian>* ,
1521 unsigned int ,
1522 Output_section* ,
1523 const elfcpp::Rela<size, big_endian>& ,
1524 unsigned int r_type,
1525 const elfcpp::Sym<size, big_endian>&)
1526 {
1527 // When building a shared library, do not fold any local symbols as it is
1528 // not possible to distinguish pointer taken versus a call by looking at
1529 // the relocation types.
1530 return (parameters->options().shared()
1531 || possible_function_pointer_reloc(r_type));
1532 }
1533
1534 // For safe ICF, scan a relocation for a global symbol to check if it
1535 // corresponds to a function pointer being taken. In that case mark
1536 // the function whose pointer was taken as not foldable.
1537
1538 template<int size, bool big_endian>
1539 inline bool
1540 Target_aarch64<size, big_endian>::Scan::global_reloc_may_be_function_pointer(
1541 Symbol_table* ,
1542 Layout* ,
1543 Target_aarch64<size, big_endian>* ,
1544 Sized_relobj_file<size, big_endian>* ,
1545 unsigned int ,
1546 Output_section* ,
1547 const elfcpp::Rela<size, big_endian>& ,
1548 unsigned int r_type,
1549 Symbol* gsym)
1550 {
1551 // When building a shared library, do not fold symbols whose visibility
1552 // is hidden, internal or protected.
1553 return ((parameters->options().shared()
1554 && (gsym->visibility() == elfcpp::STV_INTERNAL
1555 || gsym->visibility() == elfcpp::STV_PROTECTED
1556 || gsym->visibility() == elfcpp::STV_HIDDEN))
1557 || possible_function_pointer_reloc(r_type));
1558 }
1559
1560 // Report an unsupported relocation against a local symbol.
1561
1562 template<int size, bool big_endian>
1563 void
1564 Target_aarch64<size, big_endian>::Scan::unsupported_reloc_local(
1565 Sized_relobj_file<size, big_endian>* object,
1566 unsigned int r_type)
1567 {
1568 gold_error(_("%s: unsupported reloc %u against local symbol"),
1569 object->name().c_str(), r_type);
1570 }
1571
1572 // We are about to emit a dynamic relocation of type R_TYPE. If the
1573 // dynamic linker does not support it, issue an error.
1574
1575 template<int size, bool big_endian>
1576 void
1577 Target_aarch64<size, big_endian>::Scan::check_non_pic(Relobj* object,
1578 unsigned int r_type)
1579 {
1580 gold_assert(r_type != elfcpp::R_AARCH64_NONE);
1581
1582 switch (r_type)
1583 {
1584 // These are the relocation types supported by glibc for AARCH64.
1585 case elfcpp::R_AARCH64_NONE:
1586 case elfcpp::R_AARCH64_COPY:
1587 case elfcpp::R_AARCH64_GLOB_DAT:
1588 case elfcpp::R_AARCH64_JUMP_SLOT:
1589 case elfcpp::R_AARCH64_RELATIVE:
1590 case elfcpp::R_AARCH64_TLS_DTPREL64:
1591 case elfcpp::R_AARCH64_TLS_DTPMOD64:
1592 case elfcpp::R_AARCH64_TLS_TPREL64:
1593 case elfcpp::R_AARCH64_TLSDESC:
1594 case elfcpp::R_AARCH64_IRELATIVE:
1595 case elfcpp::R_AARCH64_ABS32:
1596 case elfcpp::R_AARCH64_ABS64:
1597 return;
1598
1599 default:
1600 break;
1601 }
1602
1603 // This prevents us from issuing more than one error per reloc
1604 // section. But we can still wind up issuing more than one
1605 // error per object file.
1606 if (this->issued_non_pic_error_)
1607 return;
1608 gold_assert(parameters->options().output_is_position_independent());
1609 object->error(_("requires unsupported dynamic reloc; "
1610 "recompile with -fPIC"));
1611 this->issued_non_pic_error_ = true;
1612 return;
1613 }
1614
1615 // Scan a relocation for a local symbol.
1616
1617 template<int size, bool big_endian>
1618 inline void
1619 Target_aarch64<size, big_endian>::Scan::local(
1620 Symbol_table* /* symtab */,
1621 Layout* /* layout */,
1622 Target_aarch64<size, big_endian>* /* target */,
1623 Sized_relobj_file<size, big_endian>* object,
1624 unsigned int /* data_shndx */,
1625 Output_section* /* output_section */,
1626 const elfcpp::Rela<size, big_endian>& /* reloc */,
1627 unsigned int r_type,
1628 const elfcpp::Sym<size, big_endian>& /* lsym */,
1629 bool is_discarded)
1630 {
1631 if (is_discarded)
1632 return;
1633
1634 switch (r_type)
1635 {
1636 case elfcpp::R_AARCH64_ABS64:
1637 case elfcpp::R_AARCH64_ABS32:
1638 case elfcpp::R_AARCH64_ABS16:
1639 // If building a shared library or pie, we need to mark this as a dynmic
1640 // reloction, so that the dynamic loader can relocate it.
1641 // Not supported yet.
1642 if (parameters->options().output_is_position_independent())
1643 {
1644 gold_error(_("%s: unsupported ABS64 relocation type for pie or "
1645 "shared library.\n"),
1646 object->name().c_str());
1647 }
1648 break;
1649
1650 // Relocations to generate 19, 21 and 33-bit PC-relative address
1651 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275
1652 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC: // 278
1653 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC: // 286
1654 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC: // 277
1655 break;
1656
1657 // Control flow, pc-relative. We don't need to do anything for a relative
1658 // addressing relocation against a local symbol if it does not reference
1659 // the GOT.
1660 case elfcpp::R_AARCH64_CALL26: // 283
1661 break;
1662
1663 default:
1664 unsupported_reloc_local(object, r_type);
1665 }
1666 }
1667
1668
1669 // Report an unsupported relocation against a global symbol.
1670
1671 template<int size, bool big_endian>
1672 void
1673 Target_aarch64<size, big_endian>::Scan::unsupported_reloc_global(
1674 Sized_relobj_file<size, big_endian>* object,
1675 unsigned int r_type,
1676 Symbol* gsym)
1677 {
1678 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
1679 object->name().c_str(), r_type, gsym->demangled_name().c_str());
1680 }
1681
1682 template<int size, bool big_endian>
1683 inline void
1684 Target_aarch64<size, big_endian>::Scan::global(
1685 Symbol_table* symtab,
1686 Layout* layout,
1687 Target_aarch64<size, big_endian>* target,
1688 Sized_relobj_file<size, big_endian>* /* object */,
1689 unsigned int /* data_shndx */,
1690 Output_section* /* output_section */,
1691 const elfcpp::Rela<size, big_endian>& /* reloc */,
1692 unsigned int r_type,
1693 Symbol* gsym)
1694 {
1695 switch (r_type)
1696 {
1697 case elfcpp::R_AARCH64_ABS64:
1698 // This is used to fill the GOT absolute address.
1699 if (gsym->needs_plt_entry())
1700 {
1701 target->make_plt_entry(symtab, layout, gsym);
1702 }
1703 break;
1704
1705 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
1706 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
1707 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
1708 {
1709 // Do nothing here.
1710 break;
1711 }
1712
1713 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
1714 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
1715 {
1716 // This pair of relocations is used to access a specific GOT entry.
1717 // Note a GOT entry is an *address* to a symbol.
1718 // The symbol requires a GOT entry
1719 Output_data_got_aarch64<size, big_endian>* got =
1720 target->got_section(symtab, layout);
1721 if (gsym->final_value_is_known())
1722 {
1723 got->add_global(gsym, GOT_TYPE_STANDARD);
1724 }
1725 else
1726 {
1727 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1728 if (gsym->is_from_dynobj()
1729 || gsym->is_undefined()
1730 || gsym->is_preemptible()
1731 || (gsym->visibility() == elfcpp::STV_PROTECTED
1732 && parameters->options().shared()))
1733 got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
1734 rela_dyn, elfcpp::R_AARCH64_GLOB_DAT);
1735 else
1736 {
1737 // Not implemented yet.
1738 gold_assert(false);
1739 }
1740 }
1741 break;
1742 }
1743
1744 case elfcpp::R_AARCH64_JUMP26:
1745 case elfcpp::R_AARCH64_CALL26:
1746 {
1747 if (gsym->final_value_is_known())
1748 break;
1749
1750 if (gsym->is_defined() &&
1751 !gsym->is_from_dynobj() &&
1752 !gsym->is_preemptible())
1753 break;
1754
1755 // Make plt entry for function call.
1756 const AArch64_reloc_property* arp =
1757 aarch64_reloc_property_table->get_reloc_property(r_type);
1758 gold_assert(arp != NULL);
1759 target->make_plt_entry(symtab, layout, gsym);
1760 break;
1761 }
1762
1763 default:
1764 gold_error(_("%s: unsupported reloc type"),
1765 aarch64_reloc_property_table->
1766 reloc_name_in_error_message(r_type).c_str());
1767 }
1768 return;
1769 } // End of Scan::global
1770
1771 // Create the PLT section.
1772 template<int size, bool big_endian>
1773 void
1774 Target_aarch64<size, big_endian>::make_plt_section(
1775 Symbol_table* symtab, Layout* layout)
1776 {
1777 if (this->plt_ == NULL)
1778 {
1779 // Create the GOT section first.
1780 this->got_section(symtab, layout);
1781
1782 this->plt_ = this->make_data_plt(layout, this->got_plt_);
1783
1784 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
1785 (elfcpp::SHF_ALLOC
1786 | elfcpp::SHF_EXECINSTR),
1787 this->plt_, ORDER_PLT, false);
1788
1789 // Make the sh_info field of .rela.plt point to .plt.
1790 Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
1791 rela_plt_os->set_info_section(this->plt_->output_section());
1792 }
1793 }
1794
1795 // Create a PLT entry for a global symbol.
1796
1797 template<int size, bool big_endian>
1798 void
1799 Target_aarch64<size, big_endian>::make_plt_entry(
1800 Symbol_table* symtab,
1801 Layout* layout,
1802 Symbol* gsym)
1803 {
1804 if (gsym->has_plt_offset())
1805 return;
1806
1807 if (this->plt_ == NULL)
1808 this->make_plt_section(symtab, layout);
1809
1810 this->plt_->add_entry(gsym);
1811 }
1812
1813 template<int size, bool big_endian>
1814 void
1815 Target_aarch64<size, big_endian>::gc_process_relocs(
1816 Symbol_table* symtab,
1817 Layout* layout,
1818 Sized_relobj_file<size, big_endian>* object,
1819 unsigned int data_shndx,
1820 unsigned int sh_type,
1821 const unsigned char* prelocs,
1822 size_t reloc_count,
1823 Output_section* output_section,
1824 bool needs_special_offset_handling,
1825 size_t local_symbol_count,
1826 const unsigned char* plocal_symbols)
1827 {
1828 if (sh_type == elfcpp::SHT_REL)
1829 {
1830 return;
1831 }
1832
1833 gold::gc_process_relocs<
1834 size, big_endian,
1835 Target_aarch64<size, big_endian>,
1836 elfcpp::SHT_RELA,
1837 typename Target_aarch64<size, big_endian>::Scan,
1838 typename Target_aarch64<size, big_endian>::Relocatable_size_for_reloc>(
1839 symtab,
1840 layout,
1841 this,
1842 object,
1843 data_shndx,
1844 prelocs,
1845 reloc_count,
1846 output_section,
1847 needs_special_offset_handling,
1848 local_symbol_count,
1849 plocal_symbols);
1850 }
1851
1852 // Scan relocations for a section.
1853
1854 template<int size, bool big_endian>
1855 void
1856 Target_aarch64<size, big_endian>::scan_relocs(
1857 Symbol_table* symtab,
1858 Layout* layout,
1859 Sized_relobj_file<size, big_endian>* object,
1860 unsigned int data_shndx,
1861 unsigned int sh_type,
1862 const unsigned char* prelocs,
1863 size_t reloc_count,
1864 Output_section* output_section,
1865 bool needs_special_offset_handling,
1866 size_t local_symbol_count,
1867 const unsigned char* plocal_symbols)
1868 {
1869 if (sh_type == elfcpp::SHT_REL)
1870 {
1871 gold_error(_("%s: unsupported REL reloc section"),
1872 object->name().c_str());
1873 return;
1874 }
1875 gold::scan_relocs<size, big_endian, Target_aarch64, elfcpp::SHT_RELA, Scan>(
1876 symtab,
1877 layout,
1878 this,
1879 object,
1880 data_shndx,
1881 prelocs,
1882 reloc_count,
1883 output_section,
1884 needs_special_offset_handling,
1885 local_symbol_count,
1886 plocal_symbols);
1887 }
1888
1889 // Finalize the sections.
1890
1891 template<int size, bool big_endian>
1892 void
1893 Target_aarch64<size, big_endian>::do_finalize_sections(
1894 Layout* layout,
1895 const Input_objects*,
1896 Symbol_table* symtab)
1897 {
1898 const Reloc_section* rel_plt = (this->plt_ == NULL
1899 ? NULL
1900 : this->plt_->rela_plt());
1901 layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
1902 this->rela_dyn_, true, false);
1903
1904 // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
1905 // the .got.plt section.
1906 Symbol* sym = this->global_offset_table_;
1907 if (sym != NULL)
1908 {
1909 uint64_t data_size = this->got_plt_->current_data_size();
1910 symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
1911
1912 // If the .got section is more than 0x8000 bytes, we add
1913 // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
1914 // bit relocations have a greater chance of working.
1915 if (data_size >= 0x8000)
1916 symtab->get_sized_symbol<size>(sym)->set_value(
1917 symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
1918 }
1919
1920 if (parameters->doing_static_link()
1921 && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
1922 {
1923 // If linking statically, make sure that the __rela_iplt symbols
1924 // were defined if necessary, even if we didn't create a PLT.
1925 static const Define_symbol_in_segment syms[] =
1926 {
1927 {
1928 "__rela_iplt_start", // name
1929 elfcpp::PT_LOAD, // segment_type
1930 elfcpp::PF_W, // segment_flags_set
1931 elfcpp::PF(0), // segment_flags_clear
1932 0, // value
1933 0, // size
1934 elfcpp::STT_NOTYPE, // type
1935 elfcpp::STB_GLOBAL, // binding
1936 elfcpp::STV_HIDDEN, // visibility
1937 0, // nonvis
1938 Symbol::SEGMENT_START, // offset_from_base
1939 true // only_if_ref
1940 },
1941 {
1942 "__rela_iplt_end", // name
1943 elfcpp::PT_LOAD, // segment_type
1944 elfcpp::PF_W, // segment_flags_set
1945 elfcpp::PF(0), // segment_flags_clear
1946 0, // value
1947 0, // size
1948 elfcpp::STT_NOTYPE, // type
1949 elfcpp::STB_GLOBAL, // binding
1950 elfcpp::STV_HIDDEN, // visibility
1951 0, // nonvis
1952 Symbol::SEGMENT_START, // offset_from_base
1953 true // only_if_ref
1954 }
1955 };
1956
1957 symtab->define_symbols(layout, 2, syms,
1958 layout->script_options()->saw_sections_clause());
1959 }
1960
1961 return;
1962 }
1963
1964 // Perform a relocation.
1965
1966 template<int size, bool big_endian>
1967 inline bool
1968 Target_aarch64<size, big_endian>::Relocate::relocate(
1969 const Relocate_info<size, big_endian>* relinfo,
1970 Target_aarch64<size, big_endian>* target,
1971 Output_section* ,
1972 size_t relnum,
1973 const elfcpp::Rela<size, big_endian>& rela,
1974 unsigned int r_type,
1975 const Sized_symbol<size>* gsym,
1976 const Symbol_value<size>* psymval,
1977 unsigned char* view,
1978 typename elfcpp::Elf_types<size>::Elf_Addr address,
1979 section_size_type /* view_size */)
1980 {
1981 if (view == NULL)
1982 return true;
1983
1984 typedef AArch64_relocate_functions<size, big_endian> Reloc;
1985
1986 const AArch64_reloc_property* reloc_property =
1987 aarch64_reloc_property_table->get_reloc_property(r_type);
1988
1989 if (reloc_property == NULL)
1990 {
1991 std::string reloc_name =
1992 aarch64_reloc_property_table->reloc_name_in_error_message(r_type);
1993 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
1994 _("cannot relocate %s in object file"),
1995 reloc_name.c_str());
1996 return true;
1997 }
1998
1999 const Sized_relobj_file<size, big_endian>* object = relinfo->object;
2000
2001 // Pick the value to use for symbols defined in the PLT.
2002 Symbol_value<size> symval;
2003 if (gsym != NULL
2004 && gsym->use_plt_offset(reloc_property->reference_flags()))
2005 {
2006 symval.set_output_value(target->plt_address_for_global(gsym));
2007 psymval = &symval;
2008 }
2009 else if (gsym == NULL && psymval->is_ifunc_symbol())
2010 {
2011 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
2012 if (object->local_has_plt_offset(r_sym))
2013 {
2014 symval.set_output_value(target->plt_address_for_local(object, r_sym));
2015 psymval = &symval;
2016 }
2017 }
2018
2019 const elfcpp::Elf_Xword addend = rela.get_r_addend();
2020
2021 // Get the GOT offset if needed.
2022 // For aarch64, the GOT pointer points to the start of the GOT section.
2023 bool have_got_offset = false;
2024 int got_offset = 0;
2025 int got_base = (target->got_ != NULL
2026 ? (target->got_->current_data_size() >= 0x8000
2027 ? 0x8000 : 0)
2028 : 0);
2029 switch (r_type)
2030 {
2031 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0:
2032 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0_NC:
2033 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1:
2034 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1_NC:
2035 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2:
2036 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2_NC:
2037 case elfcpp::R_AARCH64_MOVW_GOTOFF_G3:
2038 case elfcpp::R_AARCH64_GOTREL64:
2039 case elfcpp::R_AARCH64_GOTREL32:
2040 case elfcpp::R_AARCH64_GOT_LD_PREL19:
2041 case elfcpp::R_AARCH64_LD64_GOTOFF_LO15:
2042 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
2043 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
2044 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
2045 if (gsym != NULL)
2046 {
2047 gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
2048 got_offset = gsym->got_offset(GOT_TYPE_STANDARD) - got_base;
2049 }
2050 else
2051 {
2052 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
2053 gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
2054 got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
2055 - got_base);
2056 }
2057 have_got_offset = true;
2058 break;
2059 default:
2060 break;
2061 }
2062
2063 typename Reloc::Status reloc_status = Reloc::STATUS_OKAY;
2064 typename elfcpp::Elf_types<size>::Elf_Addr value;
2065 switch (r_type)
2066 {
2067 case elfcpp::R_AARCH64_NONE:
2068 break;
2069
2070 case elfcpp::R_AARCH64_ABS64:
2071 reloc_status = Reloc::template rela_ua<64>(
2072 view, object, psymval, addend, reloc_property);
2073 break;
2074
2075 case elfcpp::R_AARCH64_ABS32:
2076 reloc_status = Reloc::template rela_ua<32>(
2077 view, object, psymval, addend, reloc_property);
2078 break;
2079
2080 case elfcpp::R_AARCH64_ABS16:
2081 reloc_status = Reloc::template rela_ua<16>(
2082 view, object, psymval, addend, reloc_property);
2083 break;
2084
2085 case elfcpp::R_AARCH64_PREL64:
2086 reloc_status = Reloc::template pcrela_ua<64>(
2087 view, object, psymval, addend, address, reloc_property);
2088
2089 case elfcpp::R_AARCH64_PREL32:
2090 reloc_status = Reloc::template pcrela_ua<32>(
2091 view, object, psymval, addend, address, reloc_property);
2092
2093 case elfcpp::R_AARCH64_PREL16:
2094 reloc_status = Reloc::template pcrela_ua<16>(
2095 view, object, psymval, addend, address, reloc_property);
2096
2097 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
2098 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
2099 reloc_status = Reloc::adrp(view, object, psymval, addend, address,
2100 reloc_property);
2101 break;
2102
2103 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC:
2104 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC:
2105 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC:
2106 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC:
2107 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC:
2108 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
2109 reloc_status = Reloc::template rela_general<32>(
2110 view, object, psymval, addend, reloc_property);
2111 break;
2112
2113 case elfcpp::R_AARCH64_CALL26:
2114 case elfcpp::R_AARCH64_JUMP26:
2115 reloc_status = Reloc::template pcrela_general<32>(
2116 view, object, psymval, addend, address, reloc_property);
2117 break;
2118
2119 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
2120 gold_assert(have_got_offset);
2121 value = target->got_->address() + got_base + got_offset;
2122 reloc_status = Reloc::adrp(view, value + addend, address);
2123 break;
2124
2125 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
2126 gold_assert(have_got_offset);
2127 value = target->got_->address() + got_base + got_offset;
2128 reloc_status = Reloc::template rela_general<32>(
2129 view, value, addend, reloc_property);
2130 break;
2131
2132 default:
2133 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
2134 _("unsupported reloc aaa %u"),
2135 r_type);
2136 break;
2137 }
2138
2139 // Report any errors.
2140 switch (reloc_status)
2141 {
2142 case Reloc::STATUS_OKAY:
2143 break;
2144 case Reloc::STATUS_OVERFLOW:
2145 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
2146 _("relocation overflow in %s"),
2147 reloc_property->name().c_str());
2148 break;
2149 case Reloc::STATUS_BAD_RELOC:
2150 gold_error_at_location(
2151 relinfo,
2152 relnum,
2153 rela.get_r_offset(),
2154 _("unexpected opcode while processing relocation %s"),
2155 reloc_property->name().c_str());
2156 break;
2157 default:
2158 gold_unreachable();
2159 }
2160
2161 return true;
2162 }
2163
2164 // Relocate section data.
2165
2166 template<int size, bool big_endian>
2167 void
2168 Target_aarch64<size, big_endian>::relocate_section(
2169 const Relocate_info<size, big_endian>* relinfo,
2170 unsigned int sh_type,
2171 const unsigned char* prelocs,
2172 size_t reloc_count,
2173 Output_section* output_section,
2174 bool needs_special_offset_handling,
2175 unsigned char* view,
2176 typename elfcpp::Elf_types<size>::Elf_Addr address,
2177 section_size_type view_size,
2178 const Reloc_symbol_changes* reloc_symbol_changes)
2179 {
2180 gold_assert(sh_type == elfcpp::SHT_RELA);
2181 typedef typename Target_aarch64<size, big_endian>::Relocate AArch64_relocate;
2182 gold::relocate_section<size, big_endian, Target_aarch64, elfcpp::SHT_RELA,
2183 AArch64_relocate, gold::Default_comdat_behavior>(
2184 relinfo,
2185 this,
2186 prelocs,
2187 reloc_count,
2188 output_section,
2189 needs_special_offset_handling,
2190 view,
2191 address,
2192 view_size,
2193 reloc_symbol_changes);
2194 }
2195
2196 // Return the size of a relocation while scanning during a relocatable
2197 // link.
2198
2199 template<int size, bool big_endian>
2200 unsigned int
2201 Target_aarch64<size, big_endian>::Relocatable_size_for_reloc::
2202 get_size_for_reloc(
2203 unsigned int ,
2204 Relobj* )
2205 {
2206 // We will never support SHT_REL relocations.
2207 gold_unreachable();
2208 return 0;
2209 }
2210
2211 // Scan the relocs during a relocatable link.
2212
2213 template<int size, bool big_endian>
2214 void
2215 Target_aarch64<size, big_endian>::scan_relocatable_relocs(
2216 Symbol_table* /* symtab */,
2217 Layout* /* layout */,
2218 Sized_relobj_file<size, big_endian>* /* object */,
2219 unsigned int /* data_shndx */,
2220 unsigned int sh_type,
2221 const unsigned char* /* prelocs */,
2222 size_t /* reloc_count */,
2223 Output_section* /* output_section */,
2224 bool /* needs_special_offset_handling */,
2225 size_t /* local_symbol_count */,
2226 const unsigned char* /* plocal_symbols */,
2227 Relocatable_relocs* /* rr */)
2228 {
2229 //TODO
2230 gold_assert(sh_type == elfcpp::SHT_RELA);
2231 }
2232
2233 // Relocate a section during a relocatable link.
2234
2235 template<int size, bool big_endian>
2236 void
2237 Target_aarch64<size, big_endian>::relocate_relocs(
2238 const Relocate_info<size, big_endian>* /* relinfo */,
2239 unsigned int sh_type,
2240 const unsigned char* /* prelocs */,
2241 size_t /* reloc_count */,
2242 Output_section* /* output_section */,
2243 typename elfcpp::Elf_types<size>::Elf_Off /* offset_in_output_section */,
2244 const Relocatable_relocs* /* rr */,
2245 unsigned char* /* view */,
2246 typename elfcpp::Elf_types<size>::Elf_Addr /* view_address */,
2247 section_size_type /* view_size */,
2248 unsigned char* /* reloc_view */,
2249 section_size_type /* reloc_view_size */)
2250 {
2251 //TODO
2252 gold_assert(sh_type == elfcpp::SHT_RELA);
2253 }
2254
2255 // The selector for aarch64 object files.
2256
2257 template<int size, bool big_endian>
2258 class Target_selector_aarch64 : public Target_selector
2259 {
2260 public:
2261 Target_selector_aarch64();
2262
2263 virtual Target*
2264 do_instantiate_target()
2265 { return new Target_aarch64<size, big_endian>(); }
2266 };
2267
2268 template<>
2269 Target_selector_aarch64<32, true>::Target_selector_aarch64()
2270 : Target_selector(elfcpp::EM_AARCH64, 32, true,
2271 "elf32-bigaarch64", "aarch64_elf32_be_vec")
2272 { }
2273
2274 template<>
2275 Target_selector_aarch64<32, false>::Target_selector_aarch64()
2276 : Target_selector(elfcpp::EM_AARCH64, 32, false,
2277 "elf32-littleaarch64", "aarch64_elf32_le_vec")
2278 { }
2279
2280 template<>
2281 Target_selector_aarch64<64, true>::Target_selector_aarch64()
2282 : Target_selector(elfcpp::EM_AARCH64, 64, true,
2283 "elf64-bigaarch64", "aarch64_elf64_be_vec")
2284 { }
2285
2286 template<>
2287 Target_selector_aarch64<64, false>::Target_selector_aarch64()
2288 : Target_selector(elfcpp::EM_AARCH64, 64, false,
2289 "elf64-littleaarch64", "aarch64_elf64_le_vec")
2290 { }
2291
2292 Target_selector_aarch64<32, true> target_selector_aarch64elf32b;
2293 Target_selector_aarch64<32, false> target_selector_aarch64elf32;
2294 Target_selector_aarch64<64, true> target_selector_aarch64elfb;
2295 Target_selector_aarch64<64, false> target_selector_aarch64elf;
2296
2297 } // End anonymous namespace.