Update release README with new version numbers
[binutils-gdb.git] / bfd / elfnn-loongarch.c
blob5b44901b9e098e86e4c5a0faa86c84ffa2c42612
1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2022 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/>. */
21 #include "ansidecl.h"
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #define ARCH_SIZE NN
26 #include "elf-bfd.h"
27 #include "objalloc.h"
28 #include "elf/loongarch.h"
29 #include "elfxx-loongarch.h"
31 static bool
32 loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
33 Elf_Internal_Rela *dst)
35 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
36 ELFNN_R_TYPE (dst->r_info));
37 return cache_ptr->howto != NULL;
40 /* LoongArch ELF linker hash entry. */
41 struct loongarch_elf_link_hash_entry
43 struct elf_link_hash_entry elf;
45 #define GOT_UNKNOWN 0
46 #define GOT_NORMAL 1
47 #define GOT_TLS_GD 2
48 #define GOT_TLS_IE 4
49 #define GOT_TLS_LE 8
50 char tls_type;
53 #define loongarch_elf_hash_entry(ent) \
54 ((struct loongarch_elf_link_hash_entry *) (ent))
56 struct _bfd_loongarch_elf_obj_tdata
58 struct elf_obj_tdata root;
60 /* The tls_type for each local got entry. */
61 char *local_got_tls_type;
64 #define _bfd_loongarch_elf_tdata(abfd) \
65 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
67 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
68 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
70 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
71 (*((h) != NULL \
72 ? &loongarch_elf_hash_entry (h)->tls_type \
73 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
75 #define is_loongarch_elf(bfd) \
76 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
77 && elf_tdata (bfd) != NULL \
78 && elf_object_id (bfd) == LARCH_ELF_DATA)
80 struct loongarch_elf_link_hash_table
82 struct elf_link_hash_table elf;
84 /* Short-cuts to get to dynamic linker sections. */
85 asection *sdyntdata;
87 /* Small local sym to section mapping cache. */
88 struct sym_cache sym_cache;
90 /* Used by local STT_GNU_IFUNC symbols. */
91 htab_t loc_hash_table;
92 void *loc_hash_memory;
94 /* The max alignment of output sections. */
95 bfd_vma max_alignment;
98 /* Get the LoongArch ELF linker hash table from a link_info structure. */
99 #define loongarch_elf_hash_table(p) \
100 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
101 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
102 : NULL)
104 #define MINUS_ONE ((bfd_vma) 0 - 1)
106 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
108 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
109 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
111 #define PLT_HEADER_INSNS 8
112 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
114 #define PLT_ENTRY_INSNS 4
115 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
117 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
119 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
121 #define elf_backend_want_got_plt 1
123 #define elf_backend_plt_readonly 1
125 #define elf_backend_want_plt_sym 0
126 #define elf_backend_plt_alignment 4
127 #define elf_backend_can_gc_sections 1
128 #define elf_backend_want_got_sym 1
130 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
132 #define elf_backend_want_dynrelro 1
134 /* Generate a PLT header. */
136 static bool
137 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
138 uint32_t *entry)
140 bfd_vma pcrel = got_plt_addr - plt_header_addr;
141 bfd_vma hi, lo;
143 if (pcrel + 0x80000800 > 0xffffffff)
145 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
146 bfd_set_error (bfd_error_bad_value);
147 return false;
149 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
150 lo = pcrel & 0xfff;
152 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
153 sub.[wd] $t1, $t1, $t3
154 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
155 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
156 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
157 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
158 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
159 jirl $r0, $t3, 0 */
161 if (GOT_ENTRY_SIZE == 8)
163 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
164 entry[1] = 0x0011bdad;
165 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
166 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
167 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
168 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
169 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
170 entry[7] = 0x4c0001e0;
172 else
174 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
175 entry[1] = 0x00113dad;
176 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
177 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
178 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
179 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
180 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
181 entry[7] = 0x4c0001e0;
183 return true;
186 /* Generate a PLT entry. */
188 static bool
189 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
190 uint32_t *entry)
192 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
193 bfd_vma hi, lo;
195 if (pcrel + 0x80000800 > 0xffffffff)
197 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
198 bfd_set_error (bfd_error_bad_value);
199 return false;
201 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
202 lo = pcrel & 0xfff;
204 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
205 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
206 | (lo & 0xfff) << 10);
207 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
208 entry[3] = 0x03400000; /* nop */
210 return true;
213 /* Create an entry in an LoongArch ELF linker hash table. */
215 static struct bfd_hash_entry *
216 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
217 const char *string)
219 struct loongarch_elf_link_hash_entry *eh;
221 /* Allocate the structure if it has not already been allocated by a
222 subclass. */
223 if (entry == NULL)
225 entry = bfd_hash_allocate (table, sizeof (*eh));
226 if (entry == NULL)
227 return entry;
230 /* Call the allocation method of the superclass. */
231 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
232 if (entry != NULL)
234 eh = (struct loongarch_elf_link_hash_entry *) entry;
235 eh->tls_type = GOT_UNKNOWN;
238 return entry;
241 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
242 for local symbol so that we can handle local STT_GNU_IFUNC symbols
243 as global symbol. We reuse indx and dynstr_index for local symbol
244 hash since they aren't used by global symbols in this backend. */
246 static hashval_t
247 elfNN_loongarch_local_htab_hash (const void *ptr)
249 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
250 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
253 /* Compare local hash entries. */
255 static int
256 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
258 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
259 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
261 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
264 /* Find and/or create a hash entry for local symbol. */
265 static struct elf_link_hash_entry *
266 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
267 bfd *abfd, const Elf_Internal_Rela *rel,
268 bool create)
270 struct loongarch_elf_link_hash_entry e, *ret;
271 asection *sec = abfd->sections;
272 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
273 void **slot;
275 e.elf.indx = sec->id;
276 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
277 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
278 create ? INSERT : NO_INSERT);
280 if (!slot)
281 return NULL;
283 if (*slot)
285 ret = (struct loongarch_elf_link_hash_entry *) *slot;
286 return &ret->elf;
289 ret = ((struct loongarch_elf_link_hash_entry *)
290 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
291 sizeof (struct loongarch_elf_link_hash_entry)));
292 if (ret)
294 memset (ret, 0, sizeof (*ret));
295 ret->elf.indx = sec->id;
296 ret->elf.pointer_equality_needed = 0;
297 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
298 ret->elf.dynindx = -1;
299 ret->elf.needs_plt = 0;
300 ret->elf.plt.refcount = -1;
301 ret->elf.got.refcount = -1;
302 ret->elf.def_dynamic = 0;
303 ret->elf.def_regular = 1;
304 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
305 ret->elf.ref_regular = 0;
306 ret->elf.forced_local = 1;
307 ret->elf.root.type = bfd_link_hash_defined;
308 *slot = ret;
310 return &ret->elf;
313 /* Destroy an LoongArch elf linker hash table. */
315 static void
316 elfNN_loongarch_link_hash_table_free (bfd *obfd)
318 struct loongarch_elf_link_hash_table *ret;
319 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
321 if (ret->loc_hash_table)
322 htab_delete (ret->loc_hash_table);
323 if (ret->loc_hash_memory)
324 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
326 _bfd_elf_link_hash_table_free (obfd);
329 /* Create a LoongArch ELF linker hash table. */
331 static struct bfd_link_hash_table *
332 loongarch_elf_link_hash_table_create (bfd *abfd)
334 struct loongarch_elf_link_hash_table *ret;
335 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
337 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
338 if (ret == NULL)
339 return NULL;
341 if (!_bfd_elf_link_hash_table_init
342 (&ret->elf, abfd, link_hash_newfunc,
343 sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
345 free (ret);
346 return NULL;
349 ret->max_alignment = MINUS_ONE;
351 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
352 elfNN_loongarch_local_htab_eq, NULL);
353 ret->loc_hash_memory = objalloc_create ();
354 if (!ret->loc_hash_table || !ret->loc_hash_memory)
356 elfNN_loongarch_link_hash_table_free (abfd);
357 return NULL;
359 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
361 return &ret->elf.root;
364 /* Merge backend specific data from an object file to the output
365 object file when linking. */
367 static bool
368 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
370 bfd *obfd = info->output_bfd;
371 flagword in_flags = elf_elfheader (ibfd)->e_flags;
372 flagword out_flags = elf_elfheader (obfd)->e_flags;
374 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
375 return true;
377 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
379 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
380 "the selected emulation:\n"
381 " target emulation `%s' does not match `%s'"),
382 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
383 return false;
386 if (!_bfd_elf_merge_object_attributes (ibfd, info))
387 return false;
389 /* If the input BFD is not a dynamic object and it does not contain any
390 non-data sections, do not account its ABI. For example, various
391 packages produces such data-only relocatable objects with
392 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
393 But they are compatible with all ABIs. */
394 if (!(ibfd->flags & DYNAMIC))
396 asection *sec;
397 bool have_code_sections = false;
398 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
399 if ((bfd_section_flags (sec)
400 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
401 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
403 have_code_sections = true;
404 break;
406 if (!have_code_sections)
407 return true;
410 if (!elf_flags_init (obfd))
412 elf_flags_init (obfd) = true;
413 elf_elfheader (obfd)->e_flags = in_flags;
414 return true;
417 /* Disallow linking different ABIs. */
418 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
420 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
421 goto fail;
424 return true;
426 fail:
427 bfd_set_error (bfd_error_bad_value);
428 return false;
431 /* Create the .got section. */
433 static bool
434 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
436 flagword flags;
437 char *name;
438 asection *s, *s_got;
439 struct elf_link_hash_entry *h;
440 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
441 struct elf_link_hash_table *htab = elf_hash_table (info);
443 /* This function may be called more than once. */
444 if (htab->sgot != NULL)
445 return true;
447 flags = bed->dynamic_sec_flags;
448 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
449 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
451 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
452 return false;
453 htab->srelgot = s;
455 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
456 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
457 return false;
458 htab->sgot = s;
460 /* The first bit of the global offset table is the header. */
461 s->size += bed->got_header_size;
463 if (bed->want_got_plt)
465 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
466 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
467 return false;
468 htab->sgotplt = s;
470 /* Reserve room for the header. */
471 s->size = GOTPLT_HEADER_SIZE;
474 if (bed->want_got_sym)
476 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
477 section. We don't do this in the linker script because we don't want
478 to define the symbol if we are not creating a global offset table. */
479 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
480 "_GLOBAL_OFFSET_TABLE_");
481 elf_hash_table (info)->hgot = h;
482 if (h == NULL)
483 return false;
485 return true;
488 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
489 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
490 hash table. */
492 static bool
493 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
495 struct loongarch_elf_link_hash_table *htab;
497 htab = loongarch_elf_hash_table (info);
498 BFD_ASSERT (htab != NULL);
500 if (!loongarch_elf_create_got_section (dynobj, info))
501 return false;
503 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
504 return false;
506 if (!bfd_link_pic (info))
507 htab->sdyntdata
508 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
509 SEC_ALLOC | SEC_THREAD_LOCAL);
511 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
512 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
513 abort ();
515 return true;
518 static bool
519 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
520 struct bfd_link_info *info,
521 struct elf_link_hash_entry *h,
522 unsigned long symndx,
523 char tls_type)
525 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
526 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
528 /* This is a global offset table entry for a local symbol. */
529 if (elf_local_got_refcounts (abfd) == NULL)
531 bfd_size_type size =
532 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
533 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
534 return false;
535 _bfd_loongarch_elf_local_got_tls_type (abfd) =
536 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
539 switch (tls_type)
541 case GOT_NORMAL:
542 case GOT_TLS_GD:
543 case GOT_TLS_IE:
544 /* Need GOT. */
545 if (htab->elf.sgot == NULL
546 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
547 return false;
548 if (h)
550 if (h->got.refcount < 0)
551 h->got.refcount = 0;
552 h->got.refcount++;
554 else
555 elf_local_got_refcounts (abfd)[symndx]++;
556 break;
557 case GOT_TLS_LE:
558 /* No need for GOT. */
559 break;
560 default:
561 _bfd_error_handler (_("Internal error: unreachable."));
562 return false;
565 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
566 *new_tls_type |= tls_type;
567 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
569 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
570 "thread local symbol"),
571 abfd,
572 h ? h->root.root.string : "<local>");
573 return false;
576 return true;
579 /* Look through the relocs for a section during the first phase, and
580 allocate space in the global offset table or procedure linkage
581 table. */
583 static bool
584 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
585 asection *sec, const Elf_Internal_Rela *relocs)
587 struct loongarch_elf_link_hash_table *htab;
588 Elf_Internal_Shdr *symtab_hdr;
589 struct elf_link_hash_entry **sym_hashes;
590 const Elf_Internal_Rela *rel;
591 asection *sreloc = NULL;
593 if (bfd_link_relocatable (info))
594 return true;
596 htab = loongarch_elf_hash_table (info);
597 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
598 sym_hashes = elf_sym_hashes (abfd);
600 if (htab->elf.dynobj == NULL)
601 htab->elf.dynobj = abfd;
603 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
605 unsigned int r_type;
606 unsigned int r_symndx;
607 struct elf_link_hash_entry *h;
608 Elf_Internal_Sym *isym = NULL;
610 int need_dynreloc;
611 int only_need_pcrel;
613 r_symndx = ELFNN_R_SYM (rel->r_info);
614 r_type = ELFNN_R_TYPE (rel->r_info);
616 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
618 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
619 return false;
622 if (r_symndx < symtab_hdr->sh_info)
624 /* A local symbol. */
625 isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
626 if (isym == NULL)
627 return false;
629 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
631 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
632 if (h == NULL)
633 return false;
635 h->type = STT_GNU_IFUNC;
636 h->ref_regular = 1;
638 else
639 h = NULL;
641 else
643 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
644 while (h->root.type == bfd_link_hash_indirect
645 || h->root.type == bfd_link_hash_warning)
646 h = (struct elf_link_hash_entry *) h->root.u.i.link;
649 /* It is referenced by a non-shared object. */
650 if (h != NULL)
651 h->ref_regular = 1;
653 if (h && h->type == STT_GNU_IFUNC)
655 if (htab->elf.dynobj == NULL)
656 htab->elf.dynobj = abfd;
658 /* Create the ifunc sections, iplt and ipltgot, for static
659 executables. */
660 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
661 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
662 return false;
664 if (!htab->elf.splt
665 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
666 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
667 return false;
669 if (h->plt.refcount < 0)
670 h->plt.refcount = 0;
671 h->plt.refcount++;
672 h->needs_plt = 1;
674 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
677 need_dynreloc = 0;
678 only_need_pcrel = 0;
679 switch (r_type)
681 case R_LARCH_SOP_PUSH_GPREL:
682 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
683 r_symndx,
684 GOT_NORMAL))
685 return false;
686 break;
688 case R_LARCH_SOP_PUSH_TLS_GD:
689 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
690 r_symndx,
691 GOT_TLS_GD))
692 return false;
693 break;
695 case R_LARCH_SOP_PUSH_TLS_GOT:
696 if (bfd_link_pic (info))
697 /* May fail for lazy-bind. */
698 info->flags |= DF_STATIC_TLS;
700 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
701 r_symndx,
702 GOT_TLS_IE))
703 return false;
704 break;
706 case R_LARCH_SOP_PUSH_TLS_TPREL:
707 if (!bfd_link_executable (info))
708 return false;
710 info->flags |= DF_STATIC_TLS;
712 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
713 r_symndx,
714 GOT_TLS_LE))
715 return false;
716 break;
718 case R_LARCH_SOP_PUSH_ABSOLUTE:
719 if (h != NULL)
720 /* If this reloc is in a read-only section, we might
721 need a copy reloc. We can't check reliably at this
722 stage whether the section is read-only, as input
723 sections have not yet been mapped to output sections.
724 Tentatively set the flag for now, and correct in
725 adjust_dynamic_symbol. */
726 h->non_got_ref = 1;
727 break;
729 case R_LARCH_SOP_PUSH_PCREL:
730 if (h != NULL)
732 h->non_got_ref = 1;
734 /* We try to create PLT stub for all non-local function. */
735 if (h->plt.refcount < 0)
736 h->plt.refcount = 0;
737 h->plt.refcount++;
739 break;
741 case R_LARCH_SOP_PUSH_PLT_PCREL:
742 /* This symbol requires a procedure linkage table entry. We
743 actually build the entry in adjust_dynamic_symbol,
744 because this might be a case of linking PIC code without
745 linking in any dynamic objects, in which case we don't
746 need to generate a procedure linkage table after all. */
747 if (h != NULL)
749 h->needs_plt = 1;
750 if (h->plt.refcount < 0)
751 h->plt.refcount = 0;
752 h->plt.refcount++;
754 break;
756 case R_LARCH_TLS_DTPREL32:
757 case R_LARCH_TLS_DTPREL64:
758 need_dynreloc = 1;
759 only_need_pcrel = 1;
760 break;
762 case R_LARCH_JUMP_SLOT:
763 case R_LARCH_32:
764 case R_LARCH_64:
765 need_dynreloc = 1;
767 /* If resolved symbol is defined in this object,
768 1. Under pie, the symbol is known. We convert it
769 into R_LARCH_RELATIVE and need load-addr still.
770 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
771 3. Under dll, R_LARCH_NN can't be changed normally, since
772 its defination could be covered by the one in executable.
773 For symbolic, we convert it into R_LARCH_RELATIVE.
774 Thus, only under pde, it needs pcrel only. We discard it. */
775 only_need_pcrel = bfd_link_pde (info);
777 if (h != NULL)
778 h->non_got_ref = 1;
780 if (h != NULL
781 && (!bfd_link_pic (info)
782 || h->type == STT_GNU_IFUNC))
784 /* This reloc might not bind locally. */
785 h->non_got_ref = 1;
786 h->pointer_equality_needed = 1;
788 if (!h->def_regular
789 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
791 /* We may need a .plt entry if the symbol is a function
792 defined in a shared lib or is a function referenced
793 from the code or read-only section. */
794 h->plt.refcount += 1;
797 break;
799 case R_LARCH_GNU_VTINHERIT:
800 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
801 return false;
802 break;
804 case R_LARCH_GNU_VTENTRY:
805 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
806 return false;
807 break;
809 default:
810 break;
813 /* Record some info for sizing and allocating dynamic entry. */
814 if (need_dynreloc && (sec->flags & SEC_ALLOC))
816 /* When creating a shared object, we must copy these
817 relocs into the output file. We create a reloc
818 section in dynobj and make room for the reloc. */
819 struct elf_dyn_relocs *p;
820 struct elf_dyn_relocs **head;
822 if (sreloc == NULL)
824 sreloc
825 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
826 LARCH_ELF_LOG_WORD_BYTES,
827 abfd, /*rela?*/ true);
828 if (sreloc == NULL)
829 return false;
832 /* If this is a global symbol, we count the number of
833 relocations we need for this symbol. */
834 if (h != NULL)
835 head = &h->dyn_relocs;
836 else
838 /* Track dynamic relocs needed for local syms too.
839 We really need local syms available to do this
840 easily. Oh well. */
842 asection *s;
843 void *vpp;
845 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
846 if (s == NULL)
847 s = sec;
849 vpp = &elf_section_data (s)->local_dynrel;
850 head = (struct elf_dyn_relocs **) vpp;
853 p = *head;
854 if (p == NULL || p->sec != sec)
856 bfd_size_type amt = sizeof *p;
857 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
858 if (p == NULL)
859 return false;
860 p->next = *head;
861 *head = p;
862 p->sec = sec;
863 p->count = 0;
864 p->pc_count = 0;
867 p->count++;
868 p->pc_count += only_need_pcrel;
872 return true;
875 /* Find dynamic relocs for H that apply to read-only sections. */
877 static asection *
878 readonly_dynrelocs (struct elf_link_hash_entry *h)
880 struct elf_dyn_relocs *p;
882 for (p = h->dyn_relocs; p != NULL; p = p->next)
884 asection *s = p->sec->output_section;
886 if (s != NULL && (s->flags & SEC_READONLY) != 0)
887 return p->sec;
889 return NULL;
892 /* Adjust a symbol defined by a dynamic object and referenced by a
893 regular object. The current definition is in some section of the
894 dynamic object, but we're not including those sections. We have to
895 change the definition to something the rest of the link can
896 understand. */
897 static bool
898 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
899 struct elf_link_hash_entry *h)
901 struct loongarch_elf_link_hash_table *htab;
902 struct loongarch_elf_link_hash_entry *eh;
903 bfd *dynobj;
904 asection *s, *srel;
906 htab = loongarch_elf_hash_table (info);
907 BFD_ASSERT (htab != NULL);
909 dynobj = htab->elf.dynobj;
911 /* Make sure we know what is going on here. */
912 BFD_ASSERT (dynobj != NULL
913 && (h->needs_plt || h->type == STT_GNU_IFUNC || h->is_weakalias
914 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
916 /* If this is a function, put it in the procedure linkage table. We
917 will fill in the contents of the procedure linkage table later
918 (although we could actually do it here). */
919 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
921 if (h->plt.refcount < 0
922 || (h->type != STT_GNU_IFUNC
923 && (SYMBOL_REFERENCES_LOCAL (info, h)
924 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
925 && h->root.type == bfd_link_hash_undefweak))))
927 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
928 in an input file, but the symbol was never referred to by a
929 dynamic object, or if all references were garbage collected.
930 In such a case, we don't actually need to build a PLT entry. */
931 h->plt.offset = MINUS_ONE;
932 h->needs_plt = 0;
934 else
935 h->needs_plt = 1;
937 return true;
939 else
940 h->plt.offset = MINUS_ONE;
942 /* If this is a weak symbol, and there is a real definition, the
943 processor independent code will have arranged for us to see the
944 real definition first, and we can just use the same value. */
945 if (h->is_weakalias)
947 struct elf_link_hash_entry *def = weakdef (h);
948 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
949 h->root.u.def.section = def->root.u.def.section;
950 h->root.u.def.value = def->root.u.def.value;
951 return true;
954 /* This is a reference to a symbol defined by a dynamic object which
955 is not a function. */
957 /* If we are creating a shared library, we must presume that the
958 only references to the symbol are via the global offset table.
959 For such cases we need not do anything here; the relocations will
960 be handled correctly by relocate_section. */
961 if (bfd_link_dll (info))
962 return true;
964 /* If there are no references to this symbol that do not use the
965 GOT, we don't need to generate a copy reloc. */
966 if (!h->non_got_ref)
967 return true;
969 /* If -z nocopyreloc was given, we won't generate them either. */
970 if (info->nocopyreloc)
972 h->non_got_ref = 0;
973 return true;
976 /* If we don't find any dynamic relocs in read-only sections, then
977 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
978 if (!readonly_dynrelocs (h))
980 h->non_got_ref = 0;
981 return true;
984 /* We must allocate the symbol in our .dynbss section, which will
985 become part of the .bss section of the executable. There will be
986 an entry for this symbol in the .dynsym section. The dynamic
987 object will contain position independent code, so all references
988 from the dynamic object to this symbol will go through the global
989 offset table. The dynamic linker will use the .dynsym entry to
990 determine the address it must put in the global offset table, so
991 both the dynamic object and the regular object will refer to the
992 same memory location for the variable. */
994 /* We must generate a R_LARCH_COPY reloc to tell the dynamic linker
995 to copy the initial value out of the dynamic object and into the
996 runtime process image. We need to remember the offset into the
997 .rel.bss section we are going to use. */
998 eh = (struct loongarch_elf_link_hash_entry *) h;
999 if (eh->tls_type & ~GOT_NORMAL)
1001 s = htab->sdyntdata;
1002 srel = htab->elf.srelbss;
1004 else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
1006 s = htab->elf.sdynrelro;
1007 srel = htab->elf.sreldynrelro;
1009 else
1011 s = htab->elf.sdynbss;
1012 srel = htab->elf.srelbss;
1014 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
1016 srel->size += sizeof (ElfNN_External_Rela);
1017 h->needs_copy = 1;
1020 return _bfd_elf_adjust_dynamic_copy (info, h, s);
1023 /* Allocate space in .plt, .got and associated reloc sections for
1024 dynamic relocs. */
1026 static bool
1027 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1029 struct bfd_link_info *info;
1030 struct loongarch_elf_link_hash_table *htab;
1031 struct elf_dyn_relocs *p;
1033 if (h->root.type == bfd_link_hash_indirect)
1034 return true;
1036 if (h->type == STT_GNU_IFUNC
1037 && h->def_regular)
1038 return true;
1040 info = (struct bfd_link_info *) inf;
1041 htab = loongarch_elf_hash_table (info);
1042 BFD_ASSERT (htab != NULL);
1046 asection *plt, *gotplt, *relplt;
1048 if (!h->needs_plt)
1049 break;
1051 h->needs_plt = 0;
1053 if (htab->elf.splt)
1055 if (h->dynindx == -1 && !h->forced_local
1056 && !bfd_elf_link_record_dynamic_symbol (info, h))
1057 return false;
1059 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1060 && h->type != STT_GNU_IFUNC)
1061 break;
1063 plt = htab->elf.splt;
1064 gotplt = htab->elf.sgotplt;
1065 relplt = htab->elf.srelplt;
1067 else if (htab->elf.iplt)
1069 /* .iplt only for IFUNC. */
1070 if (h->type != STT_GNU_IFUNC)
1071 break;
1073 plt = htab->elf.iplt;
1074 gotplt = htab->elf.igotplt;
1075 relplt = htab->elf.irelplt;
1077 else
1078 break;
1080 if (plt->size == 0)
1081 plt->size = PLT_HEADER_SIZE;
1083 h->plt.offset = plt->size;
1084 plt->size += PLT_ENTRY_SIZE;
1085 gotplt->size += GOT_ENTRY_SIZE;
1086 relplt->size += sizeof (ElfNN_External_Rela);
1088 /* If this symbol is not defined in a regular file, and we are
1089 not generating a shared library, then set the symbol to this
1090 location in the .plt. This is required to make function
1091 pointers compare as equal between the normal executable and
1092 the shared library. */
1093 if (!bfd_link_pic(info)
1094 && !h->def_regular)
1096 h->root.u.def.section = plt;
1097 h->root.u.def.value = h->plt.offset;
1100 h->needs_plt = 1;
1102 while (0);
1104 if (!h->needs_plt)
1105 h->plt.offset = MINUS_ONE;
1107 if (0 < h->got.refcount)
1109 asection *s;
1110 bool dyn;
1111 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1113 /* Make sure this symbol is output as a dynamic symbol.
1114 Undefined weak syms won't yet be marked as dynamic. */
1115 if (h->dynindx == -1 && !h->forced_local)
1117 if (SYMBOL_REFERENCES_LOCAL (info, h)
1118 && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
1119 && h->start_stop)
1121 /* The pr21964-4. do nothing. */
1123 else
1125 if( !bfd_elf_link_record_dynamic_symbol (info, h))
1126 return false;
1130 s = htab->elf.sgot;
1131 h->got.offset = s->size;
1132 dyn = htab->elf.dynamic_sections_created;
1133 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
1135 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1136 if (tls_type & GOT_TLS_GD)
1138 s->size += 2 * GOT_ENTRY_SIZE;
1139 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1142 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1143 if (tls_type & GOT_TLS_IE)
1145 s->size += GOT_ENTRY_SIZE;
1146 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1149 else
1151 s->size += GOT_ENTRY_SIZE;
1152 if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
1153 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1154 || h->type == STT_GNU_IFUNC)
1155 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1158 else
1159 h->got.offset = MINUS_ONE;
1161 if (h->dyn_relocs == NULL)
1162 return true;
1164 if (SYMBOL_REFERENCES_LOCAL (info, h))
1166 struct elf_dyn_relocs **pp;
1168 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1170 p->count -= p->pc_count;
1171 p->pc_count = 0;
1172 if (p->count == 0)
1173 *pp = p->next;
1174 else
1175 pp = &p->next;
1179 if (h->root.type == bfd_link_hash_undefweak)
1181 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1182 h->dyn_relocs = NULL;
1183 else if (h->dynindx == -1 && !h->forced_local
1184 /* Make sure this symbol is output as a dynamic symbol.
1185 Undefined weak syms won't yet be marked as dynamic. */
1186 && !bfd_elf_link_record_dynamic_symbol (info, h))
1187 return false;
1190 for (p = h->dyn_relocs; p != NULL; p = p->next)
1192 asection *sreloc = elf_section_data (p->sec)->sreloc;
1193 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1196 return true;
1199 /* Allocate space in .plt, .got and associated reloc sections for
1200 ifunc dynamic relocs. */
1202 static bool
1203 elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
1204 void *inf)
1206 struct bfd_link_info *info;
1207 /* An example of a bfd_link_hash_indirect symbol is versioned
1208 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1209 -> __gxx_personality_v0(bfd_link_hash_defined)
1211 There is no need to process bfd_link_hash_indirect symbols here
1212 because we will also be presented with the concrete instance of
1213 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1214 called to copy all relevant data from the generic to the concrete
1215 symbol instance. */
1216 if (h->root.type == bfd_link_hash_indirect)
1217 return true;
1219 if (h->root.type == bfd_link_hash_warning)
1220 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1222 info = (struct bfd_link_info *) inf;
1224 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1225 here if it is defined and referenced in a non-shared object. */
1226 if (h->type == STT_GNU_IFUNC
1227 && h->def_regular)
1228 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1229 &h->dyn_relocs,
1230 PLT_ENTRY_SIZE,
1231 PLT_HEADER_SIZE,
1232 GOT_ENTRY_SIZE,
1233 false);
1234 return true;
1237 /* Allocate space in .plt, .got and associated reloc sections for
1238 ifunc dynamic relocs. */
1240 static bool
1241 elfNN_loongarch_allocate_local_dynrelocs (void **slot, void *inf)
1243 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1245 if (h->type != STT_GNU_IFUNC
1246 || !h->def_regular
1247 || !h->ref_regular
1248 || !h->forced_local
1249 || h->root.type != bfd_link_hash_defined)
1250 abort ();
1252 return elfNN_loongarch_allocate_ifunc_dynrelocs (h, inf);
1255 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1256 read-only sections. */
1258 static bool
1259 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1261 asection *sec;
1263 if (h->root.type == bfd_link_hash_indirect)
1264 return true;
1266 sec = readonly_dynrelocs (h);
1267 if (sec != NULL)
1269 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1271 info->flags |= DF_TEXTREL;
1272 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1273 "read-only section `%pA'\n"),
1274 sec->owner, h->root.root.string, sec);
1276 /* Not an error, just cut short the traversal. */
1277 return false;
1279 return true;
1282 static bool
1283 loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1284 struct bfd_link_info *info)
1286 struct loongarch_elf_link_hash_table *htab;
1287 bfd *dynobj;
1288 asection *s;
1289 bfd *ibfd;
1291 htab = loongarch_elf_hash_table (info);
1292 BFD_ASSERT (htab != NULL);
1293 dynobj = htab->elf.dynobj;
1294 BFD_ASSERT (dynobj != NULL);
1296 if (htab->elf.dynamic_sections_created)
1298 /* Set the contents of the .interp section to the interpreter. */
1299 if (bfd_link_executable (info) && !info->nointerp)
1301 const char *interpreter;
1302 flagword flags = elf_elfheader (output_bfd)->e_flags;
1303 s = bfd_get_linker_section (dynobj, ".interp");
1304 BFD_ASSERT (s != NULL);
1305 if (EF_LOONGARCH_IS_ILP32 (flags))
1306 interpreter = "/lib32/ld.so.1";
1307 else if (EF_LOONGARCH_IS_LP64 (flags))
1308 interpreter = "/lib64/ld.so.1";
1309 else
1310 interpreter = "/lib/ld.so.1";
1311 s->contents = (unsigned char *) interpreter;
1312 s->size = strlen (interpreter) + 1;
1316 /* Set up .got offsets for local syms, and space for local dynamic
1317 relocs. */
1318 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1320 bfd_signed_vma *local_got;
1321 bfd_signed_vma *end_local_got;
1322 char *local_tls_type;
1323 bfd_size_type locsymcount;
1324 Elf_Internal_Shdr *symtab_hdr;
1325 asection *srel;
1327 if (!is_loongarch_elf (ibfd))
1328 continue;
1330 for (s = ibfd->sections; s != NULL; s = s->next)
1332 struct elf_dyn_relocs *p;
1334 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1336 p->count -= p->pc_count;
1337 if (!bfd_is_abs_section (p->sec)
1338 && bfd_is_abs_section (p->sec->output_section))
1340 /* Input section has been discarded, either because
1341 it is a copy of a linkonce section or due to
1342 linker script /DISCARD/, so we'll be discarding
1343 the relocs too. */
1345 else if (0 < p->count)
1347 srel = elf_section_data (p->sec)->sreloc;
1348 srel->size += p->count * sizeof (ElfNN_External_Rela);
1349 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1350 info->flags |= DF_TEXTREL;
1355 local_got = elf_local_got_refcounts (ibfd);
1356 if (!local_got)
1357 continue;
1359 symtab_hdr = &elf_symtab_hdr (ibfd);
1360 locsymcount = symtab_hdr->sh_info;
1361 end_local_got = local_got + locsymcount;
1362 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1363 s = htab->elf.sgot;
1364 srel = htab->elf.srelgot;
1365 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1367 if (0 < *local_got)
1369 *local_got = s->size;
1370 s->size += GOT_ENTRY_SIZE;
1372 if (*local_tls_type & GOT_TLS_GD)
1373 s->size += GOT_ENTRY_SIZE;
1375 /* If R_LARCH_RELATIVE. */
1376 if (bfd_link_pic (info)
1377 /* Or R_LARCH_TLS_DTPRELNN or R_LARCH_TLS_TPRELNN. */
1378 || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
1379 srel->size += sizeof (ElfNN_External_Rela);
1381 else
1382 *local_got = MINUS_ONE;
1386 /* Allocate global sym .plt and .got entries, and space for global
1387 sym dynamic relocs. */
1388 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1390 /* Allocate global ifunc sym .plt and .got entries, and space for global
1391 ifunc sym dynamic relocs. */
1392 elf_link_hash_traverse (&htab->elf, elfNN_loongarch_allocate_ifunc_dynrelocs, info);
1394 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1395 htab_traverse (htab->loc_hash_table,
1396 (void *) elfNN_loongarch_allocate_local_dynrelocs, info);
1398 /* Don't allocate .got.plt section if there are no PLT. */
1399 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1400 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1401 htab->elf.sgotplt->size = 0;
1403 /* The check_relocs and adjust_dynamic_symbol entry points have
1404 determined the sizes of the various dynamic sections. Allocate
1405 memory for them. */
1406 for (s = dynobj->sections; s != NULL; s = s->next)
1408 if ((s->flags & SEC_LINKER_CREATED) == 0)
1409 continue;
1411 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1412 || s == htab->elf.sgotplt || s == htab->elf.igotplt
1413 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1415 /* Strip this section if we don't need it; see the
1416 comment below. */
1418 else if (strncmp (s->name, ".rela", 5) == 0)
1420 if (s->size != 0)
1422 /* We use the reloc_count field as a counter if we need
1423 to copy relocs into the output file. */
1424 s->reloc_count = 0;
1427 else
1429 /* It's not one of our sections. */
1430 continue;
1433 if (s->size == 0)
1435 /* If we don't need this section, strip it from the
1436 output file. This is mostly to handle .rela.bss and
1437 .rela.plt. We must create both sections in
1438 create_dynamic_sections, because they must be created
1439 before the linker maps input sections to output
1440 sections. The linker does that before
1441 adjust_dynamic_symbol is called, and it is that
1442 function which decides whether anything needs to go
1443 into these sections. */
1444 s->flags |= SEC_EXCLUDE;
1445 continue;
1448 if ((s->flags & SEC_HAS_CONTENTS) == 0)
1449 continue;
1451 /* Allocate memory for the section contents. Zero the memory
1452 for the benefit of .rela.plt, which has 4 unused entries
1453 at the beginning, and we don't want garbage. */
1454 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1455 if (s->contents == NULL)
1456 return false;
1459 if (elf_hash_table (info)->dynamic_sections_created)
1461 /* Add some entries to the .dynamic section. We fill in the
1462 values later, in loongarch_elf_finish_dynamic_sections, but we
1463 must add the entries now so that we get the correct size for
1464 the .dynamic section. The DT_DEBUG entry is filled in by the
1465 dynamic linker and used by the debugger. */
1466 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1468 if (bfd_link_executable (info))
1470 if (!add_dynamic_entry (DT_DEBUG, 0))
1471 return false;
1474 if (htab->elf.srelplt->size != 0)
1476 if (!add_dynamic_entry (DT_PLTGOT, 0)
1477 || !add_dynamic_entry (DT_PLTRELSZ, 0)
1478 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1479 || !add_dynamic_entry (DT_JMPREL, 0))
1480 return false;
1483 if (!add_dynamic_entry (DT_RELA, 0)
1484 || !add_dynamic_entry (DT_RELASZ, 0)
1485 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1486 return false;
1488 /* If any dynamic relocs apply to a read-only section,
1489 then we need a DT_TEXTREL entry. */
1490 if ((info->flags & DF_TEXTREL) == 0)
1491 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1493 if (info->flags & DF_TEXTREL)
1495 if (!add_dynamic_entry (DT_TEXTREL, 0))
1496 return false;
1497 /* Clear the DF_TEXTREL flag. It will be set again if we
1498 write out an actual text relocation; we may not, because
1499 at this point we do not know whether e.g. any .eh_frame
1500 absolute relocations have been converted to PC-relative. */
1501 info->flags &= ~DF_TEXTREL;
1504 #undef add_dynamic_entry
1506 return true;
1509 #define LARCH_LD_STACK_DEPTH 16
1510 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1511 static size_t larch_stack_top = 0;
1513 static bfd_reloc_status_type
1514 loongarch_push (int64_t val)
1516 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1517 return bfd_reloc_outofrange;
1518 larch_opc_stack[larch_stack_top++] = val;
1519 return bfd_reloc_ok;
1522 static bfd_reloc_status_type
1523 loongarch_pop (int64_t *val)
1525 if (larch_stack_top == 0)
1526 return bfd_reloc_outofrange;
1527 BFD_ASSERT (val);
1528 *val = larch_opc_stack[--larch_stack_top];
1529 return bfd_reloc_ok;
1532 static bfd_reloc_status_type
1533 loongarch_top (int64_t *val)
1535 if (larch_stack_top == 0)
1536 return bfd_reloc_outofrange;
1537 BFD_ASSERT (val);
1538 *val = larch_opc_stack[larch_stack_top - 1];
1539 return bfd_reloc_ok;
1542 static void
1543 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
1545 const struct elf_backend_data *bed;
1546 bfd_byte *loc;
1548 bed = get_elf_backend_data (abfd);
1549 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
1550 bed->s->swap_reloca_out (abfd, rel, loc);
1553 /* Check rel->r_offset in range of contents. */
1554 static bfd_reloc_status_type
1555 loongarch_check_offset (const Elf_Internal_Rela *rel,
1556 const asection *input_section)
1558 if (0 == strcmp(input_section->name, ".text")
1559 && rel->r_offset > input_section->size)
1560 return bfd_reloc_overflow;
1562 return bfd_reloc_ok;
1565 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
1566 ({ \
1567 bfd_reloc_status_type ret = loongarch_pop (&op2); \
1568 if (ret == bfd_reloc_ok) \
1570 ret = loongarch_pop (&op1); \
1571 if (ret == bfd_reloc_ok) \
1572 ret = loongarch_push (op3); \
1574 ret; \
1577 static bfd_reloc_status_type
1578 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
1579 const asection *input_section ATTRIBUTE_UNUSED,
1580 reloc_howto_type *howto, bfd *input_bfd,
1581 bfd_byte *contents, bfd_vma reloc_val)
1583 int bits = bfd_get_reloc_size (howto) * 8;
1584 uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
1586 if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
1587 return bfd_reloc_overflow;
1589 insn = (insn & (uint32_t)howto->src_mask)
1590 | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
1592 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
1594 return bfd_reloc_ok;
1597 /* Emplace a static relocation. */
1599 static bfd_reloc_status_type
1600 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
1601 reloc_howto_type *howto, bfd_vma value,
1602 bfd *input_bfd, bfd_byte *contents)
1604 uint32_t insn1;
1605 int64_t opr1, opr2, opr3;
1606 bfd_reloc_status_type r = bfd_reloc_ok;
1607 int bits = bfd_get_reloc_size (howto) * 8;
1610 switch (ELFNN_R_TYPE (rel->r_info))
1612 case R_LARCH_SOP_PUSH_PCREL:
1613 case R_LARCH_SOP_PUSH_ABSOLUTE:
1614 case R_LARCH_SOP_PUSH_GPREL:
1615 case R_LARCH_SOP_PUSH_TLS_TPREL:
1616 case R_LARCH_SOP_PUSH_TLS_GOT:
1617 case R_LARCH_SOP_PUSH_TLS_GD:
1618 case R_LARCH_SOP_PUSH_PLT_PCREL:
1619 r = loongarch_push (value);
1620 break;
1622 case R_LARCH_SOP_PUSH_DUP:
1623 r = loongarch_pop (&opr1);
1624 if (r == bfd_reloc_ok)
1626 r = loongarch_push (opr1);
1627 if (r == bfd_reloc_ok)
1628 r = loongarch_push (opr1);
1630 break;
1632 case R_LARCH_SOP_ASSERT:
1633 r = loongarch_pop (&opr1);
1634 if (r != bfd_reloc_ok || !opr1)
1635 r = bfd_reloc_notsupported;
1636 break;
1638 case R_LARCH_SOP_NOT:
1639 r = loongarch_pop (&opr1);
1640 if (r == bfd_reloc_ok)
1641 r = loongarch_push (!opr1);
1642 break;
1644 case R_LARCH_SOP_SUB:
1645 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
1646 break;
1648 case R_LARCH_SOP_SL:
1649 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
1650 break;
1652 case R_LARCH_SOP_SR:
1653 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
1654 break;
1656 case R_LARCH_SOP_AND:
1657 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
1658 break;
1660 case R_LARCH_SOP_ADD:
1661 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
1662 break;
1664 case R_LARCH_SOP_IF_ELSE:
1665 r = loongarch_pop (&opr3);
1666 if (r == bfd_reloc_ok)
1668 r = loongarch_pop (&opr2);
1669 if (r == bfd_reloc_ok)
1671 r = loongarch_pop (&opr1);
1672 if (r == bfd_reloc_ok)
1673 r = loongarch_push (opr1 ? opr2 : opr3);
1676 break;
1678 case R_LARCH_SOP_POP_32_S_10_5:
1679 case R_LARCH_SOP_POP_32_S_10_12:
1680 case R_LARCH_SOP_POP_32_S_10_16:
1681 case R_LARCH_SOP_POP_32_S_10_16_S2:
1682 case R_LARCH_SOP_POP_32_S_5_20:
1683 case R_LARCH_SOP_POP_32_U_10_12:
1684 case R_LARCH_SOP_POP_32_U:
1685 r = loongarch_pop (&opr1);
1686 if (r != bfd_reloc_ok)
1687 break;
1688 r = loongarch_check_offset (rel, input_section);
1689 if (r != bfd_reloc_ok)
1690 break;
1692 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
1693 howto, input_bfd,
1694 contents, (bfd_vma)opr1);
1695 break;
1697 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
1699 r = loongarch_pop (&opr1);
1700 if (r != bfd_reloc_ok)
1701 break;
1703 if ((opr1 & 0x3) != 0)
1705 r = bfd_reloc_overflow;
1706 break;
1709 uint32_t imm = opr1 >> howto->rightshift;
1710 if ((imm & (~0xfffffU)) && ((imm & (~0xfffffU)) != (~0xfffffU)))
1712 r = bfd_reloc_overflow;
1713 break;
1715 r = loongarch_check_offset (rel, input_section);
1716 if (r != bfd_reloc_ok)
1717 break;
1719 insn1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
1720 insn1 = (insn1 & howto->src_mask)
1721 | ((imm & 0xffffU) << 10)
1722 | ((imm & 0x1f0000U) >> 16);
1723 bfd_put (bits, input_bfd, insn1, contents + rel->r_offset);
1724 break;
1727 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
1729 r = loongarch_pop (&opr1);
1730 if (r != bfd_reloc_ok)
1731 break;
1733 if ((opr1 & 0x3) != 0)
1735 r = bfd_reloc_overflow;
1736 break;
1739 uint32_t imm = opr1 >> howto->rightshift;
1740 if ((imm & (~0x1ffffffU)) && (imm & (~0x1ffffffU)) != (~0x1ffffffU))
1742 r = bfd_reloc_overflow;
1743 break;
1746 r = loongarch_check_offset (rel, input_section);
1747 if (r != bfd_reloc_ok)
1748 break;
1750 insn1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
1751 insn1 = ((insn1 & howto->src_mask)
1752 | ((imm & 0xffffU) << 10)
1753 | ((imm & 0x3ff0000U) >> 16));
1754 bfd_put (bits, input_bfd, insn1, contents + rel->r_offset);
1755 break;
1758 case R_LARCH_TLS_DTPREL32:
1759 case R_LARCH_32:
1760 case R_LARCH_TLS_DTPREL64:
1761 case R_LARCH_64:
1762 r = loongarch_check_offset (rel, input_section);
1763 if (r != bfd_reloc_ok)
1764 break;
1766 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
1767 break;
1769 case R_LARCH_ADD8:
1770 case R_LARCH_ADD16:
1771 case R_LARCH_ADD24:
1772 case R_LARCH_ADD32:
1773 case R_LARCH_ADD64:
1774 r = loongarch_check_offset (rel, input_section);
1775 if (r != bfd_reloc_ok)
1776 break;
1778 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
1779 bfd_put (bits, input_bfd, opr1 + value, contents + rel->r_offset);
1780 break;
1782 case R_LARCH_SUB8:
1783 case R_LARCH_SUB16:
1784 case R_LARCH_SUB24:
1785 case R_LARCH_SUB32:
1786 case R_LARCH_SUB64:
1787 r = loongarch_check_offset (rel, input_section);
1788 if (r != bfd_reloc_ok)
1789 break;
1791 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
1792 bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
1793 break;
1795 default:
1796 r = bfd_reloc_notsupported;
1798 return r;
1801 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
1802 static struct
1804 bfd *bfd;
1805 asection *section;
1806 bfd_vma r_offset;
1807 int r_type;
1808 bfd_vma relocation;
1809 Elf_Internal_Sym *sym;
1810 struct elf_link_hash_entry *h;
1811 bfd_vma addend;
1812 int64_t top_then;
1813 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
1814 static size_t larch_reloc_queue_head = 0;
1815 static size_t larch_reloc_queue_tail = 0;
1817 static const char *
1818 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
1819 Elf_Internal_Sym *sym)
1821 const char *ret = NULL;
1822 if (sym)
1823 ret = bfd_elf_string_from_elf_section (input_bfd,
1824 elf_symtab_hdr (input_bfd).sh_link,
1825 sym->st_name);
1826 else if (h)
1827 ret = h->root.root.string;
1829 if (ret == NULL || *ret == '\0')
1830 ret = "<nameless>";
1831 return ret;
1834 static void
1835 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
1836 bfd_vma r_offset, Elf_Internal_Sym *sym,
1837 struct elf_link_hash_entry *h, bfd_vma addend)
1839 if ((larch_reloc_queue_head == 0
1840 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
1841 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
1842 larch_reloc_queue_head =
1843 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
1844 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
1845 larch_reloc_queue[larch_reloc_queue_tail].section = section;
1846 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
1847 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
1848 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
1849 larch_reloc_queue[larch_reloc_queue_tail].h = h;
1850 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
1851 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
1852 larch_reloc_queue_tail =
1853 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
1856 static void
1857 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
1859 size_t i = larch_reloc_queue_head;
1860 bfd *a_bfd = NULL;
1861 asection *section = NULL;
1862 bfd_vma r_offset = 0;
1863 int inited = 0;
1864 p ("Dump relocate record:\n");
1865 p ("stack top\t\trelocation name\t\tsymbol");
1866 while (i != larch_reloc_queue_tail)
1868 if (a_bfd != larch_reloc_queue[i].bfd
1869 || section != larch_reloc_queue[i].section
1870 || r_offset != larch_reloc_queue[i].r_offset)
1872 a_bfd = larch_reloc_queue[i].bfd;
1873 section = larch_reloc_queue[i].section;
1874 r_offset = larch_reloc_queue[i].r_offset;
1875 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
1876 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
1879 if (!inited)
1880 inited = 1, p ("...\n");
1882 reloc_howto_type *howto =
1883 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
1884 larch_reloc_queue[i].r_type);
1885 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
1886 howto ? howto->name : "<unknown reloc>",
1887 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
1888 larch_reloc_queue[i].sym));
1890 long addend = larch_reloc_queue[i].addend;
1891 if (addend < 0)
1892 p (" - %ld", -addend);
1893 else if (0 < addend)
1894 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
1896 p ("\n");
1897 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
1899 p ("\n"
1900 "-- Record dump end --\n\n");
1904 static bool
1905 loongarch_reloc_is_fatal (struct bfd_link_info *info,
1906 bfd *input_bfd,
1907 asection *input_section,
1908 Elf_Internal_Rela *rel,
1909 reloc_howto_type *howto,
1910 bfd_reloc_status_type rtype,
1911 bool is_undefweak,
1912 const char *name,
1913 const char *msg)
1915 bool fatal = true;
1916 switch (rtype)
1918 /* 'dangerous' means we do it but can't promise it's ok
1919 'unsupport' means out of ability of relocation type
1920 'undefined' means we can't deal with the undefined symbol. */
1921 case bfd_reloc_undefined:
1922 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
1923 rel->r_offset, true);
1924 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1925 input_bfd, input_section, rel->r_offset,
1926 howto->name,
1927 is_undefweak ? "[undefweak] " : "", name, msg);
1928 break;
1929 case bfd_reloc_dangerous:
1930 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
1931 input_bfd, input_section, rel->r_offset,
1932 howto->name,
1933 is_undefweak ? "[undefweak] " : "", name, msg);
1934 fatal = false;
1935 break;
1936 case bfd_reloc_notsupported:
1937 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1938 input_bfd, input_section, rel->r_offset,
1939 howto->name,
1940 is_undefweak ? "[undefweak] " : "", name, msg);
1941 break;
1942 default:
1943 break;
1945 return fatal;
1951 static int
1952 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
1953 bfd *input_bfd, asection *input_section,
1954 bfd_byte *contents, Elf_Internal_Rela *relocs,
1955 Elf_Internal_Sym *local_syms,
1956 asection **local_sections)
1958 Elf_Internal_Rela *rel;
1959 Elf_Internal_Rela *relend;
1960 bool fatal = false;
1961 asection *sreloc = elf_section_data (input_section)->sreloc;
1962 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
1963 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
1964 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
1965 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
1966 bool is_pic = bfd_link_pic (info);
1967 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
1968 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
1969 asection *got = htab->elf.sgot;
1971 relend = relocs + input_section->reloc_count;
1972 for (rel = relocs; rel < relend; rel++)
1974 int r_type = ELFNN_R_TYPE (rel->r_info);
1975 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1976 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
1977 reloc_howto_type *howto = NULL;
1978 asection *sec = NULL;
1979 Elf_Internal_Sym *sym = NULL;
1980 struct elf_link_hash_entry *h = NULL;
1981 const char *name;
1982 bfd_reloc_status_type r = bfd_reloc_ok;
1983 bool is_ie, is_undefweak, unresolved_reloc, defined_local;
1984 bool resolved_local, resolved_dynly, resolved_to_const;
1985 char tls_type;
1986 bfd_vma relocation;
1987 bfd_vma off, ie_off;
1988 int i, j;
1990 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
1991 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
1992 || r_type == R_LARCH_GNU_VTENTRY)
1993 continue;
1995 /* This is a final link. */
1996 if (r_symndx < symtab_hdr->sh_info)
1998 is_undefweak = false;
1999 unresolved_reloc = false;
2000 sym = local_syms + r_symndx;
2001 sec = local_sections[r_symndx];
2002 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2004 /* Relocate against local STT_GNU_IFUNC symbol. */
2005 if (!bfd_link_relocatable (info)
2006 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2008 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2009 false);
2010 if (h == NULL)
2011 abort ();
2013 /* Set STT_GNU_IFUNC symbol value. */
2014 h->root.u.def.value = sym->st_value;
2015 h->root.u.def.section = sec;
2017 defined_local = true;
2018 resolved_local = true;
2019 resolved_dynly = false;
2020 resolved_to_const = false;
2021 if (bfd_link_relocatable (info)
2022 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2023 rel->r_addend += sec->output_offset;
2025 else
2027 bool warned, ignored;
2029 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2030 r_symndx, symtab_hdr, sym_hashes,
2031 h, sec, relocation,
2032 unresolved_reloc, warned, ignored);
2033 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2035 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2036 symbol. And 'dynamic_undefined_weak' specify what to do when
2037 meeting undefweak. */
2039 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2041 defined_local = false;
2042 resolved_local = false;
2043 resolved_to_const = (!is_dyn || h->dynindx == -1
2044 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2045 resolved_dynly = !resolved_local && !resolved_to_const;
2047 else if (warned)
2049 /* Symbol undefined offen means failed already. I don't know why
2050 'warned' here but I guess it want to continue relocating as if
2051 no error occures to find other errors as more as possible. */
2053 /* To avoid generating warning messages about truncated
2054 relocations, set the relocation's address to be the same as
2055 the start of this section. */
2056 relocation = (input_section->output_section
2057 ? input_section->output_section->vma
2058 : 0);
2060 defined_local = relocation != 0;
2061 resolved_local = defined_local;
2062 resolved_to_const = !resolved_local;
2063 resolved_dynly = false;
2065 else
2067 defined_local = !unresolved_reloc && !ignored;
2068 resolved_local =
2069 defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2070 resolved_dynly = !resolved_local;
2071 resolved_to_const = !resolved_local && !resolved_dynly;
2075 name = loongarch_sym_name (input_bfd, h, sym);
2077 if (sec != NULL && discarded_section (sec))
2078 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2079 1, relend, howto, 0, contents);
2081 if (bfd_link_relocatable (info))
2082 continue;
2084 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2085 from removed linkonce sections, or sections discarded by a linker
2086 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2087 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2089 defined_local = false;
2090 resolved_local = false;
2091 resolved_dynly = false;
2092 resolved_to_const = true;
2095 /* The ifunc without reference does not generate plt. */
2096 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2098 defined_local = true;
2099 resolved_local = true;
2100 resolved_dynly = false;
2101 resolved_to_const = false;
2102 relocation = sec_addr (plt) + h->plt.offset;
2105 unresolved_reloc = resolved_dynly;
2107 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2109 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2111 BFD_ASSERT (!resolved_local || defined_local);
2113 is_ie = false;
2114 switch (r_type)
2116 case R_LARCH_MARK_PCREL:
2117 case R_LARCH_MARK_LA:
2118 case R_LARCH_NONE:
2119 r = bfd_reloc_continue;
2120 unresolved_reloc = false;
2121 break;
2123 case R_LARCH_32:
2124 case R_LARCH_64:
2125 if (resolved_dynly || (is_pic && resolved_local))
2127 Elf_Internal_Rela outrel;
2129 /* When generating a shared object, these relocations are copied
2130 into the output file to be resolved at run time. */
2132 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2133 input_section,
2134 rel->r_offset);
2136 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2137 && (input_section->flags & SEC_ALLOC));
2139 outrel.r_offset += sec_addr (input_section);
2141 /* A pointer point to a local ifunc symbol. */
2142 if(h
2143 && h->type == STT_GNU_IFUNC
2144 && (h->dynindx == -1
2145 || h->forced_local
2146 || bfd_link_executable(info)))
2148 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2149 outrel.r_addend = (h->root.u.def.value
2150 + h->root.u.def.section->output_section->vma
2151 + h->root.u.def.section->output_offset);
2153 /* Dynamic relocations are stored in
2154 1. .rela.ifunc section in PIC object.
2155 2. .rela.got section in dynamic executable.
2156 3. .rela.iplt section in static executable. */
2157 if (bfd_link_pic (info))
2158 sreloc = htab->elf.irelifunc;
2159 else if (htab->elf.splt != NULL)
2160 sreloc = htab->elf.srelgot;
2161 else
2162 sreloc = htab->elf.irelplt;
2164 else if (resolved_dynly)
2166 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2167 outrel.r_addend = rel->r_addend;
2169 else
2171 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2172 outrel.r_addend = relocation + rel->r_addend;
2175 if (unresolved_reloc)
2176 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2179 relocation += rel->r_addend;
2180 break;
2182 case R_LARCH_ADD8:
2183 case R_LARCH_ADD16:
2184 case R_LARCH_ADD24:
2185 case R_LARCH_ADD32:
2186 case R_LARCH_ADD64:
2187 case R_LARCH_SUB8:
2188 case R_LARCH_SUB16:
2189 case R_LARCH_SUB24:
2190 case R_LARCH_SUB32:
2191 case R_LARCH_SUB64:
2192 if (resolved_dynly)
2193 fatal = (loongarch_reloc_is_fatal
2194 (info, input_bfd, input_section, rel, howto,
2195 bfd_reloc_undefined, is_undefweak, name,
2196 "Can't be resolved dynamically. "
2197 "If this procedure is hand-written assembly,\n"
2198 "there must be something like '.dword sym1 - sym2' "
2199 "to generate these relocs\n"
2200 "and we can't get known link-time address of "
2201 "these symbols."));
2202 else
2203 relocation += rel->r_addend;
2204 break;
2206 case R_LARCH_TLS_DTPREL32:
2207 case R_LARCH_TLS_DTPREL64:
2208 if (resolved_dynly)
2210 Elf_Internal_Rela outrel;
2212 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2213 input_section,
2214 rel->r_offset);
2215 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2216 && (input_section->flags & SEC_ALLOC));
2217 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2218 outrel.r_offset += sec_addr (input_section);
2219 outrel.r_addend = rel->r_addend;
2220 if (unresolved_reloc)
2221 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2222 break;
2225 if (resolved_to_const)
2226 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2227 rel, howto,
2228 bfd_reloc_notsupported,
2229 is_undefweak, name,
2230 "Internal:");
2231 if (resolved_local)
2233 if (!elf_hash_table (info)->tls_sec)
2235 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2236 input_section, rel, howto, bfd_reloc_notsupported,
2237 is_undefweak, name, "TLS section not be created");
2239 else
2240 relocation -= elf_hash_table (info)->tls_sec->vma;
2242 else
2244 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2245 input_section, rel, howto, bfd_reloc_undefined,
2246 is_undefweak, name,
2247 "TLS LE just can be resolved local only.");
2250 break;
2252 case R_LARCH_SOP_PUSH_TLS_TPREL:
2253 if (resolved_local)
2255 if (!elf_hash_table (info)->tls_sec)
2256 fatal = (loongarch_reloc_is_fatal
2257 (info, input_bfd, input_section, rel, howto,
2258 bfd_reloc_notsupported, is_undefweak, name,
2259 "TLS section not be created"));
2260 else
2261 relocation -= elf_hash_table (info)->tls_sec->vma;
2263 else
2264 fatal = (loongarch_reloc_is_fatal
2265 (info, input_bfd, input_section, rel, howto,
2266 bfd_reloc_undefined, is_undefweak, name,
2267 "TLS LE just can be resolved local only."));
2268 break;
2270 case R_LARCH_SOP_PUSH_ABSOLUTE:
2271 if (is_undefweak)
2273 if (resolved_dynly)
2274 fatal = (loongarch_reloc_is_fatal
2275 (info, input_bfd, input_section, rel, howto,
2276 bfd_reloc_dangerous, is_undefweak, name,
2277 "Someone require us to resolve undefweak "
2278 "symbol dynamically. \n"
2279 "But this reloc can't be done. "
2280 "I think I can't throw error "
2281 "for this\n"
2282 "so I resolved it to 0. "
2283 "I suggest to re-compile with '-fpic'."));
2285 relocation = 0;
2286 unresolved_reloc = false;
2287 break;
2290 if (resolved_to_const)
2292 relocation += rel->r_addend;
2293 break;
2296 if (is_pic)
2298 fatal = (loongarch_reloc_is_fatal
2299 (info, input_bfd, input_section, rel, howto,
2300 bfd_reloc_notsupported, is_undefweak, name,
2301 "Under PIC we don't know load address. Re-compile "
2302 "with '-fpic'?"));
2303 break;
2306 if (resolved_dynly)
2308 if (!(plt && h && h->plt.offset != MINUS_ONE))
2310 fatal = (loongarch_reloc_is_fatal
2311 (info, input_bfd, input_section, rel, howto,
2312 bfd_reloc_undefined, is_undefweak, name,
2313 "Can't be resolved dynamically. Try to re-compile "
2314 "with '-fpic'?"));
2315 break;
2318 if (rel->r_addend != 0)
2320 fatal = (loongarch_reloc_is_fatal
2321 (info, input_bfd, input_section, rel, howto,
2322 bfd_reloc_notsupported, is_undefweak, name,
2323 "Shouldn't be with r_addend."));
2324 break;
2327 relocation = sec_addr (plt) + h->plt.offset;
2328 unresolved_reloc = false;
2329 break;
2332 if (resolved_local)
2334 relocation += rel->r_addend;
2335 break;
2338 break;
2340 case R_LARCH_SOP_PUSH_PCREL:
2341 case R_LARCH_SOP_PUSH_PLT_PCREL:
2342 unresolved_reloc = false;
2344 if (resolved_to_const)
2346 relocation += rel->r_addend;
2347 break;
2349 else if (is_undefweak)
2351 i = 0, j = 0;
2352 relocation = 0;
2353 if (resolved_dynly)
2355 if (h && h->plt.offset != MINUS_ONE)
2356 i = 1, j = 2;
2357 else
2358 fatal = (loongarch_reloc_is_fatal
2359 (info, input_bfd, input_section, rel, howto,
2360 bfd_reloc_dangerous, is_undefweak, name,
2361 "Undefweak need to be resolved dynamically, "
2362 "but PLT stub doesn't represent."));
2365 else
2367 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
2369 fatal = (loongarch_reloc_is_fatal
2370 (info, input_bfd, input_section, rel, howto,
2371 bfd_reloc_undefined, is_undefweak, name,
2372 "PLT stub does not represent and "
2373 "symbol not defined."));
2374 break;
2377 if (resolved_local)
2378 i = 0, j = 2;
2379 else /* if (resolved_dynly) */
2381 if (!(h && h->plt.offset != MINUS_ONE))
2382 fatal = (loongarch_reloc_is_fatal
2383 (info, input_bfd, input_section, rel, howto,
2384 bfd_reloc_dangerous, is_undefweak, name,
2385 "Internal: PLT stub doesn't represent. "
2386 "Resolve it with pcrel"));
2387 i = 1, j = 3;
2391 for (; i < j; i++)
2393 if ((i & 1) == 0 && defined_local)
2395 relocation -= pc;
2396 relocation += rel->r_addend;
2397 break;
2400 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
2402 if (rel->r_addend != 0)
2404 fatal = (loongarch_reloc_is_fatal
2405 (info, input_bfd, input_section, rel, howto,
2406 bfd_reloc_notsupported, is_undefweak, name,
2407 "PLT shouldn't be with r_addend."));
2408 break;
2410 relocation = sec_addr (plt) + h->plt.offset - pc;
2411 break;
2414 break;
2416 case R_LARCH_SOP_PUSH_GPREL:
2417 unresolved_reloc = false;
2419 if (rel->r_addend != 0)
2421 fatal = (loongarch_reloc_is_fatal
2422 (info, input_bfd, input_section, rel, howto,
2423 bfd_reloc_notsupported, is_undefweak, name,
2424 "Shouldn't be with r_addend."));
2425 break;
2428 if (h != NULL)
2430 off = h->got.offset;
2432 if (off == MINUS_ONE
2433 && h->type != STT_GNU_IFUNC)
2435 fatal = (loongarch_reloc_is_fatal
2436 (info, input_bfd, input_section, rel, howto,
2437 bfd_reloc_notsupported, is_undefweak, name,
2438 "Internal: GOT entry doesn't represent."));
2439 break;
2442 /* Hidden symbol not has .got entry, only .got.plt entry
2443 so gprel is (plt - got). */
2444 if (off == MINUS_ONE
2445 && h->type == STT_GNU_IFUNC)
2447 if (h->plt.offset == (bfd_vma) -1)
2449 abort();
2452 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2453 off = plt_index * GOT_ENTRY_SIZE;
2455 if (htab->elf.splt != NULL)
2457 /* Section .plt header is 2 times of plt entry. */
2458 off = sec_addr(htab->elf.sgotplt) + off
2459 - sec_addr(htab->elf.sgot);
2461 else
2463 /* Section iplt not has plt header. */
2464 off = sec_addr(htab->elf.igotplt) + off
2465 - sec_addr(htab->elf.sgot);
2469 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, is_pic, h)
2470 || (is_pic && SYMBOL_REFERENCES_LOCAL (info, h)))
2472 /* This is actually a static link, or it is a
2473 -Bsymbolic link and the symbol is defined
2474 locally, or the symbol was forced to be local
2475 because of a version file. We must initialize
2476 this entry in the global offset table. Since the
2477 offset must always be a multiple of the word size,
2478 we use the least significant bit to record whether
2479 we have initialized it already.
2481 When doing a dynamic link, we create a .rela.got
2482 relocation entry to initialize the value. This
2483 is done in the finish_dynamic_symbol routine. */
2485 if (resolved_dynly)
2487 fatal = (loongarch_reloc_is_fatal
2488 (info, input_bfd, input_section, rel, howto,
2489 bfd_reloc_dangerous, is_undefweak, name,
2490 "Internal: here shouldn't dynamic."));
2493 if (!(defined_local || resolved_to_const))
2495 fatal = (loongarch_reloc_is_fatal
2496 (info, input_bfd, input_section, rel, howto,
2497 bfd_reloc_undefined, is_undefweak, name,
2498 "Internal: "));
2499 break;
2502 if ((off & 1) != 0)
2503 off &= ~1;
2504 else
2506 /* The pr21964-4. Create relocate entry. */
2507 if (is_pic && h->start_stop)
2509 asection *s;
2510 Elf_Internal_Rela outrel;
2511 /* We need to generate a R_LARCH_RELATIVE reloc
2512 for the dynamic linker. */
2513 s = htab->elf.srelgot;
2514 if (!s)
2516 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2517 input_section, rel, howto,
2518 bfd_reloc_notsupported, is_undefweak, name,
2519 "Internal: '.rel.got' not represent");
2520 break;
2523 outrel.r_offset = sec_addr (got) + off;
2524 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2525 outrel.r_addend = relocation; /* Link-time addr. */
2526 loongarch_elf_append_rela (output_bfd, s, &outrel);
2528 bfd_put_NN (output_bfd, relocation, got->contents + off);
2529 h->got.offset |= 1;
2533 else
2535 if (!local_got_offsets)
2537 fatal = (loongarch_reloc_is_fatal
2538 (info, input_bfd, input_section, rel, howto,
2539 bfd_reloc_notsupported, is_undefweak, name,
2540 "Internal: local got offsets not reporesent."));
2541 break;
2544 off = local_got_offsets[r_symndx];
2546 if (off == MINUS_ONE)
2548 fatal = (loongarch_reloc_is_fatal
2549 (info, input_bfd, input_section, rel, howto,
2550 bfd_reloc_notsupported, is_undefweak, name,
2551 "Internal: GOT entry doesn't represent."));
2552 break;
2555 /* The offset must always be a multiple of the word size.
2556 So, we can use the least significant bit to record
2557 whether we have already processed this entry. */
2558 if ((off & 1) != 0)
2559 off &= ~1;
2560 else
2562 if (is_pic)
2564 asection *s;
2565 Elf_Internal_Rela outrel;
2566 /* We need to generate a R_LARCH_RELATIVE reloc
2567 for the dynamic linker. */
2568 s = htab->elf.srelgot;
2569 if (!s)
2571 fatal = (loongarch_reloc_is_fatal
2572 (info, input_bfd, input_section, rel, howto,
2573 bfd_reloc_notsupported, is_undefweak, name,
2574 "Internal: '.rel.got' not represent"));
2575 break;
2578 outrel.r_offset = sec_addr (got) + off;
2579 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2580 outrel.r_addend = relocation; /* Link-time addr. */
2581 loongarch_elf_append_rela (output_bfd, s, &outrel);
2584 bfd_put_NN (output_bfd, relocation, got->contents + off);
2585 local_got_offsets[r_symndx] |= 1;
2588 relocation = off;
2589 break;
2591 case R_LARCH_SOP_PUSH_TLS_GOT:
2592 case R_LARCH_SOP_PUSH_TLS_GD:
2593 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
2594 is_ie = true;
2595 unresolved_reloc = false;
2597 if (rel->r_addend != 0)
2599 fatal = (loongarch_reloc_is_fatal
2600 (info, input_bfd, input_section, rel, howto,
2601 bfd_reloc_notsupported, is_undefweak, name,
2602 "Shouldn't be with r_addend."));
2603 break;
2607 if (resolved_to_const && is_undefweak && h->dynindx != -1)
2609 /* What if undefweak? Let rtld make a decision. */
2610 resolved_to_const = resolved_local = false;
2611 resolved_dynly = true;
2614 if (resolved_to_const)
2616 fatal = (loongarch_reloc_is_fatal
2617 (info, input_bfd, input_section, rel, howto,
2618 bfd_reloc_notsupported, is_undefweak, name,
2619 "Internal: Shouldn't be resolved to const."));
2620 break;
2623 if (h != NULL)
2625 off = h->got.offset;
2626 h->got.offset |= 1;
2628 else
2630 off = local_got_offsets[r_symndx];
2631 local_got_offsets[r_symndx] |= 1;
2634 if (off == MINUS_ONE)
2636 fatal = (loongarch_reloc_is_fatal
2637 (info, input_bfd, input_section, rel, howto,
2638 bfd_reloc_notsupported, is_undefweak, name,
2639 "Internal: TLS GOT entry doesn't represent."));
2640 break;
2643 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
2645 /* If this symbol is referenced by both GD and IE TLS, the IE
2646 reference's GOT slot follows the GD reference's slots. */
2647 ie_off = 0;
2648 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
2649 ie_off = 2 * GOT_ENTRY_SIZE;
2651 if ((off & 1) != 0)
2652 off &= ~1;
2653 else
2655 bfd_vma tls_block_off = 0;
2656 Elf_Internal_Rela outrel;
2658 if (resolved_local)
2660 if (!elf_hash_table (info)->tls_sec)
2662 fatal = (loongarch_reloc_is_fatal
2663 (info, input_bfd, input_section, rel, howto,
2664 bfd_reloc_notsupported, is_undefweak, name,
2665 "Internal: TLS sec not represent."));
2666 break;
2668 tls_block_off =
2669 relocation - elf_hash_table (info)->tls_sec->vma;
2672 if (tls_type & GOT_TLS_GD)
2674 outrel.r_offset = sec_addr (got) + off;
2675 outrel.r_addend = 0;
2676 bfd_put_NN (output_bfd, 0, got->contents + off);
2677 if (resolved_local && bfd_link_executable (info))
2678 bfd_put_NN (output_bfd, 1, got->contents + off);
2679 else if (resolved_local /* && !bfd_link_executable (info) */)
2681 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
2682 loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
2683 &outrel);
2685 else /* if (resolved_dynly) */
2687 outrel.r_info =
2688 ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_DTPMODNN);
2689 loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
2690 &outrel);
2693 outrel.r_offset += GOT_ENTRY_SIZE;
2694 bfd_put_NN (output_bfd, tls_block_off,
2695 got->contents + off + GOT_ENTRY_SIZE);
2696 if (resolved_local)
2697 /* DTPREL known. */;
2698 else /* if (resolved_dynly) */
2700 outrel.r_info =
2701 ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_DTPRELNN);
2702 loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
2703 &outrel);
2707 if (tls_type & GOT_TLS_IE)
2709 outrel.r_offset = sec_addr (got) + off + ie_off;
2710 bfd_put_NN (output_bfd, tls_block_off,
2711 got->contents + off + ie_off);
2712 if (resolved_local && bfd_link_executable (info))
2713 /* TPREL known. */;
2714 else if (resolved_local /* && !bfd_link_executable (info) */)
2716 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
2717 outrel.r_addend = tls_block_off;
2718 loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
2719 &outrel);
2721 else /* if (resolved_dynly) */
2723 /* Static linking has no .dynsym table. */
2724 if (!htab->elf.dynamic_sections_created)
2726 outrel.r_info =
2727 ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
2728 outrel.r_addend = 0;
2730 else
2732 outrel.r_info =
2733 ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_TPRELNN);
2734 outrel.r_addend = 0;
2736 loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
2737 &outrel);
2742 relocation = off + (is_ie ? ie_off : 0);
2743 break;
2745 default:
2746 break;
2749 if (fatal)
2750 break;
2754 /* 'unresolved_reloc' means we haven't done it yet.
2755 We need help of dynamic linker to fix this memory location up. */
2756 if (!unresolved_reloc)
2757 break;
2759 if (_bfd_elf_section_offset (output_bfd, info, input_section,
2760 rel->r_offset) == MINUS_ONE)
2761 /* WHY? May because it's invalid so skip checking.
2762 But why dynamic reloc a invalid section? */
2763 break;
2765 if (input_section->output_section->flags & SEC_DEBUGGING)
2767 fatal = (loongarch_reloc_is_fatal
2768 (info, input_bfd, input_section, rel, howto,
2769 bfd_reloc_dangerous, is_undefweak, name,
2770 "Seems dynamic linker not process "
2771 "sections 'SEC_DEBUGGING'."));
2773 if (!is_dyn)
2774 break;
2776 if ((info->flags & DF_TEXTREL) == 0)
2777 if (input_section->output_section->flags & SEC_READONLY)
2778 info->flags |= DF_TEXTREL;
2780 while (0);
2782 if (fatal)
2783 break;
2785 loongarch_record_one_reloc (input_bfd, input_section, r_type,
2786 rel->r_offset, sym, h, rel->r_addend);
2788 if (r != bfd_reloc_continue)
2789 r = perform_relocation (rel, input_section, howto, relocation,
2790 input_bfd, contents);
2792 switch (r)
2794 case bfd_reloc_dangerous:
2795 case bfd_reloc_continue:
2796 case bfd_reloc_ok:
2797 continue;
2799 case bfd_reloc_overflow:
2800 /* Overflow value can't be filled in. */
2801 loongarch_dump_reloc_record (info->callbacks->info);
2802 info->callbacks->reloc_overflow
2803 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
2804 input_bfd, input_section, rel->r_offset);
2805 break;
2807 case bfd_reloc_outofrange:
2808 /* Stack state incorrect. */
2809 loongarch_dump_reloc_record (info->callbacks->info);
2810 info->callbacks->info
2811 ("%X%H: Internal stack state is incorrect.\n"
2812 "Want to push to full stack or pop from empty stack?\n",
2813 input_bfd, input_section, rel->r_offset);
2814 break;
2816 case bfd_reloc_notsupported:
2817 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
2818 input_section, rel->r_offset);
2819 break;
2821 default:
2822 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
2823 input_section, rel->r_offset);
2824 break;
2827 fatal = true;
2828 break;
2831 return !fatal;
2834 /* Finish up dynamic symbol handling. We set the contents of various
2835 dynamic sections here. */
2837 static bool
2838 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
2839 struct bfd_link_info *info,
2840 struct elf_link_hash_entry *h,
2841 Elf_Internal_Sym *sym)
2843 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2844 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2846 if (h->plt.offset != MINUS_ONE)
2848 size_t i, plt_idx;
2849 asection *plt, *gotplt, *relplt;
2850 bfd_vma got_address;
2851 uint32_t plt_entry[PLT_ENTRY_INSNS];
2852 bfd_byte *loc;
2853 Elf_Internal_Rela rela;
2855 if (htab->elf.splt)
2857 BFD_ASSERT ((h->type == STT_GNU_IFUNC
2858 && SYMBOL_REFERENCES_LOCAL (info, h))
2859 || h->dynindx != -1);
2861 plt = htab->elf.splt;
2862 gotplt = htab->elf.sgotplt;
2863 relplt = htab->elf.srelplt;
2864 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
2865 got_address =
2866 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
2868 else /* if (htab->elf.iplt) */
2870 BFD_ASSERT (h->type == STT_GNU_IFUNC
2871 && SYMBOL_REFERENCES_LOCAL (info, h));
2873 plt = htab->elf.iplt;
2874 gotplt = htab->elf.igotplt;
2875 relplt = htab->elf.irelplt;
2876 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
2877 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
2880 /* Find out where the .plt entry should go. */
2881 loc = plt->contents + h->plt.offset;
2883 /* Fill in the PLT entry itself. */
2884 if (!loongarch_make_plt_entry (got_address,
2885 sec_addr (plt) + h->plt.offset,
2886 plt_entry))
2887 return false;
2889 for (i = 0; i < PLT_ENTRY_INSNS; i++)
2890 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
2892 /* Fill in the initial value of the .got.plt entry. */
2893 loc = gotplt->contents + (got_address - sec_addr (gotplt));
2894 bfd_put_NN (output_bfd, sec_addr (plt), loc);
2896 rela.r_offset = got_address;
2898 /* TRUE if this is a PLT reference to a local IFUNC. */
2899 if (PLT_LOCAL_IFUNC_P(info, h))
2901 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2902 rela.r_addend = (h->root.u.def.value
2903 + h->root.u.def.section->output_section->vma
2904 + h->root.u.def.section->output_offset);
2906 else
2908 /* Fill in the entry in the .rela.plt section. */
2909 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
2910 rela.r_addend = 0;
2913 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
2914 bed->s->swap_reloca_out (output_bfd, &rela, loc);
2916 if (!h->def_regular)
2918 /* Mark the symbol as undefined, rather than as defined in
2919 the .plt section. Leave the value alone. */
2920 sym->st_shndx = SHN_UNDEF;
2921 /* If the symbol is weak, we do need to clear the value.
2922 Otherwise, the PLT entry would provide a definition for
2923 the symbol even if the symbol wasn't defined anywhere,
2924 and so the symbol would never be NULL. */
2925 if (!h->ref_regular_nonweak)
2926 sym->st_value = 0;
2930 if (h->got.offset != MINUS_ONE
2931 /* TLS got entry have been handled in elf_relocate_section. */
2932 && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
2933 /* have allocated got entry but not allocated rela before. */
2934 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2936 asection *sgot, *srela;
2937 Elf_Internal_Rela rela;
2938 bfd_vma off = h->got.offset & ~(bfd_vma) 1;
2940 /* This symbol has an entry in the GOT. Set it up. */
2942 sgot = htab->elf.sgot;
2943 srela = htab->elf.srelgot;
2944 BFD_ASSERT (sgot && srela);
2946 rela.r_offset = sec_addr (sgot) + off;
2948 if (h->def_regular
2949 && h->type == STT_GNU_IFUNC)
2951 if(h->plt.offset == MINUS_ONE)
2953 if (htab->elf.splt == NULL)
2954 srela = htab->elf.irelplt;
2956 if (SYMBOL_REFERENCES_LOCAL (info, h))
2958 asection *sec = h->root.u.def.section;
2959 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2960 rela.r_addend = h->root.u.def.value + sec->output_section->vma
2961 + sec->output_offset;
2962 bfd_put_NN (output_bfd, 0, sgot->contents + off);
2964 else
2966 BFD_ASSERT ((h->got.offset & 1) == 0);
2967 BFD_ASSERT (h->dynindx != -1);
2968 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2969 rela.r_addend = 0;
2970 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
2973 else if(bfd_link_pic (info))
2975 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2976 rela.r_addend = 0;
2977 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
2979 else
2981 asection *plt;
2982 /* For non-shared object, we can't use .got.plt, which
2983 contains the real function address if we need pointer
2984 equality. We load the GOT entry with the PLT entry. */
2985 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2986 bfd_put_NN (output_bfd,
2987 (plt->output_section->vma
2988 + plt->output_offset
2989 + h->plt.offset),
2990 sgot->contents + off);
2991 return true;
2994 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
2996 BFD_ASSERT (h->got.offset & 1 /* Has been filled in addr. */);
2997 asection *sec = h->root.u.def.section;
2998 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2999 rela.r_addend = (h->root.u.def.value + sec->output_section->vma
3000 + sec->output_offset);
3002 else
3004 BFD_ASSERT ((h->got.offset & 1) == 0);
3005 BFD_ASSERT (h->dynindx != -1);
3006 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3007 rela.r_addend = 0;
3010 loongarch_elf_append_rela (output_bfd, srela, &rela);
3013 if (h->needs_copy)
3015 Elf_Internal_Rela rela;
3016 asection *s;
3018 /* This symbols needs a copy reloc. Set it up. */
3019 BFD_ASSERT (h->dynindx != -1);
3021 rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
3022 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_COPY);
3023 rela.r_addend = 0;
3024 if (h->root.u.def.section == htab->elf.sdynrelro)
3025 s = htab->elf.sreldynrelro;
3026 else
3027 s = htab->elf.srelbss;
3028 loongarch_elf_append_rela (output_bfd, s, &rela);
3031 /* Mark some specially defined symbols as absolute. */
3032 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
3033 sym->st_shndx = SHN_ABS;
3035 return true;
3038 /* Finish up the dynamic sections. */
3040 static bool
3041 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
3042 asection *sdyn)
3044 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3045 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3046 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
3047 bfd_byte *dyncon, *dynconend;
3049 dynconend = sdyn->contents + sdyn->size;
3050 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
3052 Elf_Internal_Dyn dyn;
3053 asection *s;
3054 int skipped = 0;
3056 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
3058 switch (dyn.d_tag)
3060 case DT_PLTGOT:
3061 s = htab->elf.sgotplt;
3062 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3063 break;
3064 case DT_JMPREL:
3065 s = htab->elf.srelplt;
3066 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3067 break;
3068 case DT_PLTRELSZ:
3069 s = htab->elf.srelplt;
3070 dyn.d_un.d_val = s->size;
3071 break;
3072 case DT_TEXTREL:
3073 if ((info->flags & DF_TEXTREL) == 0)
3074 skipped = 1;
3075 break;
3076 case DT_FLAGS:
3077 if ((info->flags & DF_TEXTREL) == 0)
3078 dyn.d_un.d_val &= ~DF_TEXTREL;
3079 break;
3081 if (skipped)
3082 skipped_size += dynsize;
3083 else
3084 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
3086 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
3087 memset (dyncon - skipped_size, 0, skipped_size);
3088 return true;
3091 /* Finish up local dynamic symbol handling. We set the contents of
3092 various dynamic sections here. */
3094 static bool
3095 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
3097 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
3098 struct bfd_link_info *info = (struct bfd_link_info *) inf;
3100 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
3103 static bool
3104 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
3105 struct bfd_link_info *info)
3107 bfd *dynobj;
3108 asection *sdyn, *plt, *gotplt = NULL;
3109 struct loongarch_elf_link_hash_table *htab;
3111 htab = loongarch_elf_hash_table (info);
3112 BFD_ASSERT (htab);
3113 dynobj = htab->elf.dynobj;
3114 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3116 if (elf_hash_table (info)->dynamic_sections_created)
3118 BFD_ASSERT (htab->elf.splt && sdyn);
3120 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
3121 return false;
3124 plt = htab->elf.splt;
3125 gotplt = htab->elf.sgotplt;
3127 if (plt && 0 < plt->size)
3129 size_t i;
3130 uint32_t plt_header[PLT_HEADER_INSNS];
3131 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
3132 plt_header))
3133 return false;
3135 for (i = 0; i < PLT_HEADER_INSNS; i++)
3136 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
3138 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
3139 PLT_ENTRY_SIZE;
3142 if (htab->elf.sgotplt)
3144 asection *output_section = htab->elf.sgotplt->output_section;
3146 if (bfd_is_abs_section (output_section))
3148 _bfd_error_handler (_("discarded output section: `%pA'"),
3149 htab->elf.sgotplt);
3150 return false;
3153 if (0 < htab->elf.sgotplt->size)
3155 /* Write the first two entries in .got.plt, needed for the dynamic
3156 linker. */
3157 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
3159 bfd_put_NN (output_bfd, (bfd_vma) 0,
3160 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
3163 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3166 if (htab->elf.sgot)
3168 asection *output_section = htab->elf.sgot->output_section;
3170 if (0 < htab->elf.sgot->size)
3172 /* Set the first entry in the global offset table to the address of
3173 the dynamic section. */
3174 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
3175 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
3178 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3181 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
3182 htab_traverse (htab->loc_hash_table,
3183 (void *) elfNN_loongarch_finish_local_dynamic_symbol, info);
3185 return true;
3188 /* Return address for Ith PLT stub in section PLT, for relocation REL
3189 or (bfd_vma) -1 if it should not be included. */
3191 static bfd_vma
3192 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
3193 const arelent *rel ATTRIBUTE_UNUSED)
3195 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
3198 static enum elf_reloc_type_class
3199 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
3200 const asection *rel_sec ATTRIBUTE_UNUSED,
3201 const Elf_Internal_Rela *rela)
3203 struct loongarch_elf_link_hash_table *htab;
3204 htab = loongarch_elf_hash_table (info);
3206 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
3208 /* Check relocation against STT_GNU_IFUNC symbol if there are
3209 dynamic symbols. */
3210 bfd *abfd = info->output_bfd;
3211 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3212 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
3213 if (r_symndx != STN_UNDEF)
3215 Elf_Internal_Sym sym;
3216 if (!bed->s->swap_symbol_in (abfd,
3217 htab->elf.dynsym->contents
3218 + r_symndx * bed->s->sizeof_sym,
3219 0, &sym))
3221 /* xgettext:c-format */
3222 _bfd_error_handler (_("%pB symbol number %lu references"
3223 " nonexistent SHT_SYMTAB_SHNDX section"),
3224 abfd, r_symndx);
3225 /* Ideally an error class should be returned here. */
3227 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
3228 return reloc_class_ifunc;
3232 switch (ELFNN_R_TYPE (rela->r_info))
3234 case R_LARCH_IRELATIVE:
3235 return reloc_class_ifunc;
3236 case R_LARCH_RELATIVE:
3237 return reloc_class_relative;
3238 case R_LARCH_JUMP_SLOT:
3239 return reloc_class_plt;
3240 case R_LARCH_COPY:
3241 return reloc_class_copy;
3242 default:
3243 return reloc_class_normal;
3247 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3249 static void
3250 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
3251 struct elf_link_hash_entry *dir,
3252 struct elf_link_hash_entry *ind)
3254 struct elf_link_hash_entry *edir, *eind;
3256 edir = dir;
3257 eind = ind;
3259 if (eind->dyn_relocs != NULL)
3261 if (edir->dyn_relocs != NULL)
3263 struct elf_dyn_relocs **pp;
3264 struct elf_dyn_relocs *p;
3266 /* Add reloc counts against the indirect sym to the direct sym
3267 list. Merge any entries against the same section. */
3268 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
3270 struct elf_dyn_relocs *q;
3272 for (q = edir->dyn_relocs; q != NULL; q = q->next)
3273 if (q->sec == p->sec)
3275 q->pc_count += p->pc_count;
3276 q->count += p->count;
3277 *pp = p->next;
3278 break;
3280 if (q == NULL)
3281 pp = &p->next;
3283 *pp = edir->dyn_relocs;
3286 edir->dyn_relocs = eind->dyn_relocs;
3287 eind->dyn_relocs = NULL;
3290 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
3292 loongarch_elf_hash_entry(edir)->tls_type
3293 = loongarch_elf_hash_entry(eind)->tls_type;
3294 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
3296 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3299 #define PRSTATUS_SIZE 0x1d8
3300 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
3301 #define PRSTATUS_OFFSET_PR_PID 0x20
3302 #define ELF_GREGSET_T_SIZE 0x168
3303 #define PRSTATUS_OFFSET_PR_REG 0x70
3305 /* Support for core dump NOTE sections. */
3307 static bool
3308 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3310 switch (note->descsz)
3312 default:
3313 return false;
3315 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
3316 case PRSTATUS_SIZE:
3317 /* pr_cursig */
3318 elf_tdata (abfd)->core->signal =
3319 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
3321 /* pr_pid */
3322 elf_tdata (abfd)->core->lwpid =
3323 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
3324 break;
3327 /* Make a ".reg/999" section. */
3328 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
3329 note->descpos
3330 + PRSTATUS_OFFSET_PR_REG);
3333 #define PRPSINFO_SIZE 0x88
3334 #define PRPSINFO_OFFSET_PR_PID 0x18
3335 #define PRPSINFO_OFFSET_PR_FNAME 0x28
3336 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
3337 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
3338 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
3341 static bool
3342 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3344 switch (note->descsz)
3346 default:
3347 return false;
3349 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
3350 case PRPSINFO_SIZE:
3351 /* pr_pid */
3352 elf_tdata (abfd)->core->pid =
3353 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
3355 /* pr_fname */
3356 elf_tdata (abfd)->core->program =
3357 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
3358 PRPSINFO_SIZEOF_PR_FNAME);
3360 /* pr_psargs */
3361 elf_tdata (abfd)->core->command =
3362 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
3363 PRPSINFO_SIZEOF_PR_PS_ARGS);
3364 break;
3367 /* Note that for some reason, a spurious space is tacked
3368 onto the end of the args in some (at least one anyway)
3369 implementations, so strip it off if it exists. */
3372 char *command = elf_tdata (abfd)->core->command;
3373 int n = strlen (command);
3375 if (0 < n && command[n - 1] == ' ')
3376 command[n - 1] = '\0';
3379 return true;
3382 /* Set the right mach type. */
3383 static bool
3384 loongarch_elf_object_p (bfd *abfd)
3386 /* There are only two mach types in LoongArch currently. */
3387 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
3388 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
3389 else
3390 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
3391 return true;
3394 static asection *
3395 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
3396 Elf_Internal_Rela *rel,
3397 struct elf_link_hash_entry *h,
3398 Elf_Internal_Sym *sym)
3400 if (h != NULL)
3401 switch (ELFNN_R_TYPE (rel->r_info))
3403 case R_LARCH_GNU_VTINHERIT:
3404 case R_LARCH_GNU_VTENTRY:
3405 return NULL;
3408 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3411 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3412 executable PLT slots where the executable never takes the address of those
3413 functions, the function symbols are not added to the hash table. */
3415 static bool
3416 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
3418 if (h->plt.offset != (bfd_vma) -1
3419 && !h->def_regular
3420 && !h->pointer_equality_needed)
3421 return false;
3423 return _bfd_elf_hash_symbol (h);
3426 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
3427 #define TARGET_LITTLE_NAME "elfNN-loongarch"
3428 #define ELF_ARCH bfd_arch_loongarch
3429 #define ELF_TARGET_ID LARCH_ELF_DATA
3430 #define ELF_MACHINE_CODE EM_LOONGARCH
3431 #define ELF_MAXPAGESIZE 0x4000
3432 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
3433 #define bfd_elfNN_bfd_link_hash_table_create \
3434 loongarch_elf_link_hash_table_create
3435 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
3436 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
3437 #define elf_info_to_howto loongarch_info_to_howto_rela
3438 #define bfd_elfNN_bfd_merge_private_bfd_data \
3439 elfNN_loongarch_merge_private_bfd_data
3441 #define elf_backend_reloc_type_class loongarch_reloc_type_class
3442 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
3443 #define elf_backend_create_dynamic_sections \
3444 loongarch_elf_create_dynamic_sections
3445 #define elf_backend_check_relocs loongarch_elf_check_relocs
3446 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
3447 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
3448 #define elf_backend_relocate_section loongarch_elf_relocate_section
3449 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
3450 #define elf_backend_finish_dynamic_sections \
3451 loongarch_elf_finish_dynamic_sections
3452 #define elf_backend_object_p loongarch_elf_object_p
3453 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
3454 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
3455 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
3456 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
3457 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
3459 #include "elfNN-target.h"