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_DESC_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)
154 #define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
155 ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
156 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
158 /* Generate a PLT header. */
161 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
164 bfd_vma pcrel = got_plt_addr - plt_header_addr;
167 if (pcrel + 0x80000800 > 0xffffffff)
169 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
170 bfd_set_error (bfd_error_bad_value);
173 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
176 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
177 sub.[wd] $t1, $t1, $t3
178 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
179 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
180 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
181 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
182 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
185 if (GOT_ENTRY_SIZE == 8)
187 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
188 entry[1] = 0x0011bdad;
189 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
190 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
191 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
192 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
193 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
194 entry[7] = 0x4c0001e0;
198 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
199 entry[1] = 0x00113dad;
200 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
201 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
202 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
203 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
204 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
205 entry[7] = 0x4c0001e0;
210 /* Generate a PLT entry. */
213 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
216 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
219 if (pcrel + 0x80000800 > 0xffffffff)
221 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
222 bfd_set_error (bfd_error_bad_value);
225 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
228 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
229 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
230 | (lo & 0xfff) << 10);
231 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
232 entry[3] = 0x03400000; /* nop */
237 /* Create an entry in an LoongArch ELF linker hash table. */
239 static struct bfd_hash_entry *
240 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
243 struct loongarch_elf_link_hash_entry *eh;
245 /* Allocate the structure if it has not already been allocated by a
249 entry = bfd_hash_allocate (table, sizeof (*eh));
254 /* Call the allocation method of the superclass. */
255 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
258 eh = (struct loongarch_elf_link_hash_entry *) entry;
259 eh->tls_type = GOT_UNKNOWN;
265 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
266 for local symbol so that we can handle local STT_GNU_IFUNC symbols
267 as global symbol. We reuse indx and dynstr_index for local symbol
268 hash since they aren't used by global symbols in this backend. */
271 elfNN_loongarch_local_htab_hash (const void *ptr)
273 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
274 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
277 /* Compare local hash entries. */
280 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
282 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
283 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
285 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
288 /* Find and/or create a hash entry for local symbol. */
289 static struct elf_link_hash_entry *
290 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
291 bfd *abfd, const Elf_Internal_Rela *rel,
294 struct loongarch_elf_link_hash_entry e, *ret;
295 asection *sec = abfd->sections;
296 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
299 e.elf.indx = sec->id;
300 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
301 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
302 create ? INSERT : NO_INSERT);
309 ret = (struct loongarch_elf_link_hash_entry *) *slot;
313 ret = ((struct loongarch_elf_link_hash_entry *)
314 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
315 sizeof (struct loongarch_elf_link_hash_entry)));
318 memset (ret, 0, sizeof (*ret));
319 ret->elf.indx = sec->id;
320 ret->elf.pointer_equality_needed = 0;
321 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
322 ret->elf.dynindx = -1;
323 ret->elf.needs_plt = 0;
324 ret->elf.plt.refcount = -1;
325 ret->elf.got.refcount = -1;
326 ret->elf.def_dynamic = 0;
327 ret->elf.def_regular = 1;
328 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
329 ret->elf.ref_regular = 0;
330 ret->elf.forced_local = 1;
331 ret->elf.root.type = bfd_link_hash_defined;
337 /* Destroy an LoongArch elf linker hash table. */
340 elfNN_loongarch_link_hash_table_free (bfd *obfd)
342 struct loongarch_elf_link_hash_table *ret;
343 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
345 if (ret->loc_hash_table)
346 htab_delete (ret->loc_hash_table);
347 if (ret->loc_hash_memory)
348 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
350 _bfd_elf_link_hash_table_free (obfd);
353 /* Create a LoongArch ELF linker hash table. */
355 static struct bfd_link_hash_table *
356 loongarch_elf_link_hash_table_create (bfd *abfd)
358 struct loongarch_elf_link_hash_table *ret;
359 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
361 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
365 if (!_bfd_elf_link_hash_table_init
366 (&ret->elf, abfd, link_hash_newfunc,
367 sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
373 ret->max_alignment = MINUS_ONE;
375 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
376 elfNN_loongarch_local_htab_eq, NULL);
377 ret->loc_hash_memory = objalloc_create ();
378 if (!ret->loc_hash_table || !ret->loc_hash_memory)
380 elfNN_loongarch_link_hash_table_free (abfd);
383 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
385 return &ret->elf.root;
388 /* Merge backend specific data from an object file to the output
389 object file when linking. */
392 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
394 bfd *obfd = info->output_bfd;
395 flagword in_flags = elf_elfheader (ibfd)->e_flags;
396 flagword out_flags = elf_elfheader (obfd)->e_flags;
398 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
401 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
403 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
404 "the selected emulation:\n"
405 " target emulation `%s' does not match `%s'"),
406 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
410 if (!_bfd_elf_merge_object_attributes (ibfd, info))
413 /* If the input BFD is not a dynamic object and it does not contain any
414 non-data sections, do not account its ABI. For example, various
415 packages produces such data-only relocatable objects with
416 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
417 But they are compatible with all ABIs. */
418 if (!(ibfd->flags & DYNAMIC))
421 bool have_code_sections = false;
422 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
423 if ((bfd_section_flags (sec)
424 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
425 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
427 have_code_sections = true;
430 if (!have_code_sections)
434 if (!elf_flags_init (obfd))
436 elf_flags_init (obfd) = true;
437 elf_elfheader (obfd)->e_flags = in_flags;
440 else if (out_flags != in_flags)
442 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
443 && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
444 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
445 && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
447 elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
448 out_flags = elf_elfheader (obfd)->e_flags;
449 in_flags = out_flags;
453 /* Disallow linking different ABIs. */
454 /* Only check relocation version.
455 The obj_v0 is compatible with obj_v1. */
456 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
458 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
465 bfd_set_error (bfd_error_bad_value);
469 /* Create the .got section. */
472 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
477 struct elf_link_hash_entry *h;
478 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
479 struct elf_link_hash_table *htab = elf_hash_table (info);
481 /* This function may be called more than once. */
482 if (htab->sgot != NULL)
485 flags = bed->dynamic_sec_flags;
486 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
487 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
489 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
493 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
494 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
498 /* The first bit of the global offset table is the header. */
499 s->size += bed->got_header_size;
501 if (bed->want_got_plt)
503 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
504 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
508 /* Reserve room for the header. */
509 s->size = GOTPLT_HEADER_SIZE;
512 if (bed->want_got_sym)
514 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
515 section. We don't do this in the linker script because we don't want
516 to define the symbol if we are not creating a global offset table. */
517 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
518 "_GLOBAL_OFFSET_TABLE_");
519 elf_hash_table (info)->hgot = h;
526 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
527 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
531 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
533 struct loongarch_elf_link_hash_table *htab;
535 htab = loongarch_elf_hash_table (info);
536 BFD_ASSERT (htab != NULL);
538 if (!loongarch_elf_create_got_section (dynobj, info))
541 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
544 if (!bfd_link_pic (info))
546 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
547 SEC_ALLOC | SEC_THREAD_LOCAL);
549 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
550 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
557 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
558 struct bfd_link_info *info,
559 struct elf_link_hash_entry *h,
560 unsigned long symndx,
563 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
564 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
566 /* This is a global offset table entry for a local symbol. */
567 if (elf_local_got_refcounts (abfd) == NULL)
570 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
571 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
573 _bfd_loongarch_elf_local_got_tls_type (abfd) =
574 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
584 if (htab->elf.sgot == NULL
585 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
589 if (h->got.refcount < 0)
594 elf_local_got_refcounts (abfd)[symndx]++;
597 /* No need for GOT. */
600 _bfd_error_handler (_("Internal error: unreachable."));
604 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
605 *new_tls_type |= tls_type;
607 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
608 if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
609 *new_tls_type &= ~ (GOT_TLS_GDESC);
610 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
612 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
613 "thread local symbol"),
615 h ? h->root.root.string : "<local>");
623 loongarch_reloc_got_type (unsigned int r_type)
627 case R_LARCH_TLS_DESC_PC_HI20:
628 case R_LARCH_TLS_DESC_PC_LO12:
629 case R_LARCH_TLS_DESC_LD:
630 case R_LARCH_TLS_DESC_CALL:
631 return GOT_TLS_GDESC;
633 case R_LARCH_TLS_IE_PC_HI20:
634 case R_LARCH_TLS_IE_PC_LO12:
643 /* Return true if tls type transition can be performed. */
645 loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
646 struct elf_link_hash_entry *h, bfd *input_bfd,
647 unsigned long r_symndx)
649 char symbol_tls_type;
650 unsigned int reloc_got_type;
652 if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type)
653 || IS_LOONGARCH_TLS_IE_RELOC (r_type)))
656 symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
657 reloc_got_type = loongarch_reloc_got_type (r_type);
659 if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
662 if (! bfd_link_executable (info))
665 if (h && h->root.type == bfd_link_hash_undefweak)
671 /* The type of relocation that can be transitioned. */
673 loongarch_tls_transition_without_check (struct bfd_link_info *info,
675 struct elf_link_hash_entry *h)
677 bool local_exec = bfd_link_executable (info)
678 && SYMBOL_REFERENCES_LOCAL (info, h);
682 case R_LARCH_TLS_DESC_PC_HI20:
684 ? R_LARCH_TLS_LE_HI20
685 : R_LARCH_TLS_IE_PC_HI20);
687 case R_LARCH_TLS_DESC_PC_LO12:
689 ? R_LARCH_TLS_LE_LO12
690 : R_LARCH_TLS_IE_PC_LO12);
692 case R_LARCH_TLS_DESC_LD:
693 case R_LARCH_TLS_DESC_CALL:
696 case R_LARCH_TLS_IE_PC_HI20:
697 return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
699 case R_LARCH_TLS_IE_PC_LO12:
700 return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
710 loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
711 struct elf_link_hash_entry *h, bfd *input_bfd,
712 unsigned long r_symndx)
714 if (! loongarch_can_relax_tls (info, r_type, h, input_bfd,r_symndx))
717 return loongarch_tls_transition_without_check (info, r_type, h);
720 /* Look through the relocs for a section during the first phase, and
721 allocate space in the global offset table or procedure linkage
725 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
726 asection *sec, const Elf_Internal_Rela *relocs)
728 struct loongarch_elf_link_hash_table *htab;
729 Elf_Internal_Shdr *symtab_hdr;
730 struct elf_link_hash_entry **sym_hashes;
731 const Elf_Internal_Rela *rel;
732 asection *sreloc = NULL;
734 if (bfd_link_relocatable (info))
737 htab = loongarch_elf_hash_table (info);
738 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
739 sym_hashes = elf_sym_hashes (abfd);
741 if (htab->elf.dynobj == NULL)
742 htab->elf.dynobj = abfd;
744 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
747 unsigned int r_symndx;
748 struct elf_link_hash_entry *h;
749 Elf_Internal_Sym *isym = NULL;
751 r_symndx = ELFNN_R_SYM (rel->r_info);
752 r_type = ELFNN_R_TYPE (rel->r_info);
754 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
756 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
760 if (r_symndx < symtab_hdr->sh_info)
762 /* A local symbol. */
763 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
767 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
769 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
773 h->type = STT_GNU_IFUNC;
781 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
782 while (h->root.type == bfd_link_hash_indirect
783 || h->root.type == bfd_link_hash_warning)
784 h = (struct elf_link_hash_entry *) h->root.u.i.link;
787 /* It is referenced by a non-shared object. */
791 if (h && h->type == STT_GNU_IFUNC)
793 if (htab->elf.dynobj == NULL)
794 htab->elf.dynobj = abfd;
796 /* Create 'irelifunc' in PIC object. */
797 if (bfd_link_pic (info)
798 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
800 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
801 else if (!htab->elf.splt
802 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
804 /* Create the ifunc sections, iplt and ipltgot, for static
806 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
807 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
810 if (h->plt.refcount < 0)
815 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
818 int need_dynreloc = 0;
819 int only_need_pcrel = 0;
821 r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx);
824 case R_LARCH_GOT_PC_HI20:
825 case R_LARCH_GOT_HI20:
826 case R_LARCH_SOP_PUSH_GPREL:
829 h->pointer_equality_needed = 1;
830 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
836 case R_LARCH_TLS_LD_PC_HI20:
837 case R_LARCH_TLS_LD_HI20:
838 case R_LARCH_TLS_GD_PC_HI20:
839 case R_LARCH_TLS_GD_HI20:
840 case R_LARCH_SOP_PUSH_TLS_GD:
841 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
847 case R_LARCH_TLS_IE_PC_HI20:
848 case R_LARCH_TLS_IE_HI20:
849 case R_LARCH_SOP_PUSH_TLS_GOT:
850 if (bfd_link_pic (info))
851 /* May fail for lazy-bind. */
852 info->flags |= DF_STATIC_TLS;
854 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
860 case R_LARCH_TLS_LE_HI20:
861 case R_LARCH_TLS_LE_HI20_R:
862 case R_LARCH_SOP_PUSH_TLS_TPREL:
863 if (!bfd_link_executable (info))
866 info->flags |= DF_STATIC_TLS;
868 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
874 case R_LARCH_TLS_DESC_PC_HI20:
875 case R_LARCH_TLS_DESC_HI20:
876 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
882 case R_LARCH_ABS_HI20:
883 case R_LARCH_SOP_PUSH_ABSOLUTE:
885 /* If this reloc is in a read-only section, we might
886 need a copy reloc. We can't check reliably at this
887 stage whether the section is read-only, as input
888 sections have not yet been mapped to output sections.
889 Tentatively set the flag for now, and correct in
890 adjust_dynamic_symbol. */
894 /* For normal cmodel, pcalau12i + addi.d/w used to data.
895 For first version medium cmodel, pcalau12i + jirl are used to
896 function call, it need to creat PLT entry for STT_FUNC and
897 STT_GNU_IFUNC type symbol. */
898 case R_LARCH_PCALA_HI20:
899 if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
901 /* For pcalau12i + jirl. */
903 if (h->plt.refcount < 0)
908 h->pointer_equality_needed = 1;
920 if (!bfd_link_pic (info))
923 /* We try to create PLT stub for all non-local function. */
924 if (h->plt.refcount < 0)
931 case R_LARCH_SOP_PUSH_PCREL:
934 if (!bfd_link_pic (info))
937 /* We try to create PLT stub for all non-local function. */
938 if (h->plt.refcount < 0)
941 h->pointer_equality_needed = 1;
946 case R_LARCH_SOP_PUSH_PLT_PCREL:
947 /* This symbol requires a procedure linkage table entry. We
948 actually build the entry in adjust_dynamic_symbol,
949 because this might be a case of linking PIC code without
950 linking in any dynamic objects, in which case we don't
951 need to generate a procedure linkage table after all. */
955 if (h->plt.refcount < 0)
961 case R_LARCH_TLS_DTPREL32:
962 case R_LARCH_TLS_DTPREL64:
967 case R_LARCH_JUMP_SLOT:
973 /* If resolved symbol is defined in this object,
974 1. Under pie, the symbol is known. We convert it
975 into R_LARCH_RELATIVE and need load-addr still.
976 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
977 3. Under dll, R_LARCH_NN can't be changed normally, since
978 its defination could be covered by the one in executable.
979 For symbolic, we convert it into R_LARCH_RELATIVE.
980 Thus, only under pde, it needs pcrel only. We discard it. */
981 only_need_pcrel = bfd_link_pde (info);
984 && (!bfd_link_pic (info)
985 || h->type == STT_GNU_IFUNC))
987 /* This reloc might not bind locally. */
989 h->pointer_equality_needed = 1;
992 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
994 /* We may need a .plt entry if the symbol is a function
995 defined in a shared lib or is a function referenced
996 from the code or read-only section. */
997 h->plt.refcount += 1;
1002 case R_LARCH_GNU_VTINHERIT:
1003 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1007 case R_LARCH_GNU_VTENTRY:
1008 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1016 /* Record some info for sizing and allocating dynamic entry. */
1017 if (need_dynreloc && (sec->flags & SEC_ALLOC))
1019 /* When creating a shared object, we must copy these
1020 relocs into the output file. We create a reloc
1021 section in dynobj and make room for the reloc. */
1022 struct elf_dyn_relocs *p;
1023 struct elf_dyn_relocs **head;
1028 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
1029 LARCH_ELF_LOG_WORD_BYTES,
1030 abfd, /*rela?*/ true);
1035 /* If this is a global symbol, we count the number of
1036 relocations we need for this symbol. */
1038 head = &h->dyn_relocs;
1041 /* Track dynamic relocs needed for local syms too.
1042 We really need local syms available to do this
1048 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1052 vpp = &elf_section_data (s)->local_dynrel;
1053 head = (struct elf_dyn_relocs **) vpp;
1057 if (p == NULL || p->sec != sec)
1059 bfd_size_type amt = sizeof *p;
1060 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
1071 p->pc_count += only_need_pcrel;
1078 /* Find dynamic relocs for H that apply to read-only sections. */
1081 readonly_dynrelocs (struct elf_link_hash_entry *h)
1083 struct elf_dyn_relocs *p;
1085 for (p = h->dyn_relocs; p != NULL; p = p->next)
1087 asection *s = p->sec->output_section;
1089 if (s != NULL && (s->flags & SEC_READONLY) != 0)
1095 /* Adjust a symbol defined by a dynamic object and referenced by a
1096 regular object. The current definition is in some section of the
1097 dynamic object, but we're not including those sections. We have to
1098 change the definition to something the rest of the link can
1101 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1102 struct elf_link_hash_entry *h)
1104 struct loongarch_elf_link_hash_table *htab;
1107 htab = loongarch_elf_hash_table (info);
1108 BFD_ASSERT (htab != NULL);
1110 dynobj = htab->elf.dynobj;
1112 /* Make sure we know what is going on here. */
1113 BFD_ASSERT (dynobj != NULL
1115 || h->type == STT_GNU_IFUNC
1119 && !h->def_regular)));
1121 /* If this is a function, put it in the procedure linkage table. We
1122 will fill in the contents of the procedure linkage table later
1123 (although we could actually do it here). */
1124 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
1126 if (h->plt.refcount <= 0
1127 || (h->type != STT_GNU_IFUNC
1128 && (SYMBOL_REFERENCES_LOCAL (info, h)
1129 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1130 && h->root.type == bfd_link_hash_undefweak))))
1132 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1133 in an input file, but the symbol was never referred to by a
1134 dynamic object, or if all references were garbage collected.
1135 In such a case, we don't actually need to build a PLT entry. */
1136 h->plt.offset = MINUS_ONE;
1143 h->plt.offset = MINUS_ONE;
1145 /* If this is a weak symbol, and there is a real definition, the
1146 processor independent code will have arranged for us to see the
1147 real definition first, and we can just use the same value. */
1148 if (h->is_weakalias)
1150 struct elf_link_hash_entry *def = weakdef (h);
1151 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1152 h->root.u.def.section = def->root.u.def.section;
1153 h->root.u.def.value = def->root.u.def.value;
1157 /* R_LARCH_COPY is not adept glibc, not to generate. */
1158 /* Can not print anything, because make check ld. */
1162 /* Allocate space in .plt, .got and associated reloc sections for
1166 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1168 struct bfd_link_info *info;
1169 struct loongarch_elf_link_hash_table *htab;
1170 struct elf_dyn_relocs *p;
1172 if (h->root.type == bfd_link_hash_indirect)
1175 if (h->type == STT_GNU_IFUNC
1179 info = (struct bfd_link_info *) inf;
1180 htab = loongarch_elf_hash_table (info);
1181 bool dyn = htab->elf.dynamic_sections_created;
1182 BFD_ASSERT (htab != NULL);
1186 asection *plt, *gotplt, *relplt;
1195 if (h->dynindx == -1 && !h->forced_local && dyn
1196 && h->root.type == bfd_link_hash_undefweak)
1198 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1202 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1203 && h->type != STT_GNU_IFUNC)
1206 plt = htab->elf.splt;
1207 gotplt = htab->elf.sgotplt;
1208 relplt = htab->elf.srelplt;
1210 else if (htab->elf.iplt)
1212 /* .iplt only for IFUNC. */
1213 if (h->type != STT_GNU_IFUNC)
1216 plt = htab->elf.iplt;
1217 gotplt = htab->elf.igotplt;
1218 relplt = htab->elf.irelplt;
1224 plt->size = PLT_HEADER_SIZE;
1226 h->plt.offset = plt->size;
1227 plt->size += PLT_ENTRY_SIZE;
1228 gotplt->size += GOT_ENTRY_SIZE;
1229 relplt->size += sizeof (ElfNN_External_Rela);
1231 /* If this symbol is not defined in a regular file, and we are
1232 not generating a shared library, then set the symbol to this
1233 location in the .plt. This is required to make function
1234 pointers compare as equal between the normal executable and
1235 the shared library. */
1236 if (!bfd_link_pic (info)
1239 h->root.u.def.section = plt;
1240 h->root.u.def.value = h->plt.offset;
1248 h->plt.offset = MINUS_ONE;
1250 if (0 < h->got.refcount)
1253 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1255 /* Make sure this symbol is output as a dynamic symbol.
1256 Undefined weak syms won't yet be marked as dynamic. */
1257 if (h->dynindx == -1 && !h->forced_local && dyn
1258 && h->root.type == bfd_link_hash_undefweak)
1260 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1265 h->got.offset = s->size;
1266 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1268 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1269 if (tls_type & GOT_TLS_GD)
1271 s->size += 2 * GOT_ENTRY_SIZE;
1272 if (bfd_link_executable (info))
1274 /* Link exe and not defined local. */
1275 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1276 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1280 if (SYMBOL_REFERENCES_LOCAL (info, h))
1281 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1283 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1287 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1288 if (tls_type & GOT_TLS_IE)
1290 s->size += GOT_ENTRY_SIZE;
1292 if (bfd_link_executable (info))
1294 /* Link exe and not defined local. */
1295 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1296 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1300 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1304 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1305 if (tls_type & GOT_TLS_GDESC)
1307 s->size += GOT_ENTRY_SIZE * 2;
1308 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1314 s->size += GOT_ENTRY_SIZE;
1315 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1316 || h->root.type != bfd_link_hash_undefweak)
1317 && (bfd_link_pic (info)
1318 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1320 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1321 /* Undefined weak symbol in static PIE resolves to 0 without
1322 any dynamic relocations. */
1323 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1327 h->got.offset = MINUS_ONE;
1329 if (h->dyn_relocs == NULL)
1332 /* Extra dynamic relocate,
1334 * R_LARCH_TLS_DTPRELNN
1338 if (SYMBOL_CALLS_LOCAL (info, h))
1340 struct elf_dyn_relocs **pp;
1342 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1344 p->count -= p->pc_count;
1353 if (h->root.type == bfd_link_hash_undefweak)
1355 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1356 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1357 || (!bfd_link_pic (info) && h->non_got_ref))
1358 h->dyn_relocs = NULL;
1359 else if (h->dynindx == -1 && !h->forced_local)
1361 /* Make sure this symbol is output as a dynamic symbol.
1362 Undefined weak syms won't yet be marked as dynamic. */
1363 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1366 if (h->dynindx == -1)
1367 h->dyn_relocs = NULL;
1371 for (p = h->dyn_relocs; p != NULL; p = p->next)
1373 asection *sreloc = elf_section_data (p->sec)->sreloc;
1374 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1380 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1381 For local def and ref ifunc,
1382 dynamic relocations are stored in
1383 1. rela.srelgot section in dynamic object (dll or exec).
1384 2. rela.irelplt section in static executable.
1385 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1386 instead of rela.srelplt. Glibc ELF loader will not support
1387 R_LARCH_IRELATIVE relocation in rela.plt. */
1390 local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1391 struct elf_link_hash_entry *h,
1392 struct elf_dyn_relocs **head,
1393 unsigned int plt_entry_size,
1394 unsigned int plt_header_size,
1395 unsigned int got_entry_size,
1398 asection *plt, *gotplt, *relplt;
1399 struct elf_dyn_relocs *p;
1400 unsigned int sizeof_reloc;
1401 const struct elf_backend_data *bed;
1402 struct elf_link_hash_table *htab;
1403 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1404 bool use_plt = !avoid_plt || h->plt.refcount > 0;
1405 bool need_dynreloc = !use_plt || bfd_link_pic (info);
1407 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1408 in executable or it isn't referenced via PLT, the address of
1409 the resolved function may be used. But in non-PIC executable,
1410 the address of its plt slot may be used. Pointer equality may
1411 not work correctly. PIE or non-PLT reference should be used if
1412 pointer equality is required here.
1414 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1415 backend should change it to the normal function and set its address
1416 to its PLT entry which should be resolved by R_*_IRELATIVE at
1417 run-time. All external references should be resolved to its PLT in
1420 && !(bfd_link_pde (info) && h->def_regular)
1421 && (h->dynindx != -1
1422 || info->export_dynamic)
1423 && h->pointer_equality_needed)
1425 info->callbacks->einfo
1426 /* xgettext:c-format. */
1427 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1428 "equality in `%pB' can not be used when making an "
1429 "executable; recompile with -fPIE and relink with -pie\n"),
1430 h->root.root.string,
1431 h->root.u.def.section->owner);
1432 bfd_set_error (bfd_error_bad_value);
1436 htab = elf_hash_table (info);
1438 /* When the symbol is marked with regular reference, if PLT isn't used
1439 or we are building a PIC object, we must keep dynamic relocation
1440 if there is non-GOT reference and use PLT if there is PC-relative
1442 if (need_dynreloc && h->ref_regular)
1445 for (p = *head; p != NULL; p = p->next)
1449 /* Need dynamic relocations for non-GOT reference. */
1453 /* Must use PLT for PC-relative reference. */
1455 need_dynreloc = bfd_link_pic (info);
1463 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1464 if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1466 h->got = htab->init_got_offset;
1467 h->plt = htab->init_plt_offset;
1472 /* Return and discard space for dynamic relocations against it if
1473 it is never referenced. */
1474 if (!h->ref_regular)
1476 if (h->plt.refcount > 0
1477 || h->got.refcount > 0)
1479 h->got = htab->init_got_offset;
1480 h->plt = htab->init_plt_offset;
1486 bed = get_elf_backend_data (info->output_bfd);
1487 if (bed->rela_plts_and_copies_p)
1488 sizeof_reloc = bed->s->sizeof_rela;
1490 sizeof_reloc = bed->s->sizeof_rel;
1492 /* When building a static executable, use iplt, igot.plt and
1493 rela.iplt sections for STT_GNU_IFUNC symbols. */
1494 if (htab->splt != NULL)
1497 gotplt = htab->sgotplt;
1498 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1499 relplt = htab->srelgot;
1501 /* If this is the first plt entry and PLT is used, make room for
1502 the special first entry. */
1503 if (plt->size == 0 && use_plt)
1504 plt->size += plt_header_size;
1509 gotplt = htab->igotplt;
1510 relplt = htab->irelplt;
1515 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1516 the original value for R_*_IRELATIVE. */
1517 h->plt.offset = plt->size;
1519 /* Make room for this entry in the plt/iplt section. */
1520 plt->size += plt_entry_size;
1522 /* We also need to make an entry in the got.plt/got.iplt section,
1523 which will be placed in the got section by the linker script. */
1524 gotplt->size += got_entry_size;
1527 /* We also need to make an entry in the rela.plt/.rela.iplt
1528 section for GOTPLT relocation if PLT is used. */
1531 relplt->size += sizeof_reloc;
1532 relplt->reloc_count++;
1535 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1536 there is a non-GOT reference in a PIC object or PLT isn't used. */
1537 if (!need_dynreloc || !h->non_got_ref)
1540 /* Finally, allocate space. */
1544 bfd_size_type count = 0;
1552 htab->ifunc_resolvers = count != 0;
1554 /* Dynamic relocations are stored in
1555 1. rela.srelgot section in PIC object.
1556 2. rela.srelgot section in dynamic executable.
1557 3. rela.irelplt section in static executable. */
1558 if (htab->splt != NULL)
1559 htab->srelgot->size += count * sizeof_reloc;
1562 relplt->size += count * sizeof_reloc;
1563 relplt->reloc_count += count;
1567 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1568 and got has the PLT entry adddress. We will load the GOT entry
1569 with the PLT entry in finish_dynamic_symbol if it is used. For
1570 branch, it uses got.plt. For symbol value, if PLT is used,
1571 1. Use got.plt in a PIC object if it is forced local or not
1573 2. Use got.plt in a non-PIC object if pointer equality isn't
1575 3. Use got.plt in PIE.
1576 4. Use got.plt if got isn't used.
1577 5. Otherwise use got so that it can be shared among different
1578 objects at run-time.
1579 If PLT isn't used, always use got for symbol value.
1580 We only need to relocate got entry in PIC object or in dynamic
1581 executable without PLT. */
1583 && (h->got.refcount <= 0
1584 || (bfd_link_pic (info)
1585 && (h->dynindx == -1
1586 || h->forced_local))
1588 !h->pointer_equality_needed)
1589 || htab->sgot == NULL))
1592 h->got.offset = (bfd_vma) -1;
1598 /* PLT isn't used. */
1599 h->plt.offset = (bfd_vma) -1;
1601 if (h->got.refcount <= 0)
1603 /* GOT isn't need when there are only relocations for static
1605 h->got.offset = (bfd_vma) -1;
1609 h->got.offset = htab->sgot->size;
1610 htab->sgot->size += got_entry_size;
1611 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1612 used. Otherwise, the GOT entry will be filled with the PLT
1613 entry and dynamic GOT relocation isn't needed. */
1616 /* For non-static executable, dynamic GOT relocation is in
1617 rela.got section, but for static executable, it is
1618 in rela.iplt section. */
1619 if (htab->splt != NULL)
1620 htab->srelgot->size += sizeof_reloc;
1623 relplt->size += sizeof_reloc;
1624 relplt->reloc_count++;
1633 /* Allocate space in .plt, .got and associated reloc sections for
1634 ifunc dynamic relocs. */
1637 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1639 struct bfd_link_info *info;
1640 /* An example of a bfd_link_hash_indirect symbol is versioned
1641 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1642 -> __gxx_personality_v0(bfd_link_hash_defined)
1644 There is no need to process bfd_link_hash_indirect symbols here
1645 because we will also be presented with the concrete instance of
1646 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1647 called to copy all relevant data from the generic to the concrete
1649 if (h->root.type == bfd_link_hash_indirect)
1652 if (h->root.type == bfd_link_hash_warning)
1653 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1655 info = (struct bfd_link_info *) inf;
1657 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1658 here if it is defined and referenced in a non-shared object. */
1659 if (h->type == STT_GNU_IFUNC && h->def_regular)
1661 if (SYMBOL_REFERENCES_LOCAL (info, h))
1662 return local_allocate_ifunc_dyn_relocs (info, h,
1669 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1680 /* Allocate space in .plt, .got and associated reloc sections for
1681 ifunc dynamic relocs. */
1684 elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1686 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1688 if (h->type != STT_GNU_IFUNC
1692 || h->root.type != bfd_link_hash_defined)
1695 return elfNN_allocate_ifunc_dynrelocs (h, inf);
1698 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1699 read-only sections. */
1702 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1706 if (h->root.type == bfd_link_hash_indirect)
1709 sec = readonly_dynrelocs (h);
1712 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1714 info->flags |= DF_TEXTREL;
1715 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1716 "read-only section `%pA'\n"),
1717 sec->owner, h->root.root.string, sec);
1719 /* Not an error, just cut short the traversal. */
1726 loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1727 struct bfd_link_info *info)
1729 struct loongarch_elf_link_hash_table *htab;
1734 htab = loongarch_elf_hash_table (info);
1735 BFD_ASSERT (htab != NULL);
1736 dynobj = htab->elf.dynobj;
1737 BFD_ASSERT (dynobj != NULL);
1739 if (htab->elf.dynamic_sections_created)
1741 /* Set the contents of the .interp section to the interpreter. */
1742 if (bfd_link_executable (info) && !info->nointerp)
1744 const char *interpreter;
1745 s = bfd_get_linker_section (dynobj, ".interp");
1746 BFD_ASSERT (s != NULL);
1748 if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
1749 interpreter = "/lib32/ld.so.1";
1750 else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
1751 interpreter = "/lib64/ld.so.1";
1753 interpreter = "/lib/ld.so.1";
1755 s->contents = (unsigned char *) interpreter;
1756 s->size = strlen (interpreter) + 1;
1760 /* Set up .got offsets for local syms, and space for local dynamic
1762 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1764 bfd_signed_vma *local_got;
1765 bfd_signed_vma *end_local_got;
1766 char *local_tls_type;
1767 bfd_size_type locsymcount;
1768 Elf_Internal_Shdr *symtab_hdr;
1771 if (!is_loongarch_elf (ibfd))
1774 for (s = ibfd->sections; s != NULL; s = s->next)
1776 struct elf_dyn_relocs *p;
1778 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1780 p->count -= p->pc_count;
1781 if (!bfd_is_abs_section (p->sec)
1782 && bfd_is_abs_section (p->sec->output_section))
1784 /* Input section has been discarded, either because
1785 it is a copy of a linkonce section or due to
1786 linker script /DISCARD/, so we'll be discarding
1789 else if (0 < p->count)
1791 srel = elf_section_data (p->sec)->sreloc;
1792 srel->size += p->count * sizeof (ElfNN_External_Rela);
1793 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1794 info->flags |= DF_TEXTREL;
1799 local_got = elf_local_got_refcounts (ibfd);
1803 symtab_hdr = &elf_symtab_hdr (ibfd);
1804 locsymcount = symtab_hdr->sh_info;
1805 end_local_got = local_got + locsymcount;
1806 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1808 srel = htab->elf.srelgot;
1809 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1813 *local_got = s->size;
1814 if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1816 /* TLS gd use two got. */
1817 if (*local_tls_type & GOT_TLS_GD)
1819 s->size += 2 * GOT_ENTRY_SIZE;
1820 if (!bfd_link_executable (info))
1821 srel->size += sizeof (ElfNN_External_Rela);
1824 /* TLS_DESC use two got. */
1825 if (*local_tls_type & GOT_TLS_GDESC)
1827 s->size += 2 * GOT_ENTRY_SIZE;
1828 srel->size += sizeof (ElfNN_External_Rela);
1831 /* TLS ie and use one got. */
1832 if (*local_tls_type & GOT_TLS_IE)
1834 s->size += GOT_ENTRY_SIZE;
1835 if (!bfd_link_executable (info))
1836 srel->size += sizeof (ElfNN_External_Rela);
1841 s->size += GOT_ENTRY_SIZE;
1842 srel->size += sizeof (ElfNN_External_Rela);
1846 *local_got = MINUS_ONE;
1850 /* Allocate global sym .plt and .got entries, and space for global
1851 sym dynamic relocs. */
1852 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1854 /* Allocate global ifunc sym .plt and .got entries, and space for global
1855 ifunc sym dynamic relocs. */
1856 elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
1858 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1859 htab_traverse (htab->loc_hash_table,
1860 elfNN_allocate_local_ifunc_dynrelocs, info);
1862 /* Don't allocate .got.plt section if there are no PLT. */
1863 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1864 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1865 htab->elf.sgotplt->size = 0;
1867 /* The check_relocs and adjust_dynamic_symbol entry points have
1868 determined the sizes of the various dynamic sections. Allocate
1870 for (s = dynobj->sections; s != NULL; s = s->next)
1872 if ((s->flags & SEC_LINKER_CREATED) == 0)
1875 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1876 || s == htab->elf.sgotplt || s == htab->elf.igotplt
1877 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1879 /* Strip this section if we don't need it; see the
1882 else if (strncmp (s->name, ".rela", 5) == 0)
1886 /* We use the reloc_count field as a counter if we need
1887 to copy relocs into the output file. */
1893 /* It's not one of our sections. */
1899 /* If we don't need this section, strip it from the
1900 output file. This is mostly to handle .rela.bss and
1901 .rela.plt. We must create both sections in
1902 create_dynamic_sections, because they must be created
1903 before the linker maps input sections to output
1904 sections. The linker does that before
1905 adjust_dynamic_symbol is called, and it is that
1906 function which decides whether anything needs to go
1907 into these sections. */
1908 s->flags |= SEC_EXCLUDE;
1912 if ((s->flags & SEC_HAS_CONTENTS) == 0)
1915 /* Allocate memory for the section contents. Zero the memory
1916 for the benefit of .rela.plt, which has 4 unused entries
1917 at the beginning, and we don't want garbage. */
1918 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1919 if (s->contents == NULL)
1923 if (elf_hash_table (info)->dynamic_sections_created)
1925 /* Add some entries to the .dynamic section. We fill in the
1926 values later, in loongarch_elf_finish_dynamic_sections, but we
1927 must add the entries now so that we get the correct size for
1928 the .dynamic section. The DT_DEBUG entry is filled in by the
1929 dynamic linker and used by the debugger. */
1930 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1932 if (bfd_link_executable (info))
1934 if (!add_dynamic_entry (DT_DEBUG, 0))
1938 if (htab->elf.srelplt->size != 0)
1940 if (!add_dynamic_entry (DT_PLTGOT, 0)
1941 || !add_dynamic_entry (DT_PLTRELSZ, 0)
1942 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1943 || !add_dynamic_entry (DT_JMPREL, 0))
1947 if (!add_dynamic_entry (DT_RELA, 0)
1948 || !add_dynamic_entry (DT_RELASZ, 0)
1949 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1952 /* If any dynamic relocs apply to a read-only section,
1953 then we need a DT_TEXTREL entry. */
1954 if ((info->flags & DF_TEXTREL) == 0)
1955 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1957 if (info->flags & DF_TEXTREL)
1959 if (!add_dynamic_entry (DT_TEXTREL, 0))
1961 /* Clear the DF_TEXTREL flag. It will be set again if we
1962 write out an actual text relocation; we may not, because
1963 at this point we do not know whether e.g. any .eh_frame
1964 absolute relocations have been converted to PC-relative. */
1965 info->flags &= ~DF_TEXTREL;
1968 #undef add_dynamic_entry
1973 #define LARCH_LD_STACK_DEPTH 16
1974 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1975 static size_t larch_stack_top = 0;
1977 static bfd_reloc_status_type
1978 loongarch_push (int64_t val)
1980 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1981 return bfd_reloc_outofrange;
1982 larch_opc_stack[larch_stack_top++] = val;
1983 return bfd_reloc_ok;
1986 static bfd_reloc_status_type
1987 loongarch_pop (int64_t *val)
1989 if (larch_stack_top == 0)
1990 return bfd_reloc_outofrange;
1992 *val = larch_opc_stack[--larch_stack_top];
1993 return bfd_reloc_ok;
1996 static bfd_reloc_status_type
1997 loongarch_top (int64_t *val)
1999 if (larch_stack_top == 0)
2000 return bfd_reloc_outofrange;
2002 *val = larch_opc_stack[larch_stack_top - 1];
2003 return bfd_reloc_ok;
2007 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
2009 BFD_ASSERT (s && s->contents);
2010 const struct elf_backend_data *bed;
2013 bed = get_elf_backend_data (abfd);
2014 if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
2015 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
2016 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
2017 bed->s->swap_reloca_out (abfd, rel, loc);
2020 /* Check rel->r_offset in range of contents. */
2021 static bfd_reloc_status_type
2022 loongarch_check_offset (const Elf_Internal_Rela *rel,
2023 const asection *input_section)
2025 if (0 == strcmp(input_section->name, ".text")
2026 && rel->r_offset > input_section->size)
2027 return bfd_reloc_overflow;
2029 return bfd_reloc_ok;
2032 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2034 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2035 if (ret == bfd_reloc_ok) \
2037 ret = loongarch_pop (&op1); \
2038 if (ret == bfd_reloc_ok) \
2039 ret = loongarch_push (op3); \
2044 /* Write immediate to instructions. */
2046 static bfd_reloc_status_type
2047 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
2048 const asection *input_section ATTRIBUTE_UNUSED,
2049 reloc_howto_type *howto, bfd *input_bfd,
2050 bfd_byte *contents, bfd_vma reloc_val)
2052 /* Adjust the immediate based on alignment and
2053 its position in the instruction. */
2054 if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
2055 return bfd_reloc_overflow;
2057 int bits = bfd_get_reloc_size (howto) * 8;
2058 uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
2060 /* Write immediate to instruction. */
2061 insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
2063 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
2065 return bfd_reloc_ok;
2068 static bfd_reloc_status_type
2069 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
2070 reloc_howto_type *howto, bfd_vma value,
2071 bfd *input_bfd, bfd_byte *contents)
2073 int64_t opr1, opr2, opr3;
2074 bfd_reloc_status_type r = bfd_reloc_ok;
2075 int bits = bfd_get_reloc_size (howto) * 8;
2077 switch (ELFNN_R_TYPE (rel->r_info))
2079 case R_LARCH_SOP_PUSH_PCREL:
2080 case R_LARCH_SOP_PUSH_ABSOLUTE:
2081 case R_LARCH_SOP_PUSH_GPREL:
2082 case R_LARCH_SOP_PUSH_TLS_TPREL:
2083 case R_LARCH_SOP_PUSH_TLS_GOT:
2084 case R_LARCH_SOP_PUSH_TLS_GD:
2085 case R_LARCH_SOP_PUSH_PLT_PCREL:
2086 r = loongarch_push (value);
2089 case R_LARCH_SOP_PUSH_DUP:
2090 r = loongarch_pop (&opr1);
2091 if (r == bfd_reloc_ok)
2093 r = loongarch_push (opr1);
2094 if (r == bfd_reloc_ok)
2095 r = loongarch_push (opr1);
2099 case R_LARCH_SOP_ASSERT:
2100 r = loongarch_pop (&opr1);
2101 if (r != bfd_reloc_ok || !opr1)
2102 r = bfd_reloc_notsupported;
2105 case R_LARCH_SOP_NOT:
2106 r = loongarch_pop (&opr1);
2107 if (r == bfd_reloc_ok)
2108 r = loongarch_push (!opr1);
2111 case R_LARCH_SOP_SUB:
2112 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
2115 case R_LARCH_SOP_SL:
2116 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
2119 case R_LARCH_SOP_SR:
2120 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
2123 case R_LARCH_SOP_AND:
2124 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
2127 case R_LARCH_SOP_ADD:
2128 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
2131 case R_LARCH_SOP_IF_ELSE:
2132 r = loongarch_pop (&opr3);
2133 if (r == bfd_reloc_ok)
2135 r = loongarch_pop (&opr2);
2136 if (r == bfd_reloc_ok)
2138 r = loongarch_pop (&opr1);
2139 if (r == bfd_reloc_ok)
2140 r = loongarch_push (opr1 ? opr2 : opr3);
2145 case R_LARCH_SOP_POP_32_S_10_5:
2146 case R_LARCH_SOP_POP_32_S_10_12:
2147 case R_LARCH_SOP_POP_32_S_10_16:
2148 case R_LARCH_SOP_POP_32_S_10_16_S2:
2149 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2150 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2151 case R_LARCH_SOP_POP_32_S_5_20:
2152 case R_LARCH_SOP_POP_32_U_10_12:
2153 case R_LARCH_SOP_POP_32_U:
2154 r = loongarch_pop (&opr1);
2155 if (r != bfd_reloc_ok)
2157 r = loongarch_check_offset (rel, input_section);
2158 if (r != bfd_reloc_ok)
2161 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2163 contents, (bfd_vma)opr1);
2166 case R_LARCH_TLS_DTPREL32:
2168 case R_LARCH_TLS_DTPREL64:
2170 r = loongarch_check_offset (rel, input_section);
2171 if (r != bfd_reloc_ok)
2174 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2177 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2178 Because set/sub reloc pair not support multi-thread. While add/sub
2179 reloc pair process order not affect the final result.
2181 For add/sub reloc, the original value will be involved in the
2182 calculation. In order not to add/sub extra value, we write 0 to symbol
2183 address at assembly time.
2185 add/sub reloc bits determined by the value after symbol subtraction,
2188 add/sub reloc save part of the symbol value, so we only need to
2189 save howto->dst_mask bits. */
2193 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2194 contents + rel->r_offset);
2195 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2196 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2201 /* Not need to read the original value, just write the new value. */
2213 /* Because add/sub reloc is processed separately,
2214 so the high bits is invalid. */
2215 bfd_vma word = value & howto->dst_mask;
2216 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2221 case R_LARCH_ADD_ULEB128:
2222 case R_LARCH_SUB_ULEB128:
2224 unsigned int len = 0;
2225 /* Before write uleb128, first read it to get it's length. */
2226 _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2227 loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2232 /* For eh_frame and debug info. */
2233 case R_LARCH_32_PCREL:
2234 case R_LARCH_64_PCREL:
2236 value -= sec_addr (input_section) + rel->r_offset;
2237 value += rel->r_addend;
2238 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2239 contents + rel->r_offset);
2240 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2241 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2247 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2251 case R_LARCH_ABS_HI20:
2252 case R_LARCH_ABS_LO12:
2253 case R_LARCH_ABS64_LO20:
2254 case R_LARCH_ABS64_HI12:
2255 case R_LARCH_PCALA_HI20:
2256 case R_LARCH_PCALA_LO12:
2257 case R_LARCH_PCALA64_LO20:
2258 case R_LARCH_PCALA64_HI12:
2259 case R_LARCH_GOT_PC_HI20:
2260 case R_LARCH_GOT_PC_LO12:
2261 case R_LARCH_GOT64_PC_LO20:
2262 case R_LARCH_GOT64_PC_HI12:
2263 case R_LARCH_GOT_HI20:
2264 case R_LARCH_GOT_LO12:
2265 case R_LARCH_GOT64_LO20:
2266 case R_LARCH_GOT64_HI12:
2267 case R_LARCH_TLS_LE_HI20:
2268 case R_LARCH_TLS_LE_LO12:
2269 case R_LARCH_TLS_LE_HI20_R:
2270 case R_LARCH_TLS_LE_LO12_R:
2271 case R_LARCH_TLS_LE64_LO20:
2272 case R_LARCH_TLS_LE64_HI12:
2273 case R_LARCH_TLS_IE_PC_HI20:
2274 case R_LARCH_TLS_IE_PC_LO12:
2275 case R_LARCH_TLS_IE64_PC_LO20:
2276 case R_LARCH_TLS_IE64_PC_HI12:
2277 case R_LARCH_TLS_IE_HI20:
2278 case R_LARCH_TLS_IE_LO12:
2279 case R_LARCH_TLS_IE64_LO20:
2280 case R_LARCH_TLS_IE64_HI12:
2281 case R_LARCH_TLS_LD_PC_HI20:
2282 case R_LARCH_TLS_LD_HI20:
2283 case R_LARCH_TLS_GD_PC_HI20:
2284 case R_LARCH_TLS_GD_HI20:
2285 case R_LARCH_PCREL20_S2:
2286 case R_LARCH_CALL36:
2287 case R_LARCH_TLS_DESC_PC_HI20:
2288 case R_LARCH_TLS_DESC_PC_LO12:
2289 case R_LARCH_TLS_DESC64_PC_LO20:
2290 case R_LARCH_TLS_DESC64_PC_HI12:
2291 case R_LARCH_TLS_DESC_HI20:
2292 case R_LARCH_TLS_DESC_LO12:
2293 case R_LARCH_TLS_DESC64_LO20:
2294 case R_LARCH_TLS_DESC64_HI12:
2295 case R_LARCH_TLS_LD_PCREL20_S2:
2296 case R_LARCH_TLS_GD_PCREL20_S2:
2297 case R_LARCH_TLS_DESC_PCREL20_S2:
2298 r = loongarch_check_offset (rel, input_section);
2299 if (r != bfd_reloc_ok)
2302 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2307 case R_LARCH_TLS_DESC_LD:
2308 case R_LARCH_TLS_DESC_CALL:
2313 case R_LARCH_TLS_LE_ADD_R:
2317 r = bfd_reloc_notsupported;
2322 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2330 Elf_Internal_Sym *sym;
2331 struct elf_link_hash_entry *h;
2334 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2335 static size_t larch_reloc_queue_head = 0;
2336 static size_t larch_reloc_queue_tail = 0;
2339 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2340 Elf_Internal_Sym *sym)
2342 const char *ret = NULL;
2344 ret = bfd_elf_string_from_elf_section (input_bfd,
2345 elf_symtab_hdr (input_bfd).sh_link,
2348 ret = h->root.root.string;
2350 if (ret == NULL || *ret == '\0')
2356 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2357 bfd_vma r_offset, Elf_Internal_Sym *sym,
2358 struct elf_link_hash_entry *h, bfd_vma addend)
2360 if ((larch_reloc_queue_head == 0
2361 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2362 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2363 larch_reloc_queue_head =
2364 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2365 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2366 larch_reloc_queue[larch_reloc_queue_tail].section = section;
2367 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2368 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2369 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2370 larch_reloc_queue[larch_reloc_queue_tail].h = h;
2371 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2372 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2373 larch_reloc_queue_tail =
2374 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2378 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2380 size_t i = larch_reloc_queue_head;
2382 asection *section = NULL;
2383 bfd_vma r_offset = 0;
2385 p ("Dump relocate record:\n");
2386 p ("stack top\t\trelocation name\t\tsymbol");
2387 while (i != larch_reloc_queue_tail)
2389 if (a_bfd != larch_reloc_queue[i].bfd
2390 || section != larch_reloc_queue[i].section
2391 || r_offset != larch_reloc_queue[i].r_offset)
2393 a_bfd = larch_reloc_queue[i].bfd;
2394 section = larch_reloc_queue[i].section;
2395 r_offset = larch_reloc_queue[i].r_offset;
2396 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2397 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2401 inited = 1, p ("...\n");
2403 reloc_howto_type *howto =
2404 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2405 larch_reloc_queue[i].r_type);
2406 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2407 howto ? howto->name : "<unknown reloc>",
2408 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2409 larch_reloc_queue[i].sym));
2411 long addend = larch_reloc_queue[i].addend;
2413 p (" - %ld", -addend);
2414 else if (0 < addend)
2415 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2418 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2421 "-- Record dump end --\n\n");
2425 loongarch_reloc_is_fatal (struct bfd_link_info *info,
2427 asection *input_section,
2428 Elf_Internal_Rela *rel,
2429 reloc_howto_type *howto,
2430 bfd_reloc_status_type rtype,
2438 /* 'dangerous' means we do it but can't promise it's ok
2439 'unsupport' means out of ability of relocation type
2440 'undefined' means we can't deal with the undefined symbol. */
2441 case bfd_reloc_undefined:
2442 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2443 rel->r_offset, true);
2444 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2445 input_bfd, input_section, rel->r_offset,
2447 is_undefweak ? "[undefweak] " : "", name, msg);
2449 case bfd_reloc_dangerous:
2450 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2451 input_bfd, input_section, rel->r_offset,
2453 is_undefweak ? "[undefweak] " : "", name, msg);
2456 case bfd_reloc_notsupported:
2457 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2458 input_bfd, input_section, rel->r_offset,
2460 is_undefweak ? "[undefweak] " : "", name, msg);
2468 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2469 hi20 immediate need to add 0x1.
2470 For example: pc 0x120000000, symbol 0x120000812
2471 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2472 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2473 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2476 pcalau12i $t0, hi20 (0x1)
2477 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2478 addi.d $t0, $t0, lo12 (0x812)
2479 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2480 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2482 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2484 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
2485 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2487 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2488 relocation = (relocation & ~(bfd_vma)0xfff) \
2489 - (pc & ~(bfd_vma)0xfff); \
2491 relocation += 0x1000; \
2494 /* Handle problems caused by symbol extensions in TLS LE, The processing
2495 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
2496 #define RELOCATE_TLS_TP32_HI20(relocation) \
2498 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2500 relocation += 0x800; \
2501 relocation = relocation & ~(bfd_vma)0xfff; \
2504 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2505 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2507 lo12: 0x1812348ffff812 & 0xfff = 0x812
2508 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2509 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2512 pcalau12i $t1, hi20 (0x80000)
2513 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2514 = 0x11000010000100 + 0xffffffff80000000
2516 addi.d $t0, $zero, lo12 (0x812)
2517 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2518 lo20 need to sub 0x1)
2519 lu32i.d $t0, lo20 (0x71234)
2520 $t0 = {0x71234, 0xfffff812}
2522 lu52i.d $t0, hi12 (0x0)
2523 $t0 = {0x0, 0x71234fffff812}
2526 $t1 = 0x10ffff90000000 + 0x71234fffff812
2527 = 0x1812348ffff812. */
2528 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2530 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2531 relocation = (relocation & ~(bfd_vma)0xfff) \
2532 - (pc & ~(bfd_vma)0xfff); \
2534 relocation += (0x1000 - 0x100000000); \
2535 if (relocation & 0x80000000) \
2536 relocation += 0x100000000; \
2539 /* Transition instruction sequence to relax instruction sequence. */
2541 loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
2542 int r_type, struct elf_link_hash_entry *h,
2543 struct bfd_link_info *info)
2545 bool local_exec = bfd_link_executable (info)
2546 && SYMBOL_REFERENCES_LOCAL (info, h);
2547 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
2552 case R_LARCH_TLS_DESC_PC_HI20:
2554 /* DESC -> LE relaxation:
2555 pcalalau12i $a0,%desc_pc_hi20(var) =>
2556 lu12i.w $a0,%le_hi20(var)
2558 bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
2559 contents + rel->r_offset);
2561 /* DESC -> IE relaxation:
2562 pcalalau12i $a0,%desc_pc_hi20(var) =>
2563 pcalalau12i $a0,%ie_pc_hi20(var)
2567 case R_LARCH_TLS_DESC_PC_LO12:
2570 /* DESC -> LE relaxation:
2571 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2572 ori $a0,$a0,le_lo12(var)
2574 insn = LARCH_ORI | LARCH_RD_RJ_A0;
2575 bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
2576 contents + rel->r_offset);
2580 /* DESC -> IE relaxation:
2581 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2582 ld.d $a0,$a0,%%ie_pc_lo12
2584 bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
2585 contents + rel->r_offset);
2589 case R_LARCH_TLS_DESC_LD:
2590 case R_LARCH_TLS_DESC_CALL:
2591 /* DESC -> LE/IE relaxation:
2592 ld.d $ra,$a0,%desc_ld(var) => NOP
2593 jirl $ra,$ra,%desc_call(var) => NOP
2595 bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
2598 case R_LARCH_TLS_IE_PC_HI20:
2601 /* IE -> LE relaxation:
2602 pcalalau12i $rd,%ie_pc_hi20(var) =>
2603 lu12i.w $rd,%le_hi20(var)
2605 insn = bfd_getl32 (contents + rel->r_offset);
2606 bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
2607 contents + rel->r_offset);
2611 case R_LARCH_TLS_IE_PC_LO12:
2614 /* IE -> LE relaxation:
2615 ld.d $rd,$rj,%%ie_pc_lo12 =>
2616 ori $rd,$rj,le_lo12(var)
2618 insn = bfd_getl32 (contents + rel->r_offset);
2619 bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
2620 contents + rel->r_offset);
2630 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2631 bfd *input_bfd, asection *input_section,
2632 bfd_byte *contents, Elf_Internal_Rela *relocs,
2633 Elf_Internal_Sym *local_syms,
2634 asection **local_sections)
2636 Elf_Internal_Rela *rel;
2637 Elf_Internal_Rela *relend;
2639 asection *sreloc = elf_section_data (input_section)->sreloc;
2640 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2641 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2642 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2643 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2644 bool is_pic = bfd_link_pic (info);
2645 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2646 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2647 asection *got = htab->elf.sgot;
2649 relend = relocs + input_section->reloc_count;
2650 for (rel = relocs; rel < relend; rel++)
2652 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
2653 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2654 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2655 reloc_howto_type *howto = NULL;
2656 asection *sec = NULL;
2657 Elf_Internal_Sym *sym = NULL;
2658 struct elf_link_hash_entry *h = NULL;
2660 bfd_reloc_status_type r = bfd_reloc_ok;
2661 bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
2662 unsigned int relaxed_r_type;
2663 bool resolved_local, resolved_dynly, resolved_to_const;
2665 bfd_vma relocation, off, ie_off, desc_off;
2668 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2669 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2670 || r_type == R_LARCH_GNU_VTENTRY)
2673 /* This is a final link. */
2674 if (r_symndx < symtab_hdr->sh_info)
2676 is_undefweak = false;
2677 unresolved_reloc = false;
2678 sym = local_syms + r_symndx;
2679 sec = local_sections[r_symndx];
2680 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2682 /* Relocate against local STT_GNU_IFUNC symbol. */
2683 if (!bfd_link_relocatable (info)
2684 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2686 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2691 /* Set STT_GNU_IFUNC symbol value. */
2692 h->root.u.def.value = sym->st_value;
2693 h->root.u.def.section = sec;
2695 defined_local = true;
2696 resolved_local = true;
2697 resolved_dynly = false;
2698 resolved_to_const = false;
2700 /* Calc in funtion elf_link_input_bfd,
2701 * if #define elf_backend_rela_normal to 1. */
2702 if (bfd_link_relocatable (info)
2703 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2708 bool warned, ignored;
2710 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2711 r_symndx, symtab_hdr, sym_hashes,
2713 unresolved_reloc, warned, ignored);
2714 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2716 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2717 symbol. And 'dynamic_undefined_weak' specify what to do when
2718 meeting undefweak. */
2720 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2722 defined_local = false;
2723 resolved_local = false;
2724 resolved_to_const = (!is_dyn || h->dynindx == -1
2725 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2726 resolved_dynly = !resolved_local && !resolved_to_const;
2730 /* Symbol undefined offen means failed already. I don't know why
2731 'warned' here but I guess it want to continue relocating as if
2732 no error occures to find other errors as more as possible. */
2734 /* To avoid generating warning messages about truncated
2735 relocations, set the relocation's address to be the same as
2736 the start of this section. */
2737 relocation = (input_section->output_section
2738 ? input_section->output_section->vma
2741 defined_local = relocation != 0;
2742 resolved_local = defined_local;
2743 resolved_to_const = !resolved_local;
2744 resolved_dynly = false;
2748 defined_local = !unresolved_reloc && !ignored;
2750 defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2751 resolved_dynly = !resolved_local;
2752 resolved_to_const = !resolved_local && !resolved_dynly;
2756 name = loongarch_sym_name (input_bfd, h, sym);
2758 if (sec != NULL && discarded_section (sec))
2759 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2760 1, relend, howto, 0, contents);
2762 if (bfd_link_relocatable (info))
2765 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2766 from removed linkonce sections, or sections discarded by a linker
2767 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2768 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2770 defined_local = false;
2771 resolved_local = false;
2772 resolved_dynly = false;
2773 resolved_to_const = true;
2776 /* The ifunc reference generate plt. */
2777 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2779 defined_local = true;
2780 resolved_local = true;
2781 resolved_dynly = false;
2782 resolved_to_const = false;
2783 relocation = sec_addr (plt) + h->plt.offset;
2786 unresolved_reloc = resolved_dynly;
2788 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2790 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2792 BFD_ASSERT (!resolved_local || defined_local);
2794 relaxed_r_type = loongarch_tls_transition (info, r_type, h, input_bfd, r_symndx);
2795 if (relaxed_r_type != r_type)
2797 howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type);
2798 BFD_ASSERT (howto != NULL);
2800 if (loongarch_tls_relax (input_bfd, input_section, rel, r_type, h, info))
2801 r_type = relaxed_r_type;
2808 case R_LARCH_MARK_PCREL:
2809 case R_LARCH_MARK_LA:
2811 r = bfd_reloc_continue;
2812 unresolved_reloc = false;
2817 if (resolved_dynly || (is_pic && resolved_local))
2819 Elf_Internal_Rela outrel;
2821 /* When generating a shared object, these relocations are copied
2822 into the output file to be resolved at run time. */
2824 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2828 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2829 && (input_section->flags & SEC_ALLOC));
2831 outrel.r_offset += sec_addr (input_section);
2833 /* A pointer point to a ifunc symbol. */
2834 if (h && h->type == STT_GNU_IFUNC)
2836 if (h->dynindx == -1)
2838 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2839 outrel.r_addend = (h->root.u.def.value
2840 + h->root.u.def.section->output_section->vma
2841 + h->root.u.def.section->output_offset);
2845 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2846 outrel.r_addend = 0;
2849 if (SYMBOL_REFERENCES_LOCAL (info, h))
2852 if (htab->elf.splt != NULL)
2853 sreloc = htab->elf.srelgot;
2855 sreloc = htab->elf.irelplt;
2860 if (bfd_link_pic (info))
2861 sreloc = htab->elf.irelifunc;
2862 else if (htab->elf.splt != NULL)
2863 sreloc = htab->elf.srelgot;
2865 sreloc = htab->elf.irelplt;
2868 else if (resolved_dynly)
2870 if (h->dynindx == -1)
2872 if (h->root.type == bfd_link_hash_undefined)
2873 (*info->callbacks->undefined_symbol)
2874 (info, name, input_bfd, input_section,
2875 rel->r_offset, true);
2877 outrel.r_info = ELFNN_R_INFO (0, r_type);
2880 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2882 outrel.r_addend = rel->r_addend;
2886 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2887 outrel.r_addend = relocation + rel->r_addend;
2890 /* No alloc space of func allocate_dynrelocs. */
2891 if (unresolved_reloc
2892 && !(h && (h->is_weakalias || !h->dyn_relocs)))
2893 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2896 relocation += rel->r_addend;
2906 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2907 contents + rel->r_offset);
2908 relocation = old_value + relocation + rel->r_addend;
2919 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2920 contents + rel->r_offset);
2921 relocation = old_value - relocation - rel->r_addend;
2925 case R_LARCH_ADD_ULEB128:
2926 case R_LARCH_SUB_ULEB128:
2928 /* Get the value and length of the uleb128 data. */
2929 unsigned int len = 0;
2930 bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2931 contents + rel->r_offset, &len);
2933 if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2934 relocation = old_value + relocation + rel->r_addend;
2935 else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2936 relocation = old_value - relocation - rel->r_addend;
2938 bfd_vma mask = (1 << (7 * len)) - 1;
2943 case R_LARCH_TLS_DTPREL32:
2944 case R_LARCH_TLS_DTPREL64:
2947 Elf_Internal_Rela outrel;
2949 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2952 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2953 && (input_section->flags & SEC_ALLOC));
2954 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2955 outrel.r_offset += sec_addr (input_section);
2956 outrel.r_addend = rel->r_addend;
2957 if (unresolved_reloc)
2958 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2962 if (resolved_to_const)
2963 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2965 bfd_reloc_notsupported,
2970 if (!elf_hash_table (info)->tls_sec)
2972 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2973 input_section, rel, howto, bfd_reloc_notsupported,
2974 is_undefweak, name, "TLS section not be created");
2977 relocation -= elf_hash_table (info)->tls_sec->vma;
2981 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2982 input_section, rel, howto, bfd_reloc_undefined,
2984 "TLS LE just can be resolved local only.");
2989 case R_LARCH_SOP_PUSH_TLS_TPREL:
2992 if (!elf_hash_table (info)->tls_sec)
2993 fatal = (loongarch_reloc_is_fatal
2994 (info, input_bfd, input_section, rel, howto,
2995 bfd_reloc_notsupported, is_undefweak, name,
2996 "TLS section not be created"));
2998 relocation -= elf_hash_table (info)->tls_sec->vma;
3001 fatal = (loongarch_reloc_is_fatal
3002 (info, input_bfd, input_section, rel, howto,
3003 bfd_reloc_undefined, is_undefweak, name,
3004 "TLS LE just can be resolved local only."));
3007 case R_LARCH_SOP_PUSH_ABSOLUTE:
3011 fatal = (loongarch_reloc_is_fatal
3012 (info, input_bfd, input_section, rel, howto,
3013 bfd_reloc_dangerous, is_undefweak, name,
3014 "Someone require us to resolve undefweak "
3015 "symbol dynamically. \n"
3016 "But this reloc can't be done. "
3017 "I think I can't throw error "
3019 "so I resolved it to 0. "
3020 "I suggest to re-compile with '-fpic'."));
3023 unresolved_reloc = false;
3027 if (resolved_to_const)
3029 relocation += rel->r_addend;
3035 fatal = (loongarch_reloc_is_fatal
3036 (info, input_bfd, input_section, rel, howto,
3037 bfd_reloc_notsupported, is_undefweak, name,
3038 "Under PIC we don't know load address. Re-compile "
3045 if (!(plt && h && h->plt.offset != MINUS_ONE))
3047 fatal = (loongarch_reloc_is_fatal
3048 (info, input_bfd, input_section, rel, howto,
3049 bfd_reloc_undefined, is_undefweak, name,
3050 "Can't be resolved dynamically. Try to re-compile "
3055 if (rel->r_addend != 0)
3057 fatal = (loongarch_reloc_is_fatal
3058 (info, input_bfd, input_section, rel, howto,
3059 bfd_reloc_notsupported, is_undefweak, name,
3060 "Shouldn't be with r_addend."));
3064 relocation = sec_addr (plt) + h->plt.offset;
3065 unresolved_reloc = false;
3071 relocation += rel->r_addend;
3077 case R_LARCH_SOP_PUSH_PCREL:
3078 case R_LARCH_SOP_PUSH_PLT_PCREL:
3079 unresolved_reloc = false;
3087 if (h && h->plt.offset != MINUS_ONE)
3090 fatal = (loongarch_reloc_is_fatal
3091 (info, input_bfd, input_section, rel, howto,
3092 bfd_reloc_dangerous, is_undefweak, name,
3093 "Undefweak need to be resolved dynamically, "
3094 "but PLT stub doesn't represent."));
3099 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
3101 fatal = (loongarch_reloc_is_fatal
3102 (info, input_bfd, input_section, rel, howto,
3103 bfd_reloc_undefined, is_undefweak, name,
3104 "PLT stub does not represent and "
3105 "symbol not defined."));
3111 else /* if (resolved_dynly) */
3113 if (!(h && h->plt.offset != MINUS_ONE))
3114 fatal = (loongarch_reloc_is_fatal
3115 (info, input_bfd, input_section, rel, howto,
3116 bfd_reloc_dangerous, is_undefweak, name,
3117 "Internal: PLT stub doesn't represent. "
3118 "Resolve it with pcrel"));
3125 if ((i & 1) == 0 && defined_local)
3128 relocation += rel->r_addend;
3132 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
3134 if (rel->r_addend != 0)
3136 fatal = (loongarch_reloc_is_fatal
3137 (info, input_bfd, input_section, rel, howto,
3138 bfd_reloc_notsupported, is_undefweak, name,
3139 "PLT shouldn't be with r_addend."));
3142 relocation = sec_addr (plt) + h->plt.offset - pc;
3148 case R_LARCH_SOP_PUSH_GPREL:
3149 unresolved_reloc = false;
3151 if (rel->r_addend != 0)
3153 fatal = (loongarch_reloc_is_fatal
3154 (info, input_bfd, input_section, rel, howto,
3155 bfd_reloc_notsupported, is_undefweak, name,
3156 "Shouldn't be with r_addend."));
3162 off = h->got.offset & (~1);
3164 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
3166 fatal = (loongarch_reloc_is_fatal
3167 (info, input_bfd, input_section, rel, howto,
3168 bfd_reloc_notsupported, is_undefweak, name,
3169 "Internal: GOT entry doesn't represent."));
3173 /* Hidden symbol not has .got entry, only .got.plt entry
3174 so gprel is (plt - got). */
3175 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3177 if (h->plt.offset == (bfd_vma) -1)
3182 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3183 off = plt_index * GOT_ENTRY_SIZE;
3185 if (htab->elf.splt != NULL)
3187 /* Section .plt header is 2 times of plt entry. */
3188 off = sec_addr (htab->elf.sgotplt) + off
3189 - sec_addr (htab->elf.sgot);
3193 /* Section iplt not has plt header. */
3194 off = sec_addr (htab->elf.igotplt) + off
3195 - sec_addr (htab->elf.sgot);
3199 if ((h->got.offset & 1) == 0)
3201 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3202 bfd_link_pic (info), h)
3203 && ((bfd_link_pic (info)
3204 && SYMBOL_REFERENCES_LOCAL (info, h))))
3206 /* This is actually a static link, or it is a
3207 -Bsymbolic link and the symbol is defined
3208 locally, or the symbol was forced to be local
3209 because of a version file. We must initialize
3210 this entry in the global offset table. Since the
3211 offset must always be a multiple of the word size,
3212 we use the least significant bit to record whether
3213 we have initialized it already.
3215 When doing a dynamic link, we create a rela.got
3216 relocation entry to initialize the value. This
3217 is done in the finish_dynamic_symbol routine. */
3221 fatal = (loongarch_reloc_is_fatal
3222 (info, input_bfd, input_section, rel, howto,
3223 bfd_reloc_dangerous, is_undefweak, name,
3224 "Internal: here shouldn't dynamic."));
3227 if (!(defined_local || resolved_to_const))
3229 fatal = (loongarch_reloc_is_fatal
3230 (info, input_bfd, input_section, rel, howto,
3231 bfd_reloc_undefined, is_undefweak, name,
3237 Elf_Internal_Rela outrel;
3238 /* We need to generate a R_LARCH_RELATIVE reloc
3239 for the dynamic linker. */
3240 s = htab->elf.srelgot;
3243 fatal = loongarch_reloc_is_fatal
3245 input_section, rel, howto,
3246 bfd_reloc_notsupported, is_undefweak, name,
3247 "Internal: '.rel.got' not represent");
3251 outrel.r_offset = sec_addr (got) + off;
3252 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3253 outrel.r_addend = relocation; /* Link-time addr. */
3254 loongarch_elf_append_rela (output_bfd, s, &outrel);
3256 bfd_put_NN (output_bfd, relocation, got->contents + off);
3262 if (!local_got_offsets)
3264 fatal = (loongarch_reloc_is_fatal
3265 (info, input_bfd, input_section, rel, howto,
3266 bfd_reloc_notsupported, is_undefweak, name,
3267 "Internal: local got offsets not reporesent."));
3271 off = local_got_offsets[r_symndx] & (~1);
3273 if (local_got_offsets[r_symndx] == MINUS_ONE)
3275 fatal = (loongarch_reloc_is_fatal
3276 (info, input_bfd, input_section, rel, howto,
3277 bfd_reloc_notsupported, is_undefweak, name,
3278 "Internal: GOT entry doesn't represent."));
3282 /* The offset must always be a multiple of the word size.
3283 So, we can use the least significant bit to record
3284 whether we have already processed this entry. */
3285 if ((local_got_offsets[r_symndx] & 1) == 0)
3290 Elf_Internal_Rela outrel;
3291 /* We need to generate a R_LARCH_RELATIVE reloc
3292 for the dynamic linker. */
3293 s = htab->elf.srelgot;
3296 fatal = (loongarch_reloc_is_fatal
3297 (info, input_bfd, input_section, rel, howto,
3298 bfd_reloc_notsupported, is_undefweak, name,
3299 "Internal: '.rel.got' not represent"));
3303 outrel.r_offset = sec_addr (got) + off;
3304 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3305 outrel.r_addend = relocation; /* Link-time addr. */
3306 loongarch_elf_append_rela (output_bfd, s, &outrel);
3309 bfd_put_NN (output_bfd, relocation, got->contents + off);
3310 local_got_offsets[r_symndx] |= 1;
3317 case R_LARCH_SOP_PUSH_TLS_GOT:
3318 case R_LARCH_SOP_PUSH_TLS_GD:
3320 unresolved_reloc = false;
3321 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3324 bfd_vma got_off = 0;
3327 got_off = h->got.offset;
3332 got_off = local_got_offsets[r_symndx];
3333 local_got_offsets[r_symndx] |= 1;
3336 BFD_ASSERT (got_off != MINUS_ONE);
3339 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3340 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3341 ie_off = 2 * GOT_ENTRY_SIZE;
3343 if ((got_off & 1) == 0)
3345 Elf_Internal_Rela rela;
3346 asection *srel = htab->elf.srelgot;
3347 bfd_vma tls_block_off = 0;
3349 if (SYMBOL_REFERENCES_LOCAL (info, h))
3351 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3352 tls_block_off = relocation
3353 - elf_hash_table (info)->tls_sec->vma;
3356 if (tls_type & GOT_TLS_GD)
3358 rela.r_offset = sec_addr (got) + got_off;
3360 if (SYMBOL_REFERENCES_LOCAL (info, h))
3362 /* Local sym, used in exec, set module id 1. */
3363 if (bfd_link_executable (info))
3364 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3367 rela.r_info = ELFNN_R_INFO (0,
3368 R_LARCH_TLS_DTPMODNN);
3369 loongarch_elf_append_rela (output_bfd, srel, &rela);
3372 bfd_put_NN (output_bfd, tls_block_off,
3373 got->contents + got_off + GOT_ENTRY_SIZE);
3375 /* Dynamic resolved. */
3378 /* Dynamic relocate module id. */
3379 rela.r_info = ELFNN_R_INFO (h->dynindx,
3380 R_LARCH_TLS_DTPMODNN);
3381 loongarch_elf_append_rela (output_bfd, srel, &rela);
3383 /* Dynamic relocate offset of block. */
3384 rela.r_offset += GOT_ENTRY_SIZE;
3385 rela.r_info = ELFNN_R_INFO (h->dynindx,
3386 R_LARCH_TLS_DTPRELNN);
3387 loongarch_elf_append_rela (output_bfd, srel, &rela);
3390 if (tls_type & GOT_TLS_IE)
3392 rela.r_offset = sec_addr (got) + got_off + ie_off;
3393 if (SYMBOL_REFERENCES_LOCAL (info, h))
3395 /* Local sym, used in exec, set module id 1. */
3396 if (!bfd_link_executable (info))
3398 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3399 rela.r_addend = tls_block_off;
3400 loongarch_elf_append_rela (output_bfd, srel, &rela);
3403 bfd_put_NN (output_bfd, tls_block_off,
3404 got->contents + got_off + ie_off);
3406 /* Dynamic resolved. */
3409 /* Dynamic relocate offset of block. */
3410 rela.r_info = ELFNN_R_INFO (h->dynindx,
3411 R_LARCH_TLS_TPRELNN);
3413 loongarch_elf_append_rela (output_bfd, srel, &rela);
3418 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3422 /* New reloc types. */
3426 case R_LARCH_CALL36:
3427 unresolved_reloc = false;
3436 relocation += rel->r_addend;
3438 else if (resolved_dynly)
3441 && (h->plt.offset != MINUS_ONE
3442 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3443 && rel->r_addend == 0);
3444 if (h && h->plt.offset == MINUS_ONE
3445 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3448 relocation += rel->r_addend;
3451 relocation = sec_addr (plt) + h->plt.offset - pc;
3456 case R_LARCH_ABS_HI20:
3457 case R_LARCH_ABS_LO12:
3458 case R_LARCH_ABS64_LO20:
3459 case R_LARCH_ABS64_HI12:
3460 BFD_ASSERT (!is_pic);
3464 BFD_ASSERT (resolved_dynly);
3468 else if (resolved_to_const || resolved_local)
3470 relocation += rel->r_addend;
3472 else if (resolved_dynly)
3474 unresolved_reloc = false;
3475 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3476 && rel->r_addend == 0);
3477 relocation = sec_addr (plt) + h->plt.offset;
3482 case R_LARCH_PCREL20_S2:
3483 unresolved_reloc = false;
3484 if (h && h->plt.offset != MINUS_ONE)
3485 relocation = sec_addr (plt) + h->plt.offset;
3487 relocation += rel->r_addend;
3491 case R_LARCH_PCALA_HI20:
3492 unresolved_reloc = false;
3493 if (h && h->plt.offset != MINUS_ONE)
3494 relocation = sec_addr (plt) + h->plt.offset;
3496 relocation += rel->r_addend;
3498 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3502 case R_LARCH_TLS_LE_HI20_R:
3503 relocation -= elf_hash_table (info)->tls_sec->vma;
3505 RELOCATE_TLS_TP32_HI20 (relocation);
3509 case R_LARCH_PCALA_LO12:
3510 /* Not support if sym_addr in 2k page edge.
3511 pcalau12i pc_hi20 (sym_addr)
3512 ld.w/d pc_lo12 (sym_addr)
3513 ld.w/d pc_lo12 (sym_addr + x)
3515 can not calc correct address
3516 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3518 if (h && h->plt.offset != MINUS_ONE)
3519 relocation = sec_addr (plt) + h->plt.offset;
3521 relocation += rel->r_addend;
3523 /* For 2G jump, generate pcalau12i, jirl. */
3524 /* If use jirl, turns to R_LARCH_B16. */
3525 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3526 if ((insn & 0x4c000000) == 0x4c000000)
3528 relocation &= 0xfff;
3529 /* Signed extend. */
3530 relocation = (relocation ^ 0x800) - 0x800;
3532 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3533 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3537 case R_LARCH_PCALA64_LO20:
3538 case R_LARCH_PCALA64_HI12:
3539 if (h && h->plt.offset != MINUS_ONE)
3540 relocation = sec_addr (plt) + h->plt.offset;
3542 relocation += rel->r_addend;
3544 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3548 case R_LARCH_GOT_PC_HI20:
3549 case R_LARCH_GOT_HI20:
3550 /* Calc got offset. */
3552 unresolved_reloc = false;
3553 BFD_ASSERT (rel->r_addend == 0);
3555 bfd_vma got_off = 0;
3558 /* GOT ref or ifunc. */
3559 BFD_ASSERT (h->got.offset != MINUS_ONE
3560 || h->type == STT_GNU_IFUNC);
3562 got_off = h->got.offset & (~(bfd_vma)1);
3563 /* Hidden symbol not has got entry,
3564 * only got.plt entry so it is (plt - got). */
3565 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3568 if (htab->elf.splt != NULL)
3570 idx = (h->plt.offset - PLT_HEADER_SIZE)
3572 got_off = sec_addr (htab->elf.sgotplt)
3573 + GOTPLT_HEADER_SIZE
3574 + (idx * GOT_ENTRY_SIZE)
3575 - sec_addr (htab->elf.sgot);
3579 idx = h->plt.offset / PLT_ENTRY_SIZE;
3580 got_off = sec_addr (htab->elf.sgotplt)
3581 + (idx * GOT_ENTRY_SIZE)
3582 - sec_addr (htab->elf.sgot);
3586 if ((h->got.offset & 1) == 0)
3588 /* We need to generate a R_LARCH_RELATIVE reloc once
3589 * in loongarch_elf_finish_dynamic_symbol or now,
3590 * call finish_dyn && nopic
3591 * or !call finish_dyn && pic. */
3592 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3593 bfd_link_pic (info),
3595 && bfd_link_pic (info)
3596 && SYMBOL_REFERENCES_LOCAL (info, h))
3598 Elf_Internal_Rela rela;
3599 rela.r_offset = sec_addr (got) + got_off;
3600 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3601 rela.r_addend = relocation;
3602 loongarch_elf_append_rela (output_bfd,
3603 htab->elf.srelgot, &rela);
3606 bfd_put_NN (output_bfd, relocation,
3607 got->contents + got_off);
3612 BFD_ASSERT (local_got_offsets
3613 && local_got_offsets[r_symndx] != MINUS_ONE);
3615 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3616 if ((local_got_offsets[r_symndx] & 1) == 0)
3618 if (bfd_link_pic (info))
3620 Elf_Internal_Rela rela;
3621 rela.r_offset = sec_addr (got) + got_off;
3622 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3623 rela.r_addend = relocation;
3624 loongarch_elf_append_rela (output_bfd,
3625 htab->elf.srelgot, &rela);
3627 local_got_offsets[r_symndx] |= 1;
3629 bfd_put_NN (output_bfd, relocation, got->contents + got_off);
3632 relocation = got_off + sec_addr (got);
3635 if (r_type == R_LARCH_GOT_PC_HI20)
3636 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3640 case R_LARCH_GOT_PC_LO12:
3641 case R_LARCH_GOT64_PC_LO20:
3642 case R_LARCH_GOT64_PC_HI12:
3643 case R_LARCH_GOT_LO12:
3644 case R_LARCH_GOT64_LO20:
3645 case R_LARCH_GOT64_HI12:
3647 unresolved_reloc = false;
3650 got_off = h->got.offset & (~(bfd_vma)1);
3652 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3654 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3657 if (htab->elf.splt != NULL)
3658 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3660 idx = h->plt.offset / PLT_ENTRY_SIZE;
3662 got_off = sec_addr (htab->elf.sgotplt)
3663 + GOTPLT_HEADER_SIZE
3664 + (idx * GOT_ENTRY_SIZE)
3665 - sec_addr (htab->elf.sgot);
3668 relocation = got_off + sec_addr (got);
3671 if (r_type == R_LARCH_GOT64_PC_HI12
3672 || r_type == R_LARCH_GOT64_PC_LO20)
3673 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3677 case R_LARCH_TLS_LE_HI20:
3678 case R_LARCH_TLS_LE_LO12:
3679 case R_LARCH_TLS_LE_LO12_R:
3680 case R_LARCH_TLS_LE64_LO20:
3681 case R_LARCH_TLS_LE64_HI12:
3682 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3684 relocation -= elf_hash_table (info)->tls_sec->vma;
3687 /* TLS IE LD/GD process separately is troublesome.
3688 When a symbol is both ie and LD/GD, h->got.off |= 1
3689 make only one type be relocated. We must use
3690 h->got.offset |= 1 and h->got.offset |= 2
3691 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3692 (IE LD/GD and reusable GOT reloc) must change to
3693 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3695 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3697 case R_LARCH_TLS_IE_PC_HI20:
3698 case R_LARCH_TLS_IE_HI20:
3699 case R_LARCH_TLS_LD_PC_HI20:
3700 case R_LARCH_TLS_LD_HI20:
3701 case R_LARCH_TLS_GD_PC_HI20:
3702 case R_LARCH_TLS_GD_HI20:
3703 case R_LARCH_TLS_DESC_PC_HI20:
3704 case R_LARCH_TLS_DESC_HI20:
3705 case R_LARCH_TLS_LD_PCREL20_S2:
3706 case R_LARCH_TLS_GD_PCREL20_S2:
3707 case R_LARCH_TLS_DESC_PCREL20_S2:
3708 BFD_ASSERT (rel->r_addend == 0);
3709 unresolved_reloc = false;
3711 if (r_type == R_LARCH_TLS_IE_PC_HI20
3712 || r_type == R_LARCH_TLS_IE_HI20)
3715 if (r_type == R_LARCH_TLS_DESC_PC_HI20
3716 || r_type == R_LARCH_TLS_DESC_HI20
3717 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3720 bfd_vma got_off = 0;
3723 got_off = h->got.offset;
3728 got_off = local_got_offsets[r_symndx];
3729 local_got_offsets[r_symndx] |= 1;
3732 BFD_ASSERT (got_off != MINUS_ONE);
3734 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3736 /* If a tls variable is accessed in multiple ways, GD uses
3737 the first two slots of GOT, desc follows with two slots,
3738 and IE uses one slot at the end. */
3740 if (GOT_TLS_GD_BOTH_P (tls_type))
3741 desc_off = 2 * GOT_ENTRY_SIZE;
3744 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3745 ie_off = 4 * GOT_ENTRY_SIZE;
3746 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3747 ie_off = 2 * GOT_ENTRY_SIZE;
3749 if ((got_off & 1) == 0)
3751 Elf_Internal_Rela rela;
3752 asection *relgot = htab->elf.srelgot;
3753 bfd_vma tls_block_off = 0;
3755 if (SYMBOL_REFERENCES_LOCAL (info, h))
3757 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3758 tls_block_off = relocation
3759 - elf_hash_table (info)->tls_sec->vma;
3762 if (tls_type & GOT_TLS_GD)
3764 rela.r_offset = sec_addr (got) + got_off;
3766 if (SYMBOL_REFERENCES_LOCAL (info, h))
3768 /* Local sym, used in exec, set module id 1. */
3769 if (bfd_link_executable (info))
3770 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3773 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3774 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3777 bfd_put_NN (output_bfd, tls_block_off,
3778 got->contents + got_off + GOT_ENTRY_SIZE);
3780 /* Dynamic resolved. */
3783 /* Dynamic relocate module id. */
3784 rela.r_info = ELFNN_R_INFO (h->dynindx,
3785 R_LARCH_TLS_DTPMODNN);
3786 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3788 /* Dynamic relocate offset of block. */
3789 rela.r_offset += GOT_ENTRY_SIZE;
3790 rela.r_info = ELFNN_R_INFO (h->dynindx,
3791 R_LARCH_TLS_DTPRELNN);
3792 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3795 if (tls_type & GOT_TLS_GDESC)
3797 /* Unless it is a static link, DESC always emits a
3798 dynamic relocation. */
3799 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
3800 rela.r_offset = sec_addr (got) + got_off + desc_off;
3803 rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
3805 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
3806 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3807 bfd_put_NN (output_bfd, 0,
3808 got->contents + got_off + desc_off);
3810 if (tls_type & GOT_TLS_IE)
3812 rela.r_offset = sec_addr (got) + got_off + ie_off;
3813 if (SYMBOL_REFERENCES_LOCAL (info, h))
3815 /* Local sym, used in exec, set module id 1. */
3816 if (!bfd_link_executable (info))
3818 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3819 rela.r_addend = tls_block_off;
3820 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3823 bfd_put_NN (output_bfd, tls_block_off,
3824 got->contents + got_off + ie_off);
3826 /* Dynamic resolved. */
3829 /* Dynamic relocate offset of block. */
3830 rela.r_info = ELFNN_R_INFO (h->dynindx,
3831 R_LARCH_TLS_TPRELNN);
3833 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3837 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
3839 relocation += desc_off;
3841 relocation += ie_off;
3843 if (r_type == R_LARCH_TLS_LD_PC_HI20
3844 || r_type == R_LARCH_TLS_GD_PC_HI20
3845 || r_type == R_LARCH_TLS_IE_PC_HI20
3846 || r_type == R_LARCH_TLS_DESC_PC_HI20)
3847 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3848 else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
3849 || r_type == R_LARCH_TLS_GD_PCREL20_S2
3850 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3852 /* else {} ABS relocations. */
3855 case R_LARCH_TLS_DESC_PC_LO12:
3856 case R_LARCH_TLS_DESC64_PC_LO20:
3857 case R_LARCH_TLS_DESC64_PC_HI12:
3858 case R_LARCH_TLS_DESC_LO12:
3859 case R_LARCH_TLS_DESC64_LO20:
3860 case R_LARCH_TLS_DESC64_HI12:
3862 unresolved_reloc = false;
3865 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3867 relocation = sec_addr (got)
3868 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3870 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3871 /* Use both TLS_GD and TLS_DESC. */
3872 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
3873 relocation += 2 * GOT_ENTRY_SIZE;
3876 if (r_type == R_LARCH_TLS_DESC64_PC_LO20
3877 || r_type == R_LARCH_TLS_DESC64_PC_HI12)
3878 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3882 case R_LARCH_TLS_DESC_LD:
3883 case R_LARCH_TLS_DESC_CALL:
3884 unresolved_reloc = false;
3887 case R_LARCH_TLS_IE_PC_LO12:
3888 case R_LARCH_TLS_IE64_PC_LO20:
3889 case R_LARCH_TLS_IE64_PC_HI12:
3890 case R_LARCH_TLS_IE_LO12:
3891 case R_LARCH_TLS_IE64_LO20:
3892 case R_LARCH_TLS_IE64_HI12:
3893 unresolved_reloc = false;
3896 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3898 relocation = sec_addr (got)
3899 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3901 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3902 /* Use TLS_GD TLS_DESC and TLS_IE. */
3903 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3904 relocation += 4 * GOT_ENTRY_SIZE;
3905 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
3906 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3907 relocation += 2 * GOT_ENTRY_SIZE;
3909 if (r_type == R_LARCH_TLS_IE64_PC_LO20
3910 || r_type == R_LARCH_TLS_IE64_PC_HI12)
3911 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3917 r = bfd_reloc_continue;
3918 unresolved_reloc = false;
3930 /* 'unresolved_reloc' means we haven't done it yet.
3931 We need help of dynamic linker to fix this memory location up. */
3932 if (!unresolved_reloc)
3935 if (_bfd_elf_section_offset (output_bfd, info, input_section,
3936 rel->r_offset) == MINUS_ONE)
3937 /* WHY? May because it's invalid so skip checking.
3938 But why dynamic reloc a invalid section? */
3941 if (input_section->output_section->flags & SEC_DEBUGGING)
3943 fatal = (loongarch_reloc_is_fatal
3944 (info, input_bfd, input_section, rel, howto,
3945 bfd_reloc_dangerous, is_undefweak, name,
3946 "Seems dynamic linker not process "
3947 "sections 'SEC_DEBUGGING'."));
3952 if ((info->flags & DF_TEXTREL) == 0)
3953 if (input_section->output_section->flags & SEC_READONLY)
3954 info->flags |= DF_TEXTREL;
3961 loongarch_record_one_reloc (input_bfd, input_section, r_type,
3962 rel->r_offset, sym, h, rel->r_addend);
3964 if (r != bfd_reloc_continue)
3965 r = perform_relocation (rel, input_section, howto, relocation,
3966 input_bfd, contents);
3970 case bfd_reloc_dangerous:
3971 case bfd_reloc_continue:
3975 case bfd_reloc_overflow:
3976 /* Overflow value can't be filled in. */
3977 loongarch_dump_reloc_record (info->callbacks->info);
3978 info->callbacks->reloc_overflow
3979 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3980 input_bfd, input_section, rel->r_offset);
3983 case bfd_reloc_outofrange:
3984 /* Stack state incorrect. */
3985 loongarch_dump_reloc_record (info->callbacks->info);
3986 info->callbacks->info
3987 ("%X%H: Internal stack state is incorrect.\n"
3988 "Want to push to full stack or pop from empty stack?\n",
3989 input_bfd, input_section, rel->r_offset);
3992 case bfd_reloc_notsupported:
3993 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3994 input_section, rel->r_offset);
3998 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3999 input_section, rel->r_offset);
4010 loongarch_relax_delete_bytes (bfd *abfd,
4014 struct bfd_link_info *link_info)
4016 unsigned int i, symcount;
4017 bfd_vma toaddr = sec->size;
4018 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
4019 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4020 unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
4021 struct bfd_elf_section_data *data = elf_section_data (sec);
4022 bfd_byte *contents = data->this_hdr.contents;
4024 /* Actually delete the bytes. */
4026 memmove (contents + addr, contents + addr + count, toaddr - addr - count);
4028 /* Adjust the location of all of the relocs. Note that we need not
4029 adjust the addends, since all PC-relative references must be against
4030 symbols, which we will adjust below. */
4031 for (i = 0; i < sec->reloc_count; i++)
4032 if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
4033 data->relocs[i].r_offset -= count;
4035 /* Adjust the local symbols defined in this section. */
4036 for (i = 0; i < symtab_hdr->sh_info; i++)
4038 Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
4039 if (sym->st_shndx == sec_shndx)
4041 /* If the symbol is in the range of memory we just moved, we
4042 have to adjust its value. */
4043 if (sym->st_value > addr && sym->st_value <= toaddr)
4044 sym->st_value -= count;
4046 /* If the symbol *spans* the bytes we just deleted (i.e. its
4047 *end* is in the moved bytes but its *start* isn't), then we
4048 must adjust its size.
4050 This test needs to use the original value of st_value, otherwise
4051 we might accidentally decrease size when deleting bytes right
4052 before the symbol. But since deleted relocs can't span across
4053 symbols, we can't have both a st_value and a st_size decrease,
4054 so it is simpler to just use an else. */
4055 else if (sym->st_value <= addr
4056 && sym->st_value + sym->st_size > addr
4057 && sym->st_value + sym->st_size <= toaddr)
4058 sym->st_size -= count;
4062 /* Now adjust the global symbols defined in this section. */
4063 symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
4064 - symtab_hdr->sh_info);
4066 for (i = 0; i < symcount; i++)
4068 struct elf_link_hash_entry *sym_hash = sym_hashes[i];
4070 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4071 containing the definition of __wrap_SYMBOL, includes a direct
4072 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4073 the same symbol (which is __wrap_SYMBOL), but still exist as two
4074 different symbols in 'sym_hashes', we don't want to adjust
4075 the global symbol __wrap_SYMBOL twice.
4077 The same problem occurs with symbols that are versioned_hidden, as
4078 foo becomes an alias for foo@BAR, and hence they need the same
4080 if (link_info->wrap_hash != NULL
4081 || sym_hash->versioned != unversioned)
4083 struct elf_link_hash_entry **cur_sym_hashes;
4085 /* Loop only over the symbols which have already been checked. */
4086 for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
4089 /* If the current symbol is identical to 'sym_hash', that means
4090 the symbol was already adjusted (or at least checked). */
4091 if (*cur_sym_hashes == sym_hash)
4094 /* Don't adjust the symbol again. */
4095 if (cur_sym_hashes < &sym_hashes[i])
4099 if ((sym_hash->root.type == bfd_link_hash_defined
4100 || sym_hash->root.type == bfd_link_hash_defweak)
4101 && sym_hash->root.u.def.section == sec)
4103 /* As above, adjust the value if needed. */
4104 if (sym_hash->root.u.def.value > addr
4105 && sym_hash->root.u.def.value <= toaddr)
4106 sym_hash->root.u.def.value -= count;
4108 /* As above, adjust the size if needed. */
4109 else if (sym_hash->root.u.def.value <= addr
4110 && sym_hash->root.u.def.value + sym_hash->size > addr
4111 && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
4112 sym_hash->size -= count;
4118 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4119 there are three situations in which an assembly instruction sequence needs to
4121 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4124 in this case, the rd register in the st.{w/d} instruction does not store the
4125 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4126 symbolic address, and then obtains the rd + le_lo12_r address through the
4127 st.w instruction feature.
4128 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4130 before relax: after relax:
4132 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4133 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4134 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4137 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4139 before relax: after relax:
4141 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4142 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4143 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4146 in this case,the rs register in addi.{w/d} stores the full address of the tls
4147 symbol (tp + le_hi20_r + le_lo12_r).
4149 before relax: after relax:
4151 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4152 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4153 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4156 loongarch_relax_tls_le (bfd *abfd, asection *sec,
4157 Elf_Internal_Rela *rel,
4158 struct bfd_link_info *link_info,
4161 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4162 uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
4163 static uint32_t insn_rj,insn_rd;
4164 symval = symval - elf_hash_table (link_info)->tls_sec->vma;
4165 /* Whether the symbol offset is in the interval (offset < 0x800). */
4166 if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
4168 switch (ELFNN_R_TYPE (rel->r_info))
4170 case R_LARCH_TLS_LE_HI20_R:
4171 case R_LARCH_TLS_LE_ADD_R:
4173 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4174 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
4176 case R_LARCH_TLS_LE_LO12_R:
4177 /* Change rj to $tp. */
4179 /* Get rd register. */
4180 insn_rd = insn & 0x1f;
4181 /* Write symbol offset. */
4183 /* Writes the modified instruction. */
4184 insn = insn & 0xffc00000;
4185 insn = insn | symval | insn_rj | insn_rd;
4186 bfd_put (32, abfd, insn, contents + rel->r_offset);
4195 /* Relax pcalau12i,addi.d => pcaddi. */
4197 loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
4198 Elf_Internal_Rela *rel_hi, bfd_vma symval,
4199 struct bfd_link_info *info, bool *again,
4200 bfd_vma max_alignment)
4202 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4203 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4204 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4205 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4206 uint32_t rd = pca & 0x1f;
4208 /* This section's output_offset need to subtract the bytes of instructions
4209 relaxed by the previous sections, so it needs to be updated beforehand.
4210 size_input_section already took care of updating it after relaxation,
4211 so we additionally update once here. */
4212 sec->output_offset = sec->output_section->size;
4213 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4215 /* If pc and symbol not in the same segment, add/sub segment alignment.
4216 FIXME: if there are multiple readonly segments? How to determine if
4217 two sections are in the same segment. */
4218 if (!(sym_sec->flags & SEC_READONLY))
4220 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4223 pc -= max_alignment;
4224 else if (symval < pc)
4225 pc += max_alignment;
4229 pc -= max_alignment;
4230 else if (symval < pc)
4231 pc += max_alignment;
4233 const uint32_t addi_d = 0x02c00000;
4234 const uint32_t pcaddi = 0x18000000;
4236 /* Is pcalau12i + addi.d insns? */
4237 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
4238 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4239 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4240 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4241 || ((add & addi_d) != addi_d)
4242 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4243 || ((add & 0x1f) != rd)
4244 || (((add >> 5) & 0x1f) != rd)
4245 /* Can be relaxed to pcaddi? */
4246 || (symval & 0x3) /* 4 bytes align. */
4247 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4248 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4251 /* Continue next relax trip. */
4255 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4257 /* Adjust relocations. */
4258 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4259 R_LARCH_PCREL20_S2);
4260 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4262 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4267 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
4269 loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
4270 Elf_Internal_Rela *rel_hi)
4272 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4273 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4274 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4275 uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
4276 uint32_t rd = pca & 0x1f;
4277 const uint32_t ld_d = 0x28c00000;
4278 uint32_t addi_d = 0x02c00000;
4280 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
4281 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4282 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4283 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4284 || ((ld & 0x1f) != rd)
4285 || (((ld >> 5) & 0x1f) != rd)
4286 || ((ld & ld_d) != ld_d))
4289 addi_d = addi_d | (rd << 5) | rd;
4290 bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
4292 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4293 R_LARCH_PCALA_HI20);
4294 rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
4295 R_LARCH_PCALA_LO12);
4299 /* Called by after_allocation to set the information of data segment
4303 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
4304 int *data_segment_phase)
4306 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4307 htab->data_segment_phase = data_segment_phase;
4310 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4311 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
4313 loongarch_relax_align (bfd *abfd, asection *sec,
4315 struct bfd_link_info *link_info,
4316 Elf_Internal_Rela *rel,
4319 bfd_vma addend, max = 0, alignment = 1;
4321 int sym_index = ELFNN_R_SYM (rel->r_info);
4324 alignment = 1 << (rel->r_addend & 0xff);
4325 max = rel->r_addend >> 8;
4328 alignment = rel->r_addend + 4;
4330 addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
4331 symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */
4332 bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
4333 bfd_vma need_nop_bytes = aligned_addr - symval; /* */
4335 /* Make sure there are enough NOPs to actually achieve the alignment. */
4336 if (addend < need_nop_bytes)
4339 (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
4340 "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
4341 abfd, sym_sec, (uint64_t) rel->r_offset,
4342 (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
4343 bfd_set_error (bfd_error_bad_value);
4347 /* Once we've handled an R_LARCH_ALIGN in a section,
4348 we can't relax anything else in this section. */
4349 sec->sec_flg0 = true;
4350 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4352 /* If skipping more bytes than the specified maximum,
4353 then the alignment is not done at all and delete all NOPs. */
4354 if (max > 0 && need_nop_bytes > max)
4355 return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
4358 /* If the number of NOPs is already correct, there's nothing to do. */
4359 if (need_nop_bytes == addend)
4362 /* Delete the excess NOPs. */
4363 return loongarch_relax_delete_bytes (abfd, sec,
4364 rel->r_offset + need_nop_bytes,
4365 addend - need_nop_bytes, link_info);
4368 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
4370 loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
4371 Elf_Internal_Rela *rel_hi, bfd_vma symval,
4372 struct bfd_link_info *info, bool *again,
4373 bfd_vma max_alignment)
4375 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4376 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4377 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4378 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4379 uint32_t rd = pca & 0x1f;
4381 /* This section's output_offset need to subtract the bytes of instructions
4382 relaxed by the previous sections, so it needs to be updated beforehand.
4383 size_input_section already took care of updating it after relaxation,
4384 so we additionally update once here. */
4385 sec->output_offset = sec->output_section->size;
4386 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4388 /* If pc and symbol not in the same segment, add/sub segment alignment.
4389 FIXME: if there are multiple readonly segments? */
4390 if (!(sym_sec->flags & SEC_READONLY))
4392 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4395 pc -= max_alignment;
4396 else if (symval < pc)
4397 pc += max_alignment;
4401 pc -= max_alignment;
4402 else if (symval < pc)
4403 pc += max_alignment;
4405 const uint32_t addi_d = 0x02c00000;
4406 const uint32_t pcaddi = 0x18000000;
4408 /* Is pcalau12i + addi.d insns? */
4409 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
4410 && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
4411 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4412 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4413 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4414 || ((add & addi_d) != addi_d)
4415 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4416 || ((add & 0x1f) != rd)
4417 || (((add >> 5) & 0x1f) != rd)
4418 /* Can be relaxed to pcaddi? */
4419 || (symval & 0x3) /* 4 bytes align. */
4420 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4421 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4424 /* Continue next relax trip. */
4428 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4430 /* Adjust relocations. */
4431 switch (ELFNN_R_TYPE (rel_hi->r_info))
4433 case R_LARCH_TLS_LD_PC_HI20:
4434 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4435 R_LARCH_TLS_LD_PCREL20_S2);
4437 case R_LARCH_TLS_GD_PC_HI20:
4438 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4439 R_LARCH_TLS_GD_PCREL20_S2);
4441 case R_LARCH_TLS_DESC_PC_HI20:
4442 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4443 R_LARCH_TLS_DESC_PCREL20_S2);
4448 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4450 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4455 /* Traverse all output sections and return the max alignment. */
4458 loongarch_get_max_alignment (asection *sec)
4461 unsigned int max_alignment_power = 0;
4463 for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
4464 if (o->alignment_power > max_alignment_power)
4465 max_alignment_power = o->alignment_power;
4467 return (bfd_vma) 1 << max_alignment_power;
4471 loongarch_elf_relax_section (bfd *abfd, asection *sec,
4472 struct bfd_link_info *info,
4475 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4476 struct bfd_elf_section_data *data = elf_section_data (sec);
4477 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
4478 Elf_Internal_Rela *relocs;
4480 bfd_vma max_alignment = 0;
4482 if (bfd_link_relocatable (info)
4484 || (sec->flags & SEC_RELOC) == 0
4485 || sec->reloc_count == 0
4486 || (info->disable_target_specific_optimizations
4487 && info->relax_pass == 0)
4488 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4489 and defined in ld/ldexp.h. */
4490 || *(htab->data_segment_phase) == 4)
4494 relocs = data->relocs;
4495 else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
4496 info->keep_memory)))
4499 if (!data->this_hdr.contents
4500 && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
4503 if (symtab_hdr->sh_info != 0
4504 && !symtab_hdr->contents
4505 && !(symtab_hdr->contents =
4506 (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
4507 symtab_hdr->sh_info,
4508 0, NULL, NULL, NULL)))
4511 data->relocs = relocs;
4513 /* Estimate the maximum alignment for all output sections once time
4514 should be enough. */
4515 max_alignment = htab->max_alignment;
4516 if (max_alignment == (bfd_vma) -1)
4518 max_alignment = loongarch_get_max_alignment (sec);
4519 htab->max_alignment = max_alignment;
4522 for (unsigned int i = 0; i < sec->reloc_count; i++)
4527 bool local_got = false;
4528 Elf_Internal_Rela *rel = relocs + i;
4529 struct elf_link_hash_entry *h = NULL;
4530 unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
4531 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
4533 /* Four kind of relocations:
4534 Normal: symval is the symbol address.
4535 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4536 added by this relocation, and then adds 4 more.
4537 R_LARCH_CALL36: symval is the symbol address for local symbols,
4538 or the PLT entry address of the symbol. (Todo)
4539 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4541 if (r_symndx < symtab_hdr->sh_info)
4543 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
4545 if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4548 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4549 || R_LARCH_TLS_GD_PC_HI20 == r_type
4550 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4552 if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
4556 sym_sec = htab->elf.sgot;
4557 symval = elf_local_got_offsets (abfd)[r_symndx];
4558 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4560 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4561 && GOT_TLS_GD_BOTH_P (tls_type))
4562 symval += 2 * GOT_ENTRY_SIZE;
4565 else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
4568 symval = rel->r_offset;
4572 sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
4573 symval = sym->st_value;
4575 symtype = ELF_ST_TYPE (sym->st_info);
4579 r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
4580 h = elf_sym_hashes (abfd)[r_symndx];
4582 while (h->root.type == bfd_link_hash_indirect
4583 || h->root.type == bfd_link_hash_warning)
4584 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4586 /* Disable the relaxation for ifunc. */
4587 if (h != NULL && h->type == STT_GNU_IFUNC)
4590 /* The GOT entry of tls symbols must in current execute file or
4592 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4593 || R_LARCH_TLS_GD_PC_HI20 == r_type
4594 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4596 if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
4600 sym_sec = htab->elf.sgot;
4601 symval = h->got.offset;
4602 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4604 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4605 && GOT_TLS_GD_BOTH_P (tls_type))
4606 symval += 2 * GOT_ENTRY_SIZE;
4609 else if ((h->root.type == bfd_link_hash_defined
4610 || h->root.type == bfd_link_hash_defweak)
4611 && h->root.u.def.section != NULL
4612 && h->root.u.def.section->output_section != NULL)
4614 symval = h->root.u.def.value;
4615 sym_sec = h->root.u.def.section;
4620 if (h && SYMBOL_REFERENCES_LOCAL (info, h))
4625 if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
4626 && (sym_sec->flags & SEC_MERGE))
4628 if (symtype == STT_SECTION)
4629 symval += rel->r_addend;
4631 symval = _bfd_merged_section_offset (abfd, &sym_sec,
4632 elf_section_data (sym_sec)->sec_info,
4635 if (symtype != STT_SECTION)
4636 symval += rel->r_addend;
4638 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
4640 If r_symndx is 0, alignmeng-4 is r_addend.
4641 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
4642 else if (R_LARCH_ALIGN == r_type)
4644 symval += ((1 << (rel->r_addend & 0xff)) - 4);
4646 symval += rel->r_addend;
4648 symval += rel->r_addend;
4650 symval += sec_addr (sym_sec);
4655 if (1 == info->relax_pass)
4656 loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
4659 case R_LARCH_DELETE:
4660 if (1 == info->relax_pass)
4662 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4663 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4667 case R_LARCH_TLS_LE_HI20_R:
4668 case R_LARCH_TLS_LE_LO12_R:
4669 case R_LARCH_TLS_LE_ADD_R:
4670 if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
4671 loongarch_relax_tls_le (abfd, sec, rel, info, symval);
4674 case R_LARCH_PCALA_HI20:
4675 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4676 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4677 info, again, max_alignment);
4680 case R_LARCH_GOT_PC_HI20:
4681 if (local_got && 0 == info->relax_pass
4682 && (i + 4) <= sec->reloc_count)
4684 if (loongarch_relax_pcala_ld (abfd, sec, rel))
4685 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4686 info, again, max_alignment);
4690 case R_LARCH_TLS_LD_PC_HI20:
4691 case R_LARCH_TLS_GD_PC_HI20:
4692 case R_LARCH_TLS_DESC_PC_HI20:
4693 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4694 loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4695 info, again, max_alignment);
4706 /* Finish up dynamic symbol handling. We set the contents of various
4707 dynamic sections here. */
4710 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
4711 struct bfd_link_info *info,
4712 struct elf_link_hash_entry *h,
4713 Elf_Internal_Sym *sym)
4715 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4716 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4718 if (h->plt.offset != MINUS_ONE)
4721 asection *plt, *gotplt, *relplt;
4722 bfd_vma got_address;
4723 uint32_t plt_entry[PLT_ENTRY_INSNS];
4725 Elf_Internal_Rela rela;
4729 BFD_ASSERT ((h->type == STT_GNU_IFUNC
4730 && SYMBOL_REFERENCES_LOCAL (info, h))
4731 || h->dynindx != -1);
4733 plt = htab->elf.splt;
4734 gotplt = htab->elf.sgotplt;
4735 if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4736 relplt = htab->elf.srelgot;
4738 relplt = htab->elf.srelplt;
4739 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4741 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4743 else /* if (htab->elf.iplt) */
4745 BFD_ASSERT (h->type == STT_GNU_IFUNC
4746 && SYMBOL_REFERENCES_LOCAL (info, h));
4748 plt = htab->elf.iplt;
4749 gotplt = htab->elf.igotplt;
4750 relplt = htab->elf.irelplt;
4751 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
4752 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4755 /* Find out where the .plt entry should go. */
4756 loc = plt->contents + h->plt.offset;
4758 /* Fill in the PLT entry itself. */
4759 if (!loongarch_make_plt_entry (got_address,
4760 sec_addr (plt) + h->plt.offset,
4764 for (i = 0; i < PLT_ENTRY_INSNS; i++)
4765 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4767 /* Fill in the initial value of the got.plt entry. */
4768 loc = gotplt->contents + (got_address - sec_addr (gotplt));
4769 bfd_put_NN (output_bfd, sec_addr (plt), loc);
4771 rela.r_offset = got_address;
4773 /* TRUE if this is a PLT reference to a local IFUNC. */
4774 if (PLT_LOCAL_IFUNC_P (info, h)
4775 && (relplt == htab->elf.srelgot
4776 || relplt == htab->elf.irelplt))
4778 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4779 rela.r_addend = (h->root.u.def.value
4780 + h->root.u.def.section->output_section->vma
4781 + h->root.u.def.section->output_offset);
4783 loongarch_elf_append_rela (output_bfd, relplt, &rela);
4787 /* Fill in the entry in the rela.plt section. */
4788 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4790 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
4791 bed->s->swap_reloca_out (output_bfd, &rela, loc);
4794 if (!h->def_regular)
4796 /* Mark the symbol as undefined, rather than as defined in
4797 the .plt section. Leave the value alone. */
4798 sym->st_shndx = SHN_UNDEF;
4799 /* If the symbol is weak, we do need to clear the value.
4800 Otherwise, the PLT entry would provide a definition for
4801 the symbol even if the symbol wasn't defined anywhere,
4802 and so the symbol would never be NULL. */
4803 if (!h->ref_regular_nonweak)
4808 if (h->got.offset != MINUS_ONE
4809 /* TLS got entry have been handled in elf_relocate_section. */
4810 && !(loongarch_elf_hash_entry (h)->tls_type
4811 & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
4812 /* Have allocated got entry but not allocated rela before. */
4813 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4815 asection *sgot, *srela;
4816 Elf_Internal_Rela rela;
4817 bfd_vma off = h->got.offset & ~(bfd_vma)1;
4819 /* This symbol has an entry in the GOT. Set it up. */
4820 sgot = htab->elf.sgot;
4821 srela = htab->elf.srelgot;
4822 BFD_ASSERT (sgot && srela);
4824 rela.r_offset = sec_addr (sgot) + off;
4827 && h->type == STT_GNU_IFUNC)
4829 if(h->plt.offset == MINUS_ONE)
4831 if (htab->elf.splt == NULL)
4832 srela = htab->elf.irelplt;
4834 if (SYMBOL_REFERENCES_LOCAL (info, h))
4836 asection *sec = h->root.u.def.section;
4837 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4838 rela.r_addend = h->root.u.def.value + sec->output_section->vma
4839 + sec->output_offset;
4840 bfd_put_NN (output_bfd, 0, sgot->contents + off);
4844 BFD_ASSERT (h->dynindx != -1);
4845 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4847 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
4850 else if(bfd_link_pic (info))
4852 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4854 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
4859 /* For non-shared object, we can't use .got.plt, which
4860 contains the real function address if we need pointer
4861 equality. We load the GOT entry with the PLT entry. */
4862 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4863 bfd_put_NN (output_bfd,
4864 (plt->output_section->vma
4865 + plt->output_offset
4867 sgot->contents + off);
4871 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4873 asection *sec = h->root.u.def.section;
4874 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4875 rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4876 + sec->output_offset);
4880 BFD_ASSERT (h->dynindx != -1);
4881 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4885 loongarch_elf_append_rela (output_bfd, srela, &rela);
4888 /* Mark some specially defined symbols as absolute. */
4889 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4890 sym->st_shndx = SHN_ABS;
4895 /* Finish up the dynamic sections. */
4898 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4901 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4902 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4903 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4904 bfd_byte *dyncon, *dynconend;
4906 dynconend = sdyn->contents + sdyn->size;
4907 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4909 Elf_Internal_Dyn dyn;
4913 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4918 s = htab->elf.sgotplt;
4919 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4922 s = htab->elf.srelplt;
4923 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4926 s = htab->elf.srelplt;
4927 dyn.d_un.d_val = s->size;
4930 if ((info->flags & DF_TEXTREL) == 0)
4934 if ((info->flags & DF_TEXTREL) == 0)
4935 dyn.d_un.d_val &= ~DF_TEXTREL;
4939 skipped_size += dynsize;
4941 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4943 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
4944 memset (dyncon - skipped_size, 0, skipped_size);
4948 /* Finish up local dynamic symbol handling. We set the contents of
4949 various dynamic sections here. */
4952 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4954 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4955 struct bfd_link_info *info = (struct bfd_link_info *) inf;
4957 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4960 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4961 this function is called before elf_link_sort_relocs.
4962 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4963 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
4966 elf_loongarch_output_arch_local_syms
4967 (bfd *output_bfd ATTRIBUTE_UNUSED,
4968 struct bfd_link_info *info,
4969 void *flaginfo ATTRIBUTE_UNUSED,
4970 int (*func) (void *, const char *,
4973 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4975 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4979 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4980 htab_traverse (htab->loc_hash_table,
4981 elfNN_loongarch_finish_local_dynamic_symbol,
4988 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
4989 struct bfd_link_info *info)
4992 asection *sdyn, *plt, *gotplt = NULL;
4993 struct loongarch_elf_link_hash_table *htab;
4995 htab = loongarch_elf_hash_table (info);
4997 dynobj = htab->elf.dynobj;
4998 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
5000 if (elf_hash_table (info)->dynamic_sections_created)
5002 BFD_ASSERT (htab->elf.splt && sdyn);
5004 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
5008 plt = htab->elf.splt;
5009 gotplt = htab->elf.sgotplt;
5011 if (plt && 0 < plt->size)
5014 uint32_t plt_header[PLT_HEADER_INSNS];
5015 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
5019 for (i = 0; i < PLT_HEADER_INSNS; i++)
5020 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
5022 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
5026 if (htab->elf.sgotplt)
5028 asection *output_section = htab->elf.sgotplt->output_section;
5030 if (bfd_is_abs_section (output_section))
5032 _bfd_error_handler (_("discarded output section: `%pA'"),
5037 if (0 < htab->elf.sgotplt->size)
5039 /* Write the first two entries in .got.plt, needed for the dynamic
5041 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
5043 bfd_put_NN (output_bfd, (bfd_vma) 0,
5044 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
5047 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5052 asection *output_section = htab->elf.sgot->output_section;
5054 if (0 < htab->elf.sgot->size)
5056 /* Set the first entry in the global offset table to the address of
5057 the dynamic section. */
5058 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
5059 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
5062 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5068 /* Return address for Ith PLT stub in section PLT, for relocation REL
5069 or (bfd_vma) -1 if it should not be included. */
5072 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
5073 const arelent *rel ATTRIBUTE_UNUSED)
5075 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
5078 static enum elf_reloc_type_class
5079 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5080 const asection *rel_sec ATTRIBUTE_UNUSED,
5081 const Elf_Internal_Rela *rela)
5083 struct loongarch_elf_link_hash_table *htab;
5084 htab = loongarch_elf_hash_table (info);
5086 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
5088 /* Check relocation against STT_GNU_IFUNC symbol if there are
5090 bfd *abfd = info->output_bfd;
5091 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5092 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
5093 if (r_symndx != STN_UNDEF)
5095 Elf_Internal_Sym sym;
5096 if (!bed->s->swap_symbol_in (abfd,
5097 htab->elf.dynsym->contents
5098 + r_symndx * bed->s->sizeof_sym,
5101 /* xgettext:c-format */
5102 _bfd_error_handler (_("%pB symbol number %lu references"
5103 " nonexistent SHT_SYMTAB_SHNDX section"),
5105 /* Ideally an error class should be returned here. */
5107 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5108 return reloc_class_ifunc;
5112 switch (ELFNN_R_TYPE (rela->r_info))
5114 case R_LARCH_IRELATIVE:
5115 return reloc_class_ifunc;
5116 case R_LARCH_RELATIVE:
5117 return reloc_class_relative;
5118 case R_LARCH_JUMP_SLOT:
5119 return reloc_class_plt;
5121 return reloc_class_copy;
5123 return reloc_class_normal;
5127 /* Copy the extra info we tack onto an elf_link_hash_entry. */
5130 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
5131 struct elf_link_hash_entry *dir,
5132 struct elf_link_hash_entry *ind)
5134 struct elf_link_hash_entry *edir, *eind;
5139 if (eind->dyn_relocs != NULL)
5141 if (edir->dyn_relocs != NULL)
5143 struct elf_dyn_relocs **pp;
5144 struct elf_dyn_relocs *p;
5146 /* Add reloc counts against the indirect sym to the direct sym
5147 list. Merge any entries against the same section. */
5148 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
5150 struct elf_dyn_relocs *q;
5152 for (q = edir->dyn_relocs; q != NULL; q = q->next)
5153 if (q->sec == p->sec)
5155 q->pc_count += p->pc_count;
5156 q->count += p->count;
5163 *pp = edir->dyn_relocs;
5166 edir->dyn_relocs = eind->dyn_relocs;
5167 eind->dyn_relocs = NULL;
5170 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
5172 loongarch_elf_hash_entry(edir)->tls_type
5173 = loongarch_elf_hash_entry(eind)->tls_type;
5174 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
5176 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
5179 #define PRSTATUS_SIZE 0x1d8
5180 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
5181 #define PRSTATUS_OFFSET_PR_PID 0x20
5182 #define ELF_GREGSET_T_SIZE 0x168
5183 #define PRSTATUS_OFFSET_PR_REG 0x70
5185 /* Support for core dump NOTE sections. */
5188 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
5190 switch (note->descsz)
5195 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
5198 elf_tdata (abfd)->core->signal =
5199 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
5202 elf_tdata (abfd)->core->lwpid =
5203 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
5207 /* Make a ".reg/999" section. */
5208 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
5210 + PRSTATUS_OFFSET_PR_REG);
5213 #define PRPSINFO_SIZE 0x88
5214 #define PRPSINFO_OFFSET_PR_PID 0x18
5215 #define PRPSINFO_OFFSET_PR_FNAME 0x28
5216 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
5217 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
5218 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
5221 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
5223 switch (note->descsz)
5228 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
5231 elf_tdata (abfd)->core->pid =
5232 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
5235 elf_tdata (abfd)->core->program =
5236 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
5237 PRPSINFO_SIZEOF_PR_FNAME);
5240 elf_tdata (abfd)->core->command =
5241 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
5242 PRPSINFO_SIZEOF_PR_PS_ARGS);
5246 /* Note that for some reason, a spurious space is tacked
5247 onto the end of the args in some (at least one anyway)
5248 implementations, so strip it off if it exists. */
5251 char *command = elf_tdata (abfd)->core->command;
5252 int n = strlen (command);
5254 if (0 < n && command[n - 1] == ' ')
5255 command[n - 1] = '\0';
5261 /* Set the right mach type. */
5263 loongarch_elf_object_p (bfd *abfd)
5265 /* There are only two mach types in LoongArch currently. */
5266 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
5267 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
5269 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
5274 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
5275 Elf_Internal_Rela *rel,
5276 struct elf_link_hash_entry *h,
5277 Elf_Internal_Sym *sym)
5280 switch (ELFNN_R_TYPE (rel->r_info))
5282 case R_LARCH_GNU_VTINHERIT:
5283 case R_LARCH_GNU_VTENTRY:
5287 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
5290 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
5291 executable PLT slots where the executable never takes the address of those
5292 functions, the function symbols are not added to the hash table. */
5295 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
5297 if (h->plt.offset != (bfd_vma) -1
5299 && !h->pointer_equality_needed)
5302 return _bfd_elf_hash_symbol (h);
5305 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
5306 #define TARGET_LITTLE_NAME "elfNN-loongarch"
5307 #define ELF_ARCH bfd_arch_loongarch
5308 #define ELF_TARGET_ID LARCH_ELF_DATA
5309 #define ELF_MACHINE_CODE EM_LOONGARCH
5310 #define ELF_MAXPAGESIZE 0x4000
5311 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5312 #define bfd_elfNN_bfd_link_hash_table_create \
5313 loongarch_elf_link_hash_table_create
5314 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5315 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
5316 #define elf_info_to_howto loongarch_info_to_howto_rela
5317 #define bfd_elfNN_bfd_merge_private_bfd_data \
5318 elfNN_loongarch_merge_private_bfd_data
5320 #define elf_backend_reloc_type_class loongarch_reloc_type_class
5321 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5322 #define elf_backend_create_dynamic_sections \
5323 loongarch_elf_create_dynamic_sections
5324 #define elf_backend_check_relocs loongarch_elf_check_relocs
5325 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5326 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
5327 #define elf_backend_relocate_section loongarch_elf_relocate_section
5328 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
5329 #define elf_backend_output_arch_local_syms \
5330 elf_loongarch_output_arch_local_syms
5331 #define elf_backend_finish_dynamic_sections \
5332 loongarch_elf_finish_dynamic_sections
5333 #define elf_backend_object_p loongarch_elf_object_p
5334 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5335 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5336 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5337 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
5338 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
5339 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
5341 #define elf_backend_dtrel_excludes_plt 1
5343 #include "elfNN-target.h"