[gdb/testsuite] Handle unordered dict in gdb.python/py-mi-notify.exp
[binutils-gdb.git] / bfd / elfnn-loongarch.c
blobc24b2600a9ad8c4f20ef91ad48a6fc6ac779714f
1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2025 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"
30 #include "opcode/loongarch.h"
32 static bool
33 loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
34 Elf_Internal_Rela *dst)
36 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
37 ELFNN_R_TYPE (dst->r_info));
38 return cache_ptr->howto != NULL;
41 /* LoongArch ELF linker hash entry. */
42 struct loongarch_elf_link_hash_entry
44 struct elf_link_hash_entry elf;
46 #define GOT_UNKNOWN 0
47 #define GOT_NORMAL 1
48 #define GOT_TLS_GD 2
49 #define GOT_TLS_IE 4
50 #define GOT_TLS_LE 8
51 #define GOT_TLS_GDESC 16
53 #define GOT_TLS_GD_BOTH_P(tls_type) \
54 ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
55 #define GOT_TLS_GD_ANY_P(tls_type) \
56 ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
57 char tls_type;
60 #define loongarch_elf_hash_entry(ent) \
61 ((struct loongarch_elf_link_hash_entry *) (ent))
63 struct _bfd_loongarch_elf_obj_tdata
65 struct elf_obj_tdata root;
67 /* The tls_type for each local got entry. */
68 char *local_got_tls_type;
71 #define _bfd_loongarch_elf_tdata(abfd) \
72 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
74 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
75 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
77 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
78 (*((h) != NULL \
79 ? &loongarch_elf_hash_entry (h)->tls_type \
80 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
82 #define is_loongarch_elf(bfd) \
83 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
84 && elf_tdata (bfd) != NULL \
85 && elf_object_id (bfd) == LARCH_ELF_DATA)
87 static bool
88 elfNN_loongarch_object (bfd *abfd)
90 return bfd_elf_allocate_object (abfd,
91 sizeof (struct _bfd_loongarch_elf_obj_tdata));
94 struct relr_entry
96 asection *sec;
97 bfd_vma off;
100 struct loongarch_elf_link_hash_table
102 struct elf_link_hash_table elf;
104 /* Short-cuts to get to dynamic linker sections. */
105 asection *sdyntdata;
107 /* Small local sym to section mapping cache. */
108 struct sym_cache sym_cache;
110 /* Used by local STT_GNU_IFUNC symbols. */
111 htab_t loc_hash_table;
112 void *loc_hash_memory;
114 /* The max alignment of output sections. */
115 bfd_vma max_alignment;
117 /* The data segment phase, don't relax the section
118 when it is exp_seg_relro_adjust. */
119 int *data_segment_phase;
121 /* Array of relative relocs to be emitted in DT_RELR format. */
122 bfd_size_type relr_alloc;
123 bfd_size_type relr_count;
124 struct relr_entry *relr;
126 /* Sorted output addresses of above relative relocs. */
127 bfd_vma *relr_sorted;
129 /* Layout recomputation count. */
130 bfd_size_type relr_layout_iter;
132 /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip
133 size_relative_relocs is updating the layout, relax_section may see
134 a partially updated state (some sections have vma updated but the
135 others do not), and it's unsafe to do the normal relaxation. */
136 bool layout_mutating_for_relr;
139 struct loongarch_elf_section_data
141 struct bfd_elf_section_data elf;
143 /* &htab->relr[i] where i is the smallest number s.t.
144 elf_section_data (htab->relr[i].sec) == &elf.
145 NULL if there exists no such i. */
146 struct relr_entry *relr;
149 /* We need an additional field in elf_section_data to handle complex
150 interactions between DT_RELR and relaxation. */
151 static bool
152 loongarch_elf_new_section_hook (bfd *abfd, asection *sec)
154 struct loongarch_elf_section_data *sdata;
156 sdata = bfd_zalloc (abfd, sizeof (*sdata));
157 if (!sdata)
158 return false;
159 sec->used_by_bfd = sdata;
161 return _bfd_elf_new_section_hook (abfd, sec);
164 #define loongarch_elf_section_data(x) \
165 ((struct loongarch_elf_section_data *) elf_section_data (x))
167 /* Get the LoongArch ELF linker hash table from a link_info structure. */
168 #define loongarch_elf_hash_table(p) \
169 ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
171 #define MINUS_ONE ((bfd_vma) 0 - 1)
173 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
175 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
176 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
178 #define PLT_HEADER_INSNS 8
179 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
181 #define PLT_ENTRY_INSNS 4
182 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
184 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
186 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT
187 resolver _dl_runtime_resolve, the other is used for link map. */
188 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
190 #define elf_backend_want_got_plt 1
192 #define elf_backend_plt_readonly 1
194 #define elf_backend_want_plt_sym 1
195 #define elf_backend_plt_alignment 4
196 #define elf_backend_can_gc_sections 1
197 #define elf_backend_can_refcount 1
198 #define elf_backend_want_got_sym 1
200 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
202 #define elf_backend_want_dynrelro 1
203 #define elf_backend_rela_normal 1
204 #define elf_backend_default_execstack 0
206 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
207 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
208 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
209 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
210 || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
211 || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
212 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
214 #define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \
215 ((R_TYPE) == R_LARCH_TLS_LE_HI20 \
216 || (R_TYPE) == R_LARCH_TLS_LE_LO12 \
217 || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
218 || (R_TYPE) == R_LARCH_TLS_LE64_HI12)
220 #define IS_CALL_RELOC(R_TYPE) \
221 ((R_TYPE) == R_LARCH_B26 \
222 ||(R_TYPE) == R_LARCH_CALL36)
224 /* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx,
225 and set NEED_RELOC to true used in allocate_dynrelocs and
226 loongarch_elf_relocate_section for TLS GD/IE. */
227 #define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
228 do \
230 if ((H) != NULL \
231 && (H)->dynindx != -1 \
232 && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \
233 bfd_link_pic (INFO), (H))) \
234 (INDX) = (H)->dynindx; \
235 if (((H) == NULL \
236 || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
237 || (H)->root.type != bfd_link_hash_undefweak) \
238 && (!bfd_link_executable (INFO) \
239 || (INDX) != 0)) \
240 (NEED_RELOC) = true; \
242 while (0)
244 /* TL;DR always use it in this file instead when you want to type
245 SYMBOL_REFERENCES_LOCAL.
247 It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local
248 protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but
249 let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people.
251 We do generate a PLT entry when someone attempts to la.pcrel an external
252 function. But we never really implemented "R_LARCH_COPY", thus we've
253 never supported la.pcrel an external symbol unless the loaded address is
254 only used for locating a function to be called. Thus the PLT entry is
255 a normal PLT entry, not intended to be a so-called "canonical PLT entry"
256 on the ports supporting copy relocation. So attempting to la.pcrel an
257 external function will just break pointer equality, even it's a
258 STV_DEFAULT function:
260 $ cat t.c
261 #include <assert.h>
262 void check(void *p) {assert(p == check);}
263 $ cat main.c
264 extern void check(void *);
265 int main(void) { check(check); }
266 $ cc t.c -fPIC -shared -o t.so
267 $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. -fpie -pie
268 $ ./a.out
269 a.out: t.c:2: check: Assertion `p == check' failed.
270 Aborted
272 Thus handling STV_PROTECTED function specially just fixes nothing:
273 adding -fvisibility=protected compiling t.c will not magically fix
274 the inequality. The only possible and correct fix is not to use
275 -mdirect-extern-access.
277 So we should remove this special handling, because it's only an
278 unsuccessful workaround for invalid code and it's penalizing valid
279 code. */
280 #define LARCH_REF_LOCAL(info, h) \
281 (_bfd_elf_symbol_refs_local_p ((h), (info), true))
283 /* Generate a PLT header. */
285 static bool
286 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
287 uint32_t *entry)
289 bfd_vma pcrel = got_plt_addr - plt_header_addr;
290 bfd_vma hi, lo;
292 if (pcrel + 0x80000800 > 0xffffffff)
294 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
295 bfd_set_error (bfd_error_bad_value);
296 return false;
298 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
299 lo = pcrel & 0xfff;
301 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
302 sub.[wd] $t1, $t1, $t3
303 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
304 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
305 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
306 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
307 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
308 jirl $r0, $t3, 0 */
310 if (GOT_ENTRY_SIZE == 8)
312 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
313 entry[1] = 0x0011bdad;
314 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
315 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
316 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
317 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
318 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
319 entry[7] = 0x4c0001e0;
321 else
323 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
324 entry[1] = 0x00113dad;
325 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
326 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
327 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
328 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
329 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
330 entry[7] = 0x4c0001e0;
332 return true;
335 /* Generate a PLT entry. */
337 static bool
338 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
339 uint32_t *entry)
341 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
342 bfd_vma hi, lo;
344 if (pcrel + 0x80000800 > 0xffffffff)
346 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
347 bfd_set_error (bfd_error_bad_value);
348 return false;
350 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
351 lo = pcrel & 0xfff;
353 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
354 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
355 | (lo & 0xfff) << 10);
356 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
357 entry[3] = 0x03400000; /* nop */
359 return true;
362 /* Create an entry in an LoongArch ELF linker hash table. */
364 static struct bfd_hash_entry *
365 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
366 const char *string)
368 struct loongarch_elf_link_hash_entry *eh;
370 /* Allocate the structure if it has not already been allocated by a
371 subclass. */
372 if (entry == NULL)
374 entry = bfd_hash_allocate (table, sizeof (*eh));
375 if (entry == NULL)
376 return entry;
379 /* Call the allocation method of the superclass. */
380 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
381 if (entry != NULL)
383 eh = (struct loongarch_elf_link_hash_entry *) entry;
384 eh->tls_type = GOT_UNKNOWN;
387 return entry;
390 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
391 for local symbol so that we can handle local STT_GNU_IFUNC symbols
392 as global symbol. We reuse indx and dynstr_index for local symbol
393 hash since they aren't used by global symbols in this backend. */
395 static hashval_t
396 elfNN_loongarch_local_htab_hash (const void *ptr)
398 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
399 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
402 /* Compare local hash entries. */
404 static int
405 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
407 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
408 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
410 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
413 /* Find and/or create a hash entry for local symbol. */
414 static struct elf_link_hash_entry *
415 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
416 bfd *abfd, const Elf_Internal_Rela *rel,
417 bool create)
419 struct loongarch_elf_link_hash_entry e, *ret;
420 asection *sec = abfd->sections;
421 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
422 void **slot;
424 e.elf.indx = sec->id;
425 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
426 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
427 create ? INSERT : NO_INSERT);
429 if (!slot)
430 return NULL;
432 if (*slot)
434 ret = (struct loongarch_elf_link_hash_entry *) *slot;
435 return &ret->elf;
438 ret = ((struct loongarch_elf_link_hash_entry *)
439 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
440 sizeof (struct loongarch_elf_link_hash_entry)));
441 if (ret)
443 memset (ret, 0, sizeof (*ret));
444 ret->elf.indx = sec->id;
445 ret->elf.pointer_equality_needed = 0;
446 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
447 ret->elf.dynindx = -1;
448 ret->elf.needs_plt = 0;
449 ret->elf.plt.refcount = -1;
450 ret->elf.got.refcount = -1;
451 ret->elf.def_dynamic = 0;
452 ret->elf.def_regular = 1;
453 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
454 ret->elf.ref_regular = 0;
455 ret->elf.forced_local = 1;
456 ret->elf.root.type = bfd_link_hash_defined;
457 *slot = ret;
459 return &ret->elf;
462 /* Destroy an LoongArch elf linker hash table. */
464 static void
465 elfNN_loongarch_link_hash_table_free (bfd *obfd)
467 struct loongarch_elf_link_hash_table *ret;
468 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
470 if (ret->loc_hash_table)
471 htab_delete (ret->loc_hash_table);
472 if (ret->loc_hash_memory)
473 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
475 _bfd_elf_link_hash_table_free (obfd);
478 /* Create a LoongArch ELF linker hash table. */
480 static struct bfd_link_hash_table *
481 loongarch_elf_link_hash_table_create (bfd *abfd)
483 struct loongarch_elf_link_hash_table *ret;
484 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
486 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
487 if (ret == NULL)
488 return NULL;
490 if (!_bfd_elf_link_hash_table_init
491 (&ret->elf, abfd, link_hash_newfunc,
492 sizeof (struct loongarch_elf_link_hash_entry)))
494 free (ret);
495 return NULL;
498 ret->max_alignment = MINUS_ONE;
500 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
501 elfNN_loongarch_local_htab_eq, NULL);
502 ret->loc_hash_memory = objalloc_create ();
503 if (!ret->loc_hash_table || !ret->loc_hash_memory)
505 elfNN_loongarch_link_hash_table_free (abfd);
506 return NULL;
508 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
510 return &ret->elf.root;
513 /* Merge backend specific data from an object file to the output
514 object file when linking. */
516 static bool
517 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
519 bfd *obfd = info->output_bfd;
520 flagword in_flags = elf_elfheader (ibfd)->e_flags;
521 flagword out_flags = elf_elfheader (obfd)->e_flags;
523 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
524 return true;
526 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
528 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
529 "the selected emulation:\n"
530 " target emulation `%s' does not match `%s'"),
531 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
532 return false;
535 if (!_bfd_elf_merge_object_attributes (ibfd, info))
536 return false;
538 /* If the input BFD is not a dynamic object and it does not contain any
539 non-data sections, do not account its ABI. For example, various
540 packages produces such data-only relocatable objects with
541 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
542 But they are compatible with all ABIs. */
543 if (!(ibfd->flags & DYNAMIC))
545 asection *sec;
546 bool have_code_sections = false;
547 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
548 if ((bfd_section_flags (sec)
549 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
550 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
552 have_code_sections = true;
553 break;
555 if (!have_code_sections)
556 return true;
559 if (!elf_flags_init (obfd))
561 elf_flags_init (obfd) = true;
562 elf_elfheader (obfd)->e_flags = in_flags;
563 return true;
565 else if (out_flags != in_flags)
567 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
568 && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
569 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
570 && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
572 elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
573 out_flags = elf_elfheader (obfd)->e_flags;
574 in_flags = out_flags;
578 /* Disallow linking different ABIs. */
579 /* Only check relocation version.
580 The obj_v0 is compatible with obj_v1. */
581 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
583 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
584 goto fail;
587 return true;
589 fail:
590 bfd_set_error (bfd_error_bad_value);
591 return false;
594 /* Create the .got section. */
596 static bool
597 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
599 flagword flags;
600 char *name;
601 asection *s, *s_got;
602 struct elf_link_hash_entry *h;
603 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
604 struct elf_link_hash_table *htab = elf_hash_table (info);
606 /* This function may be called more than once. */
607 if (htab->sgot != NULL)
608 return true;
610 flags = bed->dynamic_sec_flags;
611 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
612 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
614 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
615 return false;
616 htab->srelgot = s;
618 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
619 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
620 return false;
621 htab->sgot = s;
623 /* The first bit of the global offset table is the header. */
624 s->size += bed->got_header_size;
626 if (bed->want_got_plt)
628 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
629 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
630 return false;
631 htab->sgotplt = s;
633 /* Reserve room for the header. */
634 s->size = GOTPLT_HEADER_SIZE;
637 if (bed->want_got_sym)
639 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
640 section. We don't do this in the linker script because we don't want
641 to define the symbol if we are not creating a global offset table. */
642 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
643 "_GLOBAL_OFFSET_TABLE_");
644 elf_hash_table (info)->hgot = h;
645 if (h == NULL)
646 return false;
648 return true;
651 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
652 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
653 hash table. */
655 static bool
656 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
658 struct loongarch_elf_link_hash_table *htab;
660 htab = loongarch_elf_hash_table (info);
661 BFD_ASSERT (htab != NULL);
663 if (!loongarch_elf_create_got_section (dynobj, info))
664 return false;
666 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
667 return false;
669 if (!bfd_link_pic (info))
670 htab->sdyntdata
671 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
672 SEC_ALLOC | SEC_THREAD_LOCAL);
674 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
675 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
676 abort ();
678 return true;
681 static bool
682 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
683 struct bfd_link_info *info,
684 struct elf_link_hash_entry *h,
685 unsigned long symndx,
686 char tls_type,
687 bool with_relax_reloc)
689 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
690 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
692 /* This is a global offset table entry for a local symbol. */
693 if (elf_local_got_refcounts (abfd) == NULL)
695 bfd_size_type size =
696 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
697 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
698 return false;
699 _bfd_loongarch_elf_local_got_tls_type (abfd) =
700 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
703 switch (tls_type)
705 case GOT_NORMAL:
706 case GOT_TLS_GD:
707 case GOT_TLS_IE:
708 case GOT_TLS_GDESC:
709 /* Need GOT. */
710 if (htab->elf.sgot == NULL
711 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
712 return false;
713 if (h)
715 if (h->got.refcount < 0)
716 h->got.refcount = 0;
717 h->got.refcount++;
719 else
720 elf_local_got_refcounts (abfd)[symndx]++;
721 break;
722 case GOT_TLS_LE:
723 /* No need for GOT. */
724 break;
725 default:
726 _bfd_error_handler (_("Internal error: unreachable."));
727 return false;
730 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
731 *new_tls_type |= tls_type;
733 /* If DESC relocs can do transitions and accessed by both IE and DESC,
734 transition DESC to IE. */
735 if (with_relax_reloc
736 && (*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
737 *new_tls_type &= ~ (GOT_TLS_GDESC);
739 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
741 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
742 "thread local symbol"),
743 abfd,
744 h ? h->root.root.string : "<local>");
745 return false;
748 return true;
751 static unsigned int
752 loongarch_reloc_got_type (unsigned int r_type)
754 switch (r_type)
756 case R_LARCH_TLS_DESC_PC_HI20:
757 case R_LARCH_TLS_DESC_PC_LO12:
758 case R_LARCH_TLS_DESC_LD:
759 case R_LARCH_TLS_DESC_CALL:
760 return GOT_TLS_GDESC;
762 case R_LARCH_TLS_IE_PC_HI20:
763 case R_LARCH_TLS_IE_PC_LO12:
764 return GOT_TLS_IE;
766 default:
767 break;
769 return GOT_UNKNOWN;
772 /* Return true if tls type transition can be performed. */
773 static bool
774 loongarch_can_trans_tls (bfd *input_bfd,
775 struct bfd_link_info *info,
776 struct elf_link_hash_entry *h,
777 unsigned int r_symndx,
778 unsigned int r_type)
780 char symbol_tls_type;
781 unsigned int reloc_got_type;
783 /* Only TLS DESC/IE in normal code mode will perform type
784 transition. */
785 if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type))
786 return false;
788 /* Obtaining tls got type here may occur before
789 loongarch_elf_record_tls_and_got_reference, so it is necessary
790 to ensure that tls got type has been initialized, otherwise it
791 is set to GOT_UNKNOWN. */
792 symbol_tls_type = GOT_UNKNOWN;
793 if (_bfd_loongarch_elf_local_got_tls_type (input_bfd) || h)
794 symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
796 reloc_got_type = loongarch_reloc_got_type (r_type);
798 if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
799 return true;
801 if (! bfd_link_executable (info))
802 return false;
804 if (h && h->root.type == bfd_link_hash_undefweak)
805 return false;
807 return true;
810 /* The type of relocation that can be transitioned. */
811 static unsigned int
812 loongarch_tls_transition_without_check (struct bfd_link_info *info,
813 unsigned int r_type,
814 struct elf_link_hash_entry *h)
816 bool local_exec = bfd_link_executable (info)
817 && LARCH_REF_LOCAL (info, h);
819 switch (r_type)
821 case R_LARCH_TLS_DESC_PC_HI20:
822 return (local_exec
823 ? R_LARCH_TLS_LE_HI20
824 : R_LARCH_TLS_IE_PC_HI20);
826 case R_LARCH_TLS_DESC_PC_LO12:
827 return (local_exec
828 ? R_LARCH_TLS_LE_LO12
829 : R_LARCH_TLS_IE_PC_LO12);
831 case R_LARCH_TLS_DESC_LD:
832 case R_LARCH_TLS_DESC_CALL:
833 return R_LARCH_NONE;
835 case R_LARCH_TLS_IE_PC_HI20:
836 return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
838 case R_LARCH_TLS_IE_PC_LO12:
839 return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
841 default:
842 break;
845 return r_type;
848 static unsigned int
849 loongarch_tls_transition (bfd *input_bfd,
850 struct bfd_link_info *info,
851 struct elf_link_hash_entry *h,
852 unsigned int r_symndx,
853 unsigned int r_type)
855 if (! loongarch_can_trans_tls (input_bfd, info, h, r_symndx, r_type))
856 return r_type;
858 return loongarch_tls_transition_without_check (info, r_type, h);
861 static bool
862 bad_static_reloc (struct bfd_link_info *info,
863 bfd *abfd, const Elf_Internal_Rela *rel,
864 asection *sec, unsigned r_type,
865 struct elf_link_hash_entry *h,
866 Elf_Internal_Sym *isym)
868 reloc_howto_type * r = loongarch_elf_rtype_to_howto (abfd, r_type);
869 const char *object;
870 const char *pic_opt;
871 const char *name = NULL;
873 /* If this, the problem is we are referring an external symbol in
874 a way only working for local symbols, not PC-relative vs.
875 absolute. */
876 bool bad_extern_access =
877 (bfd_link_pde (info)
878 || r_type == R_LARCH_PCREL20_S2
879 || r_type == R_LARCH_PCALA_HI20);
881 if (h)
882 name = h->root.root.string;
883 else if (isym)
884 name = bfd_elf_string_from_elf_section (abfd,
885 elf_symtab_hdr (abfd).sh_link,
886 isym->st_name);
887 if (name == NULL || *name == '\0')
888 name = "<nameless>";
890 if (bfd_link_dll (info))
892 object = _("a shared object");
893 pic_opt = "-fPIC";
895 else
897 if (bfd_link_pie (info))
898 object = _("a PIE object");
899 else
900 object = _("a PDE object");
902 pic_opt = bad_extern_access ? "-mno-direct-extern-access" : "-fPIE";
905 (*_bfd_error_handler)
906 (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
907 "%s; recompile with %s%s"),
908 abfd, sec, (long) rel->r_offset, r ? r->name : _("<unknown>"), name,
909 object, pic_opt,
910 bad_extern_access ? _(" and check the symbol visibility") : "");
911 bfd_set_error (bfd_error_bad_value);
912 return false;
915 /* Look through the relocs for a section during the first phase, and
916 allocate space in the global offset table or procedure linkage
917 table. */
919 static bool
920 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
921 asection *sec, const Elf_Internal_Rela *relocs)
923 struct loongarch_elf_link_hash_table *htab;
924 Elf_Internal_Shdr *symtab_hdr;
925 struct elf_link_hash_entry **sym_hashes;
926 const Elf_Internal_Rela *rel;
927 asection *sreloc = NULL;
929 if (bfd_link_relocatable (info))
930 return true;
932 htab = loongarch_elf_hash_table (info);
933 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
934 sym_hashes = elf_sym_hashes (abfd);
936 if (htab->elf.dynobj == NULL)
937 htab->elf.dynobj = abfd;
939 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
941 unsigned int r_type;
942 unsigned int r_symndx;
943 struct elf_link_hash_entry *h;
944 bool is_abs_symbol = false;
945 Elf_Internal_Sym *isym = NULL;
947 r_symndx = ELFNN_R_SYM (rel->r_info);
948 r_type = ELFNN_R_TYPE (rel->r_info);
950 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
952 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
953 return false;
956 if (r_symndx < symtab_hdr->sh_info)
958 /* A local symbol. */
959 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
960 if (isym == NULL)
961 return false;
963 is_abs_symbol = isym->st_shndx == SHN_ABS;
964 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
966 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
967 if (h == NULL)
968 return false;
970 h->type = STT_GNU_IFUNC;
971 h->ref_regular = 1;
973 else
974 h = NULL;
976 else
978 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
979 while (h->root.type == bfd_link_hash_indirect
980 || h->root.type == bfd_link_hash_warning)
981 h = (struct elf_link_hash_entry *) h->root.u.i.link;
982 is_abs_symbol = bfd_is_abs_symbol (&h->root);
985 /* It is referenced by a non-shared object. */
986 if (h != NULL)
987 h->ref_regular = 1;
989 if (h && h->type == STT_GNU_IFUNC)
991 if (htab->elf.dynobj == NULL)
992 htab->elf.dynobj = abfd;
994 /* Create 'irelifunc' in PIC object. */
995 if (bfd_link_pic (info)
996 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
997 return false;
998 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
999 else if (!htab->elf.splt
1000 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
1001 return false;
1002 /* Create the ifunc sections, iplt and ipltgot, for static
1003 executables. */
1004 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
1005 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
1006 return false;
1008 if (h->plt.refcount < 0)
1009 h->plt.refcount = 0;
1010 h->plt.refcount++;
1011 h->needs_plt = 1;
1013 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
1016 int need_dynreloc = 0;
1017 int only_need_pcrel = 0;
1019 /* Type transitions are only possible with relocations accompanied
1020 by R_LARCH_RELAX. */
1021 bool with_relax_reloc = false;
1022 if (rel + 1 != relocs + sec->reloc_count
1023 && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX)
1025 r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type);
1026 with_relax_reloc = true;
1029 /* I don't want to spend time supporting DT_RELR with old object
1030 files doing stack-based relocs. */
1031 if (info->enable_dt_relr
1032 && r_type >= R_LARCH_SOP_PUSH_PCREL
1033 && r_type <= R_LARCH_SOP_POP_32_U)
1035 /* xgettext:c-format */
1036 _bfd_error_handler (_("%pB: stack based reloc type (%u) is not "
1037 "supported with -z pack-relative-relocs"),
1038 abfd, r_type);
1039 return false;
1042 switch (r_type)
1044 case R_LARCH_GOT_PC_HI20:
1045 case R_LARCH_GOT_HI20:
1046 case R_LARCH_SOP_PUSH_GPREL:
1047 /* For la.global. */
1048 if (h)
1049 h->pointer_equality_needed = 1;
1050 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
1051 r_symndx,
1052 GOT_NORMAL,
1053 with_relax_reloc))
1054 return false;
1055 break;
1057 case R_LARCH_TLS_LD_PC_HI20:
1058 case R_LARCH_TLS_LD_HI20:
1059 case R_LARCH_TLS_GD_PC_HI20:
1060 case R_LARCH_TLS_GD_HI20:
1061 case R_LARCH_SOP_PUSH_TLS_GD:
1062 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
1063 r_symndx,
1064 GOT_TLS_GD,
1065 with_relax_reloc))
1066 return false;
1067 break;
1069 case R_LARCH_TLS_IE_PC_HI20:
1070 case R_LARCH_TLS_IE_HI20:
1071 case R_LARCH_SOP_PUSH_TLS_GOT:
1072 if (bfd_link_pic (info))
1073 /* May fail for lazy-bind. */
1074 info->flags |= DF_STATIC_TLS;
1076 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
1077 r_symndx,
1078 GOT_TLS_IE,
1079 with_relax_reloc))
1080 return false;
1081 break;
1083 case R_LARCH_TLS_LE_HI20:
1084 case R_LARCH_TLS_LE_HI20_R:
1085 case R_LARCH_SOP_PUSH_TLS_TPREL:
1086 if (!bfd_link_executable (info))
1087 return bad_static_reloc (info, abfd, rel, sec, r_type, h, isym);
1089 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
1090 r_symndx,
1091 GOT_TLS_LE,
1092 with_relax_reloc))
1093 return false;
1094 break;
1096 case R_LARCH_TLS_DESC_PC_HI20:
1097 case R_LARCH_TLS_DESC_HI20:
1098 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
1099 r_symndx,
1100 GOT_TLS_GDESC,
1101 with_relax_reloc))
1102 return false;
1103 break;
1105 case R_LARCH_ABS_HI20:
1106 if (bfd_link_pic (info))
1107 return bad_static_reloc (info, abfd, rel, sec, r_type, h, isym);
1109 /* Fall through. */
1110 case R_LARCH_SOP_PUSH_ABSOLUTE:
1111 if (h != NULL)
1112 /* If this reloc is in a read-only section, we might
1113 need a copy reloc. We can't check reliably at this
1114 stage whether the section is read-only, as input
1115 sections have not yet been mapped to output sections.
1116 Tentatively set the flag for now, and correct in
1117 adjust_dynamic_symbol. */
1118 h->non_got_ref = 1;
1119 break;
1121 /* Since shared library global symbols interpose, any
1122 PC-relative relocations against external symbols
1123 should not be used to build shared libraries.
1124 In static PIE undefined weak symbols may be allowed
1125 by rewriting pcaddi to addi.w if addend is in [-2048, 2048). */
1126 case R_LARCH_PCREL20_S2:
1127 if (bfd_link_pic (info)
1128 && (sec->flags & SEC_ALLOC) != 0
1129 && (sec->flags & SEC_READONLY) != 0
1130 && ! LARCH_REF_LOCAL (info, h)
1131 && (!info->nointerp
1132 || h->root.type != bfd_link_hash_undefweak))
1133 return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL);
1135 break;
1137 /* For normal cmodel, pcalau12i + addi.d/w used to data.
1138 For first version medium cmodel, pcalau12i + jirl are used to
1139 function call, it need to creat PLT entry for STT_FUNC and
1140 STT_GNU_IFUNC type symbol. */
1141 case R_LARCH_PCALA_HI20:
1142 if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
1144 /* For pcalau12i + jirl. */
1145 h->needs_plt = 1;
1146 if (h->plt.refcount < 0)
1147 h->plt.refcount = 0;
1148 h->plt.refcount++;
1150 h->non_got_ref = 1;
1151 h->pointer_equality_needed = 1;
1154 /* PC-relative relocations are allowed For first version
1155 medium cmodel function call. Those against undefined
1156 weak symbol are allowed for static PIE by rewritting
1157 pcalau12i to lu12i.w. */
1158 if (h != NULL && !h->needs_plt
1159 && bfd_link_pic (info)
1160 && (sec->flags & SEC_ALLOC) != 0
1161 && (sec->flags & SEC_READONLY) != 0
1162 && ! LARCH_REF_LOCAL (info, h)
1163 && (!info->nointerp
1164 || h->root.type != bfd_link_hash_undefweak))
1165 return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL);
1167 break;
1169 case R_LARCH_B16:
1170 case R_LARCH_B21:
1171 case R_LARCH_B26:
1172 case R_LARCH_CALL36:
1173 if (h != NULL)
1175 h->needs_plt = 1;
1176 if (!bfd_link_pic (info))
1177 h->non_got_ref = 1;
1179 /* We try to create PLT stub for all non-local function. */
1180 if (h->plt.refcount < 0)
1181 h->plt.refcount = 0;
1182 h->plt.refcount++;
1185 break;
1187 case R_LARCH_SOP_PUSH_PCREL:
1188 if (h != NULL)
1190 if (!bfd_link_pic (info))
1191 h->non_got_ref = 1;
1193 /* We try to create PLT stub for all non-local function. */
1194 if (h->plt.refcount < 0)
1195 h->plt.refcount = 0;
1196 h->plt.refcount++;
1197 h->pointer_equality_needed = 1;
1200 break;
1202 case R_LARCH_SOP_PUSH_PLT_PCREL:
1203 /* This symbol requires a procedure linkage table entry. We
1204 actually build the entry in adjust_dynamic_symbol,
1205 because this might be a case of linking PIC code without
1206 linking in any dynamic objects, in which case we don't
1207 need to generate a procedure linkage table after all. */
1208 if (h != NULL)
1210 h->needs_plt = 1;
1211 if (h->plt.refcount < 0)
1212 h->plt.refcount = 0;
1213 h->plt.refcount++;
1215 break;
1217 case R_LARCH_TLS_DTPREL32:
1218 case R_LARCH_TLS_DTPREL64:
1219 need_dynreloc = 1;
1220 only_need_pcrel = 1;
1221 break;
1223 case R_LARCH_32:
1224 if (ARCH_SIZE > 32
1225 && bfd_link_pic (info)
1226 && (sec->flags & SEC_ALLOC) != 0)
1228 if (!is_abs_symbol)
1230 _bfd_error_handler
1231 (_("%pB: relocation R_LARCH_32 against non-absolute "
1232 "symbol `%s' cannot be used in ELFCLASS64 when "
1233 "making a shared object or PIE"),
1234 abfd, h ? h->root.root.string : "a local symbol");
1235 bfd_set_error (bfd_error_bad_value);
1236 return false;
1240 /* Fall through. */
1241 case R_LARCH_JUMP_SLOT:
1242 case R_LARCH_64:
1244 /* Resolved to const. */
1245 if (is_abs_symbol)
1246 break;
1248 need_dynreloc = 1;
1250 /* If resolved symbol is defined in this object,
1251 1. Under pie, the symbol is known. We convert it
1252 into R_LARCH_RELATIVE and need load-addr still.
1253 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
1254 3. Under dll, R_LARCH_NN can't be changed normally, since
1255 its defination could be covered by the one in executable.
1256 For symbolic, we convert it into R_LARCH_RELATIVE.
1257 Thus, only under pde, it needs pcrel only. We discard it. */
1258 only_need_pcrel = bfd_link_pde (info);
1260 if (h != NULL
1261 && (!bfd_link_pic (info)
1262 || h->type == STT_GNU_IFUNC))
1264 /* This reloc might not bind locally. */
1265 h->non_got_ref = 1;
1266 h->pointer_equality_needed = 1;
1268 if (!h->def_regular
1269 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
1271 /* We may need a .plt entry if the symbol is a function
1272 defined in a shared lib or is a function referenced
1273 from the code or read-only section. */
1274 h->plt.refcount += 1;
1277 break;
1279 case R_LARCH_GNU_VTINHERIT:
1280 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1281 return false;
1282 break;
1284 case R_LARCH_GNU_VTENTRY:
1285 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1286 return false;
1287 break;
1289 case R_LARCH_ALIGN:
1290 /* Check against irrational R_LARCH_ALIGN relocs which may cause
1291 removing an odd number of bytes and disrupt DT_RELR. */
1292 if (rel->r_offset % 4 != 0)
1294 /* xgettext:c-format */
1295 _bfd_error_handler (
1296 _("%pB: R_LARCH_ALIGN with offset %" PRId64 " not aligned "
1297 "to instruction boundary"),
1298 abfd, (uint64_t) rel->r_offset);
1299 return false;
1301 break;
1303 default:
1304 break;
1307 /* Record some info for sizing and allocating dynamic entry. */
1308 if (need_dynreloc && (sec->flags & SEC_ALLOC))
1310 /* When creating a shared object, we must copy these
1311 relocs into the output file. We create a reloc
1312 section in dynobj and make room for the reloc. */
1313 struct elf_dyn_relocs *p;
1314 struct elf_dyn_relocs **head;
1316 if (sreloc == NULL)
1318 sreloc
1319 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
1320 LARCH_ELF_LOG_WORD_BYTES,
1321 abfd, /*rela?*/ true);
1322 if (sreloc == NULL)
1323 return false;
1326 /* If this is a global symbol, we count the number of
1327 relocations we need for this symbol. */
1328 if (h != NULL)
1329 head = &h->dyn_relocs;
1330 else
1332 /* Track dynamic relocs needed for local syms too.
1333 We really need local syms available to do this
1334 easily. Oh well. */
1336 asection *s;
1337 void *vpp;
1339 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1340 if (s == NULL)
1341 s = sec;
1343 vpp = &elf_section_data (s)->local_dynrel;
1344 head = (struct elf_dyn_relocs **) vpp;
1347 p = *head;
1348 if (p == NULL || p->sec != sec)
1350 bfd_size_type amt = sizeof *p;
1351 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
1352 if (p == NULL)
1353 return false;
1354 p->next = *head;
1355 *head = p;
1356 p->sec = sec;
1357 p->count = 0;
1358 p->pc_count = 0;
1361 p->count++;
1362 p->pc_count += only_need_pcrel;
1366 return true;
1369 /* Find dynamic relocs for H that apply to read-only sections. */
1371 static asection *
1372 readonly_dynrelocs (struct elf_link_hash_entry *h)
1374 struct elf_dyn_relocs *p;
1376 for (p = h->dyn_relocs; p != NULL; p = p->next)
1378 asection *s = p->sec->output_section;
1380 if (s != NULL && (s->flags & SEC_READONLY) != 0)
1381 return p->sec;
1383 return NULL;
1386 /* Adjust a symbol defined by a dynamic object and referenced by a
1387 regular object. The current definition is in some section of the
1388 dynamic object, but we're not including those sections. We have to
1389 change the definition to something the rest of the link can
1390 understand. */
1391 static bool
1392 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1393 struct elf_link_hash_entry *h)
1395 struct loongarch_elf_link_hash_table *htab;
1396 bfd *dynobj;
1398 htab = loongarch_elf_hash_table (info);
1399 BFD_ASSERT (htab != NULL);
1401 dynobj = htab->elf.dynobj;
1403 /* Make sure we know what is going on here. */
1404 BFD_ASSERT (dynobj != NULL
1405 && (h->needs_plt
1406 || h->type == STT_GNU_IFUNC
1407 || h->is_weakalias
1408 || (h->def_dynamic
1409 && h->ref_regular
1410 && !h->def_regular)));
1412 /* If this is a function, put it in the procedure linkage table. We
1413 will fill in the contents of the procedure linkage table later
1414 (although we could actually do it here). */
1415 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
1417 if (h->plt.refcount <= 0
1418 || (h->type != STT_GNU_IFUNC
1419 && (LARCH_REF_LOCAL (info, h)
1420 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1421 && h->root.type == bfd_link_hash_undefweak))))
1423 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1424 in an input file, but the symbol was never referred to by a
1425 dynamic object, or if all references were garbage collected.
1426 In such a case, we don't actually need to build a PLT entry. */
1427 h->plt.offset = MINUS_ONE;
1428 h->needs_plt = 0;
1431 return true;
1433 else
1434 h->plt.offset = MINUS_ONE;
1436 /* If this is a weak symbol, and there is a real definition, the
1437 processor independent code will have arranged for us to see the
1438 real definition first, and we can just use the same value. */
1439 if (h->is_weakalias)
1441 struct elf_link_hash_entry *def = weakdef (h);
1442 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1443 h->root.u.def.section = def->root.u.def.section;
1444 h->root.u.def.value = def->root.u.def.value;
1445 return true;
1448 /* R_LARCH_COPY is not adept glibc, not to generate. */
1449 /* Can not print anything, because make check ld. */
1450 return true;
1453 /* Allocate space in .plt, .got and associated reloc sections for
1454 dynamic relocs. */
1456 static bool
1457 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1459 struct bfd_link_info *info;
1460 struct loongarch_elf_link_hash_table *htab;
1461 struct elf_dyn_relocs *p;
1463 if (h->root.type == bfd_link_hash_indirect)
1464 return true;
1466 if (h->type == STT_GNU_IFUNC
1467 && h->def_regular)
1468 return true;
1470 info = (struct bfd_link_info *) inf;
1471 htab = loongarch_elf_hash_table (info);
1472 bool dyn = htab->elf.dynamic_sections_created;
1473 BFD_ASSERT (htab != NULL);
1477 asection *plt, *gotplt, *relplt;
1479 if (!h->needs_plt)
1480 break;
1482 h->needs_plt = 0;
1484 if (htab->elf.splt)
1486 if (h->dynindx == -1 && !h->forced_local && dyn
1487 && h->root.type == bfd_link_hash_undefweak)
1489 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1490 return false;
1493 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1494 && h->type != STT_GNU_IFUNC)
1495 break;
1497 plt = htab->elf.splt;
1498 gotplt = htab->elf.sgotplt;
1499 relplt = htab->elf.srelplt;
1501 else if (htab->elf.iplt)
1503 /* .iplt only for IFUNC. */
1504 if (h->type != STT_GNU_IFUNC)
1505 break;
1507 plt = htab->elf.iplt;
1508 gotplt = htab->elf.igotplt;
1509 relplt = htab->elf.irelplt;
1511 else
1512 break;
1514 if (plt->size == 0)
1515 plt->size = PLT_HEADER_SIZE;
1517 h->plt.offset = plt->size;
1518 plt->size += PLT_ENTRY_SIZE;
1519 gotplt->size += GOT_ENTRY_SIZE;
1520 relplt->size += sizeof (ElfNN_External_Rela);
1522 /* If this symbol is not defined in a regular file, and we are
1523 not generating a shared library, then set the symbol to this
1524 location in the .plt. This is required to make function
1525 pointers compare as equal between the normal executable and
1526 the shared library. */
1527 if (!bfd_link_pic (info)
1528 && !h->def_regular)
1530 h->root.u.def.section = plt;
1531 h->root.u.def.value = h->plt.offset;
1534 h->needs_plt = 1;
1536 while (0);
1538 if (!h->needs_plt)
1539 h->plt.offset = MINUS_ONE;
1541 if (0 < h->got.refcount)
1543 asection *s;
1544 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1546 /* Make sure this symbol is output as a dynamic symbol.
1547 Undefined weak syms won't yet be marked as dynamic. */
1548 if (h->dynindx == -1 && !h->forced_local && dyn
1549 && h->root.type == bfd_link_hash_undefweak)
1551 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1552 return false;
1555 s = htab->elf.sgot;
1556 h->got.offset = s->size;
1557 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1559 int indx = 0;
1560 bool need_reloc = false;
1561 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, dyn, h, indx,
1562 need_reloc);
1563 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1564 if (tls_type & GOT_TLS_GD)
1566 s->size += 2 * GOT_ENTRY_SIZE;
1567 if (need_reloc)
1568 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1571 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1572 if (tls_type & GOT_TLS_IE)
1574 s->size += GOT_ENTRY_SIZE;
1575 if (need_reloc)
1576 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1579 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1580 if (tls_type & GOT_TLS_GDESC)
1582 s->size += GOT_ENTRY_SIZE * 2;
1583 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1587 else
1589 s->size += GOT_ENTRY_SIZE;
1590 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1591 || h->root.type != bfd_link_hash_undefweak)
1592 && (bfd_link_pic (info)
1593 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1595 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1596 /* Undefined weak symbol in static PIE resolves to 0 without
1597 any dynamic relocations. */
1598 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1601 else
1602 h->got.offset = MINUS_ONE;
1604 if (h->dyn_relocs == NULL)
1605 return true;
1607 /* Extra dynamic relocate,
1608 * R_LARCH_64
1609 * R_LARCH_TLS_DTPRELNN
1610 * R_LARCH_JUMP_SLOT
1611 * R_LARCH_NN. */
1613 if (SYMBOL_CALLS_LOCAL (info, h))
1615 struct elf_dyn_relocs **pp;
1617 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1619 p->count -= p->pc_count;
1620 p->pc_count = 0;
1621 if (p->count == 0)
1622 *pp = p->next;
1623 else
1624 pp = &p->next;
1628 if (h->root.type == bfd_link_hash_undefweak)
1630 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1631 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1632 || (!bfd_link_pic (info) && h->non_got_ref))
1633 h->dyn_relocs = NULL;
1634 else if (h->dynindx == -1 && !h->forced_local)
1636 /* Make sure this symbol is output as a dynamic symbol.
1637 Undefined weak syms won't yet be marked as dynamic. */
1638 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1639 return false;
1641 if (h->dynindx == -1)
1642 h->dyn_relocs = NULL;
1646 for (p = h->dyn_relocs; p != NULL; p = p->next)
1648 if (discarded_section (p->sec))
1649 continue;
1650 asection *sreloc = elf_section_data (p->sec)->sreloc;
1651 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1654 return true;
1657 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1658 For local def and ref ifunc,
1659 dynamic relocations are stored in
1660 1. rela.srelgot section in dynamic object (dll or exec).
1661 2. rela.irelplt section in static executable.
1662 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1663 instead of rela.srelplt. Glibc ELF loader will not support
1664 R_LARCH_IRELATIVE relocation in rela.plt. */
1666 static bool
1667 local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1668 struct elf_link_hash_entry *h,
1669 struct elf_dyn_relocs **head,
1670 unsigned int plt_entry_size,
1671 unsigned int plt_header_size,
1672 unsigned int got_entry_size,
1673 bool avoid_plt)
1675 asection *plt, *gotplt, *relplt;
1676 struct elf_dyn_relocs *p;
1677 unsigned int sizeof_reloc;
1678 const struct elf_backend_data *bed;
1679 struct elf_link_hash_table *htab;
1680 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1681 bool use_plt = !avoid_plt || h->plt.refcount > 0;
1682 bool need_dynreloc = !use_plt || bfd_link_pic (info);
1684 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1685 in executable or it isn't referenced via PLT, the address of
1686 the resolved function may be used. But in non-PIC executable,
1687 the address of its plt slot may be used. Pointer equality may
1688 not work correctly. PIE or non-PLT reference should be used if
1689 pointer equality is required here.
1691 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1692 backend should change it to the normal function and set its address
1693 to its PLT entry which should be resolved by R_*_IRELATIVE at
1694 run-time. All external references should be resolved to its PLT in
1695 executable. */
1696 if (!need_dynreloc
1697 && !(bfd_link_pde (info) && h->def_regular)
1698 && (h->dynindx != -1
1699 || info->export_dynamic)
1700 && h->pointer_equality_needed)
1702 info->callbacks->einfo
1703 /* xgettext:c-format. */
1704 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1705 "equality in `%pB' can not be used when making an "
1706 "executable; recompile with -fPIE and relink with -pie\n"),
1707 h->root.root.string,
1708 h->root.u.def.section->owner);
1709 bfd_set_error (bfd_error_bad_value);
1710 return false;
1713 htab = elf_hash_table (info);
1715 /* When the symbol is marked with regular reference, if PLT isn't used
1716 or we are building a PIC object, we must keep dynamic relocation
1717 if there is non-GOT reference and use PLT if there is PC-relative
1718 reference. */
1719 if (need_dynreloc && h->ref_regular)
1721 bool keep = false;
1722 for (p = *head; p != NULL; p = p->next)
1723 if (p->count)
1725 h->non_got_ref = 1;
1726 /* Need dynamic relocations for non-GOT reference. */
1727 keep = true;
1728 if (p->pc_count)
1730 /* Must use PLT for PC-relative reference. */
1731 use_plt = true;
1732 need_dynreloc = bfd_link_pic (info);
1733 break;
1736 if (keep)
1737 goto keep;
1740 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1741 if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1743 h->got = htab->init_got_offset;
1744 h->plt = htab->init_plt_offset;
1745 *head = NULL;
1746 return true;
1749 /* Return and discard space for dynamic relocations against it if
1750 it is never referenced. */
1751 if (!h->ref_regular)
1753 if (h->plt.refcount > 0
1754 || h->got.refcount > 0)
1755 abort ();
1756 h->got = htab->init_got_offset;
1757 h->plt = htab->init_plt_offset;
1758 *head = NULL;
1759 return true;
1762 keep:
1763 bed = get_elf_backend_data (info->output_bfd);
1764 if (bed->rela_plts_and_copies_p)
1765 sizeof_reloc = bed->s->sizeof_rela;
1766 else
1767 sizeof_reloc = bed->s->sizeof_rel;
1769 /* When building a static executable, use iplt, igot.plt and
1770 rela.iplt sections for STT_GNU_IFUNC symbols. */
1771 if (htab->splt != NULL)
1773 plt = htab->splt;
1774 gotplt = htab->sgotplt;
1775 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1776 relplt = htab->srelgot;
1778 /* If this is the first plt entry and PLT is used, make room for
1779 the special first entry. */
1780 if (plt->size == 0 && use_plt)
1781 plt->size += plt_header_size;
1783 else
1785 plt = htab->iplt;
1786 gotplt = htab->igotplt;
1787 relplt = htab->irelplt;
1790 if (use_plt)
1792 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1793 the original value for R_*_IRELATIVE. */
1794 h->plt.offset = plt->size;
1796 /* Make room for this entry in the plt/iplt section. */
1797 plt->size += plt_entry_size;
1799 /* We also need to make an entry in the got.plt/got.iplt section,
1800 which will be placed in the got section by the linker script. */
1801 gotplt->size += got_entry_size;
1804 /* We also need to make an entry in the rela.plt/.rela.iplt
1805 section for GOTPLT relocation if PLT is used. */
1806 if (use_plt)
1808 relplt->size += sizeof_reloc;
1809 relplt->reloc_count++;
1812 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1813 there is a non-GOT reference in a PIC object or PLT isn't used. */
1814 if (!need_dynreloc || !h->non_got_ref)
1815 *head = NULL;
1817 /* Finally, allocate space. */
1818 p = *head;
1819 if (p != NULL)
1821 bfd_size_type count = 0;
1824 count += p->count;
1825 p = p->next;
1827 while (p != NULL);
1829 htab->ifunc_resolvers = count != 0;
1831 /* Dynamic relocations are stored in
1832 1. rela.srelgot section in PIC object.
1833 2. rela.srelgot section in dynamic executable.
1834 3. rela.irelplt section in static executable. */
1835 if (htab->splt != NULL)
1836 htab->srelgot->size += count * sizeof_reloc;
1837 else
1839 relplt->size += count * sizeof_reloc;
1840 relplt->reloc_count += count;
1844 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1845 and got has the PLT entry adddress. We will load the GOT entry
1846 with the PLT entry in finish_dynamic_symbol if it is used. For
1847 branch, it uses got.plt. For symbol value, if PLT is used,
1848 1. Use got.plt in a PIC object if it is forced local or not
1849 dynamic.
1850 2. Use got.plt in a non-PIC object if pointer equality isn't
1851 needed.
1852 3. Use got.plt in PIE.
1853 4. Use got.plt if got isn't used.
1854 5. Otherwise use got so that it can be shared among different
1855 objects at run-time.
1856 If PLT isn't used, always use got for symbol value.
1857 We only need to relocate got entry in PIC object or in dynamic
1858 executable without PLT. */
1859 if (use_plt
1860 && (h->got.refcount <= 0
1861 || (bfd_link_pic (info)
1862 && (h->dynindx == -1
1863 || h->forced_local))
1864 || (
1865 !h->pointer_equality_needed)
1866 || htab->sgot == NULL))
1868 /* Use got.plt. */
1869 h->got.offset = (bfd_vma) -1;
1871 else
1873 if (!use_plt)
1875 /* PLT isn't used. */
1876 h->plt.offset = (bfd_vma) -1;
1878 if (h->got.refcount <= 0)
1880 /* GOT isn't need when there are only relocations for static
1881 pointers. */
1882 h->got.offset = (bfd_vma) -1;
1884 else
1886 h->got.offset = htab->sgot->size;
1887 htab->sgot->size += got_entry_size;
1888 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1889 used. Otherwise, the GOT entry will be filled with the PLT
1890 entry and dynamic GOT relocation isn't needed. */
1891 if (need_dynreloc)
1893 /* For non-static executable, dynamic GOT relocation is in
1894 rela.got section, but for static executable, it is
1895 in rela.iplt section. */
1896 if (htab->splt != NULL)
1897 htab->srelgot->size += sizeof_reloc;
1898 else
1900 relplt->size += sizeof_reloc;
1901 relplt->reloc_count++;
1907 return true;
1910 /* Allocate space in .plt, .got and associated reloc sections for
1911 ifunc dynamic relocs. */
1913 static bool
1914 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
1915 struct bfd_link_info *info,
1916 bool ref_local)
1918 /* An example of a bfd_link_hash_indirect symbol is versioned
1919 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1920 -> __gxx_personality_v0(bfd_link_hash_defined)
1922 There is no need to process bfd_link_hash_indirect symbols here
1923 because we will also be presented with the concrete instance of
1924 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1925 called to copy all relevant data from the generic to the concrete
1926 symbol instance. */
1927 if (h->root.type == bfd_link_hash_indirect)
1928 return true;
1930 if (h->root.type == bfd_link_hash_warning)
1931 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1933 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1934 here if it is defined and referenced in a non-shared object. */
1935 if (h->type == STT_GNU_IFUNC && h->def_regular)
1937 if (ref_local && LARCH_REF_LOCAL (info, h))
1938 return local_allocate_ifunc_dyn_relocs (info, h,
1939 &h->dyn_relocs,
1940 PLT_ENTRY_SIZE,
1941 PLT_HEADER_SIZE,
1942 GOT_ENTRY_SIZE,
1943 false);
1944 else if (!ref_local && !LARCH_REF_LOCAL (info, h))
1945 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1946 &h->dyn_relocs,
1947 PLT_ENTRY_SIZE,
1948 PLT_HEADER_SIZE,
1949 GOT_ENTRY_SIZE,
1950 false);
1953 return true;
1956 static bool
1957 elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry *h,
1958 void *info)
1960 return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info,
1961 true);
1964 static bool
1965 elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h,
1966 void *info)
1968 return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info,
1969 false);
1972 /* Allocate space in .plt, .got and associated reloc sections for
1973 ifunc dynamic relocs. */
1975 static int
1976 elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1978 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1980 if (h->type != STT_GNU_IFUNC
1981 || !h->def_regular
1982 || !h->ref_regular
1983 || !h->forced_local
1984 || h->root.type != bfd_link_hash_defined)
1985 abort ();
1987 return elfNN_allocate_ifunc_dynrelocs_ref_local (h, inf);
1990 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1991 read-only sections. */
1993 static bool
1994 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1996 asection *sec;
1998 if (h->root.type == bfd_link_hash_indirect)
1999 return true;
2001 sec = readonly_dynrelocs (h);
2002 if (sec != NULL)
2004 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
2006 info->flags |= DF_TEXTREL;
2007 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
2008 "read-only section `%pA'\n"),
2009 sec->owner, h->root.root.string, sec);
2011 /* Not an error, just cut short the traversal. */
2012 return false;
2014 return true;
2017 static bool
2018 record_relr (struct loongarch_elf_link_hash_table *htab, asection *sec,
2019 bfd_vma off, asection *sreloc)
2021 struct relr_entry **sec_relr = &loongarch_elf_section_data (sec)->relr;
2023 /* Undo the relocation section size accounting. */
2024 BFD_ASSERT (sreloc->size >= sizeof (ElfNN_External_Rela));
2025 sreloc->size -= sizeof (ElfNN_External_Rela);
2027 BFD_ASSERT (off % 2 == 0 && sec->alignment_power > 0);
2028 if (htab->relr_count >= htab->relr_alloc)
2030 if (htab->relr_alloc == 0)
2031 htab->relr_alloc = 4096;
2032 else
2033 htab->relr_alloc *= 2;
2035 htab->relr = bfd_realloc (htab->relr,
2036 htab->relr_alloc * sizeof (*htab->relr));
2037 if (!htab->relr)
2038 return false;
2040 htab->relr[htab->relr_count].sec = sec;
2041 htab->relr[htab->relr_count].off = off;
2042 if (*sec_relr == NULL)
2043 *sec_relr = &htab->relr[htab->relr_count];
2044 htab->relr_count++;
2045 return true;
2048 static bool
2049 record_relr_local_got_relocs (bfd *input_bfd, struct bfd_link_info *info)
2051 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2052 char *local_tls_type = _bfd_loongarch_elf_local_got_tls_type (input_bfd);
2053 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2054 struct loongarch_elf_link_hash_table *htab =
2055 loongarch_elf_hash_table (info);
2057 if (!local_got_offsets || !local_tls_type || !bfd_link_pic (info))
2058 return true;
2060 for (unsigned i = 0; i < symtab_hdr->sh_info; i++)
2062 bfd_vma off = local_got_offsets[i];
2064 /* FIXME: If the local symbol is in SHN_ABS then emitting
2065 a relative relocation is not correct, but it seems to be wrong
2066 in loongarch_elf_relocate_section too. */
2067 if (local_tls_type[i] == GOT_NORMAL
2068 && !record_relr (htab, htab->elf.sgot, off, htab->elf.srelgot))
2069 return false;
2072 return true;
2075 static bool
2076 record_relr_dyn_got_relocs (struct elf_link_hash_entry *h, void *inf)
2078 struct bfd_link_info *info = (struct bfd_link_info *) inf;
2079 struct loongarch_elf_link_hash_table *htab =
2080 loongarch_elf_hash_table (info);
2082 if (h->root.type == bfd_link_hash_indirect)
2083 return true;
2084 if (h->type == STT_GNU_IFUNC && h->def_regular)
2085 return true;
2086 if (h->got.refcount <= 0)
2087 return true;
2088 if (loongarch_elf_hash_entry (h)->tls_type
2089 & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
2090 return true;
2091 if (!bfd_link_pic (info))
2092 return true;
2094 /* On LoongArch a GOT entry for undefined weak symbol is never relocated
2095 with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus
2096 the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or
2097 relocated with R_LARCH_NN (otherwise). */
2098 if (h->root.type == bfd_link_hash_undefweak)
2099 return true;
2101 if (!LARCH_REF_LOCAL (info, h))
2102 return true;
2103 if (bfd_is_abs_symbol (&h->root))
2104 return true;
2106 if (!record_relr (htab, htab->elf.sgot, h->got.offset,
2107 htab->elf.srelgot))
2108 return false;
2110 return true;
2113 static bool
2114 record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info,
2115 asection *sec)
2117 asection *sreloc;
2118 struct loongarch_elf_link_hash_table *htab;
2119 Elf_Internal_Rela *relocs, *rel, *rel_end;
2120 Elf_Internal_Shdr *symtab_hdr;
2121 struct elf_link_hash_entry **sym_hashes;
2123 if (!bfd_link_pic (info))
2124 return true;
2125 if (sec->reloc_count == 0)
2126 return true;
2127 if ((sec->flags & (SEC_RELOC | SEC_ALLOC | SEC_DEBUGGING))
2128 != (SEC_RELOC | SEC_ALLOC))
2129 return true;
2130 if (sec->alignment_power == 0)
2131 return true;
2132 if (discarded_section (sec))
2133 return true;
2135 sreloc = elf_section_data (sec)->sreloc;
2136 if (sreloc == NULL)
2137 return true;
2139 htab = loongarch_elf_hash_table (info);
2140 symtab_hdr = &elf_symtab_hdr (input_bfd);
2141 sym_hashes = elf_sym_hashes (input_bfd);
2142 relocs = _bfd_elf_link_info_read_relocs (input_bfd, info, sec, NULL,
2143 NULL, info->keep_memory);
2144 BFD_ASSERT (relocs != NULL);
2145 rel_end = relocs + sec->reloc_count;
2146 for (rel = relocs; rel < rel_end; rel++)
2148 unsigned r_symndx = ELFNN_R_SYM (rel->r_info);
2149 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
2150 struct elf_link_hash_entry *h = NULL;
2151 asection *def_sec = NULL;
2153 if ((r_type != R_LARCH_64 && r_type != R_LARCH_32)
2154 || rel->r_offset % 2 != 0)
2155 continue;
2157 /* The logical below must match loongarch_elf_relocate_section. */
2158 if (r_symndx < symtab_hdr->sh_info)
2160 /* A local symbol. */
2161 Elf_Internal_Sym *isym;
2162 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, input_bfd,
2163 r_symndx);
2164 BFD_ASSERT(isym != NULL);
2166 /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for
2167 R_LARCH_NN, not R_LARCH_RELATIVE. */
2168 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
2169 continue;
2170 def_sec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
2172 else
2174 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2175 while (h->root.type == bfd_link_hash_indirect
2176 || h->root.type == bfd_link_hash_warning)
2177 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2179 /* Filter out symbols that cannot have a relative reloc. */
2180 if (h->dyn_relocs == NULL)
2181 continue;
2182 if (bfd_is_abs_symbol (&h->root))
2183 continue;
2184 if (h->type == STT_GNU_IFUNC)
2185 continue;
2187 if (h->root.type == bfd_link_hash_defined
2188 || h->root.type == bfd_link_hash_defweak)
2189 def_sec = h->root.u.def.section;
2191 /* On LoongArch an R_LARCH_NN against undefined weak symbol
2192 is never converted to R_LARCH_RELATIVE: we don't have
2193 -z dynamic-undefined-weak, thus the reloc is either removed
2194 (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */
2195 if (h->root.type == bfd_link_hash_undefweak)
2196 continue;
2198 if (!LARCH_REF_LOCAL (info, h))
2199 continue;
2202 if (!def_sec || discarded_section (def_sec))
2203 continue;
2205 if (!record_relr (htab, sec, rel->r_offset, sreloc))
2206 return false;
2209 return true;
2212 static int
2213 cmp_relr_addr (const void *p, const void *q)
2215 const bfd_vma *a = p, *b = q;
2216 return (*a > *b) - (*a < *b);
2219 static bool
2220 sort_relr (struct bfd_link_info *info,
2221 struct loongarch_elf_link_hash_table *htab)
2223 if (htab->relr_count == 0)
2224 return true;
2226 bfd_vma *addr = htab->relr_sorted;
2227 if (!addr)
2229 addr = bfd_malloc (htab->relr_count * sizeof (*addr));
2230 if (!addr)
2231 return false;
2232 htab->relr_sorted = addr;
2235 for (bfd_size_type i = 0; i < htab->relr_count; i++)
2237 bfd_vma off = _bfd_elf_section_offset (info->output_bfd, info,
2238 htab->relr[i].sec,
2239 htab->relr[i].off);
2240 addr[i] = htab->relr[i].sec->output_section->vma
2241 + htab->relr[i].sec->output_offset + off;
2243 qsort(addr, htab->relr_count, sizeof (*addr), cmp_relr_addr);
2244 return true;
2247 static bool
2248 loongarch_elf_size_relative_relocs (struct bfd_link_info *info,
2249 bool *need_layout)
2251 struct loongarch_elf_link_hash_table *htab =
2252 loongarch_elf_hash_table (info);
2253 asection *srelrdyn = htab->elf.srelrdyn;
2255 *need_layout = false;
2257 if (!sort_relr (info, htab))
2258 return false;
2259 bfd_vma *addr = htab->relr_sorted;
2261 BFD_ASSERT (srelrdyn != NULL);
2262 bfd_size_type oldsize = srelrdyn->size;
2263 srelrdyn->size = 0;
2264 for (bfd_size_type i = 0; i < htab->relr_count; )
2266 bfd_vma base = addr[i];
2267 i++;
2268 srelrdyn->size += NN / 8;
2269 base += NN / 8;
2270 while (1)
2272 bfd_size_type start_i = i;
2273 while (i < htab->relr_count
2274 && addr[i] - base < (NN - 1) * (NN / 8)
2275 && (addr[i] - base) % (NN / 8) == 0)
2276 i++;
2277 if (i == start_i)
2278 break;
2279 srelrdyn->size += NN / 8;
2280 base += (NN - 1) * (NN / 8);
2283 if (srelrdyn->size != oldsize)
2285 *need_layout = true;
2286 /* Stop after a few iterations in case the layout does not converge,
2287 but we can only stop when the size would shrink (and pad the
2288 spare space with 1. */
2289 if (htab->relr_layout_iter++ > 5 && srelrdyn->size < oldsize)
2291 srelrdyn->size = oldsize;
2292 *need_layout = false;
2296 htab->layout_mutating_for_relr = *need_layout;
2297 return true;
2300 static bool
2301 loongarch_elf_finish_relative_relocs (struct bfd_link_info *info)
2303 struct loongarch_elf_link_hash_table *htab =
2304 loongarch_elf_hash_table (info);
2305 asection *srelrdyn = htab->elf.srelrdyn;
2306 bfd *dynobj = htab->elf.dynobj;
2308 if (!srelrdyn || srelrdyn->size == 0)
2309 return true;
2311 srelrdyn->contents = bfd_alloc (dynobj, srelrdyn->size);
2312 if (!srelrdyn->contents)
2313 return false;
2314 srelrdyn->alloced = 1;
2316 bfd_vma *addr = htab->relr_sorted;
2317 bfd_byte *loc = srelrdyn->contents;
2318 for (bfd_size_type i = 0; i < htab->relr_count; )
2320 bfd_vma base = addr[i];
2321 i++;
2322 bfd_put_NN (dynobj, base, loc);
2323 loc += NN / 8;
2324 base += NN / 8;
2325 while (1)
2327 uintNN_t bits = 0;
2328 while (i < htab->relr_count)
2330 bfd_vma delta = addr[i] - base;
2331 if (delta >= (NN - 1) * (NN / 8) || delta % (NN / 8) != 0)
2332 break;
2333 bits |= (uintNN_t) 1 << (delta / (NN / 8));
2334 i++;
2336 if (bits == 0)
2337 break;
2338 bfd_put_NN (dynobj, (bits << 1) | 1, loc);
2339 loc += NN / 8;
2340 base += (NN - 1) * (NN / 8);
2344 free (addr);
2345 htab->relr_sorted = NULL;
2347 /* Pad any excess with 1's, a do-nothing encoding. */
2348 while (loc < srelrdyn->contents + srelrdyn->size)
2350 bfd_put_NN (dynobj, 1, loc);
2351 loc += NN / 8;
2354 return true;
2357 static bool
2358 loongarch_elf_late_size_sections (bfd *output_bfd,
2359 struct bfd_link_info *info)
2361 struct loongarch_elf_link_hash_table *htab;
2362 bfd *dynobj;
2363 asection *s;
2364 bfd *ibfd;
2366 htab = loongarch_elf_hash_table (info);
2367 BFD_ASSERT (htab != NULL);
2368 dynobj = htab->elf.dynobj;
2369 if (dynobj == NULL)
2370 return true;
2372 if (htab->elf.dynamic_sections_created)
2374 /* Set the contents of the .interp section to the interpreter. */
2375 if (bfd_link_executable (info) && !info->nointerp)
2377 const char *interpreter;
2378 s = bfd_get_linker_section (dynobj, ".interp");
2379 BFD_ASSERT (s != NULL);
2381 if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
2382 interpreter = "/lib32/ld.so.1";
2383 else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
2384 interpreter = "/lib64/ld.so.1";
2385 else
2386 interpreter = "/lib/ld.so.1";
2388 s->contents = (unsigned char *) interpreter;
2389 s->alloced = 1;
2390 s->size = strlen (interpreter) + 1;
2394 /* Set up .got offsets for local syms, and space for local dynamic
2395 relocs. */
2396 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2398 bfd_signed_vma *local_got;
2399 bfd_signed_vma *end_local_got;
2400 char *local_tls_type;
2401 bfd_size_type locsymcount;
2402 Elf_Internal_Shdr *symtab_hdr;
2403 asection *srel;
2405 if (!is_loongarch_elf (ibfd))
2406 continue;
2408 for (s = ibfd->sections; s != NULL; s = s->next)
2410 struct elf_dyn_relocs *p;
2412 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
2414 p->count -= p->pc_count;
2415 if (!bfd_is_abs_section (p->sec)
2416 && bfd_is_abs_section (p->sec->output_section))
2418 /* Input section has been discarded, either because
2419 it is a copy of a linkonce section or due to
2420 linker script /DISCARD/, so we'll be discarding
2421 the relocs too. */
2423 else if (0 < p->count)
2425 srel = elf_section_data (p->sec)->sreloc;
2426 srel->size += p->count * sizeof (ElfNN_External_Rela);
2427 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2428 info->flags |= DF_TEXTREL;
2433 local_got = elf_local_got_refcounts (ibfd);
2434 if (!local_got)
2435 continue;
2437 symtab_hdr = &elf_symtab_hdr (ibfd);
2438 locsymcount = symtab_hdr->sh_info;
2439 end_local_got = local_got + locsymcount;
2440 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
2441 s = htab->elf.sgot;
2442 srel = htab->elf.srelgot;
2443 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
2445 if (0 < *local_got)
2447 *local_got = s->size;
2448 if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
2450 /* TLS gd use two got. */
2451 if (*local_tls_type & GOT_TLS_GD)
2453 s->size += 2 * GOT_ENTRY_SIZE;
2454 if (!bfd_link_executable (info))
2455 srel->size += sizeof (ElfNN_External_Rela);
2458 /* TLS_DESC use two got. */
2459 if (*local_tls_type & GOT_TLS_GDESC)
2461 s->size += 2 * GOT_ENTRY_SIZE;
2462 srel->size += sizeof (ElfNN_External_Rela);
2465 /* TLS ie and use one got. */
2466 if (*local_tls_type & GOT_TLS_IE)
2468 s->size += GOT_ENTRY_SIZE;
2469 if (!bfd_link_executable (info))
2470 srel->size += sizeof (ElfNN_External_Rela);
2473 else
2475 s->size += GOT_ENTRY_SIZE;
2476 srel->size += sizeof (ElfNN_External_Rela);
2479 else
2480 *local_got = MINUS_ONE;
2484 /* Allocate global sym .plt and .got entries, and space for global
2485 sym dynamic relocs. */
2486 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
2488 /* Allocate global ifunc sym .plt and .got entries, and space for
2489 *preemptible* ifunc sym dynamic relocs. Note that we must do it
2490 for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN
2491 ifuncs) before doing it for any non-preemptible ifunc symbol:
2492 assuming we are not so careful, when we link a shared library the
2493 correlation of .plt and .rela.plt might look like:
2495 idx in .plt idx in .rela.plt
2496 ext_func1@plt 0 0
2497 ext_func2@plt 1 1
2498 ext_func3@plt 2 2
2499 hidden_ifunc1@plt 3 None: it's in .rela.got
2500 hidden_ifunc2@plt 4 None: it's in .rela.got
2501 normal_ifunc1@plt 5 != 3
2502 normal_ifunc2@plt 6 != 4
2503 local_ifunc@plt 7 None: it's in .rela.got
2505 Now oops the indices for normal_ifunc{1,2} in .rela.plt were different
2506 from the indices in .plt :(. This would break finish_dynamic_symbol
2507 which assumes the index in .rela.plt matches the index in .plt.
2509 So let's be careful and make it correct:
2511 idx in .plt idx in .rela.plt
2512 ext_func1@plt 0 0
2513 ext_func2@plt 1 1
2514 ext_func3@plt 2 2
2515 normal_ifunc1@plt 3 3
2516 normal_ifunc2@plt 4 4
2517 hidden_ifunc1@plt 5 None: it's in .rela.got
2518 hidden_ifunc2@plt 6 None: it's in .rela.got
2519 local_ifunc@plt 7 None: it's in .rela.got
2521 Now normal_ifuncs first. */
2522 elf_link_hash_traverse (&htab->elf,
2523 elfNN_allocate_ifunc_dynrelocs_ref_global, info);
2525 /* Next hidden_ifuncs follows. */
2526 elf_link_hash_traverse (&htab->elf,
2527 elfNN_allocate_ifunc_dynrelocs_ref_local, info);
2529 /* Finally local_ifuncs. */
2530 htab_traverse (htab->loc_hash_table,
2531 elfNN_allocate_local_ifunc_dynrelocs, info);
2533 /* Don't allocate .got.plt section if there are no PLT. */
2534 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
2535 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
2536 htab->elf.sgotplt->size = 0;
2538 if (info->enable_dt_relr && !bfd_link_relocatable (info))
2540 elf_link_hash_traverse (&htab->elf, record_relr_dyn_got_relocs, info);
2542 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2544 if (!is_loongarch_elf (ibfd))
2545 continue;
2547 for (s = ibfd->sections; s != NULL; s = s->next)
2548 if (!record_relr_non_got_relocs (ibfd, info, s))
2549 return false;
2551 if (!record_relr_local_got_relocs (ibfd, info))
2552 return false;
2556 /* The check_relocs and adjust_dynamic_symbol entry points have
2557 determined the sizes of the various dynamic sections. Allocate
2558 memory for them. */
2559 for (s = dynobj->sections; s != NULL; s = s->next)
2561 if ((s->flags & SEC_LINKER_CREATED) == 0)
2562 continue;
2564 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
2565 || s == htab->elf.sgotplt || s == htab->elf.igotplt
2566 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
2568 /* Strip this section if we don't need it; see the
2569 comment below. */
2571 else if (strncmp (s->name, ".rela", 5) == 0)
2573 if (s->size != 0)
2575 /* We use the reloc_count field as a counter if we need
2576 to copy relocs into the output file. */
2577 s->reloc_count = 0;
2580 else if (s == htab->elf.srelrdyn && htab->relr_count == 0)
2582 /* Remove .relr.dyn based on relr_count, not size, since
2583 it is not sized yet. */
2584 s->flags |= SEC_EXCLUDE;
2585 /* Allocate contents later. */
2586 continue;
2588 else
2590 /* It's not one of our sections. */
2591 continue;
2594 if (s->size == 0)
2596 /* If we don't need this section, strip it from the
2597 output file. This is mostly to handle .rela.bss and
2598 .rela.plt. We must create both sections in
2599 create_dynamic_sections, because they must be created
2600 before the linker maps input sections to output
2601 sections. The linker does that before
2602 adjust_dynamic_symbol is called, and it is that
2603 function which decides whether anything needs to go
2604 into these sections. */
2605 s->flags |= SEC_EXCLUDE;
2606 continue;
2609 if ((s->flags & SEC_HAS_CONTENTS) == 0)
2610 continue;
2612 /* Allocate memory for the section contents. Zero the memory
2613 for the benefit of .rela.plt, which has 4 unused entries
2614 at the beginning, and we don't want garbage. */
2615 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2616 if (s->contents == NULL)
2617 return false;
2618 s->alloced = 1;
2621 if (elf_hash_table (info)->dynamic_sections_created)
2623 /* Add some entries to the .dynamic section. We fill in the
2624 values later, in loongarch_elf_finish_dynamic_sections, but we
2625 must add the entries now so that we get the correct size for
2626 the .dynamic section. The DT_DEBUG entry is filled in by the
2627 dynamic linker and used by the debugger. */
2628 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2630 if (bfd_link_executable (info))
2632 if (!add_dynamic_entry (DT_DEBUG, 0))
2633 return false;
2636 if (htab->elf.srelplt->size != 0)
2638 if (!add_dynamic_entry (DT_PLTGOT, 0)
2639 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2640 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2641 || !add_dynamic_entry (DT_JMPREL, 0))
2642 return false;
2645 if (!add_dynamic_entry (DT_RELA, 0)
2646 || !add_dynamic_entry (DT_RELASZ, 0)
2647 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
2648 return false;
2650 /* If any dynamic relocs apply to a read-only section,
2651 then we need a DT_TEXTREL entry. */
2652 if ((info->flags & DF_TEXTREL) == 0)
2653 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
2655 if (info->flags & DF_TEXTREL)
2657 if (!add_dynamic_entry (DT_TEXTREL, 0))
2658 return false;
2659 /* Clear the DF_TEXTREL flag. It will be set again if we
2660 write out an actual text relocation; we may not, because
2661 at this point we do not know whether e.g. any .eh_frame
2662 absolute relocations have been converted to PC-relative. */
2663 info->flags &= ~DF_TEXTREL;
2666 #undef add_dynamic_entry
2668 return true;
2671 #define LARCH_LD_STACK_DEPTH 16
2672 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
2673 static size_t larch_stack_top = 0;
2675 static bfd_reloc_status_type
2676 loongarch_push (int64_t val)
2678 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
2679 return bfd_reloc_outofrange;
2680 larch_opc_stack[larch_stack_top++] = val;
2681 return bfd_reloc_ok;
2684 static bfd_reloc_status_type
2685 loongarch_pop (int64_t *val)
2687 if (larch_stack_top == 0)
2688 return bfd_reloc_outofrange;
2689 BFD_ASSERT (val);
2690 *val = larch_opc_stack[--larch_stack_top];
2691 return bfd_reloc_ok;
2694 static bfd_reloc_status_type
2695 loongarch_top (int64_t *val)
2697 if (larch_stack_top == 0)
2698 return bfd_reloc_outofrange;
2699 BFD_ASSERT (val);
2700 *val = larch_opc_stack[larch_stack_top - 1];
2701 return bfd_reloc_ok;
2704 static void
2705 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
2707 BFD_ASSERT (s && s->contents);
2708 const struct elf_backend_data *bed;
2709 bfd_byte *loc;
2711 bed = get_elf_backend_data (abfd);
2712 if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
2713 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
2714 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
2715 bed->s->swap_reloca_out (abfd, rel, loc);
2718 /* Check rel->r_offset in range of contents. */
2719 static bfd_reloc_status_type
2720 loongarch_check_offset (const Elf_Internal_Rela *rel,
2721 const asection *input_section)
2723 if (0 == strcmp(input_section->name, ".text")
2724 && rel->r_offset > input_section->size)
2725 return bfd_reloc_overflow;
2727 return bfd_reloc_ok;
2730 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2731 ({ \
2732 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2733 if (ret == bfd_reloc_ok) \
2735 ret = loongarch_pop (&op1); \
2736 if (ret == bfd_reloc_ok) \
2737 ret = loongarch_push (op3); \
2739 ret; \
2742 /* Write immediate to instructions. */
2744 static bfd_reloc_status_type
2745 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
2746 const asection *input_section ATTRIBUTE_UNUSED,
2747 reloc_howto_type *howto, bfd *input_bfd,
2748 bfd_byte *contents, bfd_vma reloc_val)
2750 /* Adjust the immediate based on alignment and
2751 its position in the instruction. */
2752 if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
2753 return bfd_reloc_overflow;
2755 int bits = bfd_get_reloc_size (howto) * 8;
2756 uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
2758 /* Write immediate to instruction. */
2759 insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
2761 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
2763 return bfd_reloc_ok;
2766 static bfd_reloc_status_type
2767 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
2768 reloc_howto_type *howto, bfd_vma value,
2769 bfd *input_bfd, bfd_byte *contents)
2771 int64_t opr1, opr2, opr3;
2772 bfd_reloc_status_type r = bfd_reloc_ok;
2773 int bits = bfd_get_reloc_size (howto) * 8;
2775 switch (ELFNN_R_TYPE (rel->r_info))
2777 case R_LARCH_SOP_PUSH_PCREL:
2778 case R_LARCH_SOP_PUSH_ABSOLUTE:
2779 case R_LARCH_SOP_PUSH_GPREL:
2780 case R_LARCH_SOP_PUSH_TLS_TPREL:
2781 case R_LARCH_SOP_PUSH_TLS_GOT:
2782 case R_LARCH_SOP_PUSH_TLS_GD:
2783 case R_LARCH_SOP_PUSH_PLT_PCREL:
2784 r = loongarch_push (value);
2785 break;
2787 case R_LARCH_SOP_PUSH_DUP:
2788 r = loongarch_pop (&opr1);
2789 if (r == bfd_reloc_ok)
2791 r = loongarch_push (opr1);
2792 if (r == bfd_reloc_ok)
2793 r = loongarch_push (opr1);
2795 break;
2797 case R_LARCH_SOP_ASSERT:
2798 r = loongarch_pop (&opr1);
2799 if (r != bfd_reloc_ok || !opr1)
2800 r = bfd_reloc_notsupported;
2801 break;
2803 case R_LARCH_SOP_NOT:
2804 r = loongarch_pop (&opr1);
2805 if (r == bfd_reloc_ok)
2806 r = loongarch_push (!opr1);
2807 break;
2809 case R_LARCH_SOP_SUB:
2810 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
2811 break;
2813 case R_LARCH_SOP_SL:
2814 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
2815 break;
2817 case R_LARCH_SOP_SR:
2818 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
2819 break;
2821 case R_LARCH_SOP_AND:
2822 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
2823 break;
2825 case R_LARCH_SOP_ADD:
2826 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
2827 break;
2829 case R_LARCH_SOP_IF_ELSE:
2830 r = loongarch_pop (&opr3);
2831 if (r == bfd_reloc_ok)
2833 r = loongarch_pop (&opr2);
2834 if (r == bfd_reloc_ok)
2836 r = loongarch_pop (&opr1);
2837 if (r == bfd_reloc_ok)
2838 r = loongarch_push (opr1 ? opr2 : opr3);
2841 break;
2843 case R_LARCH_SOP_POP_32_S_10_5:
2844 case R_LARCH_SOP_POP_32_S_10_12:
2845 case R_LARCH_SOP_POP_32_S_10_16:
2846 case R_LARCH_SOP_POP_32_S_10_16_S2:
2847 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2848 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2849 case R_LARCH_SOP_POP_32_S_5_20:
2850 case R_LARCH_SOP_POP_32_U_10_12:
2851 case R_LARCH_SOP_POP_32_U:
2852 r = loongarch_pop (&opr1);
2853 if (r != bfd_reloc_ok)
2854 break;
2855 r = loongarch_check_offset (rel, input_section);
2856 if (r != bfd_reloc_ok)
2857 break;
2859 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2860 howto, input_bfd,
2861 contents, (bfd_vma)opr1);
2862 break;
2864 case R_LARCH_TLS_DTPREL32:
2865 case R_LARCH_32:
2866 case R_LARCH_TLS_DTPREL64:
2867 case R_LARCH_64:
2868 r = loongarch_check_offset (rel, input_section);
2869 if (r != bfd_reloc_ok)
2870 break;
2872 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2873 break;
2875 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2876 Because set/sub reloc pair not support multi-thread. While add/sub
2877 reloc pair process order not affect the final result.
2879 For add/sub reloc, the original value will be involved in the
2880 calculation. In order not to add/sub extra value, we write 0 to symbol
2881 address at assembly time.
2883 add/sub reloc bits determined by the value after symbol subtraction,
2884 not symbol value.
2886 add/sub reloc save part of the symbol value, so we only need to
2887 save howto->dst_mask bits. */
2888 case R_LARCH_ADD6:
2889 case R_LARCH_SUB6:
2891 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2892 contents + rel->r_offset);
2893 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2894 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2895 r = bfd_reloc_ok;
2896 break;
2899 /* Not need to read the original value, just write the new value. */
2900 case R_LARCH_ADD8:
2901 case R_LARCH_ADD16:
2902 case R_LARCH_ADD24:
2903 case R_LARCH_ADD32:
2904 case R_LARCH_ADD64:
2905 case R_LARCH_SUB8:
2906 case R_LARCH_SUB16:
2907 case R_LARCH_SUB24:
2908 case R_LARCH_SUB32:
2909 case R_LARCH_SUB64:
2911 /* Because add/sub reloc is processed separately,
2912 so the high bits is invalid. */
2913 bfd_vma word = value & howto->dst_mask;
2914 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2915 r = bfd_reloc_ok;
2916 break;
2919 case R_LARCH_ADD_ULEB128:
2920 case R_LARCH_SUB_ULEB128:
2922 unsigned int len = 0;
2923 /* Before write uleb128, first read it to get it's length. */
2924 _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2925 loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2926 r = bfd_reloc_ok;
2927 break;
2930 /* For eh_frame and debug info. */
2931 case R_LARCH_32_PCREL:
2932 case R_LARCH_64_PCREL:
2934 value -= sec_addr (input_section) + rel->r_offset;
2935 value += rel->r_addend;
2936 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2937 contents + rel->r_offset);
2938 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2939 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2940 r = bfd_reloc_ok;
2941 break;
2944 /* New reloc type.
2945 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2946 case R_LARCH_B16:
2947 case R_LARCH_B21:
2948 case R_LARCH_B26:
2949 case R_LARCH_ABS_HI20:
2950 case R_LARCH_ABS_LO12:
2951 case R_LARCH_ABS64_LO20:
2952 case R_LARCH_ABS64_HI12:
2953 case R_LARCH_PCALA_HI20:
2954 case R_LARCH_PCALA_LO12:
2955 case R_LARCH_PCALA64_LO20:
2956 case R_LARCH_PCALA64_HI12:
2957 case R_LARCH_GOT_PC_HI20:
2958 case R_LARCH_GOT_PC_LO12:
2959 case R_LARCH_GOT64_PC_LO20:
2960 case R_LARCH_GOT64_PC_HI12:
2961 case R_LARCH_GOT_HI20:
2962 case R_LARCH_GOT_LO12:
2963 case R_LARCH_GOT64_LO20:
2964 case R_LARCH_GOT64_HI12:
2965 case R_LARCH_TLS_LE_HI20:
2966 case R_LARCH_TLS_LE_LO12:
2967 case R_LARCH_TLS_LE_HI20_R:
2968 case R_LARCH_TLS_LE_LO12_R:
2969 case R_LARCH_TLS_LE64_LO20:
2970 case R_LARCH_TLS_LE64_HI12:
2971 case R_LARCH_TLS_IE_PC_HI20:
2972 case R_LARCH_TLS_IE_PC_LO12:
2973 case R_LARCH_TLS_IE64_PC_LO20:
2974 case R_LARCH_TLS_IE64_PC_HI12:
2975 case R_LARCH_TLS_IE_HI20:
2976 case R_LARCH_TLS_IE_LO12:
2977 case R_LARCH_TLS_IE64_LO20:
2978 case R_LARCH_TLS_IE64_HI12:
2979 case R_LARCH_TLS_LD_PC_HI20:
2980 case R_LARCH_TLS_LD_HI20:
2981 case R_LARCH_TLS_GD_PC_HI20:
2982 case R_LARCH_TLS_GD_HI20:
2983 case R_LARCH_PCREL20_S2:
2984 case R_LARCH_CALL36:
2985 case R_LARCH_TLS_DESC_PC_HI20:
2986 case R_LARCH_TLS_DESC_PC_LO12:
2987 case R_LARCH_TLS_DESC64_PC_LO20:
2988 case R_LARCH_TLS_DESC64_PC_HI12:
2989 case R_LARCH_TLS_DESC_HI20:
2990 case R_LARCH_TLS_DESC_LO12:
2991 case R_LARCH_TLS_DESC64_LO20:
2992 case R_LARCH_TLS_DESC64_HI12:
2993 case R_LARCH_TLS_LD_PCREL20_S2:
2994 case R_LARCH_TLS_GD_PCREL20_S2:
2995 case R_LARCH_TLS_DESC_PCREL20_S2:
2996 r = loongarch_check_offset (rel, input_section);
2997 if (r != bfd_reloc_ok)
2998 break;
3000 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
3001 howto, input_bfd,
3002 contents, value);
3003 break;
3005 case R_LARCH_TLS_DESC_LD:
3006 case R_LARCH_TLS_DESC_CALL:
3007 r = bfd_reloc_ok;
3008 break;
3010 case R_LARCH_RELAX:
3011 case R_LARCH_TLS_LE_ADD_R:
3012 break;
3014 default:
3015 r = bfd_reloc_notsupported;
3017 return r;
3020 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
3021 static struct
3023 bfd *bfd;
3024 asection *section;
3025 bfd_vma r_offset;
3026 int r_type;
3027 bfd_vma relocation;
3028 Elf_Internal_Sym *sym;
3029 struct elf_link_hash_entry *h;
3030 bfd_vma addend;
3031 int64_t top_then;
3032 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
3033 static size_t larch_reloc_queue_head = 0;
3034 static size_t larch_reloc_queue_tail = 0;
3036 static const char *
3037 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
3038 Elf_Internal_Sym *sym)
3040 const char *ret = NULL;
3041 if (sym)
3042 ret = bfd_elf_string_from_elf_section (input_bfd,
3043 elf_symtab_hdr (input_bfd).sh_link,
3044 sym->st_name);
3045 else if (h)
3046 ret = h->root.root.string;
3048 if (ret == NULL || *ret == '\0')
3049 ret = "<nameless>";
3050 return ret;
3053 static void
3054 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
3055 bfd_vma r_offset, Elf_Internal_Sym *sym,
3056 struct elf_link_hash_entry *h, bfd_vma addend)
3058 if ((larch_reloc_queue_head == 0
3059 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
3060 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
3061 larch_reloc_queue_head =
3062 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
3063 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
3064 larch_reloc_queue[larch_reloc_queue_tail].section = section;
3065 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
3066 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
3067 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
3068 larch_reloc_queue[larch_reloc_queue_tail].h = h;
3069 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
3070 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
3071 larch_reloc_queue_tail =
3072 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
3075 static void
3076 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
3078 size_t i = larch_reloc_queue_head;
3079 bfd *a_bfd = NULL;
3080 asection *section = NULL;
3081 bfd_vma r_offset = 0;
3082 int inited = 0;
3083 p ("Dump relocate record:\n");
3084 p ("stack top\t\trelocation name\t\tsymbol");
3085 while (i != larch_reloc_queue_tail)
3087 if (a_bfd != larch_reloc_queue[i].bfd
3088 || section != larch_reloc_queue[i].section
3089 || r_offset != larch_reloc_queue[i].r_offset)
3091 a_bfd = larch_reloc_queue[i].bfd;
3092 section = larch_reloc_queue[i].section;
3093 r_offset = larch_reloc_queue[i].r_offset;
3094 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
3095 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
3098 if (!inited)
3099 inited = 1, p ("...\n");
3101 reloc_howto_type *howto =
3102 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
3103 larch_reloc_queue[i].r_type);
3104 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
3105 howto ? howto->name : "<unknown reloc>",
3106 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
3107 larch_reloc_queue[i].sym));
3109 long addend = larch_reloc_queue[i].addend;
3110 if (addend < 0)
3111 p (" - %ld", -addend);
3112 else if (0 < addend)
3113 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
3115 p ("\n");
3116 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
3118 p ("\n"
3119 "-- Record dump end --\n\n");
3122 static bool
3123 loongarch_reloc_is_fatal (struct bfd_link_info *info,
3124 bfd *input_bfd,
3125 asection *input_section,
3126 Elf_Internal_Rela *rel,
3127 reloc_howto_type *howto,
3128 bfd_reloc_status_type rtype,
3129 bool is_undefweak,
3130 const char *name,
3131 const char *msg)
3133 bool fatal = true;
3134 switch (rtype)
3136 /* 'dangerous' means we do it but can't promise it's ok
3137 'unsupport' means out of ability of relocation type
3138 'undefined' means we can't deal with the undefined symbol. */
3139 case bfd_reloc_undefined:
3140 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
3141 rel->r_offset, true);
3142 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3143 input_bfd, input_section, rel->r_offset,
3144 howto->name,
3145 is_undefweak ? "[undefweak] " : "", name, msg);
3146 break;
3147 case bfd_reloc_dangerous:
3148 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
3149 input_bfd, input_section, rel->r_offset,
3150 howto->name,
3151 is_undefweak ? "[undefweak] " : "", name, msg);
3152 fatal = false;
3153 break;
3154 case bfd_reloc_notsupported:
3155 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3156 input_bfd, input_section, rel->r_offset,
3157 howto->name,
3158 is_undefweak ? "[undefweak] " : "", name, msg);
3159 break;
3160 default:
3161 break;
3163 return fatal;
3166 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
3167 hi20 immediate need to add 0x1.
3168 For example: pc 0x120000000, symbol 0x120000812
3169 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
3170 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
3171 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
3173 At run:
3174 pcalau12i $t0, hi20 (0x1)
3175 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
3176 addi.d $t0, $t0, lo12 (0x812)
3177 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
3178 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
3179 = 0x120000812
3180 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
3181 error.
3182 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
3183 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
3184 ({ \
3185 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3186 relocation = (relocation & ~(bfd_vma)0xfff) \
3187 - (pc & ~(bfd_vma)0xfff); \
3188 if (__lo > 0x7ff) \
3189 relocation += 0x1000; \
3192 /* Handle problems caused by symbol extensions in TLS LE, The processing
3193 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
3194 #define RELOCATE_TLS_TP32_HI20(relocation) \
3195 ({ \
3196 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3197 if (__lo > 0x7ff) \
3198 relocation += 0x800; \
3199 relocation = relocation & ~(bfd_vma)0xfff; \
3202 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
3203 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
3204 = 0x712347ffff000
3205 lo12: 0x1812348ffff812 & 0xfff = 0x812
3206 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
3207 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
3208 hi12: 0x0
3210 pcalau12i $t1, hi20 (0x80000)
3211 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
3212 = 0x11000010000100 + 0xffffffff80000000
3213 = 0x10ffff90000000
3214 addi.d $t0, $zero, lo12 (0x812)
3215 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
3216 lo20 need to sub 0x1)
3217 lu32i.d $t0, lo20 (0x71234)
3218 $t0 = {0x71234, 0xfffff812}
3219 = 0x71234fffff812
3220 lu52i.d $t0, hi12 (0x0)
3221 $t0 = {0x0, 0x71234fffff812}
3222 = 0x71234fffff812
3223 add.d $t1, $t1, $t0
3224 $t1 = 0x10ffff90000000 + 0x71234fffff812
3225 = 0x1812348ffff812. */
3226 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
3227 ({ \
3228 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
3229 relocation = (relocation & ~(bfd_vma)0xfff) \
3230 - ((pc) & ~(bfd_vma)0xfff); \
3231 if (__lo > 0x7ff) \
3232 relocation += (0x1000 - 0x100000000); \
3233 if (relocation & 0x80000000) \
3234 relocation += 0x100000000; \
3238 /* Compute the tp/dtp offset of a tls symbol.
3239 It is dtp offset in dynamic tls model (gd/ld) and tp
3240 offset in static tls model (ie/le). Both offsets are
3241 calculated the same way on LoongArch, so the same
3242 function is used. */
3243 static bfd_vma
3244 tlsoff (struct bfd_link_info *info, bfd_vma addr)
3246 /* If tls_sec is NULL, we should have signalled an error already. */
3247 if (elf_hash_table (info)->tls_sec == NULL)
3248 return 0;
3249 return addr - elf_hash_table (info)->tls_sec->vma;
3252 static int
3253 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
3254 bfd *input_bfd, asection *input_section,
3255 bfd_byte *contents, Elf_Internal_Rela *relocs,
3256 Elf_Internal_Sym *local_syms,
3257 asection **local_sections)
3259 Elf_Internal_Rela *rel;
3260 Elf_Internal_Rela *relend;
3261 bool fatal = false;
3262 asection *sreloc = elf_section_data (input_section)->sreloc;
3263 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3264 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
3265 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3266 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
3267 bool is_pic = bfd_link_pic (info);
3268 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
3269 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
3270 asection *got = htab->elf.sgot;
3272 relend = relocs + input_section->reloc_count;
3273 for (rel = relocs; rel < relend; rel++)
3275 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
3276 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
3277 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
3278 reloc_howto_type *howto = NULL;
3279 asection *sec = NULL;
3280 Elf_Internal_Sym *sym = NULL;
3281 struct elf_link_hash_entry *h = NULL;
3282 const char *name;
3283 bfd_reloc_status_type r = bfd_reloc_ok;
3284 bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
3285 bool resolved_local, resolved_dynly, resolved_to_const;
3286 char tls_type;
3287 bfd_vma relocation, off, ie_off, desc_off;
3288 int i, j;
3289 bool resolve_pcrel_undef_weak = false;
3291 /* When an unrecognized relocation is encountered, which usually
3292 occurs when using a newer assembler but an older linker, an error
3293 should be reported instead of continuing to the next relocation. */
3294 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
3295 if (howto == NULL)
3296 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
3298 if (r_type == R_LARCH_GNU_VTINHERIT || r_type == R_LARCH_GNU_VTENTRY)
3299 continue;
3301 /* This is a final link. */
3302 if (r_symndx < symtab_hdr->sh_info)
3304 is_undefweak = false;
3305 unresolved_reloc = false;
3306 sym = local_syms + r_symndx;
3307 sec = local_sections[r_symndx];
3308 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
3310 /* Relocate against local STT_GNU_IFUNC symbol. */
3311 if (!bfd_link_relocatable (info)
3312 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
3314 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
3315 false);
3316 if (h == NULL)
3317 abort ();
3319 /* Set STT_GNU_IFUNC symbol value. */
3320 h->root.u.def.value = sym->st_value;
3321 h->root.u.def.section = sec;
3323 defined_local = true;
3324 resolved_local = true;
3325 resolved_dynly = false;
3326 resolved_to_const = false;
3328 /* Calc in funtion elf_link_input_bfd,
3329 * if #define elf_backend_rela_normal to 1. */
3330 if (bfd_link_relocatable (info)
3331 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3332 continue;
3334 else
3336 bool warned, ignored;
3338 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3339 r_symndx, symtab_hdr, sym_hashes,
3340 h, sec, relocation,
3341 unresolved_reloc, warned, ignored);
3342 /* Here means symbol isn't local symbol only and 'h != NULL'. */
3344 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
3345 symbol. And 'dynamic_undefined_weak' specify what to do when
3346 meeting undefweak. */
3348 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
3350 defined_local = false;
3351 resolved_local = false;
3352 resolved_to_const = (!is_dyn || h->dynindx == -1
3353 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
3354 resolved_dynly = !resolved_local && !resolved_to_const;
3356 else if (warned)
3358 /* Symbol undefined offen means failed already. I don't know why
3359 'warned' here but I guess it want to continue relocating as if
3360 no error occures to find other errors as more as possible. */
3362 /* To avoid generating warning messages about truncated
3363 relocations, set the relocation's address to be the same as
3364 the start of this section. */
3365 relocation = (input_section->output_section
3366 ? input_section->output_section->vma
3367 : 0);
3369 defined_local = relocation != 0;
3370 resolved_local = defined_local;
3371 resolved_to_const = !resolved_local;
3372 resolved_dynly = false;
3374 else
3376 defined_local = !unresolved_reloc && !ignored;
3377 resolved_local =
3378 defined_local && LARCH_REF_LOCAL (info, h);
3379 resolved_dynly = !resolved_local;
3380 resolved_to_const = !resolved_local && !resolved_dynly;
3384 name = loongarch_sym_name (input_bfd, h, sym);
3386 if (sec != NULL && discarded_section (sec))
3387 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
3388 1, relend, howto, 0, contents);
3390 if (bfd_link_relocatable (info))
3391 continue;
3393 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
3394 from removed linkonce sections, or sections discarded by a linker
3395 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
3396 if (r_symndx == STN_UNDEF)
3398 defined_local = false;
3399 resolved_local = false;
3400 resolved_dynly = false;
3401 resolved_to_const = true;
3404 /* The ifunc reference generate plt. */
3405 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
3407 defined_local = true;
3408 resolved_local = true;
3409 resolved_dynly = false;
3410 resolved_to_const = false;
3411 relocation = sec_addr (plt) + h->plt.offset;
3414 unresolved_reloc = resolved_dynly;
3416 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
3418 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
3420 BFD_ASSERT (!resolved_local || defined_local);
3422 is_desc = false;
3423 is_ie = false;
3424 switch (r_type)
3426 case R_LARCH_MARK_PCREL:
3427 case R_LARCH_MARK_LA:
3428 case R_LARCH_NONE:
3429 r = bfd_reloc_continue;
3430 unresolved_reloc = false;
3431 break;
3433 case R_LARCH_32:
3434 case R_LARCH_64:
3435 if (resolved_dynly || (is_pic && resolved_local))
3437 Elf_Internal_Rela outrel;
3439 /* When generating a shared object, these relocations are copied
3440 into the output file to be resolved at run time. */
3442 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
3443 input_section,
3444 rel->r_offset);
3446 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
3447 && (input_section->flags & SEC_ALLOC));
3449 outrel.r_offset += sec_addr (input_section);
3451 /* A pointer point to a ifunc symbol. */
3452 if (h && h->type == STT_GNU_IFUNC)
3454 if (h->dynindx == -1)
3456 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
3457 outrel.r_addend = (h->root.u.def.value
3458 + h->root.u.def.section->output_section->vma
3459 + h->root.u.def.section->output_offset);
3461 else
3463 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3464 outrel.r_addend = 0;
3467 if (LARCH_REF_LOCAL (info, h))
3470 if (htab->elf.splt != NULL)
3471 sreloc = htab->elf.srelgot;
3472 else
3473 sreloc = htab->elf.irelplt;
3475 else
3478 if (bfd_link_pic (info))
3479 sreloc = htab->elf.irelifunc;
3480 else if (htab->elf.splt != NULL)
3481 sreloc = htab->elf.srelgot;
3482 else
3483 sreloc = htab->elf.irelplt;
3486 else if (resolved_dynly)
3488 if (h->dynindx == -1)
3489 outrel.r_info = ELFNN_R_INFO (0, r_type);
3490 else
3491 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
3493 outrel.r_addend = rel->r_addend;
3495 else
3497 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3498 outrel.r_addend = relocation + rel->r_addend;
3501 /* No alloc space of func allocate_dynrelocs.
3502 No alloc space of invalid R_LARCH_32 in ELFCLASS64. */
3503 if (unresolved_reloc
3504 && (ARCH_SIZE == 32 || r_type != R_LARCH_32)
3505 && !(h && (h->is_weakalias || !h->dyn_relocs)))
3507 if (info->enable_dt_relr
3508 && (ELFNN_R_TYPE (outrel.r_info) == R_LARCH_RELATIVE)
3509 && input_section->alignment_power != 0
3510 && rel->r_offset % 2 == 0)
3511 /* Don't emit a relative relocation that is packed,
3512 only apply the addend (as if we are applying the
3513 original R_LARCH_NN reloc in a PDE). */
3514 r = perform_relocation (rel, input_section, howto,
3515 relocation, input_bfd,
3516 contents);
3517 else
3518 loongarch_elf_append_rela (output_bfd, sreloc,
3519 &outrel);
3523 relocation += rel->r_addend;
3524 break;
3526 case R_LARCH_ADD6:
3527 case R_LARCH_ADD8:
3528 case R_LARCH_ADD16:
3529 case R_LARCH_ADD24:
3530 case R_LARCH_ADD32:
3531 case R_LARCH_ADD64:
3533 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
3534 contents + rel->r_offset);
3535 relocation = old_value + relocation + rel->r_addend;
3536 break;
3539 case R_LARCH_SUB6:
3540 case R_LARCH_SUB8:
3541 case R_LARCH_SUB16:
3542 case R_LARCH_SUB24:
3543 case R_LARCH_SUB32:
3544 case R_LARCH_SUB64:
3546 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
3547 contents + rel->r_offset);
3548 relocation = old_value - relocation - rel->r_addend;
3549 break;
3552 case R_LARCH_ADD_ULEB128:
3553 case R_LARCH_SUB_ULEB128:
3555 /* Get the value and length of the uleb128 data. */
3556 unsigned int len = 0;
3557 bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
3558 contents + rel->r_offset, &len);
3560 if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
3561 relocation = old_value + relocation + rel->r_addend;
3562 else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
3563 relocation = old_value - relocation - rel->r_addend;
3565 bfd_vma mask = (1 << (7 * len)) - 1;
3566 relocation &= mask;
3567 break;
3570 case R_LARCH_TLS_DTPREL32:
3571 case R_LARCH_TLS_DTPREL64:
3572 if (resolved_dynly)
3574 Elf_Internal_Rela outrel;
3576 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
3577 input_section,
3578 rel->r_offset);
3579 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
3580 && (input_section->flags & SEC_ALLOC));
3581 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
3582 outrel.r_offset += sec_addr (input_section);
3583 outrel.r_addend = rel->r_addend;
3584 if (unresolved_reloc)
3585 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
3586 break;
3589 if (resolved_to_const)
3590 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
3591 rel, howto,
3592 bfd_reloc_notsupported,
3593 is_undefweak, name,
3594 "Internal:");
3595 if (resolved_local)
3597 if (!elf_hash_table (info)->tls_sec)
3599 fatal = loongarch_reloc_is_fatal (info, input_bfd,
3600 input_section, rel, howto, bfd_reloc_notsupported,
3601 is_undefweak, name, "TLS section not be created");
3603 else
3604 relocation = tlsoff (info, relocation);
3606 else
3608 fatal = loongarch_reloc_is_fatal (info, input_bfd,
3609 input_section, rel, howto, bfd_reloc_undefined,
3610 is_undefweak, name,
3611 "TLS LE just can be resolved local only.");
3614 break;
3616 case R_LARCH_SOP_PUSH_TLS_TPREL:
3617 if (resolved_local)
3619 if (!elf_hash_table (info)->tls_sec)
3620 fatal = (loongarch_reloc_is_fatal
3621 (info, input_bfd, input_section, rel, howto,
3622 bfd_reloc_notsupported, is_undefweak, name,
3623 "TLS section not be created"));
3624 else
3625 relocation = tlsoff (info, relocation);
3627 else
3628 fatal = (loongarch_reloc_is_fatal
3629 (info, input_bfd, input_section, rel, howto,
3630 bfd_reloc_undefined, is_undefweak, name,
3631 "TLS LE just can be resolved local only."));
3632 break;
3634 case R_LARCH_SOP_PUSH_ABSOLUTE:
3635 if (is_undefweak)
3637 if (resolved_dynly)
3638 fatal = (loongarch_reloc_is_fatal
3639 (info, input_bfd, input_section, rel, howto,
3640 bfd_reloc_dangerous, is_undefweak, name,
3641 "Someone require us to resolve undefweak "
3642 "symbol dynamically. \n"
3643 "But this reloc can't be done. "
3644 "I think I can't throw error "
3645 "for this\n"
3646 "so I resolved it to 0. "
3647 "I suggest to re-compile with '-fpic'."));
3649 relocation = 0;
3650 unresolved_reloc = false;
3651 break;
3654 if (resolved_to_const)
3656 relocation += rel->r_addend;
3657 break;
3660 if (is_pic)
3662 fatal = (loongarch_reloc_is_fatal
3663 (info, input_bfd, input_section, rel, howto,
3664 bfd_reloc_notsupported, is_undefweak, name,
3665 "Under PIC we don't know load address. Re-compile "
3666 "with '-fpic'?"));
3667 break;
3670 if (resolved_dynly)
3672 if (!(plt && h && h->plt.offset != MINUS_ONE))
3674 fatal = (loongarch_reloc_is_fatal
3675 (info, input_bfd, input_section, rel, howto,
3676 bfd_reloc_undefined, is_undefweak, name,
3677 "Can't be resolved dynamically. Try to re-compile "
3678 "with '-fpic'?"));
3679 break;
3682 if (rel->r_addend != 0)
3684 fatal = (loongarch_reloc_is_fatal
3685 (info, input_bfd, input_section, rel, howto,
3686 bfd_reloc_notsupported, is_undefweak, name,
3687 "Shouldn't be with r_addend."));
3688 break;
3691 relocation = sec_addr (plt) + h->plt.offset;
3692 unresolved_reloc = false;
3693 break;
3696 if (resolved_local)
3698 relocation += rel->r_addend;
3699 break;
3702 break;
3704 case R_LARCH_SOP_PUSH_PCREL:
3705 case R_LARCH_SOP_PUSH_PLT_PCREL:
3706 unresolved_reloc = false;
3708 if (is_undefweak)
3710 i = 0, j = 0;
3711 relocation = 0;
3712 if (resolved_dynly)
3714 if (h && h->plt.offset != MINUS_ONE)
3715 i = 1, j = 2;
3716 else
3717 fatal = (loongarch_reloc_is_fatal
3718 (info, input_bfd, input_section, rel, howto,
3719 bfd_reloc_dangerous, is_undefweak, name,
3720 "Undefweak need to be resolved dynamically, "
3721 "but PLT stub doesn't represent."));
3724 else
3726 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
3728 fatal = (loongarch_reloc_is_fatal
3729 (info, input_bfd, input_section, rel, howto,
3730 bfd_reloc_undefined, is_undefweak, name,
3731 "PLT stub does not represent and "
3732 "symbol not defined."));
3733 break;
3736 if (resolved_local)
3737 i = 0, j = 2;
3738 else /* if (resolved_dynly) */
3740 if (!(h && h->plt.offset != MINUS_ONE))
3741 fatal = (loongarch_reloc_is_fatal
3742 (info, input_bfd, input_section, rel, howto,
3743 bfd_reloc_dangerous, is_undefweak, name,
3744 "Internal: PLT stub doesn't represent. "
3745 "Resolve it with pcrel"));
3746 i = 1, j = 3;
3750 for (; i < j; i++)
3752 if ((i & 1) == 0 && defined_local)
3754 relocation -= pc;
3755 relocation += rel->r_addend;
3756 break;
3759 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
3761 if (rel->r_addend != 0)
3763 fatal = (loongarch_reloc_is_fatal
3764 (info, input_bfd, input_section, rel, howto,
3765 bfd_reloc_notsupported, is_undefweak, name,
3766 "PLT shouldn't be with r_addend."));
3767 break;
3769 relocation = sec_addr (plt) + h->plt.offset - pc;
3770 break;
3773 break;
3775 case R_LARCH_SOP_PUSH_GPREL:
3776 unresolved_reloc = false;
3778 if (rel->r_addend != 0)
3780 fatal = (loongarch_reloc_is_fatal
3781 (info, input_bfd, input_section, rel, howto,
3782 bfd_reloc_notsupported, is_undefweak, name,
3783 "Shouldn't be with r_addend."));
3784 break;
3787 if (h != NULL)
3789 off = h->got.offset & (~1);
3791 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
3793 fatal = (loongarch_reloc_is_fatal
3794 (info, input_bfd, input_section, rel, howto,
3795 bfd_reloc_notsupported, is_undefweak, name,
3796 "Internal: GOT entry doesn't represent."));
3797 break;
3800 /* Hidden symbol not has .got entry, only .got.plt entry
3801 so gprel is (plt - got). */
3802 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3804 if (h->plt.offset == (bfd_vma) -1)
3806 abort();
3809 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3810 off = plt_index * GOT_ENTRY_SIZE;
3812 if (htab->elf.splt != NULL)
3814 /* Section .plt header is 2 times of plt entry. */
3815 off = sec_addr (htab->elf.sgotplt) + off
3816 - sec_addr (htab->elf.sgot);
3818 else
3820 /* Section iplt not has plt header. */
3821 off = sec_addr (htab->elf.igotplt) + off
3822 - sec_addr (htab->elf.sgot);
3826 if ((h->got.offset & 1) == 0)
3828 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3829 bfd_link_pic (info), h)
3830 && ((bfd_link_pic (info)
3831 && LARCH_REF_LOCAL (info, h))))
3833 /* This is actually a static link, or it is a
3834 -Bsymbolic link and the symbol is defined
3835 locally, or the symbol was forced to be local
3836 because of a version file. We must initialize
3837 this entry in the global offset table. Since the
3838 offset must always be a multiple of the word size,
3839 we use the least significant bit to record whether
3840 we have initialized it already.
3842 When doing a dynamic link, we create a rela.got
3843 relocation entry to initialize the value. This
3844 is done in the finish_dynamic_symbol routine. */
3846 if (resolved_dynly)
3848 fatal = (loongarch_reloc_is_fatal
3849 (info, input_bfd, input_section, rel, howto,
3850 bfd_reloc_dangerous, is_undefweak, name,
3851 "Internal: here shouldn't dynamic."));
3854 if (!(defined_local || resolved_to_const))
3856 fatal = (loongarch_reloc_is_fatal
3857 (info, input_bfd, input_section, rel, howto,
3858 bfd_reloc_undefined, is_undefweak, name,
3859 "Internal: "));
3860 break;
3863 asection *s;
3864 Elf_Internal_Rela outrel;
3865 /* We need to generate a R_LARCH_RELATIVE reloc
3866 for the dynamic linker. */
3867 s = htab->elf.srelgot;
3868 if (!s)
3870 fatal = loongarch_reloc_is_fatal
3871 (info, input_bfd,
3872 input_section, rel, howto,
3873 bfd_reloc_notsupported, is_undefweak, name,
3874 "Internal: '.rel.got' not represent");
3875 break;
3878 outrel.r_offset = sec_addr (got) + off;
3879 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3880 outrel.r_addend = relocation; /* Link-time addr. */
3881 loongarch_elf_append_rela (output_bfd, s, &outrel);
3883 bfd_put_NN (output_bfd, relocation, got->contents + off);
3884 h->got.offset |= 1;
3887 else
3889 if (!local_got_offsets)
3891 fatal = (loongarch_reloc_is_fatal
3892 (info, input_bfd, input_section, rel, howto,
3893 bfd_reloc_notsupported, is_undefweak, name,
3894 "Internal: local got offsets not reporesent."));
3895 break;
3898 off = local_got_offsets[r_symndx] & (~1);
3900 if (local_got_offsets[r_symndx] == MINUS_ONE)
3902 fatal = (loongarch_reloc_is_fatal
3903 (info, input_bfd, input_section, rel, howto,
3904 bfd_reloc_notsupported, is_undefweak, name,
3905 "Internal: GOT entry doesn't represent."));
3906 break;
3909 /* The offset must always be a multiple of the word size.
3910 So, we can use the least significant bit to record
3911 whether we have already processed this entry. */
3912 if ((local_got_offsets[r_symndx] & 1) == 0)
3914 if (is_pic)
3916 asection *s;
3917 Elf_Internal_Rela outrel;
3918 /* We need to generate a R_LARCH_RELATIVE reloc
3919 for the dynamic linker. */
3920 s = htab->elf.srelgot;
3921 if (!s)
3923 fatal = (loongarch_reloc_is_fatal
3924 (info, input_bfd, input_section, rel, howto,
3925 bfd_reloc_notsupported, is_undefweak, name,
3926 "Internal: '.rel.got' not represent"));
3927 break;
3930 outrel.r_offset = sec_addr (got) + off;
3931 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3932 outrel.r_addend = relocation; /* Link-time addr. */
3933 loongarch_elf_append_rela (output_bfd, s, &outrel);
3936 bfd_put_NN (output_bfd, relocation, got->contents + off);
3937 local_got_offsets[r_symndx] |= 1;
3940 relocation = off;
3942 break;
3944 case R_LARCH_SOP_PUSH_TLS_GOT:
3945 case R_LARCH_SOP_PUSH_TLS_GD:
3947 unresolved_reloc = false;
3948 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3949 is_ie = true;
3951 bfd_vma got_off = 0;
3952 if (h != NULL)
3954 got_off = h->got.offset;
3955 h->got.offset |= 1;
3957 else
3959 got_off = local_got_offsets[r_symndx];
3960 local_got_offsets[r_symndx] |= 1;
3963 BFD_ASSERT (got_off != MINUS_ONE);
3965 ie_off = 0;
3966 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3967 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3968 ie_off = 2 * GOT_ENTRY_SIZE;
3970 if ((got_off & 1) == 0)
3972 Elf_Internal_Rela rela;
3973 asection *srel = htab->elf.srelgot;
3975 int indx = 0;
3976 bool need_reloc = false;
3977 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx,
3978 need_reloc);
3980 if (tls_type & GOT_TLS_GD)
3982 if (need_reloc)
3984 /* Dynamic resolved Module ID. */
3985 rela.r_offset = sec_addr (got) + got_off;
3986 rela.r_addend = 0;
3987 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DTPMODNN);
3988 bfd_put_NN (output_bfd, 0, got->contents + got_off);
3989 loongarch_elf_append_rela (output_bfd, srel, &rela);
3991 if (indx == 0)
3993 /* Local symbol, tp offset has been known. */
3994 BFD_ASSERT (! unresolved_reloc);
3995 bfd_put_NN (output_bfd,
3996 tlsoff (info, relocation),
3997 (got->contents + got_off + GOT_ENTRY_SIZE));
3999 else
4001 /* Dynamic resolved block offset. */
4002 bfd_put_NN (output_bfd, 0,
4003 got->contents + got_off + GOT_ENTRY_SIZE);
4004 rela.r_info = ELFNN_R_INFO (indx,
4005 R_LARCH_TLS_DTPRELNN);
4006 rela.r_offset += GOT_ENTRY_SIZE;
4007 loongarch_elf_append_rela (output_bfd, srel, &rela);
4010 else
4012 /* In a static link or an executable link with the symbol
4013 binding locally. Mark it as belonging to module 1. */
4014 bfd_put_NN (output_bfd, 1, got->contents + got_off);
4015 bfd_put_NN (output_bfd, tlsoff (info, relocation),
4016 got->contents + got_off + GOT_ENTRY_SIZE);
4019 if (tls_type & GOT_TLS_IE)
4021 if (need_reloc)
4023 bfd_put_NN (output_bfd, 0,
4024 got->contents + got_off + ie_off);
4025 rela.r_offset = sec_addr (got) + got_off + ie_off;
4026 rela.r_addend = 0;
4028 if (indx == 0)
4029 rela.r_addend = tlsoff (info, relocation);
4030 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN);
4031 loongarch_elf_append_rela (output_bfd, srel, &rela);
4033 else
4035 /* In a static link or an executable link with the symbol
4036 binding locally, compute offset directly. */
4037 bfd_put_NN (output_bfd, tlsoff (info, relocation),
4038 got->contents + got_off + ie_off);
4043 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
4045 break;
4047 /* New reloc types. */
4048 case R_LARCH_B16:
4049 case R_LARCH_B21:
4050 case R_LARCH_B26:
4051 case R_LARCH_CALL36:
4052 unresolved_reloc = false;
4053 bool via_plt =
4054 plt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
4056 if (is_undefweak)
4058 relocation = 0;
4060 /* A call to an undefined weak symbol is converted to 0. */
4061 if (!via_plt && IS_CALL_RELOC (r_type))
4063 /* call36 fn1 => pcaddu18i $ra,0+jirl $ra,$zero,0
4064 tail36 $t0,fn1 => pcaddi18i $t0,0+jirl $zero,$zero,0 */
4065 if (R_LARCH_CALL36 == r_type)
4067 uint32_t jirl = bfd_get (32, input_bfd,
4068 contents + rel->r_offset + 4);
4069 uint32_t rd = LARCH_GET_RD (jirl);
4070 jirl = LARCH_OP_JIRL | rd;
4072 bfd_put (32, input_bfd, jirl,
4073 contents + rel->r_offset + 4);
4075 else
4077 uint32_t b_bl = bfd_get (32, input_bfd,
4078 contents + rel->r_offset);
4079 /* b %plt(fn1) => jirl $zero,zero,0. */
4080 if (LARCH_INSN_B (b_bl))
4081 bfd_put (32, input_bfd, LARCH_OP_JIRL,
4082 contents + rel->r_offset);
4083 else
4084 /* bl %plt(fn1) => jirl $ra,zero,0. */
4085 bfd_put (32, input_bfd, LARCH_OP_JIRL | 0x1,
4086 contents + rel->r_offset);
4088 r = bfd_reloc_continue;
4089 break;
4093 if (resolved_local)
4095 relocation -= pc;
4096 relocation += rel->r_addend;
4098 else if (resolved_dynly)
4100 BFD_ASSERT (h
4101 && (h->plt.offset != MINUS_ONE
4102 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
4103 && rel->r_addend == 0);
4104 if (h && h->plt.offset == MINUS_ONE
4105 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
4107 relocation -= pc;
4108 relocation += rel->r_addend;
4110 else
4111 relocation = sec_addr (plt) + h->plt.offset - pc;
4114 break;
4116 case R_LARCH_ABS_HI20:
4117 case R_LARCH_ABS_LO12:
4118 case R_LARCH_ABS64_LO20:
4119 case R_LARCH_ABS64_HI12:
4121 if (is_undefweak)
4123 BFD_ASSERT (resolved_dynly);
4124 relocation = 0;
4125 break;
4127 else if (resolved_to_const || resolved_local)
4129 relocation += rel->r_addend;
4131 else if (resolved_dynly)
4133 unresolved_reloc = false;
4134 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
4135 && rel->r_addend == 0);
4136 relocation = sec_addr (plt) + h->plt.offset;
4139 break;
4141 case R_LARCH_PCALA64_HI12:
4142 pc -= 4;
4143 /* Fall through. */
4144 case R_LARCH_PCALA64_LO20:
4145 pc -= 8;
4146 /* Fall through. */
4147 case R_LARCH_PCREL20_S2:
4148 case R_LARCH_PCALA_HI20:
4149 unresolved_reloc = false;
4151 /* If sym is undef weak and it's hidden or we are doing a static
4152 link, (sym + addend) should be resolved to runtime address
4153 (0 + addend). */
4154 resolve_pcrel_undef_weak =
4155 ((info->nointerp
4156 || (h && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT))
4157 && is_undefweak);
4159 if (resolve_pcrel_undef_weak)
4160 pc = 0;
4162 if (h && h->plt.offset != MINUS_ONE)
4163 relocation = sec_addr (plt) + h->plt.offset;
4164 else
4165 relocation += rel->r_addend;
4167 switch (r_type)
4169 case R_LARCH_PCREL20_S2:
4170 relocation -= pc;
4171 if (resolve_pcrel_undef_weak)
4173 bfd_signed_vma addr = (bfd_signed_vma) relocation;
4174 if (addr >= 2048 || addr < -2048)
4176 const char *msg =
4177 _("cannot resolve R_LARCH_PCREL20_S2 against "
4178 "undefined weak symbol with addend out of "
4179 "[-2048, 2048)");
4180 fatal =
4181 loongarch_reloc_is_fatal (info, input_bfd,
4182 input_section, rel,
4183 howto,
4184 bfd_reloc_notsupported,
4185 is_undefweak, name, msg);
4186 break;
4189 uint32_t insn = bfd_get (32, input_bfd,
4190 contents + rel->r_offset);
4191 insn = LARCH_GET_RD (insn) | LARCH_OP_ADDI_W;
4192 insn |= (relocation & 0xfff) << 10;
4193 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
4194 r = bfd_reloc_continue;
4196 break;
4197 case R_LARCH_PCALA_HI20:
4198 RELOCATE_CALC_PC32_HI20 (relocation, pc);
4199 if (resolve_pcrel_undef_weak)
4201 uint32_t insn = bfd_get (32, input_bfd,
4202 contents + rel->r_offset);
4203 insn = LARCH_GET_RD (insn) | LARCH_OP_LU12I_W;
4204 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
4206 break;
4207 default:
4208 RELOCATE_CALC_PC64_HI32 (relocation, pc);
4210 break;
4212 case R_LARCH_TLS_LE_HI20_R:
4213 relocation += rel->r_addend;
4214 relocation = tlsoff (info, relocation);
4215 RELOCATE_TLS_TP32_HI20 (relocation);
4216 break;
4218 case R_LARCH_PCALA_LO12:
4219 /* Not support if sym_addr in 2k page edge.
4220 pcalau12i pc_hi20 (sym_addr)
4221 ld.w/d pc_lo12 (sym_addr)
4222 ld.w/d pc_lo12 (sym_addr + x)
4224 can not calc correct address
4225 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
4227 if (h && h->plt.offset != MINUS_ONE)
4228 relocation = sec_addr (plt) + h->plt.offset;
4229 else
4230 relocation += rel->r_addend;
4232 /* For 2G jump, generate pcalau12i, jirl. */
4233 /* If use jirl, turns to R_LARCH_B16. */
4234 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
4235 if (LARCH_INSN_JIRL (insn))
4237 relocation &= 0xfff;
4238 /* Signed extend. */
4239 relocation = (relocation ^ 0x800) - 0x800;
4241 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
4242 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
4244 break;
4246 case R_LARCH_GOT_PC_HI20:
4247 case R_LARCH_GOT_HI20:
4248 /* Calc got offset. */
4250 unresolved_reloc = false;
4251 BFD_ASSERT (rel->r_addend == 0);
4253 bfd_vma got_off = 0;
4254 if (h != NULL)
4256 /* GOT ref or ifunc. */
4257 BFD_ASSERT (h->got.offset != MINUS_ONE
4258 || h->type == STT_GNU_IFUNC);
4260 got_off = h->got.offset & (~(bfd_vma)1);
4261 /* Hidden symbol not has got entry,
4262 * only got.plt entry so it is (plt - got). */
4263 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
4265 bfd_vma idx;
4266 if (htab->elf.splt != NULL)
4268 idx = (h->plt.offset - PLT_HEADER_SIZE)
4269 / PLT_ENTRY_SIZE;
4270 got_off = sec_addr (htab->elf.sgotplt)
4271 + GOTPLT_HEADER_SIZE
4272 + (idx * GOT_ENTRY_SIZE)
4273 - sec_addr (htab->elf.sgot);
4275 else
4277 idx = h->plt.offset / PLT_ENTRY_SIZE;
4278 got_off = sec_addr (htab->elf.sgotplt)
4279 + (idx * GOT_ENTRY_SIZE)
4280 - sec_addr (htab->elf.sgot);
4284 if ((h->got.offset & 1) == 0)
4286 /* We need to generate a R_LARCH_RELATIVE reloc once
4287 * in loongarch_elf_finish_dynamic_symbol or now,
4288 * call finish_dyn && nopic
4289 * or !call finish_dyn && pic. */
4290 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
4291 bfd_link_pic (info),
4293 && !bfd_is_abs_section(h->root.u.def.section)
4294 && bfd_link_pic (info)
4295 && LARCH_REF_LOCAL (info, h)
4296 && !info->enable_dt_relr)
4298 Elf_Internal_Rela rela;
4299 rela.r_offset = sec_addr (got) + got_off;
4300 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4301 rela.r_addend = relocation;
4302 loongarch_elf_append_rela (output_bfd,
4303 htab->elf.srelgot, &rela);
4305 h->got.offset |= 1;
4306 bfd_put_NN (output_bfd, relocation,
4307 got->contents + got_off);
4310 else
4312 BFD_ASSERT (local_got_offsets
4313 && local_got_offsets[r_symndx] != MINUS_ONE);
4315 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
4316 if (sym->st_shndx != SHN_ABS
4317 && (local_got_offsets[r_symndx] & 1) == 0)
4319 if (bfd_link_pic (info) && !info->enable_dt_relr)
4321 Elf_Internal_Rela rela;
4322 rela.r_offset = sec_addr (got) + got_off;
4323 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4324 rela.r_addend = relocation;
4325 loongarch_elf_append_rela (output_bfd,
4326 htab->elf.srelgot, &rela);
4328 local_got_offsets[r_symndx] |= 1;
4330 bfd_put_NN (output_bfd, relocation, got->contents + got_off);
4333 relocation = got_off + sec_addr (got);
4336 if (r_type == R_LARCH_GOT_PC_HI20)
4337 RELOCATE_CALC_PC32_HI20 (relocation, pc);
4339 break;
4341 case R_LARCH_GOT_PC_LO12:
4342 case R_LARCH_GOT64_PC_LO20:
4343 case R_LARCH_GOT64_PC_HI12:
4344 case R_LARCH_GOT_LO12:
4345 case R_LARCH_GOT64_LO20:
4346 case R_LARCH_GOT64_HI12:
4348 unresolved_reloc = false;
4349 bfd_vma got_off;
4350 if (h)
4351 got_off = h->got.offset & (~(bfd_vma)1);
4352 else
4353 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
4355 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
4357 bfd_vma idx;
4358 if (htab->elf.splt != NULL)
4359 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4360 else
4361 idx = h->plt.offset / PLT_ENTRY_SIZE;
4363 got_off = sec_addr (htab->elf.sgotplt)
4364 + GOTPLT_HEADER_SIZE
4365 + (idx * GOT_ENTRY_SIZE)
4366 - sec_addr (htab->elf.sgot);
4369 relocation = got_off + sec_addr (got);
4372 if (r_type == R_LARCH_GOT64_PC_HI12)
4373 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
4374 else if (r_type == R_LARCH_GOT64_PC_LO20)
4375 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
4377 break;
4379 case R_LARCH_TLS_LE_HI20:
4380 case R_LARCH_TLS_LE_LO12:
4381 case R_LARCH_TLS_LE_LO12_R:
4382 case R_LARCH_TLS_LE64_LO20:
4383 case R_LARCH_TLS_LE64_HI12:
4384 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
4386 relocation += rel->r_addend;
4387 relocation = tlsoff (info, relocation);
4388 break;
4390 /* TLS IE LD/GD process separately is troublesome.
4391 When a symbol is both ie and LD/GD, h->got.off |= 1
4392 make only one type be relocated. We must use
4393 h->got.offset |= 1 and h->got.offset |= 2
4394 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
4395 (IE LD/GD and reusable GOT reloc) must change to
4396 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
4397 as a tag.
4398 Now, LD and GD is both GOT_TLS_GD type, LD seems to
4399 can be omitted. */
4400 case R_LARCH_TLS_IE_PC_HI20:
4401 case R_LARCH_TLS_IE_HI20:
4402 case R_LARCH_TLS_LD_PC_HI20:
4403 case R_LARCH_TLS_LD_HI20:
4404 case R_LARCH_TLS_GD_PC_HI20:
4405 case R_LARCH_TLS_GD_HI20:
4406 case R_LARCH_TLS_DESC_PC_HI20:
4407 case R_LARCH_TLS_DESC_HI20:
4408 case R_LARCH_TLS_LD_PCREL20_S2:
4409 case R_LARCH_TLS_GD_PCREL20_S2:
4410 case R_LARCH_TLS_DESC_PCREL20_S2:
4411 BFD_ASSERT (rel->r_addend == 0);
4412 unresolved_reloc = false;
4414 if (r_type == R_LARCH_TLS_IE_PC_HI20
4415 || r_type == R_LARCH_TLS_IE_HI20)
4416 is_ie = true;
4418 if (r_type == R_LARCH_TLS_DESC_PC_HI20
4419 || r_type == R_LARCH_TLS_DESC_HI20
4420 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
4421 is_desc = true;
4423 bfd_vma got_off = 0;
4424 if (h != NULL)
4426 got_off = h->got.offset;
4427 h->got.offset |= 1;
4429 else
4431 got_off = local_got_offsets[r_symndx];
4432 local_got_offsets[r_symndx] |= 1;
4435 BFD_ASSERT (got_off != MINUS_ONE);
4437 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
4439 /* If a tls variable is accessed in multiple ways, GD uses
4440 the first two slots of GOT, desc follows with two slots,
4441 and IE uses one slot at the end. */
4442 off = 0;
4443 if (tls_type & GOT_TLS_GD)
4444 off += 2 * GOT_ENTRY_SIZE;
4445 desc_off = off;
4446 if (tls_type & GOT_TLS_GDESC)
4447 off += 2 * GOT_ENTRY_SIZE;
4448 ie_off = off;
4450 if ((got_off & 1) == 0)
4452 Elf_Internal_Rela rela;
4453 asection *relgot = htab->elf.srelgot;
4455 int indx = 0;
4456 bool need_reloc = false;
4457 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx,
4458 need_reloc);
4460 if (tls_type & GOT_TLS_GD)
4462 if (need_reloc)
4464 /* Dynamic resolved Module ID. */
4465 rela.r_offset = sec_addr (got) + got_off;
4466 rela.r_addend = 0;
4467 rela.r_info = ELFNN_R_INFO (indx,R_LARCH_TLS_DTPMODNN);
4468 bfd_put_NN (output_bfd, 0, got->contents + got_off);
4469 loongarch_elf_append_rela (output_bfd, relgot, &rela);
4471 if (indx == 0)
4473 /* Local symbol, tp offset has been known. */
4474 BFD_ASSERT (! unresolved_reloc);
4475 bfd_put_NN (output_bfd,
4476 tlsoff (info, relocation),
4477 (got->contents + got_off + GOT_ENTRY_SIZE));
4479 else
4481 /* Dynamic resolved block offset. */
4482 bfd_put_NN (output_bfd, 0,
4483 got->contents + got_off + GOT_ENTRY_SIZE);
4484 rela.r_info = ELFNN_R_INFO (indx,
4485 R_LARCH_TLS_DTPRELNN);
4486 rela.r_offset += GOT_ENTRY_SIZE;
4487 loongarch_elf_append_rela (output_bfd, relgot, &rela);
4490 else
4492 /* In a static link or an executable link with the symbol
4493 binding locally. Mark it as belonging to module 1. */
4494 bfd_put_NN (output_bfd, 1, got->contents + got_off);
4495 bfd_put_NN (output_bfd, tlsoff (info, relocation),
4496 got->contents + got_off + GOT_ENTRY_SIZE);
4499 if (tls_type & GOT_TLS_GDESC)
4501 /* Unless it is a static link, DESC always emits a
4502 dynamic relocation. */
4503 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4504 rela.r_offset = sec_addr (got) + got_off + desc_off;
4505 rela.r_addend = 0;
4506 if (indx == 0)
4507 rela.r_addend = tlsoff (info, relocation);
4509 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
4510 loongarch_elf_append_rela (output_bfd, relgot, &rela);
4511 bfd_put_NN (output_bfd, 0,
4512 got->contents + got_off + desc_off);
4514 if (tls_type & GOT_TLS_IE)
4516 if (need_reloc)
4518 bfd_put_NN (output_bfd, 0,
4519 got->contents + got_off + ie_off);
4520 rela.r_offset = sec_addr (got) + got_off + ie_off;
4521 rela.r_addend = 0;
4523 if (indx == 0)
4524 rela.r_addend = tlsoff (info, relocation);
4525 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN);
4526 loongarch_elf_append_rela (output_bfd, relgot, &rela);
4528 else
4530 /* In a static link or an executable link with the symbol
4531 bindinglocally, compute offset directly. */
4532 bfd_put_NN (output_bfd, tlsoff (info, relocation),
4533 got->contents + got_off + ie_off);
4537 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
4538 if (is_desc)
4539 relocation += desc_off;
4540 else if (is_ie)
4541 relocation += ie_off;
4543 if (r_type == R_LARCH_TLS_LD_PC_HI20
4544 || r_type == R_LARCH_TLS_GD_PC_HI20
4545 || r_type == R_LARCH_TLS_IE_PC_HI20
4546 || r_type == R_LARCH_TLS_DESC_PC_HI20)
4547 RELOCATE_CALC_PC32_HI20 (relocation, pc);
4548 else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
4549 || r_type == R_LARCH_TLS_GD_PCREL20_S2
4550 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
4551 relocation -= pc;
4552 /* else {} ABS relocations. */
4553 break;
4555 case R_LARCH_TLS_DESC_PC_LO12:
4556 case R_LARCH_TLS_DESC64_PC_LO20:
4557 case R_LARCH_TLS_DESC64_PC_HI12:
4558 case R_LARCH_TLS_DESC_LO12:
4559 case R_LARCH_TLS_DESC64_LO20:
4560 case R_LARCH_TLS_DESC64_HI12:
4562 unresolved_reloc = false;
4564 if (h)
4565 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
4566 else
4567 relocation = sec_addr (got)
4568 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
4570 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
4571 /* Use both TLS_GD and TLS_DESC. */
4572 if (GOT_TLS_GD_BOTH_P (tls_type))
4573 relocation += 2 * GOT_ENTRY_SIZE;
4575 if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
4576 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
4577 else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
4578 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
4580 break;
4583 case R_LARCH_TLS_DESC_LD:
4584 case R_LARCH_TLS_DESC_CALL:
4585 unresolved_reloc = false;
4586 break;
4588 case R_LARCH_TLS_IE_PC_LO12:
4589 case R_LARCH_TLS_IE64_PC_LO20:
4590 case R_LARCH_TLS_IE64_PC_HI12:
4591 case R_LARCH_TLS_IE_LO12:
4592 case R_LARCH_TLS_IE64_LO20:
4593 case R_LARCH_TLS_IE64_HI12:
4594 unresolved_reloc = false;
4596 if (h)
4597 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
4598 else
4599 relocation = sec_addr (got)
4600 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
4602 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
4603 /* Use TLS_GD TLS_DESC and TLS_IE. */
4604 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
4605 relocation += 4 * GOT_ENTRY_SIZE;
4606 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
4607 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
4608 relocation += 2 * GOT_ENTRY_SIZE;
4610 if (r_type == R_LARCH_TLS_IE64_PC_LO20)
4611 RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
4612 else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
4613 RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
4615 break;
4617 case R_LARCH_RELAX:
4618 case R_LARCH_ALIGN:
4619 r = bfd_reloc_continue;
4620 unresolved_reloc = false;
4621 break;
4623 default:
4624 break;
4627 if (fatal)
4628 break;
4632 /* 'unresolved_reloc' means we haven't done it yet.
4633 We need help of dynamic linker to fix this memory location up. */
4634 if (!unresolved_reloc)
4635 break;
4637 if (_bfd_elf_section_offset (output_bfd, info, input_section,
4638 rel->r_offset) == MINUS_ONE)
4639 /* WHY? May because it's invalid so skip checking.
4640 But why dynamic reloc a invalid section? */
4641 break;
4643 if (input_section->output_section->flags & SEC_DEBUGGING)
4645 fatal = (loongarch_reloc_is_fatal
4646 (info, input_bfd, input_section, rel, howto,
4647 bfd_reloc_dangerous, is_undefweak, name,
4648 "Seems dynamic linker not process "
4649 "sections 'SEC_DEBUGGING'."));
4651 if (!is_dyn)
4652 break;
4654 if ((info->flags & DF_TEXTREL) == 0)
4655 if (input_section->output_section->flags & SEC_READONLY)
4656 info->flags |= DF_TEXTREL;
4658 while (0);
4660 if (fatal)
4661 break;
4663 loongarch_record_one_reloc (input_bfd, input_section, r_type,
4664 rel->r_offset, sym, h, rel->r_addend);
4666 if (r != bfd_reloc_continue)
4667 r = perform_relocation (rel, input_section, howto, relocation,
4668 input_bfd, contents);
4670 switch (r)
4672 case bfd_reloc_dangerous:
4673 case bfd_reloc_continue:
4674 case bfd_reloc_ok:
4675 continue;
4677 case bfd_reloc_overflow:
4678 /* Overflow value can't be filled in. */
4679 loongarch_dump_reloc_record (info->callbacks->info);
4680 info->callbacks->reloc_overflow
4681 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
4682 input_bfd, input_section, rel->r_offset);
4683 if (r_type == R_LARCH_PCREL20_S2
4684 || r_type == R_LARCH_TLS_LD_PCREL20_S2
4685 || r_type == R_LARCH_TLS_GD_PCREL20_S2
4686 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
4687 _bfd_error_handler (_("recompile with 'gcc -mno-relax' or"
4688 " 'as -mno-relax' or 'ld --no-relax'"));
4689 break;
4691 case bfd_reloc_outofrange:
4692 /* Stack state incorrect. */
4693 loongarch_dump_reloc_record (info->callbacks->info);
4694 info->callbacks->info
4695 ("%X%H: Internal stack state is incorrect.\n"
4696 "Want to push to full stack or pop from empty stack?\n",
4697 input_bfd, input_section, rel->r_offset);
4698 break;
4700 case bfd_reloc_notsupported:
4701 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
4702 input_section, rel->r_offset);
4703 break;
4705 default:
4706 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
4707 input_section, rel->r_offset);
4708 break;
4711 fatal = true;
4714 return !fatal;
4717 static bool
4718 loongarch_relax_delete_bytes (bfd *abfd,
4719 asection *sec,
4720 bfd_vma addr,
4721 size_t count,
4722 struct bfd_link_info *link_info)
4724 unsigned int i, symcount;
4725 bfd_vma toaddr = sec->size;
4726 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
4727 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4728 unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
4729 struct bfd_elf_section_data *data = elf_section_data (sec);
4730 bfd_byte *contents = data->this_hdr.contents;
4731 struct relr_entry *relr = loongarch_elf_section_data (sec)->relr;
4732 struct loongarch_elf_link_hash_table *htab =
4733 loongarch_elf_hash_table (link_info);
4734 struct relr_entry *relr_end = NULL;
4736 if (htab->relr_count)
4737 relr_end = htab->relr + htab->relr_count;
4739 /* Actually delete the bytes. */
4740 sec->size -= count;
4741 memmove (contents + addr, contents + addr + count, toaddr - addr - count);
4743 /* Adjust the location of all of the relocs. Note that we need not
4744 adjust the addends, since all PC-relative references must be against
4745 symbols, which we will adjust below. */
4746 for (i = 0; i < sec->reloc_count; i++)
4747 if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
4748 data->relocs[i].r_offset -= count;
4750 /* Likewise for relative relocs to be packed into .relr. */
4751 for (; relr && relr < relr_end && relr->sec == sec; relr++)
4752 if (relr->off > addr && relr->off < toaddr)
4753 relr->off -= count;
4755 /* Adjust the local symbols defined in this section. */
4756 for (i = 0; i < symtab_hdr->sh_info; i++)
4758 Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
4759 if (sym->st_shndx == sec_shndx)
4761 /* If the symbol is in the range of memory we just moved, we
4762 have to adjust its value. */
4763 if (sym->st_value > addr && sym->st_value <= toaddr)
4764 sym->st_value -= count;
4766 /* If the symbol *spans* the bytes we just deleted (i.e. its
4767 *end* is in the moved bytes but its *start* isn't), then we
4768 must adjust its size.
4770 This test needs to use the original value of st_value, otherwise
4771 we might accidentally decrease size when deleting bytes right
4772 before the symbol. But since deleted relocs can't span across
4773 symbols, we can't have both a st_value and a st_size decrease,
4774 so it is simpler to just use an else. */
4775 else if (sym->st_value <= addr
4776 && sym->st_value + sym->st_size > addr
4777 && sym->st_value + sym->st_size <= toaddr)
4778 sym->st_size -= count;
4782 /* Now adjust the global symbols defined in this section. */
4783 symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
4784 - symtab_hdr->sh_info);
4786 for (i = 0; i < symcount; i++)
4788 struct elf_link_hash_entry *sym_hash = sym_hashes[i];
4790 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4791 containing the definition of __wrap_SYMBOL, includes a direct
4792 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4793 the same symbol (which is __wrap_SYMBOL), but still exist as two
4794 different symbols in 'sym_hashes', we don't want to adjust
4795 the global symbol __wrap_SYMBOL twice.
4797 The same problem occurs with symbols that are versioned_hidden, as
4798 foo becomes an alias for foo@BAR, and hence they need the same
4799 treatment. */
4800 if (link_info->wrap_hash != NULL
4801 || sym_hash->versioned != unversioned)
4803 struct elf_link_hash_entry **cur_sym_hashes;
4805 /* Loop only over the symbols which have already been checked. */
4806 for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
4807 cur_sym_hashes++)
4809 /* If the current symbol is identical to 'sym_hash', that means
4810 the symbol was already adjusted (or at least checked). */
4811 if (*cur_sym_hashes == sym_hash)
4812 break;
4814 /* Don't adjust the symbol again. */
4815 if (cur_sym_hashes < &sym_hashes[i])
4816 continue;
4819 if ((sym_hash->root.type == bfd_link_hash_defined
4820 || sym_hash->root.type == bfd_link_hash_defweak)
4821 && sym_hash->root.u.def.section == sec)
4823 /* As above, adjust the value if needed. */
4824 if (sym_hash->root.u.def.value > addr
4825 && sym_hash->root.u.def.value <= toaddr)
4826 sym_hash->root.u.def.value -= count;
4828 /* As above, adjust the size if needed. */
4829 else if (sym_hash->root.u.def.value <= addr
4830 && sym_hash->root.u.def.value + sym_hash->size > addr
4831 && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
4832 sym_hash->size -= count;
4836 return true;
4839 /* Start perform TLS type transition.
4840 Currently there are three cases of relocation handled here:
4841 DESC -> IE, DEC -> LE and IE -> LE. */
4842 static bool
4843 loongarch_tls_perform_trans (bfd *abfd, asection *sec,
4844 Elf_Internal_Rela *rel,
4845 struct elf_link_hash_entry *h,
4846 struct bfd_link_info *info)
4848 unsigned long insn;
4849 bool local_exec = bfd_link_executable (info)
4850 && LARCH_REF_LOCAL (info, h);
4851 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4852 unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
4853 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
4855 switch (r_type)
4857 case R_LARCH_TLS_DESC_PC_HI20:
4858 if (local_exec)
4860 /* DESC -> LE relaxation:
4861 pcalalau12i $a0,%desc_pc_hi20(var) =>
4862 lu12i.w $a0,%le_hi20(var)
4864 bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_RD_A0,
4865 contents + rel->r_offset);
4866 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
4868 else
4870 /* DESC -> IE relaxation:
4871 pcalalau12i $a0,%desc_pc_hi20(var) =>
4872 pcalalau12i $a0,%ie_pc_hi20(var)
4874 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_HI20);
4876 return true;
4878 case R_LARCH_TLS_DESC_PC_LO12:
4879 if (local_exec)
4881 /* DESC -> LE relaxation:
4882 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4883 ori $a0,$a0,le_lo12(var)
4885 insn = LARCH_OP_ORI | LARCH_RD_RJ_A0;
4886 bfd_put (32, abfd, LARCH_OP_ORI | LARCH_RD_RJ_A0,
4887 contents + rel->r_offset);
4888 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
4890 else
4892 /* DESC -> IE relaxation:
4893 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4894 ld.d $a0,$a0,%ie_pc_lo12(var)
4896 bfd_put (32, abfd, LARCH_OP_LD_D | LARCH_RD_RJ_A0,
4897 contents + rel->r_offset);
4898 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_LO12);
4900 return true;
4902 case R_LARCH_TLS_DESC_LD:
4903 case R_LARCH_TLS_DESC_CALL:
4904 /* DESC -> LE/IE relaxation:
4905 ld.d $ra,$a0,%desc_ld(var) => NOP
4906 jirl $ra,$ra,%desc_call(var) => NOP
4908 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4909 bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
4910 /* link with -relax option will delete NOP. */
4911 if (!info->disable_target_specific_optimizations)
4912 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4913 return true;
4915 case R_LARCH_TLS_IE_PC_HI20:
4916 if (local_exec)
4918 /* IE -> LE relaxation:
4919 pcalalau12i $rd,%ie_pc_hi20(var) =>
4920 lu12i.w $rd,%le_hi20(var)
4922 insn = bfd_getl32 (contents + rel->r_offset);
4923 bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_GET_RD(insn),
4924 contents + rel->r_offset);
4925 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
4927 return true;
4929 case R_LARCH_TLS_IE_PC_LO12:
4930 if (local_exec)
4932 /* IE -> LE relaxation:
4933 ld.d $rd,$rj,%%ie_pc_lo12(var) =>
4934 ori $rd,$rj,le_lo12(var)
4936 insn = bfd_getl32 (contents + rel->r_offset);
4937 bfd_put (32, abfd, LARCH_OP_ORI | (insn & 0x3ff),
4938 contents + rel->r_offset);
4939 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
4941 return true;
4944 return false;
4948 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4949 there are three situations in which an assembly instruction sequence needs to
4950 be relaxed:
4951 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4953 Case 1:
4954 in this case, the rd register in the st.{w/d} instruction does not store the
4955 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4956 symbolic address, and then obtains the rd + le_lo12_r address through the
4957 st.w instruction feature.
4958 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4960 before relax: after relax:
4962 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4963 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4964 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4966 Case 2:
4967 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4969 before relax: after relax:
4971 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4972 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4973 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4975 Case 3:
4976 in this case,the rs register in addi.{w/d} stores the full address of the tls
4977 symbol (tp + le_hi20_r + le_lo12_r).
4979 before relax: after relax:
4981 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4982 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4983 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4986 For relocation of all old LE instruction sequences, whether it is
4987 a normal code model or an extreme code model, relaxation will be
4988 performed when the relaxation conditions are met.
4990 nomal code model:
4991 lu12i.w $rd,%le_hi20(sym) => (deleted)
4992 ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4994 extreme code model:
4995 lu12i.w $rd,%le_hi20(sym) => (deleted)
4996 ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4997 lu32i.d $rd,%le64_lo20(sym) => (deleted)
4998 lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted)
5000 static bool
5001 loongarch_relax_tls_le (bfd *abfd, asection *sec,
5002 asection *sym_sec ATTRIBUTE_UNUSED,
5003 Elf_Internal_Rela *rel, bfd_vma symval,
5004 struct bfd_link_info *link_info,
5005 bool *agin ATTRIBUTE_UNUSED,
5006 bfd_vma max_alignment ATTRIBUTE_UNUSED)
5008 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
5009 uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
5010 static uint32_t insn_rj,insn_rd;
5011 symval = symval - elf_hash_table (link_info)->tls_sec->vma;
5012 /* The old LE instruction sequence can be relaxed when the symbol offset
5013 is smaller than the 12-bit range. */
5014 if (symval <= 0xfff)
5016 switch (ELFNN_R_TYPE (rel->r_info))
5018 /*if offset < 0x800, then perform the new le instruction
5019 sequence relax. */
5020 case R_LARCH_TLS_LE_HI20_R:
5021 case R_LARCH_TLS_LE_ADD_R:
5022 /* delete insn. */
5023 if (symval < 0x800)
5025 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
5026 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
5027 4, link_info);
5029 break;
5031 case R_LARCH_TLS_LE_LO12_R:
5032 if (symval < 0x800)
5034 /* Change rj to $tp. */
5035 insn_rj = 0x2 << 5;
5036 /* Get rd register. */
5037 insn_rd = LARCH_GET_RD (insn);
5038 /* Write symbol offset. */
5039 symval <<= 10;
5040 /* Writes the modified instruction. */
5041 insn = insn & LARCH_MK_ADDI_D;
5042 insn = insn | symval | insn_rj | insn_rd;
5043 bfd_put (32, abfd, insn, contents + rel->r_offset);
5045 break;
5047 case R_LARCH_TLS_LE_HI20:
5048 case R_LARCH_TLS_LE64_LO20:
5049 case R_LARCH_TLS_LE64_HI12:
5050 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
5051 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
5052 4, link_info);
5053 break;
5055 case R_LARCH_TLS_LE_LO12:
5056 bfd_put (32, abfd, LARCH_OP_ORI | LARCH_GET_RD (insn),
5057 contents + rel->r_offset);
5058 break;
5060 default:
5061 break;
5064 return true;
5067 /* Whether two sections in the same segment. */
5068 static bool
5069 loongarch_two_sections_in_same_segment (bfd *abfd, asection *a, asection *b)
5071 struct elf_segment_map *m;
5072 for (m = elf_seg_map (abfd); m != NULL; m = m->next)
5074 int i;
5075 int j = 0;
5076 for (i = m->count - 1; i >= 0; i--)
5078 if (m->sections[i] == a)
5079 j++;
5080 if (m->sections[i] == b)
5081 j++;
5083 if (1 == j)
5084 return false;
5085 if (2 == j)
5086 return true;
5088 return false;
5091 /* Relax pcalau12i,addi.d => pcaddi. */
5092 static bool
5093 loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
5094 Elf_Internal_Rela *rel_hi, bfd_vma symval,
5095 struct bfd_link_info *info, bool *again,
5096 bfd_vma max_alignment)
5098 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
5099 Elf_Internal_Rela *rel_lo = rel_hi + 2;
5100 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
5101 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
5102 uint32_t rd = LARCH_GET_RD (pca);
5104 /* This section's output_offset need to subtract the bytes of instructions
5105 relaxed by the previous sections, so it needs to be updated beforehand.
5106 size_input_section already took care of updating it after relaxation,
5107 so we additionally update once here. */
5108 sec->output_offset = sec->output_section->size;
5109 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
5111 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5112 if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5113 sec->output_section,
5114 sym_sec->output_section))
5115 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5116 : max_alignment;
5118 if (symval > pc)
5119 pc -= (max_alignment > 4 ? max_alignment : 0);
5120 else if (symval < pc)
5121 pc += (max_alignment > 4 ? max_alignment : 0);
5123 const uint32_t pcaddi = LARCH_OP_PCADDI;
5125 /* Is pcalau12i + addi.d insns? */
5126 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
5127 || !LARCH_INSN_ADDI_D (add)
5128 /* Is pcalau12i $rd + addi.d $rd,$rd? */
5129 || (LARCH_GET_RD (add) != rd)
5130 || (LARCH_GET_RJ (add) != rd)
5131 /* Can be relaxed to pcaddi? */
5132 || (symval & 0x3) /* 4 bytes align. */
5133 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
5134 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
5135 return false;
5137 /* Continue next relax trip. */
5138 *again = true;
5140 pca = pcaddi | rd;
5141 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
5143 /* Adjust relocations. */
5144 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
5145 R_LARCH_PCREL20_S2);
5146 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
5148 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
5150 return true;
5153 /* call36 f -> bl f
5154 tail36 $t0, f -> b f. */
5155 static bool
5156 loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
5157 Elf_Internal_Rela *rel, bfd_vma symval,
5158 struct bfd_link_info *info, bool *again,
5159 bfd_vma max_alignment)
5161 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
5162 uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4);
5163 uint32_t rd = LARCH_GET_RD (jirl);
5165 /* This section's output_offset need to subtract the bytes of instructions
5166 relaxed by the previous sections, so it needs to be updated beforehand.
5167 size_input_section already took care of updating it after relaxation,
5168 so we additionally update once here. */
5169 sec->output_offset = sec->output_section->size;
5170 bfd_vma pc = sec_addr (sec) + rel->r_offset;
5172 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5173 if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5174 sec->output_section,
5175 sym_sec->output_section))
5176 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5177 : max_alignment;
5179 if (symval > pc)
5180 pc -= (max_alignment > 4 ? max_alignment : 0);
5181 else if (symval < pc)
5182 pc += (max_alignment > 4 ? max_alignment : 0);
5184 /* Is pcalau12i + addi.d insns? */
5185 if (!LARCH_INSN_JIRL (jirl)
5186 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000)
5187 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc))
5188 return false;
5190 /* Continue next relax trip. */
5191 *again = true;
5193 const uint32_t bl = LARCH_OP_BL;
5194 const uint32_t b = LARCH_OP_B;
5196 if (rd)
5197 bfd_put (32, abfd, bl, contents + rel->r_offset);
5198 else
5199 bfd_put (32, abfd, b, contents + rel->r_offset);
5201 /* Adjust relocations. */
5202 rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_LARCH_B26);
5203 /* Delete jirl instruction. */
5204 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4, info);
5205 return true;
5208 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
5209 static bool
5210 loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
5211 asection *sym_sec,
5212 Elf_Internal_Rela *rel_hi,
5213 bfd_vma symval,
5214 struct bfd_link_info *info,
5215 bool *again ATTRIBUTE_UNUSED,
5216 bfd_vma max_alignment)
5218 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
5219 Elf_Internal_Rela *rel_lo = rel_hi + 2;
5220 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
5221 uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
5222 uint32_t rd = LARCH_GET_RD (pca);
5223 uint32_t addi_d = LARCH_OP_ADDI_D;
5225 /* This section's output_offset need to subtract the bytes of instructions
5226 relaxed by the previous sections, so it needs to be updated beforehand.
5227 size_input_section already took care of updating it after relaxation,
5228 so we additionally update once here. */
5229 sec->output_offset = sec->output_section->size;
5230 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
5232 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5233 if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5234 sec->output_section,
5235 sym_sec->output_section))
5236 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5237 : max_alignment;
5239 if (symval > pc)
5240 pc -= (max_alignment > 4 ? max_alignment : 0);
5241 else if (symval < pc)
5242 pc += (max_alignment > 4 ? max_alignment : 0);
5244 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
5245 || (LARCH_GET_RD (ld) != rd)
5246 || (LARCH_GET_RJ (ld) != rd)
5247 || !LARCH_INSN_LD_D (ld)
5248 /* Within +-2G addressing range. */
5249 || (bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0x80000000
5250 || (bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffff)
5251 return false;
5253 addi_d = addi_d | (rd << 5) | rd;
5254 bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
5256 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
5257 R_LARCH_PCALA_HI20);
5258 rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
5259 R_LARCH_PCALA_LO12);
5260 return true;
5263 /* Called by after_allocation to set the information of data segment
5264 before relaxing. */
5266 void
5267 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
5268 int *data_segment_phase)
5270 if (is_elf_hash_table (info->hash)
5271 && elf_hash_table_id (elf_hash_table (info)) == LARCH_ELF_DATA)
5272 loongarch_elf_hash_table (info)->data_segment_phase = data_segment_phase;
5275 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
5276 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
5277 static bool
5278 loongarch_relax_align (bfd *abfd, asection *sec, asection *sym_sec,
5279 Elf_Internal_Rela *rel,
5280 bfd_vma symval ATTRIBUTE_UNUSED,
5281 struct bfd_link_info *link_info,
5282 bool *again ATTRIBUTE_UNUSED,
5283 bfd_vma max_alignment ATTRIBUTE_UNUSED)
5285 bfd_vma addend, max = 0, alignment = 1;
5287 int sym_index = ELFNN_R_SYM (rel->r_info);
5288 if (sym_index > 0)
5290 alignment = 1 << (rel->r_addend & 0xff);
5291 max = rel->r_addend >> 8;
5293 else
5294 alignment = rel->r_addend + 4;
5296 addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
5297 symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */
5298 bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
5299 bfd_vma need_nop_bytes = aligned_addr - symval; /* */
5301 /* Make sure there are enough NOPs to actually achieve the alignment. */
5302 if (addend < need_nop_bytes)
5304 _bfd_error_handler
5305 (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
5306 "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
5307 abfd, sym_sec, (uint64_t) rel->r_offset,
5308 (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
5309 bfd_set_error (bfd_error_bad_value);
5310 return false;
5313 /* Once we've handled an R_LARCH_ALIGN in a section,
5314 we can't relax anything else in this section. */
5315 sec->sec_flg0 = true;
5316 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
5318 /* If skipping more bytes than the specified maximum,
5319 then the alignment is not done at all and delete all NOPs. */
5320 if (max > 0 && need_nop_bytes > max)
5321 return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
5322 addend, link_info);
5324 /* If the number of NOPs is already correct, there's nothing to do. */
5325 if (need_nop_bytes == addend)
5326 return true;
5328 /* Delete the excess NOPs. */
5329 return loongarch_relax_delete_bytes (abfd, sec,
5330 rel->r_offset + need_nop_bytes,
5331 addend - need_nop_bytes, link_info);
5334 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
5335 static bool
5336 loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
5337 Elf_Internal_Rela *rel_hi, bfd_vma symval,
5338 struct bfd_link_info *info, bool *again,
5339 bfd_vma max_alignment)
5341 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
5342 Elf_Internal_Rela *rel_lo = rel_hi + 2;
5343 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
5344 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
5345 uint32_t rd = LARCH_GET_RD (pca);
5347 /* This section's output_offset need to subtract the bytes of instructions
5348 relaxed by the previous sections, so it needs to be updated beforehand.
5349 size_input_section already took care of updating it after relaxation,
5350 so we additionally update once here. */
5351 sec->output_offset = sec->output_section->size;
5352 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
5354 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5355 if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5356 sec->output_section,
5357 sym_sec->output_section))
5358 max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5359 : max_alignment;
5361 if (symval > pc)
5362 pc -= (max_alignment > 4 ? max_alignment : 0);
5363 else if (symval < pc)
5364 pc += (max_alignment > 4 ? max_alignment : 0);
5366 const uint32_t pcaddi = LARCH_OP_PCADDI;
5368 /* Is pcalau12i + addi.d insns? */
5369 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
5370 && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
5371 || !LARCH_INSN_ADDI_D (add)
5372 /* Is pcalau12i $rd + addi.d $rd,$rd? */
5373 || (LARCH_GET_RD (add) != rd)
5374 || (LARCH_GET_RJ (add) != rd)
5375 /* Can be relaxed to pcaddi? */
5376 || (symval & 0x3) /* 4 bytes align. */
5377 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
5378 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
5379 return false;
5381 /* Continue next relax trip. */
5382 *again = true;
5384 pca = pcaddi | rd;
5385 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
5387 /* Adjust relocations. */
5388 switch (ELFNN_R_TYPE (rel_hi->r_info))
5390 case R_LARCH_TLS_LD_PC_HI20:
5391 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
5392 R_LARCH_TLS_LD_PCREL20_S2);
5393 break;
5394 case R_LARCH_TLS_GD_PC_HI20:
5395 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
5396 R_LARCH_TLS_GD_PCREL20_S2);
5397 break;
5398 case R_LARCH_TLS_DESC_PC_HI20:
5399 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
5400 R_LARCH_TLS_DESC_PCREL20_S2);
5401 break;
5402 default:
5403 break;
5405 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
5407 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
5409 return true;
5412 /* Traverse all output sections and return the max alignment. */
5414 static bfd_vma
5415 loongarch_get_max_alignment (asection *sec)
5417 asection *o;
5418 unsigned int max_alignment_power = 0;
5420 for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
5421 if (o->alignment_power > max_alignment_power)
5422 max_alignment_power = o->alignment_power;
5424 return (bfd_vma) 1 << max_alignment_power;
5427 typedef bool (*relax_func_t) (bfd *, asection *, asection *,
5428 Elf_Internal_Rela *, bfd_vma,
5429 struct bfd_link_info *, bool *,
5430 bfd_vma);
5432 static bool
5433 loongarch_elf_relax_section (bfd *abfd, asection *sec,
5434 struct bfd_link_info *info,
5435 bool *again)
5437 *again = false;
5439 if (!is_elf_hash_table (info->hash)
5440 || elf_hash_table_id (elf_hash_table (info)) != LARCH_ELF_DATA)
5441 return true;
5443 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
5445 /* It may happen that some sections have updated vma but the others do
5446 not. Go to the next relax trip (size_relative_relocs should have
5447 been demending another relax trip anyway). */
5448 if (htab->layout_mutating_for_relr)
5449 return true;
5451 if (bfd_link_relocatable (info)
5452 || sec->sec_flg0
5453 || sec->reloc_count == 0
5454 || (sec->flags & SEC_RELOC) == 0
5455 || (sec->flags & SEC_HAS_CONTENTS) == 0
5456 /* The exp_seg_relro_adjust is enum phase_enum (0x4). */
5457 || *(htab->data_segment_phase) == 4
5458 || (info->disable_target_specific_optimizations
5459 && info->relax_pass == 0))
5460 return true;
5462 struct bfd_elf_section_data *data = elf_section_data (sec);
5463 Elf_Internal_Rela *relocs;
5464 if (data->relocs)
5465 relocs = data->relocs;
5466 else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
5467 info->keep_memory)))
5468 return true;
5469 data->relocs = relocs;
5471 /* Read this BFD's contents if we haven't done so already. */
5472 if (!data->this_hdr.contents
5473 && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
5474 return true;
5476 /* Read this BFD's symbols if we haven't done so already. */
5477 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
5478 if (symtab_hdr->sh_info != 0
5479 && !symtab_hdr->contents
5480 && !(symtab_hdr->contents =
5481 (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
5482 symtab_hdr->sh_info,
5483 0, NULL, NULL, NULL)))
5484 return true;
5486 /* Estimate the maximum alignment for all output sections once time
5487 should be enough. */
5488 bfd_vma max_alignment = htab->max_alignment;
5489 if (max_alignment == (bfd_vma) -1)
5491 max_alignment = loongarch_get_max_alignment (sec);
5492 htab->max_alignment = max_alignment;
5495 for (unsigned int i = 0; i < sec->reloc_count; i++)
5497 char symtype;
5498 bfd_vma symval;
5499 asection *sym_sec;
5500 bool local_got = false;
5501 Elf_Internal_Rela *rel = relocs + i;
5502 struct elf_link_hash_entry *h = NULL;
5503 unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
5504 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
5506 if (r_symndx >= symtab_hdr->sh_info)
5508 h = elf_sym_hashes (abfd)[r_symndx - symtab_hdr->sh_info];
5509 while (h->root.type == bfd_link_hash_indirect
5510 || h->root.type == bfd_link_hash_warning)
5511 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5514 /* If the conditions for tls type transition are met, type
5515 transition is performed instead of relax.
5516 During the transition from DESC->IE/LE, there are 2 situations
5517 depending on the different configurations of the relax/norelax
5518 option.
5519 If the -relax option is used, the extra nops will be removed,
5520 and this transition is performed in pass 0.
5521 If the --no-relax option is used, nop will be retained, and
5522 this transition is performed in pass 1. */
5523 if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
5524 && (i + 1 != sec->reloc_count)
5525 && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
5526 && rel->r_offset == rel[1].r_offset
5527 && loongarch_can_trans_tls (abfd, info, h, r_symndx, r_type))
5529 loongarch_tls_perform_trans (abfd, sec, rel, h, info);
5530 r_type = ELFNN_R_TYPE (rel->r_info);
5533 relax_func_t relax_func = NULL;
5534 if (info->relax_pass == 0)
5536 switch (r_type)
5538 case R_LARCH_PCALA_HI20:
5539 relax_func = loongarch_relax_pcala_addi;
5540 break;
5541 case R_LARCH_GOT_PC_HI20:
5542 relax_func = loongarch_relax_pcala_ld;
5543 break;
5544 case R_LARCH_CALL36:
5545 relax_func = loongarch_relax_call36;
5546 break;
5547 case R_LARCH_TLS_LE_HI20_R:
5548 case R_LARCH_TLS_LE_LO12_R:
5549 case R_LARCH_TLS_LE_ADD_R:
5550 case R_LARCH_TLS_LE_HI20:
5551 case R_LARCH_TLS_LE_LO12:
5552 case R_LARCH_TLS_LE64_LO20:
5553 case R_LARCH_TLS_LE64_HI12:
5554 relax_func = loongarch_relax_tls_le;
5555 break;
5556 case R_LARCH_TLS_LD_PC_HI20:
5557 case R_LARCH_TLS_GD_PC_HI20:
5558 case R_LARCH_TLS_DESC_PC_HI20:
5559 relax_func = loongarch_relax_tls_ld_gd_desc;
5560 break;
5561 default:
5562 continue;
5565 /* Only relax this reloc if it is paired with R_RISCV_RELAX. */
5566 if (r_type == R_LARCH_TLS_LD_PC_HI20
5567 || r_type == R_LARCH_TLS_GD_PC_HI20
5568 || r_type == R_LARCH_TLS_DESC_PC_HI20
5569 || r_type == R_LARCH_PCALA_HI20
5570 || r_type == R_LARCH_GOT_PC_HI20)
5572 if ((i + 2) == sec->reloc_count - 1
5573 || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX
5574 || ELFNN_R_TYPE ((rel + 3)->r_info) != R_LARCH_RELAX
5575 || rel->r_offset != (rel + 1)->r_offset
5576 || (rel + 2)->r_offset != (rel + 3)->r_offset
5577 || rel->r_offset + 4 != (rel + 2)->r_offset)
5578 continue;
5580 else
5582 if (i == sec->reloc_count - 1
5583 || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX
5584 || rel->r_offset != (rel + 1)->r_offset)
5585 continue;
5588 else if (info->relax_pass == 1 && r_type == R_LARCH_ALIGN)
5589 relax_func = loongarch_relax_align;
5590 else
5591 continue;
5593 /* Four kind of relocations:
5594 Normal: symval is the symbol address.
5595 R_LARCH_ALIGN: symval is the address of the last NOP instruction
5596 added by this relocation, and then adds 4 more.
5597 R_LARCH_CALL36: symval is the symbol address for local symbols,
5598 or the PLT entry address of the symbol. (Todo)
5599 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
5600 of the symbol if transition is not possible. */
5601 if (r_symndx < symtab_hdr->sh_info)
5603 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
5604 + r_symndx;
5606 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
5607 && r_type != R_LARCH_CALL36)
5608 || sym->st_shndx == SHN_ABS)
5609 continue;
5611 /* Only TLS instruction sequences that are accompanied by
5612 R_LARCH_RELAX and cannot perform type transition can be
5613 relaxed. */
5614 if (r_type == R_LARCH_TLS_LD_PC_HI20
5615 || r_type == R_LARCH_TLS_GD_PC_HI20
5616 || r_type == R_LARCH_TLS_DESC_PC_HI20)
5618 sym_sec = htab->elf.sgot;
5619 symval = elf_local_got_offsets (abfd)[r_symndx];
5620 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
5621 r_symndx);
5622 if (r_type == R_LARCH_TLS_DESC_PC_HI20
5623 && GOT_TLS_GD_BOTH_P (tls_type))
5624 symval += 2 * GOT_ENTRY_SIZE;
5626 else if (sym->st_shndx == SHN_UNDEF || r_type == R_LARCH_ALIGN)
5628 sym_sec = sec;
5629 symval = rel->r_offset;
5631 else
5633 sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
5634 symval = sym->st_value;
5636 symtype = ELF_ST_TYPE (sym->st_info);
5638 else
5640 if (h != NULL
5641 && ((h->type == STT_GNU_IFUNC
5642 && r_type != R_LARCH_CALL36)
5643 || bfd_is_abs_section (h->root.u.def.section)))
5644 continue;
5646 /* The GOT entry of tls symbols must in current execute file or
5647 shared object. */
5648 if (r_type == R_LARCH_TLS_LD_PC_HI20
5649 || r_type == R_LARCH_TLS_GD_PC_HI20
5650 || r_type == R_LARCH_TLS_DESC_PC_HI20)
5652 sym_sec = htab->elf.sgot;
5653 symval = h->got.offset;
5654 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
5655 r_symndx);
5656 if (r_type == R_LARCH_TLS_DESC_PC_HI20
5657 && GOT_TLS_GD_BOTH_P (tls_type))
5658 symval += 2 * GOT_ENTRY_SIZE;
5660 else if (h->plt.offset != MINUS_ONE)
5662 sym_sec = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
5663 symval = h->plt.offset;
5665 /* Like loongarch_elf_relocate_section, set relocation(offset) to 0.
5666 Undefweak for other relocations handing in the future. */
5667 else if (h->root.type == bfd_link_hash_undefweak
5668 && !h->root.linker_def
5669 && r_type == R_LARCH_CALL36)
5671 sym_sec = sec;
5672 symval = rel->r_offset;
5674 else if ((h->root.type == bfd_link_hash_defined
5675 || h->root.type == bfd_link_hash_defweak)
5676 && h->root.u.def.section != NULL
5677 && h->root.u.def.section->output_section != NULL)
5679 sym_sec = h->root.u.def.section;
5680 symval = h->root.u.def.value;
5682 else
5683 continue;
5685 if (h && LARCH_REF_LOCAL (info, h))
5686 local_got = true;
5687 symtype = h->type;
5690 if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
5691 && (sym_sec->flags & SEC_MERGE))
5693 if (symtype == STT_SECTION)
5694 symval += rel->r_addend;
5696 symval = _bfd_merged_section_offset (abfd, &sym_sec,
5697 elf_section_data (sym_sec)->sec_info,
5698 symval);
5700 if (symtype != STT_SECTION)
5701 symval += rel->r_addend;
5703 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
5704 + (alingmeng - 4).
5705 If r_symndx is 0, alignmeng-4 is r_addend.
5706 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
5707 else if (r_type == R_LARCH_ALIGN)
5708 if (r_symndx > 0)
5709 symval += ((1 << (rel->r_addend & 0xff)) - 4);
5710 else
5711 symval += rel->r_addend;
5712 else
5713 symval += rel->r_addend;
5715 symval += sec_addr (sym_sec);
5717 if (r_type == R_LARCH_GOT_PC_HI20 && !local_got)
5718 continue;
5720 if (relax_func (abfd, sec, sym_sec, rel, symval,
5721 info, again, max_alignment)
5722 && relax_func == loongarch_relax_pcala_ld)
5723 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
5724 info, again, max_alignment);
5727 return true;
5730 /* Finish up dynamic symbol handling. We set the contents of various
5731 dynamic sections here. */
5733 static bool
5734 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
5735 struct bfd_link_info *info,
5736 struct elf_link_hash_entry *h,
5737 Elf_Internal_Sym *sym)
5739 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
5740 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
5742 if (h->plt.offset != MINUS_ONE)
5744 size_t i, plt_idx;
5745 asection *plt, *gotplt, *relplt;
5746 bfd_vma got_address;
5747 uint32_t plt_entry[PLT_ENTRY_INSNS];
5748 bfd_byte *loc;
5749 Elf_Internal_Rela rela;
5751 if (htab->elf.splt)
5753 BFD_ASSERT ((h->type == STT_GNU_IFUNC
5754 && LARCH_REF_LOCAL (info, h))
5755 || h->dynindx != -1);
5757 plt = htab->elf.splt;
5758 gotplt = htab->elf.sgotplt;
5759 if (h->type == STT_GNU_IFUNC && LARCH_REF_LOCAL (info, h))
5760 relplt = htab->elf.srelgot;
5761 else
5762 relplt = htab->elf.srelplt;
5763 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
5764 got_address =
5765 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
5767 else /* if (htab->elf.iplt) */
5769 BFD_ASSERT (h->type == STT_GNU_IFUNC
5770 && LARCH_REF_LOCAL (info, h));
5772 plt = htab->elf.iplt;
5773 gotplt = htab->elf.igotplt;
5774 relplt = htab->elf.irelplt;
5775 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
5776 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
5779 /* Find out where the .plt entry should go. */
5780 loc = plt->contents + h->plt.offset;
5782 /* Fill in the PLT entry itself. */
5783 if (!loongarch_make_plt_entry (got_address,
5784 sec_addr (plt) + h->plt.offset,
5785 plt_entry))
5786 return false;
5788 for (i = 0; i < PLT_ENTRY_INSNS; i++)
5789 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
5791 /* Fill in the initial value of the got.plt entry. */
5792 loc = gotplt->contents + (got_address - sec_addr (gotplt));
5793 bfd_put_NN (output_bfd, sec_addr (plt), loc);
5795 rela.r_offset = got_address;
5797 /* TRUE if this is a PLT reference to a local IFUNC. */
5798 if (PLT_LOCAL_IFUNC_P (info, h)
5799 && (relplt == htab->elf.srelgot
5800 || relplt == htab->elf.irelplt))
5802 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
5803 rela.r_addend = (h->root.u.def.value
5804 + h->root.u.def.section->output_section->vma
5805 + h->root.u.def.section->output_offset);
5807 loongarch_elf_append_rela (output_bfd, relplt, &rela);
5809 else
5811 /* Fill in the entry in the rela.plt section. */
5812 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
5813 rela.r_addend = 0;
5814 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
5815 bed->s->swap_reloca_out (output_bfd, &rela, loc);
5818 if (!h->def_regular)
5820 /* Mark the symbol as undefined, rather than as defined in
5821 the .plt section. Leave the value alone. */
5822 sym->st_shndx = SHN_UNDEF;
5823 /* If the symbol is weak, we do need to clear the value.
5824 Otherwise, the PLT entry would provide a definition for
5825 the symbol even if the symbol wasn't defined anywhere,
5826 and so the symbol would never be NULL. */
5827 if (!h->ref_regular_nonweak)
5828 sym->st_value = 0;
5832 if (h->got.offset != MINUS_ONE
5833 /* TLS got entry have been handled in elf_relocate_section. */
5834 && !(loongarch_elf_hash_entry (h)->tls_type
5835 & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
5836 /* Have allocated got entry but not allocated rela before. */
5837 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
5839 asection *sgot, *srela;
5840 Elf_Internal_Rela rela;
5841 bfd_vma off = h->got.offset & ~(bfd_vma)1;
5843 /* This symbol has an entry in the GOT. Set it up. */
5844 sgot = htab->elf.sgot;
5845 srela = htab->elf.srelgot;
5846 BFD_ASSERT (sgot && srela);
5848 rela.r_offset = sec_addr (sgot) + off;
5850 if (h->def_regular
5851 && h->type == STT_GNU_IFUNC)
5853 if(h->plt.offset == MINUS_ONE)
5855 if (htab->elf.splt == NULL)
5856 srela = htab->elf.irelplt;
5858 if (LARCH_REF_LOCAL (info, h))
5860 asection *sec = h->root.u.def.section;
5861 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
5862 rela.r_addend = h->root.u.def.value + sec->output_section->vma
5863 + sec->output_offset;
5864 bfd_put_NN (output_bfd, 0, sgot->contents + off);
5866 else
5868 BFD_ASSERT (h->dynindx != -1);
5869 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
5870 rela.r_addend = 0;
5871 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
5874 else if(bfd_link_pic (info))
5876 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
5877 rela.r_addend = 0;
5878 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
5880 else
5882 asection *plt;
5883 /* For non-shared object, we can't use .got.plt, which
5884 contains the real function address if we need pointer
5885 equality. We load the GOT entry with the PLT entry. */
5886 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
5887 bfd_put_NN (output_bfd,
5888 (plt->output_section->vma
5889 + plt->output_offset
5890 + h->plt.offset),
5891 sgot->contents + off);
5892 return true;
5895 else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h))
5897 asection *sec = h->root.u.def.section;
5898 bfd_vma linkaddr = h->root.u.def.value + sec->output_section->vma
5899 + sec->output_offset;
5901 /* Don't emit relative relocs if they are packed, but we need
5902 to write the addend (link-time addr) into the GOT then. */
5903 if (info->enable_dt_relr)
5905 bfd_put_NN (output_bfd, linkaddr, sgot->contents + off);
5906 goto skip_got_reloc;
5908 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
5909 rela.r_addend = linkaddr;
5911 else
5913 BFD_ASSERT (h->dynindx != -1);
5914 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
5915 rela.r_addend = 0;
5918 loongarch_elf_append_rela (output_bfd, srela, &rela);
5920 skip_got_reloc:
5922 /* Mark some specially defined symbols as absolute. */
5923 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
5924 sym->st_shndx = SHN_ABS;
5926 return true;
5929 /* Finish up the dynamic sections. */
5931 static bool
5932 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
5933 asection *sdyn)
5935 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
5936 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
5937 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
5938 bfd_byte *dyncon, *dynconend;
5940 dynconend = sdyn->contents + sdyn->size;
5941 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
5943 Elf_Internal_Dyn dyn;
5944 asection *s;
5945 int skipped = 0;
5947 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
5949 switch (dyn.d_tag)
5951 case DT_PLTGOT:
5952 s = htab->elf.sgotplt;
5953 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
5954 break;
5955 case DT_JMPREL:
5956 s = htab->elf.srelplt;
5957 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
5958 break;
5959 case DT_PLTRELSZ:
5960 s = htab->elf.srelplt;
5961 dyn.d_un.d_val = s->size;
5962 break;
5963 case DT_TEXTREL:
5964 if ((info->flags & DF_TEXTREL) == 0)
5965 skipped = 1;
5966 break;
5967 case DT_FLAGS:
5968 if ((info->flags & DF_TEXTREL) == 0)
5969 dyn.d_un.d_val &= ~DF_TEXTREL;
5970 break;
5972 if (skipped)
5973 skipped_size += dynsize;
5974 else
5975 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
5977 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
5978 memset (dyncon - skipped_size, 0, skipped_size);
5979 return true;
5982 /* Finish up local dynamic symbol handling. We set the contents of
5983 various dynamic sections here. */
5985 static int
5986 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
5988 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
5989 struct bfd_link_info *info = (struct bfd_link_info *) inf;
5991 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
5994 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
5995 this function is called before elf_link_sort_relocs.
5996 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
5997 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
5999 static bool
6000 elf_loongarch_output_arch_local_syms
6001 (bfd *output_bfd ATTRIBUTE_UNUSED,
6002 struct bfd_link_info *info,
6003 void *flaginfo ATTRIBUTE_UNUSED,
6004 int (*func) (void *, const char *,
6005 Elf_Internal_Sym *,
6006 asection *,
6007 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
6009 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
6010 if (htab == NULL)
6011 return false;
6013 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
6014 htab_traverse (htab->loc_hash_table,
6015 elfNN_loongarch_finish_local_dynamic_symbol,
6016 info);
6018 return true;
6021 static bool
6022 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
6023 struct bfd_link_info *info)
6025 bfd *dynobj;
6026 asection *sdyn, *plt, *gotplt = NULL;
6027 struct loongarch_elf_link_hash_table *htab;
6029 htab = loongarch_elf_hash_table (info);
6030 BFD_ASSERT (htab);
6031 dynobj = htab->elf.dynobj;
6032 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
6034 if (elf_hash_table (info)->dynamic_sections_created)
6036 BFD_ASSERT (htab->elf.splt && sdyn);
6038 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
6039 return false;
6042 plt = htab->elf.splt;
6043 gotplt = htab->elf.sgotplt;
6045 if (plt && 0 < plt->size)
6047 size_t i;
6048 uint32_t plt_header[PLT_HEADER_INSNS];
6049 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
6050 plt_header))
6051 return false;
6053 for (i = 0; i < PLT_HEADER_INSNS; i++)
6054 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
6056 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
6057 PLT_ENTRY_SIZE;
6060 if (htab->elf.sgotplt)
6062 asection *output_section = htab->elf.sgotplt->output_section;
6064 if (bfd_is_abs_section (output_section))
6066 _bfd_error_handler (_("discarded output section: `%pA'"),
6067 htab->elf.sgotplt);
6068 return false;
6071 if (0 < htab->elf.sgotplt->size)
6073 /* Write the first two entries in .got.plt, needed for the dynamic
6074 linker. */
6075 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
6077 bfd_put_NN (output_bfd, (bfd_vma) 0,
6078 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
6081 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
6084 if (htab->elf.sgot)
6086 asection *output_section = htab->elf.sgot->output_section;
6088 if (0 < htab->elf.sgot->size)
6090 /* Set the first entry in the global offset table to the address of
6091 the dynamic section. */
6092 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
6093 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
6096 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
6099 return true;
6102 /* Return address for Ith PLT stub in section PLT, for relocation REL
6103 or (bfd_vma) -1 if it should not be included. */
6105 static bfd_vma
6106 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
6107 const arelent *rel ATTRIBUTE_UNUSED)
6109 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
6112 static enum elf_reloc_type_class
6113 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
6114 const asection *rel_sec ATTRIBUTE_UNUSED,
6115 const Elf_Internal_Rela *rela)
6117 struct loongarch_elf_link_hash_table *htab;
6118 htab = loongarch_elf_hash_table (info);
6120 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
6122 /* Check relocation against STT_GNU_IFUNC symbol if there are
6123 dynamic symbols. */
6124 bfd *abfd = info->output_bfd;
6125 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
6126 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
6127 if (r_symndx != STN_UNDEF)
6129 Elf_Internal_Sym sym;
6130 if (!bed->s->swap_symbol_in (abfd,
6131 htab->elf.dynsym->contents
6132 + r_symndx * bed->s->sizeof_sym,
6133 0, &sym))
6135 /* xgettext:c-format */
6136 _bfd_error_handler (_("%pB symbol number %lu references"
6137 " nonexistent SHT_SYMTAB_SHNDX section"),
6138 abfd, r_symndx);
6139 /* Ideally an error class should be returned here. */
6141 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
6142 return reloc_class_ifunc;
6146 switch (ELFNN_R_TYPE (rela->r_info))
6148 case R_LARCH_IRELATIVE:
6149 return reloc_class_ifunc;
6150 case R_LARCH_RELATIVE:
6151 return reloc_class_relative;
6152 case R_LARCH_JUMP_SLOT:
6153 return reloc_class_plt;
6154 case R_LARCH_COPY:
6155 return reloc_class_copy;
6156 default:
6157 return reloc_class_normal;
6161 /* Copy the extra info we tack onto an elf_link_hash_entry. */
6163 static void
6164 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
6165 struct elf_link_hash_entry *dir,
6166 struct elf_link_hash_entry *ind)
6168 struct elf_link_hash_entry *edir, *eind;
6170 edir = dir;
6171 eind = ind;
6173 if (eind->dyn_relocs != NULL)
6175 if (edir->dyn_relocs != NULL)
6177 struct elf_dyn_relocs **pp;
6178 struct elf_dyn_relocs *p;
6180 /* Add reloc counts against the indirect sym to the direct sym
6181 list. Merge any entries against the same section. */
6182 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
6184 struct elf_dyn_relocs *q;
6186 for (q = edir->dyn_relocs; q != NULL; q = q->next)
6187 if (q->sec == p->sec)
6189 q->pc_count += p->pc_count;
6190 q->count += p->count;
6191 *pp = p->next;
6192 break;
6194 if (q == NULL)
6195 pp = &p->next;
6197 *pp = edir->dyn_relocs;
6200 edir->dyn_relocs = eind->dyn_relocs;
6201 eind->dyn_relocs = NULL;
6204 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
6206 loongarch_elf_hash_entry(edir)->tls_type
6207 = loongarch_elf_hash_entry(eind)->tls_type;
6208 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
6210 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
6213 #define PRSTATUS_SIZE 0x1d8
6214 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
6215 #define PRSTATUS_OFFSET_PR_PID 0x20
6216 #define ELF_GREGSET_T_SIZE 0x168
6217 #define PRSTATUS_OFFSET_PR_REG 0x70
6219 /* Support for core dump NOTE sections. */
6221 static bool
6222 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
6224 switch (note->descsz)
6226 default:
6227 return false;
6229 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
6230 case PRSTATUS_SIZE:
6231 /* pr_cursig */
6232 elf_tdata (abfd)->core->signal =
6233 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
6235 /* pr_pid */
6236 elf_tdata (abfd)->core->lwpid =
6237 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
6238 break;
6241 /* Make a ".reg/999" section. */
6242 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
6243 note->descpos
6244 + PRSTATUS_OFFSET_PR_REG);
6247 #define PRPSINFO_SIZE 0x88
6248 #define PRPSINFO_OFFSET_PR_PID 0x18
6249 #define PRPSINFO_OFFSET_PR_FNAME 0x28
6250 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
6251 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
6252 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
6254 static bool
6255 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
6257 switch (note->descsz)
6259 default:
6260 return false;
6262 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
6263 case PRPSINFO_SIZE:
6264 /* pr_pid */
6265 elf_tdata (abfd)->core->pid =
6266 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
6268 /* pr_fname */
6269 elf_tdata (abfd)->core->program =
6270 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
6271 PRPSINFO_SIZEOF_PR_FNAME);
6273 /* pr_psargs */
6274 elf_tdata (abfd)->core->command =
6275 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
6276 PRPSINFO_SIZEOF_PR_PS_ARGS);
6277 break;
6280 /* Note that for some reason, a spurious space is tacked
6281 onto the end of the args in some (at least one anyway)
6282 implementations, so strip it off if it exists. */
6285 char *command = elf_tdata (abfd)->core->command;
6286 int n = strlen (command);
6288 if (0 < n && command[n - 1] == ' ')
6289 command[n - 1] = '\0';
6292 return true;
6295 /* Set the right mach type. */
6296 static bool
6297 loongarch_elf_object_p (bfd *abfd)
6299 /* There are only two mach types in LoongArch currently. */
6300 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
6301 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
6302 else
6303 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
6304 return true;
6307 static asection *
6308 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
6309 Elf_Internal_Rela *rel,
6310 struct elf_link_hash_entry *h,
6311 Elf_Internal_Sym *sym)
6313 if (h != NULL)
6314 switch (ELFNN_R_TYPE (rel->r_info))
6316 case R_LARCH_GNU_VTINHERIT:
6317 case R_LARCH_GNU_VTENTRY:
6318 return NULL;
6321 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
6324 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
6325 executable PLT slots where the executable never takes the address of those
6326 functions, the function symbols are not added to the hash table. */
6328 static bool
6329 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
6331 if (h->plt.offset != (bfd_vma) -1
6332 && !h->def_regular
6333 && !h->pointer_equality_needed)
6334 return false;
6336 return _bfd_elf_hash_symbol (h);
6339 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
6340 #define TARGET_LITTLE_NAME "elfNN-loongarch"
6341 #define ELF_ARCH bfd_arch_loongarch
6342 #define ELF_TARGET_ID LARCH_ELF_DATA
6343 #define ELF_MACHINE_CODE EM_LOONGARCH
6344 #define ELF_MINPAGESIZE 0x1000
6345 #define ELF_MAXPAGESIZE 0x10000
6346 #define ELF_COMMONPAGESIZE 0x4000
6347 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
6348 #define bfd_elfNN_bfd_link_hash_table_create \
6349 loongarch_elf_link_hash_table_create
6350 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
6351 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
6352 #define elf_info_to_howto loongarch_info_to_howto_rela
6353 #define bfd_elfNN_mkobject \
6354 elfNN_loongarch_object
6355 #define bfd_elfNN_bfd_merge_private_bfd_data \
6356 elfNN_loongarch_merge_private_bfd_data
6358 #define elf_backend_reloc_type_class loongarch_reloc_type_class
6359 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
6360 #define elf_backend_create_dynamic_sections \
6361 loongarch_elf_create_dynamic_sections
6362 #define elf_backend_check_relocs loongarch_elf_check_relocs
6363 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
6364 #define elf_backend_late_size_sections loongarch_elf_late_size_sections
6365 #define elf_backend_relocate_section loongarch_elf_relocate_section
6366 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
6367 #define elf_backend_output_arch_local_syms \
6368 elf_loongarch_output_arch_local_syms
6369 #define elf_backend_finish_dynamic_sections \
6370 loongarch_elf_finish_dynamic_sections
6371 #define elf_backend_object_p loongarch_elf_object_p
6372 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
6373 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
6374 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
6375 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
6376 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
6377 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
6378 #define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs
6379 #define elf_backend_finish_relative_relocs \
6380 loongarch_elf_finish_relative_relocs
6381 #define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook
6383 #define elf_backend_dtrel_excludes_plt 1
6385 #include "elfNN-target.h"