1 // aarch64.cc -- aarch64 target support for gold.
3 // Copyright (C) 2014 Free Software Foundation, Inc.
4 // Written by Jing Yu <jingyu@google.com> and Han Shen <shenhan@google.com>.
6 // This file is part of gold.
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.
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.
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.
29 #include "parameters.h"
36 #include "copy-relocs.h"
38 #include "target-reloc.h"
39 #include "target-select.h"
45 #include "aarch64-reloc-property.h"
47 // The first three .got.plt entries are reserved.
48 const int32_t AARCH64_GOTPLT_RESERVE_COUNT
= 3;
55 template<int size
, bool big_endian
>
56 class Output_data_plt_aarch64
;
58 template<int size
, bool big_endian
>
59 class Output_data_plt_aarch64_standard
;
61 template<int size
, bool big_endian
>
64 template<int size
, bool big_endian
>
65 class AArch64_relocate_functions
;
67 // Output_data_got_aarch64 class.
69 template<int size
, bool big_endian
>
70 class Output_data_got_aarch64
: public Output_data_got
<size
, big_endian
>
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
)
79 // Add a static entry for the GOT entry at OFFSET. GSYM is a global
80 // symbol and R_TYPE is the code of a dynamic relocation that needs to be
81 // applied in a static link.
83 add_static_reloc(unsigned int got_offset
, unsigned int r_type
, Symbol
* gsym
)
84 { this->static_relocs_
.push_back(Static_reloc(got_offset
, r_type
, gsym
)); }
87 // Add a static reloc for the GOT entry at OFFSET. RELOBJ is an object
88 // defining a local symbol with INDEX. R_TYPE is the code of a dynamic
89 // relocation that needs to be applied in a static link.
91 add_static_reloc(unsigned int got_offset
, unsigned int r_type
,
92 Sized_relobj_file
<size
, big_endian
>* relobj
,
95 this->static_relocs_
.push_back(Static_reloc(got_offset
, r_type
, relobj
,
101 // Write out the GOT table.
103 do_write(Output_file
* of
) {
104 // The first entry in the GOT is the address of the .dynamic section.
105 gold_assert(this->data_size() >= size
/ 8);
106 Output_section
* dynamic
= this->layout_
->dynamic_section();
107 Valtype dynamic_addr
= dynamic
== NULL
? 0 : dynamic
->address();
108 this->replace_constant(0, dynamic_addr
);
109 Output_data_got
<size
, big_endian
>::do_write(of
);
111 // Handling static relocs
112 if (this->static_relocs_
.empty())
115 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr AArch64_address
;
117 gold_assert(parameters
->doing_static_link());
118 const off_t offset
= this->offset();
119 const section_size_type oview_size
=
120 convert_to_section_size_type(this->data_size());
121 unsigned char* const oview
= of
->get_output_view(offset
, oview_size
);
123 Output_segment
* tls_segment
= this->layout_
->tls_segment();
124 gold_assert(tls_segment
!= NULL
);
126 AArch64_address aligned_tcb_address
=
127 align_address(Target_aarch64
<size
,big_endian
>::TCB_SIZE
,
128 tls_segment
->maximum_alignment());
130 for (size_t i
= 0; i
< this->static_relocs_
.size(); ++i
)
132 Static_reloc
& reloc(this->static_relocs_
[i
]);
133 AArch64_address value
;
135 if (!reloc
.symbol_is_global())
137 Sized_relobj_file
<size
, big_endian
>* object
= reloc
.relobj();
138 const Symbol_value
<size
>* psymval
=
139 reloc
.relobj()->local_symbol(reloc
.index());
141 // We are doing static linking. Issue an error and skip this
142 // relocation if the symbol is undefined or in a discarded_section.
144 unsigned int shndx
= psymval
->input_shndx(&is_ordinary
);
145 if ((shndx
== elfcpp::SHN_UNDEF
)
147 && shndx
!= elfcpp::SHN_UNDEF
148 && !object
->is_section_included(shndx
)
149 && !this->symbol_table_
->is_section_folded(object
, shndx
)))
151 gold_error(_("undefined or discarded local symbol %u from "
152 " object %s in GOT"),
153 reloc
.index(), reloc
.relobj()->name().c_str());
156 value
= psymval
->value(object
, 0);
160 const Symbol
* gsym
= reloc
.symbol();
161 gold_assert(gsym
!= NULL
);
162 if (gsym
->is_forwarder())
163 gsym
= this->symbol_table_
->resolve_forwards(gsym
);
165 // We are doing static linking. Issue an error and skip this
166 // relocation if the symbol is undefined or in a discarded_section
167 // unless it is a weakly_undefined symbol.
168 if ((gsym
->is_defined_in_discarded_section()
169 || gsym
->is_undefined())
170 && !gsym
->is_weak_undefined())
172 gold_error(_("undefined or discarded symbol %s in GOT"),
177 if (!gsym
->is_weak_undefined())
179 const Sized_symbol
<size
>* sym
=
180 static_cast<const Sized_symbol
<size
>*>(gsym
);
181 value
= sym
->value();
187 unsigned got_offset
= reloc
.got_offset();
188 gold_assert(got_offset
< oview_size
);
190 typedef typename
elfcpp::Swap
<size
, big_endian
>::Valtype Valtype
;
191 Valtype
* wv
= reinterpret_cast<Valtype
*>(oview
+ got_offset
);
193 switch (reloc
.r_type())
195 case elfcpp::R_AARCH64_TLS_DTPREL64
:
198 case elfcpp::R_AARCH64_TLS_TPREL64
:
199 x
= value
+ aligned_tcb_address
;
204 elfcpp::Swap
<size
, big_endian
>::writeval(wv
, x
);
207 of
->write_output_view(offset
, oview_size
, oview
);
211 // Symbol table of the output object.
212 Symbol_table
* symbol_table_
;
213 // A pointer to the Layout class, so that we can find the .dynamic
214 // section when we write out the GOT section.
217 // This class represent dynamic relocations that need to be applied by
218 // gold because we are using TLS relocations in a static link.
222 Static_reloc(unsigned int got_offset
, unsigned int r_type
, Symbol
* gsym
)
223 : got_offset_(got_offset
), r_type_(r_type
), symbol_is_global_(true)
224 { this->u_
.global
.symbol
= gsym
; }
226 Static_reloc(unsigned int got_offset
, unsigned int r_type
,
227 Sized_relobj_file
<size
, big_endian
>* relobj
, unsigned int index
)
228 : got_offset_(got_offset
), r_type_(r_type
), symbol_is_global_(false)
230 this->u_
.local
.relobj
= relobj
;
231 this->u_
.local
.index
= index
;
234 // Return the GOT offset.
237 { return this->got_offset_
; }
242 { return this->r_type_
; }
244 // Whether the symbol is global or not.
246 symbol_is_global() const
247 { return this->symbol_is_global_
; }
249 // For a relocation against a global symbol, the global symbol.
253 gold_assert(this->symbol_is_global_
);
254 return this->u_
.global
.symbol
;
257 // For a relocation against a local symbol, the defining object.
258 Sized_relobj_file
<size
, big_endian
>*
261 gold_assert(!this->symbol_is_global_
);
262 return this->u_
.local
.relobj
;
265 // For a relocation against a local symbol, the local symbol index.
269 gold_assert(!this->symbol_is_global_
);
270 return this->u_
.local
.index
;
274 // GOT offset of the entry to which this relocation is applied.
275 unsigned int got_offset_
;
276 // Type of relocation.
277 unsigned int r_type_
;
278 // Whether this relocation is against a global symbol.
279 bool symbol_is_global_
;
280 // A global or local symbol.
285 // For a global symbol, the symbol itself.
290 // For a local symbol, the object defining object.
291 Sized_relobj_file
<size
, big_endian
>* relobj
;
292 // For a local symbol, the symbol index.
296 }; // End of inner class Static_reloc
298 std::vector
<Static_reloc
> static_relocs_
;
299 }; // End of Output_data_got_aarch64
302 AArch64_reloc_property_table
* aarch64_reloc_property_table
= NULL
;
305 // The aarch64 target class.
307 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
308 template<int size
, bool big_endian
>
309 class Target_aarch64
: public Sized_target
<size
, big_endian
>
312 typedef Target_aarch64
<size
,big_endian
> This
;
313 typedef Output_data_reloc
<elfcpp::SHT_RELA
, true, size
, big_endian
>
315 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr Address
;
316 const static int TCB_SIZE
= size
/ 8 * 2;
318 Target_aarch64(const Target::Target_info
* info
= &aarch64_info
)
319 : Sized_target
<size
, big_endian
>(info
),
320 got_(NULL
), plt_(NULL
), got_plt_(NULL
), got_irelative_(NULL
),
321 got_tlsdesc_(NULL
), global_offset_table_(NULL
), rela_dyn_(NULL
),
322 rela_irelative_(NULL
), copy_relocs_(elfcpp::R_AARCH64_COPY
),
323 got_mod_index_offset_(-1U), tlsdesc_reloc_info_(),
324 tls_base_symbol_defined_(false)
327 // Scan the relocations to determine unreferenced sections for
328 // garbage collection.
330 gc_process_relocs(Symbol_table
* symtab
,
332 Sized_relobj_file
<size
, big_endian
>* object
,
333 unsigned int data_shndx
,
334 unsigned int sh_type
,
335 const unsigned char* prelocs
,
337 Output_section
* output_section
,
338 bool needs_special_offset_handling
,
339 size_t local_symbol_count
,
340 const unsigned char* plocal_symbols
);
342 // Scan the relocations to look for symbol adjustments.
344 scan_relocs(Symbol_table
* symtab
,
346 Sized_relobj_file
<size
, big_endian
>* object
,
347 unsigned int data_shndx
,
348 unsigned int sh_type
,
349 const unsigned char* prelocs
,
351 Output_section
* output_section
,
352 bool needs_special_offset_handling
,
353 size_t local_symbol_count
,
354 const unsigned char* plocal_symbols
);
356 // Finalize the sections.
358 do_finalize_sections(Layout
*, const Input_objects
*, Symbol_table
*);
360 // Return the value to use for a dynamic which requires special
363 do_dynsym_value(const Symbol
*) const;
365 // Relocate a section.
367 relocate_section(const Relocate_info
<size
, big_endian
>*,
368 unsigned int sh_type
,
369 const unsigned char* prelocs
,
371 Output_section
* output_section
,
372 bool needs_special_offset_handling
,
374 typename
elfcpp::Elf_types
<size
>::Elf_Addr view_address
,
375 section_size_type view_size
,
376 const Reloc_symbol_changes
*);
378 // Scan the relocs during a relocatable link.
380 scan_relocatable_relocs(Symbol_table
* symtab
,
382 Sized_relobj_file
<size
, big_endian
>* object
,
383 unsigned int data_shndx
,
384 unsigned int sh_type
,
385 const unsigned char* prelocs
,
387 Output_section
* output_section
,
388 bool needs_special_offset_handling
,
389 size_t local_symbol_count
,
390 const unsigned char* plocal_symbols
,
391 Relocatable_relocs
*);
393 // Relocate a section during a relocatable link.
396 const Relocate_info
<size
, big_endian
>*,
397 unsigned int sh_type
,
398 const unsigned char* prelocs
,
400 Output_section
* output_section
,
401 typename
elfcpp::Elf_types
<size
>::Elf_Off offset_in_output_section
,
402 const Relocatable_relocs
*,
404 typename
elfcpp::Elf_types
<size
>::Elf_Addr view_address
,
405 section_size_type view_size
,
406 unsigned char* reloc_view
,
407 section_size_type reloc_view_size
);
409 // Return the symbol index to use for a target specific relocation.
410 // The only target specific relocation is R_AARCH64_TLSDESC for a
411 // local symbol, which is an absolute reloc.
413 do_reloc_symbol_index(void*, unsigned int r_type
) const
415 gold_assert(r_type
== elfcpp::R_AARCH64_TLSDESC
);
419 // Return the addend to use for a target specific relocation.
420 typename
elfcpp::Elf_types
<size
>::Elf_Addr
421 do_reloc_addend(void* arg
, unsigned int r_type
,
422 typename
elfcpp::Elf_types
<size
>::Elf_Addr addend
) const;
424 // Return the PLT section.
426 do_plt_address_for_global(const Symbol
* gsym
) const
427 { return this->plt_section()->address_for_global(gsym
); }
430 do_plt_address_for_local(const Relobj
* relobj
, unsigned int symndx
) const
431 { return this->plt_section()->address_for_local(relobj
, symndx
); }
433 // Return the number of entries in the PLT.
435 plt_entry_count() const;
437 //Return the offset of the first non-reserved PLT entry.
439 first_plt_entry_offset() const;
441 // Return the size of each PLT entry.
443 plt_entry_size() const;
446 tcb_size() const { return This::TCB_SIZE
; }
450 do_select_as_default_target()
452 gold_assert(aarch64_reloc_property_table
== NULL
);
453 aarch64_reloc_property_table
= new AArch64_reloc_property_table();
456 // Add a new reloc argument, returning the index in the vector.
458 add_tlsdesc_info(Sized_relobj_file
<size
, big_endian
>* object
,
461 this->tlsdesc_reloc_info_
.push_back(Tlsdesc_info(object
, r_sym
));
462 return this->tlsdesc_reloc_info_
.size() - 1;
465 virtual Output_data_plt_aarch64
<size
, big_endian
>*
466 do_make_data_plt(Layout
* layout
,
467 Output_data_got_aarch64
<size
, big_endian
>* got
,
468 Output_data_space
* got_plt
,
469 Output_data_space
* got_irelative
)
471 return new Output_data_plt_aarch64_standard
<size
, big_endian
>(
472 layout
, got
, got_plt
, got_irelative
);
475 Output_data_plt_aarch64
<size
, big_endian
>*
476 make_data_plt(Layout
* layout
,
477 Output_data_got_aarch64
<size
, big_endian
>* got
,
478 Output_data_space
* got_plt
,
479 Output_data_space
* got_irelative
)
481 return this->do_make_data_plt(layout
, got
, got_plt
, got_irelative
);
485 // The class which scans relocations.
490 : issued_non_pic_error_(false)
494 local(Symbol_table
* symtab
, Layout
* layout
, Target_aarch64
* target
,
495 Sized_relobj_file
<size
, big_endian
>* object
,
496 unsigned int data_shndx
,
497 Output_section
* output_section
,
498 const elfcpp::Rela
<size
, big_endian
>& reloc
, unsigned int r_type
,
499 const elfcpp::Sym
<size
, big_endian
>& lsym
,
503 global(Symbol_table
* symtab
, Layout
* layout
, Target_aarch64
* target
,
504 Sized_relobj_file
<size
, big_endian
>* object
,
505 unsigned int data_shndx
,
506 Output_section
* output_section
,
507 const elfcpp::Rela
<size
, big_endian
>& reloc
, unsigned int r_type
,
511 local_reloc_may_be_function_pointer(Symbol_table
* , Layout
* ,
512 Target_aarch64
<size
, big_endian
>* ,
513 Sized_relobj_file
<size
, big_endian
>* ,
516 const elfcpp::Rela
<size
, big_endian
>& ,
518 const elfcpp::Sym
<size
, big_endian
>&);
521 global_reloc_may_be_function_pointer(Symbol_table
* , Layout
* ,
522 Target_aarch64
<size
, big_endian
>* ,
523 Sized_relobj_file
<size
, big_endian
>* ,
526 const elfcpp::Rela
<size
, big_endian
>& ,
532 unsupported_reloc_local(Sized_relobj_file
<size
, big_endian
>*,
533 unsigned int r_type
);
536 unsupported_reloc_global(Sized_relobj_file
<size
, big_endian
>*,
537 unsigned int r_type
, Symbol
*);
540 possible_function_pointer_reloc(unsigned int r_type
);
543 check_non_pic(Relobj
*, unsigned int r_type
);
545 // Whether we have issued an error about a non-PIC compilation.
546 bool issued_non_pic_error_
;
549 // The class which implements relocation.
554 : skip_call_tls_get_addr_(false)
560 // Do a relocation. Return false if the caller should not issue
561 // any warnings about this relocation.
563 relocate(const Relocate_info
<size
, big_endian
>*, Target_aarch64
*,
565 size_t relnum
, const elfcpp::Rela
<size
, big_endian
>&,
566 unsigned int r_type
, const Sized_symbol
<size
>*,
567 const Symbol_value
<size
>*,
568 unsigned char*, typename
elfcpp::Elf_types
<size
>::Elf_Addr
,
572 inline typename AArch64_relocate_functions
<size
,big_endian
>::Status
573 relocate_tls(const Relocate_info
<size
,big_endian
>*,
574 Target_aarch64
<size
, big_endian
>*,
576 const elfcpp::Rela
<size
, big_endian
>&,
577 unsigned int r_type
, const Sized_symbol
<size
>*,
578 const Symbol_value
<size
>*,
580 typename
elfcpp::Elf_types
<size
>::Elf_Addr
);
582 inline typename AArch64_relocate_functions
<size
,big_endian
>::Status
584 const Relocate_info
<size
,big_endian
>*,
585 Target_aarch64
<size
, big_endian
>*,
586 const elfcpp::Rela
<size
, big_endian
>&,
589 const Symbol_value
<size
>*);
591 inline typename AArch64_relocate_functions
<size
,big_endian
>::Status
593 const Relocate_info
<size
,big_endian
>*,
594 Target_aarch64
<size
, big_endian
>*,
595 const elfcpp::Rela
<size
, big_endian
>&,
598 const Symbol_value
<size
>*);
600 inline typename AArch64_relocate_functions
<size
,big_endian
>::Status
602 const Relocate_info
<size
,big_endian
>*,
603 Target_aarch64
<size
, big_endian
>*,
604 const elfcpp::Rela
<size
, big_endian
>&,
607 const Symbol_value
<size
>*);
609 inline typename AArch64_relocate_functions
<size
,big_endian
>::Status
611 const Relocate_info
<size
,big_endian
>*,
612 Target_aarch64
<size
, big_endian
>*,
613 const elfcpp::Rela
<size
, big_endian
>&,
616 const Symbol_value
<size
>*,
617 typename
elfcpp::Elf_types
<size
>::Elf_Addr
,
618 typename
elfcpp::Elf_types
<size
>::Elf_Addr
);
620 bool skip_call_tls_get_addr_
;
622 }; // End of class Relocate
624 // A class which returns the size required for a relocation type,
625 // used while scanning relocs during a relocatable link.
626 class Relocatable_size_for_reloc
630 get_size_for_reloc(unsigned int, Relobj
*);
633 // Adjust TLS relocation type based on the options and whether this
634 // is a local symbol.
635 static tls::Tls_optimization
636 optimize_tls_reloc(bool is_final
, int r_type
);
638 // Get the GOT section, creating it if necessary.
639 Output_data_got_aarch64
<size
, big_endian
>*
640 got_section(Symbol_table
*, Layout
*);
642 // Get the GOT PLT section.
644 got_plt_section() const
646 gold_assert(this->got_plt_
!= NULL
);
647 return this->got_plt_
;
650 // Get the GOT section for TLSDESC entries.
651 Output_data_got
<size
, big_endian
>*
652 got_tlsdesc_section() const
654 gold_assert(this->got_tlsdesc_
!= NULL
);
655 return this->got_tlsdesc_
;
658 // Create the PLT section.
660 make_plt_section(Symbol_table
* symtab
, Layout
* layout
);
662 // Create a PLT entry for a global symbol.
664 make_plt_entry(Symbol_table
*, Layout
*, Symbol
*);
666 // Create a PLT entry for a local STT_GNU_IFUNC symbol.
668 make_local_ifunc_plt_entry(Symbol_table
*, Layout
*,
669 Sized_relobj_file
<size
, big_endian
>* relobj
,
670 unsigned int local_sym_index
);
672 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
674 define_tls_base_symbol(Symbol_table
*, Layout
*);
676 // Create the reserved PLT and GOT entries for the TLS descriptor resolver.
678 reserve_tlsdesc_entries(Symbol_table
* symtab
, Layout
* layout
);
680 // Create a GOT entry for the TLS module index.
682 got_mod_index_entry(Symbol_table
* symtab
, Layout
* layout
,
683 Sized_relobj_file
<size
, big_endian
>* object
);
685 // Get the PLT section.
686 Output_data_plt_aarch64
<size
, big_endian
>*
689 gold_assert(this->plt_
!= NULL
);
693 // Get the dynamic reloc section, creating it if necessary.
695 rela_dyn_section(Layout
*);
697 // Get the section to use for TLSDESC relocations.
699 rela_tlsdesc_section(Layout
*) const;
701 // Get the section to use for IRELATIVE relocations.
703 rela_irelative_section(Layout
*);
705 // Add a potential copy relocation.
707 copy_reloc(Symbol_table
* symtab
, Layout
* layout
,
708 Sized_relobj_file
<size
, big_endian
>* object
,
709 unsigned int shndx
, Output_section
* output_section
,
710 Symbol
* sym
, const elfcpp::Rela
<size
, big_endian
>& reloc
)
712 this->copy_relocs_
.copy_reloc(symtab
, layout
,
713 symtab
->get_sized_symbol
<size
>(sym
),
714 object
, shndx
, output_section
,
715 reloc
, this->rela_dyn_section(layout
));
718 // Information about this specific target which we pass to the
719 // general Target structure.
720 static const Target::Target_info aarch64_info
;
722 // The types of GOT entries needed for this platform.
723 // These values are exposed to the ABI in an incremental link.
724 // Do not renumber existing values without changing the version
725 // number of the .gnu_incremental_inputs section.
728 GOT_TYPE_STANDARD
= 0, // GOT entry for a regular symbol
729 GOT_TYPE_TLS_OFFSET
= 1, // GOT entry for TLS offset
730 GOT_TYPE_TLS_PAIR
= 2, // GOT entry for TLS module/offset pair
731 GOT_TYPE_TLS_DESC
= 3 // GOT entry for TLS_DESC pair
734 // This type is used as the argument to the target specific
735 // relocation routines. The only target specific reloc is
736 // R_AARCh64_TLSDESC against a local symbol.
739 Tlsdesc_info(Sized_relobj_file
<size
, big_endian
>* a_object
,
740 unsigned int a_r_sym
)
741 : object(a_object
), r_sym(a_r_sym
)
744 // The object in which the local symbol is defined.
745 Sized_relobj_file
<size
, big_endian
>* object
;
746 // The local symbol index in the object.
751 Output_data_got_aarch64
<size
, big_endian
>* got_
;
753 Output_data_plt_aarch64
<size
, big_endian
>* plt_
;
754 // The GOT PLT section.
755 Output_data_space
* got_plt_
;
756 // The GOT section for IRELATIVE relocations.
757 Output_data_space
* got_irelative_
;
758 // The GOT section for TLSDESC relocations.
759 Output_data_got
<size
, big_endian
>* got_tlsdesc_
;
760 // The _GLOBAL_OFFSET_TABLE_ symbol.
761 Symbol
* global_offset_table_
;
762 // The dynamic reloc section.
763 Reloc_section
* rela_dyn_
;
764 // The section to use for IRELATIVE relocs.
765 Reloc_section
* rela_irelative_
;
766 // Relocs saved to avoid a COPY reloc.
767 Copy_relocs
<elfcpp::SHT_RELA
, size
, big_endian
> copy_relocs_
;
768 // Offset of the GOT entry for the TLS module index.
769 unsigned int got_mod_index_offset_
;
770 // We handle R_AARCH64_TLSDESC against a local symbol as a target
771 // specific relocation. Here we store the object and local symbol
772 // index for the relocation.
773 std::vector
<Tlsdesc_info
> tlsdesc_reloc_info_
;
774 // True if the _TLS_MODULE_BASE_ symbol has been defined.
775 bool tls_base_symbol_defined_
;
776 }; // End of Target_aarch64
780 const Target::Target_info Target_aarch64
<64, false>::aarch64_info
=
783 false, // is_big_endian
784 elfcpp::EM_AARCH64
, // machine_code
785 false, // has_make_symbol
786 false, // has_resolve
787 false, // has_code_fill
788 true, // is_default_stack_executable
789 false, // can_icf_inline_merge_sections
791 "/lib/ld.so.1", // program interpreter
792 0x400000, // default_text_segment_address
793 0x1000, // abi_pagesize (overridable by -z max-page-size)
794 0x1000, // common_pagesize (overridable by -z common-page-size)
795 false, // isolate_execinstr
797 elfcpp::SHN_UNDEF
, // small_common_shndx
798 elfcpp::SHN_UNDEF
, // large_common_shndx
799 0, // small_common_section_flags
800 0, // large_common_section_flags
801 NULL
, // attributes_section
802 NULL
, // attributes_vendor
803 "_start" // entry_symbol_name
807 const Target::Target_info Target_aarch64
<32, false>::aarch64_info
=
810 false, // is_big_endian
811 elfcpp::EM_AARCH64
, // machine_code
812 false, // has_make_symbol
813 false, // has_resolve
814 false, // has_code_fill
815 true, // is_default_stack_executable
816 false, // can_icf_inline_merge_sections
818 "/lib/ld.so.1", // program interpreter
819 0x400000, // default_text_segment_address
820 0x1000, // abi_pagesize (overridable by -z max-page-size)
821 0x1000, // common_pagesize (overridable by -z common-page-size)
822 false, // isolate_execinstr
824 elfcpp::SHN_UNDEF
, // small_common_shndx
825 elfcpp::SHN_UNDEF
, // large_common_shndx
826 0, // small_common_section_flags
827 0, // large_common_section_flags
828 NULL
, // attributes_section
829 NULL
, // attributes_vendor
830 "_start" // entry_symbol_name
834 const Target::Target_info Target_aarch64
<64, true>::aarch64_info
=
837 true, // is_big_endian
838 elfcpp::EM_AARCH64
, // machine_code
839 false, // has_make_symbol
840 false, // has_resolve
841 false, // has_code_fill
842 true, // is_default_stack_executable
843 false, // can_icf_inline_merge_sections
845 "/lib/ld.so.1", // program interpreter
846 0x400000, // default_text_segment_address
847 0x1000, // abi_pagesize (overridable by -z max-page-size)
848 0x1000, // common_pagesize (overridable by -z common-page-size)
849 false, // isolate_execinstr
851 elfcpp::SHN_UNDEF
, // small_common_shndx
852 elfcpp::SHN_UNDEF
, // large_common_shndx
853 0, // small_common_section_flags
854 0, // large_common_section_flags
855 NULL
, // attributes_section
856 NULL
, // attributes_vendor
857 "_start" // entry_symbol_name
861 const Target::Target_info Target_aarch64
<32, true>::aarch64_info
=
864 true, // is_big_endian
865 elfcpp::EM_AARCH64
, // machine_code
866 false, // has_make_symbol
867 false, // has_resolve
868 false, // has_code_fill
869 true, // is_default_stack_executable
870 false, // can_icf_inline_merge_sections
872 "/lib/ld.so.1", // program interpreter
873 0x400000, // default_text_segment_address
874 0x1000, // abi_pagesize (overridable by -z max-page-size)
875 0x1000, // common_pagesize (overridable by -z common-page-size)
876 false, // isolate_execinstr
878 elfcpp::SHN_UNDEF
, // small_common_shndx
879 elfcpp::SHN_UNDEF
, // large_common_shndx
880 0, // small_common_section_flags
881 0, // large_common_section_flags
882 NULL
, // attributes_section
883 NULL
, // attributes_vendor
884 "_start" // entry_symbol_name
887 // Get the GOT section, creating it if necessary.
889 template<int size
, bool big_endian
>
890 Output_data_got_aarch64
<size
, big_endian
>*
891 Target_aarch64
<size
, big_endian
>::got_section(Symbol_table
* symtab
,
894 if (this->got_
== NULL
)
896 gold_assert(symtab
!= NULL
&& layout
!= NULL
);
898 // When using -z now, we can treat .got.plt as a relro section.
899 // Without -z now, it is modified after program startup by lazy
901 bool is_got_plt_relro
= parameters
->options().now();
902 Output_section_order got_order
= (is_got_plt_relro
905 Output_section_order got_plt_order
= (is_got_plt_relro
907 : ORDER_NON_RELRO_FIRST
);
909 // Layout of .got and .got.plt sections.
910 // .got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
912 // .gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
913 // .gotplt[1] reserved for ld.so (resolver)
914 // .gotplt[2] reserved
916 // Generate .got section.
917 this->got_
= new Output_data_got_aarch64
<size
, big_endian
>(symtab
,
919 layout
->add_output_section_data(".got", elfcpp::SHT_PROGBITS
,
920 (elfcpp::SHF_ALLOC
| elfcpp::SHF_WRITE
),
921 this->got_
, got_order
, true);
922 // The first word of GOT is reserved for the address of .dynamic.
923 // We put 0 here now. The value will be replaced later in
924 // Output_data_got_aarch64::do_write.
925 this->got_
->add_constant(0);
927 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
928 // _GLOBAL_OFFSET_TABLE_ value points to the start of the .got section,
929 // even if there is a .got.plt section.
930 this->global_offset_table_
=
931 symtab
->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL
,
932 Symbol_table::PREDEFINED
,
934 0, 0, elfcpp::STT_OBJECT
,
936 elfcpp::STV_HIDDEN
, 0,
939 // Generate .got.plt section.
940 this->got_plt_
= new Output_data_space(size
/ 8, "** GOT PLT");
941 layout
->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS
,
943 | elfcpp::SHF_WRITE
),
944 this->got_plt_
, got_plt_order
,
947 // The first three entries are reserved.
948 this->got_plt_
->set_current_data_size(
949 AARCH64_GOTPLT_RESERVE_COUNT
* (size
/ 8));
951 // If there are any IRELATIVE relocations, they get GOT entries
952 // in .got.plt after the jump slot entries.
953 this->got_irelative_
= new Output_data_space(size
/ 8,
954 "** GOT IRELATIVE PLT");
955 layout
->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS
,
957 | elfcpp::SHF_WRITE
),
958 this->got_irelative_
,
962 // If there are any TLSDESC relocations, they get GOT entries in
963 // .got.plt after the jump slot and IRELATIVE entries.
964 this->got_tlsdesc_
= new Output_data_got
<size
, big_endian
>();
965 layout
->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS
,
967 | elfcpp::SHF_WRITE
),
972 if (!is_got_plt_relro
)
974 // Those bytes can go into the relro segment.
975 layout
->increase_relro(
976 AARCH64_GOTPLT_RESERVE_COUNT
* (size
/ 8));
983 // Get the dynamic reloc section, creating it if necessary.
985 template<int size
, bool big_endian
>
986 typename Target_aarch64
<size
, big_endian
>::Reloc_section
*
987 Target_aarch64
<size
, big_endian
>::rela_dyn_section(Layout
* layout
)
989 if (this->rela_dyn_
== NULL
)
991 gold_assert(layout
!= NULL
);
992 this->rela_dyn_
= new Reloc_section(parameters
->options().combreloc());
993 layout
->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA
,
994 elfcpp::SHF_ALLOC
, this->rela_dyn_
,
995 ORDER_DYNAMIC_RELOCS
, false);
997 return this->rela_dyn_
;
1000 // Get the section to use for IRELATIVE relocs, creating it if
1001 // necessary. These go in .rela.dyn, but only after all other dynamic
1002 // relocations. They need to follow the other dynamic relocations so
1003 // that they can refer to global variables initialized by those
1006 template<int size
, bool big_endian
>
1007 typename Target_aarch64
<size
, big_endian
>::Reloc_section
*
1008 Target_aarch64
<size
, big_endian
>::rela_irelative_section(Layout
* layout
)
1010 if (this->rela_irelative_
== NULL
)
1012 // Make sure we have already created the dynamic reloc section.
1013 this->rela_dyn_section(layout
);
1014 this->rela_irelative_
= new Reloc_section(false);
1015 layout
->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA
,
1016 elfcpp::SHF_ALLOC
, this->rela_irelative_
,
1017 ORDER_DYNAMIC_RELOCS
, false);
1018 gold_assert(this->rela_dyn_
->output_section()
1019 == this->rela_irelative_
->output_section());
1021 return this->rela_irelative_
;
1025 // A class to handle the PLT data.
1026 // This is an abstract base class that handles most of the linker details
1027 // but does not know the actual contents of PLT entries. The derived
1028 // classes below fill in those details.
1030 template<int size
, bool big_endian
>
1031 class Output_data_plt_aarch64
: public Output_section_data
1034 typedef Output_data_reloc
<elfcpp::SHT_RELA
, true, size
, big_endian
>
1036 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr Address
;
1038 Output_data_plt_aarch64(Layout
* layout
,
1040 Output_data_got_aarch64
<size
, big_endian
>* got
,
1041 Output_data_space
* got_plt
,
1042 Output_data_space
* got_irelative
)
1043 : Output_section_data(addralign
), tlsdesc_rel_(NULL
),
1044 got_(got
), got_plt_(got_plt
), got_irelative_(got_irelative
),
1045 count_(0), irelative_count_(0), tlsdesc_got_offset_(-1U)
1046 { this->init(layout
); }
1048 // Initialize the PLT section.
1050 init(Layout
* layout
);
1052 // Add an entry to the PLT.
1054 add_entry(Symbol
* gsym
);
1056 // Add the reserved TLSDESC_PLT entry to the PLT.
1058 reserve_tlsdesc_entry(unsigned int got_offset
)
1059 { this->tlsdesc_got_offset_
= got_offset
; }
1061 // Return true if a TLSDESC_PLT entry has been reserved.
1063 has_tlsdesc_entry() const
1064 { return this->tlsdesc_got_offset_
!= -1U; }
1066 // Return the GOT offset for the reserved TLSDESC_PLT entry.
1068 get_tlsdesc_got_offset() const
1069 { return this->tlsdesc_got_offset_
; }
1071 // Return the PLT offset of the reserved TLSDESC_PLT entry.
1073 get_tlsdesc_plt_offset() const
1075 return (this->first_plt_entry_offset() +
1076 (this->count_
+ this->irelative_count_
)
1077 * this->get_plt_entry_size());
1080 // Return the .rela.plt section data.
1083 { return this->rel_
; }
1085 // Return where the TLSDESC relocations should go.
1087 rela_tlsdesc(Layout
*);
1089 // Return where the IRELATIVE relocations should go in the PLT
1092 rela_irelative(Symbol_table
*, Layout
*);
1094 // Return whether we created a section for IRELATIVE relocations.
1096 has_irelative_section() const
1097 { return this->irelative_rel_
!= NULL
; }
1099 // Return the number of PLT entries.
1102 { return this->count_
+ this->irelative_count_
; }
1104 // Return the offset of the first non-reserved PLT entry.
1106 first_plt_entry_offset() const
1107 { return this->do_first_plt_entry_offset(); }
1109 // Return the size of a PLT entry.
1111 get_plt_entry_size() const
1112 { return this->do_get_plt_entry_size(); }
1114 // Return the reserved tlsdesc entry size.
1116 get_plt_tlsdesc_entry_size() const
1117 { return this->do_get_plt_tlsdesc_entry_size(); }
1119 // Return the PLT address to use for a global symbol.
1121 address_for_global(const Symbol
*);
1123 // Return the PLT address to use for a local symbol.
1125 address_for_local(const Relobj
*, unsigned int symndx
);
1128 // Fill in the first PLT entry.
1130 fill_first_plt_entry(unsigned char* pov
,
1131 Address got_address
,
1132 Address plt_address
)
1133 { this->do_fill_first_plt_entry(pov
, got_address
, plt_address
); }
1135 // Fill in a normal PLT entry.
1137 fill_plt_entry(unsigned char* pov
,
1138 Address got_address
,
1139 Address plt_address
,
1140 unsigned int got_offset
,
1141 unsigned int plt_offset
)
1143 this->do_fill_plt_entry(pov
, got_address
, plt_address
,
1144 got_offset
, plt_offset
);
1147 // Fill in the reserved TLSDESC PLT entry.
1149 fill_tlsdesc_entry(unsigned char* pov
,
1150 Address gotplt_address
,
1151 Address plt_address
,
1153 unsigned int tlsdesc_got_offset
,
1154 unsigned int plt_offset
)
1156 this->do_fill_tlsdesc_entry(pov
, gotplt_address
, plt_address
, got_base
,
1157 tlsdesc_got_offset
, plt_offset
);
1160 virtual unsigned int
1161 do_first_plt_entry_offset() const = 0;
1163 virtual unsigned int
1164 do_get_plt_entry_size() const = 0;
1166 virtual unsigned int
1167 do_get_plt_tlsdesc_entry_size() const = 0;
1170 do_fill_first_plt_entry(unsigned char* pov
,
1172 Address plt_addr
) = 0;
1175 do_fill_plt_entry(unsigned char* pov
,
1176 Address got_address
,
1177 Address plt_address
,
1178 unsigned int got_offset
,
1179 unsigned int plt_offset
) = 0;
1182 do_fill_tlsdesc_entry(unsigned char* pov
,
1183 Address gotplt_address
,
1184 Address plt_address
,
1186 unsigned int tlsdesc_got_offset
,
1187 unsigned int plt_offset
) = 0;
1190 do_adjust_output_section(Output_section
* os
);
1192 // Write to a map file.
1194 do_print_to_mapfile(Mapfile
* mapfile
) const
1195 { mapfile
->print_output_data(this, _("** PLT")); }
1198 // Set the final size.
1200 set_final_data_size();
1202 // Write out the PLT data.
1204 do_write(Output_file
*);
1206 // The reloc section.
1207 Reloc_section
* rel_
;
1209 // The TLSDESC relocs, if necessary. These must follow the regular
1211 Reloc_section
* tlsdesc_rel_
;
1213 // The IRELATIVE relocs, if necessary. These must follow the
1214 // regular PLT relocations.
1215 Reloc_section
* irelative_rel_
;
1217 // The .got section.
1218 Output_data_got_aarch64
<size
, big_endian
>* got_
;
1220 // The .got.plt section.
1221 Output_data_space
* got_plt_
;
1223 // The part of the .got.plt section used for IRELATIVE relocs.
1224 Output_data_space
* got_irelative_
;
1226 // The number of PLT entries.
1227 unsigned int count_
;
1229 // Number of PLT entries with R_X86_64_IRELATIVE relocs. These
1230 // follow the regular PLT entries.
1231 unsigned int irelative_count_
;
1233 // GOT offset of the reserved TLSDESC_GOT entry for the lazy trampoline.
1234 // Communicated to the loader via DT_TLSDESC_GOT. The magic value -1
1235 // indicates an offset is not allocated.
1236 unsigned int tlsdesc_got_offset_
;
1239 // Initialize the PLT section.
1241 template<int size
, bool big_endian
>
1243 Output_data_plt_aarch64
<size
, big_endian
>::init(Layout
* layout
)
1245 this->rel_
= new Reloc_section(false);
1246 layout
->add_output_section_data(".rela.plt", elfcpp::SHT_RELA
,
1247 elfcpp::SHF_ALLOC
, this->rel_
,
1248 ORDER_DYNAMIC_PLT_RELOCS
, false);
1251 template<int size
, bool big_endian
>
1253 Output_data_plt_aarch64
<size
, big_endian
>::do_adjust_output_section(
1256 os
->set_entsize(this->get_plt_entry_size());
1259 // Add an entry to the PLT.
1261 template<int size
, bool big_endian
>
1263 Output_data_plt_aarch64
<size
, big_endian
>::add_entry(Symbol
* gsym
)
1265 gold_assert(!gsym
->has_plt_offset());
1267 gsym
->set_plt_offset((this->count_
) * this->get_plt_entry_size()
1268 + this->first_plt_entry_offset());
1272 section_offset_type got_offset
= this->got_plt_
->current_data_size();
1274 // Every PLT entry needs a GOT entry which points back to the PLT
1275 // entry (this will be changed by the dynamic linker, normally
1276 // lazily when the function is called).
1277 this->got_plt_
->set_current_data_size(got_offset
+ size
/ 8);
1279 // Every PLT entry needs a reloc.
1280 gsym
->set_needs_dynsym_entry();
1281 this->rel_
->add_global(gsym
, elfcpp::R_AARCH64_JUMP_SLOT
,
1282 this->got_plt_
, got_offset
, 0);
1284 // Note that we don't need to save the symbol. The contents of the
1285 // PLT are independent of which symbols are used. The symbols only
1286 // appear in the relocations.
1289 // Return where the TLSDESC relocations should go, creating it if
1290 // necessary. These follow the JUMP_SLOT relocations.
1292 template<int size
, bool big_endian
>
1293 typename Output_data_plt_aarch64
<size
, big_endian
>::Reloc_section
*
1294 Output_data_plt_aarch64
<size
, big_endian
>::rela_tlsdesc(Layout
* layout
)
1296 if (this->tlsdesc_rel_
== NULL
)
1298 this->tlsdesc_rel_
= new Reloc_section(false);
1299 layout
->add_output_section_data(".rela.plt", elfcpp::SHT_RELA
,
1300 elfcpp::SHF_ALLOC
, this->tlsdesc_rel_
,
1301 ORDER_DYNAMIC_PLT_RELOCS
, false);
1302 gold_assert(this->tlsdesc_rel_
->output_section()
1303 == this->rel_
->output_section());
1305 return this->tlsdesc_rel_
;
1308 // Return where the IRELATIVE relocations should go in the PLT. These
1309 // follow the JUMP_SLOT and the TLSDESC relocations.
1311 template<int size
, bool big_endian
>
1312 typename Output_data_plt_aarch64
<size
, big_endian
>::Reloc_section
*
1313 Output_data_plt_aarch64
<size
, big_endian
>::rela_irelative(Symbol_table
* symtab
,
1316 if (this->irelative_rel_
== NULL
)
1318 // Make sure we have a place for the TLSDESC relocations, in
1319 // case we see any later on.
1320 this->rela_tlsdesc(layout
);
1321 this->irelative_rel_
= new Reloc_section(false);
1322 layout
->add_output_section_data(".rela.plt", elfcpp::SHT_RELA
,
1323 elfcpp::SHF_ALLOC
, this->irelative_rel_
,
1324 ORDER_DYNAMIC_PLT_RELOCS
, false);
1325 gold_assert(this->irelative_rel_
->output_section()
1326 == this->rel_
->output_section());
1328 if (parameters
->doing_static_link())
1330 // A statically linked executable will only have a .rela.plt
1331 // section to hold R_AARCH64_IRELATIVE relocs for
1332 // STT_GNU_IFUNC symbols. The library will use these
1333 // symbols to locate the IRELATIVE relocs at program startup
1335 symtab
->define_in_output_data("__rela_iplt_start", NULL
,
1336 Symbol_table::PREDEFINED
,
1337 this->irelative_rel_
, 0, 0,
1338 elfcpp::STT_NOTYPE
, elfcpp::STB_GLOBAL
,
1339 elfcpp::STV_HIDDEN
, 0, false, true);
1340 symtab
->define_in_output_data("__rela_iplt_end", NULL
,
1341 Symbol_table::PREDEFINED
,
1342 this->irelative_rel_
, 0, 0,
1343 elfcpp::STT_NOTYPE
, elfcpp::STB_GLOBAL
,
1344 elfcpp::STV_HIDDEN
, 0, true, true);
1347 return this->irelative_rel_
;
1350 // Return the PLT address to use for a global symbol.
1352 template<int size
, bool big_endian
>
1354 Output_data_plt_aarch64
<size
, big_endian
>::address_for_global(
1357 uint64_t offset
= 0;
1358 if (gsym
->type() == elfcpp::STT_GNU_IFUNC
1359 && gsym
->can_use_relative_reloc(false))
1360 offset
= (this->first_plt_entry_offset() +
1361 this->count_
* this->get_plt_entry_size());
1362 return this->address() + offset
+ gsym
->plt_offset();
1365 // Return the PLT address to use for a local symbol. These are always
1366 // IRELATIVE relocs.
1368 template<int size
, bool big_endian
>
1370 Output_data_plt_aarch64
<size
, big_endian
>::address_for_local(
1371 const Relobj
* object
,
1374 return (this->address()
1375 + this->first_plt_entry_offset()
1376 + this->count_
* this->get_plt_entry_size()
1377 + object
->local_plt_offset(r_sym
));
1380 // Set the final size.
1382 template<int size
, bool big_endian
>
1384 Output_data_plt_aarch64
<size
, big_endian
>::set_final_data_size()
1386 unsigned int count
= this->count_
+ this->irelative_count_
;
1387 unsigned int extra_size
= 0;
1388 if (this->has_tlsdesc_entry())
1389 extra_size
+= this->get_plt_tlsdesc_entry_size();
1390 this->set_data_size(this->first_plt_entry_offset()
1391 + count
* this->get_plt_entry_size()
1395 template<int size
, bool big_endian
>
1396 class Output_data_plt_aarch64_standard
:
1397 public Output_data_plt_aarch64
<size
, big_endian
>
1400 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr Address
;
1401 Output_data_plt_aarch64_standard(
1403 Output_data_got_aarch64
<size
, big_endian
>* got
,
1404 Output_data_space
* got_plt
,
1405 Output_data_space
* got_irelative
)
1406 : Output_data_plt_aarch64
<size
, big_endian
>(layout
,
1413 // Return the offset of the first non-reserved PLT entry.
1414 virtual unsigned int
1415 do_first_plt_entry_offset() const
1416 { return this->first_plt_entry_size
; }
1418 // Return the size of a PLT entry
1419 virtual unsigned int
1420 do_get_plt_entry_size() const
1421 { return this->plt_entry_size
; }
1423 // Return the size of a tlsdesc entry
1424 virtual unsigned int
1425 do_get_plt_tlsdesc_entry_size() const
1426 { return this->plt_tlsdesc_entry_size
; }
1429 do_fill_first_plt_entry(unsigned char* pov
,
1430 Address got_address
,
1431 Address plt_address
);
1434 do_fill_plt_entry(unsigned char* pov
,
1435 Address got_address
,
1436 Address plt_address
,
1437 unsigned int got_offset
,
1438 unsigned int plt_offset
);
1441 do_fill_tlsdesc_entry(unsigned char* pov
,
1442 Address gotplt_address
,
1443 Address plt_address
,
1445 unsigned int tlsdesc_got_offset
,
1446 unsigned int plt_offset
);
1449 // The size of the first plt entry size.
1450 static const int first_plt_entry_size
= 32;
1451 // The size of the plt entry size.
1452 static const int plt_entry_size
= 16;
1453 // The size of the plt tlsdesc entry size.
1454 static const int plt_tlsdesc_entry_size
= 32;
1455 // Template for the first PLT entry.
1456 static const uint32_t first_plt_entry
[first_plt_entry_size
/ 4];
1457 // Template for subsequent PLT entries.
1458 static const uint32_t plt_entry
[plt_entry_size
/ 4];
1459 // The reserved TLSDESC entry in the PLT for an executable.
1460 static const uint32_t tlsdesc_plt_entry
[plt_tlsdesc_entry_size
/ 4];
1463 // The first entry in the PLT for an executable.
1467 Output_data_plt_aarch64_standard
<32, false>::
1468 first_plt_entry
[first_plt_entry_size
/ 4] =
1470 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
1471 0x90000010, /* adrp x16, PLT_GOT+0x8 */
1472 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
1473 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
1474 0xd61f0220, /* br x17 */
1475 0xd503201f, /* nop */
1476 0xd503201f, /* nop */
1477 0xd503201f, /* nop */
1482 Output_data_plt_aarch64_standard
<32, true>::
1483 first_plt_entry
[first_plt_entry_size
/ 4] =
1485 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
1486 0x90000010, /* adrp x16, PLT_GOT+0x8 */
1487 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
1488 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
1489 0xd61f0220, /* br x17 */
1490 0xd503201f, /* nop */
1491 0xd503201f, /* nop */
1492 0xd503201f, /* nop */
1497 Output_data_plt_aarch64_standard
<64, false>::
1498 first_plt_entry
[first_plt_entry_size
/ 4] =
1500 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
1501 0x90000010, /* adrp x16, PLT_GOT+16 */
1502 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
1503 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
1504 0xd61f0220, /* br x17 */
1505 0xd503201f, /* nop */
1506 0xd503201f, /* nop */
1507 0xd503201f, /* nop */
1512 Output_data_plt_aarch64_standard
<64, true>::
1513 first_plt_entry
[first_plt_entry_size
/ 4] =
1515 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
1516 0x90000010, /* adrp x16, PLT_GOT+16 */
1517 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
1518 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
1519 0xd61f0220, /* br x17 */
1520 0xd503201f, /* nop */
1521 0xd503201f, /* nop */
1522 0xd503201f, /* nop */
1527 Output_data_plt_aarch64_standard
<32, false>::
1528 plt_entry
[plt_entry_size
/ 4] =
1530 0x90000010, /* adrp x16, PLTGOT + n * 4 */
1531 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
1532 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
1533 0xd61f0220, /* br x17. */
1538 Output_data_plt_aarch64_standard
<32, true>::
1539 plt_entry
[plt_entry_size
/ 4] =
1541 0x90000010, /* adrp x16, PLTGOT + n * 4 */
1542 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
1543 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
1544 0xd61f0220, /* br x17. */
1549 Output_data_plt_aarch64_standard
<64, false>::
1550 plt_entry
[plt_entry_size
/ 4] =
1552 0x90000010, /* adrp x16, PLTGOT + n * 8 */
1553 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
1554 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
1555 0xd61f0220, /* br x17. */
1560 Output_data_plt_aarch64_standard
<64, true>::
1561 plt_entry
[plt_entry_size
/ 4] =
1563 0x90000010, /* adrp x16, PLTGOT + n * 8 */
1564 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
1565 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
1566 0xd61f0220, /* br x17. */
1569 template<int size
, bool big_endian
>
1571 Output_data_plt_aarch64_standard
<size
, big_endian
>::do_fill_first_plt_entry(
1573 Address got_address
,
1574 Address plt_address
)
1576 // PLT0 of the small PLT looks like this in ELF64 -
1577 // stp x16, x30, [sp, #-16]! Save the reloc and lr on stack.
1578 // adrp x16, PLT_GOT + 16 Get the page base of the GOTPLT
1579 // ldr x17, [x16, #:lo12:PLT_GOT+16] Load the address of the
1581 // add x16, x16, #:lo12:PLT_GOT+16 Load the lo12 bits of the
1582 // GOTPLT entry for this.
1584 // PLT0 will be slightly different in ELF32 due to different got entry
1586 memcpy(pov
, this->first_plt_entry
, this->first_plt_entry_size
);
1587 Address gotplt_2nd_ent
= got_address
+ (size
/ 8) * 2;
1589 // Fill in the top 21 bits for this: ADRP x16, PLT_GOT + 8 * 2.
1590 // ADRP: (PG(S+A)-PG(P)) >> 12) & 0x1fffff.
1591 // FIXME: This only works for 64bit
1592 AArch64_relocate_functions
<size
, big_endian
>::adrp(pov
+ 4,
1593 gotplt_2nd_ent
, plt_address
+ 4);
1595 // Fill in R_AARCH64_LDST8_LO12
1596 elfcpp::Swap
<32, big_endian
>::writeval(
1598 ((this->first_plt_entry
[2] & 0xffc003ff)
1599 | ((gotplt_2nd_ent
& 0xff8) << 7)));
1601 // Fill in R_AARCH64_ADD_ABS_LO12
1602 elfcpp::Swap
<32, big_endian
>::writeval(
1604 ((this->first_plt_entry
[3] & 0xffc003ff)
1605 | ((gotplt_2nd_ent
& 0xfff) << 10)));
1608 // Subsequent entries in the PLT for an executable.
1609 // FIXME: This only works for 64bit
1611 template<int size
, bool big_endian
>
1613 Output_data_plt_aarch64_standard
<size
, big_endian
>::do_fill_plt_entry(
1615 Address got_address
,
1616 Address plt_address
,
1617 unsigned int got_offset
,
1618 unsigned int plt_offset
)
1620 memcpy(pov
, this->plt_entry
, this->plt_entry_size
);
1622 Address gotplt_entry_address
= got_address
+ got_offset
;
1623 Address plt_entry_address
= plt_address
+ plt_offset
;
1625 // Fill in R_AARCH64_PCREL_ADR_HI21
1626 AArch64_relocate_functions
<size
, big_endian
>::adrp(
1628 gotplt_entry_address
,
1631 // Fill in R_AARCH64_LDST64_ABS_LO12
1632 elfcpp::Swap
<32, big_endian
>::writeval(
1634 ((this->plt_entry
[1] & 0xffc003ff)
1635 | ((gotplt_entry_address
& 0xff8) << 7)));
1637 // Fill in R_AARCH64_ADD_ABS_LO12
1638 elfcpp::Swap
<32, big_endian
>::writeval(
1640 ((this->plt_entry
[2] & 0xffc003ff)
1641 | ((gotplt_entry_address
& 0xfff) <<10)));
1648 Output_data_plt_aarch64_standard
<32, false>::
1649 tlsdesc_plt_entry
[plt_tlsdesc_entry_size
/ 4] =
1651 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
1652 0x90000002, /* adrp x2, 0 */
1653 0x90000003, /* adrp x3, 0 */
1654 0xb9400042, /* ldr w2, [w2, #0] */
1655 0x11000063, /* add w3, w3, 0 */
1656 0xd61f0040, /* br x2 */
1657 0xd503201f, /* nop */
1658 0xd503201f, /* nop */
1663 Output_data_plt_aarch64_standard
<32, true>::
1664 tlsdesc_plt_entry
[plt_tlsdesc_entry_size
/ 4] =
1666 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
1667 0x90000002, /* adrp x2, 0 */
1668 0x90000003, /* adrp x3, 0 */
1669 0xb9400042, /* ldr w2, [w2, #0] */
1670 0x11000063, /* add w3, w3, 0 */
1671 0xd61f0040, /* br x2 */
1672 0xd503201f, /* nop */
1673 0xd503201f, /* nop */
1678 Output_data_plt_aarch64_standard
<64, false>::
1679 tlsdesc_plt_entry
[plt_tlsdesc_entry_size
/ 4] =
1681 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
1682 0x90000002, /* adrp x2, 0 */
1683 0x90000003, /* adrp x3, 0 */
1684 0xf9400042, /* ldr x2, [x2, #0] */
1685 0x91000063, /* add x3, x3, 0 */
1686 0xd61f0040, /* br x2 */
1687 0xd503201f, /* nop */
1688 0xd503201f, /* nop */
1693 Output_data_plt_aarch64_standard
<64, true>::
1694 tlsdesc_plt_entry
[plt_tlsdesc_entry_size
/ 4] =
1696 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
1697 0x90000002, /* adrp x2, 0 */
1698 0x90000003, /* adrp x3, 0 */
1699 0xf9400042, /* ldr x2, [x2, #0] */
1700 0x91000063, /* add x3, x3, 0 */
1701 0xd61f0040, /* br x2 */
1702 0xd503201f, /* nop */
1703 0xd503201f, /* nop */
1706 template<int size
, bool big_endian
>
1708 Output_data_plt_aarch64_standard
<size
, big_endian
>::do_fill_tlsdesc_entry(
1710 Address gotplt_address
,
1711 Address plt_address
,
1713 unsigned int tlsdesc_got_offset
,
1714 unsigned int plt_offset
)
1716 memcpy(pov
, tlsdesc_plt_entry
, plt_tlsdesc_entry_size
);
1718 // move DT_TLSDESC_GOT address into x2
1719 // move .got.plt address into x3
1720 Address tlsdesc_got_entry
= got_base
+ tlsdesc_got_offset
;
1721 Address plt_entry_address
= plt_address
+ plt_offset
;
1723 // R_AARCH64_ADR_PREL_PG_HI21
1724 AArch64_relocate_functions
<size
, big_endian
>::adrp(
1727 plt_entry_address
+ 4);
1729 // R_AARCH64_ADR_PREL_PG_HI21
1730 AArch64_relocate_functions
<size
, big_endian
>::adrp(
1733 plt_entry_address
+ 8);
1735 // R_AARCH64_LDST64_ABS_LO12
1736 elfcpp::Swap
<32, big_endian
>::writeval(
1738 ((this->tlsdesc_plt_entry
[3] & 0xffc003ff)
1739 | ((tlsdesc_got_entry
& 0xff8) << 7)));
1741 // R_AARCH64_ADD_ABS_LO12
1742 elfcpp::Swap
<32, big_endian
>::writeval(
1744 ((this->tlsdesc_plt_entry
[4] & 0xffc003ff)
1745 | ((gotplt_address
& 0xfff) << 10)));
1748 // Write out the PLT. This uses the hand-coded instructions above,
1749 // and adjusts them as needed. This is specified by the AMD64 ABI.
1751 template<int size
, bool big_endian
>
1753 Output_data_plt_aarch64
<size
, big_endian
>::do_write(Output_file
* of
)
1755 const off_t offset
= this->offset();
1756 const section_size_type oview_size
=
1757 convert_to_section_size_type(this->data_size());
1758 unsigned char* const oview
= of
->get_output_view(offset
, oview_size
);
1760 const off_t got_file_offset
= this->got_plt_
->offset();
1761 const section_size_type got_size
=
1762 convert_to_section_size_type(this->got_plt_
->data_size());
1763 unsigned char* const got_view
= of
->get_output_view(got_file_offset
,
1766 unsigned char* pov
= oview
;
1768 // The base address of the .plt section.
1769 typename
elfcpp::Elf_types
<size
>::Elf_Addr plt_address
= this->address();
1770 // The base address of the PLT portion of the .got section.
1771 typename
elfcpp::Elf_types
<size
>::Elf_Addr gotplt_address
1772 = this->got_plt_
->address();
1774 this->fill_first_plt_entry(pov
, gotplt_address
, plt_address
);
1775 pov
+= this->first_plt_entry_offset();
1777 // The first three entries in .got.plt are reserved.
1778 unsigned char* got_pov
= got_view
;
1779 memset(got_pov
, 0, size
/ 8 * AARCH64_GOTPLT_RESERVE_COUNT
);
1780 got_pov
+= (size
/ 8) * AARCH64_GOTPLT_RESERVE_COUNT
;
1782 unsigned int plt_offset
= this->first_plt_entry_offset();
1783 unsigned int got_offset
= (size
/ 8) * AARCH64_GOTPLT_RESERVE_COUNT
;
1784 const unsigned int count
= this->count_
+ this->irelative_count_
;
1785 for (unsigned int plt_index
= 0;
1788 pov
+= this->get_plt_entry_size(),
1789 got_pov
+= size
/ 8,
1790 plt_offset
+= this->get_plt_entry_size(),
1791 got_offset
+= size
/ 8)
1793 // Set and adjust the PLT entry itself.
1794 this->fill_plt_entry(pov
, gotplt_address
, plt_address
,
1795 got_offset
, plt_offset
);
1797 // Set the entry in the GOT, which points to plt0.
1798 elfcpp::Swap
<size
, big_endian
>::writeval(got_pov
, plt_address
);
1801 if (this->has_tlsdesc_entry())
1803 // Set and adjust the reserved TLSDESC PLT entry.
1804 unsigned int tlsdesc_got_offset
= this->get_tlsdesc_got_offset();
1805 // The base address of the .base section.
1806 typename
elfcpp::Elf_types
<size
>::Elf_Addr got_base
=
1807 this->got_
->address();
1808 this->fill_tlsdesc_entry(pov
, gotplt_address
, plt_address
, got_base
,
1809 tlsdesc_got_offset
, plt_offset
);
1810 pov
+= this->get_plt_tlsdesc_entry_size();
1813 gold_assert(static_cast<section_size_type
>(pov
- oview
) == oview_size
);
1814 gold_assert(static_cast<section_size_type
>(got_pov
- got_view
) == got_size
);
1816 of
->write_output_view(offset
, oview_size
, oview
);
1817 of
->write_output_view(got_file_offset
, got_size
, got_view
);
1820 // Telling how to update the immediate field of an instruction.
1821 struct AArch64_howto
1823 // The immediate field mask.
1824 elfcpp::Elf_Xword dst_mask
;
1826 // The offset to apply relocation immediate
1829 // The second part offset, if the immediate field has two parts.
1830 // -1 if the immediate field has only one part.
1834 static const AArch64_howto aarch64_howto
[AArch64_reloc_property::INST_NUM
] =
1836 {0, -1, -1}, // DATA
1837 {0x1fffe0, 5, -1}, // MOVW [20:5]-imm16
1838 {0xffffe0, 5, -1}, // LD [23:5]-imm19
1839 {0x60ffffe0, 29, 5}, // ADR [30:29]-immlo [23:5]-immhi
1840 {0x60ffffe0, 29, 5}, // ADRP [30:29]-immlo [23:5]-immhi
1841 {0x3ffc00, 10, -1}, // ADD [21:10]-imm12
1842 {0x3ffc00, 10, -1}, // LDST [21:10]-imm12
1843 {0x7ffe0, 5, -1}, // TBZNZ [18:5]-imm14
1844 {0xffffe0, 5, -1}, // CONDB [23:5]-imm19
1845 {0x3ffffff, 0, -1}, // B [25:0]-imm26
1846 {0x3ffffff, 0, -1}, // CALL [25:0]-imm26
1849 // AArch64 relocate function class
1851 template<int size
, bool big_endian
>
1852 class AArch64_relocate_functions
1857 STATUS_OKAY
, // No error during relocation.
1858 STATUS_OVERFLOW
, // Relocation overflow.
1859 STATUS_BAD_RELOC
, // Relocation cannot be applied.
1863 typedef AArch64_relocate_functions
<size
, big_endian
> This
;
1864 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr Address
;
1866 // Return the page address of the address.
1867 // Page(address) = address & ~0xFFF
1869 static inline typename
elfcpp::Swap
<size
, big_endian
>::Valtype
1870 Page(Address address
)
1872 return (address
& (~static_cast<Address
>(0xFFF)));
1875 // Update instruction (pointed by view) with selected bits (immed).
1876 // val = (val & ~dst_mask) | (immed << doffset)
1878 template<int valsize
>
1880 update_view(unsigned char* view
,
1881 typename
elfcpp::Swap
<size
, big_endian
>::Valtype immed
,
1882 elfcpp::Elf_Xword doffset
,
1883 elfcpp::Elf_Xword dst_mask
)
1885 typedef typename
elfcpp::Swap
<valsize
, big_endian
>::Valtype Valtype
;
1886 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
1887 Valtype val
= elfcpp::Swap
<valsize
, big_endian
>::readval(wv
);
1889 // Clear immediate fields.
1891 elfcpp::Swap
<valsize
, big_endian
>::writeval(wv
,
1892 static_cast<Valtype
>(val
| (immed
<< doffset
)));
1895 // Update two parts of an instruction (pointed by view) with selected
1896 // bits (immed1 and immed2).
1897 // val = (val & ~dst_mask) | (immed1 << doffset1) | (immed2 << doffset2)
1899 template<int valsize
>
1901 update_view_two_parts(
1902 unsigned char* view
,
1903 typename
elfcpp::Swap
<size
, big_endian
>::Valtype immed1
,
1904 typename
elfcpp::Swap
<size
, big_endian
>::Valtype immed2
,
1905 elfcpp::Elf_Xword doffset1
,
1906 elfcpp::Elf_Xword doffset2
,
1907 elfcpp::Elf_Xword dst_mask
)
1909 typedef typename
elfcpp::Swap
<valsize
, big_endian
>::Valtype Valtype
;
1910 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
1911 Valtype val
= elfcpp::Swap
<valsize
, big_endian
>::readval(wv
);
1913 elfcpp::Swap
<valsize
, big_endian
>::writeval(wv
,
1914 static_cast<Valtype
>(val
| (immed1
<< doffset1
) |
1915 (immed2
<< doffset2
)));
1918 // Update adr or adrp instruction with [32:12] of X.
1919 // In adr and adrp: [30:29] immlo [23:5] immhi
1922 update_adr(unsigned char* view
,
1923 typename
elfcpp::Swap
<size
, big_endian
>::Valtype x
,
1924 const AArch64_reloc_property
* /* reloc_property */)
1926 elfcpp::Elf_Xword dst_mask
= (0x3 << 29) | (0x7ffff << 5);
1927 typename
elfcpp::Swap
<32, big_endian
>::Valtype immed
=
1928 (x
>> 12) & 0x1fffff;
1929 This::template update_view_two_parts
<32>(
1932 (immed
& 0x1ffffc) >> 2,
1938 // Update movz/movn instruction with bits immed.
1939 // Set instruction to movz if is_movz is true, otherwise set instruction
1942 update_movnz(unsigned char* view
,
1943 typename
elfcpp::Swap
<size
, big_endian
>::Valtype immed
,
1946 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Valtype
;
1947 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
1948 Valtype val
= elfcpp::Swap
<32, big_endian
>::readval(wv
);
1950 const elfcpp::Elf_Xword doffset
=
1951 aarch64_howto
[AArch64_reloc_property::INST_MOVW
].doffset
;
1952 const elfcpp::Elf_Xword dst_mask
=
1953 aarch64_howto
[AArch64_reloc_property::INST_MOVW
].dst_mask
;
1955 // Clear immediate fields and opc code.
1956 val
&= ~(dst_mask
| (0x11 << 29));
1958 // Set instruction to movz or movn.
1959 // movz: [30:29] is 10 movn: [30:29] is 00
1961 val
|= (0x10 << 29);
1963 elfcpp::Swap
<32, big_endian
>::writeval(wv
,
1964 static_cast<Valtype
>(val
| (immed
<< doffset
)));
1969 // Do a simple rela relocation at unaligned addresses.
1971 template<int valsize
>
1972 static inline typename
This::Status
1973 rela_ua(unsigned char* view
,
1974 const Sized_relobj_file
<size
, big_endian
>* object
,
1975 const Symbol_value
<size
>* psymval
,
1976 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
1977 const AArch64_reloc_property
* reloc_property
)
1979 typedef typename
elfcpp::Swap_unaligned
<valsize
, big_endian
>::Valtype
1981 typename
elfcpp::Elf_types
<size
>::Elf_Addr x
=
1982 psymval
->value(object
, addend
);
1983 elfcpp::Swap_unaligned
<valsize
, big_endian
>::writeval(view
,
1984 static_cast<Valtype
>(x
));
1985 return (reloc_property
->checkup_x_value(x
)
1987 : This::STATUS_OVERFLOW
);
1990 // Do a simple pc-relative relocation at unaligned addresses.
1992 template<int valsize
>
1993 static inline typename
This::Status
1994 pcrela_ua(unsigned char* view
,
1995 const Sized_relobj_file
<size
, big_endian
>* object
,
1996 const Symbol_value
<size
>* psymval
,
1997 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
1999 const AArch64_reloc_property
* reloc_property
)
2001 typedef typename
elfcpp::Swap_unaligned
<valsize
, big_endian
>::Valtype
2003 Address x
= psymval
->value(object
, addend
) - address
;
2004 elfcpp::Swap_unaligned
<valsize
, big_endian
>::writeval(view
,
2005 static_cast<Valtype
>(x
));
2006 return (reloc_property
->checkup_x_value(x
)
2008 : This::STATUS_OVERFLOW
);
2011 // Do a simple rela relocation at aligned addresses.
2013 template<int valsize
>
2014 static inline typename
This::Status
2016 unsigned char* view
,
2017 const Sized_relobj_file
<size
, big_endian
>* object
,
2018 const Symbol_value
<size
>* psymval
,
2019 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
2020 const AArch64_reloc_property
* reloc_property
)
2022 typedef typename
elfcpp::Swap
<valsize
, big_endian
>::Valtype
2024 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
2025 Address x
= psymval
->value(object
, addend
);
2026 elfcpp::Swap
<valsize
, big_endian
>::writeval(wv
,
2027 static_cast<Valtype
>(x
));
2028 return (reloc_property
->checkup_x_value(x
)
2030 : This::STATUS_OVERFLOW
);
2033 // Do relocate. Update selected bits in text.
2034 // new_val = (val & ~dst_mask) | (immed << doffset)
2036 template<int valsize
>
2037 static inline typename
This::Status
2038 rela_general(unsigned char* view
,
2039 const Sized_relobj_file
<size
, big_endian
>* object
,
2040 const Symbol_value
<size
>* psymval
,
2041 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
2042 const AArch64_reloc_property
* reloc_property
)
2044 // Calculate relocation.
2045 Address x
= psymval
->value(object
, addend
);
2047 // Select bits from X.
2048 Address immed
= reloc_property
->select_x_value(x
);
2051 const AArch64_reloc_property::Reloc_inst inst
=
2052 reloc_property
->reloc_inst();
2053 // If it is a data relocation or instruction has 2 parts of immediate
2054 // fields, you should not call rela_general.
2055 gold_assert(aarch64_howto
[inst
].doffset2
== -1 &&
2056 aarch64_howto
[inst
].doffset
!= -1);
2057 This::template update_view
<valsize
>(view
, immed
,
2058 aarch64_howto
[inst
].doffset
,
2059 aarch64_howto
[inst
].dst_mask
);
2061 // Do check overflow or alignment if needed.
2062 return (reloc_property
->checkup_x_value(x
)
2064 : This::STATUS_OVERFLOW
);
2067 // Do relocate. Update selected bits in text.
2068 // new val = (val & ~dst_mask) | (immed << doffset)
2070 template<int valsize
>
2071 static inline typename
This::Status
2073 unsigned char* view
,
2074 typename
elfcpp::Swap
<size
, big_endian
>::Valtype s
,
2075 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
2076 const AArch64_reloc_property
* reloc_property
)
2078 // Calculate relocation.
2079 Address x
= s
+ addend
;
2081 // Select bits from X.
2082 Address immed
= reloc_property
->select_x_value(x
);
2085 const AArch64_reloc_property::Reloc_inst inst
=
2086 reloc_property
->reloc_inst();
2087 // If it is a data relocation or instruction has 2 parts of immediate
2088 // fields, you should not call rela_general.
2089 gold_assert(aarch64_howto
[inst
].doffset2
== -1 &&
2090 aarch64_howto
[inst
].doffset
!= -1);
2091 This::template update_view
<valsize
>(view
, immed
,
2092 aarch64_howto
[inst
].doffset
,
2093 aarch64_howto
[inst
].dst_mask
);
2095 // Do check overflow or alignment if needed.
2096 return (reloc_property
->checkup_x_value(x
)
2098 : This::STATUS_OVERFLOW
);
2101 // Do address relative relocate. Update selected bits in text.
2102 // new val = (val & ~dst_mask) | (immed << doffset)
2104 template<int valsize
>
2105 static inline typename
This::Status
2107 unsigned char* view
,
2108 const Sized_relobj_file
<size
, big_endian
>* object
,
2109 const Symbol_value
<size
>* psymval
,
2110 typename
elfcpp::Swap
<size
, big_endian
>::Valtype addend
,
2112 const AArch64_reloc_property
* reloc_property
)
2114 // Calculate relocation.
2115 Address x
= psymval
->value(object
, addend
) - address
;
2117 // Select bits from X.
2118 Address immed
= reloc_property
->select_x_value(x
);
2121 const AArch64_reloc_property::Reloc_inst inst
=
2122 reloc_property
->reloc_inst();
2123 // If it is a data relocation or instruction has 2 parts of immediate
2124 // fields, you should not call pcrela_general.
2125 gold_assert(aarch64_howto
[inst
].doffset2
== -1 &&
2126 aarch64_howto
[inst
].doffset
!= -1);
2127 This::template update_view
<valsize
>(view
, immed
,
2128 aarch64_howto
[inst
].doffset
,
2129 aarch64_howto
[inst
].dst_mask
);
2131 // Do check overflow or alignment if needed.
2132 return (reloc_property
->checkup_x_value(x
)
2134 : This::STATUS_OVERFLOW
);
2137 // Calculate PG(S+A) - PG(address), update adrp instruction.
2138 // R_AARCH64_ADR_PREL_PG_HI21
2140 static inline typename
This::Status
2142 unsigned char* view
,
2146 typename
elfcpp::Swap
<size
, big_endian
>::Valtype x
=
2147 This::Page(sa
) - This::Page(address
);
2148 update_adr(view
, x
, NULL
);
2149 return (size
== 64 && Bits
<32>::has_overflow(x
)
2150 ? This::STATUS_OVERFLOW
2151 : This::STATUS_OKAY
);
2154 // Calculate PG(S+A) - PG(address), update adrp instruction.
2155 // R_AARCH64_ADR_PREL_PG_HI21
2157 static inline typename
This::Status
2158 adrp(unsigned char* view
,
2159 const Sized_relobj_file
<size
, big_endian
>* object
,
2160 const Symbol_value
<size
>* psymval
,
2163 const AArch64_reloc_property
* reloc_property
)
2165 Address sa
= psymval
->value(object
, addend
);
2166 typename
elfcpp::Swap
<size
, big_endian
>::Valtype x
=
2167 This::Page(sa
) - This::Page(address
);
2168 update_adr(view
, x
, reloc_property
);
2169 return (reloc_property
->checkup_x_value(x
)
2171 : This::STATUS_OVERFLOW
);
2174 // Update mov[n/z] instruction. Check overflow if needed.
2175 // If X >=0, set the instruction to movz and its immediate value to the
2177 // If X < 0, set the instruction to movn and its immediate value to
2178 // NOT (selected bits of).
2180 static inline typename
This::Status
2181 movnz(unsigned char* view
,
2182 typename
elfcpp::Swap
<size
, big_endian
>::Valtype x
,
2183 const AArch64_reloc_property
* reloc_property
)
2185 // Select bits from X.
2186 Address immed
= reloc_property
->select_x_value(x
);
2187 bool is_movz
= true;
2188 if (static_cast<int64_t>(x
) < 0)
2194 // Update movnz instruction.
2195 update_movnz(view
, immed
, is_movz
);
2197 // Do check overflow or alignment if needed.
2198 return (reloc_property
->checkup_x_value(x
)
2200 : This::STATUS_OVERFLOW
);
2203 }; // End of AArch64_relocate_functions
2206 template<int size
, bool big_endian
>
2207 typename
elfcpp::Elf_types
<size
>::Elf_Addr
2208 Target_aarch64
<size
, big_endian
>::do_reloc_addend(
2209 void* arg
, unsigned int r_type
,
2210 typename
elfcpp::Elf_types
<size
>::Elf_Addr
) const
2212 gold_assert(r_type
== elfcpp::R_AARCH64_TLSDESC
);
2213 uintptr_t intarg
= reinterpret_cast<uintptr_t>(arg
);
2214 gold_assert(intarg
< this->tlsdesc_reloc_info_
.size());
2215 const Tlsdesc_info
& ti(this->tlsdesc_reloc_info_
[intarg
]);
2216 const Symbol_value
<size
>* psymval
= ti
.object
->local_symbol(ti
.r_sym
);
2217 gold_assert(psymval
->is_tls_symbol());
2218 // The value of a TLS symbol is the offset in the TLS segment.
2219 return psymval
->value(ti
.object
, 0);
2222 // Return the number of entries in the PLT.
2224 template<int size
, bool big_endian
>
2226 Target_aarch64
<size
, big_endian
>::plt_entry_count() const
2228 if (this->plt_
== NULL
)
2230 return this->plt_
->entry_count();
2233 // Return the offset of the first non-reserved PLT entry.
2235 template<int size
, bool big_endian
>
2237 Target_aarch64
<size
, big_endian
>::first_plt_entry_offset() const
2239 return this->plt_
->first_plt_entry_offset();
2242 // Return the size of each PLT entry.
2244 template<int size
, bool big_endian
>
2246 Target_aarch64
<size
, big_endian
>::plt_entry_size() const
2248 return this->plt_
->get_plt_entry_size();
2251 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
2253 template<int size
, bool big_endian
>
2255 Target_aarch64
<size
, big_endian
>::define_tls_base_symbol(
2256 Symbol_table
* symtab
, Layout
* layout
)
2258 if (this->tls_base_symbol_defined_
)
2261 Output_segment
* tls_segment
= layout
->tls_segment();
2262 if (tls_segment
!= NULL
)
2264 bool is_exec
= parameters
->options().output_is_executable();
2265 symtab
->define_in_output_segment("_TLS_MODULE_BASE_", NULL
,
2266 Symbol_table::PREDEFINED
,
2270 elfcpp::STV_HIDDEN
, 0,
2272 ? Symbol::SEGMENT_END
2273 : Symbol::SEGMENT_START
),
2276 this->tls_base_symbol_defined_
= true;
2279 // Create the reserved PLT and GOT entries for the TLS descriptor resolver.
2281 template<int size
, bool big_endian
>
2283 Target_aarch64
<size
, big_endian
>::reserve_tlsdesc_entries(
2284 Symbol_table
* symtab
, Layout
* layout
)
2286 if (this->plt_
== NULL
)
2287 this->make_plt_section(symtab
, layout
);
2289 if (!this->plt_
->has_tlsdesc_entry())
2291 // Allocate the TLSDESC_GOT entry.
2292 Output_data_got_aarch64
<size
, big_endian
>* got
=
2293 this->got_section(symtab
, layout
);
2294 unsigned int got_offset
= got
->add_constant(0);
2296 // Allocate the TLSDESC_PLT entry.
2297 this->plt_
->reserve_tlsdesc_entry(got_offset
);
2301 // Create a GOT entry for the TLS module index.
2303 template<int size
, bool big_endian
>
2305 Target_aarch64
<size
, big_endian
>::got_mod_index_entry(
2306 Symbol_table
* symtab
, Layout
* layout
,
2307 Sized_relobj_file
<size
, big_endian
>* object
)
2309 if (this->got_mod_index_offset_
== -1U)
2311 gold_assert(symtab
!= NULL
&& layout
!= NULL
&& object
!= NULL
);
2312 Reloc_section
* rela_dyn
= this->rela_dyn_section(layout
);
2313 Output_data_got_aarch64
<size
, big_endian
>* got
=
2314 this->got_section(symtab
, layout
);
2315 unsigned int got_offset
= got
->add_constant(0);
2316 rela_dyn
->add_local(object
, 0, elfcpp::R_AARCH64_TLS_DTPMOD64
, got
,
2318 got
->add_constant(0);
2319 this->got_mod_index_offset_
= got_offset
;
2321 return this->got_mod_index_offset_
;
2324 // Optimize the TLS relocation type based on what we know about the
2325 // symbol. IS_FINAL is true if the final address of this symbol is
2326 // known at link time.
2328 template<int size
, bool big_endian
>
2329 tls::Tls_optimization
2330 Target_aarch64
<size
, big_endian
>::optimize_tls_reloc(bool is_final
,
2333 // If we are generating a shared library, then we can't do anything
2335 if (parameters
->options().shared())
2336 return tls::TLSOPT_NONE
;
2340 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
2341 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
:
2342 case elfcpp::R_AARCH64_TLSDESC_LD_PREL19
:
2343 case elfcpp::R_AARCH64_TLSDESC_ADR_PREL21
:
2344 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
2345 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
2346 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
2347 case elfcpp::R_AARCH64_TLSDESC_OFF_G1
:
2348 case elfcpp::R_AARCH64_TLSDESC_OFF_G0_NC
:
2349 case elfcpp::R_AARCH64_TLSDESC_LDR
:
2350 case elfcpp::R_AARCH64_TLSDESC_ADD
:
2351 case elfcpp::R_AARCH64_TLSDESC_CALL
:
2352 // These are General-Dynamic which permits fully general TLS
2353 // access. Since we know that we are generating an executable,
2354 // we can convert this to Initial-Exec. If we also know that
2355 // this is a local symbol, we can further switch to Local-Exec.
2357 return tls::TLSOPT_TO_LE
;
2358 return tls::TLSOPT_TO_IE
;
2360 case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
2361 case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
2362 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
2363 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
2364 case elfcpp::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
2365 // These are Initial-Exec relocs which get the thread offset
2366 // from the GOT. If we know that we are linking against the
2367 // local symbol, we can switch to Local-Exec, which links the
2368 // thread offset into the instruction.
2370 return tls::TLSOPT_TO_LE
;
2371 return tls::TLSOPT_NONE
;
2373 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2
:
2374 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1
:
2375 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
2376 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0
:
2377 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
2378 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
:
2379 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
:
2380 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
2381 // When we already have Local-Exec, there is nothing further we
2383 return tls::TLSOPT_NONE
;
2390 // Returns true if this relocation type could be that of a function pointer.
2392 template<int size
, bool big_endian
>
2394 Target_aarch64
<size
, big_endian
>::Scan::possible_function_pointer_reloc(
2395 unsigned int r_type
)
2399 case elfcpp::R_AARCH64_ABS64
:
2408 // For safe ICF, scan a relocation for a local symbol to check if it
2409 // corresponds to a function pointer being taken. In that case mark
2410 // the function whose pointer was taken as not foldable.
2412 template<int size
, bool big_endian
>
2414 Target_aarch64
<size
, big_endian
>::Scan::local_reloc_may_be_function_pointer(
2417 Target_aarch64
<size
, big_endian
>* ,
2418 Sized_relobj_file
<size
, big_endian
>* ,
2421 const elfcpp::Rela
<size
, big_endian
>& ,
2422 unsigned int r_type
,
2423 const elfcpp::Sym
<size
, big_endian
>&)
2425 // When building a shared library, do not fold any local symbols as it is
2426 // not possible to distinguish pointer taken versus a call by looking at
2427 // the relocation types.
2428 return (parameters
->options().shared()
2429 || possible_function_pointer_reloc(r_type
));
2432 // For safe ICF, scan a relocation for a global symbol to check if it
2433 // corresponds to a function pointer being taken. In that case mark
2434 // the function whose pointer was taken as not foldable.
2436 template<int size
, bool big_endian
>
2438 Target_aarch64
<size
, big_endian
>::Scan::global_reloc_may_be_function_pointer(
2441 Target_aarch64
<size
, big_endian
>* ,
2442 Sized_relobj_file
<size
, big_endian
>* ,
2445 const elfcpp::Rela
<size
, big_endian
>& ,
2446 unsigned int r_type
,
2449 // When building a shared library, do not fold symbols whose visibility
2450 // is hidden, internal or protected.
2451 return ((parameters
->options().shared()
2452 && (gsym
->visibility() == elfcpp::STV_INTERNAL
2453 || gsym
->visibility() == elfcpp::STV_PROTECTED
2454 || gsym
->visibility() == elfcpp::STV_HIDDEN
))
2455 || possible_function_pointer_reloc(r_type
));
2458 // Report an unsupported relocation against a local symbol.
2460 template<int size
, bool big_endian
>
2462 Target_aarch64
<size
, big_endian
>::Scan::unsupported_reloc_local(
2463 Sized_relobj_file
<size
, big_endian
>* object
,
2464 unsigned int r_type
)
2466 gold_error(_("%s: unsupported reloc %u against local symbol"),
2467 object
->name().c_str(), r_type
);
2470 // We are about to emit a dynamic relocation of type R_TYPE. If the
2471 // dynamic linker does not support it, issue an error.
2473 template<int size
, bool big_endian
>
2475 Target_aarch64
<size
, big_endian
>::Scan::check_non_pic(Relobj
* object
,
2476 unsigned int r_type
)
2478 gold_assert(r_type
!= elfcpp::R_AARCH64_NONE
);
2482 // These are the relocation types supported by glibc for AARCH64.
2483 case elfcpp::R_AARCH64_NONE
:
2484 case elfcpp::R_AARCH64_COPY
:
2485 case elfcpp::R_AARCH64_GLOB_DAT
:
2486 case elfcpp::R_AARCH64_JUMP_SLOT
:
2487 case elfcpp::R_AARCH64_RELATIVE
:
2488 case elfcpp::R_AARCH64_TLS_DTPREL64
:
2489 case elfcpp::R_AARCH64_TLS_DTPMOD64
:
2490 case elfcpp::R_AARCH64_TLS_TPREL64
:
2491 case elfcpp::R_AARCH64_TLSDESC
:
2492 case elfcpp::R_AARCH64_IRELATIVE
:
2493 case elfcpp::R_AARCH64_ABS32
:
2494 case elfcpp::R_AARCH64_ABS64
:
2501 // This prevents us from issuing more than one error per reloc
2502 // section. But we can still wind up issuing more than one
2503 // error per object file.
2504 if (this->issued_non_pic_error_
)
2506 gold_assert(parameters
->options().output_is_position_independent());
2507 object
->error(_("requires unsupported dynamic reloc; "
2508 "recompile with -fPIC"));
2509 this->issued_non_pic_error_
= true;
2513 // Scan a relocation for a local symbol.
2515 template<int size
, bool big_endian
>
2517 Target_aarch64
<size
, big_endian
>::Scan::local(
2518 Symbol_table
* symtab
,
2520 Target_aarch64
<size
, big_endian
>* target
,
2521 Sized_relobj_file
<size
, big_endian
>* object
,
2522 unsigned int data_shndx
,
2523 Output_section
* output_section
,
2524 const elfcpp::Rela
<size
, big_endian
>& rela
,
2525 unsigned int r_type
,
2526 const elfcpp::Sym
<size
, big_endian
>& /* lsym */,
2532 typedef Output_data_reloc
<elfcpp::SHT_RELA
, true, size
, big_endian
>
2534 Output_data_got_aarch64
<size
, big_endian
>* got
=
2535 target
->got_section(symtab
, layout
);
2536 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
2540 case elfcpp::R_AARCH64_ABS32
:
2541 case elfcpp::R_AARCH64_ABS16
:
2542 if (parameters
->options().output_is_position_independent())
2544 gold_error(_("%s: unsupported reloc %u in pos independent link."),
2545 object
->name().c_str(), r_type
);
2549 case elfcpp::R_AARCH64_ABS64
:
2550 // If building a shared library or pie, we need to mark this as a dynmic
2551 // reloction, so that the dynamic loader can relocate it.
2552 if (parameters
->options().output_is_position_independent())
2554 Reloc_section
* rela_dyn
= target
->rela_dyn_section(layout
);
2555 rela_dyn
->add_local_relative(object
, r_sym
,
2556 elfcpp::R_AARCH64_RELATIVE
,
2559 rela
.get_r_offset(),
2560 rela
.get_r_addend(),
2561 false /* is ifunc */);
2565 case elfcpp::R_AARCH64_PREL64
:
2566 case elfcpp::R_AARCH64_PREL32
:
2567 case elfcpp::R_AARCH64_PREL16
:
2570 case elfcpp::R_AARCH64_LD_PREL_LO19
: // 273
2571 case elfcpp::R_AARCH64_ADR_PREL_LO21
: // 274
2572 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21
: // 275
2573 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC
: // 276
2574 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC
: // 277
2575 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC
: // 278
2576 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC
: // 284
2577 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC
: // 285
2578 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC
: // 286
2579 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC
: // 299
2582 // Control flow, pc-relative. We don't need to do anything for a relative
2583 // addressing relocation against a local symbol if it does not reference
2585 case elfcpp::R_AARCH64_TSTBR14
:
2586 case elfcpp::R_AARCH64_CONDBR19
:
2587 case elfcpp::R_AARCH64_JUMP26
:
2588 case elfcpp::R_AARCH64_CALL26
:
2591 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
2592 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
2594 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
2595 optimize_tls_reloc(!parameters
->options().shared(), r_type
);
2596 if (tlsopt
== tls::TLSOPT_TO_LE
)
2599 layout
->set_has_static_tls();
2600 // Create a GOT entry for the tp-relative offset.
2601 if (!parameters
->doing_static_link())
2603 got
->add_local_with_rel(object
, r_sym
, GOT_TYPE_TLS_OFFSET
,
2604 target
->rela_dyn_section(layout
),
2605 elfcpp::R_AARCH64_TLS_TPREL64
);
2607 else if (!object
->local_has_got_offset(r_sym
,
2608 GOT_TYPE_TLS_OFFSET
))
2610 got
->add_local(object
, r_sym
, GOT_TYPE_TLS_OFFSET
);
2611 unsigned int got_offset
=
2612 object
->local_got_offset(r_sym
, GOT_TYPE_TLS_OFFSET
);
2613 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
2614 gold_assert(addend
== 0);
2615 got
->add_static_reloc(got_offset
, elfcpp::R_AARCH64_TLS_TPREL64
,
2621 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
2622 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
:
2624 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
2625 optimize_tls_reloc(!parameters
->options().shared(), r_type
);
2626 if (tlsopt
== tls::TLSOPT_TO_LE
)
2628 layout
->set_has_static_tls();
2631 gold_assert(tlsopt
== tls::TLSOPT_NONE
);
2633 got
->add_local_pair_with_rel(object
,r_sym
, data_shndx
,
2635 target
->rela_dyn_section(layout
),
2636 elfcpp::R_AARCH64_TLS_DTPMOD64
);
2640 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
:
2641 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
:
2642 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
2644 layout
->set_has_static_tls();
2645 bool output_is_shared
= parameters
->options().shared();
2646 if (output_is_shared
)
2647 gold_error(_("%s: unsupported TLSLE reloc %u in shared code."),
2648 object
->name().c_str(), r_type
);
2652 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
2653 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
2654 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
2656 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
2657 optimize_tls_reloc(!parameters
->options().shared(), r_type
);
2658 target
->define_tls_base_symbol(symtab
, layout
);
2659 if (tlsopt
== tls::TLSOPT_NONE
)
2661 // Create reserved PLT and GOT entries for the resolver.
2662 target
->reserve_tlsdesc_entries(symtab
, layout
);
2664 // Generate a double GOT entry with an R_AARCH64_TLSDESC reloc.
2665 // The R_AARCH64_TLSDESC reloc is resolved lazily, so the GOT
2666 // entry needs to be in an area in .got.plt, not .got. Call
2667 // got_section to make sure the section has been created.
2668 target
->got_section(symtab
, layout
);
2669 Output_data_got
<size
, big_endian
>* got
=
2670 target
->got_tlsdesc_section();
2671 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
2672 if (!object
->local_has_got_offset(r_sym
, GOT_TYPE_TLS_DESC
))
2674 unsigned int got_offset
= got
->add_constant(0);
2675 got
->add_constant(0);
2676 object
->set_local_got_offset(r_sym
, GOT_TYPE_TLS_DESC
,
2678 Reloc_section
* rt
= target
->rela_tlsdesc_section(layout
);
2679 // We store the arguments we need in a vector, and use
2680 // the index into the vector as the parameter to pass
2681 // to the target specific routines.
2682 uintptr_t intarg
= target
->add_tlsdesc_info(object
, r_sym
);
2683 void* arg
= reinterpret_cast<void*>(intarg
);
2684 rt
->add_target_specific(elfcpp::R_AARCH64_TLSDESC
, arg
,
2685 got
, got_offset
, 0);
2688 else if (tlsopt
!= tls::TLSOPT_TO_LE
)
2689 unsupported_reloc_local(object
, r_type
);
2693 case elfcpp::R_AARCH64_TLSDESC_CALL
:
2697 unsupported_reloc_local(object
, r_type
);
2702 // Report an unsupported relocation against a global symbol.
2704 template<int size
, bool big_endian
>
2706 Target_aarch64
<size
, big_endian
>::Scan::unsupported_reloc_global(
2707 Sized_relobj_file
<size
, big_endian
>* object
,
2708 unsigned int r_type
,
2711 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
2712 object
->name().c_str(), r_type
, gsym
->demangled_name().c_str());
2715 template<int size
, bool big_endian
>
2717 Target_aarch64
<size
, big_endian
>::Scan::global(
2718 Symbol_table
* symtab
,
2720 Target_aarch64
<size
, big_endian
>* target
,
2721 Sized_relobj_file
<size
, big_endian
> * object
,
2722 unsigned int data_shndx
,
2723 Output_section
* output_section
,
2724 const elfcpp::Rela
<size
, big_endian
>& rela
,
2725 unsigned int r_type
,
2728 typedef Output_data_reloc
<elfcpp::SHT_RELA
, true, size
, big_endian
>
2730 const AArch64_reloc_property
* arp
=
2731 aarch64_reloc_property_table
->get_reloc_property(r_type
);
2732 gold_assert(arp
!= NULL
);
2736 case elfcpp::R_AARCH64_ABS16
:
2737 case elfcpp::R_AARCH64_ABS32
:
2738 case elfcpp::R_AARCH64_ABS64
:
2740 // Make a PLT entry if necessary.
2741 if (gsym
->needs_plt_entry())
2743 target
->make_plt_entry(symtab
, layout
, gsym
);
2744 // Since this is not a PC-relative relocation, we may be
2745 // taking the address of a function. In that case we need to
2746 // set the entry in the dynamic symbol table to the address of
2748 if (gsym
->is_from_dynobj() && !parameters
->options().shared())
2749 gsym
->set_needs_dynsym_value();
2751 // Make a dynamic relocation if necessary.
2752 if (gsym
->needs_dynamic_reloc(arp
->reference_flags()))
2754 if (!parameters
->options().output_is_position_independent()
2755 && gsym
->may_need_copy_reloc())
2757 target
->copy_reloc(symtab
, layout
, object
,
2758 data_shndx
, output_section
, gsym
, rela
);
2760 else if (r_type
== elfcpp::R_AARCH64_ABS64
2761 && gsym
->can_use_relative_reloc(false))
2763 Reloc_section
* rela_dyn
= target
->rela_dyn_section(layout
);
2764 rela_dyn
->add_global_relative(gsym
,
2765 elfcpp::R_AARCH64_RELATIVE
,
2769 rela
.get_r_offset(),
2770 rela
.get_r_addend(),
2775 check_non_pic(object
, r_type
);
2776 Output_data_reloc
<elfcpp::SHT_RELA
, true, size
, big_endian
>*
2777 rela_dyn
= target
->rela_dyn_section(layout
);
2778 rela_dyn
->add_global(
2779 gsym
, r_type
, output_section
, object
,
2780 data_shndx
, rela
.get_r_offset(),rela
.get_r_addend());
2786 case elfcpp::R_AARCH64_PREL16
:
2787 case elfcpp::R_AARCH64_PREL32
:
2788 case elfcpp::R_AARCH64_PREL64
:
2789 // This is used to fill the GOT absolute address.
2790 if (gsym
->needs_plt_entry())
2792 target
->make_plt_entry(symtab
, layout
, gsym
);
2796 case elfcpp::R_AARCH64_LD_PREL_LO19
: // 273
2797 case elfcpp::R_AARCH64_ADR_PREL_LO21
: // 274
2798 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21
: // 275
2799 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC
: // 276
2800 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC
: // 277
2801 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC
: // 278
2802 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC
: // 284
2803 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC
: // 285
2804 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC
: // 286
2805 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC
: // 299
2807 if (gsym
->needs_plt_entry())
2808 target
->make_plt_entry(symtab
, layout
, gsym
);
2809 // Make a dynamic relocation if necessary.
2810 if (gsym
->needs_dynamic_reloc(arp
->reference_flags()))
2812 if (parameters
->options().output_is_executable()
2813 && gsym
->may_need_copy_reloc())
2815 target
->copy_reloc(symtab
, layout
, object
,
2816 data_shndx
, output_section
, gsym
, rela
);
2822 case elfcpp::R_AARCH64_ADR_GOT_PAGE
:
2823 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC
:
2825 // This pair of relocations is used to access a specific GOT entry.
2826 // Note a GOT entry is an *address* to a symbol.
2827 // The symbol requires a GOT entry
2828 Output_data_got_aarch64
<size
, big_endian
>* got
=
2829 target
->got_section(symtab
, layout
);
2830 if (gsym
->final_value_is_known())
2832 got
->add_global(gsym
, GOT_TYPE_STANDARD
);
2836 Reloc_section
* rela_dyn
= target
->rela_dyn_section(layout
);
2837 if (gsym
->is_from_dynobj()
2838 || gsym
->is_undefined()
2839 || gsym
->is_preemptible()
2840 || (gsym
->visibility() == elfcpp::STV_PROTECTED
2841 && parameters
->options().shared()))
2842 got
->add_global_with_rel(gsym
, GOT_TYPE_STANDARD
,
2843 rela_dyn
, elfcpp::R_AARCH64_GLOB_DAT
);
2846 if (got
->add_global(gsym
, GOT_TYPE_STANDARD
))
2848 rela_dyn
->add_global_relative(
2849 gsym
, elfcpp::R_AARCH64_RELATIVE
,
2851 gsym
->got_offset(GOT_TYPE_STANDARD
),
2860 case elfcpp::R_AARCH64_TSTBR14
:
2861 case elfcpp::R_AARCH64_CONDBR19
:
2862 case elfcpp::R_AARCH64_JUMP26
:
2863 case elfcpp::R_AARCH64_CALL26
:
2865 if (gsym
->final_value_is_known())
2868 if (gsym
->is_defined() &&
2869 !gsym
->is_from_dynobj() &&
2870 !gsym
->is_preemptible())
2873 // Make plt entry for function call.
2874 target
->make_plt_entry(symtab
, layout
, gsym
);
2878 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
2879 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
: // General dynamic
2881 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
2882 optimize_tls_reloc(gsym
->final_value_is_known(), r_type
);
2883 if (tlsopt
== tls::TLSOPT_TO_LE
)
2885 layout
->set_has_static_tls();
2888 gold_assert(tlsopt
== tls::TLSOPT_NONE
);
2891 Output_data_got_aarch64
<size
, big_endian
>* got
=
2892 target
->got_section(symtab
, layout
);
2893 // Create 2 consecutive entries for module index and offset.
2894 got
->add_global_pair_with_rel(gsym
, GOT_TYPE_TLS_PAIR
,
2895 target
->rela_dyn_section(layout
),
2896 elfcpp::R_AARCH64_TLS_DTPMOD64
,
2897 elfcpp::R_AARCH64_TLS_DTPREL64
);
2901 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
2902 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
: // Initial executable
2904 tls::Tls_optimization tlsopt
=Target_aarch64
<size
, big_endian
>::
2905 optimize_tls_reloc(gsym
->final_value_is_known(), r_type
);
2906 if (tlsopt
== tls::TLSOPT_TO_LE
)
2909 layout
->set_has_static_tls();
2910 // Create a GOT entry for the tp-relative offset.
2911 Output_data_got_aarch64
<size
, big_endian
>* got
2912 = target
->got_section(symtab
, layout
);
2913 if (!parameters
->doing_static_link())
2915 got
->add_global_with_rel(
2916 gsym
, GOT_TYPE_TLS_OFFSET
,
2917 target
->rela_dyn_section(layout
),
2918 elfcpp::R_AARCH64_TLS_TPREL64
);
2920 if (!gsym
->has_got_offset(GOT_TYPE_TLS_OFFSET
))
2922 got
->add_global(gsym
, GOT_TYPE_TLS_OFFSET
);
2923 unsigned int got_offset
=
2924 gsym
->got_offset(GOT_TYPE_TLS_OFFSET
);
2925 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
2926 gold_assert(addend
== 0);
2927 got
->add_static_reloc(got_offset
,
2928 elfcpp::R_AARCH64_TLS_TPREL64
, gsym
);
2933 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
:
2934 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
:
2935 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
: // Local executable
2936 layout
->set_has_static_tls();
2937 if (parameters
->options().shared())
2938 gold_error(_("%s: unsupported TLSLE reloc type %u in shared objects."),
2939 object
->name().c_str(), r_type
);
2942 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
2943 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
2944 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
: // TLS descriptor
2946 target
->define_tls_base_symbol(symtab
, layout
);
2947 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
2948 optimize_tls_reloc(gsym
->final_value_is_known(), r_type
);
2949 if (tlsopt
== tls::TLSOPT_NONE
)
2951 // Create reserved PLT and GOT entries for the resolver.
2952 target
->reserve_tlsdesc_entries(symtab
, layout
);
2954 // Create a double GOT entry with an R_AARCH64_TLSDESC
2955 // relocation. The R_AARCH64_TLSDESC is resolved lazily, so the GOT
2956 // entry needs to be in an area in .got.plt, not .got. Call
2957 // got_section to make sure the section has been created.
2958 target
->got_section(symtab
, layout
);
2959 Output_data_got
<size
, big_endian
>* got
=
2960 target
->got_tlsdesc_section();
2961 Reloc_section
* rt
= target
->rela_tlsdesc_section(layout
);
2962 got
->add_global_pair_with_rel(gsym
, GOT_TYPE_TLS_DESC
, rt
,
2963 elfcpp::R_AARCH64_TLSDESC
, 0);
2965 else if (tlsopt
== tls::TLSOPT_TO_IE
)
2967 // Create a GOT entry for the tp-relative offset.
2968 Output_data_got
<size
, big_endian
>* got
2969 = target
->got_section(symtab
, layout
);
2970 got
->add_global_with_rel(gsym
, GOT_TYPE_TLS_OFFSET
,
2971 target
->rela_dyn_section(layout
),
2972 elfcpp::R_AARCH64_TLS_TPREL64
);
2974 else if (tlsopt
!= tls::TLSOPT_TO_LE
)
2975 unsupported_reloc_global(object
, r_type
, gsym
);
2979 case elfcpp::R_AARCH64_TLSDESC_CALL
:
2983 gold_error(_("%s: unsupported reloc type in global scan"),
2984 aarch64_reloc_property_table
->
2985 reloc_name_in_error_message(r_type
).c_str());
2988 } // End of Scan::global
2991 // Create the PLT section.
2992 template<int size
, bool big_endian
>
2994 Target_aarch64
<size
, big_endian
>::make_plt_section(
2995 Symbol_table
* symtab
, Layout
* layout
)
2997 if (this->plt_
== NULL
)
2999 // Create the GOT section first.
3000 this->got_section(symtab
, layout
);
3002 this->plt_
= this->make_data_plt(layout
, this->got_
, this->got_plt_
,
3003 this->got_irelative_
);
3005 layout
->add_output_section_data(".plt", elfcpp::SHT_PROGBITS
,
3007 | elfcpp::SHF_EXECINSTR
),
3008 this->plt_
, ORDER_PLT
, false);
3010 // Make the sh_info field of .rela.plt point to .plt.
3011 Output_section
* rela_plt_os
= this->plt_
->rela_plt()->output_section();
3012 rela_plt_os
->set_info_section(this->plt_
->output_section());
3016 // Return the section for TLSDESC relocations.
3018 template<int size
, bool big_endian
>
3019 typename Target_aarch64
<size
, big_endian
>::Reloc_section
*
3020 Target_aarch64
<size
, big_endian
>::rela_tlsdesc_section(Layout
* layout
) const
3022 return this->plt_section()->rela_tlsdesc(layout
);
3025 // Create a PLT entry for a global symbol.
3027 template<int size
, bool big_endian
>
3029 Target_aarch64
<size
, big_endian
>::make_plt_entry(
3030 Symbol_table
* symtab
,
3034 if (gsym
->has_plt_offset())
3037 if (this->plt_
== NULL
)
3038 this->make_plt_section(symtab
, layout
);
3040 this->plt_
->add_entry(gsym
);
3043 template<int size
, bool big_endian
>
3045 Target_aarch64
<size
, big_endian
>::gc_process_relocs(
3046 Symbol_table
* symtab
,
3048 Sized_relobj_file
<size
, big_endian
>* object
,
3049 unsigned int data_shndx
,
3050 unsigned int sh_type
,
3051 const unsigned char* prelocs
,
3053 Output_section
* output_section
,
3054 bool needs_special_offset_handling
,
3055 size_t local_symbol_count
,
3056 const unsigned char* plocal_symbols
)
3058 if (sh_type
== elfcpp::SHT_REL
)
3063 gold::gc_process_relocs
<
3065 Target_aarch64
<size
, big_endian
>,
3067 typename Target_aarch64
<size
, big_endian
>::Scan
,
3068 typename Target_aarch64
<size
, big_endian
>::Relocatable_size_for_reloc
>(
3077 needs_special_offset_handling
,
3082 // Scan relocations for a section.
3084 template<int size
, bool big_endian
>
3086 Target_aarch64
<size
, big_endian
>::scan_relocs(
3087 Symbol_table
* symtab
,
3089 Sized_relobj_file
<size
, big_endian
>* object
,
3090 unsigned int data_shndx
,
3091 unsigned int sh_type
,
3092 const unsigned char* prelocs
,
3094 Output_section
* output_section
,
3095 bool needs_special_offset_handling
,
3096 size_t local_symbol_count
,
3097 const unsigned char* plocal_symbols
)
3099 if (sh_type
== elfcpp::SHT_REL
)
3101 gold_error(_("%s: unsupported REL reloc section"),
3102 object
->name().c_str());
3105 gold::scan_relocs
<size
, big_endian
, Target_aarch64
, elfcpp::SHT_RELA
, Scan
>(
3114 needs_special_offset_handling
,
3119 // Return the value to use for a dynamic which requires special
3120 // treatment. This is how we support equality comparisons of function
3121 // pointers across shared library boundaries, as described in the
3122 // processor specific ABI supplement.
3124 template<int size
,bool big_endian
>
3126 Target_aarch64
<size
,big_endian
>::do_dynsym_value(const Symbol
* gsym
) const
3128 gold_assert(gsym
->is_from_dynobj() && gsym
->has_plt_offset());
3129 return this->plt_address_for_global(gsym
);
3132 // Finalize the sections.
3134 template<int size
, bool big_endian
>
3136 Target_aarch64
<size
, big_endian
>::do_finalize_sections(
3138 const Input_objects
*,
3139 Symbol_table
* symtab
)
3141 const Reloc_section
* rel_plt
= (this->plt_
== NULL
3143 : this->plt_
->rela_plt());
3144 layout
->add_target_dynamic_tags(false, this->got_plt_
, rel_plt
,
3145 this->rela_dyn_
, true, false);
3147 // Emit any relocs we saved in an attempt to avoid generating COPY
3149 if (this->copy_relocs_
.any_saved_relocs())
3150 this->copy_relocs_
.emit(this->rela_dyn_section(layout
));
3152 // Fill in some more dynamic tags.
3153 Output_data_dynamic
* const odyn
= layout
->dynamic_data();
3156 if (this->plt_
!= NULL
3157 && this->plt_
->output_section() != NULL
3158 && this->plt_
->has_tlsdesc_entry())
3160 unsigned int plt_offset
= this->plt_
->get_tlsdesc_plt_offset();
3161 unsigned int got_offset
= this->plt_
->get_tlsdesc_got_offset();
3162 this->got_
->finalize_data_size();
3163 odyn
->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT
,
3164 this->plt_
, plt_offset
);
3165 odyn
->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT
,
3166 this->got_
, got_offset
);
3170 // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
3171 // the .got.plt section.
3172 Symbol
* sym
= this->global_offset_table_
;
3175 uint64_t data_size
= this->got_plt_
->current_data_size();
3176 symtab
->get_sized_symbol
<size
>(sym
)->set_symsize(data_size
);
3178 // If the .got section is more than 0x8000 bytes, we add
3179 // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
3180 // bit relocations have a greater chance of working.
3181 if (data_size
>= 0x8000)
3182 symtab
->get_sized_symbol
<size
>(sym
)->set_value(
3183 symtab
->get_sized_symbol
<size
>(sym
)->value() + 0x8000);
3186 if (parameters
->doing_static_link()
3187 && (this->plt_
== NULL
|| !this->plt_
->has_irelative_section()))
3189 // If linking statically, make sure that the __rela_iplt symbols
3190 // were defined if necessary, even if we didn't create a PLT.
3191 static const Define_symbol_in_segment syms
[] =
3194 "__rela_iplt_start", // name
3195 elfcpp::PT_LOAD
, // segment_type
3196 elfcpp::PF_W
, // segment_flags_set
3197 elfcpp::PF(0), // segment_flags_clear
3200 elfcpp::STT_NOTYPE
, // type
3201 elfcpp::STB_GLOBAL
, // binding
3202 elfcpp::STV_HIDDEN
, // visibility
3204 Symbol::SEGMENT_START
, // offset_from_base
3208 "__rela_iplt_end", // name
3209 elfcpp::PT_LOAD
, // segment_type
3210 elfcpp::PF_W
, // segment_flags_set
3211 elfcpp::PF(0), // segment_flags_clear
3214 elfcpp::STT_NOTYPE
, // type
3215 elfcpp::STB_GLOBAL
, // binding
3216 elfcpp::STV_HIDDEN
, // visibility
3218 Symbol::SEGMENT_START
, // offset_from_base
3223 symtab
->define_symbols(layout
, 2, syms
,
3224 layout
->script_options()->saw_sections_clause());
3230 // Perform a relocation.
3232 template<int size
, bool big_endian
>
3234 Target_aarch64
<size
, big_endian
>::Relocate::relocate(
3235 const Relocate_info
<size
, big_endian
>* relinfo
,
3236 Target_aarch64
<size
, big_endian
>* target
,
3239 const elfcpp::Rela
<size
, big_endian
>& rela
,
3240 unsigned int r_type
,
3241 const Sized_symbol
<size
>* gsym
,
3242 const Symbol_value
<size
>* psymval
,
3243 unsigned char* view
,
3244 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
,
3245 section_size_type
/* view_size */)
3250 typedef AArch64_relocate_functions
<size
, big_endian
> Reloc
;
3252 const AArch64_reloc_property
* reloc_property
=
3253 aarch64_reloc_property_table
->get_reloc_property(r_type
);
3255 if (reloc_property
== NULL
)
3257 std::string reloc_name
=
3258 aarch64_reloc_property_table
->reloc_name_in_error_message(r_type
);
3259 gold_error_at_location(relinfo
, relnum
, rela
.get_r_offset(),
3260 _("cannot relocate %s in object file"),
3261 reloc_name
.c_str());
3265 const Sized_relobj_file
<size
, big_endian
>* object
= relinfo
->object
;
3267 // Pick the value to use for symbols defined in the PLT.
3268 Symbol_value
<size
> symval
;
3270 && gsym
->use_plt_offset(reloc_property
->reference_flags()))
3272 symval
.set_output_value(target
->plt_address_for_global(gsym
));
3275 else if (gsym
== NULL
&& psymval
->is_ifunc_symbol())
3277 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
3278 if (object
->local_has_plt_offset(r_sym
))
3280 symval
.set_output_value(target
->plt_address_for_local(object
, r_sym
));
3285 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3287 // Get the GOT offset if needed.
3288 // For aarch64, the GOT pointer points to the start of the GOT section.
3289 bool have_got_offset
= false;
3291 int got_base
= (target
->got_
!= NULL
3292 ? (target
->got_
->current_data_size() >= 0x8000
3297 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0
:
3298 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0_NC
:
3299 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1
:
3300 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1_NC
:
3301 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2
:
3302 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2_NC
:
3303 case elfcpp::R_AARCH64_MOVW_GOTOFF_G3
:
3304 case elfcpp::R_AARCH64_GOTREL64
:
3305 case elfcpp::R_AARCH64_GOTREL32
:
3306 case elfcpp::R_AARCH64_GOT_LD_PREL19
:
3307 case elfcpp::R_AARCH64_LD64_GOTOFF_LO15
:
3308 case elfcpp::R_AARCH64_ADR_GOT_PAGE
:
3309 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC
:
3310 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15
:
3313 gold_assert(gsym
->has_got_offset(GOT_TYPE_STANDARD
));
3314 got_offset
= gsym
->got_offset(GOT_TYPE_STANDARD
) - got_base
;
3318 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
3319 gold_assert(object
->local_has_got_offset(r_sym
, GOT_TYPE_STANDARD
));
3320 got_offset
= (object
->local_got_offset(r_sym
, GOT_TYPE_STANDARD
)
3323 have_got_offset
= true;
3330 typename
Reloc::Status reloc_status
= Reloc::STATUS_OKAY
;
3331 typename
elfcpp::Elf_types
<size
>::Elf_Addr value
;
3334 case elfcpp::R_AARCH64_NONE
:
3337 case elfcpp::R_AARCH64_ABS64
:
3338 reloc_status
= Reloc::template rela_ua
<64>(
3339 view
, object
, psymval
, addend
, reloc_property
);
3342 case elfcpp::R_AARCH64_ABS32
:
3343 reloc_status
= Reloc::template rela_ua
<32>(
3344 view
, object
, psymval
, addend
, reloc_property
);
3347 case elfcpp::R_AARCH64_ABS16
:
3348 reloc_status
= Reloc::template rela_ua
<16>(
3349 view
, object
, psymval
, addend
, reloc_property
);
3352 case elfcpp::R_AARCH64_PREL64
:
3353 reloc_status
= Reloc::template pcrela_ua
<64>(
3354 view
, object
, psymval
, addend
, address
, reloc_property
);
3356 case elfcpp::R_AARCH64_PREL32
:
3357 reloc_status
= Reloc::template pcrela_ua
<32>(
3358 view
, object
, psymval
, addend
, address
, reloc_property
);
3360 case elfcpp::R_AARCH64_PREL16
:
3361 reloc_status
= Reloc::template pcrela_ua
<16>(
3362 view
, object
, psymval
, addend
, address
, reloc_property
);
3364 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC
:
3365 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21
:
3366 reloc_status
= Reloc::adrp(view
, object
, psymval
, addend
, address
,
3370 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC
:
3371 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC
:
3372 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC
:
3373 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC
:
3374 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC
:
3375 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC
:
3376 reloc_status
= Reloc::template rela_general
<32>(
3377 view
, object
, psymval
, addend
, reloc_property
);
3380 case elfcpp::R_AARCH64_CALL26
:
3381 if (this->skip_call_tls_get_addr_
)
3383 // Double check that the TLSGD insn has been optimized away.
3384 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Insntype
;
3385 Insntype insn
= elfcpp::Swap
<32, big_endian
>::readval(
3386 reinterpret_cast<Insntype
*>(view
));
3387 gold_assert((insn
& 0xff000000) == 0x91000000);
3389 reloc_status
= Reloc::STATUS_OKAY
;
3390 this->skip_call_tls_get_addr_
= false;
3391 // Return false to stop further processing this reloc.
3395 case elfcpp::R_AARCH64_TSTBR14
:
3396 case elfcpp::R_AARCH64_CONDBR19
:
3397 case elfcpp::R_AARCH64_JUMP26
:
3398 reloc_status
= Reloc::template pcrela_general
<32>(
3399 view
, object
, psymval
, addend
, address
, reloc_property
);
3402 case elfcpp::R_AARCH64_ADR_GOT_PAGE
:
3403 gold_assert(have_got_offset
);
3404 value
= target
->got_
->address() + got_base
+ got_offset
;
3405 reloc_status
= Reloc::adrp(view
, value
+ addend
, address
);
3408 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC
:
3409 gold_assert(have_got_offset
);
3410 value
= target
->got_
->address() + got_base
+ got_offset
;
3411 reloc_status
= Reloc::template rela_general
<32>(
3412 view
, value
, addend
, reloc_property
);
3415 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
3416 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
:
3417 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
3418 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
3419 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
:
3420 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
:
3421 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
3422 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
3423 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
3424 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
3425 case elfcpp::R_AARCH64_TLSDESC_CALL
:
3426 reloc_status
= relocate_tls(relinfo
, target
, relnum
, rela
, r_type
,
3427 gsym
, psymval
, view
, address
);
3430 // These are dynamic relocations, which are unexpected when linking.
3431 case elfcpp::R_AARCH64_COPY
:
3432 case elfcpp::R_AARCH64_GLOB_DAT
:
3433 case elfcpp::R_AARCH64_JUMP_SLOT
:
3434 case elfcpp::R_AARCH64_RELATIVE
:
3435 case elfcpp::R_AARCH64_IRELATIVE
:
3436 case elfcpp::R_AARCH64_TLS_DTPREL64
:
3437 case elfcpp::R_AARCH64_TLS_DTPMOD64
:
3438 case elfcpp::R_AARCH64_TLS_TPREL64
:
3439 case elfcpp::R_AARCH64_TLSDESC
:
3440 gold_error_at_location(relinfo
, relnum
, rela
.get_r_offset(),
3441 _("unexpected reloc %u in object file"),
3446 gold_error_at_location(relinfo
, relnum
, rela
.get_r_offset(),
3447 _("unsupported reloc %s"),
3448 reloc_property
->name().c_str());
3452 // Report any errors.
3453 switch (reloc_status
)
3455 case Reloc::STATUS_OKAY
:
3457 case Reloc::STATUS_OVERFLOW
:
3458 gold_error_at_location(relinfo
, relnum
, rela
.get_r_offset(),
3459 _("relocation overflow in %s"),
3460 reloc_property
->name().c_str());
3462 case Reloc::STATUS_BAD_RELOC
:
3463 gold_error_at_location(
3466 rela
.get_r_offset(),
3467 _("unexpected opcode while processing relocation %s"),
3468 reloc_property
->name().c_str());
3478 template<int size
, bool big_endian
>
3480 typename AArch64_relocate_functions
<size
,big_endian
>::Status
3481 Target_aarch64
<size
, big_endian
>::Relocate::relocate_tls(
3482 const Relocate_info
<size
,big_endian
>* relinfo
,
3483 Target_aarch64
<size
, big_endian
>* target
,
3485 const elfcpp::Rela
<size
, big_endian
>& rela
,
3486 unsigned int r_type
, const Sized_symbol
<size
>* gsym
,
3487 const Symbol_value
<size
>* psymval
,
3488 unsigned char* view
,
3489 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
3491 typedef AArch64_relocate_functions
<size
,big_endian
> aarch64_reloc_funcs
;
3492 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr AArch64_address
;
3494 Output_segment
* tls_segment
= relinfo
->layout
->tls_segment();
3495 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3496 const AArch64_reloc_property
* reloc_property
=
3497 aarch64_reloc_property_table
->get_reloc_property(r_type
);
3498 gold_assert(reloc_property
!= NULL
);
3500 const bool is_final
= (gsym
== NULL
3501 ? !parameters
->options().shared()
3502 : gsym
->final_value_is_known());
3503 tls::Tls_optimization tlsopt
= Target_aarch64
<size
, big_endian
>::
3504 optimize_tls_reloc(is_final
, r_type
);
3506 Sized_relobj_file
<size
,big_endian
>* object
= relinfo
->object
;
3507 int tls_got_offset_type
;
3510 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
3511 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
: // Global-dynamic
3513 if (tlsopt
== tls::TLSOPT_TO_LE
)
3515 if (tls_segment
== NULL
)
3517 gold_assert(parameters
->errors()->error_count() > 0
3518 || issue_undefined_symbol_error(gsym
));
3519 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3521 return tls_gd_to_le(relinfo
, target
, rela
, r_type
, view
,
3524 else if (tlsopt
== tls::TLSOPT_NONE
)
3526 tls_got_offset_type
= GOT_TYPE_TLS_PAIR
;
3527 // Firstly get the address for the got entry.
3528 typename
elfcpp::Elf_types
<size
>::Elf_Addr got_entry_address
;
3531 gold_assert(gsym
->has_got_offset(tls_got_offset_type
));
3532 got_entry_address
= target
->got_
->address() +
3533 gsym
->got_offset(tls_got_offset_type
);
3537 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
3539 object
->local_has_got_offset(r_sym
, tls_got_offset_type
));
3540 got_entry_address
= target
->got_
->address() +
3541 object
->local_got_offset(r_sym
, tls_got_offset_type
);
3544 // Relocate the address into adrp/ld, adrp/add pair.
3547 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21
:
3548 return aarch64_reloc_funcs::adrp(
3549 view
, got_entry_address
+ addend
, address
);
3553 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
:
3554 return aarch64_reloc_funcs::template rela_general
<32>(
3555 view
, got_entry_address
, addend
, reloc_property
);
3562 gold_error_at_location(relinfo
, relnum
, rela
.get_r_offset(),
3563 _("unsupported gd_to_ie relaxation on %u"),
3568 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
3569 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
: // Initial-exec
3571 if (tlsopt
== tls::TLSOPT_TO_LE
)
3573 if (tls_segment
== NULL
)
3575 gold_assert(parameters
->errors()->error_count() > 0
3576 || issue_undefined_symbol_error(gsym
));
3577 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3579 return tls_ie_to_le(relinfo
, target
, rela
, r_type
, view
,
3582 tls_got_offset_type
= GOT_TYPE_TLS_OFFSET
;
3584 // Firstly get the address for the got entry.
3585 typename
elfcpp::Elf_types
<size
>::Elf_Addr got_entry_address
;
3588 gold_assert(gsym
->has_got_offset(tls_got_offset_type
));
3589 got_entry_address
= target
->got_
->address() +
3590 gsym
->got_offset(tls_got_offset_type
);
3594 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
3596 object
->local_has_got_offset(r_sym
, tls_got_offset_type
));
3597 got_entry_address
= target
->got_
->address() +
3598 object
->local_got_offset(r_sym
, tls_got_offset_type
);
3600 // Relocate the address into adrp/ld, adrp/add pair.
3603 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
3604 return aarch64_reloc_funcs::adrp(view
, got_entry_address
+ addend
,
3607 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
3608 return aarch64_reloc_funcs::template rela_general
<32>(
3609 view
, got_entry_address
, addend
, reloc_property
);
3614 // We shall never reach here.
3617 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
:
3618 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
:
3619 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
3621 gold_assert(tls_segment
!= NULL
);
3622 AArch64_address value
= psymval
->value(object
, 0);
3624 if (!parameters
->options().shared())
3626 AArch64_address aligned_tcb_size
=
3627 align_address(target
->tcb_size(),
3628 tls_segment
->maximum_alignment());
3629 return aarch64_reloc_funcs::template
3630 rela_general
<32>(view
,
3631 value
+ aligned_tcb_size
,
3636 gold_error(_("%s: unsupported reloc %u "
3637 "in non-static TLSLE mode."),
3638 object
->name().c_str(), r_type
);
3642 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
3643 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
3644 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
3645 case elfcpp::R_AARCH64_TLSDESC_CALL
:
3647 if (tlsopt
== tls::TLSOPT_TO_LE
)
3649 if (tls_segment
== NULL
)
3651 gold_assert(parameters
->errors()->error_count() > 0
3652 || issue_undefined_symbol_error(gsym
));
3653 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3655 return tls_desc_gd_to_le(relinfo
, target
, rela
, r_type
,
3660 tls_got_offset_type
= (tlsopt
== tls::TLSOPT_TO_IE
3661 ? GOT_TYPE_TLS_OFFSET
3662 : GOT_TYPE_TLS_DESC
);
3663 unsigned int got_tlsdesc_offset
= 0;
3664 if (r_type
!= elfcpp::R_AARCH64_TLSDESC_CALL
3665 && tlsopt
== tls::TLSOPT_NONE
)
3667 // We created GOT entries in the .got.tlsdesc portion of the
3668 // .got.plt section, but the offset stored in the symbol is the
3669 // offset within .got.tlsdesc.
3670 got_tlsdesc_offset
= (target
->got_
->data_size()
3671 + target
->got_plt_section()->data_size());
3673 typename
elfcpp::Elf_types
<size
>::Elf_Addr got_entry_address
;
3676 gold_assert(gsym
->has_got_offset(tls_got_offset_type
));
3677 got_entry_address
= target
->got_
->address()
3678 + got_tlsdesc_offset
3679 + gsym
->got_offset(tls_got_offset_type
);
3683 unsigned int r_sym
= elfcpp::elf_r_sym
<size
>(rela
.get_r_info());
3685 object
->local_has_got_offset(r_sym
, tls_got_offset_type
));
3686 got_entry_address
= target
->got_
->address() +
3687 got_tlsdesc_offset
+
3688 object
->local_got_offset(r_sym
, tls_got_offset_type
);
3690 if (tlsopt
== tls::TLSOPT_TO_IE
)
3692 if (tls_segment
== NULL
)
3694 gold_assert(parameters
->errors()->error_count() > 0
3695 || issue_undefined_symbol_error(gsym
));
3696 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3698 return tls_desc_gd_to_ie(relinfo
, target
, rela
, r_type
,
3699 view
, psymval
, got_entry_address
,
3703 // Now do tlsdesc relocation.
3706 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
3707 return aarch64_reloc_funcs::adrp(view
,
3708 got_entry_address
+ addend
,
3711 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
3712 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
3713 return aarch64_reloc_funcs::template rela_general
<32>(
3714 view
, got_entry_address
, addend
, reloc_property
);
3716 case elfcpp::R_AARCH64_TLSDESC_CALL
:
3717 return aarch64_reloc_funcs::STATUS_OKAY
;
3727 gold_error(_("%s: unsupported TLS reloc %u."),
3728 object
->name().c_str(), r_type
);
3730 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3731 } // End of relocate_tls.
3734 template<int size
, bool big_endian
>
3736 typename AArch64_relocate_functions
<size
,big_endian
>::Status
3737 Target_aarch64
<size
, big_endian
>::Relocate::tls_gd_to_le(
3738 const Relocate_info
<size
,big_endian
>* relinfo
,
3739 Target_aarch64
<size
, big_endian
>* target
,
3740 const elfcpp::Rela
<size
, big_endian
>& rela
,
3741 unsigned int r_type
,
3742 unsigned char* view
,
3743 const Symbol_value
<size
>* psymval
)
3745 typedef AArch64_relocate_functions
<size
,big_endian
> aarch64_reloc_funcs
;
3746 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Insntype
;
3747 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr AArch64_address
;
3749 Insntype
* ip
= reinterpret_cast<Insntype
*>(view
);
3750 Insntype insn1
= elfcpp::Swap
<32, big_endian
>::readval(ip
);
3751 Insntype insn2
= elfcpp::Swap
<32, big_endian
>::readval(ip
+ 1);
3752 Insntype insn3
= elfcpp::Swap
<32, big_endian
>::readval(ip
+ 2);
3754 if (r_type
== elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC
)
3756 // This is the 2nd relocs, optimization should already have been
3758 gold_assert((insn1
& 0xfff00000) == 0x91400000);
3759 return aarch64_reloc_funcs::STATUS_OKAY
;
3762 // The original sequence is -
3763 // 90000000 adrp x0, 0 <main>
3764 // 91000000 add x0, x0, #0x0
3765 // 94000000 bl 0 <__tls_get_addr>
3766 // optimized to sequence -
3767 // d53bd040 mrs x0, tpidr_el0
3768 // 91400000 add x0, x0, #0x0, lsl #12
3769 // 91000000 add x0, x0, #0x0
3771 // Unlike tls_ie_to_le, we change the 3 insns in one function call when we
3772 // encounter the first relocation "R_AARCH64_TLSGD_ADR_PAGE21". Because we
3773 // have to change "bl tls_get_addr", which does not have a corresponding tls
3774 // relocation type. So before proceeding, we need to make sure compiler
3775 // does not change the sequence.
3776 if(!(insn1
== 0x90000000 // adrp x0,0
3777 && insn2
== 0x91000000 // add x0, x0, #0x0
3778 && insn3
== 0x94000000)) // bl 0
3780 // Ideally we should give up gd_to_le relaxation and do gd access.
3781 // However the gd_to_le relaxation decision has been made early
3782 // in the scan stage, where we did not allocate any GOT entry for
3783 // this symbol. Therefore we have to exit and report error now.
3784 gold_error(_("unexpected reloc insn sequence while relaxing "
3785 "tls gd to le for reloc %u."), r_type
);
3786 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3790 insn1
= 0xd53bd040; // mrs x0, tpidr_el0
3791 insn2
= 0x91400000; // add x0, x0, #0x0, lsl #12
3792 insn3
= 0x91000000; // add x0, x0, #0x0
3793 elfcpp::Swap
<32, big_endian
>::writeval(ip
, insn1
);
3794 elfcpp::Swap
<32, big_endian
>::writeval(ip
+ 1, insn2
);
3795 elfcpp::Swap
<32, big_endian
>::writeval(ip
+ 2, insn3
);
3797 // Calculate tprel value.
3798 Output_segment
* tls_segment
= relinfo
->layout
->tls_segment();
3799 gold_assert(tls_segment
!= NULL
);
3800 AArch64_address value
= psymval
->value(relinfo
->object
, 0);
3801 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3802 AArch64_address aligned_tcb_size
=
3803 align_address(target
->tcb_size(), tls_segment
->maximum_alignment());
3804 AArch64_address x
= value
+ aligned_tcb_size
;
3806 // After new insns are written, apply TLSLE relocs.
3807 const AArch64_reloc_property
* rp1
=
3808 aarch64_reloc_property_table
->get_reloc_property(
3809 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12
);
3810 const AArch64_reloc_property
* rp2
=
3811 aarch64_reloc_property_table
->get_reloc_property(
3812 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12
);
3813 gold_assert(rp1
!= NULL
&& rp2
!= NULL
);
3815 typename
aarch64_reloc_funcs::Status s1
=
3816 aarch64_reloc_funcs::template rela_general
<32>(view
+ 4,
3820 if (s1
!= aarch64_reloc_funcs::STATUS_OKAY
)
3823 typename
aarch64_reloc_funcs::Status s2
=
3824 aarch64_reloc_funcs::template rela_general
<32>(view
+ 8,
3829 this->skip_call_tls_get_addr_
= true;
3831 } // End of tls_gd_to_le
3834 template<int size
, bool big_endian
>
3836 typename AArch64_relocate_functions
<size
,big_endian
>::Status
3837 Target_aarch64
<size
, big_endian
>::Relocate::tls_ie_to_le(
3838 const Relocate_info
<size
,big_endian
>* relinfo
,
3839 Target_aarch64
<size
, big_endian
>* target
,
3840 const elfcpp::Rela
<size
, big_endian
>& rela
,
3841 unsigned int r_type
,
3842 unsigned char* view
,
3843 const Symbol_value
<size
>* psymval
)
3845 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr AArch64_address
;
3846 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Insntype
;
3847 typedef AArch64_relocate_functions
<size
,big_endian
> aarch64_reloc_funcs
;
3849 AArch64_address value
= psymval
->value(relinfo
->object
, 0);
3850 Output_segment
* tls_segment
= relinfo
->layout
->tls_segment();
3851 AArch64_address aligned_tcb_address
=
3852 align_address(target
->tcb_size(), tls_segment
->maximum_alignment());
3853 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3854 AArch64_address x
= value
+ addend
+ aligned_tcb_address
;
3855 // "x" is the offset to tp, we can only do this if x is within
3856 // range [0, 2^32-1]
3857 if (!(size
== 32 || (size
== 64 && (static_cast<uint64_t>(x
) >> 32) == 0)))
3859 gold_error(_("TLS variable referred by reloc %u is too far from TP."),
3861 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3864 Insntype
* ip
= reinterpret_cast<Insntype
*>(view
);
3865 Insntype insn
= elfcpp::Swap
<32, big_endian
>::readval(ip
);
3868 if (r_type
== elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
)
3871 regno
= (insn
& 0x1f);
3872 newinsn
= (0xd2a00000 | regno
) | (((x
>> 16) & 0xffff) << 5);
3874 else if (r_type
== elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
)
3877 regno
= (insn
& 0x1f);
3878 gold_assert(regno
== ((insn
>> 5) & 0x1f));
3879 newinsn
= (0xf2800000 | regno
) | ((x
& 0xffff) << 5);
3884 elfcpp::Swap
<32, big_endian
>::writeval(ip
, newinsn
);
3885 return aarch64_reloc_funcs::STATUS_OKAY
;
3886 } // End of tls_ie_to_le
3889 template<int size
, bool big_endian
>
3891 typename AArch64_relocate_functions
<size
,big_endian
>::Status
3892 Target_aarch64
<size
, big_endian
>::Relocate::tls_desc_gd_to_le(
3893 const Relocate_info
<size
,big_endian
>* relinfo
,
3894 Target_aarch64
<size
, big_endian
>* target
,
3895 const elfcpp::Rela
<size
, big_endian
>& rela
,
3896 unsigned int r_type
,
3897 unsigned char* view
,
3898 const Symbol_value
<size
>* psymval
)
3900 typedef typename
elfcpp::Elf_types
<size
>::Elf_Addr AArch64_address
;
3901 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Insntype
;
3902 typedef AArch64_relocate_functions
<size
,big_endian
> aarch64_reloc_funcs
;
3904 // TLSDESC-GD sequence is like:
3905 // adrp x0, :tlsdesc:v1
3906 // ldr x1, [x0, #:tlsdesc_lo12:v1]
3907 // add x0, x0, :tlsdesc_lo12:v1
3910 // After desc_gd_to_le optimization, the sequence will be like:
3911 // movz x0, #0x0, lsl #16
3916 // Calculate tprel value.
3917 Output_segment
* tls_segment
= relinfo
->layout
->tls_segment();
3918 gold_assert(tls_segment
!= NULL
);
3919 Insntype
* ip
= reinterpret_cast<Insntype
*>(view
);
3920 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3921 AArch64_address value
= psymval
->value(relinfo
->object
, addend
);
3922 AArch64_address aligned_tcb_size
=
3923 align_address(target
->tcb_size(), tls_segment
->maximum_alignment());
3924 AArch64_address x
= value
+ aligned_tcb_size
;
3925 // x is the offset to tp, we can only do this if x is within range
3926 // [0, 2^32-1]. If x is out of range, fail and exit.
3927 if (size
== 64 && (static_cast<uint64_t>(x
) >> 32) != 0)
3929 gold_error(_("TLS variable referred by reloc %u is too far from TP. "
3930 "We Can't do gd_to_le relaxation.\n"), r_type
);
3931 return aarch64_reloc_funcs::STATUS_BAD_RELOC
;
3936 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
3937 case elfcpp::R_AARCH64_TLSDESC_CALL
:
3939 newinsn
= 0xd503201f;
3942 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
3944 newinsn
= 0xd2a00000 | (((x
>> 16) & 0xffff) << 5);
3947 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
3949 newinsn
= 0xf2800000 | ((x
& 0xffff) << 5);
3953 gold_error(_("unsupported tlsdesc gd_to_le optimization on reloc %u"),
3957 elfcpp::Swap
<32, big_endian
>::writeval(ip
, newinsn
);
3958 return aarch64_reloc_funcs::STATUS_OKAY
;
3959 } // End of tls_desc_gd_to_le
3962 template<int size
, bool big_endian
>
3964 typename AArch64_relocate_functions
<size
,big_endian
>::Status
3965 Target_aarch64
<size
, big_endian
>::Relocate::tls_desc_gd_to_ie(
3966 const Relocate_info
<size
,big_endian
>* /* relinfo */,
3967 Target_aarch64
<size
, big_endian
>* /* target */,
3968 const elfcpp::Rela
<size
, big_endian
>& rela
,
3969 unsigned int r_type
,
3970 unsigned char* view
,
3971 const Symbol_value
<size
>* /* psymval */,
3972 typename
elfcpp::Elf_types
<size
>::Elf_Addr got_entry_address
,
3973 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
3975 typedef typename
elfcpp::Swap
<32, big_endian
>::Valtype Insntype
;
3976 typedef AArch64_relocate_functions
<size
,big_endian
> aarch64_reloc_funcs
;
3978 // TLSDESC-GD sequence is like:
3979 // adrp x0, :tlsdesc:v1
3980 // ldr x1, [x0, #:tlsdesc_lo12:v1]
3981 // add x0, x0, :tlsdesc_lo12:v1
3984 // After desc_gd_to_ie optimization, the sequence will be like:
3985 // adrp x0, :tlsie:v1
3986 // ldr x0, [x0, :tlsie_lo12:v1]
3990 Insntype
* ip
= reinterpret_cast<Insntype
*>(view
);
3991 const elfcpp::Elf_Xword addend
= rela
.get_r_addend();
3995 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12
:
3996 case elfcpp::R_AARCH64_TLSDESC_CALL
:
3998 newinsn
= 0xd503201f;
3999 elfcpp::Swap
<32, big_endian
>::writeval(ip
, newinsn
);
4002 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21
:
4004 return aarch64_reloc_funcs::adrp(view
, got_entry_address
+ addend
,
4009 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12
:
4011 const AArch64_reloc_property
* reloc_property
=
4012 aarch64_reloc_property_table
->get_reloc_property(
4013 elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
);
4014 return aarch64_reloc_funcs::template rela_general
<32>(
4015 view
, got_entry_address
, addend
, reloc_property
);
4020 gold_error(_("Don't support tlsdesc gd_to_ie optimization on reloc %u"),
4024 return aarch64_reloc_funcs::STATUS_OKAY
;
4025 } // End of tls_desc_gd_to_ie
4027 // Relocate section data.
4029 template<int size
, bool big_endian
>
4031 Target_aarch64
<size
, big_endian
>::relocate_section(
4032 const Relocate_info
<size
, big_endian
>* relinfo
,
4033 unsigned int sh_type
,
4034 const unsigned char* prelocs
,
4036 Output_section
* output_section
,
4037 bool needs_special_offset_handling
,
4038 unsigned char* view
,
4039 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
,
4040 section_size_type view_size
,
4041 const Reloc_symbol_changes
* reloc_symbol_changes
)
4043 gold_assert(sh_type
== elfcpp::SHT_RELA
);
4044 typedef typename Target_aarch64
<size
, big_endian
>::Relocate AArch64_relocate
;
4045 gold::relocate_section
<size
, big_endian
, Target_aarch64
, elfcpp::SHT_RELA
,
4046 AArch64_relocate
, gold::Default_comdat_behavior
>(
4052 needs_special_offset_handling
,
4056 reloc_symbol_changes
);
4059 // Return the size of a relocation while scanning during a relocatable
4062 template<int size
, bool big_endian
>
4064 Target_aarch64
<size
, big_endian
>::Relocatable_size_for_reloc::
4069 // We will never support SHT_REL relocations.
4074 // Scan the relocs during a relocatable link.
4076 template<int size
, bool big_endian
>
4078 Target_aarch64
<size
, big_endian
>::scan_relocatable_relocs(
4079 Symbol_table
* symtab
,
4081 Sized_relobj_file
<size
, big_endian
>* object
,
4082 unsigned int data_shndx
,
4083 unsigned int sh_type
,
4084 const unsigned char* prelocs
,
4086 Output_section
* output_section
,
4087 bool needs_special_offset_handling
,
4088 size_t local_symbol_count
,
4089 const unsigned char* plocal_symbols
,
4090 Relocatable_relocs
* rr
)
4092 gold_assert(sh_type
== elfcpp::SHT_RELA
);
4094 typedef gold::Default_scan_relocatable_relocs
<elfcpp::SHT_RELA
,
4095 Relocatable_size_for_reloc
> Scan_relocatable_relocs
;
4097 gold::scan_relocatable_relocs
<size
, big_endian
, elfcpp::SHT_RELA
,
4098 Scan_relocatable_relocs
>(
4106 needs_special_offset_handling
,
4112 // Relocate a section during a relocatable link.
4114 template<int size
, bool big_endian
>
4116 Target_aarch64
<size
, big_endian
>::relocate_relocs(
4117 const Relocate_info
<size
, big_endian
>* relinfo
,
4118 unsigned int sh_type
,
4119 const unsigned char* prelocs
,
4121 Output_section
* output_section
,
4122 typename
elfcpp::Elf_types
<size
>::Elf_Off offset_in_output_section
,
4123 const Relocatable_relocs
* rr
,
4124 unsigned char* view
,
4125 typename
elfcpp::Elf_types
<size
>::Elf_Addr view_address
,
4126 section_size_type view_size
,
4127 unsigned char* reloc_view
,
4128 section_size_type reloc_view_size
)
4130 gold_assert(sh_type
== elfcpp::SHT_RELA
);
4132 gold::relocate_relocs
<size
, big_endian
, elfcpp::SHT_RELA
>(
4137 offset_in_output_section
,
4146 // The selector for aarch64 object files.
4148 template<int size
, bool big_endian
>
4149 class Target_selector_aarch64
: public Target_selector
4152 Target_selector_aarch64();
4155 do_instantiate_target()
4156 { return new Target_aarch64
<size
, big_endian
>(); }
4160 Target_selector_aarch64
<32, true>::Target_selector_aarch64()
4161 : Target_selector(elfcpp::EM_AARCH64
, 32, true,
4162 "elf32-bigaarch64", "aarch64_elf32_be_vec")
4166 Target_selector_aarch64
<32, false>::Target_selector_aarch64()
4167 : Target_selector(elfcpp::EM_AARCH64
, 32, false,
4168 "elf32-littleaarch64", "aarch64_elf32_le_vec")
4172 Target_selector_aarch64
<64, true>::Target_selector_aarch64()
4173 : Target_selector(elfcpp::EM_AARCH64
, 64, true,
4174 "elf64-bigaarch64", "aarch64_elf64_be_vec")
4178 Target_selector_aarch64
<64, false>::Target_selector_aarch64()
4179 : Target_selector(elfcpp::EM_AARCH64
, 64, false,
4180 "elf64-littleaarch64", "aarch64_elf64_le_vec")
4183 Target_selector_aarch64
<32, true> target_selector_aarch64elf32b
;
4184 Target_selector_aarch64
<32, false> target_selector_aarch64elf32
;
4185 Target_selector_aarch64
<64, true> target_selector_aarch64elfb
;
4186 Target_selector_aarch64
<64, false> target_selector_aarch64elf
;
4188 } // End anonymous namespace.