1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
3 Contributed by Loongson Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
28 #include "elf/loongarch.h"
29 #include "elfxx-loongarch.h"
30 #include "opcode/loongarch.h"
33 loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
34 Elf_Internal_Rela *dst)
36 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
37 ELFNN_R_TYPE (dst->r_info));
38 return cache_ptr->howto != NULL;
41 /* LoongArch ELF linker hash entry. */
42 struct loongarch_elf_link_hash_entry
44 struct elf_link_hash_entry elf;
51 #define GOT_TLS_GDESC 16
53 #define GOT_TLS_GD_BOTH_P(tls_type) \
54 ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
55 #define GOT_TLS_GD_ANY_P(tls_type) \
56 ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
60 #define loongarch_elf_hash_entry(ent) \
61 ((struct loongarch_elf_link_hash_entry *) (ent))
63 struct _bfd_loongarch_elf_obj_tdata
65 struct elf_obj_tdata root;
67 /* The tls_type for each local got entry. */
68 char *local_got_tls_type;
71 #define _bfd_loongarch_elf_tdata(abfd) \
72 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
74 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
75 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
77 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
79 ? &loongarch_elf_hash_entry (h)->tls_type \
80 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
82 #define is_loongarch_elf(bfd) \
83 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
84 && elf_tdata (bfd) != NULL \
85 && elf_object_id (bfd) == LARCH_ELF_DATA)
87 struct loongarch_elf_link_hash_table
89 struct elf_link_hash_table elf;
91 /* Short-cuts to get to dynamic linker sections. */
94 /* Small local sym to section mapping cache. */
95 struct sym_cache sym_cache;
97 /* Used by local STT_GNU_IFUNC symbols. */
98 htab_t loc_hash_table;
99 void *loc_hash_memory;
101 /* The max alignment of output sections. */
102 bfd_vma max_alignment;
104 /* The data segment phase, don't relax the section
105 when it is exp_seg_relro_adjust. */
106 int *data_segment_phase;
109 /* Get the LoongArch ELF linker hash table from a link_info structure. */
110 #define loongarch_elf_hash_table(p) \
111 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
112 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
115 #define MINUS_ONE ((bfd_vma) 0 - 1)
117 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
119 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
120 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
122 #define PLT_HEADER_INSNS 8
123 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
125 #define PLT_ENTRY_INSNS 4
126 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
128 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
130 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
132 #define elf_backend_want_got_plt 1
134 #define elf_backend_plt_readonly 1
136 #define elf_backend_want_plt_sym 1
137 #define elf_backend_plt_alignment 4
138 #define elf_backend_can_gc_sections 1
139 #define elf_backend_can_refcount 1
140 #define elf_backend_want_got_sym 1
142 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
144 #define elf_backend_want_dynrelro 1
145 #define elf_backend_rela_normal 1
146 #define elf_backend_default_execstack 0
148 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
149 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
150 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
151 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
152 || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
153 || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
154 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
156 /* Generate a PLT header. */
159 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
162 bfd_vma pcrel = got_plt_addr - plt_header_addr;
165 if (pcrel + 0x80000800 > 0xffffffff)
167 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
168 bfd_set_error (bfd_error_bad_value);
171 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
174 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
175 sub.[wd] $t1, $t1, $t3
176 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
177 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
178 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
179 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
180 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
183 if (GOT_ENTRY_SIZE == 8)
185 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
186 entry[1] = 0x0011bdad;
187 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
188 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
189 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
190 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
191 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
192 entry[7] = 0x4c0001e0;
196 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
197 entry[1] = 0x00113dad;
198 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
199 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
200 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
201 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
202 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
203 entry[7] = 0x4c0001e0;
208 /* Generate a PLT entry. */
211 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
214 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
217 if (pcrel + 0x80000800 > 0xffffffff)
219 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
220 bfd_set_error (bfd_error_bad_value);
223 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
226 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
227 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
228 | (lo & 0xfff) << 10);
229 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
230 entry[3] = 0x03400000; /* nop */
235 /* Create an entry in an LoongArch ELF linker hash table. */
237 static struct bfd_hash_entry *
238 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
241 struct loongarch_elf_link_hash_entry *eh;
243 /* Allocate the structure if it has not already been allocated by a
247 entry = bfd_hash_allocate (table, sizeof (*eh));
252 /* Call the allocation method of the superclass. */
253 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
256 eh = (struct loongarch_elf_link_hash_entry *) entry;
257 eh->tls_type = GOT_UNKNOWN;
263 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
264 for local symbol so that we can handle local STT_GNU_IFUNC symbols
265 as global symbol. We reuse indx and dynstr_index for local symbol
266 hash since they aren't used by global symbols in this backend. */
269 elfNN_loongarch_local_htab_hash (const void *ptr)
271 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
272 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
275 /* Compare local hash entries. */
278 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
280 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
281 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
283 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
286 /* Find and/or create a hash entry for local symbol. */
287 static struct elf_link_hash_entry *
288 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
289 bfd *abfd, const Elf_Internal_Rela *rel,
292 struct loongarch_elf_link_hash_entry e, *ret;
293 asection *sec = abfd->sections;
294 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
297 e.elf.indx = sec->id;
298 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
299 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
300 create ? INSERT : NO_INSERT);
307 ret = (struct loongarch_elf_link_hash_entry *) *slot;
311 ret = ((struct loongarch_elf_link_hash_entry *)
312 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
313 sizeof (struct loongarch_elf_link_hash_entry)));
316 memset (ret, 0, sizeof (*ret));
317 ret->elf.indx = sec->id;
318 ret->elf.pointer_equality_needed = 0;
319 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
320 ret->elf.dynindx = -1;
321 ret->elf.needs_plt = 0;
322 ret->elf.plt.refcount = -1;
323 ret->elf.got.refcount = -1;
324 ret->elf.def_dynamic = 0;
325 ret->elf.def_regular = 1;
326 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
327 ret->elf.ref_regular = 0;
328 ret->elf.forced_local = 1;
329 ret->elf.root.type = bfd_link_hash_defined;
335 /* Destroy an LoongArch elf linker hash table. */
338 elfNN_loongarch_link_hash_table_free (bfd *obfd)
340 struct loongarch_elf_link_hash_table *ret;
341 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
343 if (ret->loc_hash_table)
344 htab_delete (ret->loc_hash_table);
345 if (ret->loc_hash_memory)
346 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
348 _bfd_elf_link_hash_table_free (obfd);
351 /* Create a LoongArch ELF linker hash table. */
353 static struct bfd_link_hash_table *
354 loongarch_elf_link_hash_table_create (bfd *abfd)
356 struct loongarch_elf_link_hash_table *ret;
357 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
359 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
363 if (!_bfd_elf_link_hash_table_init
364 (&ret->elf, abfd, link_hash_newfunc,
365 sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
371 ret->max_alignment = MINUS_ONE;
373 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
374 elfNN_loongarch_local_htab_eq, NULL);
375 ret->loc_hash_memory = objalloc_create ();
376 if (!ret->loc_hash_table || !ret->loc_hash_memory)
378 elfNN_loongarch_link_hash_table_free (abfd);
381 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
383 return &ret->elf.root;
386 /* Merge backend specific data from an object file to the output
387 object file when linking. */
390 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
392 bfd *obfd = info->output_bfd;
393 flagword in_flags = elf_elfheader (ibfd)->e_flags;
394 flagword out_flags = elf_elfheader (obfd)->e_flags;
396 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
399 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
401 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
402 "the selected emulation:\n"
403 " target emulation `%s' does not match `%s'"),
404 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
408 if (!_bfd_elf_merge_object_attributes (ibfd, info))
411 /* If the input BFD is not a dynamic object and it does not contain any
412 non-data sections, do not account its ABI. For example, various
413 packages produces such data-only relocatable objects with
414 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
415 But they are compatible with all ABIs. */
416 if (!(ibfd->flags & DYNAMIC))
419 bool have_code_sections = false;
420 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
421 if ((bfd_section_flags (sec)
422 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
423 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
425 have_code_sections = true;
428 if (!have_code_sections)
432 if (!elf_flags_init (obfd))
434 elf_flags_init (obfd) = true;
435 elf_elfheader (obfd)->e_flags = in_flags;
438 else if (out_flags != in_flags)
440 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
441 && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
442 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
443 && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
445 elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
446 out_flags = elf_elfheader (obfd)->e_flags;
447 in_flags = out_flags;
451 /* Disallow linking different ABIs. */
452 /* Only check relocation version.
453 The obj_v0 is compatible with obj_v1. */
454 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
456 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
463 bfd_set_error (bfd_error_bad_value);
467 /* Create the .got section. */
470 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
475 struct elf_link_hash_entry *h;
476 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
477 struct elf_link_hash_table *htab = elf_hash_table (info);
479 /* This function may be called more than once. */
480 if (htab->sgot != NULL)
483 flags = bed->dynamic_sec_flags;
484 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
485 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
487 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
491 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
492 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
496 /* The first bit of the global offset table is the header. */
497 s->size += bed->got_header_size;
499 if (bed->want_got_plt)
501 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
502 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
506 /* Reserve room for the header. */
507 s->size = GOTPLT_HEADER_SIZE;
510 if (bed->want_got_sym)
512 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
513 section. We don't do this in the linker script because we don't want
514 to define the symbol if we are not creating a global offset table. */
515 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
516 "_GLOBAL_OFFSET_TABLE_");
517 elf_hash_table (info)->hgot = h;
524 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
525 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
529 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
531 struct loongarch_elf_link_hash_table *htab;
533 htab = loongarch_elf_hash_table (info);
534 BFD_ASSERT (htab != NULL);
536 if (!loongarch_elf_create_got_section (dynobj, info))
539 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
542 if (!bfd_link_pic (info))
544 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
545 SEC_ALLOC | SEC_THREAD_LOCAL);
547 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
548 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
555 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
556 struct bfd_link_info *info,
557 struct elf_link_hash_entry *h,
558 unsigned long symndx,
561 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
562 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
564 /* This is a global offset table entry for a local symbol. */
565 if (elf_local_got_refcounts (abfd) == NULL)
568 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
569 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
571 _bfd_loongarch_elf_local_got_tls_type (abfd) =
572 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
582 if (htab->elf.sgot == NULL
583 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
587 if (h->got.refcount < 0)
592 elf_local_got_refcounts (abfd)[symndx]++;
595 /* No need for GOT. */
598 _bfd_error_handler (_("Internal error: unreachable."));
602 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
603 *new_tls_type |= tls_type;
605 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
606 if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
607 *new_tls_type &= ~ (GOT_TLS_GDESC);
608 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
610 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
611 "thread local symbol"),
613 h ? h->root.root.string : "<local>");
621 loongarch_reloc_got_type (unsigned int r_type)
625 case R_LARCH_TLS_DESC_PC_HI20:
626 case R_LARCH_TLS_DESC_PC_LO12:
627 case R_LARCH_TLS_DESC_LD:
628 case R_LARCH_TLS_DESC_CALL:
629 return GOT_TLS_GDESC;
631 case R_LARCH_TLS_IE_PC_HI20:
632 case R_LARCH_TLS_IE_PC_LO12:
641 /* Return true if tls type transition can be performed. */
643 loongarch_can_trans_tls (bfd *input_bfd,
644 struct bfd_link_info *info,
645 struct elf_link_hash_entry *h,
646 const Elf_Internal_Rela *rel,
649 char symbol_tls_type;
650 unsigned int reloc_got_type;
651 unsigned int r_symndx = ELFNN_R_SYM (rel->r_info);
653 /* Only TLS DESC/IE in normal code mode will perform type
655 if (! (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
656 && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX))
659 symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
660 reloc_got_type = loongarch_reloc_got_type (r_type);
662 if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
665 if (! bfd_link_executable (info))
668 if (h && h->root.type == bfd_link_hash_undefweak)
674 /* The type of relocation that can be transitioned. */
676 loongarch_tls_transition_without_check (struct bfd_link_info *info,
678 struct elf_link_hash_entry *h)
680 bool local_exec = bfd_link_executable (info)
681 && SYMBOL_REFERENCES_LOCAL (info, h);
685 case R_LARCH_TLS_DESC_PC_HI20:
687 ? R_LARCH_TLS_LE_HI20
688 : R_LARCH_TLS_IE_PC_HI20);
690 case R_LARCH_TLS_DESC_PC_LO12:
692 ? R_LARCH_TLS_LE_LO12
693 : R_LARCH_TLS_IE_PC_LO12);
695 case R_LARCH_TLS_DESC_LD:
696 case R_LARCH_TLS_DESC_CALL:
699 case R_LARCH_TLS_IE_PC_HI20:
700 return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
702 case R_LARCH_TLS_IE_PC_LO12:
703 return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
713 loongarch_tls_transition (bfd *input_bfd,
714 struct bfd_link_info *info,
715 struct elf_link_hash_entry *h,
716 const Elf_Internal_Rela *rel,
719 if (! loongarch_can_trans_tls (input_bfd, info, h, rel, r_type))
722 return loongarch_tls_transition_without_check (info, r_type, h);
725 /* Look through the relocs for a section during the first phase, and
726 allocate space in the global offset table or procedure linkage
730 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
731 asection *sec, const Elf_Internal_Rela *relocs)
733 struct loongarch_elf_link_hash_table *htab;
734 Elf_Internal_Shdr *symtab_hdr;
735 struct elf_link_hash_entry **sym_hashes;
736 const Elf_Internal_Rela *rel;
737 asection *sreloc = NULL;
739 if (bfd_link_relocatable (info))
742 htab = loongarch_elf_hash_table (info);
743 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
744 sym_hashes = elf_sym_hashes (abfd);
746 if (htab->elf.dynobj == NULL)
747 htab->elf.dynobj = abfd;
749 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
752 unsigned int r_symndx;
753 struct elf_link_hash_entry *h;
754 Elf_Internal_Sym *isym = NULL;
756 r_symndx = ELFNN_R_SYM (rel->r_info);
757 r_type = ELFNN_R_TYPE (rel->r_info);
759 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
761 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
765 if (r_symndx < symtab_hdr->sh_info)
767 /* A local symbol. */
768 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
772 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
774 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
778 h->type = STT_GNU_IFUNC;
786 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
787 while (h->root.type == bfd_link_hash_indirect
788 || h->root.type == bfd_link_hash_warning)
789 h = (struct elf_link_hash_entry *) h->root.u.i.link;
792 /* It is referenced by a non-shared object. */
796 if (h && h->type == STT_GNU_IFUNC)
798 if (htab->elf.dynobj == NULL)
799 htab->elf.dynobj = abfd;
801 /* Create 'irelifunc' in PIC object. */
802 if (bfd_link_pic (info)
803 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
805 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
806 else if (!htab->elf.splt
807 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
809 /* Create the ifunc sections, iplt and ipltgot, for static
811 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
812 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
815 if (h->plt.refcount < 0)
820 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
823 int need_dynreloc = 0;
824 int only_need_pcrel = 0;
826 /* Type transitions are only possible with relocations accompanied
828 if (rel + 1 != relocs + sec->reloc_count)
829 r_type = loongarch_tls_transition (abfd, info, h, rel, r_type);
832 case R_LARCH_GOT_PC_HI20:
833 case R_LARCH_GOT_HI20:
834 case R_LARCH_SOP_PUSH_GPREL:
837 h->pointer_equality_needed = 1;
838 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
844 case R_LARCH_TLS_LD_PC_HI20:
845 case R_LARCH_TLS_LD_HI20:
846 case R_LARCH_TLS_GD_PC_HI20:
847 case R_LARCH_TLS_GD_HI20:
848 case R_LARCH_SOP_PUSH_TLS_GD:
849 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
855 case R_LARCH_TLS_IE_PC_HI20:
856 case R_LARCH_TLS_IE_HI20:
857 case R_LARCH_SOP_PUSH_TLS_GOT:
858 if (bfd_link_pic (info))
859 /* May fail for lazy-bind. */
860 info->flags |= DF_STATIC_TLS;
862 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
868 case R_LARCH_TLS_LE_HI20:
869 case R_LARCH_TLS_LE_HI20_R:
870 case R_LARCH_SOP_PUSH_TLS_TPREL:
871 if (!bfd_link_executable (info))
874 info->flags |= DF_STATIC_TLS;
876 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
882 case R_LARCH_TLS_DESC_PC_HI20:
883 case R_LARCH_TLS_DESC_HI20:
884 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
890 case R_LARCH_ABS_HI20:
891 case R_LARCH_SOP_PUSH_ABSOLUTE:
893 /* If this reloc is in a read-only section, we might
894 need a copy reloc. We can't check reliably at this
895 stage whether the section is read-only, as input
896 sections have not yet been mapped to output sections.
897 Tentatively set the flag for now, and correct in
898 adjust_dynamic_symbol. */
902 /* For normal cmodel, pcalau12i + addi.d/w used to data.
903 For first version medium cmodel, pcalau12i + jirl are used to
904 function call, it need to creat PLT entry for STT_FUNC and
905 STT_GNU_IFUNC type symbol. */
906 case R_LARCH_PCALA_HI20:
907 if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
909 /* For pcalau12i + jirl. */
911 if (h->plt.refcount < 0)
916 h->pointer_equality_needed = 1;
928 if (!bfd_link_pic (info))
931 /* We try to create PLT stub for all non-local function. */
932 if (h->plt.refcount < 0)
939 case R_LARCH_SOP_PUSH_PCREL:
942 if (!bfd_link_pic (info))
945 /* We try to create PLT stub for all non-local function. */
946 if (h->plt.refcount < 0)
949 h->pointer_equality_needed = 1;
954 case R_LARCH_SOP_PUSH_PLT_PCREL:
955 /* This symbol requires a procedure linkage table entry. We
956 actually build the entry in adjust_dynamic_symbol,
957 because this might be a case of linking PIC code without
958 linking in any dynamic objects, in which case we don't
959 need to generate a procedure linkage table after all. */
963 if (h->plt.refcount < 0)
969 case R_LARCH_TLS_DTPREL32:
970 case R_LARCH_TLS_DTPREL64:
975 case R_LARCH_JUMP_SLOT:
981 /* If resolved symbol is defined in this object,
982 1. Under pie, the symbol is known. We convert it
983 into R_LARCH_RELATIVE and need load-addr still.
984 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
985 3. Under dll, R_LARCH_NN can't be changed normally, since
986 its defination could be covered by the one in executable.
987 For symbolic, we convert it into R_LARCH_RELATIVE.
988 Thus, only under pde, it needs pcrel only. We discard it. */
989 only_need_pcrel = bfd_link_pde (info);
992 && (!bfd_link_pic (info)
993 || h->type == STT_GNU_IFUNC))
995 /* This reloc might not bind locally. */
997 h->pointer_equality_needed = 1;
1000 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
1002 /* We may need a .plt entry if the symbol is a function
1003 defined in a shared lib or is a function referenced
1004 from the code or read-only section. */
1005 h->plt.refcount += 1;
1010 case R_LARCH_GNU_VTINHERIT:
1011 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1015 case R_LARCH_GNU_VTENTRY:
1016 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1024 /* Record some info for sizing and allocating dynamic entry. */
1025 if (need_dynreloc && (sec->flags & SEC_ALLOC))
1027 /* When creating a shared object, we must copy these
1028 relocs into the output file. We create a reloc
1029 section in dynobj and make room for the reloc. */
1030 struct elf_dyn_relocs *p;
1031 struct elf_dyn_relocs **head;
1036 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
1037 LARCH_ELF_LOG_WORD_BYTES,
1038 abfd, /*rela?*/ true);
1043 /* If this is a global symbol, we count the number of
1044 relocations we need for this symbol. */
1046 head = &h->dyn_relocs;
1049 /* Track dynamic relocs needed for local syms too.
1050 We really need local syms available to do this
1056 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1060 vpp = &elf_section_data (s)->local_dynrel;
1061 head = (struct elf_dyn_relocs **) vpp;
1065 if (p == NULL || p->sec != sec)
1067 bfd_size_type amt = sizeof *p;
1068 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
1079 p->pc_count += only_need_pcrel;
1086 /* Find dynamic relocs for H that apply to read-only sections. */
1089 readonly_dynrelocs (struct elf_link_hash_entry *h)
1091 struct elf_dyn_relocs *p;
1093 for (p = h->dyn_relocs; p != NULL; p = p->next)
1095 asection *s = p->sec->output_section;
1097 if (s != NULL && (s->flags & SEC_READONLY) != 0)
1103 /* Adjust a symbol defined by a dynamic object and referenced by a
1104 regular object. The current definition is in some section of the
1105 dynamic object, but we're not including those sections. We have to
1106 change the definition to something the rest of the link can
1109 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1110 struct elf_link_hash_entry *h)
1112 struct loongarch_elf_link_hash_table *htab;
1115 htab = loongarch_elf_hash_table (info);
1116 BFD_ASSERT (htab != NULL);
1118 dynobj = htab->elf.dynobj;
1120 /* Make sure we know what is going on here. */
1121 BFD_ASSERT (dynobj != NULL
1123 || h->type == STT_GNU_IFUNC
1127 && !h->def_regular)));
1129 /* If this is a function, put it in the procedure linkage table. We
1130 will fill in the contents of the procedure linkage table later
1131 (although we could actually do it here). */
1132 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
1134 if (h->plt.refcount <= 0
1135 || (h->type != STT_GNU_IFUNC
1136 && (SYMBOL_REFERENCES_LOCAL (info, h)
1137 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1138 && h->root.type == bfd_link_hash_undefweak))))
1140 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1141 in an input file, but the symbol was never referred to by a
1142 dynamic object, or if all references were garbage collected.
1143 In such a case, we don't actually need to build a PLT entry. */
1144 h->plt.offset = MINUS_ONE;
1151 h->plt.offset = MINUS_ONE;
1153 /* If this is a weak symbol, and there is a real definition, the
1154 processor independent code will have arranged for us to see the
1155 real definition first, and we can just use the same value. */
1156 if (h->is_weakalias)
1158 struct elf_link_hash_entry *def = weakdef (h);
1159 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1160 h->root.u.def.section = def->root.u.def.section;
1161 h->root.u.def.value = def->root.u.def.value;
1165 /* R_LARCH_COPY is not adept glibc, not to generate. */
1166 /* Can not print anything, because make check ld. */
1170 /* Allocate space in .plt, .got and associated reloc sections for
1174 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1176 struct bfd_link_info *info;
1177 struct loongarch_elf_link_hash_table *htab;
1178 struct elf_dyn_relocs *p;
1180 if (h->root.type == bfd_link_hash_indirect)
1183 if (h->type == STT_GNU_IFUNC
1187 info = (struct bfd_link_info *) inf;
1188 htab = loongarch_elf_hash_table (info);
1189 bool dyn = htab->elf.dynamic_sections_created;
1190 BFD_ASSERT (htab != NULL);
1194 asection *plt, *gotplt, *relplt;
1203 if (h->dynindx == -1 && !h->forced_local && dyn
1204 && h->root.type == bfd_link_hash_undefweak)
1206 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1210 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1211 && h->type != STT_GNU_IFUNC)
1214 plt = htab->elf.splt;
1215 gotplt = htab->elf.sgotplt;
1216 relplt = htab->elf.srelplt;
1218 else if (htab->elf.iplt)
1220 /* .iplt only for IFUNC. */
1221 if (h->type != STT_GNU_IFUNC)
1224 plt = htab->elf.iplt;
1225 gotplt = htab->elf.igotplt;
1226 relplt = htab->elf.irelplt;
1232 plt->size = PLT_HEADER_SIZE;
1234 h->plt.offset = plt->size;
1235 plt->size += PLT_ENTRY_SIZE;
1236 gotplt->size += GOT_ENTRY_SIZE;
1237 relplt->size += sizeof (ElfNN_External_Rela);
1239 /* If this symbol is not defined in a regular file, and we are
1240 not generating a shared library, then set the symbol to this
1241 location in the .plt. This is required to make function
1242 pointers compare as equal between the normal executable and
1243 the shared library. */
1244 if (!bfd_link_pic (info)
1247 h->root.u.def.section = plt;
1248 h->root.u.def.value = h->plt.offset;
1256 h->plt.offset = MINUS_ONE;
1258 if (0 < h->got.refcount)
1261 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1263 /* Make sure this symbol is output as a dynamic symbol.
1264 Undefined weak syms won't yet be marked as dynamic. */
1265 if (h->dynindx == -1 && !h->forced_local && dyn
1266 && h->root.type == bfd_link_hash_undefweak)
1268 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1273 h->got.offset = s->size;
1274 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1276 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1277 if (tls_type & GOT_TLS_GD)
1279 s->size += 2 * GOT_ENTRY_SIZE;
1280 if (bfd_link_executable (info))
1282 /* Link exe and not defined local. */
1283 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1284 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1288 if (SYMBOL_REFERENCES_LOCAL (info, h))
1289 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1291 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1295 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1296 if (tls_type & GOT_TLS_IE)
1298 s->size += GOT_ENTRY_SIZE;
1300 if (bfd_link_executable (info))
1302 /* Link exe and not defined local. */
1303 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1304 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1308 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1312 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1313 if (tls_type & GOT_TLS_GDESC)
1315 s->size += GOT_ENTRY_SIZE * 2;
1316 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1322 s->size += GOT_ENTRY_SIZE;
1323 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1324 || h->root.type != bfd_link_hash_undefweak)
1325 && (bfd_link_pic (info)
1326 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1328 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1329 /* Undefined weak symbol in static PIE resolves to 0 without
1330 any dynamic relocations. */
1331 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1335 h->got.offset = MINUS_ONE;
1337 if (h->dyn_relocs == NULL)
1340 /* Extra dynamic relocate,
1342 * R_LARCH_TLS_DTPRELNN
1346 if (SYMBOL_CALLS_LOCAL (info, h))
1348 struct elf_dyn_relocs **pp;
1350 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1352 p->count -= p->pc_count;
1361 if (h->root.type == bfd_link_hash_undefweak)
1363 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1364 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1365 || (!bfd_link_pic (info) && h->non_got_ref))
1366 h->dyn_relocs = NULL;
1367 else if (h->dynindx == -1 && !h->forced_local)
1369 /* Make sure this symbol is output as a dynamic symbol.
1370 Undefined weak syms won't yet be marked as dynamic. */
1371 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1374 if (h->dynindx == -1)
1375 h->dyn_relocs = NULL;
1379 for (p = h->dyn_relocs; p != NULL; p = p->next)
1381 asection *sreloc = elf_section_data (p->sec)->sreloc;
1382 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1388 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1389 For local def and ref ifunc,
1390 dynamic relocations are stored in
1391 1. rela.srelgot section in dynamic object (dll or exec).
1392 2. rela.irelplt section in static executable.
1393 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1394 instead of rela.srelplt. Glibc ELF loader will not support
1395 R_LARCH_IRELATIVE relocation in rela.plt. */
1398 local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1399 struct elf_link_hash_entry *h,
1400 struct elf_dyn_relocs **head,
1401 unsigned int plt_entry_size,
1402 unsigned int plt_header_size,
1403 unsigned int got_entry_size,
1406 asection *plt, *gotplt, *relplt;
1407 struct elf_dyn_relocs *p;
1408 unsigned int sizeof_reloc;
1409 const struct elf_backend_data *bed;
1410 struct elf_link_hash_table *htab;
1411 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1412 bool use_plt = !avoid_plt || h->plt.refcount > 0;
1413 bool need_dynreloc = !use_plt || bfd_link_pic (info);
1415 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1416 in executable or it isn't referenced via PLT, the address of
1417 the resolved function may be used. But in non-PIC executable,
1418 the address of its plt slot may be used. Pointer equality may
1419 not work correctly. PIE or non-PLT reference should be used if
1420 pointer equality is required here.
1422 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1423 backend should change it to the normal function and set its address
1424 to its PLT entry which should be resolved by R_*_IRELATIVE at
1425 run-time. All external references should be resolved to its PLT in
1428 && !(bfd_link_pde (info) && h->def_regular)
1429 && (h->dynindx != -1
1430 || info->export_dynamic)
1431 && h->pointer_equality_needed)
1433 info->callbacks->einfo
1434 /* xgettext:c-format. */
1435 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1436 "equality in `%pB' can not be used when making an "
1437 "executable; recompile with -fPIE and relink with -pie\n"),
1438 h->root.root.string,
1439 h->root.u.def.section->owner);
1440 bfd_set_error (bfd_error_bad_value);
1444 htab = elf_hash_table (info);
1446 /* When the symbol is marked with regular reference, if PLT isn't used
1447 or we are building a PIC object, we must keep dynamic relocation
1448 if there is non-GOT reference and use PLT if there is PC-relative
1450 if (need_dynreloc && h->ref_regular)
1453 for (p = *head; p != NULL; p = p->next)
1457 /* Need dynamic relocations for non-GOT reference. */
1461 /* Must use PLT for PC-relative reference. */
1463 need_dynreloc = bfd_link_pic (info);
1471 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1472 if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1474 h->got = htab->init_got_offset;
1475 h->plt = htab->init_plt_offset;
1480 /* Return and discard space for dynamic relocations against it if
1481 it is never referenced. */
1482 if (!h->ref_regular)
1484 if (h->plt.refcount > 0
1485 || h->got.refcount > 0)
1487 h->got = htab->init_got_offset;
1488 h->plt = htab->init_plt_offset;
1494 bed = get_elf_backend_data (info->output_bfd);
1495 if (bed->rela_plts_and_copies_p)
1496 sizeof_reloc = bed->s->sizeof_rela;
1498 sizeof_reloc = bed->s->sizeof_rel;
1500 /* When building a static executable, use iplt, igot.plt and
1501 rela.iplt sections for STT_GNU_IFUNC symbols. */
1502 if (htab->splt != NULL)
1505 gotplt = htab->sgotplt;
1506 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1507 relplt = htab->srelgot;
1509 /* If this is the first plt entry and PLT is used, make room for
1510 the special first entry. */
1511 if (plt->size == 0 && use_plt)
1512 plt->size += plt_header_size;
1517 gotplt = htab->igotplt;
1518 relplt = htab->irelplt;
1523 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1524 the original value for R_*_IRELATIVE. */
1525 h->plt.offset = plt->size;
1527 /* Make room for this entry in the plt/iplt section. */
1528 plt->size += plt_entry_size;
1530 /* We also need to make an entry in the got.plt/got.iplt section,
1531 which will be placed in the got section by the linker script. */
1532 gotplt->size += got_entry_size;
1535 /* We also need to make an entry in the rela.plt/.rela.iplt
1536 section for GOTPLT relocation if PLT is used. */
1539 relplt->size += sizeof_reloc;
1540 relplt->reloc_count++;
1543 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1544 there is a non-GOT reference in a PIC object or PLT isn't used. */
1545 if (!need_dynreloc || !h->non_got_ref)
1548 /* Finally, allocate space. */
1552 bfd_size_type count = 0;
1560 htab->ifunc_resolvers = count != 0;
1562 /* Dynamic relocations are stored in
1563 1. rela.srelgot section in PIC object.
1564 2. rela.srelgot section in dynamic executable.
1565 3. rela.irelplt section in static executable. */
1566 if (htab->splt != NULL)
1567 htab->srelgot->size += count * sizeof_reloc;
1570 relplt->size += count * sizeof_reloc;
1571 relplt->reloc_count += count;
1575 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1576 and got has the PLT entry adddress. We will load the GOT entry
1577 with the PLT entry in finish_dynamic_symbol if it is used. For
1578 branch, it uses got.plt. For symbol value, if PLT is used,
1579 1. Use got.plt in a PIC object if it is forced local or not
1581 2. Use got.plt in a non-PIC object if pointer equality isn't
1583 3. Use got.plt in PIE.
1584 4. Use got.plt if got isn't used.
1585 5. Otherwise use got so that it can be shared among different
1586 objects at run-time.
1587 If PLT isn't used, always use got for symbol value.
1588 We only need to relocate got entry in PIC object or in dynamic
1589 executable without PLT. */
1591 && (h->got.refcount <= 0
1592 || (bfd_link_pic (info)
1593 && (h->dynindx == -1
1594 || h->forced_local))
1596 !h->pointer_equality_needed)
1597 || htab->sgot == NULL))
1600 h->got.offset = (bfd_vma) -1;
1606 /* PLT isn't used. */
1607 h->plt.offset = (bfd_vma) -1;
1609 if (h->got.refcount <= 0)
1611 /* GOT isn't need when there are only relocations for static
1613 h->got.offset = (bfd_vma) -1;
1617 h->got.offset = htab->sgot->size;
1618 htab->sgot->size += got_entry_size;
1619 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1620 used. Otherwise, the GOT entry will be filled with the PLT
1621 entry and dynamic GOT relocation isn't needed. */
1624 /* For non-static executable, dynamic GOT relocation is in
1625 rela.got section, but for static executable, it is
1626 in rela.iplt section. */
1627 if (htab->splt != NULL)
1628 htab->srelgot->size += sizeof_reloc;
1631 relplt->size += sizeof_reloc;
1632 relplt->reloc_count++;
1641 /* Allocate space in .plt, .got and associated reloc sections for
1642 ifunc dynamic relocs. */
1645 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1647 struct bfd_link_info *info;
1648 /* An example of a bfd_link_hash_indirect symbol is versioned
1649 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1650 -> __gxx_personality_v0(bfd_link_hash_defined)
1652 There is no need to process bfd_link_hash_indirect symbols here
1653 because we will also be presented with the concrete instance of
1654 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1655 called to copy all relevant data from the generic to the concrete
1657 if (h->root.type == bfd_link_hash_indirect)
1660 if (h->root.type == bfd_link_hash_warning)
1661 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1663 info = (struct bfd_link_info *) inf;
1665 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1666 here if it is defined and referenced in a non-shared object. */
1667 if (h->type == STT_GNU_IFUNC && h->def_regular)
1669 if (SYMBOL_REFERENCES_LOCAL (info, h))
1670 return local_allocate_ifunc_dyn_relocs (info, h,
1677 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1688 /* Allocate space in .plt, .got and associated reloc sections for
1689 ifunc dynamic relocs. */
1692 elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1694 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1696 if (h->type != STT_GNU_IFUNC
1700 || h->root.type != bfd_link_hash_defined)
1703 return elfNN_allocate_ifunc_dynrelocs (h, inf);
1706 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1707 read-only sections. */
1710 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1714 if (h->root.type == bfd_link_hash_indirect)
1717 sec = readonly_dynrelocs (h);
1720 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1722 info->flags |= DF_TEXTREL;
1723 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1724 "read-only section `%pA'\n"),
1725 sec->owner, h->root.root.string, sec);
1727 /* Not an error, just cut short the traversal. */
1734 loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1735 struct bfd_link_info *info)
1737 struct loongarch_elf_link_hash_table *htab;
1742 htab = loongarch_elf_hash_table (info);
1743 BFD_ASSERT (htab != NULL);
1744 dynobj = htab->elf.dynobj;
1745 BFD_ASSERT (dynobj != NULL);
1747 if (htab->elf.dynamic_sections_created)
1749 /* Set the contents of the .interp section to the interpreter. */
1750 if (bfd_link_executable (info) && !info->nointerp)
1752 const char *interpreter;
1753 s = bfd_get_linker_section (dynobj, ".interp");
1754 BFD_ASSERT (s != NULL);
1756 if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
1757 interpreter = "/lib32/ld.so.1";
1758 else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
1759 interpreter = "/lib64/ld.so.1";
1761 interpreter = "/lib/ld.so.1";
1763 s->contents = (unsigned char *) interpreter;
1764 s->size = strlen (interpreter) + 1;
1768 /* Set up .got offsets for local syms, and space for local dynamic
1770 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1772 bfd_signed_vma *local_got;
1773 bfd_signed_vma *end_local_got;
1774 char *local_tls_type;
1775 bfd_size_type locsymcount;
1776 Elf_Internal_Shdr *symtab_hdr;
1779 if (!is_loongarch_elf (ibfd))
1782 for (s = ibfd->sections; s != NULL; s = s->next)
1784 struct elf_dyn_relocs *p;
1786 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1788 p->count -= p->pc_count;
1789 if (!bfd_is_abs_section (p->sec)
1790 && bfd_is_abs_section (p->sec->output_section))
1792 /* Input section has been discarded, either because
1793 it is a copy of a linkonce section or due to
1794 linker script /DISCARD/, so we'll be discarding
1797 else if (0 < p->count)
1799 srel = elf_section_data (p->sec)->sreloc;
1800 srel->size += p->count * sizeof (ElfNN_External_Rela);
1801 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1802 info->flags |= DF_TEXTREL;
1807 local_got = elf_local_got_refcounts (ibfd);
1811 symtab_hdr = &elf_symtab_hdr (ibfd);
1812 locsymcount = symtab_hdr->sh_info;
1813 end_local_got = local_got + locsymcount;
1814 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1816 srel = htab->elf.srelgot;
1817 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1821 *local_got = s->size;
1822 if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1824 /* TLS gd use two got. */
1825 if (*local_tls_type & GOT_TLS_GD)
1827 s->size += 2 * GOT_ENTRY_SIZE;
1828 if (!bfd_link_executable (info))
1829 srel->size += sizeof (ElfNN_External_Rela);
1832 /* TLS_DESC use two got. */
1833 if (*local_tls_type & GOT_TLS_GDESC)
1835 s->size += 2 * GOT_ENTRY_SIZE;
1836 srel->size += sizeof (ElfNN_External_Rela);
1839 /* TLS ie and use one got. */
1840 if (*local_tls_type & GOT_TLS_IE)
1842 s->size += GOT_ENTRY_SIZE;
1843 if (!bfd_link_executable (info))
1844 srel->size += sizeof (ElfNN_External_Rela);
1849 s->size += GOT_ENTRY_SIZE;
1850 srel->size += sizeof (ElfNN_External_Rela);
1854 *local_got = MINUS_ONE;
1858 /* Allocate global sym .plt and .got entries, and space for global
1859 sym dynamic relocs. */
1860 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1862 /* Allocate global ifunc sym .plt and .got entries, and space for global
1863 ifunc sym dynamic relocs. */
1864 elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
1866 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1867 htab_traverse (htab->loc_hash_table,
1868 elfNN_allocate_local_ifunc_dynrelocs, info);
1870 /* Don't allocate .got.plt section if there are no PLT. */
1871 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1872 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1873 htab->elf.sgotplt->size = 0;
1875 /* The check_relocs and adjust_dynamic_symbol entry points have
1876 determined the sizes of the various dynamic sections. Allocate
1878 for (s = dynobj->sections; s != NULL; s = s->next)
1880 if ((s->flags & SEC_LINKER_CREATED) == 0)
1883 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1884 || s == htab->elf.sgotplt || s == htab->elf.igotplt
1885 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1887 /* Strip this section if we don't need it; see the
1890 else if (strncmp (s->name, ".rela", 5) == 0)
1894 /* We use the reloc_count field as a counter if we need
1895 to copy relocs into the output file. */
1901 /* It's not one of our sections. */
1907 /* If we don't need this section, strip it from the
1908 output file. This is mostly to handle .rela.bss and
1909 .rela.plt. We must create both sections in
1910 create_dynamic_sections, because they must be created
1911 before the linker maps input sections to output
1912 sections. The linker does that before
1913 adjust_dynamic_symbol is called, and it is that
1914 function which decides whether anything needs to go
1915 into these sections. */
1916 s->flags |= SEC_EXCLUDE;
1920 if ((s->flags & SEC_HAS_CONTENTS) == 0)
1923 /* Allocate memory for the section contents. Zero the memory
1924 for the benefit of .rela.plt, which has 4 unused entries
1925 at the beginning, and we don't want garbage. */
1926 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1927 if (s->contents == NULL)
1931 if (elf_hash_table (info)->dynamic_sections_created)
1933 /* Add some entries to the .dynamic section. We fill in the
1934 values later, in loongarch_elf_finish_dynamic_sections, but we
1935 must add the entries now so that we get the correct size for
1936 the .dynamic section. The DT_DEBUG entry is filled in by the
1937 dynamic linker and used by the debugger. */
1938 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1940 if (bfd_link_executable (info))
1942 if (!add_dynamic_entry (DT_DEBUG, 0))
1946 if (htab->elf.srelplt->size != 0)
1948 if (!add_dynamic_entry (DT_PLTGOT, 0)
1949 || !add_dynamic_entry (DT_PLTRELSZ, 0)
1950 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1951 || !add_dynamic_entry (DT_JMPREL, 0))
1955 if (!add_dynamic_entry (DT_RELA, 0)
1956 || !add_dynamic_entry (DT_RELASZ, 0)
1957 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1960 /* If any dynamic relocs apply to a read-only section,
1961 then we need a DT_TEXTREL entry. */
1962 if ((info->flags & DF_TEXTREL) == 0)
1963 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1965 if (info->flags & DF_TEXTREL)
1967 if (!add_dynamic_entry (DT_TEXTREL, 0))
1969 /* Clear the DF_TEXTREL flag. It will be set again if we
1970 write out an actual text relocation; we may not, because
1971 at this point we do not know whether e.g. any .eh_frame
1972 absolute relocations have been converted to PC-relative. */
1973 info->flags &= ~DF_TEXTREL;
1976 #undef add_dynamic_entry
1981 #define LARCH_LD_STACK_DEPTH 16
1982 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1983 static size_t larch_stack_top = 0;
1985 static bfd_reloc_status_type
1986 loongarch_push (int64_t val)
1988 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1989 return bfd_reloc_outofrange;
1990 larch_opc_stack[larch_stack_top++] = val;
1991 return bfd_reloc_ok;
1994 static bfd_reloc_status_type
1995 loongarch_pop (int64_t *val)
1997 if (larch_stack_top == 0)
1998 return bfd_reloc_outofrange;
2000 *val = larch_opc_stack[--larch_stack_top];
2001 return bfd_reloc_ok;
2004 static bfd_reloc_status_type
2005 loongarch_top (int64_t *val)
2007 if (larch_stack_top == 0)
2008 return bfd_reloc_outofrange;
2010 *val = larch_opc_stack[larch_stack_top - 1];
2011 return bfd_reloc_ok;
2015 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
2017 BFD_ASSERT (s && s->contents);
2018 const struct elf_backend_data *bed;
2021 bed = get_elf_backend_data (abfd);
2022 if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
2023 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
2024 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
2025 bed->s->swap_reloca_out (abfd, rel, loc);
2028 /* Check rel->r_offset in range of contents. */
2029 static bfd_reloc_status_type
2030 loongarch_check_offset (const Elf_Internal_Rela *rel,
2031 const asection *input_section)
2033 if (0 == strcmp(input_section->name, ".text")
2034 && rel->r_offset > input_section->size)
2035 return bfd_reloc_overflow;
2037 return bfd_reloc_ok;
2040 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2042 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2043 if (ret == bfd_reloc_ok) \
2045 ret = loongarch_pop (&op1); \
2046 if (ret == bfd_reloc_ok) \
2047 ret = loongarch_push (op3); \
2052 /* Write immediate to instructions. */
2054 static bfd_reloc_status_type
2055 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
2056 const asection *input_section ATTRIBUTE_UNUSED,
2057 reloc_howto_type *howto, bfd *input_bfd,
2058 bfd_byte *contents, bfd_vma reloc_val)
2060 /* Adjust the immediate based on alignment and
2061 its position in the instruction. */
2062 if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
2063 return bfd_reloc_overflow;
2065 int bits = bfd_get_reloc_size (howto) * 8;
2066 uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
2068 /* Write immediate to instruction. */
2069 insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
2071 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
2073 return bfd_reloc_ok;
2076 static bfd_reloc_status_type
2077 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
2078 reloc_howto_type *howto, bfd_vma value,
2079 bfd *input_bfd, bfd_byte *contents)
2081 int64_t opr1, opr2, opr3;
2082 bfd_reloc_status_type r = bfd_reloc_ok;
2083 int bits = bfd_get_reloc_size (howto) * 8;
2085 switch (ELFNN_R_TYPE (rel->r_info))
2087 case R_LARCH_SOP_PUSH_PCREL:
2088 case R_LARCH_SOP_PUSH_ABSOLUTE:
2089 case R_LARCH_SOP_PUSH_GPREL:
2090 case R_LARCH_SOP_PUSH_TLS_TPREL:
2091 case R_LARCH_SOP_PUSH_TLS_GOT:
2092 case R_LARCH_SOP_PUSH_TLS_GD:
2093 case R_LARCH_SOP_PUSH_PLT_PCREL:
2094 r = loongarch_push (value);
2097 case R_LARCH_SOP_PUSH_DUP:
2098 r = loongarch_pop (&opr1);
2099 if (r == bfd_reloc_ok)
2101 r = loongarch_push (opr1);
2102 if (r == bfd_reloc_ok)
2103 r = loongarch_push (opr1);
2107 case R_LARCH_SOP_ASSERT:
2108 r = loongarch_pop (&opr1);
2109 if (r != bfd_reloc_ok || !opr1)
2110 r = bfd_reloc_notsupported;
2113 case R_LARCH_SOP_NOT:
2114 r = loongarch_pop (&opr1);
2115 if (r == bfd_reloc_ok)
2116 r = loongarch_push (!opr1);
2119 case R_LARCH_SOP_SUB:
2120 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
2123 case R_LARCH_SOP_SL:
2124 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
2127 case R_LARCH_SOP_SR:
2128 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
2131 case R_LARCH_SOP_AND:
2132 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
2135 case R_LARCH_SOP_ADD:
2136 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
2139 case R_LARCH_SOP_IF_ELSE:
2140 r = loongarch_pop (&opr3);
2141 if (r == bfd_reloc_ok)
2143 r = loongarch_pop (&opr2);
2144 if (r == bfd_reloc_ok)
2146 r = loongarch_pop (&opr1);
2147 if (r == bfd_reloc_ok)
2148 r = loongarch_push (opr1 ? opr2 : opr3);
2153 case R_LARCH_SOP_POP_32_S_10_5:
2154 case R_LARCH_SOP_POP_32_S_10_12:
2155 case R_LARCH_SOP_POP_32_S_10_16:
2156 case R_LARCH_SOP_POP_32_S_10_16_S2:
2157 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2158 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2159 case R_LARCH_SOP_POP_32_S_5_20:
2160 case R_LARCH_SOP_POP_32_U_10_12:
2161 case R_LARCH_SOP_POP_32_U:
2162 r = loongarch_pop (&opr1);
2163 if (r != bfd_reloc_ok)
2165 r = loongarch_check_offset (rel, input_section);
2166 if (r != bfd_reloc_ok)
2169 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2171 contents, (bfd_vma)opr1);
2174 case R_LARCH_TLS_DTPREL32:
2176 case R_LARCH_TLS_DTPREL64:
2178 r = loongarch_check_offset (rel, input_section);
2179 if (r != bfd_reloc_ok)
2182 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2185 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2186 Because set/sub reloc pair not support multi-thread. While add/sub
2187 reloc pair process order not affect the final result.
2189 For add/sub reloc, the original value will be involved in the
2190 calculation. In order not to add/sub extra value, we write 0 to symbol
2191 address at assembly time.
2193 add/sub reloc bits determined by the value after symbol subtraction,
2196 add/sub reloc save part of the symbol value, so we only need to
2197 save howto->dst_mask bits. */
2201 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2202 contents + rel->r_offset);
2203 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2204 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2209 /* Not need to read the original value, just write the new value. */
2221 /* Because add/sub reloc is processed separately,
2222 so the high bits is invalid. */
2223 bfd_vma word = value & howto->dst_mask;
2224 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2229 case R_LARCH_ADD_ULEB128:
2230 case R_LARCH_SUB_ULEB128:
2232 unsigned int len = 0;
2233 /* Before write uleb128, first read it to get it's length. */
2234 _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2235 loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2240 /* For eh_frame and debug info. */
2241 case R_LARCH_32_PCREL:
2242 case R_LARCH_64_PCREL:
2244 value -= sec_addr (input_section) + rel->r_offset;
2245 value += rel->r_addend;
2246 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2247 contents + rel->r_offset);
2248 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2249 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2255 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2259 case R_LARCH_ABS_HI20:
2260 case R_LARCH_ABS_LO12:
2261 case R_LARCH_ABS64_LO20:
2262 case R_LARCH_ABS64_HI12:
2263 case R_LARCH_PCALA_HI20:
2264 case R_LARCH_PCALA_LO12:
2265 case R_LARCH_PCALA64_LO20:
2266 case R_LARCH_PCALA64_HI12:
2267 case R_LARCH_GOT_PC_HI20:
2268 case R_LARCH_GOT_PC_LO12:
2269 case R_LARCH_GOT64_PC_LO20:
2270 case R_LARCH_GOT64_PC_HI12:
2271 case R_LARCH_GOT_HI20:
2272 case R_LARCH_GOT_LO12:
2273 case R_LARCH_GOT64_LO20:
2274 case R_LARCH_GOT64_HI12:
2275 case R_LARCH_TLS_LE_HI20:
2276 case R_LARCH_TLS_LE_LO12:
2277 case R_LARCH_TLS_LE_HI20_R:
2278 case R_LARCH_TLS_LE_LO12_R:
2279 case R_LARCH_TLS_LE64_LO20:
2280 case R_LARCH_TLS_LE64_HI12:
2281 case R_LARCH_TLS_IE_PC_HI20:
2282 case R_LARCH_TLS_IE_PC_LO12:
2283 case R_LARCH_TLS_IE64_PC_LO20:
2284 case R_LARCH_TLS_IE64_PC_HI12:
2285 case R_LARCH_TLS_IE_HI20:
2286 case R_LARCH_TLS_IE_LO12:
2287 case R_LARCH_TLS_IE64_LO20:
2288 case R_LARCH_TLS_IE64_HI12:
2289 case R_LARCH_TLS_LD_PC_HI20:
2290 case R_LARCH_TLS_LD_HI20:
2291 case R_LARCH_TLS_GD_PC_HI20:
2292 case R_LARCH_TLS_GD_HI20:
2293 case R_LARCH_PCREL20_S2:
2294 case R_LARCH_CALL36:
2295 case R_LARCH_TLS_DESC_PC_HI20:
2296 case R_LARCH_TLS_DESC_PC_LO12:
2297 case R_LARCH_TLS_DESC64_PC_LO20:
2298 case R_LARCH_TLS_DESC64_PC_HI12:
2299 case R_LARCH_TLS_DESC_HI20:
2300 case R_LARCH_TLS_DESC_LO12:
2301 case R_LARCH_TLS_DESC64_LO20:
2302 case R_LARCH_TLS_DESC64_HI12:
2303 case R_LARCH_TLS_LD_PCREL20_S2:
2304 case R_LARCH_TLS_GD_PCREL20_S2:
2305 case R_LARCH_TLS_DESC_PCREL20_S2:
2306 r = loongarch_check_offset (rel, input_section);
2307 if (r != bfd_reloc_ok)
2310 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2315 case R_LARCH_TLS_DESC_LD:
2316 case R_LARCH_TLS_DESC_CALL:
2321 case R_LARCH_TLS_LE_ADD_R:
2325 r = bfd_reloc_notsupported;
2330 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2338 Elf_Internal_Sym *sym;
2339 struct elf_link_hash_entry *h;
2342 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2343 static size_t larch_reloc_queue_head = 0;
2344 static size_t larch_reloc_queue_tail = 0;
2347 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2348 Elf_Internal_Sym *sym)
2350 const char *ret = NULL;
2352 ret = bfd_elf_string_from_elf_section (input_bfd,
2353 elf_symtab_hdr (input_bfd).sh_link,
2356 ret = h->root.root.string;
2358 if (ret == NULL || *ret == '\0')
2364 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2365 bfd_vma r_offset, Elf_Internal_Sym *sym,
2366 struct elf_link_hash_entry *h, bfd_vma addend)
2368 if ((larch_reloc_queue_head == 0
2369 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2370 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2371 larch_reloc_queue_head =
2372 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2373 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2374 larch_reloc_queue[larch_reloc_queue_tail].section = section;
2375 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2376 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2377 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2378 larch_reloc_queue[larch_reloc_queue_tail].h = h;
2379 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2380 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2381 larch_reloc_queue_tail =
2382 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2386 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2388 size_t i = larch_reloc_queue_head;
2390 asection *section = NULL;
2391 bfd_vma r_offset = 0;
2393 p ("Dump relocate record:\n");
2394 p ("stack top\t\trelocation name\t\tsymbol");
2395 while (i != larch_reloc_queue_tail)
2397 if (a_bfd != larch_reloc_queue[i].bfd
2398 || section != larch_reloc_queue[i].section
2399 || r_offset != larch_reloc_queue[i].r_offset)
2401 a_bfd = larch_reloc_queue[i].bfd;
2402 section = larch_reloc_queue[i].section;
2403 r_offset = larch_reloc_queue[i].r_offset;
2404 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2405 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2409 inited = 1, p ("...\n");
2411 reloc_howto_type *howto =
2412 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2413 larch_reloc_queue[i].r_type);
2414 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2415 howto ? howto->name : "<unknown reloc>",
2416 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2417 larch_reloc_queue[i].sym));
2419 long addend = larch_reloc_queue[i].addend;
2421 p (" - %ld", -addend);
2422 else if (0 < addend)
2423 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2426 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2429 "-- Record dump end --\n\n");
2433 loongarch_reloc_is_fatal (struct bfd_link_info *info,
2435 asection *input_section,
2436 Elf_Internal_Rela *rel,
2437 reloc_howto_type *howto,
2438 bfd_reloc_status_type rtype,
2446 /* 'dangerous' means we do it but can't promise it's ok
2447 'unsupport' means out of ability of relocation type
2448 'undefined' means we can't deal with the undefined symbol. */
2449 case bfd_reloc_undefined:
2450 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2451 rel->r_offset, true);
2452 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2453 input_bfd, input_section, rel->r_offset,
2455 is_undefweak ? "[undefweak] " : "", name, msg);
2457 case bfd_reloc_dangerous:
2458 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2459 input_bfd, input_section, rel->r_offset,
2461 is_undefweak ? "[undefweak] " : "", name, msg);
2464 case bfd_reloc_notsupported:
2465 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2466 input_bfd, input_section, rel->r_offset,
2468 is_undefweak ? "[undefweak] " : "", name, msg);
2476 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2477 hi20 immediate need to add 0x1.
2478 For example: pc 0x120000000, symbol 0x120000812
2479 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2480 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2481 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2484 pcalau12i $t0, hi20 (0x1)
2485 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2486 addi.d $t0, $t0, lo12 (0x812)
2487 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2488 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2490 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2492 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
2493 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2495 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2496 relocation = (relocation & ~(bfd_vma)0xfff) \
2497 - (pc & ~(bfd_vma)0xfff); \
2499 relocation += 0x1000; \
2502 /* Handle problems caused by symbol extensions in TLS LE, The processing
2503 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
2504 #define RELOCATE_TLS_TP32_HI20(relocation) \
2506 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2508 relocation += 0x800; \
2509 relocation = relocation & ~(bfd_vma)0xfff; \
2512 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2513 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2515 lo12: 0x1812348ffff812 & 0xfff = 0x812
2516 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2517 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2520 pcalau12i $t1, hi20 (0x80000)
2521 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2522 = 0x11000010000100 + 0xffffffff80000000
2524 addi.d $t0, $zero, lo12 (0x812)
2525 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2526 lo20 need to sub 0x1)
2527 lu32i.d $t0, lo20 (0x71234)
2528 $t0 = {0x71234, 0xfffff812}
2530 lu52i.d $t0, hi12 (0x0)
2531 $t0 = {0x0, 0x71234fffff812}
2534 $t1 = 0x10ffff90000000 + 0x71234fffff812
2535 = 0x1812348ffff812. */
2536 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2538 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2539 relocation = (relocation & ~(bfd_vma)0xfff) \
2540 - ((pc) & ~(bfd_vma)0xfff); \
2542 relocation += (0x1000 - 0x100000000); \
2543 if (relocation & 0x80000000) \
2544 relocation += 0x100000000; \
2547 /* Transition instruction sequence to relax instruction sequence. */
2549 loongarch_tls_perform_trans (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
2550 int r_type, struct elf_link_hash_entry *h,
2551 struct bfd_link_info *info)
2553 bool local_exec = bfd_link_executable (info)
2554 && SYMBOL_REFERENCES_LOCAL (info, h);
2555 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
2560 case R_LARCH_TLS_DESC_PC_HI20:
2562 /* DESC -> LE relaxation:
2563 pcalalau12i $a0,%desc_pc_hi20(var) =>
2564 lu12i.w $a0,%le_hi20(var)
2566 bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
2567 contents + rel->r_offset);
2569 /* DESC -> IE relaxation:
2570 pcalalau12i $a0,%desc_pc_hi20(var) =>
2571 pcalalau12i $a0,%ie_pc_hi20(var)
2575 case R_LARCH_TLS_DESC_PC_LO12:
2578 /* DESC -> LE relaxation:
2579 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2580 ori $a0,$a0,le_lo12(var)
2582 insn = LARCH_ORI | LARCH_RD_RJ_A0;
2583 bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
2584 contents + rel->r_offset);
2588 /* DESC -> IE relaxation:
2589 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2590 ld.d $a0,$a0,%%ie_pc_lo12
2592 bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
2593 contents + rel->r_offset);
2597 case R_LARCH_TLS_DESC_LD:
2598 case R_LARCH_TLS_DESC_CALL:
2599 /* DESC -> LE/IE relaxation:
2600 ld.d $ra,$a0,%desc_ld(var) => NOP
2601 jirl $ra,$ra,%desc_call(var) => NOP
2603 bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
2606 case R_LARCH_TLS_IE_PC_HI20:
2609 /* IE -> LE relaxation:
2610 pcalalau12i $rd,%ie_pc_hi20(var) =>
2611 lu12i.w $rd,%le_hi20(var)
2613 insn = bfd_getl32 (contents + rel->r_offset);
2614 bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
2615 contents + rel->r_offset);
2619 case R_LARCH_TLS_IE_PC_LO12:
2622 /* IE -> LE relaxation:
2623 ld.d $rd,$rj,%%ie_pc_lo12 =>
2624 ori $rd,$rj,le_lo12(var)
2626 insn = bfd_getl32 (contents + rel->r_offset);
2627 bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
2628 contents + rel->r_offset);
2638 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2639 bfd *input_bfd, asection *input_section,
2640 bfd_byte *contents, Elf_Internal_Rela *relocs,
2641 Elf_Internal_Sym *local_syms,
2642 asection **local_sections)
2644 Elf_Internal_Rela *rel;
2645 Elf_Internal_Rela *relend;
2647 asection *sreloc = elf_section_data (input_section)->sreloc;
2648 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2649 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2650 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2651 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2652 bool is_pic = bfd_link_pic (info);
2653 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2654 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2655 asection *got = htab->elf.sgot;
2657 relend = relocs + input_section->reloc_count;
2658 for (rel = relocs; rel < relend; rel++)
2660 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
2661 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2662 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2663 reloc_howto_type *howto = NULL;
2664 asection *sec = NULL;
2665 Elf_Internal_Sym *sym = NULL;
2666 struct elf_link_hash_entry *h = NULL;
2668 bfd_reloc_status_type r = bfd_reloc_ok;
2669 bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
2670 unsigned int trans_r_type = r_type;
2671 bool resolved_local, resolved_dynly, resolved_to_const;
2673 bfd_vma relocation, off, ie_off, desc_off;
2676 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2677 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2678 || r_type == R_LARCH_GNU_VTENTRY)
2681 /* This is a final link. */
2682 if (r_symndx < symtab_hdr->sh_info)
2684 is_undefweak = false;
2685 unresolved_reloc = false;
2686 sym = local_syms + r_symndx;
2687 sec = local_sections[r_symndx];
2688 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2690 /* Relocate against local STT_GNU_IFUNC symbol. */
2691 if (!bfd_link_relocatable (info)
2692 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2694 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2699 /* Set STT_GNU_IFUNC symbol value. */
2700 h->root.u.def.value = sym->st_value;
2701 h->root.u.def.section = sec;
2703 defined_local = true;
2704 resolved_local = true;
2705 resolved_dynly = false;
2706 resolved_to_const = false;
2708 /* Calc in funtion elf_link_input_bfd,
2709 * if #define elf_backend_rela_normal to 1. */
2710 if (bfd_link_relocatable (info)
2711 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2716 bool warned, ignored;
2718 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2719 r_symndx, symtab_hdr, sym_hashes,
2721 unresolved_reloc, warned, ignored);
2722 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2724 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2725 symbol. And 'dynamic_undefined_weak' specify what to do when
2726 meeting undefweak. */
2728 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2730 defined_local = false;
2731 resolved_local = false;
2732 resolved_to_const = (!is_dyn || h->dynindx == -1
2733 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2734 resolved_dynly = !resolved_local && !resolved_to_const;
2738 /* Symbol undefined offen means failed already. I don't know why
2739 'warned' here but I guess it want to continue relocating as if
2740 no error occures to find other errors as more as possible. */
2742 /* To avoid generating warning messages about truncated
2743 relocations, set the relocation's address to be the same as
2744 the start of this section. */
2745 relocation = (input_section->output_section
2746 ? input_section->output_section->vma
2749 defined_local = relocation != 0;
2750 resolved_local = defined_local;
2751 resolved_to_const = !resolved_local;
2752 resolved_dynly = false;
2756 defined_local = !unresolved_reloc && !ignored;
2758 defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2759 resolved_dynly = !resolved_local;
2760 resolved_to_const = !resolved_local && !resolved_dynly;
2764 name = loongarch_sym_name (input_bfd, h, sym);
2766 if (sec != NULL && discarded_section (sec))
2767 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2768 1, relend, howto, 0, contents);
2770 if (bfd_link_relocatable (info))
2773 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2774 from removed linkonce sections, or sections discarded by a linker
2775 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2776 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2778 defined_local = false;
2779 resolved_local = false;
2780 resolved_dynly = false;
2781 resolved_to_const = true;
2784 /* The ifunc reference generate plt. */
2785 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2787 defined_local = true;
2788 resolved_local = true;
2789 resolved_dynly = false;
2790 resolved_to_const = false;
2791 relocation = sec_addr (plt) + h->plt.offset;
2794 unresolved_reloc = resolved_dynly;
2796 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2798 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2800 BFD_ASSERT (!resolved_local || defined_local);
2802 if (rel + 1 != relend)
2803 trans_r_type = loongarch_tls_transition (input_bfd, info, h,
2805 if (trans_r_type != r_type)
2807 howto = loongarch_elf_rtype_to_howto (input_bfd, trans_r_type);
2808 BFD_ASSERT (howto != NULL);
2810 if (loongarch_tls_perform_trans (input_bfd, input_section,
2811 rel, r_type, h, info))
2812 r_type = trans_r_type;
2819 case R_LARCH_MARK_PCREL:
2820 case R_LARCH_MARK_LA:
2822 r = bfd_reloc_continue;
2823 unresolved_reloc = false;
2828 if (resolved_dynly || (is_pic && resolved_local))
2830 Elf_Internal_Rela outrel;
2832 /* When generating a shared object, these relocations are copied
2833 into the output file to be resolved at run time. */
2835 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2839 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2840 && (input_section->flags & SEC_ALLOC));
2842 outrel.r_offset += sec_addr (input_section);
2844 /* A pointer point to a ifunc symbol. */
2845 if (h && h->type == STT_GNU_IFUNC)
2847 if (h->dynindx == -1)
2849 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2850 outrel.r_addend = (h->root.u.def.value
2851 + h->root.u.def.section->output_section->vma
2852 + h->root.u.def.section->output_offset);
2856 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2857 outrel.r_addend = 0;
2860 if (SYMBOL_REFERENCES_LOCAL (info, h))
2863 if (htab->elf.splt != NULL)
2864 sreloc = htab->elf.srelgot;
2866 sreloc = htab->elf.irelplt;
2871 if (bfd_link_pic (info))
2872 sreloc = htab->elf.irelifunc;
2873 else if (htab->elf.splt != NULL)
2874 sreloc = htab->elf.srelgot;
2876 sreloc = htab->elf.irelplt;
2879 else if (resolved_dynly)
2881 if (h->dynindx == -1)
2883 if (h->root.type == bfd_link_hash_undefined)
2884 (*info->callbacks->undefined_symbol)
2885 (info, name, input_bfd, input_section,
2886 rel->r_offset, true);
2888 outrel.r_info = ELFNN_R_INFO (0, r_type);
2891 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2893 outrel.r_addend = rel->r_addend;
2897 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2898 outrel.r_addend = relocation + rel->r_addend;
2901 /* No alloc space of func allocate_dynrelocs. */
2902 if (unresolved_reloc
2903 && !(h && (h->is_weakalias || !h->dyn_relocs)))
2904 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2907 relocation += rel->r_addend;
2917 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2918 contents + rel->r_offset);
2919 relocation = old_value + relocation + rel->r_addend;
2930 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2931 contents + rel->r_offset);
2932 relocation = old_value - relocation - rel->r_addend;
2936 case R_LARCH_ADD_ULEB128:
2937 case R_LARCH_SUB_ULEB128:
2939 /* Get the value and length of the uleb128 data. */
2940 unsigned int len = 0;
2941 bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2942 contents + rel->r_offset, &len);
2944 if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2945 relocation = old_value + relocation + rel->r_addend;
2946 else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2947 relocation = old_value - relocation - rel->r_addend;
2949 bfd_vma mask = (1 << (7 * len)) - 1;
2954 case R_LARCH_TLS_DTPREL32:
2955 case R_LARCH_TLS_DTPREL64:
2958 Elf_Internal_Rela outrel;
2960 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2963 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2964 && (input_section->flags & SEC_ALLOC));
2965 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2966 outrel.r_offset += sec_addr (input_section);
2967 outrel.r_addend = rel->r_addend;
2968 if (unresolved_reloc)
2969 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2973 if (resolved_to_const)
2974 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2976 bfd_reloc_notsupported,
2981 if (!elf_hash_table (info)->tls_sec)
2983 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2984 input_section, rel, howto, bfd_reloc_notsupported,
2985 is_undefweak, name, "TLS section not be created");
2988 relocation -= elf_hash_table (info)->tls_sec->vma;
2992 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2993 input_section, rel, howto, bfd_reloc_undefined,
2995 "TLS LE just can be resolved local only.");
3000 case R_LARCH_SOP_PUSH_TLS_TPREL:
3003 if (!elf_hash_table (info)->tls_sec)
3004 fatal = (loongarch_reloc_is_fatal
3005 (info, input_bfd, input_section, rel, howto,
3006 bfd_reloc_notsupported, is_undefweak, name,
3007 "TLS section not be created"));
3009 relocation -= elf_hash_table (info)->tls_sec->vma;
3012 fatal = (loongarch_reloc_is_fatal
3013 (info, input_bfd, input_section, rel, howto,
3014 bfd_reloc_undefined, is_undefweak, name,
3015 "TLS LE just can be resolved local only."));
3018 case R_LARCH_SOP_PUSH_ABSOLUTE:
3022 fatal = (loongarch_reloc_is_fatal
3023 (info, input_bfd, input_section, rel, howto,
3024 bfd_reloc_dangerous, is_undefweak, name,
3025 "Someone require us to resolve undefweak "
3026 "symbol dynamically. \n"
3027 "But this reloc can't be done. "
3028 "I think I can't throw error "
3030 "so I resolved it to 0. "
3031 "I suggest to re-compile with '-fpic'."));
3034 unresolved_reloc = false;
3038 if (resolved_to_const)
3040 relocation += rel->r_addend;
3046 fatal = (loongarch_reloc_is_fatal
3047 (info, input_bfd, input_section, rel, howto,
3048 bfd_reloc_notsupported, is_undefweak, name,
3049 "Under PIC we don't know load address. Re-compile "
3056 if (!(plt && h && h->plt.offset != MINUS_ONE))
3058 fatal = (loongarch_reloc_is_fatal
3059 (info, input_bfd, input_section, rel, howto,
3060 bfd_reloc_undefined, is_undefweak, name,
3061 "Can't be resolved dynamically. Try to re-compile "
3066 if (rel->r_addend != 0)
3068 fatal = (loongarch_reloc_is_fatal
3069 (info, input_bfd, input_section, rel, howto,
3070 bfd_reloc_notsupported, is_undefweak, name,
3071 "Shouldn't be with r_addend."));
3075 relocation = sec_addr (plt) + h->plt.offset;
3076 unresolved_reloc = false;
3082 relocation += rel->r_addend;
3088 case R_LARCH_SOP_PUSH_PCREL:
3089 case R_LARCH_SOP_PUSH_PLT_PCREL:
3090 unresolved_reloc = false;
3098 if (h && h->plt.offset != MINUS_ONE)
3101 fatal = (loongarch_reloc_is_fatal
3102 (info, input_bfd, input_section, rel, howto,
3103 bfd_reloc_dangerous, is_undefweak, name,
3104 "Undefweak need to be resolved dynamically, "
3105 "but PLT stub doesn't represent."));
3110 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
3112 fatal = (loongarch_reloc_is_fatal
3113 (info, input_bfd, input_section, rel, howto,
3114 bfd_reloc_undefined, is_undefweak, name,
3115 "PLT stub does not represent and "
3116 "symbol not defined."));
3122 else /* if (resolved_dynly) */
3124 if (!(h && h->plt.offset != MINUS_ONE))
3125 fatal = (loongarch_reloc_is_fatal
3126 (info, input_bfd, input_section, rel, howto,
3127 bfd_reloc_dangerous, is_undefweak, name,
3128 "Internal: PLT stub doesn't represent. "
3129 "Resolve it with pcrel"));
3136 if ((i & 1) == 0 && defined_local)
3139 relocation += rel->r_addend;
3143 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
3145 if (rel->r_addend != 0)
3147 fatal = (loongarch_reloc_is_fatal
3148 (info, input_bfd, input_section, rel, howto,
3149 bfd_reloc_notsupported, is_undefweak, name,
3150 "PLT shouldn't be with r_addend."));
3153 relocation = sec_addr (plt) + h->plt.offset - pc;
3159 case R_LARCH_SOP_PUSH_GPREL:
3160 unresolved_reloc = false;
3162 if (rel->r_addend != 0)
3164 fatal = (loongarch_reloc_is_fatal
3165 (info, input_bfd, input_section, rel, howto,
3166 bfd_reloc_notsupported, is_undefweak, name,
3167 "Shouldn't be with r_addend."));
3173 off = h->got.offset & (~1);
3175 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
3177 fatal = (loongarch_reloc_is_fatal
3178 (info, input_bfd, input_section, rel, howto,
3179 bfd_reloc_notsupported, is_undefweak, name,
3180 "Internal: GOT entry doesn't represent."));
3184 /* Hidden symbol not has .got entry, only .got.plt entry
3185 so gprel is (plt - got). */
3186 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3188 if (h->plt.offset == (bfd_vma) -1)
3193 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3194 off = plt_index * GOT_ENTRY_SIZE;
3196 if (htab->elf.splt != NULL)
3198 /* Section .plt header is 2 times of plt entry. */
3199 off = sec_addr (htab->elf.sgotplt) + off
3200 - sec_addr (htab->elf.sgot);
3204 /* Section iplt not has plt header. */
3205 off = sec_addr (htab->elf.igotplt) + off
3206 - sec_addr (htab->elf.sgot);
3210 if ((h->got.offset & 1) == 0)
3212 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3213 bfd_link_pic (info), h)
3214 && ((bfd_link_pic (info)
3215 && SYMBOL_REFERENCES_LOCAL (info, h))))
3217 /* This is actually a static link, or it is a
3218 -Bsymbolic link and the symbol is defined
3219 locally, or the symbol was forced to be local
3220 because of a version file. We must initialize
3221 this entry in the global offset table. Since the
3222 offset must always be a multiple of the word size,
3223 we use the least significant bit to record whether
3224 we have initialized it already.
3226 When doing a dynamic link, we create a rela.got
3227 relocation entry to initialize the value. This
3228 is done in the finish_dynamic_symbol routine. */
3232 fatal = (loongarch_reloc_is_fatal
3233 (info, input_bfd, input_section, rel, howto,
3234 bfd_reloc_dangerous, is_undefweak, name,
3235 "Internal: here shouldn't dynamic."));
3238 if (!(defined_local || resolved_to_const))
3240 fatal = (loongarch_reloc_is_fatal
3241 (info, input_bfd, input_section, rel, howto,
3242 bfd_reloc_undefined, is_undefweak, name,
3248 Elf_Internal_Rela outrel;
3249 /* We need to generate a R_LARCH_RELATIVE reloc
3250 for the dynamic linker. */
3251 s = htab->elf.srelgot;
3254 fatal = loongarch_reloc_is_fatal
3256 input_section, rel, howto,
3257 bfd_reloc_notsupported, is_undefweak, name,
3258 "Internal: '.rel.got' not represent");
3262 outrel.r_offset = sec_addr (got) + off;
3263 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3264 outrel.r_addend = relocation; /* Link-time addr. */
3265 loongarch_elf_append_rela (output_bfd, s, &outrel);
3267 bfd_put_NN (output_bfd, relocation, got->contents + off);
3273 if (!local_got_offsets)
3275 fatal = (loongarch_reloc_is_fatal
3276 (info, input_bfd, input_section, rel, howto,
3277 bfd_reloc_notsupported, is_undefweak, name,
3278 "Internal: local got offsets not reporesent."));
3282 off = local_got_offsets[r_symndx] & (~1);
3284 if (local_got_offsets[r_symndx] == MINUS_ONE)
3286 fatal = (loongarch_reloc_is_fatal
3287 (info, input_bfd, input_section, rel, howto,
3288 bfd_reloc_notsupported, is_undefweak, name,
3289 "Internal: GOT entry doesn't represent."));
3293 /* The offset must always be a multiple of the word size.
3294 So, we can use the least significant bit to record
3295 whether we have already processed this entry. */
3296 if ((local_got_offsets[r_symndx] & 1) == 0)
3301 Elf_Internal_Rela outrel;
3302 /* We need to generate a R_LARCH_RELATIVE reloc
3303 for the dynamic linker. */
3304 s = htab->elf.srelgot;
3307 fatal = (loongarch_reloc_is_fatal
3308 (info, input_bfd, input_section, rel, howto,
3309 bfd_reloc_notsupported, is_undefweak, name,
3310 "Internal: '.rel.got' not represent"));
3314 outrel.r_offset = sec_addr (got) + off;
3315 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3316 outrel.r_addend = relocation; /* Link-time addr. */
3317 loongarch_elf_append_rela (output_bfd, s, &outrel);
3320 bfd_put_NN (output_bfd, relocation, got->contents + off);
3321 local_got_offsets[r_symndx] |= 1;
3328 case R_LARCH_SOP_PUSH_TLS_GOT:
3329 case R_LARCH_SOP_PUSH_TLS_GD:
3331 unresolved_reloc = false;
3332 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3335 bfd_vma got_off = 0;
3338 got_off = h->got.offset;
3343 got_off = local_got_offsets[r_symndx];
3344 local_got_offsets[r_symndx] |= 1;
3347 BFD_ASSERT (got_off != MINUS_ONE);
3350 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3351 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3352 ie_off = 2 * GOT_ENTRY_SIZE;
3354 if ((got_off & 1) == 0)
3356 Elf_Internal_Rela rela;
3357 asection *srel = htab->elf.srelgot;
3358 bfd_vma tls_block_off = 0;
3360 if (SYMBOL_REFERENCES_LOCAL (info, h))
3362 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3363 tls_block_off = relocation
3364 - elf_hash_table (info)->tls_sec->vma;
3367 if (tls_type & GOT_TLS_GD)
3369 rela.r_offset = sec_addr (got) + got_off;
3371 if (SYMBOL_REFERENCES_LOCAL (info, h))
3373 /* Local sym, used in exec, set module id 1. */
3374 if (bfd_link_executable (info))
3375 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3378 rela.r_info = ELFNN_R_INFO (0,
3379 R_LARCH_TLS_DTPMODNN);
3380 loongarch_elf_append_rela (output_bfd, srel, &rela);
3383 bfd_put_NN (output_bfd, tls_block_off,
3384 got->contents + got_off + GOT_ENTRY_SIZE);
3386 /* Dynamic resolved. */
3389 /* Dynamic relocate module id. */
3390 rela.r_info = ELFNN_R_INFO (h->dynindx,
3391 R_LARCH_TLS_DTPMODNN);
3392 loongarch_elf_append_rela (output_bfd, srel, &rela);
3394 /* Dynamic relocate offset of block. */
3395 rela.r_offset += GOT_ENTRY_SIZE;
3396 rela.r_info = ELFNN_R_INFO (h->dynindx,
3397 R_LARCH_TLS_DTPRELNN);
3398 loongarch_elf_append_rela (output_bfd, srel, &rela);
3401 if (tls_type & GOT_TLS_IE)
3403 rela.r_offset = sec_addr (got) + got_off + ie_off;
3404 if (SYMBOL_REFERENCES_LOCAL (info, h))
3406 /* Local sym, used in exec, set module id 1. */
3407 if (!bfd_link_executable (info))
3409 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3410 rela.r_addend = tls_block_off;
3411 loongarch_elf_append_rela (output_bfd, srel, &rela);
3414 bfd_put_NN (output_bfd, tls_block_off,
3415 got->contents + got_off + ie_off);
3417 /* Dynamic resolved. */
3420 /* Dynamic relocate offset of block. */
3421 rela.r_info = ELFNN_R_INFO (h->dynindx,
3422 R_LARCH_TLS_TPRELNN);
3424 loongarch_elf_append_rela (output_bfd, srel, &rela);
3429 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3433 /* New reloc types. */
3437 case R_LARCH_CALL36:
3438 unresolved_reloc = false;
3447 relocation += rel->r_addend;
3449 else if (resolved_dynly)
3452 && (h->plt.offset != MINUS_ONE
3453 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3454 && rel->r_addend == 0);
3455 if (h && h->plt.offset == MINUS_ONE
3456 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3459 relocation += rel->r_addend;
3462 relocation = sec_addr (plt) + h->plt.offset - pc;
3467 case R_LARCH_ABS_HI20:
3468 case R_LARCH_ABS_LO12:
3469 case R_LARCH_ABS64_LO20:
3470 case R_LARCH_ABS64_HI12:
3471 BFD_ASSERT (!is_pic);
3475 BFD_ASSERT (resolved_dynly);
3479 else if (resolved_to_const || resolved_local)
3481 relocation += rel->r_addend;
3483 else if (resolved_dynly)
3485 unresolved_reloc = false;
3486 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3487 && rel->r_addend == 0);
3488 relocation = sec_addr (plt) + h->plt.offset;
3493 case R_LARCH_PCREL20_S2:
3494 unresolved_reloc = false;
3495 if (h && h->plt.offset != MINUS_ONE)
3496 relocation = sec_addr (plt) + h->plt.offset;
3498 relocation += rel->r_addend;
3502 case R_LARCH_PCALA_HI20:
3503 unresolved_reloc = false;
3504 if (h && h->plt.offset != MINUS_ONE)
3505 relocation = sec_addr (plt) + h->plt.offset;
3507 relocation += rel->r_addend;
3509 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3512 case R_LARCH_TLS_LE_HI20_R:
3513 relocation += rel->r_addend;
3514 relocation -= elf_hash_table (info)->tls_sec->vma;
3515 RELOCATE_TLS_TP32_HI20 (relocation);
3518 case R_LARCH_PCALA_LO12:
3519 /* Not support if sym_addr in 2k page edge.
3520 pcalau12i pc_hi20 (sym_addr)
3521 ld.w/d pc_lo12 (sym_addr)
3522 ld.w/d pc_lo12 (sym_addr + x)
3524 can not calc correct address
3525 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3527 if (h && h->plt.offset != MINUS_ONE)
3528 relocation = sec_addr (plt) + h->plt.offset;
3530 relocation += rel->r_addend;
3532 /* For 2G jump, generate pcalau12i, jirl. */
3533 /* If use jirl, turns to R_LARCH_B16. */
3534 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3535 if ((insn & 0x4c000000) == 0x4c000000)
3537 relocation &= 0xfff;
3538 /* Signed extend. */
3539 relocation = (relocation ^ 0x800) - 0x800;
3541 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3542 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3546 case R_LARCH_PCALA64_HI12:
3549 case R_LARCH_PCALA64_LO20:
3550 if (h && h->plt.offset != MINUS_ONE)
3551 relocation = sec_addr (plt) + h->plt.offset;
3553 relocation += rel->r_addend;
3555 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3559 case R_LARCH_GOT_PC_HI20:
3560 case R_LARCH_GOT_HI20:
3561 /* Calc got offset. */
3563 unresolved_reloc = false;
3564 BFD_ASSERT (rel->r_addend == 0);
3566 bfd_vma got_off = 0;
3569 /* GOT ref or ifunc. */
3570 BFD_ASSERT (h->got.offset != MINUS_ONE
3571 || h->type == STT_GNU_IFUNC);
3573 got_off = h->got.offset & (~(bfd_vma)1);
3574 /* Hidden symbol not has got entry,
3575 * only got.plt entry so it is (plt - got). */
3576 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3579 if (htab->elf.splt != NULL)
3581 idx = (h->plt.offset - PLT_HEADER_SIZE)
3583 got_off = sec_addr (htab->elf.sgotplt)
3584 + GOTPLT_HEADER_SIZE
3585 + (idx * GOT_ENTRY_SIZE)
3586 - sec_addr (htab->elf.sgot);
3590 idx = h->plt.offset / PLT_ENTRY_SIZE;
3591 got_off = sec_addr (htab->elf.sgotplt)
3592 + (idx * GOT_ENTRY_SIZE)
3593 - sec_addr (htab->elf.sgot);
3597 if ((h->got.offset & 1) == 0)
3599 /* We need to generate a R_LARCH_RELATIVE reloc once
3600 * in loongarch_elf_finish_dynamic_symbol or now,
3601 * call finish_dyn && nopic
3602 * or !call finish_dyn && pic. */
3603 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3604 bfd_link_pic (info),
3606 && bfd_link_pic (info)
3607 && SYMBOL_REFERENCES_LOCAL (info, h))
3609 Elf_Internal_Rela rela;
3610 rela.r_offset = sec_addr (got) + got_off;
3611 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3612 rela.r_addend = relocation;
3613 loongarch_elf_append_rela (output_bfd,
3614 htab->elf.srelgot, &rela);
3617 bfd_put_NN (output_bfd, relocation,
3618 got->contents + got_off);
3623 BFD_ASSERT (local_got_offsets
3624 && local_got_offsets[r_symndx] != MINUS_ONE);
3626 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3627 if ((local_got_offsets[r_symndx] & 1) == 0)
3629 if (bfd_link_pic (info))
3631 Elf_Internal_Rela rela;
3632 rela.r_offset = sec_addr (got) + got_off;
3633 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3634 rela.r_addend = relocation;
3635 loongarch_elf_append_rela (output_bfd,
3636 htab->elf.srelgot, &rela);
3638 local_got_offsets[r_symndx] |= 1;
3640 bfd_put_NN (output_bfd, relocation, got->contents + got_off);
3643 relocation = got_off + sec_addr (got);
3646 if (r_type == R_LARCH_GOT_PC_HI20)
3647 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3651 case R_LARCH_GOT_PC_LO12:
3652 case R_LARCH_GOT64_PC_LO20:
3653 case R_LARCH_GOT64_PC_HI12:
3654 case R_LARCH_GOT_LO12:
3655 case R_LARCH_GOT64_LO20:
3656 case R_LARCH_GOT64_HI12:
3658 unresolved_reloc = false;
3661 got_off = h->got.offset & (~(bfd_vma)1);
3663 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3665 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3668 if (htab->elf.splt != NULL)
3669 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3671 idx = h->plt.offset / PLT_ENTRY_SIZE;
3673 got_off = sec_addr (htab->elf.sgotplt)
3674 + GOTPLT_HEADER_SIZE
3675 + (idx * GOT_ENTRY_SIZE)
3676 - sec_addr (htab->elf.sgot);
3679 relocation = got_off + sec_addr (got);
3682 if (r_type == R_LARCH_GOT64_PC_HI12)
3683 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3684 else if (r_type == R_LARCH_GOT64_PC_LO20)
3685 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3689 case R_LARCH_TLS_LE_HI20:
3690 case R_LARCH_TLS_LE_LO12:
3691 case R_LARCH_TLS_LE_LO12_R:
3692 case R_LARCH_TLS_LE64_LO20:
3693 case R_LARCH_TLS_LE64_HI12:
3694 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3696 relocation += rel->r_addend;
3697 relocation -= elf_hash_table (info)->tls_sec->vma;
3700 /* TLS IE LD/GD process separately is troublesome.
3701 When a symbol is both ie and LD/GD, h->got.off |= 1
3702 make only one type be relocated. We must use
3703 h->got.offset |= 1 and h->got.offset |= 2
3704 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3705 (IE LD/GD and reusable GOT reloc) must change to
3706 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3708 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3710 case R_LARCH_TLS_IE_PC_HI20:
3711 case R_LARCH_TLS_IE_HI20:
3712 case R_LARCH_TLS_LD_PC_HI20:
3713 case R_LARCH_TLS_LD_HI20:
3714 case R_LARCH_TLS_GD_PC_HI20:
3715 case R_LARCH_TLS_GD_HI20:
3716 case R_LARCH_TLS_DESC_PC_HI20:
3717 case R_LARCH_TLS_DESC_HI20:
3718 case R_LARCH_TLS_LD_PCREL20_S2:
3719 case R_LARCH_TLS_GD_PCREL20_S2:
3720 case R_LARCH_TLS_DESC_PCREL20_S2:
3721 BFD_ASSERT (rel->r_addend == 0);
3722 unresolved_reloc = false;
3724 if (r_type == R_LARCH_TLS_IE_PC_HI20
3725 || r_type == R_LARCH_TLS_IE_HI20)
3728 if (r_type == R_LARCH_TLS_DESC_PC_HI20
3729 || r_type == R_LARCH_TLS_DESC_HI20
3730 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3733 bfd_vma got_off = 0;
3736 got_off = h->got.offset;
3741 got_off = local_got_offsets[r_symndx];
3742 local_got_offsets[r_symndx] |= 1;
3745 BFD_ASSERT (got_off != MINUS_ONE);
3747 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3749 /* If a tls variable is accessed in multiple ways, GD uses
3750 the first two slots of GOT, desc follows with two slots,
3751 and IE uses one slot at the end. */
3753 if (GOT_TLS_GD_BOTH_P (tls_type))
3754 desc_off = 2 * GOT_ENTRY_SIZE;
3757 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3758 ie_off = 4 * GOT_ENTRY_SIZE;
3759 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3760 ie_off = 2 * GOT_ENTRY_SIZE;
3762 if ((got_off & 1) == 0)
3764 Elf_Internal_Rela rela;
3765 asection *relgot = htab->elf.srelgot;
3766 bfd_vma tls_block_off = 0;
3768 if (SYMBOL_REFERENCES_LOCAL (info, h))
3770 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3771 tls_block_off = relocation
3772 - elf_hash_table (info)->tls_sec->vma;
3775 if (tls_type & GOT_TLS_GD)
3777 rela.r_offset = sec_addr (got) + got_off;
3779 if (SYMBOL_REFERENCES_LOCAL (info, h))
3781 /* Local sym, used in exec, set module id 1. */
3782 if (bfd_link_executable (info))
3783 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3786 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3787 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3790 bfd_put_NN (output_bfd, tls_block_off,
3791 got->contents + got_off + GOT_ENTRY_SIZE);
3793 /* Dynamic resolved. */
3796 /* Dynamic relocate module id. */
3797 rela.r_info = ELFNN_R_INFO (h->dynindx,
3798 R_LARCH_TLS_DTPMODNN);
3799 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3801 /* Dynamic relocate offset of block. */
3802 rela.r_offset += GOT_ENTRY_SIZE;
3803 rela.r_info = ELFNN_R_INFO (h->dynindx,
3804 R_LARCH_TLS_DTPRELNN);
3805 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3808 if (tls_type & GOT_TLS_GDESC)
3810 /* Unless it is a static link, DESC always emits a
3811 dynamic relocation. */
3812 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
3813 rela.r_offset = sec_addr (got) + got_off + desc_off;
3816 rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
3818 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
3819 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3820 bfd_put_NN (output_bfd, 0,
3821 got->contents + got_off + desc_off);
3823 if (tls_type & GOT_TLS_IE)
3825 rela.r_offset = sec_addr (got) + got_off + ie_off;
3826 if (SYMBOL_REFERENCES_LOCAL (info, h))
3828 /* Local sym, used in exec, set module id 1. */
3829 if (!bfd_link_executable (info))
3831 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3832 rela.r_addend = tls_block_off;
3833 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3836 bfd_put_NN (output_bfd, tls_block_off,
3837 got->contents + got_off + ie_off);
3839 /* Dynamic resolved. */
3842 /* Dynamic relocate offset of block. */
3843 rela.r_info = ELFNN_R_INFO (h->dynindx,
3844 R_LARCH_TLS_TPRELNN);
3846 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3850 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
3852 relocation += desc_off;
3854 relocation += ie_off;
3856 if (r_type == R_LARCH_TLS_LD_PC_HI20
3857 || r_type == R_LARCH_TLS_GD_PC_HI20
3858 || r_type == R_LARCH_TLS_IE_PC_HI20
3859 || r_type == R_LARCH_TLS_DESC_PC_HI20)
3860 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3861 else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
3862 || r_type == R_LARCH_TLS_GD_PCREL20_S2
3863 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3865 /* else {} ABS relocations. */
3868 case R_LARCH_TLS_DESC_PC_LO12:
3869 case R_LARCH_TLS_DESC64_PC_LO20:
3870 case R_LARCH_TLS_DESC64_PC_HI12:
3871 case R_LARCH_TLS_DESC_LO12:
3872 case R_LARCH_TLS_DESC64_LO20:
3873 case R_LARCH_TLS_DESC64_HI12:
3875 unresolved_reloc = false;
3878 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3880 relocation = sec_addr (got)
3881 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3883 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3884 /* Use both TLS_GD and TLS_DESC. */
3885 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
3886 relocation += 2 * GOT_ENTRY_SIZE;
3888 if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
3889 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3890 else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
3891 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3896 case R_LARCH_TLS_DESC_LD:
3897 case R_LARCH_TLS_DESC_CALL:
3898 unresolved_reloc = false;
3901 case R_LARCH_TLS_IE_PC_LO12:
3902 case R_LARCH_TLS_IE64_PC_LO20:
3903 case R_LARCH_TLS_IE64_PC_HI12:
3904 case R_LARCH_TLS_IE_LO12:
3905 case R_LARCH_TLS_IE64_LO20:
3906 case R_LARCH_TLS_IE64_HI12:
3907 unresolved_reloc = false;
3910 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3912 relocation = sec_addr (got)
3913 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3915 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3916 /* Use TLS_GD TLS_DESC and TLS_IE. */
3917 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3918 relocation += 4 * GOT_ENTRY_SIZE;
3919 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
3920 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3921 relocation += 2 * GOT_ENTRY_SIZE;
3923 if (r_type == R_LARCH_TLS_IE64_PC_LO20)
3924 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3925 else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
3926 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3932 r = bfd_reloc_continue;
3933 unresolved_reloc = false;
3945 /* 'unresolved_reloc' means we haven't done it yet.
3946 We need help of dynamic linker to fix this memory location up. */
3947 if (!unresolved_reloc)
3950 if (_bfd_elf_section_offset (output_bfd, info, input_section,
3951 rel->r_offset) == MINUS_ONE)
3952 /* WHY? May because it's invalid so skip checking.
3953 But why dynamic reloc a invalid section? */
3956 if (input_section->output_section->flags & SEC_DEBUGGING)
3958 fatal = (loongarch_reloc_is_fatal
3959 (info, input_bfd, input_section, rel, howto,
3960 bfd_reloc_dangerous, is_undefweak, name,
3961 "Seems dynamic linker not process "
3962 "sections 'SEC_DEBUGGING'."));
3967 if ((info->flags & DF_TEXTREL) == 0)
3968 if (input_section->output_section->flags & SEC_READONLY)
3969 info->flags |= DF_TEXTREL;
3976 loongarch_record_one_reloc (input_bfd, input_section, r_type,
3977 rel->r_offset, sym, h, rel->r_addend);
3979 if (r != bfd_reloc_continue)
3980 r = perform_relocation (rel, input_section, howto, relocation,
3981 input_bfd, contents);
3985 case bfd_reloc_dangerous:
3986 case bfd_reloc_continue:
3990 case bfd_reloc_overflow:
3991 /* Overflow value can't be filled in. */
3992 loongarch_dump_reloc_record (info->callbacks->info);
3993 info->callbacks->reloc_overflow
3994 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3995 input_bfd, input_section, rel->r_offset);
3998 case bfd_reloc_outofrange:
3999 /* Stack state incorrect. */
4000 loongarch_dump_reloc_record (info->callbacks->info);
4001 info->callbacks->info
4002 ("%X%H: Internal stack state is incorrect.\n"
4003 "Want to push to full stack or pop from empty stack?\n",
4004 input_bfd, input_section, rel->r_offset);
4007 case bfd_reloc_notsupported:
4008 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
4009 input_section, rel->r_offset);
4013 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
4014 input_section, rel->r_offset);
4025 loongarch_relax_delete_bytes (bfd *abfd,
4029 struct bfd_link_info *link_info)
4031 unsigned int i, symcount;
4032 bfd_vma toaddr = sec->size;
4033 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
4034 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4035 unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
4036 struct bfd_elf_section_data *data = elf_section_data (sec);
4037 bfd_byte *contents = data->this_hdr.contents;
4039 /* Actually delete the bytes. */
4041 memmove (contents + addr, contents + addr + count, toaddr - addr - count);
4043 /* Adjust the location of all of the relocs. Note that we need not
4044 adjust the addends, since all PC-relative references must be against
4045 symbols, which we will adjust below. */
4046 for (i = 0; i < sec->reloc_count; i++)
4047 if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
4048 data->relocs[i].r_offset -= count;
4050 /* Adjust the local symbols defined in this section. */
4051 for (i = 0; i < symtab_hdr->sh_info; i++)
4053 Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
4054 if (sym->st_shndx == sec_shndx)
4056 /* If the symbol is in the range of memory we just moved, we
4057 have to adjust its value. */
4058 if (sym->st_value > addr && sym->st_value <= toaddr)
4059 sym->st_value -= count;
4061 /* If the symbol *spans* the bytes we just deleted (i.e. its
4062 *end* is in the moved bytes but its *start* isn't), then we
4063 must adjust its size.
4065 This test needs to use the original value of st_value, otherwise
4066 we might accidentally decrease size when deleting bytes right
4067 before the symbol. But since deleted relocs can't span across
4068 symbols, we can't have both a st_value and a st_size decrease,
4069 so it is simpler to just use an else. */
4070 else if (sym->st_value <= addr
4071 && sym->st_value + sym->st_size > addr
4072 && sym->st_value + sym->st_size <= toaddr)
4073 sym->st_size -= count;
4077 /* Now adjust the global symbols defined in this section. */
4078 symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
4079 - symtab_hdr->sh_info);
4081 for (i = 0; i < symcount; i++)
4083 struct elf_link_hash_entry *sym_hash = sym_hashes[i];
4085 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4086 containing the definition of __wrap_SYMBOL, includes a direct
4087 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4088 the same symbol (which is __wrap_SYMBOL), but still exist as two
4089 different symbols in 'sym_hashes', we don't want to adjust
4090 the global symbol __wrap_SYMBOL twice.
4092 The same problem occurs with symbols that are versioned_hidden, as
4093 foo becomes an alias for foo@BAR, and hence they need the same
4095 if (link_info->wrap_hash != NULL
4096 || sym_hash->versioned != unversioned)
4098 struct elf_link_hash_entry **cur_sym_hashes;
4100 /* Loop only over the symbols which have already been checked. */
4101 for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
4104 /* If the current symbol is identical to 'sym_hash', that means
4105 the symbol was already adjusted (or at least checked). */
4106 if (*cur_sym_hashes == sym_hash)
4109 /* Don't adjust the symbol again. */
4110 if (cur_sym_hashes < &sym_hashes[i])
4114 if ((sym_hash->root.type == bfd_link_hash_defined
4115 || sym_hash->root.type == bfd_link_hash_defweak)
4116 && sym_hash->root.u.def.section == sec)
4118 /* As above, adjust the value if needed. */
4119 if (sym_hash->root.u.def.value > addr
4120 && sym_hash->root.u.def.value <= toaddr)
4121 sym_hash->root.u.def.value -= count;
4123 /* As above, adjust the size if needed. */
4124 else if (sym_hash->root.u.def.value <= addr
4125 && sym_hash->root.u.def.value + sym_hash->size > addr
4126 && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
4127 sym_hash->size -= count;
4133 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4134 there are three situations in which an assembly instruction sequence needs to
4136 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4139 in this case, the rd register in the st.{w/d} instruction does not store the
4140 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4141 symbolic address, and then obtains the rd + le_lo12_r address through the
4142 st.w instruction feature.
4143 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4145 before relax: after relax:
4147 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4148 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4149 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4152 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4154 before relax: after relax:
4156 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4157 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4158 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4161 in this case,the rs register in addi.{w/d} stores the full address of the tls
4162 symbol (tp + le_hi20_r + le_lo12_r).
4164 before relax: after relax:
4166 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4167 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4168 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4171 loongarch_relax_tls_le (bfd *abfd, asection *sec,
4172 Elf_Internal_Rela *rel,
4173 struct bfd_link_info *link_info,
4176 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4177 uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
4178 static uint32_t insn_rj,insn_rd;
4179 symval = symval - elf_hash_table (link_info)->tls_sec->vma;
4180 /* Whether the symbol offset is in the interval (offset < 0x800). */
4181 if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
4183 switch (ELFNN_R_TYPE (rel->r_info))
4185 case R_LARCH_TLS_LE_HI20_R:
4186 case R_LARCH_TLS_LE_ADD_R:
4188 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4189 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
4191 case R_LARCH_TLS_LE_LO12_R:
4192 /* Change rj to $tp. */
4194 /* Get rd register. */
4195 insn_rd = insn & 0x1f;
4196 /* Write symbol offset. */
4198 /* Writes the modified instruction. */
4199 insn = insn & 0xffc00000;
4200 insn = insn | symval | insn_rj | insn_rd;
4201 bfd_put (32, abfd, insn, contents + rel->r_offset);
4210 /* Relax pcalau12i,addi.d => pcaddi. */
4212 loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
4213 Elf_Internal_Rela *rel_hi, bfd_vma symval,
4214 struct bfd_link_info *info, bool *again,
4215 bfd_vma max_alignment)
4217 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4218 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4219 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4220 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4221 uint32_t rd = pca & 0x1f;
4223 /* This section's output_offset need to subtract the bytes of instructions
4224 relaxed by the previous sections, so it needs to be updated beforehand.
4225 size_input_section already took care of updating it after relaxation,
4226 so we additionally update once here. */
4227 sec->output_offset = sec->output_section->size;
4228 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4230 /* If pc and symbol not in the same segment, add/sub segment alignment.
4231 FIXME: if there are multiple readonly segments? How to determine if
4232 two sections are in the same segment. */
4233 if (!(sym_sec->flags & SEC_READONLY))
4235 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4238 pc -= max_alignment;
4239 else if (symval < pc)
4240 pc += max_alignment;
4244 pc -= max_alignment;
4245 else if (symval < pc)
4246 pc += max_alignment;
4248 const uint32_t addi_d = 0x02c00000;
4249 const uint32_t pcaddi = 0x18000000;
4251 /* Is pcalau12i + addi.d insns? */
4252 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
4253 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4254 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4255 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4256 || ((add & addi_d) != addi_d)
4257 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4258 || ((add & 0x1f) != rd)
4259 || (((add >> 5) & 0x1f) != rd)
4260 /* Can be relaxed to pcaddi? */
4261 || (symval & 0x3) /* 4 bytes align. */
4262 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4263 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4266 /* Continue next relax trip. */
4270 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4272 /* Adjust relocations. */
4273 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4274 R_LARCH_PCREL20_S2);
4275 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4277 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4282 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
4284 loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
4285 Elf_Internal_Rela *rel_hi)
4287 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4288 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4289 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4290 uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
4291 uint32_t rd = pca & 0x1f;
4292 const uint32_t ld_d = 0x28c00000;
4293 uint32_t addi_d = 0x02c00000;
4295 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
4296 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4297 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4298 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4299 || ((ld & 0x1f) != rd)
4300 || (((ld >> 5) & 0x1f) != rd)
4301 || ((ld & ld_d) != ld_d))
4304 addi_d = addi_d | (rd << 5) | rd;
4305 bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
4307 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4308 R_LARCH_PCALA_HI20);
4309 rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
4310 R_LARCH_PCALA_LO12);
4314 /* Called by after_allocation to set the information of data segment
4318 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
4319 int *data_segment_phase)
4321 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4322 htab->data_segment_phase = data_segment_phase;
4325 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4326 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
4328 loongarch_relax_align (bfd *abfd, asection *sec,
4330 struct bfd_link_info *link_info,
4331 Elf_Internal_Rela *rel,
4334 bfd_vma addend, max = 0, alignment = 1;
4336 int sym_index = ELFNN_R_SYM (rel->r_info);
4339 alignment = 1 << (rel->r_addend & 0xff);
4340 max = rel->r_addend >> 8;
4343 alignment = rel->r_addend + 4;
4345 addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
4346 symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */
4347 bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
4348 bfd_vma need_nop_bytes = aligned_addr - symval; /* */
4350 /* Make sure there are enough NOPs to actually achieve the alignment. */
4351 if (addend < need_nop_bytes)
4354 (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
4355 "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
4356 abfd, sym_sec, (uint64_t) rel->r_offset,
4357 (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
4358 bfd_set_error (bfd_error_bad_value);
4362 /* Once we've handled an R_LARCH_ALIGN in a section,
4363 we can't relax anything else in this section. */
4364 sec->sec_flg0 = true;
4365 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4367 /* If skipping more bytes than the specified maximum,
4368 then the alignment is not done at all and delete all NOPs. */
4369 if (max > 0 && need_nop_bytes > max)
4370 return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
4373 /* If the number of NOPs is already correct, there's nothing to do. */
4374 if (need_nop_bytes == addend)
4377 /* Delete the excess NOPs. */
4378 return loongarch_relax_delete_bytes (abfd, sec,
4379 rel->r_offset + need_nop_bytes,
4380 addend - need_nop_bytes, link_info);
4383 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
4385 loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
4386 Elf_Internal_Rela *rel_hi, bfd_vma symval,
4387 struct bfd_link_info *info, bool *again,
4388 bfd_vma max_alignment)
4390 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4391 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4392 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4393 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4394 uint32_t rd = pca & 0x1f;
4396 /* This section's output_offset need to subtract the bytes of instructions
4397 relaxed by the previous sections, so it needs to be updated beforehand.
4398 size_input_section already took care of updating it after relaxation,
4399 so we additionally update once here. */
4400 sec->output_offset = sec->output_section->size;
4401 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4403 /* If pc and symbol not in the same segment, add/sub segment alignment.
4404 FIXME: if there are multiple readonly segments? */
4405 if (!(sym_sec->flags & SEC_READONLY))
4407 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4410 pc -= max_alignment;
4411 else if (symval < pc)
4412 pc += max_alignment;
4416 pc -= max_alignment;
4417 else if (symval < pc)
4418 pc += max_alignment;
4420 const uint32_t addi_d = 0x02c00000;
4421 const uint32_t pcaddi = 0x18000000;
4423 /* Is pcalau12i + addi.d insns? */
4424 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
4425 && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
4426 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4427 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4428 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4429 || ((add & addi_d) != addi_d)
4430 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4431 || ((add & 0x1f) != rd)
4432 || (((add >> 5) & 0x1f) != rd)
4433 /* Can be relaxed to pcaddi? */
4434 || (symval & 0x3) /* 4 bytes align. */
4435 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4436 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4439 /* Continue next relax trip. */
4443 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4445 /* Adjust relocations. */
4446 switch (ELFNN_R_TYPE (rel_hi->r_info))
4448 case R_LARCH_TLS_LD_PC_HI20:
4449 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4450 R_LARCH_TLS_LD_PCREL20_S2);
4452 case R_LARCH_TLS_GD_PC_HI20:
4453 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4454 R_LARCH_TLS_GD_PCREL20_S2);
4456 case R_LARCH_TLS_DESC_PC_HI20:
4457 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4458 R_LARCH_TLS_DESC_PCREL20_S2);
4463 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4465 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4470 /* Traverse all output sections and return the max alignment. */
4473 loongarch_get_max_alignment (asection *sec)
4476 unsigned int max_alignment_power = 0;
4478 for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
4479 if (o->alignment_power > max_alignment_power)
4480 max_alignment_power = o->alignment_power;
4482 return (bfd_vma) 1 << max_alignment_power;
4486 loongarch_elf_relax_section (bfd *abfd, asection *sec,
4487 struct bfd_link_info *info,
4490 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4491 struct bfd_elf_section_data *data = elf_section_data (sec);
4492 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
4493 Elf_Internal_Rela *relocs;
4495 bfd_vma max_alignment = 0;
4497 if (bfd_link_relocatable (info)
4499 || (sec->flags & SEC_RELOC) == 0
4500 || sec->reloc_count == 0
4501 || (info->disable_target_specific_optimizations
4502 && info->relax_pass == 0)
4503 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4504 and defined in ld/ldexp.h. */
4505 || *(htab->data_segment_phase) == 4)
4509 relocs = data->relocs;
4510 else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
4511 info->keep_memory)))
4514 if (!data->this_hdr.contents
4515 && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
4518 if (symtab_hdr->sh_info != 0
4519 && !symtab_hdr->contents
4520 && !(symtab_hdr->contents =
4521 (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
4522 symtab_hdr->sh_info,
4523 0, NULL, NULL, NULL)))
4526 data->relocs = relocs;
4528 /* Estimate the maximum alignment for all output sections once time
4529 should be enough. */
4530 max_alignment = htab->max_alignment;
4531 if (max_alignment == (bfd_vma) -1)
4533 max_alignment = loongarch_get_max_alignment (sec);
4534 htab->max_alignment = max_alignment;
4537 for (unsigned int i = 0; i < sec->reloc_count; i++)
4542 bool local_got = false;
4543 Elf_Internal_Rela *rel = relocs + i;
4544 struct elf_link_hash_entry *h = NULL;
4545 unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
4546 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
4548 /* Four kind of relocations:
4549 Normal: symval is the symbol address.
4550 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4551 added by this relocation, and then adds 4 more.
4552 R_LARCH_CALL36: symval is the symbol address for local symbols,
4553 or the PLT entry address of the symbol. (Todo)
4554 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4556 if (r_symndx < symtab_hdr->sh_info)
4558 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
4560 if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4563 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4564 || R_LARCH_TLS_GD_PC_HI20 == r_type
4565 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4567 if (i + 1 != sec->reloc_count
4568 && loongarch_can_trans_tls (abfd, info, h, rel, r_type))
4572 sym_sec = htab->elf.sgot;
4573 symval = elf_local_got_offsets (abfd)[r_symndx];
4574 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4576 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4577 && GOT_TLS_GD_BOTH_P (tls_type))
4578 symval += 2 * GOT_ENTRY_SIZE;
4581 else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
4584 symval = rel->r_offset;
4588 sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
4589 symval = sym->st_value;
4591 symtype = ELF_ST_TYPE (sym->st_info);
4595 r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
4596 h = elf_sym_hashes (abfd)[r_symndx];
4598 while (h->root.type == bfd_link_hash_indirect
4599 || h->root.type == bfd_link_hash_warning)
4600 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4602 /* Disable the relaxation for ifunc. */
4603 if (h != NULL && h->type == STT_GNU_IFUNC)
4606 /* The GOT entry of tls symbols must in current execute file or
4608 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4609 || R_LARCH_TLS_GD_PC_HI20 == r_type
4610 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4612 if (i + 1 != sec->reloc_count
4613 && loongarch_can_trans_tls (abfd, info, h, rel, r_type))
4617 sym_sec = htab->elf.sgot;
4618 symval = h->got.offset;
4619 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4621 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4622 && GOT_TLS_GD_BOTH_P (tls_type))
4623 symval += 2 * GOT_ENTRY_SIZE;
4626 else if ((h->root.type == bfd_link_hash_defined
4627 || h->root.type == bfd_link_hash_defweak)
4628 && h->root.u.def.section != NULL
4629 && h->root.u.def.section->output_section != NULL)
4631 symval = h->root.u.def.value;
4632 sym_sec = h->root.u.def.section;
4637 if (h && SYMBOL_REFERENCES_LOCAL (info, h))
4642 if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
4643 && (sym_sec->flags & SEC_MERGE))
4645 if (symtype == STT_SECTION)
4646 symval += rel->r_addend;
4648 symval = _bfd_merged_section_offset (abfd, &sym_sec,
4649 elf_section_data (sym_sec)->sec_info,
4652 if (symtype != STT_SECTION)
4653 symval += rel->r_addend;
4655 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
4657 If r_symndx is 0, alignmeng-4 is r_addend.
4658 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
4659 else if (R_LARCH_ALIGN == r_type)
4661 symval += ((1 << (rel->r_addend & 0xff)) - 4);
4663 symval += rel->r_addend;
4665 symval += rel->r_addend;
4667 symval += sec_addr (sym_sec);
4672 if (1 == info->relax_pass)
4673 loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
4676 case R_LARCH_DELETE:
4677 if (1 == info->relax_pass)
4679 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4680 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4684 case R_LARCH_TLS_LE_HI20_R:
4685 case R_LARCH_TLS_LE_LO12_R:
4686 case R_LARCH_TLS_LE_ADD_R:
4687 if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
4688 loongarch_relax_tls_le (abfd, sec, rel, info, symval);
4691 case R_LARCH_PCALA_HI20:
4692 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4693 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4694 info, again, max_alignment);
4697 case R_LARCH_GOT_PC_HI20:
4698 if (local_got && 0 == info->relax_pass
4699 && (i + 4) <= sec->reloc_count)
4701 if (loongarch_relax_pcala_ld (abfd, sec, rel))
4702 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4703 info, again, max_alignment);
4707 case R_LARCH_TLS_LD_PC_HI20:
4708 case R_LARCH_TLS_GD_PC_HI20:
4709 case R_LARCH_TLS_DESC_PC_HI20:
4710 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4711 loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4712 info, again, max_alignment);
4723 /* Finish up dynamic symbol handling. We set the contents of various
4724 dynamic sections here. */
4727 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
4728 struct bfd_link_info *info,
4729 struct elf_link_hash_entry *h,
4730 Elf_Internal_Sym *sym)
4732 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4733 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4735 if (h->plt.offset != MINUS_ONE)
4738 asection *plt, *gotplt, *relplt;
4739 bfd_vma got_address;
4740 uint32_t plt_entry[PLT_ENTRY_INSNS];
4742 Elf_Internal_Rela rela;
4746 BFD_ASSERT ((h->type == STT_GNU_IFUNC
4747 && SYMBOL_REFERENCES_LOCAL (info, h))
4748 || h->dynindx != -1);
4750 plt = htab->elf.splt;
4751 gotplt = htab->elf.sgotplt;
4752 if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4753 relplt = htab->elf.srelgot;
4755 relplt = htab->elf.srelplt;
4756 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4758 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4760 else /* if (htab->elf.iplt) */
4762 BFD_ASSERT (h->type == STT_GNU_IFUNC
4763 && SYMBOL_REFERENCES_LOCAL (info, h));
4765 plt = htab->elf.iplt;
4766 gotplt = htab->elf.igotplt;
4767 relplt = htab->elf.irelplt;
4768 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
4769 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4772 /* Find out where the .plt entry should go. */
4773 loc = plt->contents + h->plt.offset;
4775 /* Fill in the PLT entry itself. */
4776 if (!loongarch_make_plt_entry (got_address,
4777 sec_addr (plt) + h->plt.offset,
4781 for (i = 0; i < PLT_ENTRY_INSNS; i++)
4782 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4784 /* Fill in the initial value of the got.plt entry. */
4785 loc = gotplt->contents + (got_address - sec_addr (gotplt));
4786 bfd_put_NN (output_bfd, sec_addr (plt), loc);
4788 rela.r_offset = got_address;
4790 /* TRUE if this is a PLT reference to a local IFUNC. */
4791 if (PLT_LOCAL_IFUNC_P (info, h)
4792 && (relplt == htab->elf.srelgot
4793 || relplt == htab->elf.irelplt))
4795 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4796 rela.r_addend = (h->root.u.def.value
4797 + h->root.u.def.section->output_section->vma
4798 + h->root.u.def.section->output_offset);
4800 loongarch_elf_append_rela (output_bfd, relplt, &rela);
4804 /* Fill in the entry in the rela.plt section. */
4805 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4807 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
4808 bed->s->swap_reloca_out (output_bfd, &rela, loc);
4811 if (!h->def_regular)
4813 /* Mark the symbol as undefined, rather than as defined in
4814 the .plt section. Leave the value alone. */
4815 sym->st_shndx = SHN_UNDEF;
4816 /* If the symbol is weak, we do need to clear the value.
4817 Otherwise, the PLT entry would provide a definition for
4818 the symbol even if the symbol wasn't defined anywhere,
4819 and so the symbol would never be NULL. */
4820 if (!h->ref_regular_nonweak)
4825 if (h->got.offset != MINUS_ONE
4826 /* TLS got entry have been handled in elf_relocate_section. */
4827 && !(loongarch_elf_hash_entry (h)->tls_type
4828 & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
4829 /* Have allocated got entry but not allocated rela before. */
4830 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4832 asection *sgot, *srela;
4833 Elf_Internal_Rela rela;
4834 bfd_vma off = h->got.offset & ~(bfd_vma)1;
4836 /* This symbol has an entry in the GOT. Set it up. */
4837 sgot = htab->elf.sgot;
4838 srela = htab->elf.srelgot;
4839 BFD_ASSERT (sgot && srela);
4841 rela.r_offset = sec_addr (sgot) + off;
4844 && h->type == STT_GNU_IFUNC)
4846 if(h->plt.offset == MINUS_ONE)
4848 if (htab->elf.splt == NULL)
4849 srela = htab->elf.irelplt;
4851 if (SYMBOL_REFERENCES_LOCAL (info, h))
4853 asection *sec = h->root.u.def.section;
4854 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4855 rela.r_addend = h->root.u.def.value + sec->output_section->vma
4856 + sec->output_offset;
4857 bfd_put_NN (output_bfd, 0, sgot->contents + off);
4861 BFD_ASSERT (h->dynindx != -1);
4862 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4864 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
4867 else if(bfd_link_pic (info))
4869 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4871 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
4876 /* For non-shared object, we can't use .got.plt, which
4877 contains the real function address if we need pointer
4878 equality. We load the GOT entry with the PLT entry. */
4879 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4880 bfd_put_NN (output_bfd,
4881 (plt->output_section->vma
4882 + plt->output_offset
4884 sgot->contents + off);
4888 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4890 asection *sec = h->root.u.def.section;
4891 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4892 rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4893 + sec->output_offset);
4897 BFD_ASSERT (h->dynindx != -1);
4898 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4902 loongarch_elf_append_rela (output_bfd, srela, &rela);
4905 /* Mark some specially defined symbols as absolute. */
4906 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4907 sym->st_shndx = SHN_ABS;
4912 /* Finish up the dynamic sections. */
4915 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4918 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4919 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4920 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4921 bfd_byte *dyncon, *dynconend;
4923 dynconend = sdyn->contents + sdyn->size;
4924 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4926 Elf_Internal_Dyn dyn;
4930 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4935 s = htab->elf.sgotplt;
4936 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4939 s = htab->elf.srelplt;
4940 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4943 s = htab->elf.srelplt;
4944 dyn.d_un.d_val = s->size;
4947 if ((info->flags & DF_TEXTREL) == 0)
4951 if ((info->flags & DF_TEXTREL) == 0)
4952 dyn.d_un.d_val &= ~DF_TEXTREL;
4956 skipped_size += dynsize;
4958 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4960 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
4961 memset (dyncon - skipped_size, 0, skipped_size);
4965 /* Finish up local dynamic symbol handling. We set the contents of
4966 various dynamic sections here. */
4969 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4971 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4972 struct bfd_link_info *info = (struct bfd_link_info *) inf;
4974 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4977 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4978 this function is called before elf_link_sort_relocs.
4979 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4980 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
4983 elf_loongarch_output_arch_local_syms
4984 (bfd *output_bfd ATTRIBUTE_UNUSED,
4985 struct bfd_link_info *info,
4986 void *flaginfo ATTRIBUTE_UNUSED,
4987 int (*func) (void *, const char *,
4990 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4992 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4996 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4997 htab_traverse (htab->loc_hash_table,
4998 elfNN_loongarch_finish_local_dynamic_symbol,
5005 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
5006 struct bfd_link_info *info)
5009 asection *sdyn, *plt, *gotplt = NULL;
5010 struct loongarch_elf_link_hash_table *htab;
5012 htab = loongarch_elf_hash_table (info);
5014 dynobj = htab->elf.dynobj;
5015 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
5017 if (elf_hash_table (info)->dynamic_sections_created)
5019 BFD_ASSERT (htab->elf.splt && sdyn);
5021 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
5025 plt = htab->elf.splt;
5026 gotplt = htab->elf.sgotplt;
5028 if (plt && 0 < plt->size)
5031 uint32_t plt_header[PLT_HEADER_INSNS];
5032 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
5036 for (i = 0; i < PLT_HEADER_INSNS; i++)
5037 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
5039 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
5043 if (htab->elf.sgotplt)
5045 asection *output_section = htab->elf.sgotplt->output_section;
5047 if (bfd_is_abs_section (output_section))
5049 _bfd_error_handler (_("discarded output section: `%pA'"),
5054 if (0 < htab->elf.sgotplt->size)
5056 /* Write the first two entries in .got.plt, needed for the dynamic
5058 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
5060 bfd_put_NN (output_bfd, (bfd_vma) 0,
5061 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
5064 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5069 asection *output_section = htab->elf.sgot->output_section;
5071 if (0 < htab->elf.sgot->size)
5073 /* Set the first entry in the global offset table to the address of
5074 the dynamic section. */
5075 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
5076 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
5079 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5085 /* Return address for Ith PLT stub in section PLT, for relocation REL
5086 or (bfd_vma) -1 if it should not be included. */
5089 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
5090 const arelent *rel ATTRIBUTE_UNUSED)
5092 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
5095 static enum elf_reloc_type_class
5096 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5097 const asection *rel_sec ATTRIBUTE_UNUSED,
5098 const Elf_Internal_Rela *rela)
5100 struct loongarch_elf_link_hash_table *htab;
5101 htab = loongarch_elf_hash_table (info);
5103 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
5105 /* Check relocation against STT_GNU_IFUNC symbol if there are
5107 bfd *abfd = info->output_bfd;
5108 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5109 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
5110 if (r_symndx != STN_UNDEF)
5112 Elf_Internal_Sym sym;
5113 if (!bed->s->swap_symbol_in (abfd,
5114 htab->elf.dynsym->contents
5115 + r_symndx * bed->s->sizeof_sym,
5118 /* xgettext:c-format */
5119 _bfd_error_handler (_("%pB symbol number %lu references"
5120 " nonexistent SHT_SYMTAB_SHNDX section"),
5122 /* Ideally an error class should be returned here. */
5124 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5125 return reloc_class_ifunc;
5129 switch (ELFNN_R_TYPE (rela->r_info))
5131 case R_LARCH_IRELATIVE:
5132 return reloc_class_ifunc;
5133 case R_LARCH_RELATIVE:
5134 return reloc_class_relative;
5135 case R_LARCH_JUMP_SLOT:
5136 return reloc_class_plt;
5138 return reloc_class_copy;
5140 return reloc_class_normal;
5144 /* Copy the extra info we tack onto an elf_link_hash_entry. */
5147 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
5148 struct elf_link_hash_entry *dir,
5149 struct elf_link_hash_entry *ind)
5151 struct elf_link_hash_entry *edir, *eind;
5156 if (eind->dyn_relocs != NULL)
5158 if (edir->dyn_relocs != NULL)
5160 struct elf_dyn_relocs **pp;
5161 struct elf_dyn_relocs *p;
5163 /* Add reloc counts against the indirect sym to the direct sym
5164 list. Merge any entries against the same section. */
5165 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
5167 struct elf_dyn_relocs *q;
5169 for (q = edir->dyn_relocs; q != NULL; q = q->next)
5170 if (q->sec == p->sec)
5172 q->pc_count += p->pc_count;
5173 q->count += p->count;
5180 *pp = edir->dyn_relocs;
5183 edir->dyn_relocs = eind->dyn_relocs;
5184 eind->dyn_relocs = NULL;
5187 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
5189 loongarch_elf_hash_entry(edir)->tls_type
5190 = loongarch_elf_hash_entry(eind)->tls_type;
5191 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
5193 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
5196 #define PRSTATUS_SIZE 0x1d8
5197 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
5198 #define PRSTATUS_OFFSET_PR_PID 0x20
5199 #define ELF_GREGSET_T_SIZE 0x168
5200 #define PRSTATUS_OFFSET_PR_REG 0x70
5202 /* Support for core dump NOTE sections. */
5205 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
5207 switch (note->descsz)
5212 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
5215 elf_tdata (abfd)->core->signal =
5216 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
5219 elf_tdata (abfd)->core->lwpid =
5220 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
5224 /* Make a ".reg/999" section. */
5225 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
5227 + PRSTATUS_OFFSET_PR_REG);
5230 #define PRPSINFO_SIZE 0x88
5231 #define PRPSINFO_OFFSET_PR_PID 0x18
5232 #define PRPSINFO_OFFSET_PR_FNAME 0x28
5233 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
5234 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
5235 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
5238 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
5240 switch (note->descsz)
5245 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
5248 elf_tdata (abfd)->core->pid =
5249 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
5252 elf_tdata (abfd)->core->program =
5253 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
5254 PRPSINFO_SIZEOF_PR_FNAME);
5257 elf_tdata (abfd)->core->command =
5258 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
5259 PRPSINFO_SIZEOF_PR_PS_ARGS);
5263 /* Note that for some reason, a spurious space is tacked
5264 onto the end of the args in some (at least one anyway)
5265 implementations, so strip it off if it exists. */
5268 char *command = elf_tdata (abfd)->core->command;
5269 int n = strlen (command);
5271 if (0 < n && command[n - 1] == ' ')
5272 command[n - 1] = '\0';
5278 /* Set the right mach type. */
5280 loongarch_elf_object_p (bfd *abfd)
5282 /* There are only two mach types in LoongArch currently. */
5283 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
5284 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
5286 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
5291 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
5292 Elf_Internal_Rela *rel,
5293 struct elf_link_hash_entry *h,
5294 Elf_Internal_Sym *sym)
5297 switch (ELFNN_R_TYPE (rel->r_info))
5299 case R_LARCH_GNU_VTINHERIT:
5300 case R_LARCH_GNU_VTENTRY:
5304 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
5307 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
5308 executable PLT slots where the executable never takes the address of those
5309 functions, the function symbols are not added to the hash table. */
5312 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
5314 if (h->plt.offset != (bfd_vma) -1
5316 && !h->pointer_equality_needed)
5319 return _bfd_elf_hash_symbol (h);
5322 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
5323 #define TARGET_LITTLE_NAME "elfNN-loongarch"
5324 #define ELF_ARCH bfd_arch_loongarch
5325 #define ELF_TARGET_ID LARCH_ELF_DATA
5326 #define ELF_MACHINE_CODE EM_LOONGARCH
5327 #define ELF_MAXPAGESIZE 0x4000
5328 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5329 #define bfd_elfNN_bfd_link_hash_table_create \
5330 loongarch_elf_link_hash_table_create
5331 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5332 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
5333 #define elf_info_to_howto loongarch_info_to_howto_rela
5334 #define bfd_elfNN_bfd_merge_private_bfd_data \
5335 elfNN_loongarch_merge_private_bfd_data
5337 #define elf_backend_reloc_type_class loongarch_reloc_type_class
5338 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5339 #define elf_backend_create_dynamic_sections \
5340 loongarch_elf_create_dynamic_sections
5341 #define elf_backend_check_relocs loongarch_elf_check_relocs
5342 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5343 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
5344 #define elf_backend_relocate_section loongarch_elf_relocate_section
5345 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
5346 #define elf_backend_output_arch_local_syms \
5347 elf_loongarch_output_arch_local_syms
5348 #define elf_backend_finish_dynamic_sections \
5349 loongarch_elf_finish_dynamic_sections
5350 #define elf_backend_object_p loongarch_elf_object_p
5351 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5352 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5353 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5354 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
5355 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
5356 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
5358 #define elf_backend_dtrel_excludes_plt 1
5360 #include "elfNN-target.h"