Fix possible bug when no args have been provided to the executable
[deliverable/binutils-gdb.git] / gold / aarch64.cc
CommitLineData
053a4d68
JY
1// aarch64.cc -- aarch64 target support for gold.
2
2571583a 3// Copyright (C) 2014-2017 Free Software Foundation, Inc.
9363c7c3 4// Written by Jing Yu <jingyu@google.com> and Han Shen <shenhan@google.com>.
053a4d68
JY
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#include "gold.h"
24
25#include <cstring>
5019d64a 26#include <map>
a48d0c12 27#include <set>
053a4d68
JY
28
29#include "elfcpp.h"
30#include "dwarf.h"
31#include "parameters.h"
32#include "reloc.h"
33#include "aarch64.h"
34#include "object.h"
35#include "symtab.h"
36#include "layout.h"
37#include "output.h"
38#include "copy-relocs.h"
39#include "target.h"
40#include "target-reloc.h"
41#include "target-select.h"
42#include "tls.h"
43#include "freebsd.h"
44#include "nacl.h"
45#include "gc.h"
46#include "icf.h"
9363c7c3 47#include "aarch64-reloc-property.h"
053a4d68
JY
48
49// The first three .got.plt entries are reserved.
50const int32_t AARCH64_GOTPLT_RESERVE_COUNT = 3;
51
83a01957 52
053a4d68
JY
53namespace
54{
55
56using namespace gold;
57
58template<int size, bool big_endian>
59class Output_data_plt_aarch64;
60
61template<int size, bool big_endian>
62class Output_data_plt_aarch64_standard;
63
64template<int size, bool big_endian>
65class Target_aarch64;
66
9363c7c3
JY
67template<int size, bool big_endian>
68class AArch64_relocate_functions;
69
5019d64a
HS
70// Utility class dealing with insns. This is ported from macros in
71// bfd/elfnn-aarch64.cc, but wrapped inside a class as static members. This
72// class is used in erratum sequence scanning.
73
74template<bool big_endian>
75class AArch64_insn_utilities
76{
77public:
78 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
79
2f0c79aa
HS
80 static const int BYTES_PER_INSN;
81
82 // Zero register encoding - 31.
83 static const unsigned int AARCH64_ZR;
5019d64a
HS
84
85 static unsigned int
86 aarch64_bit(Insntype insn, int pos)
87 { return ((1 << pos) & insn) >> pos; }
88
89 static unsigned int
90 aarch64_bits(Insntype insn, int pos, int l)
91 { return (insn >> pos) & ((1 << l) - 1); }
92
2f0c79aa
HS
93 // Get the encoding field "op31" of 3-source data processing insns. "op31" is
94 // the name defined in armv8 insn manual C3.5.9.
95 static unsigned int
96 aarch64_op31(Insntype insn)
97 { return aarch64_bits(insn, 21, 3); }
98
99 // Get the encoding field "ra" of 3-source data processing insns. "ra" is the
100 // third source register. See armv8 insn manual C3.5.9.
101 static unsigned int
102 aarch64_ra(Insntype insn)
103 { return aarch64_bits(insn, 10, 5); }
104
0ef3814f
HS
105 static bool
106 is_adr(const Insntype insn)
107 { return (insn & 0x9F000000) == 0x10000000; }
108
5019d64a
HS
109 static bool
110 is_adrp(const Insntype insn)
111 { return (insn & 0x9F000000) == 0x90000000; }
112
113 static unsigned int
114 aarch64_rm(const Insntype insn)
115 { return aarch64_bits(insn, 16, 5); }
116
117 static unsigned int
118 aarch64_rn(const Insntype insn)
119 { return aarch64_bits(insn, 5, 5); }
120
121 static unsigned int
122 aarch64_rd(const Insntype insn)
123 { return aarch64_bits(insn, 0, 5); }
124
125 static unsigned int
126 aarch64_rt(const Insntype insn)
127 { return aarch64_bits(insn, 0, 5); }
128
129 static unsigned int
130 aarch64_rt2(const Insntype insn)
131 { return aarch64_bits(insn, 10, 5); }
132
0ef3814f
HS
133 // Encode imm21 into adr. Signed imm21 is in the range of [-1M, 1M).
134 static Insntype
135 aarch64_adr_encode_imm(Insntype adr, int imm21)
136 {
137 gold_assert(is_adr(adr));
138 gold_assert(-(1 << 20) <= imm21 && imm21 < (1 << 20));
139 const int mask19 = (1 << 19) - 1;
140 const int mask2 = 3;
141 adr &= ~((mask19 << 5) | (mask2 << 29));
142 adr |= ((imm21 & mask2) << 29) | (((imm21 >> 2) & mask19) << 5);
143 return adr;
144 }
145
146 // Retrieve encoded adrp 33-bit signed imm value. This value is obtained by
147 // 21-bit signed imm encoded in the insn multiplied by 4k (page size) and
148 // 64-bit sign-extended, resulting in [-4G, 4G) with 12-lsb being 0.
149 static int64_t
150 aarch64_adrp_decode_imm(const Insntype adrp)
151 {
152 const int mask19 = (1 << 19) - 1;
153 const int mask2 = 3;
154 gold_assert(is_adrp(adrp));
155 // 21-bit imm encoded in adrp.
156 uint64_t imm = ((adrp >> 29) & mask2) | (((adrp >> 5) & mask19) << 2);
157 // Retrieve msb of 21-bit-signed imm for sign extension.
158 uint64_t msbt = (imm >> 20) & 1;
5c3024d2 159 // Real value is imm multiplied by 4k. Value now has 33-bit information.
0ef3814f
HS
160 int64_t value = imm << 12;
161 // Sign extend to 64-bit by repeating msbt 31 (64-33) times and merge it
162 // with value.
163 return ((((uint64_t)(1) << 32) - msbt) << 33) | value;
164 }
165
5019d64a
HS
166 static bool
167 aarch64_b(const Insntype insn)
168 { return (insn & 0xFC000000) == 0x14000000; }
169
170 static bool
171 aarch64_bl(const Insntype insn)
172 { return (insn & 0xFC000000) == 0x94000000; }
173
174 static bool
175 aarch64_blr(const Insntype insn)
176 { return (insn & 0xFFFFFC1F) == 0xD63F0000; }
177
178 static bool
179 aarch64_br(const Insntype insn)
180 { return (insn & 0xFFFFFC1F) == 0xD61F0000; }
181
182 // All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
183 // LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops.
184 static bool
185 aarch64_ld(Insntype insn) { return aarch64_bit(insn, 22) == 1; }
186
187 static bool
188 aarch64_ldst(Insntype insn)
189 { return (insn & 0x0a000000) == 0x08000000; }
190
191 static bool
192 aarch64_ldst_ex(Insntype insn)
193 { return (insn & 0x3f000000) == 0x08000000; }
194
195 static bool
196 aarch64_ldst_pcrel(Insntype insn)
197 { return (insn & 0x3b000000) == 0x18000000; }
198
199 static bool
200 aarch64_ldst_nap(Insntype insn)
201 { return (insn & 0x3b800000) == 0x28000000; }
202
203 static bool
204 aarch64_ldstp_pi(Insntype insn)
205 { return (insn & 0x3b800000) == 0x28800000; }
206
207 static bool
208 aarch64_ldstp_o(Insntype insn)
209 { return (insn & 0x3b800000) == 0x29000000; }
210
211 static bool
212 aarch64_ldstp_pre(Insntype insn)
213 { return (insn & 0x3b800000) == 0x29800000; }
214
215 static bool
216 aarch64_ldst_ui(Insntype insn)
217 { return (insn & 0x3b200c00) == 0x38000000; }
218
219 static bool
220 aarch64_ldst_piimm(Insntype insn)
221 { return (insn & 0x3b200c00) == 0x38000400; }
222
223 static bool
224 aarch64_ldst_u(Insntype insn)
225 { return (insn & 0x3b200c00) == 0x38000800; }
226
227 static bool
228 aarch64_ldst_preimm(Insntype insn)
229 { return (insn & 0x3b200c00) == 0x38000c00; }
230
231 static bool
232 aarch64_ldst_ro(Insntype insn)
233 { return (insn & 0x3b200c00) == 0x38200800; }
234
235 static bool
236 aarch64_ldst_uimm(Insntype insn)
237 { return (insn & 0x3b000000) == 0x39000000; }
238
239 static bool
240 aarch64_ldst_simd_m(Insntype insn)
241 { return (insn & 0xbfbf0000) == 0x0c000000; }
242
243 static bool
244 aarch64_ldst_simd_m_pi(Insntype insn)
245 { return (insn & 0xbfa00000) == 0x0c800000; }
246
247 static bool
248 aarch64_ldst_simd_s(Insntype insn)
249 { return (insn & 0xbf9f0000) == 0x0d000000; }
250
251 static bool
252 aarch64_ldst_simd_s_pi(Insntype insn)
253 { return (insn & 0xbf800000) == 0x0d800000; }
254
255 // Classify an INSN if it is indeed a load/store. Return true if INSN is a
256 // LD/ST instruction otherwise return false. For scalar LD/ST instructions
257 // PAIR is FALSE, RT is returned and RT2 is set equal to RT. For LD/ST pair
258 // instructions PAIR is TRUE, RT and RT2 are returned.
259 static bool
260 aarch64_mem_op_p(Insntype insn, unsigned int *rt, unsigned int *rt2,
261 bool *pair, bool *load)
262 {
263 uint32_t opcode;
264 unsigned int r;
265 uint32_t opc = 0;
266 uint32_t v = 0;
267 uint32_t opc_v = 0;
268
269 /* Bail out quickly if INSN doesn't fall into the the load-store
270 encoding space. */
271 if (!aarch64_ldst (insn))
272 return false;
273
274 *pair = false;
275 *load = false;
276 if (aarch64_ldst_ex (insn))
277 {
278 *rt = aarch64_rt (insn);
279 *rt2 = *rt;
280 if (aarch64_bit (insn, 21) == 1)
281 {
282 *pair = true;
283 *rt2 = aarch64_rt2 (insn);
284 }
285 *load = aarch64_ld (insn);
286 return true;
287 }
288 else if (aarch64_ldst_nap (insn)
289 || aarch64_ldstp_pi (insn)
290 || aarch64_ldstp_o (insn)
291 || aarch64_ldstp_pre (insn))
292 {
293 *pair = true;
294 *rt = aarch64_rt (insn);
295 *rt2 = aarch64_rt2 (insn);
296 *load = aarch64_ld (insn);
297 return true;
298 }
299 else if (aarch64_ldst_pcrel (insn)
300 || aarch64_ldst_ui (insn)
301 || aarch64_ldst_piimm (insn)
302 || aarch64_ldst_u (insn)
303 || aarch64_ldst_preimm (insn)
304 || aarch64_ldst_ro (insn)
305 || aarch64_ldst_uimm (insn))
306 {
307 *rt = aarch64_rt (insn);
308 *rt2 = *rt;
309 if (aarch64_ldst_pcrel (insn))
310 *load = true;
311 opc = aarch64_bits (insn, 22, 2);
312 v = aarch64_bit (insn, 26);
313 opc_v = opc | (v << 2);
314 *load = (opc_v == 1 || opc_v == 2 || opc_v == 3
315 || opc_v == 5 || opc_v == 7);
316 return true;
317 }
318 else if (aarch64_ldst_simd_m (insn)
319 || aarch64_ldst_simd_m_pi (insn))
320 {
321 *rt = aarch64_rt (insn);
322 *load = aarch64_bit (insn, 22);
323 opcode = (insn >> 12) & 0xf;
324 switch (opcode)
325 {
326 case 0:
327 case 2:
328 *rt2 = *rt + 3;
329 break;
330
331 case 4:
332 case 6:
333 *rt2 = *rt + 2;
334 break;
335
336 case 7:
337 *rt2 = *rt;
338 break;
339
340 case 8:
341 case 10:
342 *rt2 = *rt + 1;
343 break;
344
345 default:
346 return false;
347 }
348 return true;
349 }
350 else if (aarch64_ldst_simd_s (insn)
351 || aarch64_ldst_simd_s_pi (insn))
352 {
353 *rt = aarch64_rt (insn);
354 r = (insn >> 21) & 1;
355 *load = aarch64_bit (insn, 22);
356 opcode = (insn >> 13) & 0x7;
357 switch (opcode)
358 {
359 case 0:
360 case 2:
361 case 4:
362 *rt2 = *rt + r;
363 break;
364
365 case 1:
366 case 3:
367 case 5:
368 *rt2 = *rt + (r == 0 ? 2 : 3);
369 break;
370
371 case 6:
372 *rt2 = *rt + r;
373 break;
374
375 case 7:
376 *rt2 = *rt + (r == 0 ? 2 : 3);
377 break;
378
379 default:
380 return false;
381 }
382 return true;
383 }
384 return false;
2f0c79aa
HS
385 } // End of "aarch64_mem_op_p".
386
387 // Return true if INSN is mac insn.
388 static bool
389 aarch64_mac(Insntype insn)
390 { return (insn & 0xff000000) == 0x9b000000; }
391
392 // Return true if INSN is multiply-accumulate.
393 // (This is similar to implementaton in elfnn-aarch64.c.)
394 static bool
395 aarch64_mlxl(Insntype insn)
396 {
397 uint32_t op31 = aarch64_op31(insn);
398 if (aarch64_mac(insn)
399 && (op31 == 0 || op31 == 1 || op31 == 5)
400 /* Exclude MUL instructions which are encoded as a multiple-accumulate
401 with RA = XZR. */
402 && aarch64_ra(insn) != AARCH64_ZR)
403 {
404 return true;
405 }
406 return false;
5019d64a 407 }
2f0c79aa
HS
408}; // End of "AArch64_insn_utilities".
409
410
411// Insn length in byte.
412
413template<bool big_endian>
414const int AArch64_insn_utilities<big_endian>::BYTES_PER_INSN = 4;
415
416
417// Zero register encoding - 31.
418
419template<bool big_endian>
420const unsigned int AArch64_insn_utilities<big_endian>::AARCH64_ZR = 0x1f;
5019d64a
HS
421
422
053a4d68
JY
423// Output_data_got_aarch64 class.
424
425template<int size, bool big_endian>
426class Output_data_got_aarch64 : public Output_data_got<size, big_endian>
427{
428 public:
429 typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
430 Output_data_got_aarch64(Symbol_table* symtab, Layout* layout)
9363c7c3
JY
431 : Output_data_got<size, big_endian>(),
432 symbol_table_(symtab), layout_(layout)
053a4d68
JY
433 { }
434
8e33481e
HS
435 // Add a static entry for the GOT entry at OFFSET. GSYM is a global
436 // symbol and R_TYPE is the code of a dynamic relocation that needs to be
437 // applied in a static link.
438 void
439 add_static_reloc(unsigned int got_offset, unsigned int r_type, Symbol* gsym)
440 { this->static_relocs_.push_back(Static_reloc(got_offset, r_type, gsym)); }
441
442
443 // Add a static reloc for the GOT entry at OFFSET. RELOBJ is an object
444 // defining a local symbol with INDEX. R_TYPE is the code of a dynamic
445 // relocation that needs to be applied in a static link.
446 void
447 add_static_reloc(unsigned int got_offset, unsigned int r_type,
448 Sized_relobj_file<size, big_endian>* relobj,
449 unsigned int index)
450 {
451 this->static_relocs_.push_back(Static_reloc(got_offset, r_type, relobj,
452 index));
453 }
454
455
053a4d68
JY
456 protected:
457 // Write out the GOT table.
458 void
459 do_write(Output_file* of) {
460 // The first entry in the GOT is the address of the .dynamic section.
461 gold_assert(this->data_size() >= size / 8);
462 Output_section* dynamic = this->layout_->dynamic_section();
463 Valtype dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
464 this->replace_constant(0, dynamic_addr);
465 Output_data_got<size, big_endian>::do_write(of);
8e33481e
HS
466
467 // Handling static relocs
468 if (this->static_relocs_.empty())
469 return;
470
471 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
472
473 gold_assert(parameters->doing_static_link());
474 const off_t offset = this->offset();
475 const section_size_type oview_size =
476 convert_to_section_size_type(this->data_size());
477 unsigned char* const oview = of->get_output_view(offset, oview_size);
478
479 Output_segment* tls_segment = this->layout_->tls_segment();
480 gold_assert(tls_segment != NULL);
481
482 AArch64_address aligned_tcb_address =
83a01957 483 align_address(Target_aarch64<size, big_endian>::TCB_SIZE,
8e33481e
HS
484 tls_segment->maximum_alignment());
485
486 for (size_t i = 0; i < this->static_relocs_.size(); ++i)
487 {
488 Static_reloc& reloc(this->static_relocs_[i]);
489 AArch64_address value;
490
491 if (!reloc.symbol_is_global())
492 {
493 Sized_relobj_file<size, big_endian>* object = reloc.relobj();
494 const Symbol_value<size>* psymval =
495 reloc.relobj()->local_symbol(reloc.index());
496
497 // We are doing static linking. Issue an error and skip this
498 // relocation if the symbol is undefined or in a discarded_section.
499 bool is_ordinary;
500 unsigned int shndx = psymval->input_shndx(&is_ordinary);
501 if ((shndx == elfcpp::SHN_UNDEF)
502 || (is_ordinary
503 && shndx != elfcpp::SHN_UNDEF
504 && !object->is_section_included(shndx)
505 && !this->symbol_table_->is_section_folded(object, shndx)))
506 {
507 gold_error(_("undefined or discarded local symbol %u from "
508 " object %s in GOT"),
509 reloc.index(), reloc.relobj()->name().c_str());
510 continue;
511 }
512 value = psymval->value(object, 0);
513 }
514 else
515 {
516 const Symbol* gsym = reloc.symbol();
517 gold_assert(gsym != NULL);
518 if (gsym->is_forwarder())
519 gsym = this->symbol_table_->resolve_forwards(gsym);
520
521 // We are doing static linking. Issue an error and skip this
522 // relocation if the symbol is undefined or in a discarded_section
523 // unless it is a weakly_undefined symbol.
524 if ((gsym->is_defined_in_discarded_section()
525 || gsym->is_undefined())
526 && !gsym->is_weak_undefined())
527 {
528 gold_error(_("undefined or discarded symbol %s in GOT"),
529 gsym->name());
530 continue;
531 }
532
533 if (!gsym->is_weak_undefined())
534 {
535 const Sized_symbol<size>* sym =
536 static_cast<const Sized_symbol<size>*>(gsym);
537 value = sym->value();
538 }
539 else
540 value = 0;
541 }
542
543 unsigned got_offset = reloc.got_offset();
544 gold_assert(got_offset < oview_size);
545
546 typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
547 Valtype* wv = reinterpret_cast<Valtype*>(oview + got_offset);
548 Valtype x;
549 switch (reloc.r_type())
550 {
551 case elfcpp::R_AARCH64_TLS_DTPREL64:
552 x = value;
553 break;
554 case elfcpp::R_AARCH64_TLS_TPREL64:
555 x = value + aligned_tcb_address;
556 break;
557 default:
558 gold_unreachable();
559 }
560 elfcpp::Swap<size, big_endian>::writeval(wv, x);
561 }
562
563 of->write_output_view(offset, oview_size, oview);
053a4d68
JY
564 }
565
566 private:
9363c7c3
JY
567 // Symbol table of the output object.
568 Symbol_table* symbol_table_;
053a4d68
JY
569 // A pointer to the Layout class, so that we can find the .dynamic
570 // section when we write out the GOT section.
571 Layout* layout_;
8e33481e 572
8e33481e
HS
573 // This class represent dynamic relocations that need to be applied by
574 // gold because we are using TLS relocations in a static link.
575 class Static_reloc
576 {
577 public:
578 Static_reloc(unsigned int got_offset, unsigned int r_type, Symbol* gsym)
579 : got_offset_(got_offset), r_type_(r_type), symbol_is_global_(true)
580 { this->u_.global.symbol = gsym; }
581
582 Static_reloc(unsigned int got_offset, unsigned int r_type,
583 Sized_relobj_file<size, big_endian>* relobj, unsigned int index)
584 : got_offset_(got_offset), r_type_(r_type), symbol_is_global_(false)
585 {
586 this->u_.local.relobj = relobj;
587 this->u_.local.index = index;
588 }
589
590 // Return the GOT offset.
591 unsigned int
592 got_offset() const
593 { return this->got_offset_; }
594
595 // Relocation type.
596 unsigned int
597 r_type() const
598 { return this->r_type_; }
599
600 // Whether the symbol is global or not.
601 bool
602 symbol_is_global() const
603 { return this->symbol_is_global_; }
604
605 // For a relocation against a global symbol, the global symbol.
606 Symbol*
607 symbol() const
608 {
609 gold_assert(this->symbol_is_global_);
610 return this->u_.global.symbol;
611 }
612
613 // For a relocation against a local symbol, the defining object.
614 Sized_relobj_file<size, big_endian>*
615 relobj() const
616 {
617 gold_assert(!this->symbol_is_global_);
618 return this->u_.local.relobj;
619 }
620
621 // For a relocation against a local symbol, the local symbol index.
622 unsigned int
623 index() const
624 {
625 gold_assert(!this->symbol_is_global_);
626 return this->u_.local.index;
627 }
628
629 private:
630 // GOT offset of the entry to which this relocation is applied.
631 unsigned int got_offset_;
632 // Type of relocation.
633 unsigned int r_type_;
634 // Whether this relocation is against a global symbol.
635 bool symbol_is_global_;
636 // A global or local symbol.
637 union
638 {
83a01957
HS
639 struct
640 {
641 // For a global symbol, the symbol itself.
642 Symbol* symbol;
643 } global;
644 struct
645 {
646 // For a local symbol, the object defining the symbol.
647 Sized_relobj_file<size, big_endian>* relobj;
648 // For a local symbol, the symbol index.
649 unsigned int index;
650 } local;
651 } u_;
652 }; // End of inner class Static_reloc
653
654 std::vector<Static_reloc> static_relocs_;
655}; // End of Output_data_got_aarch64
656
657
658template<int size, bool big_endian>
659class AArch64_input_section;
660
661
662template<int size, bool big_endian>
663class AArch64_output_section;
664
665
83a01957 666template<int size, bool big_endian>
a48d0c12
HS
667class AArch64_relobj;
668
669
670// Stub type enum constants.
671
672enum
83a01957 673{
a48d0c12 674 ST_NONE = 0,
83a01957 675
a48d0c12
HS
676 // Using adrp/add pair, 4 insns (including alignment) without mem access,
677 // the fastest stub. This has a limited jump distance, which is tested by
678 // aarch64_valid_for_adrp_p.
679 ST_ADRP_BRANCH = 1,
83a01957 680
a48d0c12
HS
681 // Using ldr-absolute-address/br-register, 4 insns with 1 mem access,
682 // unlimited in jump distance.
683 ST_LONG_BRANCH_ABS = 2,
83a01957 684
a48d0c12
HS
685 // Using ldr/calculate-pcrel/jump, 8 insns (including alignment) with 1
686 // mem access, slowest one. Only used in position independent executables.
687 ST_LONG_BRANCH_PCREL = 3,
83a01957 688
a48d0c12
HS
689 // Stub for erratum 843419 handling.
690 ST_E_843419 = 4,
83a01957 691
2f0c79aa
HS
692 // Stub for erratum 835769 handling.
693 ST_E_835769 = 5,
694
a48d0c12 695 // Number of total stub types.
2f0c79aa 696 ST_NUMBER = 6
a48d0c12 697};
83a01957 698
83a01957 699
a48d0c12
HS
700// Struct that wraps insns for a particular stub. All stub templates are
701// created/initialized as constants by Stub_template_repertoire.
83a01957 702
a48d0c12
HS
703template<bool big_endian>
704struct Stub_template
705{
706 const typename AArch64_insn_utilities<big_endian>::Insntype* insns;
707 const int insn_num;
708};
83a01957 709
83a01957 710
a48d0c12
HS
711// Simple singleton class that creates/initializes/stores all types of stub
712// templates.
713
714template<bool big_endian>
715class Stub_template_repertoire
716{
717public:
718 typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;
719
720 // Single static method to get stub template for a given stub type.
721 static const Stub_template<big_endian>*
722 get_stub_template(int type)
83a01957 723 {
a48d0c12
HS
724 static Stub_template_repertoire<big_endian> singleton;
725 return singleton.stub_templates_[type];
83a01957
HS
726 }
727
a48d0c12
HS
728private:
729 // Constructor - creates/initializes all stub templates.
730 Stub_template_repertoire();
731 ~Stub_template_repertoire()
83a01957
HS
732 { }
733
a48d0c12
HS
734 // Disallowing copy ctor and copy assignment operator.
735 Stub_template_repertoire(Stub_template_repertoire&);
736 Stub_template_repertoire& operator=(Stub_template_repertoire&);
83a01957 737
a48d0c12
HS
738 // Data that stores all insn templates.
739 const Stub_template<big_endian>* stub_templates_[ST_NUMBER];
740}; // End of "class Stub_template_repertoire".
741
742
743// Constructor - creates/initilizes all stub templates.
744
745template<bool big_endian>
746Stub_template_repertoire<big_endian>::Stub_template_repertoire()
747{
748 // Insn array definitions.
749 const static Insntype ST_NONE_INSNS[] = {};
750
751 const static Insntype ST_ADRP_BRANCH_INSNS[] =
752 {
753 0x90000010, /* adrp ip0, X */
754 /* ADR_PREL_PG_HI21(X) */
755 0x91000210, /* add ip0, ip0, :lo12:X */
756 /* ADD_ABS_LO12_NC(X) */
757 0xd61f0200, /* br ip0 */
758 0x00000000, /* alignment padding */
759 };
760
761 const static Insntype ST_LONG_BRANCH_ABS_INSNS[] =
762 {
763 0x58000050, /* ldr ip0, 0x8 */
764 0xd61f0200, /* br ip0 */
765 0x00000000, /* address field */
766 0x00000000, /* address fields */
767 };
768
769 const static Insntype ST_LONG_BRANCH_PCREL_INSNS[] =
770 {
771 0x58000090, /* ldr ip0, 0x10 */
772 0x10000011, /* adr ip1, #0 */
773 0x8b110210, /* add ip0, ip0, ip1 */
774 0xd61f0200, /* br ip0 */
775 0x00000000, /* address field */
776 0x00000000, /* address field */
777 0x00000000, /* alignment padding */
778 0x00000000, /* alignment padding */
779 };
780
781 const static Insntype ST_E_843419_INSNS[] =
782 {
783 0x00000000, /* Placeholder for erratum insn. */
784 0x14000000, /* b <label> */
785 };
786
a24df305
NC
787 // ST_E_835769 has the same stub template as ST_E_843419
788 // but we reproduce the array here so that the sizeof
789 // expressions in install_insn_template will work.
790 const static Insntype ST_E_835769_INSNS[] =
791 {
792 0x00000000, /* Placeholder for erratum insn. */
793 0x14000000, /* b <label> */
794 };
2f0c79aa 795
a48d0c12
HS
796#define install_insn_template(T) \
797 const static Stub_template<big_endian> template_##T = { \
798 T##_INSNS, sizeof(T##_INSNS) / sizeof(T##_INSNS[0]) }; \
799 this->stub_templates_[T] = &template_##T
800
801 install_insn_template(ST_NONE);
802 install_insn_template(ST_ADRP_BRANCH);
803 install_insn_template(ST_LONG_BRANCH_ABS);
804 install_insn_template(ST_LONG_BRANCH_PCREL);
805 install_insn_template(ST_E_843419);
2f0c79aa 806 install_insn_template(ST_E_835769);
a48d0c12
HS
807
808#undef install_insn_template
809}
810
811
812// Base class for stubs.
813
814template<int size, bool big_endian>
815class Stub_base
816{
817public:
818 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
819 typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;
820
821 static const AArch64_address invalid_address =
822 static_cast<AArch64_address>(-1);
823
824 static const section_offset_type invalid_offset =
825 static_cast<section_offset_type>(-1);
826
827 Stub_base(int type)
828 : destination_address_(invalid_address),
829 offset_(invalid_offset),
830 type_(type)
831 {}
832
833 ~Stub_base()
834 {}
835
836 // Get stub type.
837 int
838 type() const
839 { return this->type_; }
840
841 // Get stub template that provides stub insn information.
842 const Stub_template<big_endian>*
843 stub_template() const
83a01957 844 {
a48d0c12
HS
845 return Stub_template_repertoire<big_endian>::
846 get_stub_template(this->type());
83a01957
HS
847 }
848
a48d0c12 849 // Get destination address.
83a01957
HS
850 AArch64_address
851 destination_address() const
852 {
853 gold_assert(this->destination_address_ != this->invalid_address);
854 return this->destination_address_;
855 }
856
857 // Set destination address.
858 void
859 set_destination_address(AArch64_address address)
860 {
861 gold_assert(address != this->invalid_address);
862 this->destination_address_ = address;
863 }
864
865 // Reset the destination address.
866 void
867 reset_destination_address()
868 { this->destination_address_ = this->invalid_address; }
869
a48d0c12
HS
870 // Get offset of code stub. For Reloc_stub, it is the offset from the
871 // beginning of its containing stub table; for Erratum_stub, it is the offset
872 // from the end of reloc_stubs.
873 section_offset_type
874 offset() const
875 {
876 gold_assert(this->offset_ != this->invalid_offset);
877 return this->offset_;
878 }
83a01957 879
a48d0c12
HS
880 // Set stub offset.
881 void
882 set_offset(section_offset_type offset)
883 { this->offset_ = offset; }
83a01957 884
a48d0c12
HS
885 // Return the stub insn.
886 const Insntype*
887 insns() const
888 { return this->stub_template()->insns; }
83a01957 889
a48d0c12
HS
890 // Return num of stub insns.
891 unsigned int
892 insn_num() const
893 { return this->stub_template()->insn_num; }
894
895 // Get size of the stub.
896 int
897 stub_size() const
898 {
899 return this->insn_num() *
900 AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
901 }
83a01957
HS
902
903 // Write stub to output file.
904 void
905 write(unsigned char* view, section_size_type view_size)
906 { this->do_write(view, view_size); }
907
a48d0c12
HS
908protected:
909 // Abstract method to be implemented by sub-classes.
910 virtual void
911 do_write(unsigned char*, section_size_type) = 0;
912
913private:
914 // The last insn of a stub is a jump to destination insn. This field records
915 // the destination address.
916 AArch64_address destination_address_;
917 // The stub offset. Note this has difference interpretations between an
918 // Reloc_stub and an Erratum_stub. For Reloc_stub this is the offset from the
919 // beginning of the containing stub_table, whereas for Erratum_stub, this is
920 // the offset from the end of reloc_stubs.
921 section_offset_type offset_;
922 // Stub type.
923 const int type_;
924}; // End of "Stub_base".
925
926
927// Erratum stub class. An erratum stub differs from a reloc stub in that for
928// each erratum occurrence, we generate an erratum stub. We never share erratum
929// stubs, whereas for reloc stubs, different branches insns share a single reloc
930// stub as long as the branch targets are the same. (More to the point, reloc
931// stubs can be shared because they're used to reach a specific target, whereas
932// erratum stubs branch back to the original control flow.)
933
934template<int size, bool big_endian>
935class Erratum_stub : public Stub_base<size, big_endian>
936{
937public:
938 typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
939 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
56b06706 940 typedef AArch64_insn_utilities<big_endian> Insn_utilities;
a48d0c12
HS
941 typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;
942
5d7908e0 943 static const int STUB_ADDR_ALIGN;
a48d0c12
HS
944
945 static const Insntype invalid_insn = static_cast<Insntype>(-1);
946
947 Erratum_stub(The_aarch64_relobj* relobj, int type,
948 unsigned shndx, unsigned int sh_offset)
949 : Stub_base<size, big_endian>(type), relobj_(relobj),
950 shndx_(shndx), sh_offset_(sh_offset),
951 erratum_insn_(invalid_insn),
952 erratum_address_(this->invalid_address)
953 {}
954
955 ~Erratum_stub() {}
956
957 // Return the object that contains the erratum.
958 The_aarch64_relobj*
959 relobj()
960 { return this->relobj_; }
961
962 // Get section index of the erratum.
963 unsigned int
964 shndx() const
965 { return this->shndx_; }
966
967 // Get section offset of the erratum.
968 unsigned int
969 sh_offset() const
970 { return this->sh_offset_; }
971
972 // Get the erratum insn. This is the insn located at erratum_insn_address.
973 Insntype
974 erratum_insn() const
975 {
976 gold_assert(this->erratum_insn_ != this->invalid_insn);
977 return this->erratum_insn_;
978 }
979
980 // Set the insn that the erratum happens to.
981 void
982 set_erratum_insn(Insntype insn)
983 { this->erratum_insn_ = insn; }
984
56b06706
HS
985 // For 843419, the erratum insn is ld/st xt, [xn, #uimm], which may be a
986 // relocation spot, in this case, the erratum_insn_ recorded at scanning phase
987 // is no longer the one we want to write out to the stub, update erratum_insn_
988 // with relocated version. Also note that in this case xn must not be "PC", so
989 // it is safe to move the erratum insn from the origin place to the stub. For
990 // 835769, the erratum insn is multiply-accumulate insn, which could not be a
991 // relocation spot (assertion added though).
992 void
993 update_erratum_insn(Insntype insn)
994 {
995 gold_assert(this->erratum_insn_ != this->invalid_insn);
996 switch (this->type())
997 {
998 case ST_E_843419:
999 gold_assert(Insn_utilities::aarch64_ldst_uimm(insn));
1000 gold_assert(Insn_utilities::aarch64_ldst_uimm(this->erratum_insn()));
1001 gold_assert(Insn_utilities::aarch64_rd(insn) ==
1002 Insn_utilities::aarch64_rd(this->erratum_insn()));
1003 gold_assert(Insn_utilities::aarch64_rn(insn) ==
1004 Insn_utilities::aarch64_rn(this->erratum_insn()));
1005 // Update plain ld/st insn with relocated insn.
1006 this->erratum_insn_ = insn;
1007 break;
1008 case ST_E_835769:
1009 gold_assert(insn == this->erratum_insn());
1010 break;
1011 default:
1012 gold_unreachable();
1013 }
1014 }
1015
1016
a48d0c12
HS
1017 // Return the address where an erratum must be done.
1018 AArch64_address
1019 erratum_address() const
1020 {
1021 gold_assert(this->erratum_address_ != this->invalid_address);
1022 return this->erratum_address_;
1023 }
1024
1025 // Set the address where an erratum must be done.
1026 void
1027 set_erratum_address(AArch64_address addr)
1028 { this->erratum_address_ = addr; }
1029
1030 // Comparator used to group Erratum_stubs in a set by (obj, shndx,
5c3024d2 1031 // sh_offset). We do not include 'type' in the calculation, because there is
a48d0c12
HS
1032 // at most one stub type at (obj, shndx, sh_offset).
1033 bool
1034 operator<(const Erratum_stub<size, big_endian>& k) const
1035 {
1036 if (this == &k)
1037 return false;
1038 // We group stubs by relobj.
1039 if (this->relobj_ != k.relobj_)
1040 return this->relobj_ < k.relobj_;
1041 // Then by section index.
1042 if (this->shndx_ != k.shndx_)
1043 return this->shndx_ < k.shndx_;
1044 // Lastly by section offset.
1045 return this->sh_offset_ < k.sh_offset_;
1046 }
1047
1048protected:
1049 virtual void
1050 do_write(unsigned char*, section_size_type);
1051
1052private:
1053 // The object that needs to be fixed.
1054 The_aarch64_relobj* relobj_;
1055 // The shndx in the object that needs to be fixed.
1056 const unsigned int shndx_;
1057 // The section offset in the obejct that needs to be fixed.
1058 const unsigned int sh_offset_;
1059 // The insn to be fixed.
1060 Insntype erratum_insn_;
1061 // The address of the above insn.
1062 AArch64_address erratum_address_;
1063}; // End of "Erratum_stub".
1064
0ef3814f
HS
1065
1066// Erratum sub class to wrap additional info needed by 843419. In fixing this
1067// erratum, we may choose to replace 'adrp' with 'adr', in this case, we need
1068// adrp's code position (two or three insns before erratum insn itself).
1069
1070template<int size, bool big_endian>
1071class E843419_stub : public Erratum_stub<size, big_endian>
1072{
1073public:
1074 typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;
1075
1076 E843419_stub(AArch64_relobj<size, big_endian>* relobj,
1077 unsigned int shndx, unsigned int sh_offset,
1078 unsigned int adrp_sh_offset)
1079 : Erratum_stub<size, big_endian>(relobj, ST_E_843419, shndx, sh_offset),
1080 adrp_sh_offset_(adrp_sh_offset)
1081 {}
1082
1083 unsigned int
1084 adrp_sh_offset() const
1085 { return this->adrp_sh_offset_; }
1086
1087private:
1088 // Section offset of "adrp". (We do not need a "adrp_shndx_" field, because we
1089 // can can obtain it from its parent.)
1090 const unsigned int adrp_sh_offset_;
1091};
1092
1093
5d7908e0
CC
1094template<int size, bool big_endian>
1095const int Erratum_stub<size, big_endian>::STUB_ADDR_ALIGN = 4;
a48d0c12
HS
1096
1097// Comparator used in set definition.
1098template<int size, bool big_endian>
1099struct Erratum_stub_less
1100{
1101 bool
1102 operator()(const Erratum_stub<size, big_endian>* s1,
1103 const Erratum_stub<size, big_endian>* s2) const
1104 { return *s1 < *s2; }
1105};
1106
1107// Erratum_stub implementation for writing stub to output file.
1108
1109template<int size, bool big_endian>
1110void
1111Erratum_stub<size, big_endian>::do_write(unsigned char* view, section_size_type)
1112{
1113 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
1114 const Insntype* insns = this->insns();
1115 uint32_t num_insns = this->insn_num();
1116 Insntype* ip = reinterpret_cast<Insntype*>(view);
2f0c79aa
HS
1117 // For current implemented erratum 843419 and 835769, the first insn in the
1118 // stub is always a copy of the problematic insn (in 843419, the mem access
1119 // insn, in 835769, the mac insn), followed by a jump-back.
a48d0c12
HS
1120 elfcpp::Swap<32, big_endian>::writeval(ip, this->erratum_insn());
1121 for (uint32_t i = 1; i < num_insns; ++i)
1122 elfcpp::Swap<32, big_endian>::writeval(ip + i, insns[i]);
1123}
1124
1125
1126// Reloc stub class.
1127
1128template<int size, bool big_endian>
1129class Reloc_stub : public Stub_base<size, big_endian>
1130{
1131 public:
1132 typedef Reloc_stub<size, big_endian> This;
1133 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
1134
1135 // Branch range. This is used to calculate the section group size, as well as
1136 // determine whether a stub is needed.
1137 static const int MAX_BRANCH_OFFSET = ((1 << 25) - 1) << 2;
1138 static const int MIN_BRANCH_OFFSET = -((1 << 25) << 2);
1139
1140 // Constant used to determine if an offset fits in the adrp instruction
1141 // encoding.
1142 static const int MAX_ADRP_IMM = (1 << 20) - 1;
1143 static const int MIN_ADRP_IMM = -(1 << 20);
1144
1145 static const int BYTES_PER_INSN = 4;
5d7908e0 1146 static const int STUB_ADDR_ALIGN;
a48d0c12
HS
1147
1148 // Determine whether the offset fits in the jump/branch instruction.
1149 static bool
1150 aarch64_valid_branch_offset_p(int64_t offset)
1151 { return offset >= MIN_BRANCH_OFFSET && offset <= MAX_BRANCH_OFFSET; }
1152
1153 // Determine whether the offset fits in the adrp immediate field.
1154 static bool
1155 aarch64_valid_for_adrp_p(AArch64_address location, AArch64_address dest)
1156 {
1157 typedef AArch64_relocate_functions<size, big_endian> Reloc;
1158 int64_t adrp_imm = (Reloc::Page(dest) - Reloc::Page(location)) >> 12;
1159 return adrp_imm >= MIN_ADRP_IMM && adrp_imm <= MAX_ADRP_IMM;
1160 }
1161
1162 // Determine the stub type for a certain relocation or ST_NONE, if no stub is
1163 // needed.
1164 static int
1165 stub_type_for_reloc(unsigned int r_type, AArch64_address address,
1166 AArch64_address target);
1167
1168 Reloc_stub(int type)
1169 : Stub_base<size, big_endian>(type)
1170 { }
1171
1172 ~Reloc_stub()
1173 { }
1174
83a01957
HS
1175 // The key class used to index the stub instance in the stub table's stub map.
1176 class Key
1177 {
1178 public:
a48d0c12 1179 Key(int type, const Symbol* symbol, const Relobj* relobj,
83a01957 1180 unsigned int r_sym, int32_t addend)
a48d0c12 1181 : type_(type), addend_(addend)
83a01957
HS
1182 {
1183 if (symbol != NULL)
1184 {
1185 this->r_sym_ = Reloc_stub::invalid_index;
1186 this->u_.symbol = symbol;
1187 }
1188 else
1189 {
1190 gold_assert(relobj != NULL && r_sym != invalid_index);
1191 this->r_sym_ = r_sym;
1192 this->u_.relobj = relobj;
1193 }
1194 }
1195
1196 ~Key()
1197 { }
1198
1199 // Return stub type.
a48d0c12
HS
1200 int
1201 type() const
1202 { return this->type_; }
83a01957
HS
1203
1204 // Return the local symbol index or invalid_index.
1205 unsigned int
1206 r_sym() const
1207 { return this->r_sym_; }
1208
1209 // Return the symbol if there is one.
1210 const Symbol*
1211 symbol() const
1212 { return this->r_sym_ == invalid_index ? this->u_.symbol : NULL; }
1213
1214 // Return the relobj if there is one.
1215 const Relobj*
1216 relobj() const
1217 { return this->r_sym_ != invalid_index ? this->u_.relobj : NULL; }
1218
1219 // Whether this equals to another key k.
1220 bool
1221 eq(const Key& k) const
1222 {
a48d0c12 1223 return ((this->type_ == k.type_)
83a01957
HS
1224 && (this->r_sym_ == k.r_sym_)
1225 && ((this->r_sym_ != Reloc_stub::invalid_index)
1226 ? (this->u_.relobj == k.u_.relobj)
1227 : (this->u_.symbol == k.u_.symbol))
1228 && (this->addend_ == k.addend_));
1229 }
1230
1231 // Return a hash value.
1232 size_t
1233 hash_value() const
1234 {
1235 size_t name_hash_value = gold::string_hash<char>(
1236 (this->r_sym_ != Reloc_stub::invalid_index)
1237 ? this->u_.relobj->name().c_str()
1238 : this->u_.symbol->name());
1239 // We only have 4 stub types.
a48d0c12 1240 size_t stub_type_hash_value = 0x03 & this->type_;
83a01957
HS
1241 return (name_hash_value
1242 ^ stub_type_hash_value
1243 ^ ((this->r_sym_ & 0x3fff) << 2)
1244 ^ ((this->addend_ & 0xffff) << 16));
1245 }
1246
1247 // Functors for STL associative containers.
1248 struct hash
1249 {
1250 size_t
1251 operator()(const Key& k) const
1252 { return k.hash_value(); }
1253 };
1254
1255 struct equal_to
1256 {
1257 bool
1258 operator()(const Key& k1, const Key& k2) const
1259 { return k1.eq(k2); }
1260 };
1261
9726c3c1 1262 private:
83a01957 1263 // Stub type.
a48d0c12 1264 const int type_;
83a01957
HS
1265 // If this is a local symbol, this is the index in the defining object.
1266 // Otherwise, it is invalid_index for a global symbol.
1267 unsigned int r_sym_;
1268 // If r_sym_ is an invalid index, this points to a global symbol.
1269 // Otherwise, it points to a relobj. We used the unsized and target
1270 // independent Symbol and Relobj classes instead of Sized_symbol<32> and
1271 // Arm_relobj, in order to avoid making the stub class a template
1272 // as most of the stub machinery is endianness-neutral. However, it
1273 // may require a bit of casting done by users of this class.
1274 union
1275 {
1276 const Symbol* symbol;
1277 const Relobj* relobj;
1278 } u_;
1279 // Addend associated with a reloc.
1280 int32_t addend_;
1281 }; // End of inner class Reloc_stub::Key
1282
1283 protected:
1284 // This may be overridden in the child class.
1285 virtual void
1286 do_write(unsigned char*, section_size_type);
1287
1288 private:
83a01957 1289 static const unsigned int invalid_index = static_cast<unsigned int>(-1);
83a01957
HS
1290}; // End of Reloc_stub
1291
5d7908e0
CC
1292template<int size, bool big_endian>
1293const int Reloc_stub<size, big_endian>::STUB_ADDR_ALIGN = 4;
83a01957
HS
1294
1295// Write data to output file.
1296
1297template<int size, bool big_endian>
1298void
1299Reloc_stub<size, big_endian>::
1300do_write(unsigned char* view, section_size_type)
1301{
1302 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
a48d0c12
HS
1303 const uint32_t* insns = this->insns();
1304 uint32_t num_insns = this->insn_num();
83a01957 1305 Insntype* ip = reinterpret_cast<Insntype*>(view);
a48d0c12
HS
1306 for (uint32_t i = 0; i < num_insns; ++i)
1307 elfcpp::Swap<32, big_endian>::writeval(ip + i, insns[i]);
83a01957
HS
1308}
1309
1310
83a01957
HS
1311// Determine the stub type for a certain relocation or ST_NONE, if no stub is
1312// needed.
1313
1314template<int size, bool big_endian>
a48d0c12 1315inline int
83a01957
HS
1316Reloc_stub<size, big_endian>::stub_type_for_reloc(
1317 unsigned int r_type, AArch64_address location, AArch64_address dest)
1318{
1319 int64_t branch_offset = 0;
1320 switch(r_type)
1321 {
1322 case elfcpp::R_AARCH64_CALL26:
1323 case elfcpp::R_AARCH64_JUMP26:
1324 branch_offset = dest - location;
1325 break;
1326 default:
9726c3c1 1327 gold_unreachable();
83a01957
HS
1328 }
1329
1330 if (aarch64_valid_branch_offset_p(branch_offset))
1331 return ST_NONE;
1332
1333 if (aarch64_valid_for_adrp_p(location, dest))
1334 return ST_ADRP_BRANCH;
1335
9a472eda
HS
1336 // Always use PC-relative addressing in case of -shared or -pie.
1337 if (parameters->options().output_is_position_independent())
83a01957
HS
1338 return ST_LONG_BRANCH_PCREL;
1339
9a472eda
HS
1340 // This saves 2 insns per stub, compared to ST_LONG_BRANCH_PCREL.
1341 // But is only applicable to non-shared or non-pie.
83a01957
HS
1342 return ST_LONG_BRANCH_ABS;
1343}
1344
1345// A class to hold stubs for the ARM target.
1346
1347template<int size, bool big_endian>
1348class Stub_table : public Output_data
1349{
1350 public:
1351 typedef Target_aarch64<size, big_endian> The_target_aarch64;
1352 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
a48d0c12 1353 typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
83a01957
HS
1354 typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
1355 typedef Reloc_stub<size, big_endian> The_reloc_stub;
1356 typedef typename The_reloc_stub::Key The_reloc_stub_key;
a48d0c12
HS
1357 typedef Erratum_stub<size, big_endian> The_erratum_stub;
1358 typedef Erratum_stub_less<size, big_endian> The_erratum_stub_less;
83a01957
HS
1359 typedef typename The_reloc_stub_key::hash The_reloc_stub_key_hash;
1360 typedef typename The_reloc_stub_key::equal_to The_reloc_stub_key_equal_to;
1361 typedef Stub_table<size, big_endian> The_stub_table;
1362 typedef Unordered_map<The_reloc_stub_key, The_reloc_stub*,
1363 The_reloc_stub_key_hash, The_reloc_stub_key_equal_to>
1364 Reloc_stub_map;
1365 typedef typename Reloc_stub_map::const_iterator Reloc_stub_map_const_iter;
1366 typedef Relocate_info<size, big_endian> The_relocate_info;
1367
a48d0c12
HS
1368 typedef std::set<The_erratum_stub*, The_erratum_stub_less> Erratum_stub_set;
1369 typedef typename Erratum_stub_set::iterator Erratum_stub_set_iter;
1370
83a01957 1371 Stub_table(The_aarch64_input_section* owner)
a48d0c12
HS
1372 : Output_data(), owner_(owner), reloc_stubs_size_(0),
1373 erratum_stubs_size_(0), prev_data_size_(0)
83a01957
HS
1374 { }
1375
1376 ~Stub_table()
1377 { }
1378
1379 The_aarch64_input_section*
1380 owner() const
1381 { return owner_; }
1382
1383 // Whether this stub table is empty.
1384 bool
1385 empty() const
a48d0c12 1386 { return reloc_stubs_.empty() && erratum_stubs_.empty(); }
83a01957
HS
1387
1388 // Return the current data size.
1389 off_t
1390 current_data_size() const
1391 { return this->current_data_size_for_child(); }
1392
1393 // Add a STUB using KEY. The caller is responsible for avoiding addition
1394 // if a STUB with the same key has already been added.
1395 void
1396 add_reloc_stub(The_reloc_stub* stub, const The_reloc_stub_key& key);
1397
a48d0c12
HS
1398 // Add an erratum stub into the erratum stub set. The set is ordered by
1399 // (relobj, shndx, sh_offset).
1400 void
1401 add_erratum_stub(The_erratum_stub* stub);
1402
1403 // Find if such erratum exists for any given (obj, shndx, sh_offset).
1404 The_erratum_stub*
1405 find_erratum_stub(The_aarch64_relobj* a64relobj,
1406 unsigned int shndx, unsigned int sh_offset);
1407
1408 // Find all the erratums for a given input section. The return value is a pair
1409 // of iterators [begin, end).
1410 std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
1411 find_erratum_stubs_for_input_section(The_aarch64_relobj* a64relobj,
1412 unsigned int shndx);
1413
1414 // Compute the erratum stub address.
1415 AArch64_address
1416 erratum_stub_address(The_erratum_stub* stub) const
1417 {
1418 AArch64_address r = align_address(this->address() + this->reloc_stubs_size_,
1419 The_erratum_stub::STUB_ADDR_ALIGN);
1420 r += stub->offset();
1421 return r;
1422 }
1423
83a01957
HS
1424 // Finalize stubs. No-op here, just for completeness.
1425 void
1426 finalize_stubs()
1427 { }
1428
1429 // Look up a relocation stub using KEY. Return NULL if there is none.
1430 The_reloc_stub*
1431 find_reloc_stub(The_reloc_stub_key& key)
1432 {
1433 Reloc_stub_map_const_iter p = this->reloc_stubs_.find(key);
1434 return (p != this->reloc_stubs_.end()) ? p->second : NULL;
1435 }
1436
1437 // Relocate stubs in this stub table.
1438 void
1439 relocate_stubs(const The_relocate_info*,
1440 The_target_aarch64*,
1441 Output_section*,
1442 unsigned char*,
1443 AArch64_address,
1444 section_size_type);
1445
1446 // Update data size at the end of a relaxation pass. Return true if data size
1447 // is different from that of the previous relaxation pass.
1448 bool
1449 update_data_size_changed_p()
1450 {
1451 // No addralign changed here.
a48d0c12
HS
1452 off_t s = align_address(this->reloc_stubs_size_,
1453 The_erratum_stub::STUB_ADDR_ALIGN)
1454 + this->erratum_stubs_size_;
83a01957
HS
1455 bool changed = (s != this->prev_data_size_);
1456 this->prev_data_size_ = s;
1457 return changed;
1458 }
1459
1460 protected:
1461 // Write out section contents.
1462 void
1463 do_write(Output_file*);
1464
1465 // Return the required alignment.
1466 uint64_t
1467 do_addralign() const
a48d0c12
HS
1468 {
1469 return std::max(The_reloc_stub::STUB_ADDR_ALIGN,
1470 The_erratum_stub::STUB_ADDR_ALIGN);
1471 }
83a01957
HS
1472
1473 // Reset address and file offset.
1474 void
1475 do_reset_address_and_file_offset()
1476 { this->set_current_data_size_for_child(this->prev_data_size_); }
1477
1478 // Set final data size.
1479 void
1480 set_final_data_size()
1481 { this->set_data_size(this->current_data_size()); }
1482
1483 private:
1484 // Relocate one stub.
1485 void
1486 relocate_stub(The_reloc_stub*,
1487 const The_relocate_info*,
1488 The_target_aarch64*,
1489 Output_section*,
1490 unsigned char*,
1491 AArch64_address,
1492 section_size_type);
1493
1494 private:
1495 // Owner of this stub table.
1496 The_aarch64_input_section* owner_;
1497 // The relocation stubs.
1498 Reloc_stub_map reloc_stubs_;
a48d0c12
HS
1499 // The erratum stubs.
1500 Erratum_stub_set erratum_stubs_;
83a01957
HS
1501 // Size of reloc stubs.
1502 off_t reloc_stubs_size_;
a48d0c12
HS
1503 // Size of erratum stubs.
1504 off_t erratum_stubs_size_;
83a01957
HS
1505 // data size of this in the previous pass.
1506 off_t prev_data_size_;
1507}; // End of Stub_table
1508
1509
a48d0c12
HS
1510// Add an erratum stub into the erratum stub set. The set is ordered by
1511// (relobj, shndx, sh_offset).
1512
1513template<int size, bool big_endian>
1514void
1515Stub_table<size, big_endian>::add_erratum_stub(The_erratum_stub* stub)
1516{
1517 std::pair<Erratum_stub_set_iter, bool> ret =
1518 this->erratum_stubs_.insert(stub);
1519 gold_assert(ret.second);
1520 this->erratum_stubs_size_ = align_address(
1521 this->erratum_stubs_size_, The_erratum_stub::STUB_ADDR_ALIGN);
1522 stub->set_offset(this->erratum_stubs_size_);
1523 this->erratum_stubs_size_ += stub->stub_size();
1524}
1525
1526
56b06706 1527// Find if such erratum exists for given (obj, shndx, sh_offset).
a48d0c12
HS
1528
1529template<int size, bool big_endian>
1530Erratum_stub<size, big_endian>*
1531Stub_table<size, big_endian>::find_erratum_stub(
1532 The_aarch64_relobj* a64relobj, unsigned int shndx, unsigned int sh_offset)
1533{
1534 // A dummy object used as key to search in the set.
1535 The_erratum_stub key(a64relobj, ST_NONE,
1536 shndx, sh_offset);
1537 Erratum_stub_set_iter i = this->erratum_stubs_.find(&key);
1538 if (i != this->erratum_stubs_.end())
1539 {
1540 The_erratum_stub* stub(*i);
1541 gold_assert(stub->erratum_insn() != 0);
1542 return stub;
1543 }
1544 return NULL;
1545}
1546
1547
1548// Find all the errata for a given input section. The return value is a pair of
1549// iterators [begin, end).
1550
1551template<int size, bool big_endian>
1552std::pair<typename Stub_table<size, big_endian>::Erratum_stub_set_iter,
1553 typename Stub_table<size, big_endian>::Erratum_stub_set_iter>
1554Stub_table<size, big_endian>::find_erratum_stubs_for_input_section(
1555 The_aarch64_relobj* a64relobj, unsigned int shndx)
1556{
1557 typedef std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter> Result_pair;
1558 Erratum_stub_set_iter start, end;
1559 The_erratum_stub low_key(a64relobj, ST_NONE, shndx, 0);
1560 start = this->erratum_stubs_.lower_bound(&low_key);
1561 if (start == this->erratum_stubs_.end())
1562 return Result_pair(this->erratum_stubs_.end(),
1563 this->erratum_stubs_.end());
1564 end = start;
1565 while (end != this->erratum_stubs_.end() &&
1566 (*end)->relobj() == a64relobj && (*end)->shndx() == shndx)
1567 ++end;
1568 return Result_pair(start, end);
1569}
1570
1571
83a01957
HS
1572// Add a STUB using KEY. The caller is responsible for avoiding addition
1573// if a STUB with the same key has already been added.
1574
1575template<int size, bool big_endian>
1576void
1577Stub_table<size, big_endian>::add_reloc_stub(
1578 The_reloc_stub* stub, const The_reloc_stub_key& key)
1579{
a48d0c12 1580 gold_assert(stub->type() == key.type());
83a01957
HS
1581 this->reloc_stubs_[key] = stub;
1582
1583 // Assign stub offset early. We can do this because we never remove
1584 // reloc stubs and they are in the beginning of the stub table.
1585 this->reloc_stubs_size_ = align_address(this->reloc_stubs_size_,
1586 The_reloc_stub::STUB_ADDR_ALIGN);
1587 stub->set_offset(this->reloc_stubs_size_);
1588 this->reloc_stubs_size_ += stub->stub_size();
1589}
1590
1591
1592// Relocate all stubs in this stub table.
1593
1594template<int size, bool big_endian>
1595void
1596Stub_table<size, big_endian>::
1597relocate_stubs(const The_relocate_info* relinfo,
1598 The_target_aarch64* target_aarch64,
1599 Output_section* output_section,
1600 unsigned char* view,
1601 AArch64_address address,
1602 section_size_type view_size)
1603{
1604 // "view_size" is the total size of the stub_table.
1605 gold_assert(address == this->address() &&
1606 view_size == static_cast<section_size_type>(this->data_size()));
1607 for(Reloc_stub_map_const_iter p = this->reloc_stubs_.begin();
1608 p != this->reloc_stubs_.end(); ++p)
1609 relocate_stub(p->second, relinfo, target_aarch64, output_section,
1610 view, address, view_size);
a48d0c12
HS
1611
1612 // Just for convenience.
1613 const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
1614
1615 // Now 'relocate' erratum stubs.
1616 for(Erratum_stub_set_iter i = this->erratum_stubs_.begin();
1617 i != this->erratum_stubs_.end(); ++i)
1618 {
1619 AArch64_address stub_address = this->erratum_stub_address(*i);
1620 // The address of "b" in the stub that is to be "relocated".
1621 AArch64_address stub_b_insn_address;
1622 // Branch offset that is to be filled in "b" insn.
1623 int b_offset = 0;
1624 switch ((*i)->type())
1625 {
1626 case ST_E_843419:
2f0c79aa 1627 case ST_E_835769:
56b06706
HS
1628 // The 1st insn of the erratum could be a relocation spot,
1629 // in this case we need to fix it with
1630 // "(*i)->erratum_insn()".
1631 elfcpp::Swap<32, big_endian>::writeval(
1632 view + (stub_address - this->address()),
1633 (*i)->erratum_insn());
a48d0c12
HS
1634 // For the erratum, the 2nd insn is a b-insn to be patched
1635 // (relocated).
1636 stub_b_insn_address = stub_address + 1 * BPI;
1637 b_offset = (*i)->destination_address() - stub_b_insn_address;
1638 AArch64_relocate_functions<size, big_endian>::construct_b(
1639 view + (stub_b_insn_address - this->address()),
1640 ((unsigned int)(b_offset)) & 0xfffffff);
1641 break;
1642 default:
1643 gold_unreachable();
1644 break;
1645 }
1646 }
83a01957
HS
1647}
1648
1649
1650// Relocate one stub. This is a helper for Stub_table::relocate_stubs().
1651
1652template<int size, bool big_endian>
1653void
1654Stub_table<size, big_endian>::
1655relocate_stub(The_reloc_stub* stub,
1656 const The_relocate_info* relinfo,
1657 The_target_aarch64* target_aarch64,
1658 Output_section* output_section,
1659 unsigned char* view,
1660 AArch64_address address,
1661 section_size_type view_size)
1662{
1663 // "offset" is the offset from the beginning of the stub_table.
1664 section_size_type offset = stub->offset();
1665 section_size_type stub_size = stub->stub_size();
1666 // "view_size" is the total size of the stub_table.
1667 gold_assert(offset + stub_size <= view_size);
1668
1669 target_aarch64->relocate_stub(stub, relinfo, output_section,
1670 view + offset, address + offset, view_size);
1671}
1672
1673
1674// Write out the stubs to file.
1675
1676template<int size, bool big_endian>
1677void
1678Stub_table<size, big_endian>::do_write(Output_file* of)
1679{
1680 off_t offset = this->offset();
1681 const section_size_type oview_size =
1682 convert_to_section_size_type(this->data_size());
1683 unsigned char* const oview = of->get_output_view(offset, oview_size);
1684
1685 // Write relocation stubs.
1686 for (typename Reloc_stub_map::const_iterator p = this->reloc_stubs_.begin();
1687 p != this->reloc_stubs_.end(); ++p)
1688 {
1689 The_reloc_stub* stub = p->second;
1690 AArch64_address address = this->address() + stub->offset();
1691 gold_assert(address ==
1692 align_address(address, The_reloc_stub::STUB_ADDR_ALIGN));
1693 stub->write(oview + stub->offset(), stub->stub_size());
1694 }
1695
a48d0c12
HS
1696 // Write erratum stubs.
1697 unsigned int erratum_stub_start_offset =
1698 align_address(this->reloc_stubs_size_, The_erratum_stub::STUB_ADDR_ALIGN);
1699 for (typename Erratum_stub_set::iterator p = this->erratum_stubs_.begin();
1700 p != this->erratum_stubs_.end(); ++p)
1701 {
1702 The_erratum_stub* stub(*p);
1703 stub->write(oview + erratum_stub_start_offset + stub->offset(),
1704 stub->stub_size());
1705 }
1706
83a01957
HS
1707 of->write_output_view(this->offset(), oview_size, oview);
1708}
1709
1710
1711// AArch64_relobj class.
1712
1713template<int size, bool big_endian>
1714class AArch64_relobj : public Sized_relobj_file<size, big_endian>
1715{
1716 public:
1717 typedef AArch64_relobj<size, big_endian> This;
1718 typedef Target_aarch64<size, big_endian> The_target_aarch64;
1719 typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
1720 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
1721 typedef Stub_table<size, big_endian> The_stub_table;
a48d0c12
HS
1722 typedef Erratum_stub<size, big_endian> The_erratum_stub;
1723 typedef typename The_stub_table::Erratum_stub_set_iter Erratum_stub_set_iter;
83a01957
HS
1724 typedef std::vector<The_stub_table*> Stub_table_list;
1725 static const AArch64_address invalid_address =
1726 static_cast<AArch64_address>(-1);
1727
1728 AArch64_relobj(const std::string& name, Input_file* input_file, off_t offset,
1729 const typename elfcpp::Ehdr<size, big_endian>& ehdr)
1730 : Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
1731 stub_tables_()
1732 { }
1733
1734 ~AArch64_relobj()
1735 { }
1736
1737 // Return the stub table of the SHNDX-th section if there is one.
1738 The_stub_table*
1739 stub_table(unsigned int shndx) const
1740 {
1741 gold_assert(shndx < this->stub_tables_.size());
1742 return this->stub_tables_[shndx];
1743 }
1744
1745 // Set STUB_TABLE to be the stub_table of the SHNDX-th section.
1746 void
1747 set_stub_table(unsigned int shndx, The_stub_table* stub_table)
1748 {
1749 gold_assert(shndx < this->stub_tables_.size());
1750 this->stub_tables_[shndx] = stub_table;
1751 }
1752
2f0c79aa 1753 // Entrance to errata scanning.
5019d64a 1754 void
2f0c79aa
HS
1755 scan_errata(unsigned int shndx,
1756 const elfcpp::Shdr<size, big_endian>&,
1757 Output_section*, const Symbol_table*,
1758 The_target_aarch64*);
5019d64a
HS
1759
1760 // Scan all relocation sections for stub generation.
83a01957
HS
1761 void
1762 scan_sections_for_stubs(The_target_aarch64*, const Symbol_table*,
1763 const Layout*);
1764
1765 // Whether a section is a scannable text section.
1766 bool
1767 text_section_is_scannable(const elfcpp::Shdr<size, big_endian>&, unsigned int,
1768 const Output_section*, const Symbol_table*);
1769
1770 // Convert regular input section with index SHNDX to a relaxed section.
1771 void
6bf56e74 1772 convert_input_section_to_relaxed_section(unsigned shndx)
83a01957
HS
1773 {
1774 // The stubs have relocations and we need to process them after writing
1775 // out the stubs. So relocation now must follow section write.
6bf56e74 1776 this->set_section_offset(shndx, -1ULL);
83a01957
HS
1777 this->set_relocs_must_follow_section_writes();
1778 }
1779
5019d64a
HS
1780 // Structure for mapping symbol position.
1781 struct Mapping_symbol_position
1782 {
1783 Mapping_symbol_position(unsigned int shndx, AArch64_address offset):
1784 shndx_(shndx), offset_(offset)
1785 {}
1786
1787 // "<" comparator used in ordered_map container.
1788 bool
1789 operator<(const Mapping_symbol_position& p) const
1790 {
1791 return (this->shndx_ < p.shndx_
1792 || (this->shndx_ == p.shndx_ && this->offset_ < p.offset_));
1793 }
1794
1795 // Section index.
1796 unsigned int shndx_;
1797
1798 // Section offset.
1799 AArch64_address offset_;
1800 };
1801
1802 typedef std::map<Mapping_symbol_position, char> Mapping_symbol_info;
1803
83a01957
HS
1804 protected:
1805 // Post constructor setup.
1806 void
1807 do_setup()
1808 {
1809 // Call parent's setup method.
1810 Sized_relobj_file<size, big_endian>::do_setup();
1811
1812 // Initialize look-up tables.
1813 this->stub_tables_.resize(this->shnum());
1814 }
1815
1816 virtual void
1817 do_relocate_sections(
1818 const Symbol_table* symtab, const Layout* layout,
1819 const unsigned char* pshdrs, Output_file* of,
1820 typename Sized_relobj_file<size, big_endian>::Views* pviews);
1821
5019d64a
HS
1822 // Count local symbols and (optionally) record mapping info.
1823 virtual void
1824 do_count_local_symbols(Stringpool_template<char>*,
1825 Stringpool_template<char>*);
1826
83a01957 1827 private:
a48d0c12
HS
1828 // Fix all errata in the object.
1829 void
1830 fix_errata(typename Sized_relobj_file<size, big_endian>::Views* pviews);
1831
0ef3814f
HS
1832 // Try to fix erratum 843419 in an optimized way. Return true if patch is
1833 // applied.
1834 bool
1835 try_fix_erratum_843419_optimized(
1836 The_erratum_stub*,
1837 typename Sized_relobj_file<size, big_endian>::View_size&);
1838
83a01957
HS
1839 // Whether a section needs to be scanned for relocation stubs.
1840 bool
1841 section_needs_reloc_stub_scanning(const elfcpp::Shdr<size, big_endian>&,
1842 const Relobj::Output_sections&,
1843 const Symbol_table*, const unsigned char*);
1844
1845 // List of stub tables.
1846 Stub_table_list stub_tables_;
5019d64a
HS
1847
1848 // Mapping symbol information sorted by (section index, section_offset).
1849 Mapping_symbol_info mapping_symbol_info_;
83a01957
HS
1850}; // End of AArch64_relobj
1851
1852
5019d64a
HS
1853// Override to record mapping symbol information.
1854template<int size, bool big_endian>
1855void
1856AArch64_relobj<size, big_endian>::do_count_local_symbols(
1857 Stringpool_template<char>* pool, Stringpool_template<char>* dynpool)
1858{
1859 Sized_relobj_file<size, big_endian>::do_count_local_symbols(pool, dynpool);
1860
1861 // Only erratum-fixing work needs mapping symbols, so skip this time consuming
1862 // processing if not fixing erratum.
2f0c79aa
HS
1863 if (!parameters->options().fix_cortex_a53_843419()
1864 && !parameters->options().fix_cortex_a53_835769())
5019d64a
HS
1865 return;
1866
1867 const unsigned int loccount = this->local_symbol_count();
1868 if (loccount == 0)
1869 return;
1870
1871 // Read the symbol table section header.
1872 const unsigned int symtab_shndx = this->symtab_shndx();
1873 elfcpp::Shdr<size, big_endian>
1874 symtabshdr(this, this->elf_file()->section_header(symtab_shndx));
1875 gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
1876
1877 // Read the local symbols.
1878 const int sym_size =elfcpp::Elf_sizes<size>::sym_size;
1879 gold_assert(loccount == symtabshdr.get_sh_info());
1880 off_t locsize = loccount * sym_size;
1881 const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
1882 locsize, true, true);
1883
1884 // For mapping symbol processing, we need to read the symbol names.
1885 unsigned int strtab_shndx = this->adjust_shndx(symtabshdr.get_sh_link());
1886 if (strtab_shndx >= this->shnum())
1887 {
1888 this->error(_("invalid symbol table name index: %u"), strtab_shndx);
1889 return;
1890 }
1891
1892 elfcpp::Shdr<size, big_endian>
1893 strtabshdr(this, this->elf_file()->section_header(strtab_shndx));
1894 if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB)
1895 {
1896 this->error(_("symbol table name section has wrong type: %u"),
1897 static_cast<unsigned int>(strtabshdr.get_sh_type()));
1898 return;
1899 }
1900
1901 const char* pnames =
1902 reinterpret_cast<const char*>(this->get_view(strtabshdr.get_sh_offset(),
1903 strtabshdr.get_sh_size(),
1904 false, false));
1905
1906 // Skip the first dummy symbol.
1907 psyms += sym_size;
1908 typename Sized_relobj_file<size, big_endian>::Local_values*
1909 plocal_values = this->local_values();
1910 for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
1911 {
1912 elfcpp::Sym<size, big_endian> sym(psyms);
1913 Symbol_value<size>& lv((*plocal_values)[i]);
1914 AArch64_address input_value = lv.input_value();
1915
b91deca9
HS
1916 // Check to see if this is a mapping symbol. AArch64 mapping symbols are
1917 // defined in "ELF for the ARM 64-bit Architecture", Table 4-4, Mapping
1918 // symbols.
1919 // Mapping symbols could be one of the following 4 forms -
1920 // a) $x
1921 // b) $x.<any...>
1922 // c) $d
1923 // d) $d.<any...>
5019d64a
HS
1924 const char* sym_name = pnames + sym.get_st_name();
1925 if (sym_name[0] == '$' && (sym_name[1] == 'x' || sym_name[1] == 'd')
b91deca9 1926 && (sym_name[2] == '\0' || sym_name[2] == '.'))
5019d64a
HS
1927 {
1928 bool is_ordinary;
1929 unsigned int input_shndx =
1930 this->adjust_sym_shndx(i, sym.get_st_shndx(), &is_ordinary);
1931 gold_assert(is_ordinary);
1932
1933 Mapping_symbol_position msp(input_shndx, input_value);
1934 // Insert mapping_symbol_info into map whose ordering is defined by
1935 // (shndx, offset_within_section).
1936 this->mapping_symbol_info_[msp] = sym_name[1];
1937 }
1938 }
1939}
1940
1941
a48d0c12
HS
1942// Fix all errata in the object.
1943
1944template<int size, bool big_endian>
1945void
1946AArch64_relobj<size, big_endian>::fix_errata(
1947 typename Sized_relobj_file<size, big_endian>::Views* pviews)
1948{
1949 typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
1950 unsigned int shnum = this->shnum();
1951 for (unsigned int i = 1; i < shnum; ++i)
1952 {
1953 The_stub_table* stub_table = this->stub_table(i);
1954 if (!stub_table)
1955 continue;
1956 std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
1957 ipair(stub_table->find_erratum_stubs_for_input_section(this, i));
1958 Erratum_stub_set_iter p = ipair.first, end = ipair.second;
1959 while (p != end)
1960 {
1961 The_erratum_stub* stub = *p;
1962 typename Sized_relobj_file<size, big_endian>::View_size&
1963 pview((*pviews)[i]);
1964
1965 // Double check data before fix.
56b06706
HS
1966 gold_assert(pview.address + stub->sh_offset()
1967 == stub->erratum_address());
1968
1969 // Update previously recorded erratum insn with relocated
1970 // version.
a48d0c12
HS
1971 Insntype* ip =
1972 reinterpret_cast<Insntype*>(pview.view + stub->sh_offset());
1973 Insntype insn_to_fix = ip[0];
56b06706 1974 stub->update_erratum_insn(insn_to_fix);
a48d0c12 1975
0ef3814f
HS
1976 // First try to see if erratum is 843419 and if it can be fixed
1977 // without using branch-to-stub.
1978 if (!try_fix_erratum_843419_optimized(stub, pview))
1979 {
1980 // Replace the erratum insn with a branch-to-stub.
1981 AArch64_address stub_address =
1982 stub_table->erratum_stub_address(stub);
1983 unsigned int b_offset = stub_address - stub->erratum_address();
1984 AArch64_relocate_functions<size, big_endian>::construct_b(
1985 pview.view + stub->sh_offset(), b_offset & 0xfffffff);
1986 }
a48d0c12
HS
1987 ++p;
1988 }
1989 }
1990}
1991
1992
0ef3814f
HS
1993// This is an optimization for 843419. This erratum requires the sequence begin
1994// with 'adrp', when final value calculated by adrp fits in adr, we can just
1995// replace 'adrp' with 'adr', so we save 2 jumps per occurrence. (Note, however,
1996// in this case, we do not delete the erratum stub (too late to do so), it is
1997// merely generated without ever being called.)
1998
1999template<int size, bool big_endian>
2000bool
2001AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
2002 The_erratum_stub* stub,
2003 typename Sized_relobj_file<size, big_endian>::View_size& pview)
2004{
2005 if (stub->type() != ST_E_843419)
2006 return false;
2007
2008 typedef AArch64_insn_utilities<big_endian> Insn_utilities;
2009 typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
2010 E843419_stub<size, big_endian>* e843419_stub =
2011 reinterpret_cast<E843419_stub<size, big_endian>*>(stub);
2012 AArch64_address pc = pview.address + e843419_stub->adrp_sh_offset();
2013 Insntype* adrp_view = reinterpret_cast<Insntype*>(
2014 pview.view + e843419_stub->adrp_sh_offset());
2015 Insntype adrp_insn = adrp_view[0];
2016 gold_assert(Insn_utilities::is_adrp(adrp_insn));
2017 // Get adrp 33-bit signed imm value.
2018 int64_t adrp_imm = Insn_utilities::
2019 aarch64_adrp_decode_imm(adrp_insn);
2020 // adrp - final value transferred to target register is calculated as:
2021 // PC[11:0] = Zeros(12)
2022 // adrp_dest_value = PC + adrp_imm;
2023 int64_t adrp_dest_value = (pc & ~((1 << 12) - 1)) + adrp_imm;
2024 // adr -final value transferred to target register is calucalted as:
2025 // PC + adr_imm
2026 // So we have:
2027 // PC + adr_imm = adrp_dest_value
2028 // ==>
2029 // adr_imm = adrp_dest_value - PC
2030 int64_t adr_imm = adrp_dest_value - pc;
2031 // Check if imm fits in adr (21-bit signed).
2032 if (-(1 << 20) <= adr_imm && adr_imm < (1 << 20))
2033 {
2034 // Convert 'adrp' into 'adr'.
f945ba50 2035 Insntype adr_insn = adrp_insn & ((1u << 31) - 1);
0ef3814f
HS
2036 adr_insn = Insn_utilities::
2037 aarch64_adr_encode_imm(adr_insn, adr_imm);
2038 elfcpp::Swap<32, big_endian>::writeval(adrp_view, adr_insn);
2039 return true;
2040 }
2041 return false;
2042}
2043
2044
83a01957
HS
2045// Relocate sections.
2046
2047template<int size, bool big_endian>
2048void
2049AArch64_relobj<size, big_endian>::do_relocate_sections(
2050 const Symbol_table* symtab, const Layout* layout,
2051 const unsigned char* pshdrs, Output_file* of,
2052 typename Sized_relobj_file<size, big_endian>::Views* pviews)
2053{
98461510
CC
2054 // Relocate the section data.
2055 this->relocate_section_range(symtab, layout, pshdrs, of, pviews,
2056 1, this->shnum() - 1);
83a01957
HS
2057
2058 // We do not generate stubs if doing a relocatable link.
2059 if (parameters->options().relocatable())
2060 return;
2061
2f0c79aa
HS
2062 if (parameters->options().fix_cortex_a53_843419()
2063 || parameters->options().fix_cortex_a53_835769())
a48d0c12
HS
2064 this->fix_errata(pviews);
2065
83a01957
HS
2066 Relocate_info<size, big_endian> relinfo;
2067 relinfo.symtab = symtab;
2068 relinfo.layout = layout;
2069 relinfo.object = this;
2070
2071 // Relocate stub tables.
2072 unsigned int shnum = this->shnum();
2073 The_target_aarch64* target = The_target_aarch64::current_target();
2074
2075 for (unsigned int i = 1; i < shnum; ++i)
2076 {
2077 The_aarch64_input_section* aarch64_input_section =
2078 target->find_aarch64_input_section(this, i);
2079 if (aarch64_input_section != NULL
2080 && aarch64_input_section->is_stub_table_owner()
2081 && !aarch64_input_section->stub_table()->empty())
2082 {
2083 Output_section* os = this->output_section(i);
2084 gold_assert(os != NULL);
2085
2086 relinfo.reloc_shndx = elfcpp::SHN_UNDEF;
2087 relinfo.reloc_shdr = NULL;
2088 relinfo.data_shndx = i;
2089 relinfo.data_shdr = pshdrs + i * elfcpp::Elf_sizes<size>::shdr_size;
2090
2091 typename Sized_relobj_file<size, big_endian>::View_size&
2092 view_struct = (*pviews)[i];
2093 gold_assert(view_struct.view != NULL);
2094
2095 The_stub_table* stub_table = aarch64_input_section->stub_table();
2096 off_t offset = stub_table->address() - view_struct.address;
2097 unsigned char* view = view_struct.view + offset;
2098 AArch64_address address = stub_table->address();
2099 section_size_type view_size = stub_table->data_size();
2100 stub_table->relocate_stubs(&relinfo, target, os, view, address,
2101 view_size);
2102 }
2103 }
2104}
2105
2106
2107// Determine if an input section is scannable for stub processing. SHDR is
2108// the header of the section and SHNDX is the section index. OS is the output
2109// section for the input section and SYMTAB is the global symbol table used to
2110// look up ICF information.
2111
2112template<int size, bool big_endian>
2113bool
2114AArch64_relobj<size, big_endian>::text_section_is_scannable(
2115 const elfcpp::Shdr<size, big_endian>& text_shdr,
2116 unsigned int text_shndx,
2117 const Output_section* os,
2118 const Symbol_table* symtab)
2119{
2120 // Skip any empty sections, unallocated sections or sections whose
2121 // type are not SHT_PROGBITS.
2122 if (text_shdr.get_sh_size() == 0
2123 || (text_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0
2124 || text_shdr.get_sh_type() != elfcpp::SHT_PROGBITS)
2125 return false;
2126
2127 // Skip any discarded or ICF'ed sections.
2128 if (os == NULL || symtab->is_section_folded(this, text_shndx))
2129 return false;
2130
2131 // Skip exception frame.
2132 if (strcmp(os->name(), ".eh_frame") == 0)
2133 return false ;
2134
2135 gold_assert(!this->is_output_section_offset_invalid(text_shndx) ||
2136 os->find_relaxed_input_section(this, text_shndx) != NULL);
2137
2138 return true;
2139}
2140
2141
2142// Determine if we want to scan the SHNDX-th section for relocation stubs.
2143// This is a helper for AArch64_relobj::scan_sections_for_stubs().
2144
2145template<int size, bool big_endian>
2146bool
2147AArch64_relobj<size, big_endian>::section_needs_reloc_stub_scanning(
2148 const elfcpp::Shdr<size, big_endian>& shdr,
2149 const Relobj::Output_sections& out_sections,
2150 const Symbol_table* symtab,
2151 const unsigned char* pshdrs)
2152{
2153 unsigned int sh_type = shdr.get_sh_type();
2154 if (sh_type != elfcpp::SHT_RELA)
2155 return false;
2156
2157 // Ignore empty section.
2158 off_t sh_size = shdr.get_sh_size();
2159 if (sh_size == 0)
2160 return false;
2161
2162 // Ignore reloc section with unexpected symbol table. The
2163 // error will be reported in the final link.
2164 if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx())
2165 return false;
2166
2167 gold_assert(sh_type == elfcpp::SHT_RELA);
2168 unsigned int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
2169
2170 // Ignore reloc section with unexpected entsize or uneven size.
2171 // The error will be reported in the final link.
2172 if (reloc_size != shdr.get_sh_entsize() || sh_size % reloc_size != 0)
2173 return false;
2174
2175 // Ignore reloc section with bad info. This error will be
2176 // reported in the final link.
2177 unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_info());
2178 if (text_shndx >= this->shnum())
2179 return false;
2180
2181 const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
2182 const elfcpp::Shdr<size, big_endian> text_shdr(pshdrs +
2183 text_shndx * shdr_size);
2184 return this->text_section_is_scannable(text_shdr, text_shndx,
2185 out_sections[text_shndx], symtab);
2186}
2187
2188
2f0c79aa 2189// Scan section SHNDX for erratum 843419 and 835769.
5019d64a
HS
2190
2191template<int size, bool big_endian>
2192void
2f0c79aa 2193AArch64_relobj<size, big_endian>::scan_errata(
5019d64a
HS
2194 unsigned int shndx, const elfcpp::Shdr<size, big_endian>& shdr,
2195 Output_section* os, const Symbol_table* symtab,
2196 The_target_aarch64* target)
2197{
2198 if (shdr.get_sh_size() == 0
2199 || (shdr.get_sh_flags() &
2200 (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR)) == 0
2201 || shdr.get_sh_type() != elfcpp::SHT_PROGBITS)
2202 return;
2203
2204 if (!os || symtab->is_section_folded(this, shndx)) return;
2205
2206 AArch64_address output_offset = this->get_output_section_offset(shndx);
2207 AArch64_address output_address;
2208 if (output_offset != invalid_address)
2209 output_address = os->address() + output_offset;
2210 else
2211 {
2212 const Output_relaxed_input_section* poris =
2213 os->find_relaxed_input_section(this, shndx);
2214 if (!poris) return;
2215 output_address = poris->address();
2216 }
2217
2218 section_size_type input_view_size = 0;
2219 const unsigned char* input_view =
2220 this->section_contents(shndx, &input_view_size, false);
2221
2222 Mapping_symbol_position section_start(shndx, 0);
2223 // Find the first mapping symbol record within section shndx.
2224 typename Mapping_symbol_info::const_iterator p =
2225 this->mapping_symbol_info_.lower_bound(section_start);
5019d64a
HS
2226 while (p != this->mapping_symbol_info_.end() &&
2227 p->first.shndx_ == shndx)
2228 {
2229 typename Mapping_symbol_info::const_iterator prev = p;
2230 ++p;
2231 if (prev->second == 'x')
2232 {
2233 section_size_type span_start =
2234 convert_to_section_size_type(prev->first.offset_);
2235 section_size_type span_end;
2236 if (p != this->mapping_symbol_info_.end()
2237 && p->first.shndx_ == shndx)
2238 span_end = convert_to_section_size_type(p->first.offset_);
2239 else
2240 span_end = convert_to_section_size_type(shdr.get_sh_size());
2f0c79aa
HS
2241
2242 // Here we do not share the scanning code of both errata. For 843419,
2243 // only the last few insns of each page are examined, which is fast,
2244 // whereas, for 835769, every insn pair needs to be checked.
2245
2246 if (parameters->options().fix_cortex_a53_843419())
2247 target->scan_erratum_843419_span(
2248 this, shndx, span_start, span_end,
2249 const_cast<unsigned char*>(input_view), output_address);
2250
2251 if (parameters->options().fix_cortex_a53_835769())
2252 target->scan_erratum_835769_span(
5019d64a
HS
2253 this, shndx, span_start, span_end,
2254 const_cast<unsigned char*>(input_view), output_address);
2255 }
2256 }
2257}
2258
2259
83a01957
HS
2260// Scan relocations for stub generation.
2261
2262template<int size, bool big_endian>
2263void
2264AArch64_relobj<size, big_endian>::scan_sections_for_stubs(
2265 The_target_aarch64* target,
2266 const Symbol_table* symtab,
2267 const Layout* layout)
2268{
2269 unsigned int shnum = this->shnum();
2270 const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
2271
2272 // Read the section headers.
2273 const unsigned char* pshdrs = this->get_view(this->elf_file()->shoff(),
2274 shnum * shdr_size,
2275 true, true);
2276
2277 // To speed up processing, we set up hash tables for fast lookup of
2278 // input offsets to output addresses.
2279 this->initialize_input_to_output_maps();
2280
2281 const Relobj::Output_sections& out_sections(this->output_sections());
2282
2283 Relocate_info<size, big_endian> relinfo;
2284 relinfo.symtab = symtab;
2285 relinfo.layout = layout;
2286 relinfo.object = this;
2287
2288 // Do relocation stubs scanning.
2289 const unsigned char* p = pshdrs + shdr_size;
2290 for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
2291 {
2292 const elfcpp::Shdr<size, big_endian> shdr(p);
2f0c79aa
HS
2293 if (parameters->options().fix_cortex_a53_843419()
2294 || parameters->options().fix_cortex_a53_835769())
2295 scan_errata(i, shdr, out_sections[i], symtab, target);
83a01957
HS
2296 if (this->section_needs_reloc_stub_scanning(shdr, out_sections, symtab,
2297 pshdrs))
2298 {
2299 unsigned int index = this->adjust_shndx(shdr.get_sh_info());
2300 AArch64_address output_offset =
2301 this->get_output_section_offset(index);
2302 AArch64_address output_address;
2303 if (output_offset != invalid_address)
2304 {
2305 output_address = out_sections[index]->address() + output_offset;
2306 }
2307 else
2308 {
2309 // Currently this only happens for a relaxed section.
2310 const Output_relaxed_input_section* poris =
2311 out_sections[index]->find_relaxed_input_section(this, index);
2312 gold_assert(poris != NULL);
2313 output_address = poris->address();
2314 }
2315
2316 // Get the relocations.
2317 const unsigned char* prelocs = this->get_view(shdr.get_sh_offset(),
2318 shdr.get_sh_size(),
2319 true, false);
2320
2321 // Get the section contents.
2322 section_size_type input_view_size = 0;
2323 const unsigned char* input_view =
2324 this->section_contents(index, &input_view_size, false);
2325
2326 relinfo.reloc_shndx = i;
2327 relinfo.data_shndx = index;
2328 unsigned int sh_type = shdr.get_sh_type();
2329 unsigned int reloc_size;
2330 gold_assert (sh_type == elfcpp::SHT_RELA);
2331 reloc_size = elfcpp::Elf_sizes<size>::rela_size;
2332
2333 Output_section* os = out_sections[index];
2334 target->scan_section_for_stubs(&relinfo, sh_type, prelocs,
2335 shdr.get_sh_size() / reloc_size,
2336 os,
2337 output_offset == invalid_address,
2338 input_view, output_address,
2339 input_view_size);
2340 }
2341 }
2342}
2343
2344
2345// A class to wrap an ordinary input section containing executable code.
2346
2347template<int size, bool big_endian>
2348class AArch64_input_section : public Output_relaxed_input_section
2349{
2350 public:
2351 typedef Stub_table<size, big_endian> The_stub_table;
2352
2353 AArch64_input_section(Relobj* relobj, unsigned int shndx)
2354 : Output_relaxed_input_section(relobj, shndx, 1),
2355 stub_table_(NULL),
2356 original_contents_(NULL), original_size_(0),
2357 original_addralign_(1)
2358 { }
2359
2360 ~AArch64_input_section()
2361 { delete[] this->original_contents_; }
2362
2363 // Initialize.
2364 void
2365 init();
2366
2367 // Set the stub_table.
2368 void
2369 set_stub_table(The_stub_table* st)
2370 { this->stub_table_ = st; }
2371
2372 // Whether this is a stub table owner.
2373 bool
2374 is_stub_table_owner() const
2375 { return this->stub_table_ != NULL && this->stub_table_->owner() == this; }
2376
2377 // Return the original size of the section.
2378 uint32_t
2379 original_size() const
2380 { return this->original_size_; }
2381
2382 // Return the stub table.
2383 The_stub_table*
2384 stub_table()
2385 { return stub_table_; }
2386
2387 protected:
2388 // Write out this input section.
2389 void
2390 do_write(Output_file*);
2391
2392 // Return required alignment of this.
2393 uint64_t
2394 do_addralign() const
2395 {
2396 if (this->is_stub_table_owner())
2397 return std::max(this->stub_table_->addralign(),
2398 static_cast<uint64_t>(this->original_addralign_));
2399 else
2400 return this->original_addralign_;
2401 }
2402
2403 // Finalize data size.
2404 void
2405 set_final_data_size();
2406
2407 // Reset address and file offset.
2408 void
2409 do_reset_address_and_file_offset();
2410
2411 // Output offset.
2412 bool
2413 do_output_offset(const Relobj* object, unsigned int shndx,
2414 section_offset_type offset,
2415 section_offset_type* poutput) const
2416 {
2417 if ((object == this->relobj())
2418 && (shndx == this->shndx())
2419 && (offset >= 0)
2420 && (offset <=
2421 convert_types<section_offset_type, uint32_t>(this->original_size_)))
2422 {
2423 *poutput = offset;
2424 return true;
2425 }
2426 else
2427 return false;
2428 }
2429
2430 private:
2431 // Copying is not allowed.
2432 AArch64_input_section(const AArch64_input_section&);
2433 AArch64_input_section& operator=(const AArch64_input_section&);
2434
2435 // The relocation stubs.
2436 The_stub_table* stub_table_;
2437 // Original section contents. We have to make a copy here since the file
2438 // containing the original section may not be locked when we need to access
2439 // the contents.
2440 unsigned char* original_contents_;
2441 // Section size of the original input section.
2442 uint32_t original_size_;
2443 // Address alignment of the original input section.
2444 uint32_t original_addralign_;
2445}; // End of AArch64_input_section
2446
2447
2448// Finalize data size.
2449
2450template<int size, bool big_endian>
2451void
2452AArch64_input_section<size, big_endian>::set_final_data_size()
2453{
2454 off_t off = convert_types<off_t, uint64_t>(this->original_size_);
2455
2456 if (this->is_stub_table_owner())
2457 {
2458 this->stub_table_->finalize_data_size();
2459 off = align_address(off, this->stub_table_->addralign());
2460 off += this->stub_table_->data_size();
2461 }
2462 this->set_data_size(off);
2463}
2464
2465
2466// Reset address and file offset.
2467
2468template<int size, bool big_endian>
2469void
2470AArch64_input_section<size, big_endian>::do_reset_address_and_file_offset()
2471{
2472 // Size of the original input section contents.
2473 off_t off = convert_types<off_t, uint64_t>(this->original_size_);
2474
2475 // If this is a stub table owner, account for the stub table size.
2476 if (this->is_stub_table_owner())
2477 {
2478 The_stub_table* stub_table = this->stub_table_;
2479
2480 // Reset the stub table's address and file offset. The
2481 // current data size for child will be updated after that.
2482 stub_table_->reset_address_and_file_offset();
2483 off = align_address(off, stub_table_->addralign());
2484 off += stub_table->current_data_size();
2485 }
2486
2487 this->set_current_data_size(off);
2488}
2489
2490
2491// Initialize an Arm_input_section.
2492
2493template<int size, bool big_endian>
2494void
2495AArch64_input_section<size, big_endian>::init()
2496{
2497 Relobj* relobj = this->relobj();
2498 unsigned int shndx = this->shndx();
2499
2500 // We have to cache original size, alignment and contents to avoid locking
2501 // the original file.
2502 this->original_addralign_ =
2503 convert_types<uint32_t, uint64_t>(relobj->section_addralign(shndx));
2504
2505 // This is not efficient but we expect only a small number of relaxed
2506 // input sections for stubs.
2507 section_size_type section_size;
2508 const unsigned char* section_contents =
2509 relobj->section_contents(shndx, &section_size, false);
2510 this->original_size_ =
2511 convert_types<uint32_t, uint64_t>(relobj->section_size(shndx));
2512
2513 gold_assert(this->original_contents_ == NULL);
2514 this->original_contents_ = new unsigned char[section_size];
2515 memcpy(this->original_contents_, section_contents, section_size);
2516
2517 // We want to make this look like the original input section after
2518 // output sections are finalized.
2519 Output_section* os = relobj->output_section(shndx);
2520 off_t offset = relobj->output_section_offset(shndx);
2521 gold_assert(os != NULL && !relobj->is_output_section_offset_invalid(shndx));
2522 this->set_address(os->address() + offset);
2523 this->set_file_offset(os->offset() + offset);
2524 this->set_current_data_size(this->original_size_);
2525 this->finalize_data_size();
2526}
2527
2528
2529// Write data to output file.
2530
2531template<int size, bool big_endian>
2532void
2533AArch64_input_section<size, big_endian>::do_write(Output_file* of)
2534{
2535 // We have to write out the original section content.
2536 gold_assert(this->original_contents_ != NULL);
2537 of->write(this->offset(), this->original_contents_,
2538 this->original_size_);
2539
2540 // If this owns a stub table and it is not empty, write it.
2541 if (this->is_stub_table_owner() && !this->stub_table_->empty())
2542 this->stub_table_->write(of);
2543}
2544
2545
2546// Arm output section class. This is defined mainly to add a number of stub
2547// generation methods.
2548
2549template<int size, bool big_endian>
2550class AArch64_output_section : public Output_section
2551{
2552 public:
2553 typedef Target_aarch64<size, big_endian> The_target_aarch64;
2554 typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
2555 typedef Stub_table<size, big_endian> The_stub_table;
2556 typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
2557
2558 public:
2559 AArch64_output_section(const char* name, elfcpp::Elf_Word type,
2560 elfcpp::Elf_Xword flags)
2561 : Output_section(name, type, flags)
2562 { }
2563
2564 ~AArch64_output_section() {}
2565
2566 // Group input sections for stub generation.
2567 void
2568 group_sections(section_size_type, bool, Target_aarch64<size, big_endian>*,
2569 const Task*);
2570
2571 private:
2572 typedef Output_section::Input_section Input_section;
2573 typedef Output_section::Input_section_list Input_section_list;
2574
2575 // Create a stub group.
2576 void
2577 create_stub_group(Input_section_list::const_iterator,
2578 Input_section_list::const_iterator,
2579 Input_section_list::const_iterator,
2580 The_target_aarch64*,
2581 std::vector<Output_relaxed_input_section*>&,
2582 const Task*);
2583}; // End of AArch64_output_section
2584
2585
2586// Create a stub group for input sections from FIRST to LAST. OWNER points to
2587// the input section that will be the owner of the stub table.
2588
2589template<int size, bool big_endian> void
2590AArch64_output_section<size, big_endian>::create_stub_group(
2591 Input_section_list::const_iterator first,
2592 Input_section_list::const_iterator last,
2593 Input_section_list::const_iterator owner,
2594 The_target_aarch64* target,
2595 std::vector<Output_relaxed_input_section*>& new_relaxed_sections,
2596 const Task* task)
2597{
2598 // Currently we convert ordinary input sections into relaxed sections only
2599 // at this point.
2600 The_aarch64_input_section* input_section;
2601 if (owner->is_relaxed_input_section())
2602 gold_unreachable();
2603 else
2604 {
2605 gold_assert(owner->is_input_section());
2606 // Create a new relaxed input section. We need to lock the original
2607 // file.
2608 Task_lock_obj<Object> tl(task, owner->relobj());
2609 input_section =
2610 target->new_aarch64_input_section(owner->relobj(), owner->shndx());
2611 new_relaxed_sections.push_back(input_section);
2612 }
2613
2614 // Create a stub table.
2615 The_stub_table* stub_table =
2616 target->new_stub_table(input_section);
2617
2618 input_section->set_stub_table(stub_table);
2619
2620 Input_section_list::const_iterator p = first;
2621 // Look for input sections or relaxed input sections in [first ... last].
2622 do
2623 {
2624 if (p->is_input_section() || p->is_relaxed_input_section())
2625 {
2626 // The stub table information for input sections live
2627 // in their objects.
2628 The_aarch64_relobj* aarch64_relobj =
2629 static_cast<The_aarch64_relobj*>(p->relobj());
2630 aarch64_relobj->set_stub_table(p->shndx(), stub_table);
2631 }
2632 }
2633 while (p++ != last);
2634}
2635
2636
2637// Group input sections for stub generation. GROUP_SIZE is roughly the limit of
2638// stub groups. We grow a stub group by adding input section until the size is
2639// just below GROUP_SIZE. The last input section will be converted into a stub
2640// table owner. If STUB_ALWAYS_AFTER_BRANCH is false, we also add input sectiond
2641// after the stub table, effectively doubling the group size.
2642//
2643// This is similar to the group_sections() function in elf32-arm.c but is
2644// implemented differently.
2645
2646template<int size, bool big_endian>
2647void AArch64_output_section<size, big_endian>::group_sections(
2648 section_size_type group_size,
2649 bool stubs_always_after_branch,
2650 Target_aarch64<size, big_endian>* target,
2651 const Task* task)
2652{
2653 typedef enum
2654 {
2655 NO_GROUP,
2656 FINDING_STUB_SECTION,
2657 HAS_STUB_SECTION
2658 } State;
2659
2660 std::vector<Output_relaxed_input_section*> new_relaxed_sections;
2661
2662 State state = NO_GROUP;
2663 section_size_type off = 0;
2664 section_size_type group_begin_offset = 0;
2665 section_size_type group_end_offset = 0;
2666 section_size_type stub_table_end_offset = 0;
2667 Input_section_list::const_iterator group_begin =
2668 this->input_sections().end();
2669 Input_section_list::const_iterator stub_table =
2670 this->input_sections().end();
2671 Input_section_list::const_iterator group_end = this->input_sections().end();
2672 for (Input_section_list::const_iterator p = this->input_sections().begin();
2673 p != this->input_sections().end();
2674 ++p)
2675 {
2676 section_size_type section_begin_offset =
2677 align_address(off, p->addralign());
2678 section_size_type section_end_offset =
2679 section_begin_offset + p->data_size();
2680
2681 // Check to see if we should group the previously seen sections.
2682 switch (state)
2683 {
2684 case NO_GROUP:
2685 break;
2686
2687 case FINDING_STUB_SECTION:
2688 // Adding this section makes the group larger than GROUP_SIZE.
2689 if (section_end_offset - group_begin_offset >= group_size)
2690 {
2691 if (stubs_always_after_branch)
2692 {
2693 gold_assert(group_end != this->input_sections().end());
2694 this->create_stub_group(group_begin, group_end, group_end,
2695 target, new_relaxed_sections,
2696 task);
2697 state = NO_GROUP;
2698 }
2699 else
2700 {
2701 // Input sections up to stub_group_size bytes after the stub
2702 // table can be handled by it too.
2703 state = HAS_STUB_SECTION;
2704 stub_table = group_end;
2705 stub_table_end_offset = group_end_offset;
2706 }
2707 }
2708 break;
2709
2710 case HAS_STUB_SECTION:
2711 // Adding this section makes the post stub-section group larger
2712 // than GROUP_SIZE.
2713 gold_unreachable();
2714 // NOT SUPPORTED YET. For completeness only.
2715 if (section_end_offset - stub_table_end_offset >= group_size)
2716 {
2717 gold_assert(group_end != this->input_sections().end());
2718 this->create_stub_group(group_begin, group_end, stub_table,
2719 target, new_relaxed_sections, task);
2720 state = NO_GROUP;
2721 }
2722 break;
2723
2724 default:
2725 gold_unreachable();
2726 }
2727
2728 // If we see an input section and currently there is no group, start
2729 // a new one. Skip any empty sections. We look at the data size
2730 // instead of calling p->relobj()->section_size() to avoid locking.
2731 if ((p->is_input_section() || p->is_relaxed_input_section())
2732 && (p->data_size() != 0))
2733 {
2734 if (state == NO_GROUP)
2735 {
2736 state = FINDING_STUB_SECTION;
2737 group_begin = p;
2738 group_begin_offset = section_begin_offset;
2739 }
2740
2741 // Keep track of the last input section seen.
2742 group_end = p;
2743 group_end_offset = section_end_offset;
2744 }
2745
2746 off = section_end_offset;
2747 }
2748
2749 // Create a stub group for any ungrouped sections.
2750 if (state == FINDING_STUB_SECTION || state == HAS_STUB_SECTION)
2751 {
2752 gold_assert(group_end != this->input_sections().end());
2753 this->create_stub_group(group_begin, group_end,
2754 (state == FINDING_STUB_SECTION
2755 ? group_end
2756 : stub_table),
2757 target, new_relaxed_sections, task);
2758 }
8e33481e 2759
83a01957
HS
2760 if (!new_relaxed_sections.empty())
2761 this->convert_input_sections_to_relaxed_sections(new_relaxed_sections);
2762
2763 // Update the section offsets
2764 for (size_t i = 0; i < new_relaxed_sections.size(); ++i)
2765 {
2766 The_aarch64_relobj* relobj = static_cast<The_aarch64_relobj*>(
2767 new_relaxed_sections[i]->relobj());
2768 unsigned int shndx = new_relaxed_sections[i]->shndx();
2769 // Tell AArch64_relobj that this input section is converted.
2770 relobj->convert_input_section_to_relaxed_section(shndx);
2771 }
2772} // End of AArch64_output_section::group_sections
3a531937 2773
053a4d68 2774
9363c7c3
JY
2775AArch64_reloc_property_table* aarch64_reloc_property_table = NULL;
2776
3a531937 2777
053a4d68
JY
2778// The aarch64 target class.
2779// See the ABI at
2780// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
2781template<int size, bool big_endian>
2782class Target_aarch64 : public Sized_target<size, big_endian>
2783{
2784 public:
83a01957 2785 typedef Target_aarch64<size, big_endian> This;
053a4d68
JY
2786 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
2787 Reloc_section;
83a01957 2788 typedef Relocate_info<size, big_endian> The_relocate_info;
053a4d68 2789 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
83a01957
HS
2790 typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
2791 typedef Reloc_stub<size, big_endian> The_reloc_stub;
a48d0c12 2792 typedef Erratum_stub<size, big_endian> The_erratum_stub;
83a01957
HS
2793 typedef typename Reloc_stub<size, big_endian>::Key The_reloc_stub_key;
2794 typedef Stub_table<size, big_endian> The_stub_table;
2795 typedef std::vector<The_stub_table*> Stub_table_list;
2796 typedef typename Stub_table_list::iterator Stub_table_iterator;
2797 typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
2798 typedef AArch64_output_section<size, big_endian> The_aarch64_output_section;
2799 typedef Unordered_map<Section_id,
2800 AArch64_input_section<size, big_endian>*,
2801 Section_id_hash> AArch64_input_section_map;
5019d64a 2802 typedef AArch64_insn_utilities<big_endian> Insn_utilities;
8e33481e 2803 const static int TCB_SIZE = size / 8 * 2;
053a4d68
JY
2804
2805 Target_aarch64(const Target::Target_info* info = &aarch64_info)
2806 : Sized_target<size, big_endian>(info),
3a531937
JY
2807 got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
2808 got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL),
2809 rela_irelative_(NULL), copy_relocs_(elfcpp::R_AARCH64_COPY),
83a01957
HS
2810 got_mod_index_offset_(-1U),
2811 tlsdesc_reloc_info_(), tls_base_symbol_defined_(false),
0bf32ea9 2812 stub_tables_(), stub_group_size_(0), aarch64_input_section_map_()
053a4d68
JY
2813 { }
2814
2815 // Scan the relocations to determine unreferenced sections for
2816 // garbage collection.
2817 void
2818 gc_process_relocs(Symbol_table* symtab,
2819 Layout* layout,
2820 Sized_relobj_file<size, big_endian>* object,
2821 unsigned int data_shndx,
2822 unsigned int sh_type,
2823 const unsigned char* prelocs,
2824 size_t reloc_count,
2825 Output_section* output_section,
2826 bool needs_special_offset_handling,
2827 size_t local_symbol_count,
2828 const unsigned char* plocal_symbols);
2829
2830 // Scan the relocations to look for symbol adjustments.
2831 void
2832 scan_relocs(Symbol_table* symtab,
2833 Layout* layout,
2834 Sized_relobj_file<size, big_endian>* object,
2835 unsigned int data_shndx,
2836 unsigned int sh_type,
2837 const unsigned char* prelocs,
2838 size_t reloc_count,
2839 Output_section* output_section,
2840 bool needs_special_offset_handling,
2841 size_t local_symbol_count,
2842 const unsigned char* plocal_symbols);
2843
2844 // Finalize the sections.
2845 void
2846 do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
2847
3a531937
JY
2848 // Return the value to use for a dynamic which requires special
2849 // treatment.
2850 uint64_t
2851 do_dynsym_value(const Symbol*) const;
2852
053a4d68
JY
2853 // Relocate a section.
2854 void
2855 relocate_section(const Relocate_info<size, big_endian>*,
2856 unsigned int sh_type,
2857 const unsigned char* prelocs,
2858 size_t reloc_count,
2859 Output_section* output_section,
2860 bool needs_special_offset_handling,
2861 unsigned char* view,
2862 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
2863 section_size_type view_size,
2864 const Reloc_symbol_changes*);
2865
2866 // Scan the relocs during a relocatable link.
2867 void
2868 scan_relocatable_relocs(Symbol_table* symtab,
2869 Layout* layout,
2870 Sized_relobj_file<size, big_endian>* object,
2871 unsigned int data_shndx,
2872 unsigned int sh_type,
2873 const unsigned char* prelocs,
2874 size_t reloc_count,
2875 Output_section* output_section,
2876 bool needs_special_offset_handling,
2877 size_t local_symbol_count,
2878 const unsigned char* plocal_symbols,
2879 Relocatable_relocs*);
2880
4d625b70
CC
2881 // Scan the relocs for --emit-relocs.
2882 void
2883 emit_relocs_scan(Symbol_table* symtab,
2884 Layout* layout,
2885 Sized_relobj_file<size, big_endian>* object,
2886 unsigned int data_shndx,
2887 unsigned int sh_type,
2888 const unsigned char* prelocs,
2889 size_t reloc_count,
2890 Output_section* output_section,
2891 bool needs_special_offset_handling,
2892 size_t local_symbol_count,
2893 const unsigned char* plocal_syms,
2894 Relocatable_relocs* rr);
2895
053a4d68
JY
2896 // Relocate a section during a relocatable link.
2897 void
2898 relocate_relocs(
2899 const Relocate_info<size, big_endian>*,
2900 unsigned int sh_type,
2901 const unsigned char* prelocs,
2902 size_t reloc_count,
2903 Output_section* output_section,
2904 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
053a4d68
JY
2905 unsigned char* view,
2906 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
2907 section_size_type view_size,
2908 unsigned char* reloc_view,
2909 section_size_type reloc_view_size);
2910
3a531937
JY
2911 // Return the symbol index to use for a target specific relocation.
2912 // The only target specific relocation is R_AARCH64_TLSDESC for a
2913 // local symbol, which is an absolute reloc.
2914 unsigned int
2915 do_reloc_symbol_index(void*, unsigned int r_type) const
2916 {
2917 gold_assert(r_type == elfcpp::R_AARCH64_TLSDESC);
2918 return 0;
2919 }
2920
2921 // Return the addend to use for a target specific relocation.
7fa5525f
RÁE
2922 uint64_t
2923 do_reloc_addend(void* arg, unsigned int r_type, uint64_t addend) const;
3a531937 2924
9363c7c3
JY
2925 // Return the PLT section.
2926 uint64_t
2927 do_plt_address_for_global(const Symbol* gsym) const
2928 { return this->plt_section()->address_for_global(gsym); }
2929
2930 uint64_t
2931 do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
2932 { return this->plt_section()->address_for_local(relobj, symndx); }
2933
9726c3c1
HS
2934 // This function should be defined in targets that can use relocation
2935 // types to determine (implemented in local_reloc_may_be_function_pointer
2936 // and global_reloc_may_be_function_pointer)
2937 // if a function's pointer is taken. ICF uses this in safe mode to only
2938 // fold those functions whose pointer is defintely not taken.
2939 bool
2940 do_can_check_for_function_pointers() const
2941 { return true; }
2942
053a4d68
JY
2943 // Return the number of entries in the PLT.
2944 unsigned int
2945 plt_entry_count() const;
2946
2947 //Return the offset of the first non-reserved PLT entry.
2948 unsigned int
2949 first_plt_entry_offset() const;
2950
2951 // Return the size of each PLT entry.
2952 unsigned int
2953 plt_entry_size() const;
2954
83a01957
HS
2955 // Create a stub table.
2956 The_stub_table*
2957 new_stub_table(The_aarch64_input_section*);
2958
2959 // Create an aarch64 input section.
2960 The_aarch64_input_section*
2961 new_aarch64_input_section(Relobj*, unsigned int);
2962
2963 // Find an aarch64 input section instance for a given OBJ and SHNDX.
2964 The_aarch64_input_section*
2965 find_aarch64_input_section(Relobj*, unsigned int) const;
2966
2967 // Return the thread control block size.
8e33481e
HS
2968 unsigned int
2969 tcb_size() const { return This::TCB_SIZE; }
2970
83a01957
HS
2971 // Scan a section for stub generation.
2972 void
2973 scan_section_for_stubs(const Relocate_info<size, big_endian>*, unsigned int,
2974 const unsigned char*, size_t, Output_section*,
2975 bool, const unsigned char*,
2976 Address,
2977 section_size_type);
2978
2979 // Scan a relocation section for stub.
2980 template<int sh_type>
2981 void
2982 scan_reloc_section_for_stubs(
2983 const The_relocate_info* relinfo,
2984 const unsigned char* prelocs,
2985 size_t reloc_count,
2986 Output_section* output_section,
2987 bool needs_special_offset_handling,
2988 const unsigned char* view,
2989 Address view_address,
2990 section_size_type);
2991
2992 // Relocate a single stub.
2993 void
2994 relocate_stub(The_reloc_stub*, const Relocate_info<size, big_endian>*,
2995 Output_section*, unsigned char*, Address,
2996 section_size_type);
2997
2998 // Get the default AArch64 target.
2999 static This*
3000 current_target()
3001 {
3002 gold_assert(parameters->target().machine_code() == elfcpp::EM_AARCH64
3003 && parameters->target().get_size() == size
3004 && parameters->target().is_big_endian() == big_endian);
3005 return static_cast<This*>(parameters->sized_target<size, big_endian>());
3006 }
3007
5019d64a 3008
2f0c79aa 3009 // Scan erratum 843419 for a part of a section.
5019d64a
HS
3010 void
3011 scan_erratum_843419_span(
3012 AArch64_relobj<size, big_endian>*,
2f0c79aa
HS
3013 unsigned int,
3014 const section_size_type,
3015 const section_size_type,
3016 unsigned char*,
3017 Address);
3018
3019 // Scan erratum 835769 for a part of a section.
3020 void
3021 scan_erratum_835769_span(
3022 AArch64_relobj<size, big_endian>*,
3023 unsigned int,
5019d64a
HS
3024 const section_size_type,
3025 const section_size_type,
3026 unsigned char*,
3027 Address);
3028
9363c7c3
JY
3029 protected:
3030 void
3031 do_select_as_default_target()
3032 {
3033 gold_assert(aarch64_reloc_property_table == NULL);
3034 aarch64_reloc_property_table = new AArch64_reloc_property_table();
3035 }
3036
3a531937
JY
3037 // Add a new reloc argument, returning the index in the vector.
3038 size_t
3039 add_tlsdesc_info(Sized_relobj_file<size, big_endian>* object,
3040 unsigned int r_sym)
3041 {
3042 this->tlsdesc_reloc_info_.push_back(Tlsdesc_info(object, r_sym));
3043 return this->tlsdesc_reloc_info_.size() - 1;
3044 }
3045
9363c7c3 3046 virtual Output_data_plt_aarch64<size, big_endian>*
3a531937
JY
3047 do_make_data_plt(Layout* layout,
3048 Output_data_got_aarch64<size, big_endian>* got,
3049 Output_data_space* got_plt,
3050 Output_data_space* got_irelative)
9363c7c3 3051 {
3a531937
JY
3052 return new Output_data_plt_aarch64_standard<size, big_endian>(
3053 layout, got, got_plt, got_irelative);
9363c7c3
JY
3054 }
3055
83a01957
HS
3056
3057 // do_make_elf_object to override the same function in the base class.
3058 Object*
3059 do_make_elf_object(const std::string&, Input_file*, off_t,
3060 const elfcpp::Ehdr<size, big_endian>&);
3061
9363c7c3 3062 Output_data_plt_aarch64<size, big_endian>*
3a531937
JY
3063 make_data_plt(Layout* layout,
3064 Output_data_got_aarch64<size, big_endian>* got,
3065 Output_data_space* got_plt,
3066 Output_data_space* got_irelative)
9363c7c3 3067 {
3a531937 3068 return this->do_make_data_plt(layout, got, got_plt, got_irelative);
9363c7c3
JY
3069 }
3070
83a01957
HS
3071 // We only need to generate stubs, and hence perform relaxation if we are
3072 // not doing relocatable linking.
3073 virtual bool
3074 do_may_relax() const
3075 { return !parameters->options().relocatable(); }
3076
3077 // Relaxation hook. This is where we do stub generation.
3078 virtual bool
3079 do_relax(int, const Input_objects*, Symbol_table*, Layout*, const Task*);
3080
3081 void
3082 group_sections(Layout* layout,
3083 section_size_type group_size,
3084 bool stubs_always_after_branch,
3085 const Task* task);
3086
3087 void
3088 scan_reloc_for_stub(const The_relocate_info*, unsigned int,
3089 const Sized_symbol<size>*, unsigned int,
3090 const Symbol_value<size>*,
3091 typename elfcpp::Elf_types<size>::Elf_Swxword,
3092 Address Elf_Addr);
3093
3094 // Make an output section.
3095 Output_section*
3096 do_make_output_section(const char* name, elfcpp::Elf_Word type,
3097 elfcpp::Elf_Xword flags)
3098 { return new The_aarch64_output_section(name, type, flags); }
3099
053a4d68
JY
3100 private:
3101 // The class which scans relocations.
3102 class Scan
3103 {
3104 public:
3105 Scan()
3106 : issued_non_pic_error_(false)
3107 { }
3108
053a4d68
JY
3109 inline void
3110 local(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
3111 Sized_relobj_file<size, big_endian>* object,
3112 unsigned int data_shndx,
3113 Output_section* output_section,
3114 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
3115 const elfcpp::Sym<size, big_endian>& lsym,
3116 bool is_discarded);
3117
3118 inline void
3119 global(Symbol_table* symtab, Layout* layout, Target_aarch64* target,
3120 Sized_relobj_file<size, big_endian>* object,
3121 unsigned int data_shndx,
3122 Output_section* output_section,
3123 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
3124 Symbol* gsym);
3125
3126 inline bool
3127 local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
9363c7c3
JY
3128 Target_aarch64<size, big_endian>* ,
3129 Sized_relobj_file<size, big_endian>* ,
3130 unsigned int ,
3131 Output_section* ,
3132 const elfcpp::Rela<size, big_endian>& ,
3133 unsigned int r_type,
3134 const elfcpp::Sym<size, big_endian>&);
053a4d68
JY
3135
3136 inline bool
3137 global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
9363c7c3
JY
3138 Target_aarch64<size, big_endian>* ,
3139 Sized_relobj_file<size, big_endian>* ,
3140 unsigned int ,
3141 Output_section* ,
3142 const elfcpp::Rela<size, big_endian>& ,
3143 unsigned int r_type,
3144 Symbol* gsym);
053a4d68
JY
3145
3146 private:
3147 static void
3148 unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
3149 unsigned int r_type);
3150
3151 static void
3152 unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
3153 unsigned int r_type, Symbol*);
3154
3155 inline bool
3156 possible_function_pointer_reloc(unsigned int r_type);
3157
3158 void
3159 check_non_pic(Relobj*, unsigned int r_type);
3160
9726c3c1
HS
3161 bool
3162 reloc_needs_plt_for_ifunc(Sized_relobj_file<size, big_endian>*,
3163 unsigned int r_type);
3164
053a4d68
JY
3165 // Whether we have issued an error about a non-PIC compilation.
3166 bool issued_non_pic_error_;
3167 };
3168
3169 // The class which implements relocation.
3170 class Relocate
3171 {
3172 public:
3173 Relocate()
3a531937 3174 : skip_call_tls_get_addr_(false)
053a4d68
JY
3175 { }
3176
3177 ~Relocate()
3178 { }
3179
3180 // Do a relocation. Return false if the caller should not issue
3181 // any warnings about this relocation.
3182 inline bool
91a65d2f
AM
3183 relocate(const Relocate_info<size, big_endian>*, unsigned int,
3184 Target_aarch64*, Output_section*, size_t, const unsigned char*,
3185 const Sized_symbol<size>*, const Symbol_value<size>*,
053a4d68
JY
3186 unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
3187 section_size_type);
3188
8e33481e 3189 private:
83a01957
HS
3190 inline typename AArch64_relocate_functions<size, big_endian>::Status
3191 relocate_tls(const Relocate_info<size, big_endian>*,
8e33481e
HS
3192 Target_aarch64<size, big_endian>*,
3193 size_t,
3194 const elfcpp::Rela<size, big_endian>&,
3195 unsigned int r_type, const Sized_symbol<size>*,
3196 const Symbol_value<size>*,
3197 unsigned char*,
3198 typename elfcpp::Elf_types<size>::Elf_Addr);
3199
83a01957 3200 inline typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 3201 tls_gd_to_le(
83a01957 3202 const Relocate_info<size, big_endian>*,
3a531937
JY
3203 Target_aarch64<size, big_endian>*,
3204 const elfcpp::Rela<size, big_endian>&,
3205 unsigned int,
3206 unsigned char*,
3207 const Symbol_value<size>*);
3208
9726c3c1
HS
3209 inline typename AArch64_relocate_functions<size, big_endian>::Status
3210 tls_ld_to_le(
3211 const Relocate_info<size, big_endian>*,
3212 Target_aarch64<size, big_endian>*,
3213 const elfcpp::Rela<size, big_endian>&,
3214 unsigned int,
3215 unsigned char*,
3216 const Symbol_value<size>*);
3217
83a01957 3218 inline typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 3219 tls_ie_to_le(
83a01957 3220 const Relocate_info<size, big_endian>*,
3a531937
JY
3221 Target_aarch64<size, big_endian>*,
3222 const elfcpp::Rela<size, big_endian>&,
3223 unsigned int,
3224 unsigned char*,
3225 const Symbol_value<size>*);
3226
83a01957 3227 inline typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 3228 tls_desc_gd_to_le(
83a01957 3229 const Relocate_info<size, big_endian>*,
3a531937
JY
3230 Target_aarch64<size, big_endian>*,
3231 const elfcpp::Rela<size, big_endian>&,
3232 unsigned int,
3233 unsigned char*,
3234 const Symbol_value<size>*);
3235
83a01957 3236 inline typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 3237 tls_desc_gd_to_ie(
83a01957 3238 const Relocate_info<size, big_endian>*,
3a531937
JY
3239 Target_aarch64<size, big_endian>*,
3240 const elfcpp::Rela<size, big_endian>&,
3241 unsigned int,
3242 unsigned char*,
3243 const Symbol_value<size>*,
3244 typename elfcpp::Elf_types<size>::Elf_Addr,
3245 typename elfcpp::Elf_types<size>::Elf_Addr);
3246
3247 bool skip_call_tls_get_addr_;
3248
8e33481e 3249 }; // End of class Relocate
053a4d68 3250
053a4d68
JY
3251 // Adjust TLS relocation type based on the options and whether this
3252 // is a local symbol.
3253 static tls::Tls_optimization
3254 optimize_tls_reloc(bool is_final, int r_type);
3255
3256 // Get the GOT section, creating it if necessary.
3257 Output_data_got_aarch64<size, big_endian>*
3258 got_section(Symbol_table*, Layout*);
3259
3260 // Get the GOT PLT section.
3261 Output_data_space*
3262 got_plt_section() const
3263 {
3264 gold_assert(this->got_plt_ != NULL);
3265 return this->got_plt_;
3266 }
3267
3a531937
JY
3268 // Get the GOT section for TLSDESC entries.
3269 Output_data_got<size, big_endian>*
3270 got_tlsdesc_section() const
3271 {
3272 gold_assert(this->got_tlsdesc_ != NULL);
3273 return this->got_tlsdesc_;
3274 }
3275
053a4d68
JY
3276 // Create the PLT section.
3277 void
3278 make_plt_section(Symbol_table* symtab, Layout* layout);
3279
3280 // Create a PLT entry for a global symbol.
3281 void
3282 make_plt_entry(Symbol_table*, Layout*, Symbol*);
3283
3a531937
JY
3284 // Create a PLT entry for a local STT_GNU_IFUNC symbol.
3285 void
3286 make_local_ifunc_plt_entry(Symbol_table*, Layout*,
3287 Sized_relobj_file<size, big_endian>* relobj,
3288 unsigned int local_sym_index);
3289
3290 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
3291 void
3292 define_tls_base_symbol(Symbol_table*, Layout*);
3293
3294 // Create the reserved PLT and GOT entries for the TLS descriptor resolver.
3295 void
3296 reserve_tlsdesc_entries(Symbol_table* symtab, Layout* layout);
3297
3298 // Create a GOT entry for the TLS module index.
3299 unsigned int
3300 got_mod_index_entry(Symbol_table* symtab, Layout* layout,
3301 Sized_relobj_file<size, big_endian>* object);
3302
053a4d68
JY
3303 // Get the PLT section.
3304 Output_data_plt_aarch64<size, big_endian>*
3305 plt_section() const
3306 {
3307 gold_assert(this->plt_ != NULL);
3308 return this->plt_;
3309 }
3310
0ef3814f
HS
3311 // Helper method to create erratum stubs for ST_E_843419 and ST_E_835769. For
3312 // ST_E_843419, we need an additional field for adrp offset.
2f0c79aa
HS
3313 void create_erratum_stub(
3314 AArch64_relobj<size, big_endian>* relobj,
3315 unsigned int shndx,
3316 section_size_type erratum_insn_offset,
3317 Address erratum_address,
3318 typename Insn_utilities::Insntype erratum_insn,
0ef3814f
HS
3319 int erratum_type,
3320 unsigned int e843419_adrp_offset=0);
2f0c79aa 3321
5019d64a
HS
3322 // Return whether this is a 3-insn erratum sequence.
3323 bool is_erratum_843419_sequence(
3324 typename elfcpp::Swap<32,big_endian>::Valtype insn1,
3325 typename elfcpp::Swap<32,big_endian>::Valtype insn2,
3326 typename elfcpp::Swap<32,big_endian>::Valtype insn3);
3327
2f0c79aa
HS
3328 // Return whether this is a 835769 sequence.
3329 // (Similarly implemented as in elfnn-aarch64.c.)
3330 bool is_erratum_835769_sequence(
3331 typename elfcpp::Swap<32,big_endian>::Valtype,
3332 typename elfcpp::Swap<32,big_endian>::Valtype);
3333
053a4d68
JY
3334 // Get the dynamic reloc section, creating it if necessary.
3335 Reloc_section*
3336 rela_dyn_section(Layout*);
3337
3a531937
JY
3338 // Get the section to use for TLSDESC relocations.
3339 Reloc_section*
3340 rela_tlsdesc_section(Layout*) const;
3341
3342 // Get the section to use for IRELATIVE relocations.
3343 Reloc_section*
3344 rela_irelative_section(Layout*);
3345
053a4d68
JY
3346 // Add a potential copy relocation.
3347 void
3348 copy_reloc(Symbol_table* symtab, Layout* layout,
3349 Sized_relobj_file<size, big_endian>* object,
3350 unsigned int shndx, Output_section* output_section,
3351 Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
3352 {
859d7987 3353 unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
053a4d68
JY
3354 this->copy_relocs_.copy_reloc(symtab, layout,
3355 symtab->get_sized_symbol<size>(sym),
3356 object, shndx, output_section,
859d7987
CC
3357 r_type, reloc.get_r_offset(),
3358 reloc.get_r_addend(),
3359 this->rela_dyn_section(layout));
053a4d68
JY
3360 }
3361
3362 // Information about this specific target which we pass to the
3363 // general Target structure.
3364 static const Target::Target_info aarch64_info;
3365
3366 // The types of GOT entries needed for this platform.
3367 // These values are exposed to the ABI in an incremental link.
3368 // Do not renumber existing values without changing the version
3369 // number of the .gnu_incremental_inputs section.
3370 enum Got_type
3371 {
3372 GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
3373 GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset
3374 GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair
3375 GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair
3376 };
3377
3a531937
JY
3378 // This type is used as the argument to the target specific
3379 // relocation routines. The only target specific reloc is
3380 // R_AARCh64_TLSDESC against a local symbol.
3381 struct Tlsdesc_info
3382 {
3383 Tlsdesc_info(Sized_relobj_file<size, big_endian>* a_object,
3384 unsigned int a_r_sym)
3385 : object(a_object), r_sym(a_r_sym)
3386 { }
3387
3388 // The object in which the local symbol is defined.
3389 Sized_relobj_file<size, big_endian>* object;
3390 // The local symbol index in the object.
3391 unsigned int r_sym;
3392 };
3393
053a4d68
JY
3394 // The GOT section.
3395 Output_data_got_aarch64<size, big_endian>* got_;
3396 // The PLT section.
3397 Output_data_plt_aarch64<size, big_endian>* plt_;
3398 // The GOT PLT section.
3399 Output_data_space* got_plt_;
3a531937
JY
3400 // The GOT section for IRELATIVE relocations.
3401 Output_data_space* got_irelative_;
3402 // The GOT section for TLSDESC relocations.
3403 Output_data_got<size, big_endian>* got_tlsdesc_;
053a4d68
JY
3404 // The _GLOBAL_OFFSET_TABLE_ symbol.
3405 Symbol* global_offset_table_;
3406 // The dynamic reloc section.
3407 Reloc_section* rela_dyn_;
3a531937
JY
3408 // The section to use for IRELATIVE relocs.
3409 Reloc_section* rela_irelative_;
053a4d68
JY
3410 // Relocs saved to avoid a COPY reloc.
3411 Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
3a531937
JY
3412 // Offset of the GOT entry for the TLS module index.
3413 unsigned int got_mod_index_offset_;
3414 // We handle R_AARCH64_TLSDESC against a local symbol as a target
3415 // specific relocation. Here we store the object and local symbol
3416 // index for the relocation.
3417 std::vector<Tlsdesc_info> tlsdesc_reloc_info_;
3418 // True if the _TLS_MODULE_BASE_ symbol has been defined.
3419 bool tls_base_symbol_defined_;
83a01957
HS
3420 // List of stub_tables
3421 Stub_table_list stub_tables_;
0bf32ea9
JY
3422 // Actual stub group size
3423 section_size_type stub_group_size_;
83a01957 3424 AArch64_input_section_map aarch64_input_section_map_;
8e33481e 3425}; // End of Target_aarch64
053a4d68 3426
3a531937 3427
053a4d68
JY
3428template<>
3429const Target::Target_info Target_aarch64<64, false>::aarch64_info =
3430{
3431 64, // size
3432 false, // is_big_endian
3433 elfcpp::EM_AARCH64, // machine_code
3434 false, // has_make_symbol
3435 false, // has_resolve
3436 false, // has_code_fill
3437 true, // is_default_stack_executable
9726c3c1 3438 true, // can_icf_inline_merge_sections
053a4d68
JY
3439 '\0', // wrap_char
3440 "/lib/ld.so.1", // program interpreter
3441 0x400000, // default_text_segment_address
3b0357da 3442 0x10000, // abi_pagesize (overridable by -z max-page-size)
053a4d68
JY
3443 0x1000, // common_pagesize (overridable by -z common-page-size)
3444 false, // isolate_execinstr
3445 0, // rosegment_gap
3446 elfcpp::SHN_UNDEF, // small_common_shndx
3447 elfcpp::SHN_UNDEF, // large_common_shndx
3448 0, // small_common_section_flags
3449 0, // large_common_section_flags
3450 NULL, // attributes_section
3451 NULL, // attributes_vendor
8d9743bd
MK
3452 "_start", // entry_symbol_name
3453 32, // hash_entry_size
053a4d68
JY
3454};
3455
3456template<>
3457const Target::Target_info Target_aarch64<32, false>::aarch64_info =
3458{
3459 32, // size
3460 false, // is_big_endian
3461 elfcpp::EM_AARCH64, // machine_code
3462 false, // has_make_symbol
3463 false, // has_resolve
3464 false, // has_code_fill
3465 true, // is_default_stack_executable
3466 false, // can_icf_inline_merge_sections
3467 '\0', // wrap_char
3468 "/lib/ld.so.1", // program interpreter
3469 0x400000, // default_text_segment_address
3b0357da 3470 0x10000, // abi_pagesize (overridable by -z max-page-size)
053a4d68
JY
3471 0x1000, // common_pagesize (overridable by -z common-page-size)
3472 false, // isolate_execinstr
3473 0, // rosegment_gap
3474 elfcpp::SHN_UNDEF, // small_common_shndx
3475 elfcpp::SHN_UNDEF, // large_common_shndx
3476 0, // small_common_section_flags
3477 0, // large_common_section_flags
3478 NULL, // attributes_section
3479 NULL, // attributes_vendor
8d9743bd
MK
3480 "_start", // entry_symbol_name
3481 32, // hash_entry_size
053a4d68
JY
3482};
3483
3484template<>
3485const Target::Target_info Target_aarch64<64, true>::aarch64_info =
3486{
3487 64, // size
3488 true, // is_big_endian
3489 elfcpp::EM_AARCH64, // machine_code
3490 false, // has_make_symbol
3491 false, // has_resolve
3492 false, // has_code_fill
3493 true, // is_default_stack_executable
9726c3c1 3494 true, // can_icf_inline_merge_sections
053a4d68
JY
3495 '\0', // wrap_char
3496 "/lib/ld.so.1", // program interpreter
3497 0x400000, // default_text_segment_address
3b0357da 3498 0x10000, // abi_pagesize (overridable by -z max-page-size)
053a4d68
JY
3499 0x1000, // common_pagesize (overridable by -z common-page-size)
3500 false, // isolate_execinstr
3501 0, // rosegment_gap
3502 elfcpp::SHN_UNDEF, // small_common_shndx
3503 elfcpp::SHN_UNDEF, // large_common_shndx
3504 0, // small_common_section_flags
3505 0, // large_common_section_flags
3506 NULL, // attributes_section
3507 NULL, // attributes_vendor
8d9743bd
MK
3508 "_start", // entry_symbol_name
3509 32, // hash_entry_size
053a4d68
JY
3510};
3511
3512template<>
3513const Target::Target_info Target_aarch64<32, true>::aarch64_info =
3514{
3515 32, // size
3516 true, // is_big_endian
3517 elfcpp::EM_AARCH64, // machine_code
3518 false, // has_make_symbol
3519 false, // has_resolve
3520 false, // has_code_fill
3521 true, // is_default_stack_executable
3522 false, // can_icf_inline_merge_sections
3523 '\0', // wrap_char
3524 "/lib/ld.so.1", // program interpreter
3525 0x400000, // default_text_segment_address
3b0357da 3526 0x10000, // abi_pagesize (overridable by -z max-page-size)
053a4d68
JY
3527 0x1000, // common_pagesize (overridable by -z common-page-size)
3528 false, // isolate_execinstr
3529 0, // rosegment_gap
3530 elfcpp::SHN_UNDEF, // small_common_shndx
3531 elfcpp::SHN_UNDEF, // large_common_shndx
3532 0, // small_common_section_flags
3533 0, // large_common_section_flags
3534 NULL, // attributes_section
3535 NULL, // attributes_vendor
8d9743bd
MK
3536 "_start", // entry_symbol_name
3537 32, // hash_entry_size
053a4d68
JY
3538};
3539
3540// Get the GOT section, creating it if necessary.
3541
3542template<int size, bool big_endian>
3543Output_data_got_aarch64<size, big_endian>*
3544Target_aarch64<size, big_endian>::got_section(Symbol_table* symtab,
9363c7c3 3545 Layout* layout)
053a4d68
JY
3546{
3547 if (this->got_ == NULL)
3548 {
3549 gold_assert(symtab != NULL && layout != NULL);
3550
3551 // When using -z now, we can treat .got.plt as a relro section.
3552 // Without -z now, it is modified after program startup by lazy
3553 // PLT relocations.
3554 bool is_got_plt_relro = parameters->options().now();
3555 Output_section_order got_order = (is_got_plt_relro
3556 ? ORDER_RELRO
3557 : ORDER_RELRO_LAST);
3558 Output_section_order got_plt_order = (is_got_plt_relro
3559 ? ORDER_RELRO
3560 : ORDER_NON_RELRO_FIRST);
3561
3562 // Layout of .got and .got.plt sections.
3563 // .got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
3564 // ...
3565 // .gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
3566 // .gotplt[1] reserved for ld.so (resolver)
3567 // .gotplt[2] reserved
3568
3569 // Generate .got section.
3570 this->got_ = new Output_data_got_aarch64<size, big_endian>(symtab,
9363c7c3 3571 layout);
053a4d68 3572 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
9363c7c3
JY
3573 (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
3574 this->got_, got_order, true);
053a4d68
JY
3575 // The first word of GOT is reserved for the address of .dynamic.
3576 // We put 0 here now. The value will be replaced later in
3577 // Output_data_got_aarch64::do_write.
3578 this->got_->add_constant(0);
3579
3580 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
3581 // _GLOBAL_OFFSET_TABLE_ value points to the start of the .got section,
3582 // even if there is a .got.plt section.
3583 this->global_offset_table_ =
9363c7c3
JY
3584 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
3585 Symbol_table::PREDEFINED,
3586 this->got_,
3587 0, 0, elfcpp::STT_OBJECT,
3588 elfcpp::STB_LOCAL,
3589 elfcpp::STV_HIDDEN, 0,
3590 false, false);
053a4d68
JY
3591
3592 // Generate .got.plt section.
3593 this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT");
3594 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
9363c7c3
JY
3595 (elfcpp::SHF_ALLOC
3596 | elfcpp::SHF_WRITE),
3597 this->got_plt_, got_plt_order,
3598 is_got_plt_relro);
053a4d68
JY
3599
3600 // The first three entries are reserved.
9363c7c3
JY
3601 this->got_plt_->set_current_data_size(
3602 AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
053a4d68 3603
3a531937
JY
3604 // If there are any IRELATIVE relocations, they get GOT entries
3605 // in .got.plt after the jump slot entries.
3606 this->got_irelative_ = new Output_data_space(size / 8,
3607 "** GOT IRELATIVE PLT");
3608 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
3609 (elfcpp::SHF_ALLOC
3610 | elfcpp::SHF_WRITE),
3611 this->got_irelative_,
3612 got_plt_order,
3613 is_got_plt_relro);
3614
3615 // If there are any TLSDESC relocations, they get GOT entries in
3616 // .got.plt after the jump slot and IRELATIVE entries.
3617 this->got_tlsdesc_ = new Output_data_got<size, big_endian>();
3618 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
3619 (elfcpp::SHF_ALLOC
3620 | elfcpp::SHF_WRITE),
3621 this->got_tlsdesc_,
3622 got_plt_order,
3623 is_got_plt_relro);
3624
053a4d68 3625 if (!is_got_plt_relro)
9363c7c3
JY
3626 {
3627 // Those bytes can go into the relro segment.
3628 layout->increase_relro(
3629 AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
3630 }
053a4d68
JY
3631
3632 }
3633 return this->got_;
3634}
3635
3636// Get the dynamic reloc section, creating it if necessary.
3637
3638template<int size, bool big_endian>
3639typename Target_aarch64<size, big_endian>::Reloc_section*
3640Target_aarch64<size, big_endian>::rela_dyn_section(Layout* layout)
3641{
3642 if (this->rela_dyn_ == NULL)
3643 {
3644 gold_assert(layout != NULL);
3645 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
3646 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
3647 elfcpp::SHF_ALLOC, this->rela_dyn_,
3648 ORDER_DYNAMIC_RELOCS, false);
3649 }
3650 return this->rela_dyn_;
3651}
3652
3a531937
JY
3653// Get the section to use for IRELATIVE relocs, creating it if
3654// necessary. These go in .rela.dyn, but only after all other dynamic
3655// relocations. They need to follow the other dynamic relocations so
3656// that they can refer to global variables initialized by those
3657// relocs.
3658
3659template<int size, bool big_endian>
3660typename Target_aarch64<size, big_endian>::Reloc_section*
3661Target_aarch64<size, big_endian>::rela_irelative_section(Layout* layout)
3662{
3663 if (this->rela_irelative_ == NULL)
3664 {
3665 // Make sure we have already created the dynamic reloc section.
3666 this->rela_dyn_section(layout);
3667 this->rela_irelative_ = new Reloc_section(false);
3668 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
3669 elfcpp::SHF_ALLOC, this->rela_irelative_,
3670 ORDER_DYNAMIC_RELOCS, false);
3671 gold_assert(this->rela_dyn_->output_section()
3672 == this->rela_irelative_->output_section());
3673 }
3674 return this->rela_irelative_;
3675}
3676
3677
83a01957
HS
3678// do_make_elf_object to override the same function in the base class. We need
3679// to use a target-specific sub-class of Sized_relobj_file<size, big_endian> to
3680// store backend specific information. Hence we need to have our own ELF object
3681// creation.
3682
3683template<int size, bool big_endian>
3684Object*
3685Target_aarch64<size, big_endian>::do_make_elf_object(
3686 const std::string& name,
3687 Input_file* input_file,
3688 off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
3689{
3690 int et = ehdr.get_e_type();
3691 // ET_EXEC files are valid input for --just-symbols/-R,
3692 // and we treat them as relocatable objects.
3693 if (et == elfcpp::ET_EXEC && input_file->just_symbols())
3694 return Sized_target<size, big_endian>::do_make_elf_object(
3695 name, input_file, offset, ehdr);
3696 else if (et == elfcpp::ET_REL)
3697 {
3698 AArch64_relobj<size, big_endian>* obj =
3699 new AArch64_relobj<size, big_endian>(name, input_file, offset, ehdr);
3700 obj->setup();
3701 return obj;
3702 }
3703 else if (et == elfcpp::ET_DYN)
3704 {
3705 // Keep base implementation.
3706 Sized_dynobj<size, big_endian>* obj =
3707 new Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr);
3708 obj->setup();
3709 return obj;
3710 }
3711 else
3712 {
3713 gold_error(_("%s: unsupported ELF file type %d"),
3714 name.c_str(), et);
3715 return NULL;
3716 }
3717}
3718
3719
3720// Scan a relocation for stub generation.
3721
3722template<int size, bool big_endian>
3723void
3724Target_aarch64<size, big_endian>::scan_reloc_for_stub(
3725 const Relocate_info<size, big_endian>* relinfo,
3726 unsigned int r_type,
3727 const Sized_symbol<size>* gsym,
3728 unsigned int r_sym,
3729 const Symbol_value<size>* psymval,
3730 typename elfcpp::Elf_types<size>::Elf_Swxword addend,
3731 Address address)
3732{
3733 const AArch64_relobj<size, big_endian>* aarch64_relobj =
3734 static_cast<AArch64_relobj<size, big_endian>*>(relinfo->object);
3735
3736 Symbol_value<size> symval;
3737 if (gsym != NULL)
3738 {
3739 const AArch64_reloc_property* arp = aarch64_reloc_property_table->
3740 get_reloc_property(r_type);
3741 if (gsym->use_plt_offset(arp->reference_flags()))
3742 {
3743 // This uses a PLT, change the symbol value.
3744 symval.set_output_value(this->plt_section()->address()
3745 + gsym->plt_offset());
3746 psymval = &symval;
3747 }
3748 else if (gsym->is_undefined())
81b6fe3b
EC
3749 {
3750 // There is no need to generate a stub symbol is undefined.
3751 gold_debug(DEBUG_TARGET,
3752 "stub: not creating a stub for undefined symbol %s in file %s",
3753 gsym->name(), aarch64_relobj->name().c_str());
3754 return;
3755 }
83a01957
HS
3756 }
3757
3758 // Get the symbol value.
3759 typename Symbol_value<size>::Value value = psymval->value(aarch64_relobj, 0);
3760
3761 // Owing to pipelining, the PC relative branches below actually skip
3762 // two instructions when the branch offset is 0.
3763 Address destination = static_cast<Address>(-1);
3764 switch (r_type)
3765 {
3766 case elfcpp::R_AARCH64_CALL26:
3767 case elfcpp::R_AARCH64_JUMP26:
3768 destination = value + addend;
3769 break;
3770 default:
9726c3c1 3771 gold_unreachable();
83a01957
HS
3772 }
3773
a48d0c12 3774 int stub_type = The_reloc_stub::
83a01957 3775 stub_type_for_reloc(r_type, address, destination);
a48d0c12 3776 if (stub_type == ST_NONE)
5019d64a 3777 return;
83a01957
HS
3778
3779 The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx);
3780 gold_assert(stub_table != NULL);
3781
3782 The_reloc_stub_key key(stub_type, gsym, aarch64_relobj, r_sym, addend);
3783 The_reloc_stub* stub = stub_table->find_reloc_stub(key);
3784 if (stub == NULL)
3785 {
3786 stub = new The_reloc_stub(stub_type);
3787 stub_table->add_reloc_stub(stub, key);
3788 }
3789 stub->set_destination_address(destination);
3790} // End of Target_aarch64::scan_reloc_for_stub
3791
3792
3793// This function scans a relocation section for stub generation.
3794// The template parameter Relocate must be a class type which provides
3795// a single function, relocate(), which implements the machine
3796// specific part of a relocation.
3797
3798// BIG_ENDIAN is the endianness of the data. SH_TYPE is the section type:
3799// SHT_REL or SHT_RELA.
3800
3801// PRELOCS points to the relocation data. RELOC_COUNT is the number
3802// of relocs. OUTPUT_SECTION is the output section.
3803// NEEDS_SPECIAL_OFFSET_HANDLING is true if input offsets need to be
3804// mapped to output offsets.
3805
3806// VIEW is the section data, VIEW_ADDRESS is its memory address, and
3807// VIEW_SIZE is the size. These refer to the input section, unless
3808// NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to
3809// the output section.
3810
3811template<int size, bool big_endian>
3812template<int sh_type>
3813void inline
3814Target_aarch64<size, big_endian>::scan_reloc_section_for_stubs(
3815 const Relocate_info<size, big_endian>* relinfo,
3816 const unsigned char* prelocs,
3817 size_t reloc_count,
3818 Output_section* /*output_section*/,
3819 bool /*needs_special_offset_handling*/,
3820 const unsigned char* /*view*/,
3821 Address view_address,
3822 section_size_type)
3823{
3824 typedef typename Reloc_types<sh_type,size,big_endian>::Reloc Reltype;
3825
3826 const int reloc_size =
3827 Reloc_types<sh_type,size,big_endian>::reloc_size;
3828 AArch64_relobj<size, big_endian>* object =
3829 static_cast<AArch64_relobj<size, big_endian>*>(relinfo->object);
3830 unsigned int local_count = object->local_symbol_count();
3831
3832 gold::Default_comdat_behavior default_comdat_behavior;
3833 Comdat_behavior comdat_behavior = CB_UNDETERMINED;
3834
3835 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
3836 {
3837 Reltype reloc(prelocs);
3838 typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
3839 unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
3840 unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
3841 if (r_type != elfcpp::R_AARCH64_CALL26
3842 && r_type != elfcpp::R_AARCH64_JUMP26)
3843 continue;
3844
3845 section_offset_type offset =
3846 convert_to_section_size_type(reloc.get_r_offset());
3847
3848 // Get the addend.
3849 typename elfcpp::Elf_types<size>::Elf_Swxword addend =
3850 reloc.get_r_addend();
3851
3852 const Sized_symbol<size>* sym;
3853 Symbol_value<size> symval;
3854 const Symbol_value<size> *psymval;
3855 bool is_defined_in_discarded_section;
3856 unsigned int shndx;
3857 if (r_sym < local_count)
3858 {
3859 sym = NULL;
3860 psymval = object->local_symbol(r_sym);
3861
3862 // If the local symbol belongs to a section we are discarding,
3863 // and that section is a debug section, try to find the
3864 // corresponding kept section and map this symbol to its
3865 // counterpart in the kept section. The symbol must not
3866 // correspond to a section we are folding.
3867 bool is_ordinary;
3868 shndx = psymval->input_shndx(&is_ordinary);
3869 is_defined_in_discarded_section =
3870 (is_ordinary
3871 && shndx != elfcpp::SHN_UNDEF
3872 && !object->is_section_included(shndx)
3873 && !relinfo->symtab->is_section_folded(object, shndx));
3874
3875 // We need to compute the would-be final value of this local
3876 // symbol.
3877 if (!is_defined_in_discarded_section)
3878 {
3879 typedef Sized_relobj_file<size, big_endian> ObjType;
0f125432
CC
3880 if (psymval->is_section_symbol())
3881 symval.set_is_section_symbol();
83a01957
HS
3882 typename ObjType::Compute_final_local_value_status status =
3883 object->compute_final_local_value(r_sym, psymval, &symval,
3884 relinfo->symtab);
3885 if (status == ObjType::CFLV_OK)
3886 {
3887 // Currently we cannot handle a branch to a target in
3888 // a merged section. If this is the case, issue an error
3889 // and also free the merge symbol value.
3890 if (!symval.has_output_value())
3891 {
3892 const std::string& section_name =
3893 object->section_name(shndx);
3894 object->error(_("cannot handle branch to local %u "
3895 "in a merged section %s"),
3896 r_sym, section_name.c_str());
3897 }
3898 psymval = &symval;
3899 }
3900 else
3901 {
3902 // We cannot determine the final value.
3903 continue;
3904 }
3905 }
3906 }
3907 else
3908 {
3909 const Symbol* gsym;
3910 gsym = object->global_symbol(r_sym);
3911 gold_assert(gsym != NULL);
3912 if (gsym->is_forwarder())
3913 gsym = relinfo->symtab->resolve_forwards(gsym);
3914
3915 sym = static_cast<const Sized_symbol<size>*>(gsym);
3916 if (sym->has_symtab_index() && sym->symtab_index() != -1U)
3917 symval.set_output_symtab_index(sym->symtab_index());
3918 else
3919 symval.set_no_output_symtab_entry();
3920
3921 // We need to compute the would-be final value of this global
3922 // symbol.
3923 const Symbol_table* symtab = relinfo->symtab;
3924 const Sized_symbol<size>* sized_symbol =
3925 symtab->get_sized_symbol<size>(gsym);
3926 Symbol_table::Compute_final_value_status status;
3927 typename elfcpp::Elf_types<size>::Elf_Addr value =
3928 symtab->compute_final_value<size>(sized_symbol, &status);
3929
3930 // Skip this if the symbol has not output section.
3931 if (status == Symbol_table::CFVS_NO_OUTPUT_SECTION)
3932 continue;
3933 symval.set_output_value(value);
3934
3935 if (gsym->type() == elfcpp::STT_TLS)
3936 symval.set_is_tls_symbol();
3937 else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
3938 symval.set_is_ifunc_symbol();
3939 psymval = &symval;
3940
3941 is_defined_in_discarded_section =
3942 (gsym->is_defined_in_discarded_section()
3943 && gsym->is_undefined());
3944 shndx = 0;
3945 }
3946
3947 Symbol_value<size> symval2;
3948 if (is_defined_in_discarded_section)
3949 {
3950 if (comdat_behavior == CB_UNDETERMINED)
3951 {
3952 std::string name = object->section_name(relinfo->data_shndx);
3953 comdat_behavior = default_comdat_behavior.get(name.c_str());
3954 }
3955 if (comdat_behavior == CB_PRETEND)
3956 {
3957 bool found;
3958 typename elfcpp::Elf_types<size>::Elf_Addr value =
3959 object->map_to_kept_section(shndx, &found);
3960 if (found)
3961 symval2.set_output_value(value + psymval->input_value());
3962 else
3963 symval2.set_output_value(0);
3964 }
3965 else
3966 {
3967 if (comdat_behavior == CB_WARNING)
3968 gold_warning_at_location(relinfo, i, offset,
3969 _("relocation refers to discarded "
3970 "section"));
3971 symval2.set_output_value(0);
3972 }
3973 symval2.set_no_output_symtab_entry();
3974 psymval = &symval2;
3975 }
3976
3977 // If symbol is a section symbol, we don't know the actual type of
3978 // destination. Give up.
3979 if (psymval->is_section_symbol())
3980 continue;
3981
3982 this->scan_reloc_for_stub(relinfo, r_type, sym, r_sym, psymval,
3983 addend, view_address + offset);
3984 } // End of iterating relocs in a section
3985} // End of Target_aarch64::scan_reloc_section_for_stubs
3986
3987
3988// Scan an input section for stub generation.
3989
3990template<int size, bool big_endian>
3991void
3992Target_aarch64<size, big_endian>::scan_section_for_stubs(
3993 const Relocate_info<size, big_endian>* relinfo,
3994 unsigned int sh_type,
3995 const unsigned char* prelocs,
3996 size_t reloc_count,
3997 Output_section* output_section,
3998 bool needs_special_offset_handling,
3999 const unsigned char* view,
4000 Address view_address,
4001 section_size_type view_size)
4002{
4003 gold_assert(sh_type == elfcpp::SHT_RELA);
4004 this->scan_reloc_section_for_stubs<elfcpp::SHT_RELA>(
4005 relinfo,
4006 prelocs,
4007 reloc_count,
4008 output_section,
4009 needs_special_offset_handling,
4010 view,
4011 view_address,
4012 view_size);
4013}
4014
4015
4016// Relocate a single stub.
4017
4018template<int size, bool big_endian>
4019void Target_aarch64<size, big_endian>::
4020relocate_stub(The_reloc_stub* stub,
4021 const The_relocate_info*,
4022 Output_section*,
4023 unsigned char* view,
4024 Address address,
4025 section_size_type)
4026{
4027 typedef AArch64_relocate_functions<size, big_endian> The_reloc_functions;
4028 typedef typename The_reloc_functions::Status The_reloc_functions_status;
4029 typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
4030
4031 Insntype* ip = reinterpret_cast<Insntype*>(view);
a48d0c12
HS
4032 int insn_number = stub->insn_num();
4033 const uint32_t* insns = stub->insns();
83a01957
HS
4034 // Check the insns are really those stub insns.
4035 for (int i = 0; i < insn_number; ++i)
4036 {
4037 Insntype insn = elfcpp::Swap<32,big_endian>::readval(ip + i);
a48d0c12 4038 gold_assert(((uint32_t)insn == insns[i]));
83a01957
HS
4039 }
4040
4041 Address dest = stub->destination_address();
4042
a48d0c12 4043 switch(stub->type())
83a01957 4044 {
a48d0c12 4045 case ST_ADRP_BRANCH:
83a01957
HS
4046 {
4047 // 1st reloc is ADR_PREL_PG_HI21
4048 The_reloc_functions_status status =
4049 The_reloc_functions::adrp(view, dest, address);
4050 // An error should never arise in the above step. If so, please
4051 // check 'aarch64_valid_for_adrp_p'.
4052 gold_assert(status == The_reloc_functions::STATUS_OKAY);
4053
4054 // 2nd reloc is ADD_ABS_LO12_NC
4055 const AArch64_reloc_property* arp =
4056 aarch64_reloc_property_table->get_reloc_property(
4057 elfcpp::R_AARCH64_ADD_ABS_LO12_NC);
4058 gold_assert(arp != NULL);
4059 status = The_reloc_functions::template
4060 rela_general<32>(view + 4, dest, 0, arp);
4061 // An error should never arise, it is an "_NC" relocation.
4062 gold_assert(status == The_reloc_functions::STATUS_OKAY);
4063 }
4064 break;
4065
a48d0c12 4066 case ST_LONG_BRANCH_ABS:
83a01957
HS
4067 // 1st reloc is R_AARCH64_PREL64, at offset 8
4068 elfcpp::Swap<64,big_endian>::writeval(view + 8, dest);
4069 break;
4070
a48d0c12 4071 case ST_LONG_BRANCH_PCREL:
83a01957
HS
4072 {
4073 // "PC" calculation is the 2nd insn in the stub.
4074 uint64_t offset = dest - (address + 4);
4075 // Offset is placed at offset 4 and 5.
4076 elfcpp::Swap<64,big_endian>::writeval(view + 16, offset);
4077 }
4078 break;
4079
4080 default:
9726c3c1 4081 gold_unreachable();
83a01957
HS
4082 }
4083}
4084
4085
053a4d68
JY
4086// A class to handle the PLT data.
4087// This is an abstract base class that handles most of the linker details
4088// but does not know the actual contents of PLT entries. The derived
4089// classes below fill in those details.
4090
4091template<int size, bool big_endian>
4092class Output_data_plt_aarch64 : public Output_section_data
4093{
4094 public:
4095 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
4096 Reloc_section;
4097 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
4098
4099 Output_data_plt_aarch64(Layout* layout,
9363c7c3 4100 uint64_t addralign,
3a531937
JY
4101 Output_data_got_aarch64<size, big_endian>* got,
4102 Output_data_space* got_plt,
4103 Output_data_space* got_irelative)
9726c3c1 4104 : Output_section_data(addralign), tlsdesc_rel_(NULL), irelative_rel_(NULL),
3a531937
JY
4105 got_(got), got_plt_(got_plt), got_irelative_(got_irelative),
4106 count_(0), irelative_count_(0), tlsdesc_got_offset_(-1U)
053a4d68
JY
4107 { this->init(layout); }
4108
4109 // Initialize the PLT section.
4110 void
4111 init(Layout* layout);
4112
4113 // Add an entry to the PLT.
4114 void
9726c3c1
HS
4115 add_entry(Symbol_table*, Layout*, Symbol* gsym);
4116
4117 // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
4118 unsigned int
4119 add_local_ifunc_entry(Symbol_table* symtab, Layout*,
4120 Sized_relobj_file<size, big_endian>* relobj,
4121 unsigned int local_sym_index);
4122
4123 // Add the relocation for a PLT entry.
4124 void
4125 add_relocation(Symbol_table*, Layout*, Symbol* gsym,
4126 unsigned int got_offset);
053a4d68 4127
3a531937
JY
4128 // Add the reserved TLSDESC_PLT entry to the PLT.
4129 void
4130 reserve_tlsdesc_entry(unsigned int got_offset)
4131 { this->tlsdesc_got_offset_ = got_offset; }
4132
4133 // Return true if a TLSDESC_PLT entry has been reserved.
4134 bool
4135 has_tlsdesc_entry() const
4136 { return this->tlsdesc_got_offset_ != -1U; }
4137
4138 // Return the GOT offset for the reserved TLSDESC_PLT entry.
4139 unsigned int
4140 get_tlsdesc_got_offset() const
4141 { return this->tlsdesc_got_offset_; }
4142
4143 // Return the PLT offset of the reserved TLSDESC_PLT entry.
4144 unsigned int
4145 get_tlsdesc_plt_offset() const
4146 {
4147 return (this->first_plt_entry_offset() +
4148 (this->count_ + this->irelative_count_)
4149 * this->get_plt_entry_size());
4150 }
4151
053a4d68
JY
4152 // Return the .rela.plt section data.
4153 Reloc_section*
4154 rela_plt()
4155 { return this->rel_; }
4156
3a531937
JY
4157 // Return where the TLSDESC relocations should go.
4158 Reloc_section*
4159 rela_tlsdesc(Layout*);
4160
4161 // Return where the IRELATIVE relocations should go in the PLT
4162 // relocations.
4163 Reloc_section*
4164 rela_irelative(Symbol_table*, Layout*);
4165
9363c7c3
JY
4166 // Return whether we created a section for IRELATIVE relocations.
4167 bool
4168 has_irelative_section() const
4169 { return this->irelative_rel_ != NULL; }
4170
053a4d68
JY
4171 // Return the number of PLT entries.
4172 unsigned int
4173 entry_count() const
3a531937 4174 { return this->count_ + this->irelative_count_; }
053a4d68
JY
4175
4176 // Return the offset of the first non-reserved PLT entry.
4177 unsigned int
3a531937 4178 first_plt_entry_offset() const
053a4d68
JY
4179 { return this->do_first_plt_entry_offset(); }
4180
4181 // Return the size of a PLT entry.
4182 unsigned int
4183 get_plt_entry_size() const
4184 { return this->do_get_plt_entry_size(); }
4185
3a531937
JY
4186 // Return the reserved tlsdesc entry size.
4187 unsigned int
4188 get_plt_tlsdesc_entry_size() const
4189 { return this->do_get_plt_tlsdesc_entry_size(); }
4190
9363c7c3
JY
4191 // Return the PLT address to use for a global symbol.
4192 uint64_t
4193 address_for_global(const Symbol*);
4194
4195 // Return the PLT address to use for a local symbol.
4196 uint64_t
4197 address_for_local(const Relobj*, unsigned int symndx);
4198
053a4d68
JY
4199 protected:
4200 // Fill in the first PLT entry.
4201 void
4202 fill_first_plt_entry(unsigned char* pov,
4203 Address got_address,
4204 Address plt_address)
4205 { this->do_fill_first_plt_entry(pov, got_address, plt_address); }
4206
4207 // Fill in a normal PLT entry.
4208 void
4209 fill_plt_entry(unsigned char* pov,
4210 Address got_address,
4211 Address plt_address,
4212 unsigned int got_offset,
4213 unsigned int plt_offset)
4214 {
4215 this->do_fill_plt_entry(pov, got_address, plt_address,
4216 got_offset, plt_offset);
4217 }
4218
3a531937
JY
4219 // Fill in the reserved TLSDESC PLT entry.
4220 void
4221 fill_tlsdesc_entry(unsigned char* pov,
4222 Address gotplt_address,
4223 Address plt_address,
4224 Address got_base,
4225 unsigned int tlsdesc_got_offset,
4226 unsigned int plt_offset)
4227 {
4228 this->do_fill_tlsdesc_entry(pov, gotplt_address, plt_address, got_base,
4229 tlsdesc_got_offset, plt_offset);
4230 }
4231
053a4d68
JY
4232 virtual unsigned int
4233 do_first_plt_entry_offset() const = 0;
4234
4235 virtual unsigned int
4236 do_get_plt_entry_size() const = 0;
4237
3a531937
JY
4238 virtual unsigned int
4239 do_get_plt_tlsdesc_entry_size() const = 0;
4240
053a4d68
JY
4241 virtual void
4242 do_fill_first_plt_entry(unsigned char* pov,
4243 Address got_addr,
4244 Address plt_addr) = 0;
4245
4246 virtual void
4247 do_fill_plt_entry(unsigned char* pov,
4248 Address got_address,
4249 Address plt_address,
4250 unsigned int got_offset,
4251 unsigned int plt_offset) = 0;
4252
3a531937
JY
4253 virtual void
4254 do_fill_tlsdesc_entry(unsigned char* pov,
4255 Address gotplt_address,
4256 Address plt_address,
4257 Address got_base,
4258 unsigned int tlsdesc_got_offset,
4259 unsigned int plt_offset) = 0;
4260
053a4d68
JY
4261 void
4262 do_adjust_output_section(Output_section* os);
4263
4264 // Write to a map file.
4265 void
4266 do_print_to_mapfile(Mapfile* mapfile) const
4267 { mapfile->print_output_data(this, _("** PLT")); }
4268
4269 private:
4270 // Set the final size.
4271 void
4272 set_final_data_size();
4273
4274 // Write out the PLT data.
4275 void
4276 do_write(Output_file*);
4277
4278 // The reloc section.
4279 Reloc_section* rel_;
3a531937
JY
4280
4281 // The TLSDESC relocs, if necessary. These must follow the regular
4282 // PLT relocs.
4283 Reloc_section* tlsdesc_rel_;
4284
9363c7c3
JY
4285 // The IRELATIVE relocs, if necessary. These must follow the
4286 // regular PLT relocations.
4287 Reloc_section* irelative_rel_;
3a531937 4288
053a4d68
JY
4289 // The .got section.
4290 Output_data_got_aarch64<size, big_endian>* got_;
3a531937 4291
053a4d68
JY
4292 // The .got.plt section.
4293 Output_data_space* got_plt_;
3a531937
JY
4294
4295 // The part of the .got.plt section used for IRELATIVE relocs.
4296 Output_data_space* got_irelative_;
4297
053a4d68
JY
4298 // The number of PLT entries.
4299 unsigned int count_;
3a531937 4300
fa89cc82 4301 // Number of PLT entries with R_AARCH64_IRELATIVE relocs. These
3a531937
JY
4302 // follow the regular PLT entries.
4303 unsigned int irelative_count_;
4304
4305 // GOT offset of the reserved TLSDESC_GOT entry for the lazy trampoline.
4306 // Communicated to the loader via DT_TLSDESC_GOT. The magic value -1
4307 // indicates an offset is not allocated.
4308 unsigned int tlsdesc_got_offset_;
053a4d68
JY
4309};
4310
4311// Initialize the PLT section.
4312
4313template<int size, bool big_endian>
4314void
4315Output_data_plt_aarch64<size, big_endian>::init(Layout* layout)
4316{
4317 this->rel_ = new Reloc_section(false);
4318 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
4319 elfcpp::SHF_ALLOC, this->rel_,
4320 ORDER_DYNAMIC_PLT_RELOCS, false);
4321}
4322
4323template<int size, bool big_endian>
4324void
4325Output_data_plt_aarch64<size, big_endian>::do_adjust_output_section(
4326 Output_section* os)
4327{
4328 os->set_entsize(this->get_plt_entry_size());
4329}
4330
4331// Add an entry to the PLT.
4332
4333template<int size, bool big_endian>
4334void
9726c3c1
HS
4335Output_data_plt_aarch64<size, big_endian>::add_entry(Symbol_table* symtab,
4336 Layout* layout, Symbol* gsym)
053a4d68
JY
4337{
4338 gold_assert(!gsym->has_plt_offset());
9363c7c3 4339
9726c3c1
HS
4340 unsigned int* pcount;
4341 unsigned int plt_reserved;
4342 Output_section_data_build* got;
9363c7c3 4343
9726c3c1
HS
4344 if (gsym->type() == elfcpp::STT_GNU_IFUNC
4345 && gsym->can_use_relative_reloc(false))
4346 {
4347 pcount = &this->irelative_count_;
4348 plt_reserved = 0;
4349 got = this->got_irelative_;
4350 }
4351 else
4352 {
4353 pcount = &this->count_;
4354 plt_reserved = this->first_plt_entry_offset();
4355 got = this->got_plt_;
4356 }
9363c7c3 4357
9726c3c1
HS
4358 gsym->set_plt_offset((*pcount) * this->get_plt_entry_size()
4359 + plt_reserved);
4360
4361 ++*pcount;
4362
4363 section_offset_type got_offset = got->current_data_size();
9363c7c3
JY
4364
4365 // Every PLT entry needs a GOT entry which points back to the PLT
4366 // entry (this will be changed by the dynamic linker, normally
4367 // lazily when the function is called).
9726c3c1 4368 got->set_current_data_size(got_offset + size / 8);
9363c7c3
JY
4369
4370 // Every PLT entry needs a reloc.
9726c3c1 4371 this->add_relocation(symtab, layout, gsym, got_offset);
9363c7c3
JY
4372
4373 // Note that we don't need to save the symbol. The contents of the
4374 // PLT are independent of which symbols are used. The symbols only
4375 // appear in the relocations.
4376}
4377
9726c3c1
HS
4378// Add an entry to the PLT for a local STT_GNU_IFUNC symbol. Return
4379// the PLT offset.
4380
4381template<int size, bool big_endian>
4382unsigned int
4383Output_data_plt_aarch64<size, big_endian>::add_local_ifunc_entry(
4384 Symbol_table* symtab,
4385 Layout* layout,
4386 Sized_relobj_file<size, big_endian>* relobj,
4387 unsigned int local_sym_index)
4388{
4389 unsigned int plt_offset = this->irelative_count_ * this->get_plt_entry_size();
4390 ++this->irelative_count_;
4391
4392 section_offset_type got_offset = this->got_irelative_->current_data_size();
4393
4394 // Every PLT entry needs a GOT entry which points back to the PLT
4395 // entry.
4396 this->got_irelative_->set_current_data_size(got_offset + size / 8);
4397
4398 // Every PLT entry needs a reloc.
4399 Reloc_section* rela = this->rela_irelative(symtab, layout);
4400 rela->add_symbolless_local_addend(relobj, local_sym_index,
4401 elfcpp::R_AARCH64_IRELATIVE,
4402 this->got_irelative_, got_offset, 0);
4403
4404 return plt_offset;
4405}
4406
4407// Add the relocation for a PLT entry.
4408
4409template<int size, bool big_endian>
4410void
4411Output_data_plt_aarch64<size, big_endian>::add_relocation(
4412 Symbol_table* symtab, Layout* layout, Symbol* gsym, unsigned int got_offset)
4413{
4414 if (gsym->type() == elfcpp::STT_GNU_IFUNC
4415 && gsym->can_use_relative_reloc(false))
4416 {
4417 Reloc_section* rela = this->rela_irelative(symtab, layout);
4418 rela->add_symbolless_global_addend(gsym, elfcpp::R_AARCH64_IRELATIVE,
4419 this->got_irelative_, got_offset, 0);
4420 }
4421 else
4422 {
4423 gsym->set_needs_dynsym_entry();
4424 this->rel_->add_global(gsym, elfcpp::R_AARCH64_JUMP_SLOT, this->got_plt_,
4425 got_offset, 0);
4426 }
4427}
4428
3a531937
JY
4429// Return where the TLSDESC relocations should go, creating it if
4430// necessary. These follow the JUMP_SLOT relocations.
4431
4432template<int size, bool big_endian>
4433typename Output_data_plt_aarch64<size, big_endian>::Reloc_section*
4434Output_data_plt_aarch64<size, big_endian>::rela_tlsdesc(Layout* layout)
4435{
4436 if (this->tlsdesc_rel_ == NULL)
4437 {
4438 this->tlsdesc_rel_ = new Reloc_section(false);
4439 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
4440 elfcpp::SHF_ALLOC, this->tlsdesc_rel_,
4441 ORDER_DYNAMIC_PLT_RELOCS, false);
4442 gold_assert(this->tlsdesc_rel_->output_section()
4443 == this->rel_->output_section());
4444 }
4445 return this->tlsdesc_rel_;
4446}
4447
4448// Return where the IRELATIVE relocations should go in the PLT. These
4449// follow the JUMP_SLOT and the TLSDESC relocations.
4450
4451template<int size, bool big_endian>
4452typename Output_data_plt_aarch64<size, big_endian>::Reloc_section*
4453Output_data_plt_aarch64<size, big_endian>::rela_irelative(Symbol_table* symtab,
4454 Layout* layout)
4455{
4456 if (this->irelative_rel_ == NULL)
4457 {
4458 // Make sure we have a place for the TLSDESC relocations, in
4459 // case we see any later on.
4460 this->rela_tlsdesc(layout);
4461 this->irelative_rel_ = new Reloc_section(false);
4462 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
4463 elfcpp::SHF_ALLOC, this->irelative_rel_,
4464 ORDER_DYNAMIC_PLT_RELOCS, false);
4465 gold_assert(this->irelative_rel_->output_section()
4466 == this->rel_->output_section());
4467
4468 if (parameters->doing_static_link())
4469 {
4470 // A statically linked executable will only have a .rela.plt
4471 // section to hold R_AARCH64_IRELATIVE relocs for
4472 // STT_GNU_IFUNC symbols. The library will use these
4473 // symbols to locate the IRELATIVE relocs at program startup
4474 // time.
4475 symtab->define_in_output_data("__rela_iplt_start", NULL,
4476 Symbol_table::PREDEFINED,
4477 this->irelative_rel_, 0, 0,
4478 elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
4479 elfcpp::STV_HIDDEN, 0, false, true);
4480 symtab->define_in_output_data("__rela_iplt_end", NULL,
4481 Symbol_table::PREDEFINED,
4482 this->irelative_rel_, 0, 0,
4483 elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
4484 elfcpp::STV_HIDDEN, 0, true, true);
4485 }
4486 }
4487 return this->irelative_rel_;
4488}
4489
9363c7c3
JY
4490// Return the PLT address to use for a global symbol.
4491
4492template<int size, bool big_endian>
4493uint64_t
4494Output_data_plt_aarch64<size, big_endian>::address_for_global(
4495 const Symbol* gsym)
4496{
4497 uint64_t offset = 0;
4498 if (gsym->type() == elfcpp::STT_GNU_IFUNC
4499 && gsym->can_use_relative_reloc(false))
4500 offset = (this->first_plt_entry_offset() +
4501 this->count_ * this->get_plt_entry_size());
4502 return this->address() + offset + gsym->plt_offset();
4503}
4504
4505// Return the PLT address to use for a local symbol. These are always
4506// IRELATIVE relocs.
4507
4508template<int size, bool big_endian>
4509uint64_t
4510Output_data_plt_aarch64<size, big_endian>::address_for_local(
4511 const Relobj* object,
4512 unsigned int r_sym)
4513{
4514 return (this->address()
4515 + this->first_plt_entry_offset()
4516 + this->count_ * this->get_plt_entry_size()
4517 + object->local_plt_offset(r_sym));
053a4d68
JY
4518}
4519
4520// Set the final size.
9363c7c3 4521
053a4d68
JY
4522template<int size, bool big_endian>
4523void
4524Output_data_plt_aarch64<size, big_endian>::set_final_data_size()
4525{
3a531937
JY
4526 unsigned int count = this->count_ + this->irelative_count_;
4527 unsigned int extra_size = 0;
4528 if (this->has_tlsdesc_entry())
4529 extra_size += this->get_plt_tlsdesc_entry_size();
053a4d68 4530 this->set_data_size(this->first_plt_entry_offset()
3a531937
JY
4531 + count * this->get_plt_entry_size()
4532 + extra_size);
053a4d68
JY
4533}
4534
4535template<int size, bool big_endian>
4536class Output_data_plt_aarch64_standard :
4537 public Output_data_plt_aarch64<size, big_endian>
4538{
4539 public:
4540 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
3a531937
JY
4541 Output_data_plt_aarch64_standard(
4542 Layout* layout,
4543 Output_data_got_aarch64<size, big_endian>* got,
4544 Output_data_space* got_plt,
4545 Output_data_space* got_irelative)
053a4d68 4546 : Output_data_plt_aarch64<size, big_endian>(layout,
9363c7c3 4547 size == 32 ? 4 : 8,
3a531937
JY
4548 got, got_plt,
4549 got_irelative)
053a4d68
JY
4550 { }
4551
4552 protected:
4553 // Return the offset of the first non-reserved PLT entry.
4554 virtual unsigned int
4555 do_first_plt_entry_offset() const
4556 { return this->first_plt_entry_size; }
4557
4558 // Return the size of a PLT entry
4559 virtual unsigned int
4560 do_get_plt_entry_size() const
4561 { return this->plt_entry_size; }
4562
3a531937
JY
4563 // Return the size of a tlsdesc entry
4564 virtual unsigned int
4565 do_get_plt_tlsdesc_entry_size() const
4566 { return this->plt_tlsdesc_entry_size; }
4567
053a4d68
JY
4568 virtual void
4569 do_fill_first_plt_entry(unsigned char* pov,
9363c7c3
JY
4570 Address got_address,
4571 Address plt_address);
053a4d68
JY
4572
4573 virtual void
4574 do_fill_plt_entry(unsigned char* pov,
9363c7c3
JY
4575 Address got_address,
4576 Address plt_address,
4577 unsigned int got_offset,
4578 unsigned int plt_offset);
053a4d68 4579
3a531937
JY
4580 virtual void
4581 do_fill_tlsdesc_entry(unsigned char* pov,
4582 Address gotplt_address,
4583 Address plt_address,
4584 Address got_base,
4585 unsigned int tlsdesc_got_offset,
4586 unsigned int plt_offset);
4587
053a4d68
JY
4588 private:
4589 // The size of the first plt entry size.
4590 static const int first_plt_entry_size = 32;
4591 // The size of the plt entry size.
4592 static const int plt_entry_size = 16;
3a531937
JY
4593 // The size of the plt tlsdesc entry size.
4594 static const int plt_tlsdesc_entry_size = 32;
053a4d68
JY
4595 // Template for the first PLT entry.
4596 static const uint32_t first_plt_entry[first_plt_entry_size / 4];
4597 // Template for subsequent PLT entries.
4598 static const uint32_t plt_entry[plt_entry_size / 4];
3a531937
JY
4599 // The reserved TLSDESC entry in the PLT for an executable.
4600 static const uint32_t tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4];
053a4d68
JY
4601};
4602
4603// The first entry in the PLT for an executable.
4604
4605template<>
4606const uint32_t
4607Output_data_plt_aarch64_standard<32, false>::
4608 first_plt_entry[first_plt_entry_size / 4] =
4609{
4610 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
4611 0x90000010, /* adrp x16, PLT_GOT+0x8 */
4612 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
4613 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
4614 0xd61f0220, /* br x17 */
4615 0xd503201f, /* nop */
4616 0xd503201f, /* nop */
4617 0xd503201f, /* nop */
4618};
4619
83a01957 4620
053a4d68
JY
4621template<>
4622const uint32_t
4623Output_data_plt_aarch64_standard<32, true>::
4624 first_plt_entry[first_plt_entry_size / 4] =
4625{
4626 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
4627 0x90000010, /* adrp x16, PLT_GOT+0x8 */
4628 0xb9400A11, /* ldr w17, [x16, #PLT_GOT+0x8] */
4629 0x11002210, /* add w16, w16,#PLT_GOT+0x8 */
4630 0xd61f0220, /* br x17 */
4631 0xd503201f, /* nop */
4632 0xd503201f, /* nop */
4633 0xd503201f, /* nop */
4634};
4635
83a01957 4636
053a4d68
JY
4637template<>
4638const uint32_t
4639Output_data_plt_aarch64_standard<64, false>::
4640 first_plt_entry[first_plt_entry_size / 4] =
4641{
4642 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
4643 0x90000010, /* adrp x16, PLT_GOT+16 */
4644 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
4645 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
4646 0xd61f0220, /* br x17 */
4647 0xd503201f, /* nop */
4648 0xd503201f, /* nop */
4649 0xd503201f, /* nop */
4650};
4651
83a01957 4652
053a4d68
JY
4653template<>
4654const uint32_t
4655Output_data_plt_aarch64_standard<64, true>::
4656 first_plt_entry[first_plt_entry_size / 4] =
4657{
4658 0xa9bf7bf0, /* stp x16, x30, [sp, #-16]! */
4659 0x90000010, /* adrp x16, PLT_GOT+16 */
4660 0xf9400A11, /* ldr x17, [x16, #PLT_GOT+0x10] */
4661 0x91004210, /* add x16, x16,#PLT_GOT+0x10 */
4662 0xd61f0220, /* br x17 */
4663 0xd503201f, /* nop */
4664 0xd503201f, /* nop */
4665 0xd503201f, /* nop */
4666};
4667
83a01957 4668
053a4d68
JY
4669template<>
4670const uint32_t
4671Output_data_plt_aarch64_standard<32, false>::
4672 plt_entry[plt_entry_size / 4] =
4673{
4674 0x90000010, /* adrp x16, PLTGOT + n * 4 */
4675 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
4676 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
4677 0xd61f0220, /* br x17. */
4678};
4679
83a01957 4680
053a4d68
JY
4681template<>
4682const uint32_t
4683Output_data_plt_aarch64_standard<32, true>::
4684 plt_entry[plt_entry_size / 4] =
4685{
4686 0x90000010, /* adrp x16, PLTGOT + n * 4 */
4687 0xb9400211, /* ldr w17, [w16, PLTGOT + n * 4] */
4688 0x11000210, /* add w16, w16, :lo12:PLTGOT + n * 4 */
4689 0xd61f0220, /* br x17. */
4690};
4691
83a01957 4692
053a4d68
JY
4693template<>
4694const uint32_t
4695Output_data_plt_aarch64_standard<64, false>::
4696 plt_entry[plt_entry_size / 4] =
4697{
4698 0x90000010, /* adrp x16, PLTGOT + n * 8 */
4699 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
4700 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
4701 0xd61f0220, /* br x17. */
4702};
4703
83a01957 4704
053a4d68
JY
4705template<>
4706const uint32_t
4707Output_data_plt_aarch64_standard<64, true>::
4708 plt_entry[plt_entry_size / 4] =
4709{
4710 0x90000010, /* adrp x16, PLTGOT + n * 8 */
4711 0xf9400211, /* ldr x17, [x16, PLTGOT + n * 8] */
4712 0x91000210, /* add x16, x16, :lo12:PLTGOT + n * 8 */
4713 0xd61f0220, /* br x17. */
4714};
4715
83a01957 4716
053a4d68
JY
4717template<int size, bool big_endian>
4718void
4719Output_data_plt_aarch64_standard<size, big_endian>::do_fill_first_plt_entry(
4720 unsigned char* pov,
9363c7c3
JY
4721 Address got_address,
4722 Address plt_address)
053a4d68
JY
4723{
4724 // PLT0 of the small PLT looks like this in ELF64 -
4725 // stp x16, x30, [sp, #-16]! Save the reloc and lr on stack.
4726 // adrp x16, PLT_GOT + 16 Get the page base of the GOTPLT
4727 // ldr x17, [x16, #:lo12:PLT_GOT+16] Load the address of the
4728 // symbol resolver
4729 // add x16, x16, #:lo12:PLT_GOT+16 Load the lo12 bits of the
4730 // GOTPLT entry for this.
4731 // br x17
4732 // PLT0 will be slightly different in ELF32 due to different got entry
4733 // size.
4734 memcpy(pov, this->first_plt_entry, this->first_plt_entry_size);
9363c7c3
JY
4735 Address gotplt_2nd_ent = got_address + (size / 8) * 2;
4736
4737 // Fill in the top 21 bits for this: ADRP x16, PLT_GOT + 8 * 2.
4738 // ADRP: (PG(S+A)-PG(P)) >> 12) & 0x1fffff.
4739 // FIXME: This only works for 64bit
4740 AArch64_relocate_functions<size, big_endian>::adrp(pov + 4,
4741 gotplt_2nd_ent, plt_address + 4);
4742
4743 // Fill in R_AARCH64_LDST8_LO12
4744 elfcpp::Swap<32, big_endian>::writeval(
4745 pov + 8,
4746 ((this->first_plt_entry[2] & 0xffc003ff)
4747 | ((gotplt_2nd_ent & 0xff8) << 7)));
4748
4749 // Fill in R_AARCH64_ADD_ABS_LO12
4750 elfcpp::Swap<32, big_endian>::writeval(
4751 pov + 12,
4752 ((this->first_plt_entry[3] & 0xffc003ff)
4753 | ((gotplt_2nd_ent & 0xfff) << 10)));
053a4d68
JY
4754}
4755
83a01957 4756
053a4d68 4757// Subsequent entries in the PLT for an executable.
9363c7c3 4758// FIXME: This only works for 64bit
053a4d68
JY
4759
4760template<int size, bool big_endian>
4761void
4762Output_data_plt_aarch64_standard<size, big_endian>::do_fill_plt_entry(
4763 unsigned char* pov,
9363c7c3
JY
4764 Address got_address,
4765 Address plt_address,
4766 unsigned int got_offset,
4767 unsigned int plt_offset)
053a4d68
JY
4768{
4769 memcpy(pov, this->plt_entry, this->plt_entry_size);
9363c7c3
JY
4770
4771 Address gotplt_entry_address = got_address + got_offset;
4772 Address plt_entry_address = plt_address + plt_offset;
4773
4774 // Fill in R_AARCH64_PCREL_ADR_HI21
4775 AArch64_relocate_functions<size, big_endian>::adrp(
4776 pov,
4777 gotplt_entry_address,
4778 plt_entry_address);
4779
4780 // Fill in R_AARCH64_LDST64_ABS_LO12
4781 elfcpp::Swap<32, big_endian>::writeval(
4782 pov + 4,
4783 ((this->plt_entry[1] & 0xffc003ff)
4784 | ((gotplt_entry_address & 0xff8) << 7)));
4785
4786 // Fill in R_AARCH64_ADD_ABS_LO12
4787 elfcpp::Swap<32, big_endian>::writeval(
4788 pov + 8,
4789 ((this->plt_entry[2] & 0xffc003ff)
4790 | ((gotplt_entry_address & 0xfff) <<10)));
4791
053a4d68
JY
4792}
4793
3a531937
JY
4794
4795template<>
4796const uint32_t
4797Output_data_plt_aarch64_standard<32, false>::
4798 tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
4799{
4800 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
4801 0x90000002, /* adrp x2, 0 */
4802 0x90000003, /* adrp x3, 0 */
4803 0xb9400042, /* ldr w2, [w2, #0] */
4804 0x11000063, /* add w3, w3, 0 */
4805 0xd61f0040, /* br x2 */
4806 0xd503201f, /* nop */
4807 0xd503201f, /* nop */
4808};
4809
4810template<>
4811const uint32_t
4812Output_data_plt_aarch64_standard<32, true>::
4813 tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
4814{
4815 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
4816 0x90000002, /* adrp x2, 0 */
4817 0x90000003, /* adrp x3, 0 */
4818 0xb9400042, /* ldr w2, [w2, #0] */
4819 0x11000063, /* add w3, w3, 0 */
4820 0xd61f0040, /* br x2 */
4821 0xd503201f, /* nop */
4822 0xd503201f, /* nop */
4823};
4824
4825template<>
4826const uint32_t
4827Output_data_plt_aarch64_standard<64, false>::
4828 tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
4829{
4830 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
4831 0x90000002, /* adrp x2, 0 */
4832 0x90000003, /* adrp x3, 0 */
4833 0xf9400042, /* ldr x2, [x2, #0] */
4834 0x91000063, /* add x3, x3, 0 */
4835 0xd61f0040, /* br x2 */
4836 0xd503201f, /* nop */
4837 0xd503201f, /* nop */
4838};
4839
4840template<>
4841const uint32_t
4842Output_data_plt_aarch64_standard<64, true>::
4843 tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
4844{
4845 0xa9bf0fe2, /* stp x2, x3, [sp, #-16]! */
4846 0x90000002, /* adrp x2, 0 */
4847 0x90000003, /* adrp x3, 0 */
4848 0xf9400042, /* ldr x2, [x2, #0] */
4849 0x91000063, /* add x3, x3, 0 */
4850 0xd61f0040, /* br x2 */
4851 0xd503201f, /* nop */
4852 0xd503201f, /* nop */
4853};
4854
4855template<int size, bool big_endian>
4856void
4857Output_data_plt_aarch64_standard<size, big_endian>::do_fill_tlsdesc_entry(
4858 unsigned char* pov,
4859 Address gotplt_address,
4860 Address plt_address,
4861 Address got_base,
4862 unsigned int tlsdesc_got_offset,
4863 unsigned int plt_offset)
4864{
4865 memcpy(pov, tlsdesc_plt_entry, plt_tlsdesc_entry_size);
4866
4867 // move DT_TLSDESC_GOT address into x2
4868 // move .got.plt address into x3
4869 Address tlsdesc_got_entry = got_base + tlsdesc_got_offset;
4870 Address plt_entry_address = plt_address + plt_offset;
4871
4872 // R_AARCH64_ADR_PREL_PG_HI21
4873 AArch64_relocate_functions<size, big_endian>::adrp(
4874 pov + 4,
4875 tlsdesc_got_entry,
4876 plt_entry_address + 4);
4877
4878 // R_AARCH64_ADR_PREL_PG_HI21
4879 AArch64_relocate_functions<size, big_endian>::adrp(
4880 pov + 8,
4881 gotplt_address,
4882 plt_entry_address + 8);
4883
4884 // R_AARCH64_LDST64_ABS_LO12
4885 elfcpp::Swap<32, big_endian>::writeval(
4886 pov + 12,
4887 ((this->tlsdesc_plt_entry[3] & 0xffc003ff)
4888 | ((tlsdesc_got_entry & 0xff8) << 7)));
4889
4890 // R_AARCH64_ADD_ABS_LO12
4891 elfcpp::Swap<32, big_endian>::writeval(
4892 pov + 16,
4893 ((this->tlsdesc_plt_entry[4] & 0xffc003ff)
4894 | ((gotplt_address & 0xfff) << 10)));
4895}
4896
053a4d68
JY
4897// Write out the PLT. This uses the hand-coded instructions above,
4898// and adjusts them as needed. This is specified by the AMD64 ABI.
4899
4900template<int size, bool big_endian>
4901void
4902Output_data_plt_aarch64<size, big_endian>::do_write(Output_file* of)
4903{
4904 const off_t offset = this->offset();
4905 const section_size_type oview_size =
4906 convert_to_section_size_type(this->data_size());
4907 unsigned char* const oview = of->get_output_view(offset, oview_size);
4908
4909 const off_t got_file_offset = this->got_plt_->offset();
9726c3c1
HS
4910 gold_assert(got_file_offset + this->got_plt_->data_size()
4911 == this->got_irelative_->offset());
4912
053a4d68 4913 const section_size_type got_size =
9726c3c1
HS
4914 convert_to_section_size_type(this->got_plt_->data_size()
4915 + this->got_irelative_->data_size());
053a4d68
JY
4916 unsigned char* const got_view = of->get_output_view(got_file_offset,
4917 got_size);
4918
4919 unsigned char* pov = oview;
4920
4921 // The base address of the .plt section.
4922 typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
053a4d68 4923 // The base address of the PLT portion of the .got section.
3a531937
JY
4924 typename elfcpp::Elf_types<size>::Elf_Addr gotplt_address
4925 = this->got_plt_->address();
053a4d68 4926
3a531937 4927 this->fill_first_plt_entry(pov, gotplt_address, plt_address);
053a4d68
JY
4928 pov += this->first_plt_entry_offset();
4929
4930 // The first three entries in .got.plt are reserved.
4931 unsigned char* got_pov = got_view;
4932 memset(got_pov, 0, size / 8 * AARCH64_GOTPLT_RESERVE_COUNT);
4933 got_pov += (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
4934
4935 unsigned int plt_offset = this->first_plt_entry_offset();
4936 unsigned int got_offset = (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
3a531937 4937 const unsigned int count = this->count_ + this->irelative_count_;
053a4d68
JY
4938 for (unsigned int plt_index = 0;
4939 plt_index < count;
4940 ++plt_index,
4941 pov += this->get_plt_entry_size(),
4942 got_pov += size / 8,
4943 plt_offset += this->get_plt_entry_size(),
4944 got_offset += size / 8)
4945 {
4946 // Set and adjust the PLT entry itself.
3a531937 4947 this->fill_plt_entry(pov, gotplt_address, plt_address,
9363c7c3 4948 got_offset, plt_offset);
053a4d68 4949
9363c7c3
JY
4950 // Set the entry in the GOT, which points to plt0.
4951 elfcpp::Swap<size, big_endian>::writeval(got_pov, plt_address);
053a4d68
JY
4952 }
4953
3a531937
JY
4954 if (this->has_tlsdesc_entry())
4955 {
4956 // Set and adjust the reserved TLSDESC PLT entry.
4957 unsigned int tlsdesc_got_offset = this->get_tlsdesc_got_offset();
4958 // The base address of the .base section.
4959 typename elfcpp::Elf_types<size>::Elf_Addr got_base =
4960 this->got_->address();
4961 this->fill_tlsdesc_entry(pov, gotplt_address, plt_address, got_base,
4962 tlsdesc_got_offset, plt_offset);
4963 pov += this->get_plt_tlsdesc_entry_size();
4964 }
4965
053a4d68
JY
4966 gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
4967 gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
4968
4969 of->write_output_view(offset, oview_size, oview);
4970 of->write_output_view(got_file_offset, got_size, got_view);
4971}
4972
9363c7c3
JY
4973// Telling how to update the immediate field of an instruction.
4974struct AArch64_howto
4975{
4976 // The immediate field mask.
4977 elfcpp::Elf_Xword dst_mask;
4978
4979 // The offset to apply relocation immediate
4980 int doffset;
4981
4982 // The second part offset, if the immediate field has two parts.
4983 // -1 if the immediate field has only one part.
4984 int doffset2;
4985};
4986
4987static const AArch64_howto aarch64_howto[AArch64_reloc_property::INST_NUM] =
4988{
4989 {0, -1, -1}, // DATA
4990 {0x1fffe0, 5, -1}, // MOVW [20:5]-imm16
4991 {0xffffe0, 5, -1}, // LD [23:5]-imm19
4992 {0x60ffffe0, 29, 5}, // ADR [30:29]-immlo [23:5]-immhi
4993 {0x60ffffe0, 29, 5}, // ADRP [30:29]-immlo [23:5]-immhi
4994 {0x3ffc00, 10, -1}, // ADD [21:10]-imm12
4995 {0x3ffc00, 10, -1}, // LDST [21:10]-imm12
4996 {0x7ffe0, 5, -1}, // TBZNZ [18:5]-imm14
4997 {0xffffe0, 5, -1}, // CONDB [23:5]-imm19
4998 {0x3ffffff, 0, -1}, // B [25:0]-imm26
4999 {0x3ffffff, 0, -1}, // CALL [25:0]-imm26
5000};
5001
5002// AArch64 relocate function class
5003
5004template<int size, bool big_endian>
5005class AArch64_relocate_functions
5006{
5007 public:
5008 typedef enum
5009 {
5010 STATUS_OKAY, // No error during relocation.
5011 STATUS_OVERFLOW, // Relocation overflow.
5012 STATUS_BAD_RELOC, // Relocation cannot be applied.
5013 } Status;
5014
9363c7c3
JY
5015 typedef AArch64_relocate_functions<size, big_endian> This;
5016 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
83a01957
HS
5017 typedef Relocate_info<size, big_endian> The_relocate_info;
5018 typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
5019 typedef Reloc_stub<size, big_endian> The_reloc_stub;
83a01957
HS
5020 typedef Stub_table<size, big_endian> The_stub_table;
5021 typedef elfcpp::Rela<size, big_endian> The_rela;
9726c3c1 5022 typedef typename elfcpp::Swap<size, big_endian>::Valtype AArch64_valtype;
9363c7c3
JY
5023
5024 // Return the page address of the address.
5025 // Page(address) = address & ~0xFFF
5026
9726c3c1 5027 static inline AArch64_valtype
9363c7c3
JY
5028 Page(Address address)
5029 {
5030 return (address & (~static_cast<Address>(0xFFF)));
5031 }
5032
83a01957 5033 private:
9363c7c3
JY
5034 // Update instruction (pointed by view) with selected bits (immed).
5035 // val = (val & ~dst_mask) | (immed << doffset)
5036
5037 template<int valsize>
5038 static inline void
5039 update_view(unsigned char* view,
9726c3c1 5040 AArch64_valtype immed,
9363c7c3
JY
5041 elfcpp::Elf_Xword doffset,
5042 elfcpp::Elf_Xword dst_mask)
5043 {
5044 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
5045 Valtype* wv = reinterpret_cast<Valtype*>(view);
5046 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
5047
5048 // Clear immediate fields.
5049 val &= ~dst_mask;
5050 elfcpp::Swap<valsize, big_endian>::writeval(wv,
5051 static_cast<Valtype>(val | (immed << doffset)));
5052 }
5053
5054 // Update two parts of an instruction (pointed by view) with selected
5055 // bits (immed1 and immed2).
5056 // val = (val & ~dst_mask) | (immed1 << doffset1) | (immed2 << doffset2)
5057
5058 template<int valsize>
5059 static inline void
5060 update_view_two_parts(
5061 unsigned char* view,
9726c3c1
HS
5062 AArch64_valtype immed1,
5063 AArch64_valtype immed2,
9363c7c3
JY
5064 elfcpp::Elf_Xword doffset1,
5065 elfcpp::Elf_Xword doffset2,
5066 elfcpp::Elf_Xword dst_mask)
5067 {
5068 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
5069 Valtype* wv = reinterpret_cast<Valtype*>(view);
5070 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
5071 val &= ~dst_mask;
5072 elfcpp::Swap<valsize, big_endian>::writeval(wv,
5073 static_cast<Valtype>(val | (immed1 << doffset1) |
5074 (immed2 << doffset2)));
5075 }
5076
9726c3c1 5077 // Update adr or adrp instruction with immed.
9363c7c3
JY
5078 // In adr and adrp: [30:29] immlo [23:5] immhi
5079
5080 static inline void
9726c3c1 5081 update_adr(unsigned char* view, AArch64_valtype immed)
9363c7c3
JY
5082 {
5083 elfcpp::Elf_Xword dst_mask = (0x3 << 29) | (0x7ffff << 5);
9363c7c3
JY
5084 This::template update_view_two_parts<32>(
5085 view,
5086 immed & 0x3,
5087 (immed & 0x1ffffc) >> 2,
5088 29,
5089 5,
5090 dst_mask);
5091 }
5092
3a531937
JY
5093 // Update movz/movn instruction with bits immed.
5094 // Set instruction to movz if is_movz is true, otherwise set instruction
5095 // to movn.
9726c3c1 5096
3a531937
JY
5097 static inline void
5098 update_movnz(unsigned char* view,
9726c3c1 5099 AArch64_valtype immed,
3a531937
JY
5100 bool is_movz)
5101 {
5102 typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
5103 Valtype* wv = reinterpret_cast<Valtype*>(view);
5104 Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
5105
5106 const elfcpp::Elf_Xword doffset =
5107 aarch64_howto[AArch64_reloc_property::INST_MOVW].doffset;
5108 const elfcpp::Elf_Xword dst_mask =
5109 aarch64_howto[AArch64_reloc_property::INST_MOVW].dst_mask;
5110
5111 // Clear immediate fields and opc code.
9726c3c1 5112 val &= ~(dst_mask | (0x3 << 29));
3a531937
JY
5113
5114 // Set instruction to movz or movn.
5115 // movz: [30:29] is 10 movn: [30:29] is 00
5116 if (is_movz)
9726c3c1 5117 val |= (0x2 << 29);
3a531937
JY
5118
5119 elfcpp::Swap<32, big_endian>::writeval(wv,
5120 static_cast<Valtype>(val | (immed << doffset)));
5121 }
5122
5c28a503
HS
5123 public:
5124
9726c3c1
HS
5125 // Update selected bits in text.
5126
5127 template<int valsize>
5128 static inline typename This::Status
5129 reloc_common(unsigned char* view, Address x,
5130 const AArch64_reloc_property* reloc_property)
5131 {
5132 // Select bits from X.
5133 Address immed = reloc_property->select_x_value(x);
5134
5135 // Update view.
5136 const AArch64_reloc_property::Reloc_inst inst =
5137 reloc_property->reloc_inst();
5138 // If it is a data relocation or instruction has 2 parts of immediate
5139 // fields, you should not call pcrela_general.
5140 gold_assert(aarch64_howto[inst].doffset2 == -1 &&
5141 aarch64_howto[inst].doffset != -1);
5142 This::template update_view<valsize>(view, immed,
5143 aarch64_howto[inst].doffset,
5144 aarch64_howto[inst].dst_mask);
5145
5146 // Do check overflow or alignment if needed.
5147 return (reloc_property->checkup_x_value(x)
5148 ? This::STATUS_OKAY
5149 : This::STATUS_OVERFLOW);
5150 }
5151
a48d0c12
HS
5152 // Construct a B insn. Note, although we group it here with other relocation
5153 // operation, there is actually no 'relocation' involved here.
5154 static inline void
5155 construct_b(unsigned char* view, unsigned int branch_offset)
5156 {
5157 update_view_two_parts<32>(view, 0x05, (branch_offset >> 2),
5158 26, 0, 0xffffffff);
5159 }
5160
9363c7c3
JY
5161 // Do a simple rela relocation at unaligned addresses.
5162
5163 template<int valsize>
5164 static inline typename This::Status
5165 rela_ua(unsigned char* view,
5166 const Sized_relobj_file<size, big_endian>* object,
5167 const Symbol_value<size>* psymval,
9726c3c1 5168 AArch64_valtype addend,
9363c7c3
JY
5169 const AArch64_reloc_property* reloc_property)
5170 {
5171 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
5172 Valtype;
5173 typename elfcpp::Elf_types<size>::Elf_Addr x =
5174 psymval->value(object, addend);
5175 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
5176 static_cast<Valtype>(x));
5177 return (reloc_property->checkup_x_value(x)
5178 ? This::STATUS_OKAY
5179 : This::STATUS_OVERFLOW);
5180 }
5181
5182 // Do a simple pc-relative relocation at unaligned addresses.
5183
5184 template<int valsize>
5185 static inline typename This::Status
5186 pcrela_ua(unsigned char* view,
5187 const Sized_relobj_file<size, big_endian>* object,
5188 const Symbol_value<size>* psymval,
9726c3c1 5189 AArch64_valtype addend,
9363c7c3
JY
5190 Address address,
5191 const AArch64_reloc_property* reloc_property)
5192 {
5193 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
5194 Valtype;
3a531937 5195 Address x = psymval->value(object, addend) - address;
9363c7c3
JY
5196 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
5197 static_cast<Valtype>(x));
5198 return (reloc_property->checkup_x_value(x)
5199 ? This::STATUS_OKAY
5200 : This::STATUS_OVERFLOW);
5201 }
5202
5203 // Do a simple rela relocation at aligned addresses.
5204
5205 template<int valsize>
5206 static inline typename This::Status
5207 rela(
5208 unsigned char* view,
5209 const Sized_relobj_file<size, big_endian>* object,
5210 const Symbol_value<size>* psymval,
9726c3c1 5211 AArch64_valtype addend,
9363c7c3
JY
5212 const AArch64_reloc_property* reloc_property)
5213 {
9726c3c1 5214 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
9363c7c3 5215 Valtype* wv = reinterpret_cast<Valtype*>(view);
3a531937 5216 Address x = psymval->value(object, addend);
9726c3c1 5217 elfcpp::Swap<valsize, big_endian>::writeval(wv,static_cast<Valtype>(x));
9363c7c3
JY
5218 return (reloc_property->checkup_x_value(x)
5219 ? This::STATUS_OKAY
5220 : This::STATUS_OVERFLOW);
5221 }
5222
5223 // Do relocate. Update selected bits in text.
5224 // new_val = (val & ~dst_mask) | (immed << doffset)
5225
5226 template<int valsize>
5227 static inline typename This::Status
5228 rela_general(unsigned char* view,
5229 const Sized_relobj_file<size, big_endian>* object,
5230 const Symbol_value<size>* psymval,
9726c3c1 5231 AArch64_valtype addend,
9363c7c3
JY
5232 const AArch64_reloc_property* reloc_property)
5233 {
5234 // Calculate relocation.
83a01957 5235 Address x = psymval->value(object, addend);
9726c3c1 5236 return This::template reloc_common<valsize>(view, x, reloc_property);
9363c7c3
JY
5237 }
5238
5239 // Do relocate. Update selected bits in text.
5240 // new val = (val & ~dst_mask) | (immed << doffset)
5241
5242 template<int valsize>
5243 static inline typename This::Status
5244 rela_general(
5245 unsigned char* view,
9726c3c1
HS
5246 AArch64_valtype s,
5247 AArch64_valtype addend,
9363c7c3
JY
5248 const AArch64_reloc_property* reloc_property)
5249 {
5250 // Calculate relocation.
5251 Address x = s + addend;
9726c3c1 5252 return This::template reloc_common<valsize>(view, x, reloc_property);
9363c7c3
JY
5253 }
5254
5255 // Do address relative relocate. Update selected bits in text.
5256 // new val = (val & ~dst_mask) | (immed << doffset)
5257
5258 template<int valsize>
5259 static inline typename This::Status
5260 pcrela_general(
5261 unsigned char* view,
5262 const Sized_relobj_file<size, big_endian>* object,
5263 const Symbol_value<size>* psymval,
9726c3c1 5264 AArch64_valtype addend,
9363c7c3
JY
5265 Address address,
5266 const AArch64_reloc_property* reloc_property)
5267 {
5268 // Calculate relocation.
3a531937 5269 Address x = psymval->value(object, addend) - address;
9726c3c1
HS
5270 return This::template reloc_common<valsize>(view, x, reloc_property);
5271 }
9363c7c3 5272
9363c7c3 5273
9726c3c1 5274 // Calculate (S + A) - address, update adr instruction.
9363c7c3 5275
9726c3c1
HS
5276 static inline typename This::Status
5277 adr(unsigned char* view,
5278 const Sized_relobj_file<size, big_endian>* object,
5279 const Symbol_value<size>* psymval,
5280 Address addend,
5281 Address address,
5282 const AArch64_reloc_property* /* reloc_property */)
5283 {
5284 AArch64_valtype x = psymval->value(object, addend) - address;
5285 // Pick bits [20:0] of X.
5286 AArch64_valtype immed = x & 0x1fffff;
5287 update_adr(view, immed);
5288 // Check -2^20 <= X < 2^20
5289 return (size == 64 && Bits<21>::has_overflow((x))
5290 ? This::STATUS_OVERFLOW
5291 : This::STATUS_OKAY);
9363c7c3
JY
5292 }
5293
5294 // Calculate PG(S+A) - PG(address), update adrp instruction.
5295 // R_AARCH64_ADR_PREL_PG_HI21
5296
5297 static inline typename This::Status
5298 adrp(
5299 unsigned char* view,
5300 Address sa,
5301 Address address)
5302 {
9726c3c1
HS
5303 AArch64_valtype x = This::Page(sa) - This::Page(address);
5304 // Pick [32:12] of X.
5305 AArch64_valtype immed = (x >> 12) & 0x1fffff;
5306 update_adr(view, immed);
83a01957
HS
5307 // Check -2^32 <= X < 2^32
5308 return (size == 64 && Bits<33>::has_overflow((x))
9363c7c3
JY
5309 ? This::STATUS_OVERFLOW
5310 : This::STATUS_OKAY);
5311 }
5312
5313 // Calculate PG(S+A) - PG(address), update adrp instruction.
5314 // R_AARCH64_ADR_PREL_PG_HI21
5315
5316 static inline typename This::Status
5317 adrp(unsigned char* view,
5318 const Sized_relobj_file<size, big_endian>* object,
5319 const Symbol_value<size>* psymval,
5320 Address addend,
5321 Address address,
5322 const AArch64_reloc_property* reloc_property)
5323 {
5324 Address sa = psymval->value(object, addend);
9726c3c1
HS
5325 AArch64_valtype x = This::Page(sa) - This::Page(address);
5326 // Pick [32:12] of X.
5327 AArch64_valtype immed = (x >> 12) & 0x1fffff;
5328 update_adr(view, immed);
9363c7c3
JY
5329 return (reloc_property->checkup_x_value(x)
5330 ? This::STATUS_OKAY
5331 : This::STATUS_OVERFLOW);
5332 }
5333
3a531937
JY
5334 // Update mov[n/z] instruction. Check overflow if needed.
5335 // If X >=0, set the instruction to movz and its immediate value to the
5336 // selected bits S.
5337 // If X < 0, set the instruction to movn and its immediate value to
5338 // NOT (selected bits of).
5339
5340 static inline typename This::Status
5341 movnz(unsigned char* view,
9726c3c1 5342 AArch64_valtype x,
3a531937
JY
5343 const AArch64_reloc_property* reloc_property)
5344 {
5345 // Select bits from X.
9726c3c1
HS
5346 Address immed;
5347 bool is_movz;
5348 typedef typename elfcpp::Elf_types<size>::Elf_Swxword SignedW;
5349 if (static_cast<SignedW>(x) >= 0)
5350 {
5351 immed = reloc_property->select_x_value(x);
5352 is_movz = true;
5353 }
5354 else
3a531937 5355 {
9726c3c1 5356 immed = reloc_property->select_x_value(~x);;
3a531937
JY
5357 is_movz = false;
5358 }
5359
5360 // Update movnz instruction.
5361 update_movnz(view, immed, is_movz);
5362
5363 // Do check overflow or alignment if needed.
5364 return (reloc_property->checkup_x_value(x)
5365 ? This::STATUS_OKAY
5366 : This::STATUS_OVERFLOW);
5367 }
5368
83a01957
HS
5369 static inline bool
5370 maybe_apply_stub(unsigned int,
5371 const The_relocate_info*,
5372 const The_rela&,
5373 unsigned char*,
5374 Address,
5375 const Sized_symbol<size>*,
5376 const Symbol_value<size>*,
0bf32ea9
JY
5377 const Sized_relobj_file<size, big_endian>*,
5378 section_size_type);
83a01957 5379
3a531937
JY
5380}; // End of AArch64_relocate_functions
5381
5382
83a01957
HS
5383// For a certain relocation type (usually jump/branch), test to see if the
5384// destination needs a stub to fulfil. If so, re-route the destination of the
5385// original instruction to the stub, note, at this time, the stub has already
5386// been generated.
5387
5388template<int size, bool big_endian>
5389bool
5390AArch64_relocate_functions<size, big_endian>::
5391maybe_apply_stub(unsigned int r_type,
5392 const The_relocate_info* relinfo,
5393 const The_rela& rela,
5394 unsigned char* view,
5395 Address address,
5396 const Sized_symbol<size>* gsym,
5397 const Symbol_value<size>* psymval,
0bf32ea9
JY
5398 const Sized_relobj_file<size, big_endian>* object,
5399 section_size_type current_group_size)
83a01957
HS
5400{
5401 if (parameters->options().relocatable())
5402 return false;
5403
5404 typename elfcpp::Elf_types<size>::Elf_Swxword addend = rela.get_r_addend();
5405 Address branch_target = psymval->value(object, 0) + addend;
a48d0c12
HS
5406 int stub_type =
5407 The_reloc_stub::stub_type_for_reloc(r_type, address, branch_target);
5408 if (stub_type == ST_NONE)
83a01957
HS
5409 return false;
5410
5411 const The_aarch64_relobj* aarch64_relobj =
5412 static_cast<const The_aarch64_relobj*>(object);
81b6fe3b
EC
5413 // We don't create stubs for undefined symbols so don't look for one.
5414 if (gsym && gsym->is_undefined())
5415 {
5416 gold_debug(DEBUG_TARGET,
5417 "stub: looking for a stub for undefined symbol %s in file %s",
5418 gsym->name(), aarch64_relobj->name().c_str());
5419 return false;
5420 }
5421
83a01957
HS
5422 The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx);
5423 gold_assert(stub_table != NULL);
5424
5425 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
5426 typename The_reloc_stub::Key stub_key(stub_type, gsym, object, r_sym, addend);
5427 The_reloc_stub* stub = stub_table->find_reloc_stub(stub_key);
5428 gold_assert(stub != NULL);
5429
5430 Address new_branch_target = stub_table->address() + stub->offset();
5431 typename elfcpp::Swap<size, big_endian>::Valtype branch_offset =
5432 new_branch_target - address;
5433 const AArch64_reloc_property* arp =
5434 aarch64_reloc_property_table->get_reloc_property(r_type);
5435 gold_assert(arp != NULL);
aed56ec5 5436 typename This::Status status = This::template
83a01957
HS
5437 rela_general<32>(view, branch_offset, 0, arp);
5438 if (status != This::STATUS_OKAY)
5439 gold_error(_("Stub is too far away, try a smaller value "
0bf32ea9 5440 "for '--stub-group-size'. The current value is 0x%lx."),
add6016b 5441 static_cast<unsigned long>(current_group_size));
83a01957
HS
5442 return true;
5443}
5444
5445
5446// Group input sections for stub generation.
5447//
5448// We group input sections in an output section so that the total size,
5449// including any padding space due to alignment is smaller than GROUP_SIZE
5450// unless the only input section in group is bigger than GROUP_SIZE already.
5451// Then an ARM stub table is created to follow the last input section
5452// in group. For each group an ARM stub table is created an is placed
5453// after the last group. If STUB_ALWAYS_AFTER_BRANCH is false, we further
5454// extend the group after the stub table.
5455
5456template<int size, bool big_endian>
5457void
5458Target_aarch64<size, big_endian>::group_sections(
5459 Layout* layout,
5460 section_size_type group_size,
5461 bool stubs_always_after_branch,
5462 const Task* task)
5463{
5464 // Group input sections and insert stub table
5465 Layout::Section_list section_list;
5466 layout->get_executable_sections(&section_list);
5467 for (Layout::Section_list::const_iterator p = section_list.begin();
5468 p != section_list.end();
5469 ++p)
5470 {
5471 AArch64_output_section<size, big_endian>* output_section =
5472 static_cast<AArch64_output_section<size, big_endian>*>(*p);
5473 output_section->group_sections(group_size, stubs_always_after_branch,
5474 this, task);
5475 }
5476}
5477
5478
5479// Find the AArch64_input_section object corresponding to the SHNDX-th input
5480// section of RELOBJ.
5481
5482template<int size, bool big_endian>
5483AArch64_input_section<size, big_endian>*
5484Target_aarch64<size, big_endian>::find_aarch64_input_section(
5485 Relobj* relobj, unsigned int shndx) const
5486{
5487 Section_id sid(relobj, shndx);
5488 typename AArch64_input_section_map::const_iterator p =
5489 this->aarch64_input_section_map_.find(sid);
5490 return (p != this->aarch64_input_section_map_.end()) ? p->second : NULL;
5491}
5492
5493
5494// Make a new AArch64_input_section object.
5495
5496template<int size, bool big_endian>
5497AArch64_input_section<size, big_endian>*
5498Target_aarch64<size, big_endian>::new_aarch64_input_section(
5499 Relobj* relobj, unsigned int shndx)
5500{
5501 Section_id sid(relobj, shndx);
5502
5503 AArch64_input_section<size, big_endian>* input_section =
5504 new AArch64_input_section<size, big_endian>(relobj, shndx);
5505 input_section->init();
5506
5507 // Register new AArch64_input_section in map for look-up.
5508 std::pair<typename AArch64_input_section_map::iterator,bool> ins =
5509 this->aarch64_input_section_map_.insert(
5510 std::make_pair(sid, input_section));
5511
5512 // Make sure that it we have not created another AArch64_input_section
5513 // for this input section already.
5514 gold_assert(ins.second);
5515
5516 return input_section;
5517}
5518
5519
5520// Relaxation hook. This is where we do stub generation.
5521
5522template<int size, bool big_endian>
5523bool
5524Target_aarch64<size, big_endian>::do_relax(
5525 int pass,
5526 const Input_objects* input_objects,
5527 Symbol_table* symtab,
5528 Layout* layout ,
5529 const Task* task)
5530{
5531 gold_assert(!parameters->options().relocatable());
5532 if (pass == 1)
5533 {
0bf32ea9
JY
5534 // We don't handle negative stub_group_size right now.
5535 this->stub_group_size_ = abs(parameters->options().stub_group_size());
5536 if (this->stub_group_size_ == 1)
83a01957
HS
5537 {
5538 // Leave room for 4096 4-byte stub entries. If we exceed that, then we
5539 // will fail to link. The user will have to relink with an explicit
5540 // group size option.
0bf32ea9
JY
5541 this->stub_group_size_ = The_reloc_stub::MAX_BRANCH_OFFSET -
5542 4096 * 4;
83a01957 5543 }
0bf32ea9 5544 group_sections(layout, this->stub_group_size_, true, task);
83a01957
HS
5545 }
5546 else
5547 {
5548 // If this is not the first pass, addresses and file offsets have
5549 // been reset at this point, set them here.
5550 for (Stub_table_iterator sp = this->stub_tables_.begin();
5551 sp != this->stub_tables_.end(); ++sp)
5552 {
5553 The_stub_table* stt = *sp;
5554 The_aarch64_input_section* owner = stt->owner();
5555 off_t off = align_address(owner->original_size(),
5556 stt->addralign());
5557 stt->set_address_and_file_offset(owner->address() + off,
5558 owner->offset() + off);
5559 }
5560 }
5561
5562 // Scan relocs for relocation stubs
5563 for (Input_objects::Relobj_iterator op = input_objects->relobj_begin();
5564 op != input_objects->relobj_end();
5565 ++op)
5566 {
5567 The_aarch64_relobj* aarch64_relobj =
5568 static_cast<The_aarch64_relobj*>(*op);
5569 // Lock the object so we can read from it. This is only called
5570 // single-threaded from Layout::finalize, so it is OK to lock.
5571 Task_lock_obj<Object> tl(task, aarch64_relobj);
5572 aarch64_relobj->scan_sections_for_stubs(this, symtab, layout);
5573 }
5574
5575 bool any_stub_table_changed = false;
5576 for (Stub_table_iterator siter = this->stub_tables_.begin();
5577 siter != this->stub_tables_.end() && !any_stub_table_changed; ++siter)
5578 {
5579 The_stub_table* stub_table = *siter;
5580 if (stub_table->update_data_size_changed_p())
5581 {
5582 The_aarch64_input_section* owner = stub_table->owner();
5583 uint64_t address = owner->address();
5584 off_t offset = owner->offset();
5585 owner->reset_address_and_file_offset();
5586 owner->set_address_and_file_offset(address, offset);
5587
5588 any_stub_table_changed = true;
5589 }
5590 }
5591
5592 // Do not continue relaxation.
5593 bool continue_relaxation = any_stub_table_changed;
5594 if (!continue_relaxation)
5595 for (Stub_table_iterator sp = this->stub_tables_.begin();
5596 (sp != this->stub_tables_.end());
5597 ++sp)
5598 (*sp)->finalize_stubs();
5599
5600 return continue_relaxation;
5601}
5602
5603
5604// Make a new Stub_table.
5605
5606template<int size, bool big_endian>
5607Stub_table<size, big_endian>*
5608Target_aarch64<size, big_endian>::new_stub_table(
5609 AArch64_input_section<size, big_endian>* owner)
5610{
5611 Stub_table<size, big_endian>* stub_table =
5612 new Stub_table<size, big_endian>(owner);
5613 stub_table->set_address(align_address(
5614 owner->address() + owner->data_size(), 8));
5615 stub_table->set_file_offset(owner->offset() + owner->data_size());
5616 stub_table->finalize_data_size();
5617
5618 this->stub_tables_.push_back(stub_table);
5619
5620 return stub_table;
5621}
5622
5623
3a531937 5624template<int size, bool big_endian>
7fa5525f 5625uint64_t
3a531937 5626Target_aarch64<size, big_endian>::do_reloc_addend(
7fa5525f 5627 void* arg, unsigned int r_type, uint64_t) const
3a531937
JY
5628{
5629 gold_assert(r_type == elfcpp::R_AARCH64_TLSDESC);
5630 uintptr_t intarg = reinterpret_cast<uintptr_t>(arg);
5631 gold_assert(intarg < this->tlsdesc_reloc_info_.size());
5632 const Tlsdesc_info& ti(this->tlsdesc_reloc_info_[intarg]);
5633 const Symbol_value<size>* psymval = ti.object->local_symbol(ti.r_sym);
5634 gold_assert(psymval->is_tls_symbol());
5635 // The value of a TLS symbol is the offset in the TLS segment.
5636 return psymval->value(ti.object, 0);
5637}
9363c7c3 5638
053a4d68
JY
5639// Return the number of entries in the PLT.
5640
5641template<int size, bool big_endian>
5642unsigned int
5643Target_aarch64<size, big_endian>::plt_entry_count() const
5644{
5645 if (this->plt_ == NULL)
5646 return 0;
5647 return this->plt_->entry_count();
5648}
5649
5650// Return the offset of the first non-reserved PLT entry.
5651
5652template<int size, bool big_endian>
5653unsigned int
5654Target_aarch64<size, big_endian>::first_plt_entry_offset() const
5655{
5656 return this->plt_->first_plt_entry_offset();
5657}
5658
5659// Return the size of each PLT entry.
5660
5661template<int size, bool big_endian>
5662unsigned int
5663Target_aarch64<size, big_endian>::plt_entry_size() const
5664{
5665 return this->plt_->get_plt_entry_size();
5666}
5667
3a531937 5668// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
053a4d68
JY
5669
5670template<int size, bool big_endian>
3a531937
JY
5671void
5672Target_aarch64<size, big_endian>::define_tls_base_symbol(
5673 Symbol_table* symtab, Layout* layout)
053a4d68 5674{
3a531937
JY
5675 if (this->tls_base_symbol_defined_)
5676 return;
5677
5678 Output_segment* tls_segment = layout->tls_segment();
5679 if (tls_segment != NULL)
5680 {
6b0ad2eb 5681 // _TLS_MODULE_BASE_ always points to the beginning of tls segment.
3a531937
JY
5682 symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
5683 Symbol_table::PREDEFINED,
5684 tls_segment, 0, 0,
5685 elfcpp::STT_TLS,
5686 elfcpp::STB_LOCAL,
5687 elfcpp::STV_HIDDEN, 0,
6b0ad2eb 5688 Symbol::SEGMENT_START,
3a531937
JY
5689 true);
5690 }
5691 this->tls_base_symbol_defined_ = true;
053a4d68
JY
5692}
5693
3a531937 5694// Create the reserved PLT and GOT entries for the TLS descriptor resolver.
053a4d68
JY
5695
5696template<int size, bool big_endian>
3a531937
JY
5697void
5698Target_aarch64<size, big_endian>::reserve_tlsdesc_entries(
5699 Symbol_table* symtab, Layout* layout)
053a4d68 5700{
3a531937
JY
5701 if (this->plt_ == NULL)
5702 this->make_plt_section(symtab, layout);
5703
5704 if (!this->plt_->has_tlsdesc_entry())
053a4d68 5705 {
3a531937
JY
5706 // Allocate the TLSDESC_GOT entry.
5707 Output_data_got_aarch64<size, big_endian>* got =
5708 this->got_section(symtab, layout);
5709 unsigned int got_offset = got->add_constant(0);
5710
5711 // Allocate the TLSDESC_PLT entry.
5712 this->plt_->reserve_tlsdesc_entry(got_offset);
053a4d68 5713 }
053a4d68
JY
5714}
5715
3a531937 5716// Create a GOT entry for the TLS module index.
053a4d68
JY
5717
5718template<int size, bool big_endian>
3a531937
JY
5719unsigned int
5720Target_aarch64<size, big_endian>::got_mod_index_entry(
5721 Symbol_table* symtab, Layout* layout,
5722 Sized_relobj_file<size, big_endian>* object)
5723{
5724 if (this->got_mod_index_offset_ == -1U)
5725 {
5726 gold_assert(symtab != NULL && layout != NULL && object != NULL);
5727 Reloc_section* rela_dyn = this->rela_dyn_section(layout);
5728 Output_data_got_aarch64<size, big_endian>* got =
5729 this->got_section(symtab, layout);
5730 unsigned int got_offset = got->add_constant(0);
5731 rela_dyn->add_local(object, 0, elfcpp::R_AARCH64_TLS_DTPMOD64, got,
5732 got_offset, 0);
5733 got->add_constant(0);
5734 this->got_mod_index_offset_ = got_offset;
5735 }
5736 return this->got_mod_index_offset_;
5737}
5738
5739// Optimize the TLS relocation type based on what we know about the
5740// symbol. IS_FINAL is true if the final address of this symbol is
5741// known at link time.
5742
5743template<int size, bool big_endian>
5744tls::Tls_optimization
5745Target_aarch64<size, big_endian>::optimize_tls_reloc(bool is_final,
5746 int r_type)
5747{
5748 // If we are generating a shared library, then we can't do anything
5749 // in the linker
5750 if (parameters->options().shared())
5751 return tls::TLSOPT_NONE;
5752
5753 switch (r_type)
5754 {
5755 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
5756 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
5757 case elfcpp::R_AARCH64_TLSDESC_LD_PREL19:
5758 case elfcpp::R_AARCH64_TLSDESC_ADR_PREL21:
5759 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
5760 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
5761 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
5762 case elfcpp::R_AARCH64_TLSDESC_OFF_G1:
5763 case elfcpp::R_AARCH64_TLSDESC_OFF_G0_NC:
5764 case elfcpp::R_AARCH64_TLSDESC_LDR:
5765 case elfcpp::R_AARCH64_TLSDESC_ADD:
5766 case elfcpp::R_AARCH64_TLSDESC_CALL:
5767 // These are General-Dynamic which permits fully general TLS
5768 // access. Since we know that we are generating an executable,
5769 // we can convert this to Initial-Exec. If we also know that
5770 // this is a local symbol, we can further switch to Local-Exec.
5771 if (is_final)
5772 return tls::TLSOPT_TO_LE;
5773 return tls::TLSOPT_TO_IE;
5774
9726c3c1
HS
5775 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
5776 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
5777 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
5778 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6b0ad2eb
JY
5779 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
5780 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
9726c3c1
HS
5781 // These are Local-Dynamic, which refer to local symbols in the
5782 // dynamic TLS block. Since we know that we generating an
5783 // executable, we can switch to Local-Exec.
5784 return tls::TLSOPT_TO_LE;
5785
3a531937
JY
5786 case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
5787 case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
5788 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5789 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
5790 case elfcpp::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5791 // These are Initial-Exec relocs which get the thread offset
5792 // from the GOT. If we know that we are linking against the
5793 // local symbol, we can switch to Local-Exec, which links the
5794 // thread offset into the instruction.
5795 if (is_final)
5796 return tls::TLSOPT_TO_LE;
5797 return tls::TLSOPT_NONE;
5798
5799 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
5800 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
5801 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
5802 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
5803 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
5804 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
5805 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
5806 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
5807 // When we already have Local-Exec, there is nothing further we
5808 // can do.
5809 return tls::TLSOPT_NONE;
5810
5811 default:
5812 gold_unreachable();
5813 }
5814}
5815
5816// Returns true if this relocation type could be that of a function pointer.
5817
5818template<int size, bool big_endian>
5819inline bool
5820Target_aarch64<size, big_endian>::Scan::possible_function_pointer_reloc(
5821 unsigned int r_type)
5822{
5823 switch (r_type)
5824 {
9726c3c1
HS
5825 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
5826 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
5827 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
5828 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
5829 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
3a531937
JY
5830 {
5831 return true;
5832 }
5833 }
5834 return false;
5835}
5836
5837// For safe ICF, scan a relocation for a local symbol to check if it
5838// corresponds to a function pointer being taken. In that case mark
5839// the function whose pointer was taken as not foldable.
5840
5841template<int size, bool big_endian>
5842inline bool
5843Target_aarch64<size, big_endian>::Scan::local_reloc_may_be_function_pointer(
5844 Symbol_table* ,
053a4d68
JY
5845 Layout* ,
5846 Target_aarch64<size, big_endian>* ,
5847 Sized_relobj_file<size, big_endian>* ,
5848 unsigned int ,
5849 Output_section* ,
5850 const elfcpp::Rela<size, big_endian>& ,
5851 unsigned int r_type,
5852 const elfcpp::Sym<size, big_endian>&)
5853{
9726c3c1 5854 // When building a shared library, do not fold any local symbols.
053a4d68 5855 return (parameters->options().shared()
9363c7c3 5856 || possible_function_pointer_reloc(r_type));
053a4d68
JY
5857}
5858
5859// For safe ICF, scan a relocation for a global symbol to check if it
5860// corresponds to a function pointer being taken. In that case mark
5861// the function whose pointer was taken as not foldable.
5862
5863template<int size, bool big_endian>
5864inline bool
5865Target_aarch64<size, big_endian>::Scan::global_reloc_may_be_function_pointer(
5866 Symbol_table* ,
5867 Layout* ,
5868 Target_aarch64<size, big_endian>* ,
5869 Sized_relobj_file<size, big_endian>* ,
5870 unsigned int ,
5871 Output_section* ,
5872 const elfcpp::Rela<size, big_endian>& ,
5873 unsigned int r_type,
5874 Symbol* gsym)
5875{
5876 // When building a shared library, do not fold symbols whose visibility
5877 // is hidden, internal or protected.
5878 return ((parameters->options().shared()
9363c7c3
JY
5879 && (gsym->visibility() == elfcpp::STV_INTERNAL
5880 || gsym->visibility() == elfcpp::STV_PROTECTED
5881 || gsym->visibility() == elfcpp::STV_HIDDEN))
5882 || possible_function_pointer_reloc(r_type));
053a4d68
JY
5883}
5884
5885// Report an unsupported relocation against a local symbol.
5886
5887template<int size, bool big_endian>
5888void
5889Target_aarch64<size, big_endian>::Scan::unsupported_reloc_local(
5890 Sized_relobj_file<size, big_endian>* object,
5891 unsigned int r_type)
5892{
5893 gold_error(_("%s: unsupported reloc %u against local symbol"),
5894 object->name().c_str(), r_type);
5895}
5896
5897// We are about to emit a dynamic relocation of type R_TYPE. If the
5898// dynamic linker does not support it, issue an error.
5899
5900template<int size, bool big_endian>
5901void
5902Target_aarch64<size, big_endian>::Scan::check_non_pic(Relobj* object,
9363c7c3 5903 unsigned int r_type)
053a4d68
JY
5904{
5905 gold_assert(r_type != elfcpp::R_AARCH64_NONE);
5906
5907 switch (r_type)
5908 {
5909 // These are the relocation types supported by glibc for AARCH64.
5910 case elfcpp::R_AARCH64_NONE:
5911 case elfcpp::R_AARCH64_COPY:
5912 case elfcpp::R_AARCH64_GLOB_DAT:
5913 case elfcpp::R_AARCH64_JUMP_SLOT:
5914 case elfcpp::R_AARCH64_RELATIVE:
5915 case elfcpp::R_AARCH64_TLS_DTPREL64:
5916 case elfcpp::R_AARCH64_TLS_DTPMOD64:
5917 case elfcpp::R_AARCH64_TLS_TPREL64:
5918 case elfcpp::R_AARCH64_TLSDESC:
5919 case elfcpp::R_AARCH64_IRELATIVE:
5920 case elfcpp::R_AARCH64_ABS32:
5921 case elfcpp::R_AARCH64_ABS64:
5922 return;
5923
5924 default:
5925 break;
5926 }
5927
5928 // This prevents us from issuing more than one error per reloc
5929 // section. But we can still wind up issuing more than one
5930 // error per object file.
5931 if (this->issued_non_pic_error_)
5932 return;
5933 gold_assert(parameters->options().output_is_position_independent());
5934 object->error(_("requires unsupported dynamic reloc; "
9363c7c3 5935 "recompile with -fPIC"));
053a4d68
JY
5936 this->issued_non_pic_error_ = true;
5937 return;
5938}
5939
9726c3c1
HS
5940// Return whether we need to make a PLT entry for a relocation of the
5941// given type against a STT_GNU_IFUNC symbol.
5942
5943template<int size, bool big_endian>
5944bool
5945Target_aarch64<size, big_endian>::Scan::reloc_needs_plt_for_ifunc(
5946 Sized_relobj_file<size, big_endian>* object,
5947 unsigned int r_type)
5948{
5949 const AArch64_reloc_property* arp =
5950 aarch64_reloc_property_table->get_reloc_property(r_type);
5951 gold_assert(arp != NULL);
5952
5953 int flags = arp->reference_flags();
5954 if (flags & Symbol::TLS_REF)
5955 {
5956 gold_error(_("%s: unsupported TLS reloc %s for IFUNC symbol"),
5957 object->name().c_str(), arp->name().c_str());
5958 return false;
5959 }
5960 return flags != 0;
5961}
5962
053a4d68
JY
5963// Scan a relocation for a local symbol.
5964
5965template<int size, bool big_endian>
5966inline void
5967Target_aarch64<size, big_endian>::Scan::local(
8e33481e
HS
5968 Symbol_table* symtab,
5969 Layout* layout,
5970 Target_aarch64<size, big_endian>* target,
9363c7c3 5971 Sized_relobj_file<size, big_endian>* object,
8e33481e
HS
5972 unsigned int data_shndx,
5973 Output_section* output_section,
5974 const elfcpp::Rela<size, big_endian>& rela,
053a4d68 5975 unsigned int r_type,
9726c3c1 5976 const elfcpp::Sym<size, big_endian>& lsym,
053a4d68
JY
5977 bool is_discarded)
5978{
5979 if (is_discarded)
5980 return;
5981
8e33481e 5982 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
3a531937 5983 Reloc_section;
3a531937 5984 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
8e33481e 5985
9726c3c1
HS
5986 // A local STT_GNU_IFUNC symbol may require a PLT entry.
5987 bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
5988 if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
5989 target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
5990
053a4d68
JY
5991 switch (r_type)
5992 {
5627d875
IK
5993 case elfcpp::R_AARCH64_NONE:
5994 break;
5995
9363c7c3
JY
5996 case elfcpp::R_AARCH64_ABS32:
5997 case elfcpp::R_AARCH64_ABS16:
8e33481e
HS
5998 if (parameters->options().output_is_position_independent())
5999 {
6000 gold_error(_("%s: unsupported reloc %u in pos independent link."),
6001 object->name().c_str(), r_type);
6002 }
6003 break;
6004
6005 case elfcpp::R_AARCH64_ABS64:
9363c7c3
JY
6006 // If building a shared library or pie, we need to mark this as a dynmic
6007 // reloction, so that the dynamic loader can relocate it.
9363c7c3
JY
6008 if (parameters->options().output_is_position_independent())
6009 {
8e33481e 6010 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
8e33481e
HS
6011 rela_dyn->add_local_relative(object, r_sym,
6012 elfcpp::R_AARCH64_RELATIVE,
6013 output_section,
6014 data_shndx,
6015 rela.get_r_offset(),
6016 rela.get_r_addend(),
9726c3c1 6017 is_ifunc);
9363c7c3
JY
6018 }
6019 break;
6020
8e33481e
HS
6021 case elfcpp::R_AARCH64_PREL64:
6022 case elfcpp::R_AARCH64_PREL32:
6023 case elfcpp::R_AARCH64_PREL16:
6024 break;
6025
4d2f5d58
HS
6026 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
6027 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
5c28a503
HS
6028 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
6029 // The above relocations are used to access GOT entries.
4d2f5d58 6030 {
8032ac03
IK
6031 Output_data_got_aarch64<size, big_endian>* got =
6032 target->got_section(symtab, layout);
4d2f5d58
HS
6033 bool is_new = false;
6034 // This symbol requires a GOT entry.
6035 if (is_ifunc)
6036 is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
6037 else
6038 is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
6039 if (is_new && parameters->options().output_is_position_independent())
6040 target->rela_dyn_section(layout)->
6041 add_local_relative(object,
6042 r_sym,
6043 elfcpp::R_AARCH64_RELATIVE,
6044 got,
6045 object->local_got_offset(r_sym,
6046 GOT_TYPE_STANDARD),
6047 0,
6048 false);
6049 }
6050 break;
6051
8769bc4b
HS
6052 case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263
6053 case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264
6054 case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265
6055 case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266
6056 case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267
6057 case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268
6058 case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269
6059 case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270
6060 case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271
6061 case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272
6062 if (parameters->options().output_is_position_independent())
6063 {
6064 gold_error(_("%s: unsupported reloc %u in pos independent link."),
6065 object->name().c_str(), r_type);
6066 }
6067 break;
6068
3a531937
JY
6069 case elfcpp::R_AARCH64_LD_PREL_LO19: // 273
6070 case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274
6071 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275
6072 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC: // 276
6073 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC: // 277
6074 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC: // 278
6075 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC: // 284
6076 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC: // 285
6077 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC: // 286
8e33481e 6078 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC: // 299
3a531937 6079 break;
053a4d68 6080
8e33481e
HS
6081 // Control flow, pc-relative. We don't need to do anything for a relative
6082 // addressing relocation against a local symbol if it does not reference
6083 // the GOT.
6084 case elfcpp::R_AARCH64_TSTBR14:
6085 case elfcpp::R_AARCH64_CONDBR19:
6086 case elfcpp::R_AARCH64_JUMP26:
6087 case elfcpp::R_AARCH64_CALL26:
6088 break;
6089
6090 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6091 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
6092 {
3a531937
JY
6093 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6094 optimize_tls_reloc(!parameters->options().shared(), r_type);
6095 if (tlsopt == tls::TLSOPT_TO_LE)
6096 break;
6097
8e33481e
HS
6098 layout->set_has_static_tls();
6099 // Create a GOT entry for the tp-relative offset.
8e33481e
HS
6100 if (!parameters->doing_static_link())
6101 {
8032ac03
IK
6102 Output_data_got_aarch64<size, big_endian>* got =
6103 target->got_section(symtab, layout);
8e33481e
HS
6104 got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
6105 target->rela_dyn_section(layout),
6106 elfcpp::R_AARCH64_TLS_TPREL64);
6107 }
6108 else if (!object->local_has_got_offset(r_sym,
6109 GOT_TYPE_TLS_OFFSET))
6110 {
8032ac03
IK
6111 Output_data_got_aarch64<size, big_endian>* got =
6112 target->got_section(symtab, layout);
8e33481e
HS
6113 got->add_local(object, r_sym, GOT_TYPE_TLS_OFFSET);
6114 unsigned int got_offset =
6115 object->local_got_offset(r_sym, GOT_TYPE_TLS_OFFSET);
6116 const elfcpp::Elf_Xword addend = rela.get_r_addend();
6117 gold_assert(addend == 0);
6118 got->add_static_reloc(got_offset, elfcpp::R_AARCH64_TLS_TPREL64,
6119 object, r_sym);
6120 }
6121 }
6122 break;
6123
3a531937
JY
6124 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
6125 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
6126 {
6127 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6128 optimize_tls_reloc(!parameters->options().shared(), r_type);
6129 if (tlsopt == tls::TLSOPT_TO_LE)
6130 {
6131 layout->set_has_static_tls();
6132 break;
6133 }
6134 gold_assert(tlsopt == tls::TLSOPT_NONE);
6135
8032ac03
IK
6136 Output_data_got_aarch64<size, big_endian>* got =
6137 target->got_section(symtab, layout);
3a531937
JY
6138 got->add_local_pair_with_rel(object,r_sym, data_shndx,
6139 GOT_TYPE_TLS_PAIR,
6140 target->rela_dyn_section(layout),
6141 elfcpp::R_AARCH64_TLS_DTPMOD64);
6142 }
6143 break;
6144
1a920511
JY
6145 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
6146 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
6147 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
6148 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
6149 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
8e33481e
HS
6150 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
6151 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
6152 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
6153 {
6154 layout->set_has_static_tls();
6155 bool output_is_shared = parameters->options().shared();
6156 if (output_is_shared)
3a531937 6157 gold_error(_("%s: unsupported TLSLE reloc %u in shared code."),
8e33481e
HS
6158 object->name().c_str(), r_type);
6159 }
9363c7c3
JY
6160 break;
6161
9726c3c1
HS
6162 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
6163 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
6164 {
6165 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6166 optimize_tls_reloc(!parameters->options().shared(), r_type);
6167 if (tlsopt == tls::TLSOPT_NONE)
6168 {
6169 // Create a GOT entry for the module index.
6170 target->got_mod_index_entry(symtab, layout, object);
6171 }
6172 else if (tlsopt != tls::TLSOPT_TO_LE)
6173 unsupported_reloc_local(object, r_type);
6174 }
6175 break;
6176
6177 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
6178 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6b0ad2eb
JY
6179 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
6180 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
9726c3c1
HS
6181 break;
6182
3a531937
JY
6183 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
6184 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
6185 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
6186 {
6187 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6188 optimize_tls_reloc(!parameters->options().shared(), r_type);
6189 target->define_tls_base_symbol(symtab, layout);
6190 if (tlsopt == tls::TLSOPT_NONE)
6191 {
6192 // Create reserved PLT and GOT entries for the resolver.
6193 target->reserve_tlsdesc_entries(symtab, layout);
6194
6195 // Generate a double GOT entry with an R_AARCH64_TLSDESC reloc.
6196 // The R_AARCH64_TLSDESC reloc is resolved lazily, so the GOT
6197 // entry needs to be in an area in .got.plt, not .got. Call
6198 // got_section to make sure the section has been created.
6199 target->got_section(symtab, layout);
6200 Output_data_got<size, big_endian>* got =
6201 target->got_tlsdesc_section();
6202 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
6203 if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC))
6204 {
6205 unsigned int got_offset = got->add_constant(0);
6206 got->add_constant(0);
6207 object->set_local_got_offset(r_sym, GOT_TYPE_TLS_DESC,
6208 got_offset);
6209 Reloc_section* rt = target->rela_tlsdesc_section(layout);
6210 // We store the arguments we need in a vector, and use
6211 // the index into the vector as the parameter to pass
6212 // to the target specific routines.
6213 uintptr_t intarg = target->add_tlsdesc_info(object, r_sym);
6214 void* arg = reinterpret_cast<void*>(intarg);
6215 rt->add_target_specific(elfcpp::R_AARCH64_TLSDESC, arg,
6216 got, got_offset, 0);
6217 }
6218 }
6219 else if (tlsopt != tls::TLSOPT_TO_LE)
6220 unsupported_reloc_local(object, r_type);
6221 }
6222 break;
6223
6224 case elfcpp::R_AARCH64_TLSDESC_CALL:
6225 break;
6226
9363c7c3
JY
6227 default:
6228 unsupported_reloc_local(object, r_type);
053a4d68
JY
6229 }
6230}
6231
6232
6233// Report an unsupported relocation against a global symbol.
6234
6235template<int size, bool big_endian>
6236void
6237Target_aarch64<size, big_endian>::Scan::unsupported_reloc_global(
6238 Sized_relobj_file<size, big_endian>* object,
6239 unsigned int r_type,
6240 Symbol* gsym)
6241{
6242 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
6243 object->name().c_str(), r_type, gsym->demangled_name().c_str());
6244}
6245
6246template<int size, bool big_endian>
6247inline void
6248Target_aarch64<size, big_endian>::Scan::global(
9363c7c3
JY
6249 Symbol_table* symtab,
6250 Layout* layout,
6251 Target_aarch64<size, big_endian>* target,
8e33481e
HS
6252 Sized_relobj_file<size, big_endian> * object,
6253 unsigned int data_shndx,
6254 Output_section* output_section,
6255 const elfcpp::Rela<size, big_endian>& rela,
9363c7c3
JY
6256 unsigned int r_type,
6257 Symbol* gsym)
053a4d68 6258{
9726c3c1
HS
6259 // A STT_GNU_IFUNC symbol may require a PLT entry.
6260 if (gsym->type() == elfcpp::STT_GNU_IFUNC
6261 && this->reloc_needs_plt_for_ifunc(object, r_type))
6262 target->make_plt_entry(symtab, layout, gsym);
6263
8e33481e
HS
6264 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
6265 Reloc_section;
3a531937
JY
6266 const AArch64_reloc_property* arp =
6267 aarch64_reloc_property_table->get_reloc_property(r_type);
6268 gold_assert(arp != NULL);
6269
9363c7c3
JY
6270 switch (r_type)
6271 {
5627d875
IK
6272 case elfcpp::R_AARCH64_NONE:
6273 break;
6274
8e33481e
HS
6275 case elfcpp::R_AARCH64_ABS16:
6276 case elfcpp::R_AARCH64_ABS32:
9363c7c3 6277 case elfcpp::R_AARCH64_ABS64:
8e33481e
HS
6278 {
6279 // Make a PLT entry if necessary.
6280 if (gsym->needs_plt_entry())
6281 {
6282 target->make_plt_entry(symtab, layout, gsym);
6283 // Since this is not a PC-relative relocation, we may be
6284 // taking the address of a function. In that case we need to
6285 // set the entry in the dynamic symbol table to the address of
6286 // the PLT entry.
6287 if (gsym->is_from_dynobj() && !parameters->options().shared())
6288 gsym->set_needs_dynsym_value();
6289 }
6290 // Make a dynamic relocation if necessary.
8e33481e
HS
6291 if (gsym->needs_dynamic_reloc(arp->reference_flags()))
6292 {
6293 if (!parameters->options().output_is_position_independent()
6294 && gsym->may_need_copy_reloc())
6295 {
3a531937
JY
6296 target->copy_reloc(symtab, layout, object,
6297 data_shndx, output_section, gsym, rela);
8e33481e 6298 }
9726c3c1
HS
6299 else if (r_type == elfcpp::R_AARCH64_ABS64
6300 && gsym->type() == elfcpp::STT_GNU_IFUNC
6301 && gsym->can_use_relative_reloc(false)
6302 && !gsym->is_from_dynobj()
6303 && !gsym->is_undefined()
6304 && !gsym->is_preemptible())
6305 {
6306 // Use an IRELATIVE reloc for a locally defined STT_GNU_IFUNC
6307 // symbol. This makes a function address in a PIE executable
6308 // match the address in a shared library that it links against.
6309 Reloc_section* rela_dyn =
6310 target->rela_irelative_section(layout);
6311 unsigned int r_type = elfcpp::R_AARCH64_IRELATIVE;
6312 rela_dyn->add_symbolless_global_addend(gsym, r_type,
6313 output_section, object,
6314 data_shndx,
6315 rela.get_r_offset(),
6316 rela.get_r_addend());
6317 }
8e33481e
HS
6318 else if (r_type == elfcpp::R_AARCH64_ABS64
6319 && gsym->can_use_relative_reloc(false))
6320 {
6321 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
6322 rela_dyn->add_global_relative(gsym,
6323 elfcpp::R_AARCH64_RELATIVE,
6324 output_section,
6325 object,
6326 data_shndx,
6327 rela.get_r_offset(),
6328 rela.get_r_addend(),
6329 false);
6330 }
6331 else
6332 {
6333 check_non_pic(object, r_type);
6334 Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>*
6335 rela_dyn = target->rela_dyn_section(layout);
6336 rela_dyn->add_global(
6337 gsym, r_type, output_section, object,
6338 data_shndx, rela.get_r_offset(),rela.get_r_addend());
6339 }
6340 }
6341 }
6342 break;
6343
6344 case elfcpp::R_AARCH64_PREL16:
6345 case elfcpp::R_AARCH64_PREL32:
6346 case elfcpp::R_AARCH64_PREL64:
9363c7c3
JY
6347 // This is used to fill the GOT absolute address.
6348 if (gsym->needs_plt_entry())
6349 {
6350 target->make_plt_entry(symtab, layout, gsym);
6351 }
6352 break;
6353
8769bc4b
HS
6354 case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263
6355 case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264
6356 case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265
6357 case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266
6358 case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267
6359 case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268
6360 case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269
6361 case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270
6362 case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271
6363 case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272
6364 if (parameters->options().output_is_position_independent())
6365 {
6366 gold_error(_("%s: unsupported reloc %u in pos independent link."),
6367 object->name().c_str(), r_type);
6368 }
6369 break;
6370
3a531937
JY
6371 case elfcpp::R_AARCH64_LD_PREL_LO19: // 273
6372 case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274
6373 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275
6374 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC: // 276
6375 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC: // 277
6376 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC: // 278
6377 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC: // 284
6378 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC: // 285
6379 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC: // 286
8e33481e 6380 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC: // 299
9363c7c3 6381 {
3a531937
JY
6382 if (gsym->needs_plt_entry())
6383 target->make_plt_entry(symtab, layout, gsym);
6384 // Make a dynamic relocation if necessary.
6385 if (gsym->needs_dynamic_reloc(arp->reference_flags()))
6386 {
6387 if (parameters->options().output_is_executable()
6388 && gsym->may_need_copy_reloc())
6389 {
6390 target->copy_reloc(symtab, layout, object,
6391 data_shndx, output_section, gsym, rela);
6392 }
6393 }
9363c7c3
JY
6394 break;
6395 }
6396
6397 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
6398 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
5c28a503 6399 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
9363c7c3 6400 {
5c28a503 6401 // The above relocations are used to access GOT entries.
9363c7c3
JY
6402 // Note a GOT entry is an *address* to a symbol.
6403 // The symbol requires a GOT entry
6404 Output_data_got_aarch64<size, big_endian>* got =
6405 target->got_section(symtab, layout);
6406 if (gsym->final_value_is_known())
6407 {
9726c3c1
HS
6408 // For a STT_GNU_IFUNC symbol we want the PLT address.
6409 if (gsym->type() == elfcpp::STT_GNU_IFUNC)
6410 got->add_global_plt(gsym, GOT_TYPE_STANDARD);
6411 else
6412 got->add_global(gsym, GOT_TYPE_STANDARD);
9363c7c3
JY
6413 }
6414 else
6415 {
9726c3c1
HS
6416 // If this symbol is not fully resolved, we need to add a dynamic
6417 // relocation for it.
9363c7c3 6418 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
9726c3c1
HS
6419
6420 // Use a GLOB_DAT rather than a RELATIVE reloc if:
6421 //
6422 // 1) The symbol may be defined in some other module.
6423 // 2) We are building a shared library and this is a protected
6424 // symbol; using GLOB_DAT means that the dynamic linker can use
6425 // the address of the PLT in the main executable when appropriate
6426 // so that function address comparisons work.
6427 // 3) This is a STT_GNU_IFUNC symbol in position dependent code,
6428 // again so that function address comparisons work.
9363c7c3
JY
6429 if (gsym->is_from_dynobj()
6430 || gsym->is_undefined()
6431 || gsym->is_preemptible()
6432 || (gsym->visibility() == elfcpp::STV_PROTECTED
9726c3c1
HS
6433 && parameters->options().shared())
6434 || (gsym->type() == elfcpp::STT_GNU_IFUNC
6435 && parameters->options().output_is_position_independent()))
9363c7c3
JY
6436 got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
6437 rela_dyn, elfcpp::R_AARCH64_GLOB_DAT);
6438 else
6439 {
9726c3c1
HS
6440 // For a STT_GNU_IFUNC symbol we want to write the PLT
6441 // offset into the GOT, so that function pointer
6442 // comparisons work correctly.
6443 bool is_new;
6444 if (gsym->type() != elfcpp::STT_GNU_IFUNC)
6445 is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
6446 else
6447 {
6448 is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
6449 // Tell the dynamic linker to use the PLT address
6450 // when resolving relocations.
6451 if (gsym->is_from_dynobj()
6452 && !parameters->options().shared())
6453 gsym->set_needs_dynsym_value();
6454 }
6455 if (is_new)
3a531937
JY
6456 {
6457 rela_dyn->add_global_relative(
6458 gsym, elfcpp::R_AARCH64_RELATIVE,
6459 got,
6460 gsym->got_offset(GOT_TYPE_STANDARD),
6461 0,
6462 false);
6463 }
9363c7c3
JY
6464 }
6465 }
6466 break;
6467 }
6468
8e33481e
HS
6469 case elfcpp::R_AARCH64_TSTBR14:
6470 case elfcpp::R_AARCH64_CONDBR19:
9363c7c3
JY
6471 case elfcpp::R_AARCH64_JUMP26:
6472 case elfcpp::R_AARCH64_CALL26:
6473 {
6474 if (gsym->final_value_is_known())
6475 break;
6476
6477 if (gsym->is_defined() &&
6478 !gsym->is_from_dynobj() &&
6479 !gsym->is_preemptible())
6480 break;
6481
6482 // Make plt entry for function call.
9363c7c3
JY
6483 target->make_plt_entry(symtab, layout, gsym);
6484 break;
6485 }
6486
3a531937
JY
6487 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
6488 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC: // General dynamic
6489 {
6490 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6491 optimize_tls_reloc(gsym->final_value_is_known(), r_type);
6492 if (tlsopt == tls::TLSOPT_TO_LE)
6493 {
6494 layout->set_has_static_tls();
6495 break;
6496 }
6497 gold_assert(tlsopt == tls::TLSOPT_NONE);
6498
6499 // General dynamic.
6500 Output_data_got_aarch64<size, big_endian>* got =
6501 target->got_section(symtab, layout);
6502 // Create 2 consecutive entries for module index and offset.
6503 got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
6504 target->rela_dyn_section(layout),
6505 elfcpp::R_AARCH64_TLS_DTPMOD64,
6506 elfcpp::R_AARCH64_TLS_DTPREL64);
6507 }
6508 break;
6509
9726c3c1
HS
6510 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
6511 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC: // Local dynamic
6512 {
6513 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6514 optimize_tls_reloc(!parameters->options().shared(), r_type);
6515 if (tlsopt == tls::TLSOPT_NONE)
6516 {
6517 // Create a GOT entry for the module index.
6518 target->got_mod_index_entry(symtab, layout, object);
6519 }
6520 else if (tlsopt != tls::TLSOPT_TO_LE)
6521 unsupported_reloc_local(object, r_type);
6522 }
6523 break;
6524
6525 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
6b0ad2eb
JY
6526 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6527 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
6528 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: // Other local dynamic
9726c3c1
HS
6529 break;
6530
8e33481e 6531 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3a531937 6532 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: // Initial executable
8e33481e 6533 {
9726c3c1 6534 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
3a531937
JY
6535 optimize_tls_reloc(gsym->final_value_is_known(), r_type);
6536 if (tlsopt == tls::TLSOPT_TO_LE)
6537 break;
6538
8e33481e
HS
6539 layout->set_has_static_tls();
6540 // Create a GOT entry for the tp-relative offset.
6541 Output_data_got_aarch64<size, big_endian>* got
6542 = target->got_section(symtab, layout);
6543 if (!parameters->doing_static_link())
6544 {
6545 got->add_global_with_rel(
6546 gsym, GOT_TYPE_TLS_OFFSET,
6547 target->rela_dyn_section(layout),
6548 elfcpp::R_AARCH64_TLS_TPREL64);
6549 }
6550 if (!gsym->has_got_offset(GOT_TYPE_TLS_OFFSET))
6551 {
6552 got->add_global(gsym, GOT_TYPE_TLS_OFFSET);
6553 unsigned int got_offset =
6554 gsym->got_offset(GOT_TYPE_TLS_OFFSET);
6555 const elfcpp::Elf_Xword addend = rela.get_r_addend();
6556 gold_assert(addend == 0);
6557 got->add_static_reloc(got_offset,
6558 elfcpp::R_AARCH64_TLS_TPREL64, gsym);
6559 }
6560 }
6561 break;
6562
1a920511
JY
6563 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
6564 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
6565 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
6566 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
6567 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
8e33481e
HS
6568 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
6569 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
3a531937 6570 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: // Local executable
8e33481e
HS
6571 layout->set_has_static_tls();
6572 if (parameters->options().shared())
6573 gold_error(_("%s: unsupported TLSLE reloc type %u in shared objects."),
6574 object->name().c_str(), r_type);
6575 break;
6576
3a531937
JY
6577 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
6578 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
6579 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12: // TLS descriptor
6580 {
6581 target->define_tls_base_symbol(symtab, layout);
6582 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
6583 optimize_tls_reloc(gsym->final_value_is_known(), r_type);
6584 if (tlsopt == tls::TLSOPT_NONE)
6585 {
6586 // Create reserved PLT and GOT entries for the resolver.
6587 target->reserve_tlsdesc_entries(symtab, layout);
6588
6589 // Create a double GOT entry with an R_AARCH64_TLSDESC
6590 // relocation. The R_AARCH64_TLSDESC is resolved lazily, so the GOT
6591 // entry needs to be in an area in .got.plt, not .got. Call
6592 // got_section to make sure the section has been created.
6593 target->got_section(symtab, layout);
6594 Output_data_got<size, big_endian>* got =
6595 target->got_tlsdesc_section();
6596 Reloc_section* rt = target->rela_tlsdesc_section(layout);
6597 got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
6598 elfcpp::R_AARCH64_TLSDESC, 0);
6599 }
6600 else if (tlsopt == tls::TLSOPT_TO_IE)
6601 {
6602 // Create a GOT entry for the tp-relative offset.
6603 Output_data_got<size, big_endian>* got
6604 = target->got_section(symtab, layout);
6605 got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
6606 target->rela_dyn_section(layout),
6607 elfcpp::R_AARCH64_TLS_TPREL64);
6608 }
6609 else if (tlsopt != tls::TLSOPT_TO_LE)
6610 unsupported_reloc_global(object, r_type, gsym);
6611 }
6612 break;
6613
6614 case elfcpp::R_AARCH64_TLSDESC_CALL:
6615 break;
6616
9363c7c3 6617 default:
8e33481e 6618 gold_error(_("%s: unsupported reloc type in global scan"),
3a531937
JY
6619 aarch64_reloc_property_table->
6620 reloc_name_in_error_message(r_type).c_str());
9363c7c3 6621 }
053a4d68 6622 return;
9363c7c3
JY
6623} // End of Scan::global
6624
3a531937 6625
9363c7c3
JY
6626// Create the PLT section.
6627template<int size, bool big_endian>
6628void
6629Target_aarch64<size, big_endian>::make_plt_section(
6630 Symbol_table* symtab, Layout* layout)
6631{
6632 if (this->plt_ == NULL)
6633 {
6634 // Create the GOT section first.
6635 this->got_section(symtab, layout);
6636
3a531937
JY
6637 this->plt_ = this->make_data_plt(layout, this->got_, this->got_plt_,
6638 this->got_irelative_);
9363c7c3
JY
6639
6640 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
6641 (elfcpp::SHF_ALLOC
6642 | elfcpp::SHF_EXECINSTR),
6643 this->plt_, ORDER_PLT, false);
6644
6645 // Make the sh_info field of .rela.plt point to .plt.
6646 Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
6647 rela_plt_os->set_info_section(this->plt_->output_section());
6648 }
6649}
6650
3a531937
JY
6651// Return the section for TLSDESC relocations.
6652
6653template<int size, bool big_endian>
6654typename Target_aarch64<size, big_endian>::Reloc_section*
6655Target_aarch64<size, big_endian>::rela_tlsdesc_section(Layout* layout) const
6656{
6657 return this->plt_section()->rela_tlsdesc(layout);
6658}
6659
9363c7c3
JY
6660// Create a PLT entry for a global symbol.
6661
6662template<int size, bool big_endian>
6663void
6664Target_aarch64<size, big_endian>::make_plt_entry(
6665 Symbol_table* symtab,
6666 Layout* layout,
6667 Symbol* gsym)
6668{
6669 if (gsym->has_plt_offset())
6670 return;
6671
6672 if (this->plt_ == NULL)
6673 this->make_plt_section(symtab, layout);
6674
9726c3c1
HS
6675 this->plt_->add_entry(symtab, layout, gsym);
6676}
6677
6678// Make a PLT entry for a local STT_GNU_IFUNC symbol.
6679
6680template<int size, bool big_endian>
6681void
6682Target_aarch64<size, big_endian>::make_local_ifunc_plt_entry(
6683 Symbol_table* symtab, Layout* layout,
6684 Sized_relobj_file<size, big_endian>* relobj,
6685 unsigned int local_sym_index)
6686{
6687 if (relobj->local_has_plt_offset(local_sym_index))
6688 return;
6689 if (this->plt_ == NULL)
6690 this->make_plt_section(symtab, layout);
6691 unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
6692 relobj,
6693 local_sym_index);
6694 relobj->set_local_plt_offset(local_sym_index, plt_offset);
053a4d68
JY
6695}
6696
6697template<int size, bool big_endian>
6698void
6699Target_aarch64<size, big_endian>::gc_process_relocs(
6700 Symbol_table* symtab,
6701 Layout* layout,
6702 Sized_relobj_file<size, big_endian>* object,
6703 unsigned int data_shndx,
6704 unsigned int sh_type,
6705 const unsigned char* prelocs,
6706 size_t reloc_count,
6707 Output_section* output_section,
6708 bool needs_special_offset_handling,
6709 size_t local_symbol_count,
6710 const unsigned char* plocal_symbols)
6711{
4d625b70
CC
6712 typedef Target_aarch64<size, big_endian> Aarch64;
6713 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
6714 Classify_reloc;
6715
053a4d68
JY
6716 if (sh_type == elfcpp::SHT_REL)
6717 {
6718 return;
6719 }
6720
4d625b70 6721 gold::gc_process_relocs<size, big_endian, Aarch64, Scan, Classify_reloc>(
053a4d68
JY
6722 symtab,
6723 layout,
6724 this,
6725 object,
6726 data_shndx,
6727 prelocs,
6728 reloc_count,
6729 output_section,
6730 needs_special_offset_handling,
6731 local_symbol_count,
6732 plocal_symbols);
6733}
6734
6735// Scan relocations for a section.
6736
6737template<int size, bool big_endian>
6738void
6739Target_aarch64<size, big_endian>::scan_relocs(
6740 Symbol_table* symtab,
6741 Layout* layout,
6742 Sized_relobj_file<size, big_endian>* object,
6743 unsigned int data_shndx,
6744 unsigned int sh_type,
6745 const unsigned char* prelocs,
6746 size_t reloc_count,
6747 Output_section* output_section,
6748 bool needs_special_offset_handling,
6749 size_t local_symbol_count,
6750 const unsigned char* plocal_symbols)
6751{
4d625b70
CC
6752 typedef Target_aarch64<size, big_endian> Aarch64;
6753 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
6754 Classify_reloc;
6755
053a4d68
JY
6756 if (sh_type == elfcpp::SHT_REL)
6757 {
6758 gold_error(_("%s: unsupported REL reloc section"),
6759 object->name().c_str());
6760 return;
6761 }
4d625b70
CC
6762
6763 gold::scan_relocs<size, big_endian, Aarch64, Scan, Classify_reloc>(
053a4d68
JY
6764 symtab,
6765 layout,
6766 this,
6767 object,
6768 data_shndx,
6769 prelocs,
6770 reloc_count,
6771 output_section,
6772 needs_special_offset_handling,
6773 local_symbol_count,
6774 plocal_symbols);
6775}
6776
3a531937
JY
6777// Return the value to use for a dynamic which requires special
6778// treatment. This is how we support equality comparisons of function
6779// pointers across shared library boundaries, as described in the
6780// processor specific ABI supplement.
6781
83a01957 6782template<int size, bool big_endian>
3a531937 6783uint64_t
83a01957 6784Target_aarch64<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
3a531937
JY
6785{
6786 gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
6787 return this->plt_address_for_global(gsym);
6788}
6789
83a01957 6790
053a4d68
JY
6791// Finalize the sections.
6792
6793template<int size, bool big_endian>
6794void
6795Target_aarch64<size, big_endian>::do_finalize_sections(
9363c7c3 6796 Layout* layout,
053a4d68 6797 const Input_objects*,
9363c7c3 6798 Symbol_table* symtab)
053a4d68 6799{
9363c7c3
JY
6800 const Reloc_section* rel_plt = (this->plt_ == NULL
6801 ? NULL
6802 : this->plt_->rela_plt());
6803 layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
6804 this->rela_dyn_, true, false);
6805
3a531937
JY
6806 // Emit any relocs we saved in an attempt to avoid generating COPY
6807 // relocs.
6808 if (this->copy_relocs_.any_saved_relocs())
6809 this->copy_relocs_.emit(this->rela_dyn_section(layout));
6810
6811 // Fill in some more dynamic tags.
6812 Output_data_dynamic* const odyn = layout->dynamic_data();
6813 if (odyn != NULL)
6814 {
6815 if (this->plt_ != NULL
6816 && this->plt_->output_section() != NULL
6817 && this->plt_ ->has_tlsdesc_entry())
6818 {
6819 unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
6820 unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
6821 this->got_->finalize_data_size();
6822 odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT,
6823 this->plt_, plt_offset);
6824 odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT,
6825 this->got_, got_offset);
6826 }
6827 }
6828
9363c7c3
JY
6829 // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
6830 // the .got.plt section.
6831 Symbol* sym = this->global_offset_table_;
6832 if (sym != NULL)
6833 {
6834 uint64_t data_size = this->got_plt_->current_data_size();
6835 symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
6836
6837 // If the .got section is more than 0x8000 bytes, we add
6838 // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
6839 // bit relocations have a greater chance of working.
6840 if (data_size >= 0x8000)
6841 symtab->get_sized_symbol<size>(sym)->set_value(
6842 symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
6843 }
6844
6845 if (parameters->doing_static_link()
6846 && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
6847 {
6848 // If linking statically, make sure that the __rela_iplt symbols
6849 // were defined if necessary, even if we didn't create a PLT.
6850 static const Define_symbol_in_segment syms[] =
6851 {
6852 {
6853 "__rela_iplt_start", // name
6854 elfcpp::PT_LOAD, // segment_type
6855 elfcpp::PF_W, // segment_flags_set
6856 elfcpp::PF(0), // segment_flags_clear
6857 0, // value
6858 0, // size
6859 elfcpp::STT_NOTYPE, // type
6860 elfcpp::STB_GLOBAL, // binding
6861 elfcpp::STV_HIDDEN, // visibility
6862 0, // nonvis
6863 Symbol::SEGMENT_START, // offset_from_base
6864 true // only_if_ref
6865 },
6866 {
6867 "__rela_iplt_end", // name
6868 elfcpp::PT_LOAD, // segment_type
6869 elfcpp::PF_W, // segment_flags_set
6870 elfcpp::PF(0), // segment_flags_clear
6871 0, // value
6872 0, // size
6873 elfcpp::STT_NOTYPE, // type
6874 elfcpp::STB_GLOBAL, // binding
6875 elfcpp::STV_HIDDEN, // visibility
6876 0, // nonvis
6877 Symbol::SEGMENT_START, // offset_from_base
6878 true // only_if_ref
6879 }
6880 };
6881
6882 symtab->define_symbols(layout, 2, syms,
6883 layout->script_options()->saw_sections_clause());
6884 }
6885
053a4d68
JY
6886 return;
6887}
6888
6889// Perform a relocation.
6890
6891template<int size, bool big_endian>
6892inline bool
6893Target_aarch64<size, big_endian>::Relocate::relocate(
9363c7c3 6894 const Relocate_info<size, big_endian>* relinfo,
91a65d2f 6895 unsigned int,
9363c7c3 6896 Target_aarch64<size, big_endian>* target,
053a4d68 6897 Output_section* ,
9363c7c3 6898 size_t relnum,
91a65d2f 6899 const unsigned char* preloc,
9363c7c3
JY
6900 const Sized_symbol<size>* gsym,
6901 const Symbol_value<size>* psymval,
6902 unsigned char* view,
6903 typename elfcpp::Elf_types<size>::Elf_Addr address,
053a4d68
JY
6904 section_size_type /* view_size */)
6905{
9363c7c3
JY
6906 if (view == NULL)
6907 return true;
6908
6909 typedef AArch64_relocate_functions<size, big_endian> Reloc;
6910
91a65d2f
AM
6911 const elfcpp::Rela<size, big_endian> rela(preloc);
6912 unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
9363c7c3
JY
6913 const AArch64_reloc_property* reloc_property =
6914 aarch64_reloc_property_table->get_reloc_property(r_type);
6915
6916 if (reloc_property == NULL)
6917 {
6918 std::string reloc_name =
6919 aarch64_reloc_property_table->reloc_name_in_error_message(r_type);
6920 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
6921 _("cannot relocate %s in object file"),
6922 reloc_name.c_str());
6923 return true;
6924 }
6925
6926 const Sized_relobj_file<size, big_endian>* object = relinfo->object;
6927
6928 // Pick the value to use for symbols defined in the PLT.
6929 Symbol_value<size> symval;
6930 if (gsym != NULL
6931 && gsym->use_plt_offset(reloc_property->reference_flags()))
6932 {
6933 symval.set_output_value(target->plt_address_for_global(gsym));
6934 psymval = &symval;
6935 }
6936 else if (gsym == NULL && psymval->is_ifunc_symbol())
6937 {
6938 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
6939 if (object->local_has_plt_offset(r_sym))
6940 {
6941 symval.set_output_value(target->plt_address_for_local(object, r_sym));
6942 psymval = &symval;
6943 }
6944 }
6945
6946 const elfcpp::Elf_Xword addend = rela.get_r_addend();
6947
6948 // Get the GOT offset if needed.
6949 // For aarch64, the GOT pointer points to the start of the GOT section.
6950 bool have_got_offset = false;
6951 int got_offset = 0;
6952 int got_base = (target->got_ != NULL
6953 ? (target->got_->current_data_size() >= 0x8000
6954 ? 0x8000 : 0)
6955 : 0);
6956 switch (r_type)
6957 {
6958 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0:
6959 case elfcpp::R_AARCH64_MOVW_GOTOFF_G0_NC:
6960 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1:
6961 case elfcpp::R_AARCH64_MOVW_GOTOFF_G1_NC:
6962 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2:
6963 case elfcpp::R_AARCH64_MOVW_GOTOFF_G2_NC:
6964 case elfcpp::R_AARCH64_MOVW_GOTOFF_G3:
6965 case elfcpp::R_AARCH64_GOTREL64:
6966 case elfcpp::R_AARCH64_GOTREL32:
6967 case elfcpp::R_AARCH64_GOT_LD_PREL19:
6968 case elfcpp::R_AARCH64_LD64_GOTOFF_LO15:
6969 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
6970 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
6971 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
6972 if (gsym != NULL)
6973 {
6974 gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
6975 got_offset = gsym->got_offset(GOT_TYPE_STANDARD) - got_base;
6976 }
6977 else
6978 {
6979 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
6980 gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
6981 got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
6982 - got_base);
6983 }
6984 have_got_offset = true;
6985 break;
8e33481e 6986
9363c7c3
JY
6987 default:
6988 break;
6989 }
6990
6991 typename Reloc::Status reloc_status = Reloc::STATUS_OKAY;
6992 typename elfcpp::Elf_types<size>::Elf_Addr value;
6993 switch (r_type)
6994 {
6995 case elfcpp::R_AARCH64_NONE:
6996 break;
6997
6998 case elfcpp::R_AARCH64_ABS64:
0eccf19f
CC
6999 if (!parameters->options().apply_dynamic_relocs()
7000 && parameters->options().output_is_position_independent()
7001 && gsym != NULL
7002 && gsym->needs_dynamic_reloc(reloc_property->reference_flags())
7003 && !gsym->can_use_relative_reloc(false))
7004 // We have generated an absolute dynamic relocation, so do not
7005 // apply the relocation statically. (Works around bugs in older
7006 // Android dynamic linkers.)
7007 break;
9363c7c3
JY
7008 reloc_status = Reloc::template rela_ua<64>(
7009 view, object, psymval, addend, reloc_property);
7010 break;
7011
7012 case elfcpp::R_AARCH64_ABS32:
0eccf19f
CC
7013 if (!parameters->options().apply_dynamic_relocs()
7014 && parameters->options().output_is_position_independent()
7015 && gsym != NULL
7016 && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
7017 // We have generated an absolute dynamic relocation, so do not
7018 // apply the relocation statically. (Works around bugs in older
7019 // Android dynamic linkers.)
7020 break;
9363c7c3
JY
7021 reloc_status = Reloc::template rela_ua<32>(
7022 view, object, psymval, addend, reloc_property);
7023 break;
7024
7025 case elfcpp::R_AARCH64_ABS16:
0eccf19f
CC
7026 if (!parameters->options().apply_dynamic_relocs()
7027 && parameters->options().output_is_position_independent()
7028 && gsym != NULL
7029 && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
7030 // We have generated an absolute dynamic relocation, so do not
7031 // apply the relocation statically. (Works around bugs in older
7032 // Android dynamic linkers.)
7033 break;
9363c7c3
JY
7034 reloc_status = Reloc::template rela_ua<16>(
7035 view, object, psymval, addend, reloc_property);
7036 break;
7037
7038 case elfcpp::R_AARCH64_PREL64:
7039 reloc_status = Reloc::template pcrela_ua<64>(
7040 view, object, psymval, addend, address, reloc_property);
83a01957 7041 break;
9363c7c3
JY
7042
7043 case elfcpp::R_AARCH64_PREL32:
7044 reloc_status = Reloc::template pcrela_ua<32>(
7045 view, object, psymval, addend, address, reloc_property);
83a01957 7046 break;
9363c7c3
JY
7047
7048 case elfcpp::R_AARCH64_PREL16:
7049 reloc_status = Reloc::template pcrela_ua<16>(
7050 view, object, psymval, addend, address, reloc_property);
83a01957 7051 break;
9363c7c3 7052
8769bc4b
HS
7053 case elfcpp::R_AARCH64_MOVW_UABS_G0:
7054 case elfcpp::R_AARCH64_MOVW_UABS_G0_NC:
7055 case elfcpp::R_AARCH64_MOVW_UABS_G1:
7056 case elfcpp::R_AARCH64_MOVW_UABS_G1_NC:
7057 case elfcpp::R_AARCH64_MOVW_UABS_G2:
7058 case elfcpp::R_AARCH64_MOVW_UABS_G2_NC:
7059 case elfcpp::R_AARCH64_MOVW_UABS_G3:
7060 reloc_status = Reloc::template rela_general<32>(
7061 view, object, psymval, addend, reloc_property);
7062 break;
7063 case elfcpp::R_AARCH64_MOVW_SABS_G0:
7064 case elfcpp::R_AARCH64_MOVW_SABS_G1:
7065 case elfcpp::R_AARCH64_MOVW_SABS_G2:
7066 reloc_status = Reloc::movnz(view, psymval->value(object, addend),
7067 reloc_property);
7068 break;
7069
9726c3c1
HS
7070 case elfcpp::R_AARCH64_LD_PREL_LO19:
7071 reloc_status = Reloc::template pcrela_general<32>(
7072 view, object, psymval, addend, address, reloc_property);
7073 break;
7074
7075 case elfcpp::R_AARCH64_ADR_PREL_LO21:
7076 reloc_status = Reloc::adr(view, object, psymval, addend,
7077 address, reloc_property);
7078 break;
7079
9363c7c3
JY
7080 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
7081 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
7082 reloc_status = Reloc::adrp(view, object, psymval, addend, address,
7083 reloc_property);
7084 break;
7085
7086 case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC:
7087 case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC:
7088 case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC:
7089 case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC:
7090 case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC:
7091 case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
7092 reloc_status = Reloc::template rela_general<32>(
7093 view, object, psymval, addend, reloc_property);
7094 break;
7095
3a531937
JY
7096 case elfcpp::R_AARCH64_CALL26:
7097 if (this->skip_call_tls_get_addr_)
7098 {
7099 // Double check that the TLSGD insn has been optimized away.
7100 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
7101 Insntype insn = elfcpp::Swap<32, big_endian>::readval(
7102 reinterpret_cast<Insntype*>(view));
7103 gold_assert((insn & 0xff000000) == 0x91000000);
7104
7105 reloc_status = Reloc::STATUS_OKAY;
7106 this->skip_call_tls_get_addr_ = false;
7107 // Return false to stop further processing this reloc.
7108 return false;
7109 }
d8e90251 7110 // Fall through.
83a01957
HS
7111 case elfcpp::R_AARCH64_JUMP26:
7112 if (Reloc::maybe_apply_stub(r_type, relinfo, rela, view, address,
0bf32ea9
JY
7113 gsym, psymval, object,
7114 target->stub_group_size_))
83a01957 7115 break;
d8e90251 7116 // Fall through.
8e33481e
HS
7117 case elfcpp::R_AARCH64_TSTBR14:
7118 case elfcpp::R_AARCH64_CONDBR19:
9363c7c3
JY
7119 reloc_status = Reloc::template pcrela_general<32>(
7120 view, object, psymval, addend, address, reloc_property);
7121 break;
7122
7123 case elfcpp::R_AARCH64_ADR_GOT_PAGE:
7124 gold_assert(have_got_offset);
7125 value = target->got_->address() + got_base + got_offset;
7126 reloc_status = Reloc::adrp(view, value + addend, address);
7127 break;
7128
7129 case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
7130 gold_assert(have_got_offset);
7131 value = target->got_->address() + got_base + got_offset;
7132 reloc_status = Reloc::template rela_general<32>(
7133 view, value, addend, reloc_property);
7134 break;
7135
5c28a503
HS
7136 case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
7137 {
7138 gold_assert(have_got_offset);
7139 value = target->got_->address() + got_base + got_offset + addend -
7140 Reloc::Page(target->got_->address() + got_base);
7141 if ((value & 7) != 0)
7142 reloc_status = Reloc::STATUS_OVERFLOW;
7143 else
7144 reloc_status = Reloc::template reloc_common<32>(
7145 view, value, reloc_property);
7146 break;
7147 }
7148
3a531937
JY
7149 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
7150 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
9726c3c1
HS
7151 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
7152 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
7153 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
7154 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6b0ad2eb
JY
7155 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
7156 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
8e33481e
HS
7157 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
7158 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
1a920511
JY
7159 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
7160 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
7161 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
7162 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
7163 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
8e33481e
HS
7164 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
7165 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
7166 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
3a531937
JY
7167 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
7168 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
7169 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
7170 case elfcpp::R_AARCH64_TLSDESC_CALL:
8e33481e
HS
7171 reloc_status = relocate_tls(relinfo, target, relnum, rela, r_type,
7172 gsym, psymval, view, address);
7173 break;
7174
3a531937
JY
7175 // These are dynamic relocations, which are unexpected when linking.
7176 case elfcpp::R_AARCH64_COPY:
7177 case elfcpp::R_AARCH64_GLOB_DAT:
7178 case elfcpp::R_AARCH64_JUMP_SLOT:
7179 case elfcpp::R_AARCH64_RELATIVE:
7180 case elfcpp::R_AARCH64_IRELATIVE:
7181 case elfcpp::R_AARCH64_TLS_DTPREL64:
7182 case elfcpp::R_AARCH64_TLS_DTPMOD64:
7183 case elfcpp::R_AARCH64_TLS_TPREL64:
7184 case elfcpp::R_AARCH64_TLSDESC:
9363c7c3 7185 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
3a531937 7186 _("unexpected reloc %u in object file"),
9363c7c3
JY
7187 r_type);
7188 break;
3a531937
JY
7189
7190 default:
7191 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
7192 _("unsupported reloc %s"),
7193 reloc_property->name().c_str());
7194 break;
9363c7c3
JY
7195 }
7196
7197 // Report any errors.
7198 switch (reloc_status)
7199 {
7200 case Reloc::STATUS_OKAY:
7201 break;
7202 case Reloc::STATUS_OVERFLOW:
7203 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
7204 _("relocation overflow in %s"),
7205 reloc_property->name().c_str());
7206 break;
7207 case Reloc::STATUS_BAD_RELOC:
7208 gold_error_at_location(
7209 relinfo,
7210 relnum,
7211 rela.get_r_offset(),
7212 _("unexpected opcode while processing relocation %s"),
7213 reloc_property->name().c_str());
7214 break;
7215 default:
7216 gold_unreachable();
7217 }
7218
053a4d68
JY
7219 return true;
7220}
7221
3a531937 7222
8e33481e
HS
7223template<int size, bool big_endian>
7224inline
83a01957 7225typename AArch64_relocate_functions<size, big_endian>::Status
8e33481e 7226Target_aarch64<size, big_endian>::Relocate::relocate_tls(
83a01957 7227 const Relocate_info<size, big_endian>* relinfo,
3a531937
JY
7228 Target_aarch64<size, big_endian>* target,
7229 size_t relnum,
7230 const elfcpp::Rela<size, big_endian>& rela,
7231 unsigned int r_type, const Sized_symbol<size>* gsym,
7232 const Symbol_value<size>* psymval,
7233 unsigned char* view,
8e33481e
HS
7234 typename elfcpp::Elf_types<size>::Elf_Addr address)
7235{
83a01957 7236 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
3a531937 7237 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
8e33481e 7238
3a531937
JY
7239 Output_segment* tls_segment = relinfo->layout->tls_segment();
7240 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7241 const AArch64_reloc_property* reloc_property =
7242 aarch64_reloc_property_table->get_reloc_property(r_type);
8e33481e
HS
7243 gold_assert(reloc_property != NULL);
7244
3a531937
JY
7245 const bool is_final = (gsym == NULL
7246 ? !parameters->options().shared()
7247 : gsym->final_value_is_known());
7248 tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
7249 optimize_tls_reloc(is_final, r_type);
7250
83a01957 7251 Sized_relobj_file<size, big_endian>* object = relinfo->object;
3a531937 7252 int tls_got_offset_type;
8e33481e
HS
7253 switch (r_type)
7254 {
3a531937
JY
7255 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
7256 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC: // Global-dynamic
7257 {
7258 if (tlsopt == tls::TLSOPT_TO_LE)
7259 {
7260 if (tls_segment == NULL)
7261 {
7262 gold_assert(parameters->errors()->error_count() > 0
7263 || issue_undefined_symbol_error(gsym));
7264 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7265 }
7266 return tls_gd_to_le(relinfo, target, rela, r_type, view,
7267 psymval);
7268 }
7269 else if (tlsopt == tls::TLSOPT_NONE)
7270 {
7271 tls_got_offset_type = GOT_TYPE_TLS_PAIR;
7272 // Firstly get the address for the got entry.
7273 typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
7274 if (gsym != NULL)
7275 {
7276 gold_assert(gsym->has_got_offset(tls_got_offset_type));
7277 got_entry_address = target->got_->address() +
7278 gsym->got_offset(tls_got_offset_type);
7279 }
7280 else
7281 {
7282 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
7283 gold_assert(
7284 object->local_has_got_offset(r_sym, tls_got_offset_type));
7285 got_entry_address = target->got_->address() +
7286 object->local_got_offset(r_sym, tls_got_offset_type);
7287 }
7288
7289 // Relocate the address into adrp/ld, adrp/add pair.
7290 switch (r_type)
7291 {
7292 case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
7293 return aarch64_reloc_funcs::adrp(
7294 view, got_entry_address + addend, address);
7295
7296 break;
7297
7298 case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
7299 return aarch64_reloc_funcs::template rela_general<32>(
7300 view, got_entry_address, addend, reloc_property);
7301 break;
7302
7303 default:
9726c3c1 7304 gold_unreachable();
3a531937
JY
7305 }
7306 }
7307 gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
7308 _("unsupported gd_to_ie relaxation on %u"),
7309 r_type);
7310 }
7311 break;
7312
9726c3c1
HS
7313 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
7314 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC: // Local-dynamic
7315 {
7316 if (tlsopt == tls::TLSOPT_TO_LE)
7317 {
7318 if (tls_segment == NULL)
7319 {
7320 gold_assert(parameters->errors()->error_count() > 0
7321 || issue_undefined_symbol_error(gsym));
7322 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7323 }
7324 return this->tls_ld_to_le(relinfo, target, rela, r_type, view,
7325 psymval);
7326 }
7327
7328 gold_assert(tlsopt == tls::TLSOPT_NONE);
7329 // Relocate the field with the offset of the GOT entry for
7330 // the module index.
7331 typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
7332 got_entry_address = (target->got_mod_index_entry(NULL, NULL, NULL) +
7333 target->got_->address());
7334
7335 switch (r_type)
7336 {
7337 case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
7338 return aarch64_reloc_funcs::adrp(
7339 view, got_entry_address + addend, address);
7340 break;
7341
7342 case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
7343 return aarch64_reloc_funcs::template rela_general<32>(
7344 view, got_entry_address, addend, reloc_property);
7345 break;
7346
7347 default:
7348 gold_unreachable();
7349 }
7350 }
7351 break;
7352
7353 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
6b0ad2eb
JY
7354 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
7355 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
7356 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: // Other local-dynamic
9726c3c1
HS
7357 {
7358 AArch64_address value = psymval->value(object, 0);
7359 if (tlsopt == tls::TLSOPT_TO_LE)
7360 {
7361 if (tls_segment == NULL)
7362 {
7363 gold_assert(parameters->errors()->error_count() > 0
7364 || issue_undefined_symbol_error(gsym));
7365 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7366 }
9726c3c1
HS
7367 }
7368 switch (r_type)
7369 {
7370 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
7371 return aarch64_reloc_funcs::movnz(view, value + addend,
7372 reloc_property);
7373 break;
7374
7375 case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6b0ad2eb
JY
7376 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
7377 case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
9726c3c1
HS
7378 return aarch64_reloc_funcs::template rela_general<32>(
7379 view, value, addend, reloc_property);
7380 break;
7381
7382 default:
7383 gold_unreachable();
7384 }
7385 // We should never reach here.
7386 }
7387 break;
7388
8e33481e 7389 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3a531937 7390 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: // Initial-exec
8e33481e 7391 {
3a531937
JY
7392 if (tlsopt == tls::TLSOPT_TO_LE)
7393 {
7394 if (tls_segment == NULL)
7395 {
7396 gold_assert(parameters->errors()->error_count() > 0
7397 || issue_undefined_symbol_error(gsym));
7398 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7399 }
7400 return tls_ie_to_le(relinfo, target, rela, r_type, view,
7401 psymval);
7402 }
7403 tls_got_offset_type = GOT_TYPE_TLS_OFFSET;
7404
7405 // Firstly get the address for the got entry.
8e33481e
HS
7406 typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
7407 if (gsym != NULL)
7408 {
3a531937 7409 gold_assert(gsym->has_got_offset(tls_got_offset_type));
8e33481e 7410 got_entry_address = target->got_->address() +
3a531937 7411 gsym->got_offset(tls_got_offset_type);
8e33481e
HS
7412 }
7413 else
7414 {
7415 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
7416 gold_assert(
3a531937 7417 object->local_has_got_offset(r_sym, tls_got_offset_type));
8e33481e 7418 got_entry_address = target->got_->address() +
3a531937 7419 object->local_got_offset(r_sym, tls_got_offset_type);
8e33481e 7420 }
3a531937
JY
7421 // Relocate the address into adrp/ld, adrp/add pair.
7422 switch (r_type)
8e33481e 7423 {
3a531937
JY
7424 case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
7425 return aarch64_reloc_funcs::adrp(view, got_entry_address + addend,
7426 address);
7427 break;
7428 case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
7429 return aarch64_reloc_funcs::template rela_general<32>(
7430 view, got_entry_address, addend, reloc_property);
7431 default:
9726c3c1 7432 gold_unreachable();
8e33481e 7433 }
8e33481e 7434 }
3a531937 7435 // We shall never reach here.
8e33481e
HS
7436 break;
7437
1a920511
JY
7438 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
7439 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
7440 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
7441 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
7442 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
8e33481e
HS
7443 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
7444 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
7445 case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
7446 {
8e33481e 7447 gold_assert(tls_segment != NULL);
3a531937 7448 AArch64_address value = psymval->value(object, 0);
8e33481e
HS
7449
7450 if (!parameters->options().shared())
7451 {
3a531937
JY
7452 AArch64_address aligned_tcb_size =
7453 align_address(target->tcb_size(),
7454 tls_segment->maximum_alignment());
1a920511
JY
7455 value += aligned_tcb_size;
7456 switch (r_type)
7457 {
7458 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
7459 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
7460 case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
7461 return aarch64_reloc_funcs::movnz(view, value + addend,
7462 reloc_property);
7463 default:
7464 return aarch64_reloc_funcs::template
7465 rela_general<32>(view,
7466 value,
7467 addend,
7468 reloc_property);
7469 }
8e33481e
HS
7470 }
7471 else
7472 gold_error(_("%s: unsupported reloc %u "
7473 "in non-static TLSLE mode."),
7474 object->name().c_str(), r_type);
7475 }
7476 break;
7477
3a531937
JY
7478 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
7479 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
7480 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
7481 case elfcpp::R_AARCH64_TLSDESC_CALL:
7482 {
7483 if (tlsopt == tls::TLSOPT_TO_LE)
7484 {
7485 if (tls_segment == NULL)
7486 {
7487 gold_assert(parameters->errors()->error_count() > 0
7488 || issue_undefined_symbol_error(gsym));
7489 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7490 }
7491 return tls_desc_gd_to_le(relinfo, target, rela, r_type,
7492 view, psymval);
7493 }
7494 else
7495 {
7496 tls_got_offset_type = (tlsopt == tls::TLSOPT_TO_IE
7497 ? GOT_TYPE_TLS_OFFSET
7498 : GOT_TYPE_TLS_DESC);
7499 unsigned int got_tlsdesc_offset = 0;
7500 if (r_type != elfcpp::R_AARCH64_TLSDESC_CALL
7501 && tlsopt == tls::TLSOPT_NONE)
7502 {
7503 // We created GOT entries in the .got.tlsdesc portion of the
7504 // .got.plt section, but the offset stored in the symbol is the
7505 // offset within .got.tlsdesc.
7506 got_tlsdesc_offset = (target->got_->data_size()
7507 + target->got_plt_section()->data_size());
7508 }
7509 typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
7510 if (gsym != NULL)
7511 {
7512 gold_assert(gsym->has_got_offset(tls_got_offset_type));
7513 got_entry_address = target->got_->address()
7514 + got_tlsdesc_offset
7515 + gsym->got_offset(tls_got_offset_type);
7516 }
7517 else
7518 {
7519 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
7520 gold_assert(
7521 object->local_has_got_offset(r_sym, tls_got_offset_type));
7522 got_entry_address = target->got_->address() +
7523 got_tlsdesc_offset +
7524 object->local_got_offset(r_sym, tls_got_offset_type);
7525 }
7526 if (tlsopt == tls::TLSOPT_TO_IE)
7527 {
3a531937
JY
7528 return tls_desc_gd_to_ie(relinfo, target, rela, r_type,
7529 view, psymval, got_entry_address,
7530 address);
7531 }
7532
7533 // Now do tlsdesc relocation.
7534 switch (r_type)
7535 {
7536 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
7537 return aarch64_reloc_funcs::adrp(view,
7538 got_entry_address + addend,
7539 address);
7540 break;
7541 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
7542 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
7543 return aarch64_reloc_funcs::template rela_general<32>(
7544 view, got_entry_address, addend, reloc_property);
7545 break;
7546 case elfcpp::R_AARCH64_TLSDESC_CALL:
7547 return aarch64_reloc_funcs::STATUS_OKAY;
7548 break;
7549 default:
7550 gold_unreachable();
7551 }
7552 }
7553 }
7554 break;
7555
8e33481e
HS
7556 default:
7557 gold_error(_("%s: unsupported TLS reloc %u."),
7558 object->name().c_str(), r_type);
7559 }
7560 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
3a531937
JY
7561} // End of relocate_tls.
7562
7563
7564template<int size, bool big_endian>
7565inline
83a01957 7566typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 7567Target_aarch64<size, big_endian>::Relocate::tls_gd_to_le(
83a01957 7568 const Relocate_info<size, big_endian>* relinfo,
3a531937
JY
7569 Target_aarch64<size, big_endian>* target,
7570 const elfcpp::Rela<size, big_endian>& rela,
7571 unsigned int r_type,
7572 unsigned char* view,
7573 const Symbol_value<size>* psymval)
7574{
83a01957 7575 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
3a531937
JY
7576 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
7577 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
7578
7579 Insntype* ip = reinterpret_cast<Insntype*>(view);
7580 Insntype insn1 = elfcpp::Swap<32, big_endian>::readval(ip);
7581 Insntype insn2 = elfcpp::Swap<32, big_endian>::readval(ip + 1);
7582 Insntype insn3 = elfcpp::Swap<32, big_endian>::readval(ip + 2);
7583
7584 if (r_type == elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC)
7585 {
7586 // This is the 2nd relocs, optimization should already have been
7587 // done.
7588 gold_assert((insn1 & 0xfff00000) == 0x91400000);
7589 return aarch64_reloc_funcs::STATUS_OKAY;
7590 }
7591
7592 // The original sequence is -
7593 // 90000000 adrp x0, 0 <main>
7594 // 91000000 add x0, x0, #0x0
7595 // 94000000 bl 0 <__tls_get_addr>
7596 // optimized to sequence -
7597 // d53bd040 mrs x0, tpidr_el0
7598 // 91400000 add x0, x0, #0x0, lsl #12
7599 // 91000000 add x0, x0, #0x0
7600
7601 // Unlike tls_ie_to_le, we change the 3 insns in one function call when we
7602 // encounter the first relocation "R_AARCH64_TLSGD_ADR_PAGE21". Because we
7603 // have to change "bl tls_get_addr", which does not have a corresponding tls
7604 // relocation type. So before proceeding, we need to make sure compiler
7605 // does not change the sequence.
7606 if(!(insn1 == 0x90000000 // adrp x0,0
7607 && insn2 == 0x91000000 // add x0, x0, #0x0
7608 && insn3 == 0x94000000)) // bl 0
7609 {
7610 // Ideally we should give up gd_to_le relaxation and do gd access.
7611 // However the gd_to_le relaxation decision has been made early
7612 // in the scan stage, where we did not allocate any GOT entry for
7613 // this symbol. Therefore we have to exit and report error now.
7614 gold_error(_("unexpected reloc insn sequence while relaxing "
7615 "tls gd to le for reloc %u."), r_type);
7616 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7617 }
7618
7619 // Write new insns.
7620 insn1 = 0xd53bd040; // mrs x0, tpidr_el0
7621 insn2 = 0x91400000; // add x0, x0, #0x0, lsl #12
7622 insn3 = 0x91000000; // add x0, x0, #0x0
7623 elfcpp::Swap<32, big_endian>::writeval(ip, insn1);
7624 elfcpp::Swap<32, big_endian>::writeval(ip + 1, insn2);
7625 elfcpp::Swap<32, big_endian>::writeval(ip + 2, insn3);
7626
7627 // Calculate tprel value.
7628 Output_segment* tls_segment = relinfo->layout->tls_segment();
7629 gold_assert(tls_segment != NULL);
7630 AArch64_address value = psymval->value(relinfo->object, 0);
7631 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7632 AArch64_address aligned_tcb_size =
7633 align_address(target->tcb_size(), tls_segment->maximum_alignment());
7634 AArch64_address x = value + aligned_tcb_size;
7635
7636 // After new insns are written, apply TLSLE relocs.
7637 const AArch64_reloc_property* rp1 =
7638 aarch64_reloc_property_table->get_reloc_property(
7639 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12);
7640 const AArch64_reloc_property* rp2 =
7641 aarch64_reloc_property_table->get_reloc_property(
7642 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12);
7643 gold_assert(rp1 != NULL && rp2 != NULL);
7644
7645 typename aarch64_reloc_funcs::Status s1 =
7646 aarch64_reloc_funcs::template rela_general<32>(view + 4,
7647 x,
7648 addend,
7649 rp1);
7650 if (s1 != aarch64_reloc_funcs::STATUS_OKAY)
7651 return s1;
7652
7653 typename aarch64_reloc_funcs::Status s2 =
7654 aarch64_reloc_funcs::template rela_general<32>(view + 8,
7655 x,
7656 addend,
7657 rp2);
7658
7659 this->skip_call_tls_get_addr_ = true;
7660 return s2;
7661} // End of tls_gd_to_le
7662
7663
9726c3c1
HS
7664template<int size, bool big_endian>
7665inline
7666typename AArch64_relocate_functions<size, big_endian>::Status
7667Target_aarch64<size, big_endian>::Relocate::tls_ld_to_le(
7668 const Relocate_info<size, big_endian>* relinfo,
7669 Target_aarch64<size, big_endian>* target,
7670 const elfcpp::Rela<size, big_endian>& rela,
7671 unsigned int r_type,
7672 unsigned char* view,
7673 const Symbol_value<size>* psymval)
7674{
7675 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
7676 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
7677 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
7678
7679 Insntype* ip = reinterpret_cast<Insntype*>(view);
7680 Insntype insn1 = elfcpp::Swap<32, big_endian>::readval(ip);
7681 Insntype insn2 = elfcpp::Swap<32, big_endian>::readval(ip + 1);
7682 Insntype insn3 = elfcpp::Swap<32, big_endian>::readval(ip + 2);
7683
7684 if (r_type == elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC)
7685 {
7686 // This is the 2nd relocs, optimization should already have been
7687 // done.
7688 gold_assert((insn1 & 0xfff00000) == 0x91400000);
7689 return aarch64_reloc_funcs::STATUS_OKAY;
7690 }
7691
7692 // The original sequence is -
7693 // 90000000 adrp x0, 0 <main>
7694 // 91000000 add x0, x0, #0x0
7695 // 94000000 bl 0 <__tls_get_addr>
7696 // optimized to sequence -
7697 // d53bd040 mrs x0, tpidr_el0
7698 // 91400000 add x0, x0, #0x0, lsl #12
7699 // 91000000 add x0, x0, #0x0
7700
7701 // Unlike tls_ie_to_le, we change the 3 insns in one function call when we
7702 // encounter the first relocation "R_AARCH64_TLSLD_ADR_PAGE21". Because we
7703 // have to change "bl tls_get_addr", which does not have a corresponding tls
7704 // relocation type. So before proceeding, we need to make sure compiler
7705 // does not change the sequence.
7706 if(!(insn1 == 0x90000000 // adrp x0,0
7707 && insn2 == 0x91000000 // add x0, x0, #0x0
7708 && insn3 == 0x94000000)) // bl 0
7709 {
7710 // Ideally we should give up gd_to_le relaxation and do gd access.
7711 // However the gd_to_le relaxation decision has been made early
7712 // in the scan stage, where we did not allocate any GOT entry for
7713 // this symbol. Therefore we have to exit and report error now.
7714 gold_error(_("unexpected reloc insn sequence while relaxing "
7715 "tls gd to le for reloc %u."), r_type);
7716 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7717 }
7718
7719 // Write new insns.
7720 insn1 = 0xd53bd040; // mrs x0, tpidr_el0
7721 insn2 = 0x91400000; // add x0, x0, #0x0, lsl #12
7722 insn3 = 0x91000000; // add x0, x0, #0x0
7723 elfcpp::Swap<32, big_endian>::writeval(ip, insn1);
7724 elfcpp::Swap<32, big_endian>::writeval(ip + 1, insn2);
7725 elfcpp::Swap<32, big_endian>::writeval(ip + 2, insn3);
7726
7727 // Calculate tprel value.
7728 Output_segment* tls_segment = relinfo->layout->tls_segment();
7729 gold_assert(tls_segment != NULL);
7730 AArch64_address value = psymval->value(relinfo->object, 0);
7731 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7732 AArch64_address aligned_tcb_size =
7733 align_address(target->tcb_size(), tls_segment->maximum_alignment());
7734 AArch64_address x = value + aligned_tcb_size;
7735
7736 // After new insns are written, apply TLSLE relocs.
7737 const AArch64_reloc_property* rp1 =
7738 aarch64_reloc_property_table->get_reloc_property(
7739 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12);
7740 const AArch64_reloc_property* rp2 =
7741 aarch64_reloc_property_table->get_reloc_property(
7742 elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12);
7743 gold_assert(rp1 != NULL && rp2 != NULL);
7744
7745 typename aarch64_reloc_funcs::Status s1 =
7746 aarch64_reloc_funcs::template rela_general<32>(view + 4,
7747 x,
7748 addend,
7749 rp1);
7750 if (s1 != aarch64_reloc_funcs::STATUS_OKAY)
7751 return s1;
7752
7753 typename aarch64_reloc_funcs::Status s2 =
7754 aarch64_reloc_funcs::template rela_general<32>(view + 8,
7755 x,
7756 addend,
7757 rp2);
7758
7759 this->skip_call_tls_get_addr_ = true;
7760 return s2;
7761
7762} // End of tls_ld_to_le
7763
3a531937
JY
7764template<int size, bool big_endian>
7765inline
83a01957 7766typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 7767Target_aarch64<size, big_endian>::Relocate::tls_ie_to_le(
83a01957 7768 const Relocate_info<size, big_endian>* relinfo,
3a531937
JY
7769 Target_aarch64<size, big_endian>* target,
7770 const elfcpp::Rela<size, big_endian>& rela,
7771 unsigned int r_type,
7772 unsigned char* view,
7773 const Symbol_value<size>* psymval)
7774{
7775 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
7776 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
83a01957 7777 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
3a531937
JY
7778
7779 AArch64_address value = psymval->value(relinfo->object, 0);
7780 Output_segment* tls_segment = relinfo->layout->tls_segment();
7781 AArch64_address aligned_tcb_address =
7782 align_address(target->tcb_size(), tls_segment->maximum_alignment());
7783 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7784 AArch64_address x = value + addend + aligned_tcb_address;
7785 // "x" is the offset to tp, we can only do this if x is within
7786 // range [0, 2^32-1]
7787 if (!(size == 32 || (size == 64 && (static_cast<uint64_t>(x) >> 32) == 0)))
7788 {
7789 gold_error(_("TLS variable referred by reloc %u is too far from TP."),
7790 r_type);
7791 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7792 }
7793
7794 Insntype* ip = reinterpret_cast<Insntype*>(view);
7795 Insntype insn = elfcpp::Swap<32, big_endian>::readval(ip);
7796 unsigned int regno;
7797 Insntype newinsn;
7798 if (r_type == elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
7799 {
7800 // Generate movz.
7801 regno = (insn & 0x1f);
7802 newinsn = (0xd2a00000 | regno) | (((x >> 16) & 0xffff) << 5);
7803 }
7804 else if (r_type == elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
7805 {
7806 // Generate movk.
7807 regno = (insn & 0x1f);
7808 gold_assert(regno == ((insn >> 5) & 0x1f));
7809 newinsn = (0xf2800000 | regno) | ((x & 0xffff) << 5);
7810 }
7811 else
9726c3c1 7812 gold_unreachable();
3a531937
JY
7813
7814 elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
7815 return aarch64_reloc_funcs::STATUS_OKAY;
7816} // End of tls_ie_to_le
7817
7818
7819template<int size, bool big_endian>
7820inline
83a01957 7821typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 7822Target_aarch64<size, big_endian>::Relocate::tls_desc_gd_to_le(
83a01957 7823 const Relocate_info<size, big_endian>* relinfo,
3a531937
JY
7824 Target_aarch64<size, big_endian>* target,
7825 const elfcpp::Rela<size, big_endian>& rela,
7826 unsigned int r_type,
7827 unsigned char* view,
7828 const Symbol_value<size>* psymval)
7829{
7830 typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
7831 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
83a01957 7832 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
3a531937
JY
7833
7834 // TLSDESC-GD sequence is like:
7835 // adrp x0, :tlsdesc:v1
7836 // ldr x1, [x0, #:tlsdesc_lo12:v1]
7837 // add x0, x0, :tlsdesc_lo12:v1
7838 // .tlsdesccall v1
7839 // blr x1
7840 // After desc_gd_to_le optimization, the sequence will be like:
7841 // movz x0, #0x0, lsl #16
7842 // movk x0, #0x10
7843 // nop
7844 // nop
7845
7846 // Calculate tprel value.
7847 Output_segment* tls_segment = relinfo->layout->tls_segment();
7848 gold_assert(tls_segment != NULL);
7849 Insntype* ip = reinterpret_cast<Insntype*>(view);
7850 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7851 AArch64_address value = psymval->value(relinfo->object, addend);
7852 AArch64_address aligned_tcb_size =
7853 align_address(target->tcb_size(), tls_segment->maximum_alignment());
7854 AArch64_address x = value + aligned_tcb_size;
7855 // x is the offset to tp, we can only do this if x is within range
7856 // [0, 2^32-1]. If x is out of range, fail and exit.
7857 if (size == 64 && (static_cast<uint64_t>(x) >> 32) != 0)
7858 {
7859 gold_error(_("TLS variable referred by reloc %u is too far from TP. "
7860 "We Can't do gd_to_le relaxation.\n"), r_type);
7861 return aarch64_reloc_funcs::STATUS_BAD_RELOC;
7862 }
7863 Insntype newinsn;
7864 switch (r_type)
7865 {
7866 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
7867 case elfcpp::R_AARCH64_TLSDESC_CALL:
7868 // Change to nop
7869 newinsn = 0xd503201f;
7870 break;
7871
7872 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
7873 // Change to movz.
7874 newinsn = 0xd2a00000 | (((x >> 16) & 0xffff) << 5);
7875 break;
7876
7877 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
7878 // Change to movk.
7879 newinsn = 0xf2800000 | ((x & 0xffff) << 5);
7880 break;
7881
7882 default:
7883 gold_error(_("unsupported tlsdesc gd_to_le optimization on reloc %u"),
7884 r_type);
7885 gold_unreachable();
7886 }
7887 elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
7888 return aarch64_reloc_funcs::STATUS_OKAY;
7889} // End of tls_desc_gd_to_le
7890
7891
7892template<int size, bool big_endian>
7893inline
83a01957 7894typename AArch64_relocate_functions<size, big_endian>::Status
3a531937 7895Target_aarch64<size, big_endian>::Relocate::tls_desc_gd_to_ie(
83a01957 7896 const Relocate_info<size, big_endian>* /* relinfo */,
3a531937
JY
7897 Target_aarch64<size, big_endian>* /* target */,
7898 const elfcpp::Rela<size, big_endian>& rela,
7899 unsigned int r_type,
7900 unsigned char* view,
7901 const Symbol_value<size>* /* psymval */,
7902 typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address,
7903 typename elfcpp::Elf_types<size>::Elf_Addr address)
7904{
7905 typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
83a01957 7906 typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
3a531937
JY
7907
7908 // TLSDESC-GD sequence is like:
7909 // adrp x0, :tlsdesc:v1
7910 // ldr x1, [x0, #:tlsdesc_lo12:v1]
7911 // add x0, x0, :tlsdesc_lo12:v1
7912 // .tlsdesccall v1
7913 // blr x1
7914 // After desc_gd_to_ie optimization, the sequence will be like:
7915 // adrp x0, :tlsie:v1
7916 // ldr x0, [x0, :tlsie_lo12:v1]
7917 // nop
7918 // nop
7919
7920 Insntype* ip = reinterpret_cast<Insntype*>(view);
7921 const elfcpp::Elf_Xword addend = rela.get_r_addend();
7922 Insntype newinsn;
7923 switch (r_type)
7924 {
7925 case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
7926 case elfcpp::R_AARCH64_TLSDESC_CALL:
7927 // Change to nop
7928 newinsn = 0xd503201f;
7929 elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
7930 break;
7931
7932 case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
7933 {
7934 return aarch64_reloc_funcs::adrp(view, got_entry_address + addend,
7935 address);
7936 }
7937 break;
7938
7939 case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
7940 {
bb779192
HS
7941 // Set ldr target register to be x0.
7942 Insntype insn = elfcpp::Swap<32, big_endian>::readval(ip);
7943 insn &= 0xffffffe0;
7944 elfcpp::Swap<32, big_endian>::writeval(ip, insn);
7945 // Do relocation.
3a531937
JY
7946 const AArch64_reloc_property* reloc_property =
7947 aarch64_reloc_property_table->get_reloc_property(
7948 elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
7949 return aarch64_reloc_funcs::template rela_general<32>(
7950 view, got_entry_address, addend, reloc_property);
7951 }
7952 break;
8e33481e 7953
3a531937
JY
7954 default:
7955 gold_error(_("Don't support tlsdesc gd_to_ie optimization on reloc %u"),
7956 r_type);
7957 gold_unreachable();
7958 }
7959 return aarch64_reloc_funcs::STATUS_OKAY;
7960} // End of tls_desc_gd_to_ie
8e33481e 7961
053a4d68
JY
7962// Relocate section data.
7963
7964template<int size, bool big_endian>
7965void
7966Target_aarch64<size, big_endian>::relocate_section(
9363c7c3 7967 const Relocate_info<size, big_endian>* relinfo,
053a4d68 7968 unsigned int sh_type,
9363c7c3
JY
7969 const unsigned char* prelocs,
7970 size_t reloc_count,
7971 Output_section* output_section,
7972 bool needs_special_offset_handling,
7973 unsigned char* view,
7974 typename elfcpp::Elf_types<size>::Elf_Addr address,
7975 section_size_type view_size,
7976 const Reloc_symbol_changes* reloc_symbol_changes)
053a4d68 7977{
6bf56e74 7978 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
4d625b70 7979 typedef Target_aarch64<size, big_endian> Aarch64;
9363c7c3 7980 typedef typename Target_aarch64<size, big_endian>::Relocate AArch64_relocate;
4d625b70
CC
7981 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
7982 Classify_reloc;
7983
7984 gold_assert(sh_type == elfcpp::SHT_RELA);
7985
6bf56e74
IK
7986 // See if we are relocating a relaxed input section. If so, the view
7987 // covers the whole output section and we need to adjust accordingly.
7988 if (needs_special_offset_handling)
7989 {
7990 const Output_relaxed_input_section* poris =
7991 output_section->find_relaxed_input_section(relinfo->object,
7992 relinfo->data_shndx);
7993 if (poris != NULL)
7994 {
7995 Address section_address = poris->address();
7996 section_size_type section_size = poris->data_size();
7997
7998 gold_assert((section_address >= address)
7999 && ((section_address + section_size)
8000 <= (address + view_size)));
8001
8002 off_t offset = section_address - address;
8003 view += offset;
8004 address += offset;
8005 view_size = section_size;
8006 }
8007 }
8008
4d625b70
CC
8009 gold::relocate_section<size, big_endian, Aarch64, AArch64_relocate,
8010 gold::Default_comdat_behavior, Classify_reloc>(
9363c7c3
JY
8011 relinfo,
8012 this,
8013 prelocs,
8014 reloc_count,
8015 output_section,
8016 needs_special_offset_handling,
8017 view,
8018 address,
8019 view_size,
8020 reloc_symbol_changes);
053a4d68
JY
8021}
8022
4d625b70 8023// Scan the relocs during a relocatable link.
053a4d68
JY
8024
8025template<int size, bool big_endian>
4d625b70
CC
8026void
8027Target_aarch64<size, big_endian>::scan_relocatable_relocs(
8028 Symbol_table* symtab,
8029 Layout* layout,
8030 Sized_relobj_file<size, big_endian>* object,
8031 unsigned int data_shndx,
8032 unsigned int sh_type,
8033 const unsigned char* prelocs,
8034 size_t reloc_count,
8035 Output_section* output_section,
8036 bool needs_special_offset_handling,
8037 size_t local_symbol_count,
8038 const unsigned char* plocal_symbols,
8039 Relocatable_relocs* rr)
053a4d68 8040{
4d625b70
CC
8041 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
8042 Classify_reloc;
8043 typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
8044 Scan_relocatable_relocs;
8045
8046 gold_assert(sh_type == elfcpp::SHT_RELA);
8047
8048 gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
8049 symtab,
8050 layout,
8051 object,
8052 data_shndx,
8053 prelocs,
8054 reloc_count,
8055 output_section,
8056 needs_special_offset_handling,
8057 local_symbol_count,
8058 plocal_symbols,
8059 rr);
053a4d68
JY
8060}
8061
4d625b70 8062// Scan the relocs for --emit-relocs.
053a4d68
JY
8063
8064template<int size, bool big_endian>
8065void
4d625b70 8066Target_aarch64<size, big_endian>::emit_relocs_scan(
8e33481e
HS
8067 Symbol_table* symtab,
8068 Layout* layout,
8069 Sized_relobj_file<size, big_endian>* object,
8070 unsigned int data_shndx,
053a4d68 8071 unsigned int sh_type,
8e33481e
HS
8072 const unsigned char* prelocs,
8073 size_t reloc_count,
8074 Output_section* output_section,
8075 bool needs_special_offset_handling,
8076 size_t local_symbol_count,
4d625b70 8077 const unsigned char* plocal_syms,
8e33481e 8078 Relocatable_relocs* rr)
053a4d68 8079{
4d625b70
CC
8080 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
8081 Classify_reloc;
8082 typedef gold::Default_emit_relocs_strategy<Classify_reloc>
8083 Emit_relocs_strategy;
8e33481e 8084
4d625b70 8085 gold_assert(sh_type == elfcpp::SHT_RELA);
8e33481e 8086
4d625b70 8087 gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
8e33481e
HS
8088 symtab,
8089 layout,
8090 object,
8091 data_shndx,
8092 prelocs,
8093 reloc_count,
8094 output_section,
8095 needs_special_offset_handling,
8096 local_symbol_count,
4d625b70 8097 plocal_syms,
8e33481e 8098 rr);
053a4d68
JY
8099}
8100
8101// Relocate a section during a relocatable link.
8102
8103template<int size, bool big_endian>
8104void
8105Target_aarch64<size, big_endian>::relocate_relocs(
8e33481e 8106 const Relocate_info<size, big_endian>* relinfo,
053a4d68 8107 unsigned int sh_type,
8e33481e
HS
8108 const unsigned char* prelocs,
8109 size_t reloc_count,
8110 Output_section* output_section,
8111 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
8e33481e
HS
8112 unsigned char* view,
8113 typename elfcpp::Elf_types<size>::Elf_Addr view_address,
8114 section_size_type view_size,
8115 unsigned char* reloc_view,
8116 section_size_type reloc_view_size)
053a4d68 8117{
4d625b70
CC
8118 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
8119 Classify_reloc;
8120
053a4d68 8121 gold_assert(sh_type == elfcpp::SHT_RELA);
8e33481e 8122
4d625b70 8123 gold::relocate_relocs<size, big_endian, Classify_reloc>(
8e33481e
HS
8124 relinfo,
8125 prelocs,
8126 reloc_count,
8127 output_section,
8128 offset_in_output_section,
8e33481e
HS
8129 view,
8130 view_address,
8131 view_size,
8132 reloc_view,
8133 reloc_view_size);
053a4d68
JY
8134}
8135
83a01957 8136
5019d64a
HS
8137// Return whether this is a 3-insn erratum sequence.
8138
8139template<int size, bool big_endian>
8140bool
8141Target_aarch64<size, big_endian>::is_erratum_843419_sequence(
8142 typename elfcpp::Swap<32,big_endian>::Valtype insn1,
8143 typename elfcpp::Swap<32,big_endian>::Valtype insn2,
8144 typename elfcpp::Swap<32,big_endian>::Valtype insn3)
8145{
8146 unsigned rt1, rt2;
8147 bool load, pair;
8148
8149 // The 2nd insn is a single register load or store; or register pair
8150 // store.
8151 if (Insn_utilities::aarch64_mem_op_p(insn2, &rt1, &rt2, &pair, &load)
8152 && (!pair || (pair && !load)))
8153 {
8154 // The 3rd insn is a load or store instruction from the "Load/store
8155 // register (unsigned immediate)" encoding class, using Rn as the
8156 // base address register.
8157 if (Insn_utilities::aarch64_ldst_uimm(insn3)
8158 && (Insn_utilities::aarch64_rn(insn3)
8159 == Insn_utilities::aarch64_rd(insn1)))
8160 return true;
8161 }
8162 return false;
8163}
8164
8165
2f0c79aa
HS
8166// Return whether this is a 835769 sequence.
8167// (Similarly implemented as in elfnn-aarch64.c.)
8168
8169template<int size, bool big_endian>
8170bool
8171Target_aarch64<size, big_endian>::is_erratum_835769_sequence(
8172 typename elfcpp::Swap<32,big_endian>::Valtype insn1,
8173 typename elfcpp::Swap<32,big_endian>::Valtype insn2)
8174{
8175 uint32_t rt;
24228130 8176 uint32_t rt2 = 0;
2f0c79aa
HS
8177 uint32_t rn;
8178 uint32_t rm;
8179 uint32_t ra;
8180 bool pair;
8181 bool load;
8182
8183 if (Insn_utilities::aarch64_mlxl(insn2)
8184 && Insn_utilities::aarch64_mem_op_p (insn1, &rt, &rt2, &pair, &load))
8185 {
8186 /* Any SIMD memory op is independent of the subsequent MLA
8187 by definition of the erratum. */
8188 if (Insn_utilities::aarch64_bit(insn1, 26))
8189 return true;
8190
8191 /* If not SIMD, check for integer memory ops and MLA relationship. */
8192 rn = Insn_utilities::aarch64_rn(insn2);
8193 ra = Insn_utilities::aarch64_ra(insn2);
8194 rm = Insn_utilities::aarch64_rm(insn2);
8195
8196 /* If this is a load and there's a true(RAW) dependency, we are safe
8197 and this is not an erratum sequence. */
8198 if (load &&
8199 (rt == rn || rt == rm || rt == ra
8200 || (pair && (rt2 == rn || rt2 == rm || rt2 == ra))))
8201 return false;
8202
8203 /* We conservatively put out stubs for all other cases (including
8204 writebacks). */
8205 return true;
8206 }
8207
8208 return false;
8209}
8210
8211
8212// Helper method to create erratum stub for ST_E_843419 and ST_E_835769.
8213
8214template<int size, bool big_endian>
8215void
8216Target_aarch64<size, big_endian>::create_erratum_stub(
8217 AArch64_relobj<size, big_endian>* relobj,
8218 unsigned int shndx,
8219 section_size_type erratum_insn_offset,
8220 Address erratum_address,
8221 typename Insn_utilities::Insntype erratum_insn,
0ef3814f
HS
8222 int erratum_type,
8223 unsigned int e843419_adrp_offset)
2f0c79aa
HS
8224{
8225 gold_assert(erratum_type == ST_E_843419 || erratum_type == ST_E_835769);
8226 The_stub_table* stub_table = relobj->stub_table(shndx);
8227 gold_assert(stub_table != NULL);
8228 if (stub_table->find_erratum_stub(relobj,
8229 shndx,
8230 erratum_insn_offset) == NULL)
8231 {
8232 const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
0ef3814f
HS
8233 The_erratum_stub* stub;
8234 if (erratum_type == ST_E_835769)
8235 stub = new The_erratum_stub(relobj, erratum_type, shndx,
8236 erratum_insn_offset);
8237 else if (erratum_type == ST_E_843419)
8238 stub = new E843419_stub<size, big_endian>(
8239 relobj, shndx, erratum_insn_offset, e843419_adrp_offset);
8240 else
8241 gold_unreachable();
2f0c79aa
HS
8242 stub->set_erratum_insn(erratum_insn);
8243 stub->set_erratum_address(erratum_address);
8244 // For erratum ST_E_843419 and ST_E_835769, the destination address is
8245 // always the next insn after erratum insn.
8246 stub->set_destination_address(erratum_address + BPI);
8247 stub_table->add_erratum_stub(stub);
8248 }
8249}
8250
8251
8252// Scan erratum for section SHNDX range [output_address + span_start,
8253// output_address + span_end). Note here we do not share the code with
8254// scan_erratum_843419_span function, because for 843419 we optimize by only
8255// scanning the last few insns of a page, whereas for 835769, we need to scan
8256// every insn.
8257
8258template<int size, bool big_endian>
8259void
8260Target_aarch64<size, big_endian>::scan_erratum_835769_span(
8261 AArch64_relobj<size, big_endian>* relobj,
8262 unsigned int shndx,
8263 const section_size_type span_start,
8264 const section_size_type span_end,
8265 unsigned char* input_view,
8266 Address output_address)
8267{
8268 typedef typename Insn_utilities::Insntype Insntype;
8269
8270 const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
8271
8272 // Adjust output_address and view to the start of span.
8273 output_address += span_start;
8274 input_view += span_start;
8275
8276 section_size_type span_length = span_end - span_start;
8277 section_size_type offset = 0;
8278 for (offset = 0; offset + BPI < span_length; offset += BPI)
8279 {
8280 Insntype* ip = reinterpret_cast<Insntype*>(input_view + offset);
8281 Insntype insn1 = ip[0];
8282 Insntype insn2 = ip[1];
8283 if (is_erratum_835769_sequence(insn1, insn2))
8284 {
8285 Insntype erratum_insn = insn2;
8286 // "span_start + offset" is the offset for insn1. So for insn2, it is
8287 // "span_start + offset + BPI".
8288 section_size_type erratum_insn_offset = span_start + offset + BPI;
8289 Address erratum_address = output_address + offset + BPI;
73854cdd 8290 gold_info(_("Erratum 835769 found and fixed at \"%s\", "
2f0c79aa
HS
8291 "section %d, offset 0x%08x."),
8292 relobj->name().c_str(), shndx,
8293 (unsigned int)(span_start + offset));
8294
8295 this->create_erratum_stub(relobj, shndx,
8296 erratum_insn_offset, erratum_address,
8297 erratum_insn, ST_E_835769);
8298 offset += BPI; // Skip mac insn.
8299 }
8300 }
8301} // End of "Target_aarch64::scan_erratum_835769_span".
8302
8303
5019d64a
HS
8304// Scan erratum for section SHNDX range
8305// [output_address + span_start, output_address + span_end).
8306
8307template<int size, bool big_endian>
8308void
8309Target_aarch64<size, big_endian>::scan_erratum_843419_span(
8310 AArch64_relobj<size, big_endian>* relobj,
8311 unsigned int shndx,
8312 const section_size_type span_start,
8313 const section_size_type span_end,
8314 unsigned char* input_view,
8315 Address output_address)
8316{
8317 typedef typename Insn_utilities::Insntype Insntype;
8318
8319 // Adjust output_address and view to the start of span.
8320 output_address += span_start;
8321 input_view += span_start;
8322
8323 if ((output_address & 0x03) != 0)
8324 return;
8325
8326 section_size_type offset = 0;
8327 section_size_type span_length = span_end - span_start;
8328 // The first instruction must be ending at 0xFF8 or 0xFFC.
8329 unsigned int page_offset = output_address & 0xFFF;
8330 // Make sure starting position, that is "output_address+offset",
8331 // starts at page position 0xff8 or 0xffc.
8332 if (page_offset < 0xff8)
8333 offset = 0xff8 - page_offset;
8334 while (offset + 3 * Insn_utilities::BYTES_PER_INSN <= span_length)
8335 {
8336 Insntype* ip = reinterpret_cast<Insntype*>(input_view + offset);
8337 Insntype insn1 = ip[0];
8338 if (Insn_utilities::is_adrp(insn1))
8339 {
8340 Insntype insn2 = ip[1];
8341 Insntype insn3 = ip[2];
a48d0c12
HS
8342 Insntype erratum_insn;
8343 unsigned insn_offset;
5019d64a
HS
8344 bool do_report = false;
8345 if (is_erratum_843419_sequence(insn1, insn2, insn3))
a48d0c12
HS
8346 {
8347 do_report = true;
8348 erratum_insn = insn3;
8349 insn_offset = 2 * Insn_utilities::BYTES_PER_INSN;
8350 }
5019d64a
HS
8351 else if (offset + 4 * Insn_utilities::BYTES_PER_INSN <= span_length)
8352 {
8353 // Optionally we can have an insn between ins2 and ins3
8354 Insntype insn_opt = ip[2];
8355 // And insn_opt must not be a branch.
8356 if (!Insn_utilities::aarch64_b(insn_opt)
8357 && !Insn_utilities::aarch64_bl(insn_opt)
8358 && !Insn_utilities::aarch64_blr(insn_opt)
8359 && !Insn_utilities::aarch64_br(insn_opt))
8360 {
8361 // And insn_opt must not write to dest reg in insn1. However
8362 // we do a conservative scan, which means we may fix/report
8363 // more than necessary, but it doesn't hurt.
8364
8365 Insntype insn4 = ip[3];
8366 if (is_erratum_843419_sequence(insn1, insn2, insn4))
a48d0c12
HS
8367 {
8368 do_report = true;
8369 erratum_insn = insn4;
8370 insn_offset = 3 * Insn_utilities::BYTES_PER_INSN;
8371 }
5019d64a
HS
8372 }
8373 }
8374 if (do_report)
8375 {
2f0c79aa 8376 unsigned int erratum_insn_offset =
a48d0c12 8377 span_start + offset + insn_offset;
2f0c79aa
HS
8378 Address erratum_address =
8379 output_address + offset + insn_offset;
8380 create_erratum_stub(relobj, shndx,
8381 erratum_insn_offset, erratum_address,
0ef3814f
HS
8382 erratum_insn, ST_E_843419,
8383 span_start + offset);
5019d64a
HS
8384 }
8385 }
8386
8387 // Advance to next candidate instruction. We only consider instruction
8388 // sequences starting at a page offset of 0xff8 or 0xffc.
8389 page_offset = (output_address + offset) & 0xfff;
8390 if (page_offset == 0xff8)
8391 offset += 4;
8392 else // (page_offset == 0xffc), we move to next page's 0xff8.
8393 offset += 0xffc;
8394 }
a48d0c12 8395} // End of "Target_aarch64::scan_erratum_843419_span".
5019d64a
HS
8396
8397
053a4d68
JY
8398// The selector for aarch64 object files.
8399
8400template<int size, bool big_endian>
8401class Target_selector_aarch64 : public Target_selector
8402{
8403 public:
9363c7c3 8404 Target_selector_aarch64();
053a4d68
JY
8405
8406 virtual Target*
8407 do_instantiate_target()
8408 { return new Target_aarch64<size, big_endian>(); }
8409};
8410
9363c7c3
JY
8411template<>
8412Target_selector_aarch64<32, true>::Target_selector_aarch64()
8413 : Target_selector(elfcpp::EM_AARCH64, 32, true,
8414 "elf32-bigaarch64", "aarch64_elf32_be_vec")
8415{ }
8416
8417template<>
8418Target_selector_aarch64<32, false>::Target_selector_aarch64()
8419 : Target_selector(elfcpp::EM_AARCH64, 32, false,
8420 "elf32-littleaarch64", "aarch64_elf32_le_vec")
8421{ }
8422
8423template<>
8424Target_selector_aarch64<64, true>::Target_selector_aarch64()
8425 : Target_selector(elfcpp::EM_AARCH64, 64, true,
8426 "elf64-bigaarch64", "aarch64_elf64_be_vec")
8427{ }
8428
8429template<>
8430Target_selector_aarch64<64, false>::Target_selector_aarch64()
8431 : Target_selector(elfcpp::EM_AARCH64, 64, false,
8432 "elf64-littleaarch64", "aarch64_elf64_le_vec")
8433{ }
8434
053a4d68
JY
8435Target_selector_aarch64<32, true> target_selector_aarch64elf32b;
8436Target_selector_aarch64<32, false> target_selector_aarch64elf32;
8437Target_selector_aarch64<64, true> target_selector_aarch64elfb;
8438Target_selector_aarch64<64, false> target_selector_aarch64elf;
8439
053a4d68 8440} // End anonymous namespace.
This page took 0.536102 seconds and 4 git commands to generate.