]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elfnn-loongarch.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / bfd / elfnn-loongarch.c
CommitLineData
e214f8db 1/* LoongArch-specific support for NN-bit ELF.
fd67aa11 2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
e214f8db 3 Contributed by Loongson Ltd.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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/>. */
20
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"
1b6fccd2 30#include "opcode/loongarch.h"
e214f8db 31
32static bool
33loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
34 Elf_Internal_Rela *dst)
35{
36 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
37 ELFNN_R_TYPE (dst->r_info));
38 return cache_ptr->howto != NULL;
39}
40
41/* LoongArch ELF linker hash entry. */
42struct loongarch_elf_link_hash_entry
43{
44 struct elf_link_hash_entry elf;
45
e214f8db 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
4f248d61
LC
51#define GOT_TLS_GDESC 16
52
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))
e214f8db 57 char tls_type;
58};
59
60#define loongarch_elf_hash_entry(ent) \
61 ((struct loongarch_elf_link_hash_entry *) (ent))
62
63struct _bfd_loongarch_elf_obj_tdata
64{
65 struct elf_obj_tdata root;
66
67 /* The tls_type for each local got entry. */
68 char *local_got_tls_type;
69};
70
71#define _bfd_loongarch_elf_tdata(abfd) \
72 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
73
74#define _bfd_loongarch_elf_local_got_tls_type(abfd) \
75 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
76
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]))
81
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)
86
87struct loongarch_elf_link_hash_table
88{
89 struct elf_link_hash_table elf;
90
91 /* Short-cuts to get to dynamic linker sections. */
92 asection *sdyntdata;
93
94 /* Small local sym to section mapping cache. */
95 struct sym_cache sym_cache;
96
97 /* Used by local STT_GNU_IFUNC symbols. */
98 htab_t loc_hash_table;
99 void *loc_hash_memory;
100
101 /* The max alignment of output sections. */
102 bfd_vma max_alignment;
1b6fccd2 103
104 /* The data segment phase, don't relax the section
105 when it is exp_seg_relro_adjust. */
106 int *data_segment_phase;
e214f8db 107};
108
109/* Get the LoongArch ELF linker hash table from a link_info structure. */
110#define loongarch_elf_hash_table(p) \
111 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
112 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
113 : NULL)
114
115#define MINUS_ONE ((bfd_vma) 0 - 1)
116
117#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
118
119#define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
120#define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
121
122#define PLT_HEADER_INSNS 8
123#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
124
125#define PLT_ENTRY_INSNS 4
126#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
127
128#define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
129
130#define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
131
132#define elf_backend_want_got_plt 1
133
134#define elf_backend_plt_readonly 1
135
6d13722a 136#define elf_backend_want_plt_sym 1
e214f8db 137#define elf_backend_plt_alignment 4
138#define elf_backend_can_gc_sections 1
6d13722a 139#define elf_backend_can_refcount 1
e214f8db 140#define elf_backend_want_got_sym 1
141
142#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
143
144#define elf_backend_want_dynrelro 1
6d13722a 145#define elf_backend_rela_normal 1
48ca1b26 146#define elf_backend_default_execstack 0
e214f8db 147
3898e04b
LC
148#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE) \
149 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
150 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
151 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
152 || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
153
154#define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
155 ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
156 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
157
e214f8db 158/* Generate a PLT header. */
159
160static bool
161loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
162 uint32_t *entry)
163{
164 bfd_vma pcrel = got_plt_addr - plt_header_addr;
165 bfd_vma hi, lo;
166
167 if (pcrel + 0x80000800 > 0xffffffff)
168 {
169 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
170 bfd_set_error (bfd_error_bad_value);
171 return false;
172 }
173 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
174 lo = pcrel & 0xfff;
175
176 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
177 sub.[wd] $t1, $t1, $t3
178 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
179 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
180 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
181 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
182 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
183 jirl $r0, $t3, 0 */
184
185 if (GOT_ENTRY_SIZE == 8)
186 {
187 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
188 entry[1] = 0x0011bdad;
189 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
190 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
191 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
192 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
193 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
194 entry[7] = 0x4c0001e0;
195 }
196 else
197 {
198 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
199 entry[1] = 0x00113dad;
200 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
201 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
202 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
203 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
204 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
205 entry[7] = 0x4c0001e0;
206 }
207 return true;
208}
209
210/* Generate a PLT entry. */
211
212static bool
213loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
214 uint32_t *entry)
215{
216 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
217 bfd_vma hi, lo;
218
219 if (pcrel + 0x80000800 > 0xffffffff)
220 {
221 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
222 bfd_set_error (bfd_error_bad_value);
223 return false;
224 }
225 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
226 lo = pcrel & 0xfff;
227
228 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
229 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
230 | (lo & 0xfff) << 10);
231 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
232 entry[3] = 0x03400000; /* nop */
233
234 return true;
235}
236
237/* Create an entry in an LoongArch ELF linker hash table. */
238
239static struct bfd_hash_entry *
240link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
241 const char *string)
242{
243 struct loongarch_elf_link_hash_entry *eh;
244
245 /* Allocate the structure if it has not already been allocated by a
246 subclass. */
247 if (entry == NULL)
248 {
249 entry = bfd_hash_allocate (table, sizeof (*eh));
250 if (entry == NULL)
251 return entry;
252 }
253
254 /* Call the allocation method of the superclass. */
255 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
256 if (entry != NULL)
257 {
258 eh = (struct loongarch_elf_link_hash_entry *) entry;
e214f8db 259 eh->tls_type = GOT_UNKNOWN;
260 }
261
262 return entry;
263}
264
265/* Compute a hash of a local hash entry. We use elf_link_hash_entry
266 for local symbol so that we can handle local STT_GNU_IFUNC symbols
267 as global symbol. We reuse indx and dynstr_index for local symbol
268 hash since they aren't used by global symbols in this backend. */
269
270static hashval_t
271elfNN_loongarch_local_htab_hash (const void *ptr)
272{
273 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
274 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
275}
276
277/* Compare local hash entries. */
278
279static int
280elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
281{
282 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
283 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
284
285 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
286}
287
288/* Find and/or create a hash entry for local symbol. */
289static struct elf_link_hash_entry *
290elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
291 bfd *abfd, const Elf_Internal_Rela *rel,
292 bool create)
293{
294 struct loongarch_elf_link_hash_entry e, *ret;
295 asection *sec = abfd->sections;
296 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
297 void **slot;
298
299 e.elf.indx = sec->id;
300 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
301 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
302 create ? INSERT : NO_INSERT);
303
304 if (!slot)
305 return NULL;
306
307 if (*slot)
308 {
309 ret = (struct loongarch_elf_link_hash_entry *) *slot;
310 return &ret->elf;
311 }
312
313 ret = ((struct loongarch_elf_link_hash_entry *)
314 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
315 sizeof (struct loongarch_elf_link_hash_entry)));
316 if (ret)
317 {
318 memset (ret, 0, sizeof (*ret));
319 ret->elf.indx = sec->id;
320 ret->elf.pointer_equality_needed = 0;
321 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
322 ret->elf.dynindx = -1;
323 ret->elf.needs_plt = 0;
324 ret->elf.plt.refcount = -1;
325 ret->elf.got.refcount = -1;
326 ret->elf.def_dynamic = 0;
327 ret->elf.def_regular = 1;
328 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
329 ret->elf.ref_regular = 0;
330 ret->elf.forced_local = 1;
331 ret->elf.root.type = bfd_link_hash_defined;
332 *slot = ret;
333 }
334 return &ret->elf;
335}
336
337/* Destroy an LoongArch elf linker hash table. */
338
339static void
340elfNN_loongarch_link_hash_table_free (bfd *obfd)
341{
342 struct loongarch_elf_link_hash_table *ret;
343 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
344
345 if (ret->loc_hash_table)
346 htab_delete (ret->loc_hash_table);
347 if (ret->loc_hash_memory)
348 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
349
350 _bfd_elf_link_hash_table_free (obfd);
351}
352
353/* Create a LoongArch ELF linker hash table. */
354
355static struct bfd_link_hash_table *
356loongarch_elf_link_hash_table_create (bfd *abfd)
357{
358 struct loongarch_elf_link_hash_table *ret;
359 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
360
361 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
362 if (ret == NULL)
363 return NULL;
364
365 if (!_bfd_elf_link_hash_table_init
366 (&ret->elf, abfd, link_hash_newfunc,
367 sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
368 {
369 free (ret);
370 return NULL;
371 }
372
373 ret->max_alignment = MINUS_ONE;
374
375 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
376 elfNN_loongarch_local_htab_eq, NULL);
377 ret->loc_hash_memory = objalloc_create ();
378 if (!ret->loc_hash_table || !ret->loc_hash_memory)
379 {
380 elfNN_loongarch_link_hash_table_free (abfd);
381 return NULL;
382 }
383 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
384
385 return &ret->elf.root;
386}
387
388/* Merge backend specific data from an object file to the output
389 object file when linking. */
390
391static bool
392elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
393{
394 bfd *obfd = info->output_bfd;
395 flagword in_flags = elf_elfheader (ibfd)->e_flags;
396 flagword out_flags = elf_elfheader (obfd)->e_flags;
397
398 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
399 return true;
400
401 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
402 {
403 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
404 "the selected emulation:\n"
405 " target emulation `%s' does not match `%s'"),
406 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
407 return false;
408 }
409
410 if (!_bfd_elf_merge_object_attributes (ibfd, info))
411 return false;
412
83c5f3ae
XR
413 /* If the input BFD is not a dynamic object and it does not contain any
414 non-data sections, do not account its ABI. For example, various
415 packages produces such data-only relocatable objects with
416 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
417 But they are compatible with all ABIs. */
418 if (!(ibfd->flags & DYNAMIC))
419 {
420 asection *sec;
421 bool have_code_sections = false;
422 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
423 if ((bfd_section_flags (sec)
424 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
425 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
426 {
427 have_code_sections = true;
428 break;
429 }
430 if (!have_code_sections)
431 return true;
432 }
433
e214f8db 434 if (!elf_flags_init (obfd))
435 {
436 elf_flags_init (obfd) = true;
437 elf_elfheader (obfd)->e_flags = in_flags;
438 return true;
439 }
c4a7e6b5 440 else if (out_flags != in_flags)
441 {
442 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
443 && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
444 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
445 && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
446 {
447 elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
448 out_flags = elf_elfheader (obfd)->e_flags;
449 in_flags = out_flags;
450 }
451 }
e214f8db 452
453 /* Disallow linking different ABIs. */
c4a7e6b5 454 /* Only check relocation version.
455 The obj_v0 is compatible with obj_v1. */
3b14682a 456 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
e214f8db 457 {
458 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
459 goto fail;
460 }
461
462 return true;
463
464 fail:
465 bfd_set_error (bfd_error_bad_value);
466 return false;
467}
468
469/* Create the .got section. */
470
471static bool
472loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
473{
474 flagword flags;
475 char *name;
476 asection *s, *s_got;
477 struct elf_link_hash_entry *h;
478 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
479 struct elf_link_hash_table *htab = elf_hash_table (info);
480
481 /* This function may be called more than once. */
482 if (htab->sgot != NULL)
483 return true;
484
485 flags = bed->dynamic_sec_flags;
486 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
487 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
488
489 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
490 return false;
491 htab->srelgot = s;
492
493 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
494 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
495 return false;
496 htab->sgot = s;
497
498 /* The first bit of the global offset table is the header. */
499 s->size += bed->got_header_size;
500
501 if (bed->want_got_plt)
502 {
503 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
504 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
505 return false;
506 htab->sgotplt = s;
507
508 /* Reserve room for the header. */
509 s->size = GOTPLT_HEADER_SIZE;
510 }
511
512 if (bed->want_got_sym)
513 {
514 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
515 section. We don't do this in the linker script because we don't want
516 to define the symbol if we are not creating a global offset table. */
517 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
518 "_GLOBAL_OFFSET_TABLE_");
519 elf_hash_table (info)->hgot = h;
520 if (h == NULL)
521 return false;
522 }
523 return true;
524}
525
526/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
527 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
528 hash table. */
529
530static bool
531loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
532{
533 struct loongarch_elf_link_hash_table *htab;
534
535 htab = loongarch_elf_hash_table (info);
536 BFD_ASSERT (htab != NULL);
537
538 if (!loongarch_elf_create_got_section (dynobj, info))
539 return false;
540
541 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
542 return false;
543
544 if (!bfd_link_pic (info))
545 htab->sdyntdata
546 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
547 SEC_ALLOC | SEC_THREAD_LOCAL);
548
549 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
550 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
551 abort ();
552
553 return true;
554}
555
556static bool
557loongarch_elf_record_tls_and_got_reference (bfd *abfd,
558 struct bfd_link_info *info,
559 struct elf_link_hash_entry *h,
560 unsigned long symndx,
561 char tls_type)
562{
563 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
564 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
565
566 /* This is a global offset table entry for a local symbol. */
567 if (elf_local_got_refcounts (abfd) == NULL)
568 {
569 bfd_size_type size =
570 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
571 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
572 return false;
573 _bfd_loongarch_elf_local_got_tls_type (abfd) =
574 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
575 }
576
577 switch (tls_type)
578 {
579 case GOT_NORMAL:
580 case GOT_TLS_GD:
581 case GOT_TLS_IE:
4f248d61 582 case GOT_TLS_GDESC:
e214f8db 583 /* Need GOT. */
584 if (htab->elf.sgot == NULL
585 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
586 return false;
587 if (h)
588 {
589 if (h->got.refcount < 0)
590 h->got.refcount = 0;
591 h->got.refcount++;
592 }
593 else
594 elf_local_got_refcounts (abfd)[symndx]++;
595 break;
596 case GOT_TLS_LE:
597 /* No need for GOT. */
598 break;
599 default:
600 _bfd_error_handler (_("Internal error: unreachable."));
601 return false;
602 }
603
604 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
605 *new_tls_type |= tls_type;
3898e04b
LC
606
607 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
608 if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
609 *new_tls_type &= ~ (GOT_TLS_GDESC);
e214f8db 610 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
611 {
612 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
613 "thread local symbol"),
614 abfd,
615 h ? h->root.root.string : "<local>");
616 return false;
617 }
618
619 return true;
620}
621
3898e04b
LC
622static unsigned int
623loongarch_reloc_got_type (unsigned int r_type)
624{
625 switch (r_type)
626 {
627 case R_LARCH_TLS_DESC_PC_HI20:
628 case R_LARCH_TLS_DESC_PC_LO12:
629 case R_LARCH_TLS_DESC_LD:
630 case R_LARCH_TLS_DESC_CALL:
631 return GOT_TLS_GDESC;
632
633 case R_LARCH_TLS_IE_PC_HI20:
634 case R_LARCH_TLS_IE_PC_LO12:
635 return GOT_TLS_IE;
636
637 default:
638 break;
639 }
640 return GOT_UNKNOWN;
641}
642
643/* Return true if tls type transition can be performed. */
644static bool
645loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
646 struct elf_link_hash_entry *h, bfd *input_bfd,
647 unsigned long r_symndx)
648{
649 char symbol_tls_type;
650 unsigned int reloc_got_type;
651
652 if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type)
653 || IS_LOONGARCH_TLS_IE_RELOC (r_type)))
654 return false;
655
656 symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
657 reloc_got_type = loongarch_reloc_got_type (r_type);
658
659 if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
660 return true;
661
662 if (! bfd_link_executable (info))
663 return false;
664
665 if (h && h->root.type == bfd_link_hash_undefweak)
666 return false;
667
668 return true;
669}
670
671/* The type of relocation that can be transitioned. */
672static unsigned int
673loongarch_tls_transition_without_check (struct bfd_link_info *info,
674 unsigned int r_type,
675 struct elf_link_hash_entry *h)
676{
677 bool local_exec = bfd_link_executable (info)
678 && SYMBOL_REFERENCES_LOCAL (info, h);
679
680 switch (r_type)
681 {
682 case R_LARCH_TLS_DESC_PC_HI20:
683 return (local_exec
684 ? R_LARCH_TLS_LE_HI20
685 : R_LARCH_TLS_IE_PC_HI20);
686
687 case R_LARCH_TLS_DESC_PC_LO12:
688 return (local_exec
689 ? R_LARCH_TLS_LE_LO12
690 : R_LARCH_TLS_IE_PC_LO12);
691
692 case R_LARCH_TLS_DESC_LD:
693 case R_LARCH_TLS_DESC_CALL:
694 return R_LARCH_NONE;
695
696 case R_LARCH_TLS_IE_PC_HI20:
697 return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
698
699 case R_LARCH_TLS_IE_PC_LO12:
700 return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
701
702 default:
703 break;
704 }
705
706 return r_type;
707}
708
709static unsigned int
710loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
711 struct elf_link_hash_entry *h, bfd *input_bfd,
712 unsigned long r_symndx)
713{
714 if (! loongarch_can_relax_tls (info, r_type, h, input_bfd,r_symndx))
715 return r_type;
716
717 return loongarch_tls_transition_without_check (info, r_type, h);
718}
719
e214f8db 720/* Look through the relocs for a section during the first phase, and
721 allocate space in the global offset table or procedure linkage
722 table. */
723
724static bool
725loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
726 asection *sec, const Elf_Internal_Rela *relocs)
727{
728 struct loongarch_elf_link_hash_table *htab;
729 Elf_Internal_Shdr *symtab_hdr;
730 struct elf_link_hash_entry **sym_hashes;
731 const Elf_Internal_Rela *rel;
732 asection *sreloc = NULL;
733
734 if (bfd_link_relocatable (info))
735 return true;
736
737 htab = loongarch_elf_hash_table (info);
738 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
739 sym_hashes = elf_sym_hashes (abfd);
740
741 if (htab->elf.dynobj == NULL)
742 htab->elf.dynobj = abfd;
743
744 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
745 {
746 unsigned int r_type;
747 unsigned int r_symndx;
748 struct elf_link_hash_entry *h;
749 Elf_Internal_Sym *isym = NULL;
750
e214f8db 751 r_symndx = ELFNN_R_SYM (rel->r_info);
752 r_type = ELFNN_R_TYPE (rel->r_info);
753
754 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
755 {
756 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
757 return false;
758 }
759
760 if (r_symndx < symtab_hdr->sh_info)
761 {
762 /* A local symbol. */
6d13722a 763 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
e214f8db 764 if (isym == NULL)
765 return false;
766
767 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
768 {
769 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
770 if (h == NULL)
771 return false;
772
773 h->type = STT_GNU_IFUNC;
774 h->ref_regular = 1;
775 }
776 else
777 h = NULL;
778 }
779 else
780 {
781 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
782 while (h->root.type == bfd_link_hash_indirect
783 || h->root.type == bfd_link_hash_warning)
784 h = (struct elf_link_hash_entry *) h->root.u.i.link;
785 }
786
d218dba3 787 /* It is referenced by a non-shared object. */
788 if (h != NULL)
789 h->ref_regular = 1;
790
e214f8db 791 if (h && h->type == STT_GNU_IFUNC)
792 {
793 if (htab->elf.dynobj == NULL)
794 htab->elf.dynobj = abfd;
795
6d13722a 796 /* Create 'irelifunc' in PIC object. */
797 if (bfd_link_pic (info)
798 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
799 return false;
800 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
801 else if (!htab->elf.splt
802 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
803 return false;
d218dba3 804 /* Create the ifunc sections, iplt and ipltgot, for static
805 executables. */
806 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
807 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
808 return false;
809
e214f8db 810 if (h->plt.refcount < 0)
811 h->plt.refcount = 0;
812 h->plt.refcount++;
813 h->needs_plt = 1;
814
815 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
816 }
817
6d13722a 818 int need_dynreloc = 0;
819 int only_need_pcrel = 0;
820
3898e04b 821 r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx);
e214f8db 822 switch (r_type)
823 {
6d13722a 824 case R_LARCH_GOT_PC_HI20:
825 case R_LARCH_GOT_HI20:
e214f8db 826 case R_LARCH_SOP_PUSH_GPREL:
6d13722a 827 /* For la.global. */
828 if (h)
829 h->pointer_equality_needed = 1;
e214f8db 830 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
831 r_symndx,
832 GOT_NORMAL))
833 return false;
834 break;
835
6d13722a 836 case R_LARCH_TLS_LD_PC_HI20:
837 case R_LARCH_TLS_LD_HI20:
838 case R_LARCH_TLS_GD_PC_HI20:
839 case R_LARCH_TLS_GD_HI20:
e214f8db 840 case R_LARCH_SOP_PUSH_TLS_GD:
841 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
842 r_symndx,
843 GOT_TLS_GD))
844 return false;
845 break;
846
6d13722a 847 case R_LARCH_TLS_IE_PC_HI20:
848 case R_LARCH_TLS_IE_HI20:
e214f8db 849 case R_LARCH_SOP_PUSH_TLS_GOT:
850 if (bfd_link_pic (info))
851 /* May fail for lazy-bind. */
852 info->flags |= DF_STATIC_TLS;
853
854 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
855 r_symndx,
856 GOT_TLS_IE))
857 return false;
858 break;
859
6d13722a 860 case R_LARCH_TLS_LE_HI20:
aae8784c 861 case R_LARCH_TLS_LE_HI20_R:
e214f8db 862 case R_LARCH_SOP_PUSH_TLS_TPREL:
863 if (!bfd_link_executable (info))
864 return false;
865
866 info->flags |= DF_STATIC_TLS;
867
868 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
869 r_symndx,
870 GOT_TLS_LE))
871 return false;
872 break;
873
4f248d61
LC
874 case R_LARCH_TLS_DESC_PC_HI20:
875 case R_LARCH_TLS_DESC_HI20:
876 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
877 r_symndx,
878 GOT_TLS_GDESC))
879 return false;
880 break;
881
6d13722a 882 case R_LARCH_ABS_HI20:
e214f8db 883 case R_LARCH_SOP_PUSH_ABSOLUTE:
884 if (h != NULL)
885 /* If this reloc is in a read-only section, we might
886 need a copy reloc. We can't check reliably at this
887 stage whether the section is read-only, as input
888 sections have not yet been mapped to output sections.
889 Tentatively set the flag for now, and correct in
890 adjust_dynamic_symbol. */
891 h->non_got_ref = 1;
892 break;
893
e493ba62 894 /* For normal cmodel, pcalau12i + addi.d/w used to data.
895 For first version medium cmodel, pcalau12i + jirl are used to
896 function call, it need to creat PLT entry for STT_FUNC and
897 STT_GNU_IFUNC type symbol. */
6d13722a 898 case R_LARCH_PCALA_HI20:
e493ba62 899 if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
e214f8db 900 {
42bd5254 901 /* For pcalau12i + jirl. */
902 h->needs_plt = 1;
903 if (h->plt.refcount < 0)
904 h->plt.refcount = 0;
905 h->plt.refcount++;
906
e214f8db 907 h->non_got_ref = 1;
6d13722a 908 h->pointer_equality_needed = 1;
909 }
910
911 break;
912
6d13722a 913 case R_LARCH_B16:
1b6fccd2 914 case R_LARCH_B21:
6d13722a 915 case R_LARCH_B26:
dc5f359e 916 case R_LARCH_CALL36:
6d13722a 917 if (h != NULL)
918 {
919 h->needs_plt = 1;
920 if (!bfd_link_pic (info))
921 h->non_got_ref = 1;
e214f8db 922
923 /* We try to create PLT stub for all non-local function. */
924 if (h->plt.refcount < 0)
925 h->plt.refcount = 0;
926 h->plt.refcount++;
927 }
6d13722a 928
929 break;
930
931 case R_LARCH_SOP_PUSH_PCREL:
932 if (h != NULL)
933 {
934 if (!bfd_link_pic (info))
935 h->non_got_ref = 1;
936
937 /* We try to create PLT stub for all non-local function. */
938 if (h->plt.refcount < 0)
939 h->plt.refcount = 0;
940 h->plt.refcount++;
941 h->pointer_equality_needed = 1;
942 }
943
e214f8db 944 break;
945
946 case R_LARCH_SOP_PUSH_PLT_PCREL:
947 /* This symbol requires a procedure linkage table entry. We
948 actually build the entry in adjust_dynamic_symbol,
949 because this might be a case of linking PIC code without
950 linking in any dynamic objects, in which case we don't
951 need to generate a procedure linkage table after all. */
952 if (h != NULL)
953 {
954 h->needs_plt = 1;
955 if (h->plt.refcount < 0)
956 h->plt.refcount = 0;
957 h->plt.refcount++;
958 }
959 break;
960
961 case R_LARCH_TLS_DTPREL32:
962 case R_LARCH_TLS_DTPREL64:
963 need_dynreloc = 1;
964 only_need_pcrel = 1;
965 break;
966
967 case R_LARCH_JUMP_SLOT:
968 case R_LARCH_32:
969 case R_LARCH_64:
6d13722a 970
e214f8db 971 need_dynreloc = 1;
972
973 /* If resolved symbol is defined in this object,
974 1. Under pie, the symbol is known. We convert it
975 into R_LARCH_RELATIVE and need load-addr still.
976 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
977 3. Under dll, R_LARCH_NN can't be changed normally, since
978 its defination could be covered by the one in executable.
979 For symbolic, we convert it into R_LARCH_RELATIVE.
980 Thus, only under pde, it needs pcrel only. We discard it. */
981 only_need_pcrel = bfd_link_pde (info);
982
d218dba3 983 if (h != NULL
984 && (!bfd_link_pic (info)
985 || h->type == STT_GNU_IFUNC))
986 {
987 /* This reloc might not bind locally. */
988 h->non_got_ref = 1;
989 h->pointer_equality_needed = 1;
990
991 if (!h->def_regular
992 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
993 {
994 /* We may need a .plt entry if the symbol is a function
995 defined in a shared lib or is a function referenced
996 from the code or read-only section. */
997 h->plt.refcount += 1;
998 }
999 }
e214f8db 1000 break;
1001
1002 case R_LARCH_GNU_VTINHERIT:
1003 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1004 return false;
1005 break;
1006
1007 case R_LARCH_GNU_VTENTRY:
1008 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1009 return false;
1010 break;
1011
1012 default:
1013 break;
1014 }
1015
1016 /* Record some info for sizing and allocating dynamic entry. */
1017 if (need_dynreloc && (sec->flags & SEC_ALLOC))
1018 {
1019 /* When creating a shared object, we must copy these
1020 relocs into the output file. We create a reloc
1021 section in dynobj and make room for the reloc. */
1022 struct elf_dyn_relocs *p;
1023 struct elf_dyn_relocs **head;
1024
1025 if (sreloc == NULL)
1026 {
1027 sreloc
1028 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
1029 LARCH_ELF_LOG_WORD_BYTES,
1030 abfd, /*rela?*/ true);
1031 if (sreloc == NULL)
1032 return false;
1033 }
1034
1035 /* If this is a global symbol, we count the number of
1036 relocations we need for this symbol. */
1037 if (h != NULL)
d218dba3 1038 head = &h->dyn_relocs;
e214f8db 1039 else
1040 {
1041 /* Track dynamic relocs needed for local syms too.
1042 We really need local syms available to do this
1043 easily. Oh well. */
1044
1045 asection *s;
1046 void *vpp;
1047
1048 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1049 if (s == NULL)
1050 s = sec;
1051
1052 vpp = &elf_section_data (s)->local_dynrel;
1053 head = (struct elf_dyn_relocs **) vpp;
1054 }
1055
1056 p = *head;
1057 if (p == NULL || p->sec != sec)
1058 {
1059 bfd_size_type amt = sizeof *p;
1060 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
1061 if (p == NULL)
1062 return false;
1063 p->next = *head;
1064 *head = p;
1065 p->sec = sec;
1066 p->count = 0;
1067 p->pc_count = 0;
1068 }
1069
1070 p->count++;
1071 p->pc_count += only_need_pcrel;
1072 }
1073 }
1074
1075 return true;
1076}
1077
1078/* Find dynamic relocs for H that apply to read-only sections. */
1079
1080static asection *
1081readonly_dynrelocs (struct elf_link_hash_entry *h)
1082{
1083 struct elf_dyn_relocs *p;
1084
d218dba3 1085 for (p = h->dyn_relocs; p != NULL; p = p->next)
e214f8db 1086 {
1087 asection *s = p->sec->output_section;
1088
1089 if (s != NULL && (s->flags & SEC_READONLY) != 0)
1090 return p->sec;
1091 }
1092 return NULL;
1093}
1094
1095/* Adjust a symbol defined by a dynamic object and referenced by a
1096 regular object. The current definition is in some section of the
1097 dynamic object, but we're not including those sections. We have to
1098 change the definition to something the rest of the link can
1099 understand. */
1100static bool
1101loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1102 struct elf_link_hash_entry *h)
1103{
1104 struct loongarch_elf_link_hash_table *htab;
e214f8db 1105 bfd *dynobj;
e214f8db 1106
1107 htab = loongarch_elf_hash_table (info);
1108 BFD_ASSERT (htab != NULL);
1109
1110 dynobj = htab->elf.dynobj;
1111
1112 /* Make sure we know what is going on here. */
1113 BFD_ASSERT (dynobj != NULL
1b6fccd2 1114 && (h->needs_plt
1115 || h->type == STT_GNU_IFUNC
1116 || h->is_weakalias
1117 || (h->def_dynamic
1118 && h->ref_regular
1119 && !h->def_regular)));
e214f8db 1120
1121 /* If this is a function, put it in the procedure linkage table. We
1122 will fill in the contents of the procedure linkage table later
1123 (although we could actually do it here). */
1124 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
1125 {
6a1cf1bf 1126 if (h->plt.refcount <= 0
e214f8db 1127 || (h->type != STT_GNU_IFUNC
1128 && (SYMBOL_REFERENCES_LOCAL (info, h)
1129 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1130 && h->root.type == bfd_link_hash_undefweak))))
1131 {
1132 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1133 in an input file, but the symbol was never referred to by a
1134 dynamic object, or if all references were garbage collected.
1135 In such a case, we don't actually need to build a PLT entry. */
1136 h->plt.offset = MINUS_ONE;
1137 h->needs_plt = 0;
1138 }
e214f8db 1139
1140 return true;
1141 }
1142 else
1143 h->plt.offset = MINUS_ONE;
1144
1145 /* If this is a weak symbol, and there is a real definition, the
1146 processor independent code will have arranged for us to see the
1147 real definition first, and we can just use the same value. */
1148 if (h->is_weakalias)
1149 {
1150 struct elf_link_hash_entry *def = weakdef (h);
1151 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1152 h->root.u.def.section = def->root.u.def.section;
1153 h->root.u.def.value = def->root.u.def.value;
1154 return true;
1155 }
1156
6d13722a 1157 /* R_LARCH_COPY is not adept glibc, not to generate. */
1158 /* Can not print anything, because make check ld. */
1159 return true;
e214f8db 1160}
1161
1162/* Allocate space in .plt, .got and associated reloc sections for
1163 dynamic relocs. */
1164
1165static bool
1166allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1167{
1168 struct bfd_link_info *info;
1169 struct loongarch_elf_link_hash_table *htab;
e214f8db 1170 struct elf_dyn_relocs *p;
1171
1172 if (h->root.type == bfd_link_hash_indirect)
1173 return true;
1174
d218dba3 1175 if (h->type == STT_GNU_IFUNC
1176 && h->def_regular)
1177 return true;
1178
e214f8db 1179 info = (struct bfd_link_info *) inf;
1180 htab = loongarch_elf_hash_table (info);
6d13722a 1181 bool dyn = htab->elf.dynamic_sections_created;
e214f8db 1182 BFD_ASSERT (htab != NULL);
1183
1184 do
1185 {
1186 asection *plt, *gotplt, *relplt;
1187
1188 if (!h->needs_plt)
1189 break;
1190
1191 h->needs_plt = 0;
1192
1193 if (htab->elf.splt)
1194 {
6d13722a 1195 if (h->dynindx == -1 && !h->forced_local && dyn
1196 && h->root.type == bfd_link_hash_undefweak)
1197 {
1198 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1199 return false;
1200 }
e214f8db 1201
1202 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1203 && h->type != STT_GNU_IFUNC)
1204 break;
1205
1206 plt = htab->elf.splt;
1207 gotplt = htab->elf.sgotplt;
1208 relplt = htab->elf.srelplt;
1209 }
1210 else if (htab->elf.iplt)
1211 {
1212 /* .iplt only for IFUNC. */
1213 if (h->type != STT_GNU_IFUNC)
1214 break;
1215
1216 plt = htab->elf.iplt;
1217 gotplt = htab->elf.igotplt;
1218 relplt = htab->elf.irelplt;
1219 }
1220 else
1221 break;
1222
1223 if (plt->size == 0)
1224 plt->size = PLT_HEADER_SIZE;
1225
1226 h->plt.offset = plt->size;
1227 plt->size += PLT_ENTRY_SIZE;
1228 gotplt->size += GOT_ENTRY_SIZE;
1229 relplt->size += sizeof (ElfNN_External_Rela);
1230
d218dba3 1231 /* If this symbol is not defined in a regular file, and we are
1232 not generating a shared library, then set the symbol to this
1233 location in the .plt. This is required to make function
1234 pointers compare as equal between the normal executable and
1235 the shared library. */
6d13722a 1236 if (!bfd_link_pic (info)
d218dba3 1237 && !h->def_regular)
1238 {
1239 h->root.u.def.section = plt;
1240 h->root.u.def.value = h->plt.offset;
1241 }
1242
e214f8db 1243 h->needs_plt = 1;
1244 }
1245 while (0);
1246
1247 if (!h->needs_plt)
1248 h->plt.offset = MINUS_ONE;
1249
1250 if (0 < h->got.refcount)
1251 {
1252 asection *s;
e214f8db 1253 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1254
1255 /* Make sure this symbol is output as a dynamic symbol.
1256 Undefined weak syms won't yet be marked as dynamic. */
6d13722a 1257 if (h->dynindx == -1 && !h->forced_local && dyn
1258 && h->root.type == bfd_link_hash_undefweak)
d218dba3 1259 {
6d13722a 1260 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1261 return false;
d218dba3 1262 }
e214f8db 1263
1264 s = htab->elf.sgot;
1265 h->got.offset = s->size;
4f248d61 1266 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
e214f8db 1267 {
1268 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1269 if (tls_type & GOT_TLS_GD)
1270 {
1271 s->size += 2 * GOT_ENTRY_SIZE;
6d13722a 1272 if (bfd_link_executable (info))
1273 {
1274 /* Link exe and not defined local. */
1275 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1276 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1277 }
1278 else
1279 {
1280 if (SYMBOL_REFERENCES_LOCAL (info, h))
1281 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1282 else
1283 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1284 }
e214f8db 1285 }
1286
1287 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1288 if (tls_type & GOT_TLS_IE)
1289 {
1290 s->size += GOT_ENTRY_SIZE;
6d13722a 1291
1292 if (bfd_link_executable (info))
1293 {
1294 /* Link exe and not defined local. */
1295 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1296 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1297 }
1298 else
1299 {
1300 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1301 }
e214f8db 1302 }
4f248d61
LC
1303
1304 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1305 if (tls_type & GOT_TLS_GDESC)
1306 {
1307 s->size += GOT_ENTRY_SIZE * 2;
1308 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1309 }
e214f8db 1310 }
4f248d61 1311
e214f8db 1312 else
1313 {
1314 s->size += GOT_ENTRY_SIZE;
6d13722a 1315 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1316 || h->root.type != bfd_link_hash_undefweak)
1317 && (bfd_link_pic (info)
1318 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1319 h))
1320 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1321 /* Undefined weak symbol in static PIE resolves to 0 without
1322 any dynamic relocations. */
e214f8db 1323 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1324 }
1325 }
1326 else
1327 h->got.offset = MINUS_ONE;
1328
d218dba3 1329 if (h->dyn_relocs == NULL)
e214f8db 1330 return true;
1331
6d13722a 1332 /* Extra dynamic relocate,
1333 * R_LARCH_64
1334 * R_LARCH_TLS_DTPRELNN
1335 * R_LARCH_JUMP_SLOT
1336 * R_LARCH_NN. */
1337
1338 if (SYMBOL_CALLS_LOCAL (info, h))
e214f8db 1339 {
1340 struct elf_dyn_relocs **pp;
1341
d218dba3 1342 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
e214f8db 1343 {
1344 p->count -= p->pc_count;
1345 p->pc_count = 0;
1346 if (p->count == 0)
1347 *pp = p->next;
1348 else
1349 pp = &p->next;
1350 }
1351 }
1352
1353 if (h->root.type == bfd_link_hash_undefweak)
1354 {
6d13722a 1355 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1356 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1357 || (!bfd_link_pic (info) && h->non_got_ref))
d218dba3 1358 h->dyn_relocs = NULL;
6d13722a 1359 else if (h->dynindx == -1 && !h->forced_local)
1360 {
1361 /* Make sure this symbol is output as a dynamic symbol.
1362 Undefined weak syms won't yet be marked as dynamic. */
1363 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1364 return false;
1365
1366 if (h->dynindx == -1)
1367 h->dyn_relocs = NULL;
1368 }
e214f8db 1369 }
1370
d218dba3 1371 for (p = h->dyn_relocs; p != NULL; p = p->next)
e214f8db 1372 {
1373 asection *sreloc = elf_section_data (p->sec)->sreloc;
1374 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1375 }
1376
1377 return true;
1378}
1379
bc2a35c0 1380/* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1381 For local def and ref ifunc,
1382 dynamic relocations are stored in
1383 1. rela.srelgot section in dynamic object (dll or exec).
1384 2. rela.irelplt section in static executable.
1385 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1386 instead of rela.srelplt. Glibc ELF loader will not support
1387 R_LARCH_IRELATIVE relocation in rela.plt. */
1388
1389static bool
1390local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1391 struct elf_link_hash_entry *h,
1392 struct elf_dyn_relocs **head,
1393 unsigned int plt_entry_size,
1394 unsigned int plt_header_size,
1395 unsigned int got_entry_size,
1396 bool avoid_plt)
1397{
1398 asection *plt, *gotplt, *relplt;
1399 struct elf_dyn_relocs *p;
1400 unsigned int sizeof_reloc;
1401 const struct elf_backend_data *bed;
1402 struct elf_link_hash_table *htab;
1403 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1404 bool use_plt = !avoid_plt || h->plt.refcount > 0;
1405 bool need_dynreloc = !use_plt || bfd_link_pic (info);
1406
1407 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1408 in executable or it isn't referenced via PLT, the address of
1409 the resolved function may be used. But in non-PIC executable,
1410 the address of its plt slot may be used. Pointer equality may
1411 not work correctly. PIE or non-PLT reference should be used if
1412 pointer equality is required here.
1413
1414 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1415 backend should change it to the normal function and set its address
1416 to its PLT entry which should be resolved by R_*_IRELATIVE at
1417 run-time. All external references should be resolved to its PLT in
1418 executable. */
1419 if (!need_dynreloc
1420 && !(bfd_link_pde (info) && h->def_regular)
1421 && (h->dynindx != -1
1422 || info->export_dynamic)
1423 && h->pointer_equality_needed)
1424 {
1425 info->callbacks->einfo
1426 /* xgettext:c-format. */
1427 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1428 "equality in `%pB' can not be used when making an "
1429 "executable; recompile with -fPIE and relink with -pie\n"),
1430 h->root.root.string,
1431 h->root.u.def.section->owner);
1432 bfd_set_error (bfd_error_bad_value);
1433 return false;
1434 }
1435
1436 htab = elf_hash_table (info);
1437
1438 /* When the symbol is marked with regular reference, if PLT isn't used
1439 or we are building a PIC object, we must keep dynamic relocation
1440 if there is non-GOT reference and use PLT if there is PC-relative
1441 reference. */
1442 if (need_dynreloc && h->ref_regular)
1443 {
1444 bool keep = false;
1445 for (p = *head; p != NULL; p = p->next)
1446 if (p->count)
1447 {
1448 h->non_got_ref = 1;
1449 /* Need dynamic relocations for non-GOT reference. */
1450 keep = true;
1451 if (p->pc_count)
1452 {
1453 /* Must use PLT for PC-relative reference. */
1454 use_plt = true;
1455 need_dynreloc = bfd_link_pic (info);
1456 break;
1457 }
1458 }
1459 if (keep)
1460 goto keep;
1461 }
1462
1463 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1464 if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1465 {
1466 h->got = htab->init_got_offset;
1467 h->plt = htab->init_plt_offset;
1468 *head = NULL;
1469 return true;
1470 }
1471
1472 /* Return and discard space for dynamic relocations against it if
1473 it is never referenced. */
1474 if (!h->ref_regular)
1475 {
1476 if (h->plt.refcount > 0
1477 || h->got.refcount > 0)
1478 abort ();
1479 h->got = htab->init_got_offset;
1480 h->plt = htab->init_plt_offset;
1481 *head = NULL;
1482 return true;
1483 }
1484
1485 keep:
1486 bed = get_elf_backend_data (info->output_bfd);
1487 if (bed->rela_plts_and_copies_p)
1488 sizeof_reloc = bed->s->sizeof_rela;
1489 else
1490 sizeof_reloc = bed->s->sizeof_rel;
1491
1492 /* When building a static executable, use iplt, igot.plt and
1493 rela.iplt sections for STT_GNU_IFUNC symbols. */
1494 if (htab->splt != NULL)
1495 {
1496 plt = htab->splt;
1497 gotplt = htab->sgotplt;
1498 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1499 relplt = htab->srelgot;
1500
1501 /* If this is the first plt entry and PLT is used, make room for
1502 the special first entry. */
1503 if (plt->size == 0 && use_plt)
1504 plt->size += plt_header_size;
1505 }
1506 else
1507 {
1508 plt = htab->iplt;
1509 gotplt = htab->igotplt;
1510 relplt = htab->irelplt;
1511 }
1512
1513 if (use_plt)
1514 {
1515 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1516 the original value for R_*_IRELATIVE. */
1517 h->plt.offset = plt->size;
1518
1519 /* Make room for this entry in the plt/iplt section. */
1520 plt->size += plt_entry_size;
1521
1522 /* We also need to make an entry in the got.plt/got.iplt section,
1523 which will be placed in the got section by the linker script. */
1524 gotplt->size += got_entry_size;
1525 }
1526
1527 /* We also need to make an entry in the rela.plt/.rela.iplt
1528 section for GOTPLT relocation if PLT is used. */
1529 if (use_plt)
1530 {
1531 relplt->size += sizeof_reloc;
1532 relplt->reloc_count++;
1533 }
1534
1535 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1536 there is a non-GOT reference in a PIC object or PLT isn't used. */
1537 if (!need_dynreloc || !h->non_got_ref)
1538 *head = NULL;
1539
1540 /* Finally, allocate space. */
1541 p = *head;
1542 if (p != NULL)
1543 {
1544 bfd_size_type count = 0;
1545 do
1546 {
1547 count += p->count;
1548 p = p->next;
1549 }
1550 while (p != NULL);
1551
1552 htab->ifunc_resolvers = count != 0;
1553
1554 /* Dynamic relocations are stored in
1555 1. rela.srelgot section in PIC object.
1556 2. rela.srelgot section in dynamic executable.
1557 3. rela.irelplt section in static executable. */
1558 if (htab->splt != NULL)
1559 htab->srelgot->size += count * sizeof_reloc;
1560 else
1561 {
1562 relplt->size += count * sizeof_reloc;
1563 relplt->reloc_count += count;
1564 }
1565 }
1566
1567 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1568 and got has the PLT entry adddress. We will load the GOT entry
1569 with the PLT entry in finish_dynamic_symbol if it is used. For
1570 branch, it uses got.plt. For symbol value, if PLT is used,
1571 1. Use got.plt in a PIC object if it is forced local or not
1572 dynamic.
1573 2. Use got.plt in a non-PIC object if pointer equality isn't
1574 needed.
1575 3. Use got.plt in PIE.
1576 4. Use got.plt if got isn't used.
1577 5. Otherwise use got so that it can be shared among different
1578 objects at run-time.
1579 If PLT isn't used, always use got for symbol value.
1580 We only need to relocate got entry in PIC object or in dynamic
1581 executable without PLT. */
1582 if (use_plt
1583 && (h->got.refcount <= 0
1584 || (bfd_link_pic (info)
1585 && (h->dynindx == -1
1586 || h->forced_local))
1587 || (
1588 !h->pointer_equality_needed)
1589 || htab->sgot == NULL))
1590 {
1591 /* Use got.plt. */
1592 h->got.offset = (bfd_vma) -1;
1593 }
1594 else
1595 {
1596 if (!use_plt)
1597 {
1598 /* PLT isn't used. */
1599 h->plt.offset = (bfd_vma) -1;
1600 }
1601 if (h->got.refcount <= 0)
1602 {
1603 /* GOT isn't need when there are only relocations for static
1604 pointers. */
1605 h->got.offset = (bfd_vma) -1;
1606 }
1607 else
1608 {
1609 h->got.offset = htab->sgot->size;
1610 htab->sgot->size += got_entry_size;
1611 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1612 used. Otherwise, the GOT entry will be filled with the PLT
1613 entry and dynamic GOT relocation isn't needed. */
1614 if (need_dynreloc)
1615 {
1616 /* For non-static executable, dynamic GOT relocation is in
1617 rela.got section, but for static executable, it is
1618 in rela.iplt section. */
1619 if (htab->splt != NULL)
1620 htab->srelgot->size += sizeof_reloc;
1621 else
1622 {
1623 relplt->size += sizeof_reloc;
1624 relplt->reloc_count++;
1625 }
1626 }
1627 }
1628 }
1629
1630 return true;
1631}
1632
d218dba3 1633/* Allocate space in .plt, .got and associated reloc sections for
1634 ifunc dynamic relocs. */
1635
1636static bool
6d13722a 1637elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
d218dba3 1638{
1639 struct bfd_link_info *info;
1640 /* An example of a bfd_link_hash_indirect symbol is versioned
1641 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1642 -> __gxx_personality_v0(bfd_link_hash_defined)
1643
1644 There is no need to process bfd_link_hash_indirect symbols here
1645 because we will also be presented with the concrete instance of
1646 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1647 called to copy all relevant data from the generic to the concrete
1648 symbol instance. */
1649 if (h->root.type == bfd_link_hash_indirect)
1650 return true;
1651
1652 if (h->root.type == bfd_link_hash_warning)
1653 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1654
1655 info = (struct bfd_link_info *) inf;
1656
1657 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1658 here if it is defined and referenced in a non-shared object. */
6d13722a 1659 if (h->type == STT_GNU_IFUNC && h->def_regular)
bc2a35c0 1660 {
1661 if (SYMBOL_REFERENCES_LOCAL (info, h))
1662 return local_allocate_ifunc_dyn_relocs (info, h,
1663 &h->dyn_relocs,
1664 PLT_ENTRY_SIZE,
1665 PLT_HEADER_SIZE,
1666 GOT_ENTRY_SIZE,
1667 false);
1668 else
1669 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1670 &h->dyn_relocs,
1671 PLT_ENTRY_SIZE,
1672 PLT_HEADER_SIZE,
1673 GOT_ENTRY_SIZE,
1674 false);
1675 }
6d13722a 1676
d218dba3 1677 return true;
1678}
1679
1680/* Allocate space in .plt, .got and associated reloc sections for
1681 ifunc dynamic relocs. */
1682
b5c37946 1683static int
6d13722a 1684elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
e214f8db 1685{
1686 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1687
d218dba3 1688 if (h->type != STT_GNU_IFUNC
1689 || !h->def_regular
1690 || !h->ref_regular
1691 || !h->forced_local
e214f8db 1692 || h->root.type != bfd_link_hash_defined)
1693 abort ();
1694
6d13722a 1695 return elfNN_allocate_ifunc_dynrelocs (h, inf);
e214f8db 1696}
1697
1698/* Set DF_TEXTREL if we find any dynamic relocs that apply to
1699 read-only sections. */
1700
1701static bool
1702maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1703{
1704 asection *sec;
1705
1706 if (h->root.type == bfd_link_hash_indirect)
1707 return true;
1708
1709 sec = readonly_dynrelocs (h);
1710 if (sec != NULL)
1711 {
1712 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1713
1714 info->flags |= DF_TEXTREL;
1715 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1716 "read-only section `%pA'\n"),
1717 sec->owner, h->root.root.string, sec);
1718
1719 /* Not an error, just cut short the traversal. */
1720 return false;
1721 }
1722 return true;
1723}
1724
1725static bool
1726loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1727 struct bfd_link_info *info)
1728{
1729 struct loongarch_elf_link_hash_table *htab;
1730 bfd *dynobj;
1731 asection *s;
1732 bfd *ibfd;
1733
1734 htab = loongarch_elf_hash_table (info);
1735 BFD_ASSERT (htab != NULL);
1736 dynobj = htab->elf.dynobj;
1737 BFD_ASSERT (dynobj != NULL);
1738
1739 if (htab->elf.dynamic_sections_created)
1740 {
1741 /* Set the contents of the .interp section to the interpreter. */
1742 if (bfd_link_executable (info) && !info->nointerp)
1743 {
1744 const char *interpreter;
e214f8db 1745 s = bfd_get_linker_section (dynobj, ".interp");
1746 BFD_ASSERT (s != NULL);
c4a7e6b5 1747
1748 if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
e214f8db 1749 interpreter = "/lib32/ld.so.1";
c4a7e6b5 1750 else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
e214f8db 1751 interpreter = "/lib64/ld.so.1";
1752 else
1753 interpreter = "/lib/ld.so.1";
c4a7e6b5 1754
e214f8db 1755 s->contents = (unsigned char *) interpreter;
1756 s->size = strlen (interpreter) + 1;
1757 }
1758 }
1759
1760 /* Set up .got offsets for local syms, and space for local dynamic
1761 relocs. */
1762 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1763 {
1764 bfd_signed_vma *local_got;
1765 bfd_signed_vma *end_local_got;
1766 char *local_tls_type;
1767 bfd_size_type locsymcount;
1768 Elf_Internal_Shdr *symtab_hdr;
1769 asection *srel;
1770
1771 if (!is_loongarch_elf (ibfd))
1772 continue;
1773
1774 for (s = ibfd->sections; s != NULL; s = s->next)
1775 {
1776 struct elf_dyn_relocs *p;
1777
1778 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1779 {
1780 p->count -= p->pc_count;
1781 if (!bfd_is_abs_section (p->sec)
1782 && bfd_is_abs_section (p->sec->output_section))
1783 {
1784 /* Input section has been discarded, either because
1785 it is a copy of a linkonce section or due to
1786 linker script /DISCARD/, so we'll be discarding
1787 the relocs too. */
1788 }
1789 else if (0 < p->count)
1790 {
1791 srel = elf_section_data (p->sec)->sreloc;
1792 srel->size += p->count * sizeof (ElfNN_External_Rela);
1793 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1794 info->flags |= DF_TEXTREL;
1795 }
1796 }
1797 }
1798
1799 local_got = elf_local_got_refcounts (ibfd);
1800 if (!local_got)
1801 continue;
1802
1803 symtab_hdr = &elf_symtab_hdr (ibfd);
1804 locsymcount = symtab_hdr->sh_info;
1805 end_local_got = local_got + locsymcount;
1806 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1807 s = htab->elf.sgot;
1808 srel = htab->elf.srelgot;
1809 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1810 {
1811 if (0 < *local_got)
1812 {
1813 *local_got = s->size;
4f248d61
LC
1814 if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1815 {
1816 /* TLS gd use two got. */
1817 if (*local_tls_type & GOT_TLS_GD)
1818 {
1819 s->size += 2 * GOT_ENTRY_SIZE;
1820 if (!bfd_link_executable (info))
1821 srel->size += sizeof (ElfNN_External_Rela);
1822 }
e214f8db 1823
4f248d61
LC
1824 /* TLS_DESC use two got. */
1825 if (*local_tls_type & GOT_TLS_GDESC)
1826 {
1827 s->size += 2 * GOT_ENTRY_SIZE;
1828 srel->size += sizeof (ElfNN_External_Rela);
1829 }
e214f8db 1830
4f248d61
LC
1831 /* TLS ie and use one got. */
1832 if (*local_tls_type & GOT_TLS_IE)
1833 {
1834 s->size += GOT_ENTRY_SIZE;
1835 if (!bfd_link_executable (info))
1836 srel->size += sizeof (ElfNN_External_Rela);
1837 }
1838 }
6d13722a 1839 else
1840 {
4f248d61 1841 s->size += GOT_ENTRY_SIZE;
6d13722a 1842 srel->size += sizeof (ElfNN_External_Rela);
1843 }
e214f8db 1844 }
1845 else
1846 *local_got = MINUS_ONE;
1847 }
1848 }
1849
1850 /* Allocate global sym .plt and .got entries, and space for global
1851 sym dynamic relocs. */
1852 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
d218dba3 1853
1854 /* Allocate global ifunc sym .plt and .got entries, and space for global
1855 ifunc sym dynamic relocs. */
6d13722a 1856 elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
d218dba3 1857
e214f8db 1858 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1859 htab_traverse (htab->loc_hash_table,
b5c37946 1860 elfNN_allocate_local_ifunc_dynrelocs, info);
e214f8db 1861
1862 /* Don't allocate .got.plt section if there are no PLT. */
1863 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1864 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1865 htab->elf.sgotplt->size = 0;
1866
1867 /* The check_relocs and adjust_dynamic_symbol entry points have
1868 determined the sizes of the various dynamic sections. Allocate
1869 memory for them. */
1870 for (s = dynobj->sections; s != NULL; s = s->next)
1871 {
1872 if ((s->flags & SEC_LINKER_CREATED) == 0)
1873 continue;
1874
1875 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1876 || s == htab->elf.sgotplt || s == htab->elf.igotplt
1877 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1878 {
1879 /* Strip this section if we don't need it; see the
1880 comment below. */
1881 }
1882 else if (strncmp (s->name, ".rela", 5) == 0)
1883 {
1884 if (s->size != 0)
1885 {
1886 /* We use the reloc_count field as a counter if we need
1887 to copy relocs into the output file. */
1888 s->reloc_count = 0;
1889 }
1890 }
1891 else
1892 {
1893 /* It's not one of our sections. */
1894 continue;
1895 }
1896
1897 if (s->size == 0)
1898 {
1899 /* If we don't need this section, strip it from the
1900 output file. This is mostly to handle .rela.bss and
1901 .rela.plt. We must create both sections in
1902 create_dynamic_sections, because they must be created
1903 before the linker maps input sections to output
1904 sections. The linker does that before
1905 adjust_dynamic_symbol is called, and it is that
1906 function which decides whether anything needs to go
1907 into these sections. */
1908 s->flags |= SEC_EXCLUDE;
1909 continue;
1910 }
1911
1912 if ((s->flags & SEC_HAS_CONTENTS) == 0)
1913 continue;
1914
1915 /* Allocate memory for the section contents. Zero the memory
1916 for the benefit of .rela.plt, which has 4 unused entries
1917 at the beginning, and we don't want garbage. */
1918 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1919 if (s->contents == NULL)
1920 return false;
1921 }
1922
1923 if (elf_hash_table (info)->dynamic_sections_created)
1924 {
1925 /* Add some entries to the .dynamic section. We fill in the
1926 values later, in loongarch_elf_finish_dynamic_sections, but we
1927 must add the entries now so that we get the correct size for
1928 the .dynamic section. The DT_DEBUG entry is filled in by the
1929 dynamic linker and used by the debugger. */
1930#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1931
1932 if (bfd_link_executable (info))
1933 {
1934 if (!add_dynamic_entry (DT_DEBUG, 0))
1935 return false;
1936 }
1937
1938 if (htab->elf.srelplt->size != 0)
1939 {
1940 if (!add_dynamic_entry (DT_PLTGOT, 0)
1941 || !add_dynamic_entry (DT_PLTRELSZ, 0)
1942 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1943 || !add_dynamic_entry (DT_JMPREL, 0))
1944 return false;
1945 }
1946
1947 if (!add_dynamic_entry (DT_RELA, 0)
1948 || !add_dynamic_entry (DT_RELASZ, 0)
1949 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1950 return false;
1951
1952 /* If any dynamic relocs apply to a read-only section,
1953 then we need a DT_TEXTREL entry. */
1954 if ((info->flags & DF_TEXTREL) == 0)
1955 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1956
1957 if (info->flags & DF_TEXTREL)
1958 {
1959 if (!add_dynamic_entry (DT_TEXTREL, 0))
1960 return false;
1961 /* Clear the DF_TEXTREL flag. It will be set again if we
1962 write out an actual text relocation; we may not, because
1963 at this point we do not know whether e.g. any .eh_frame
1964 absolute relocations have been converted to PC-relative. */
1965 info->flags &= ~DF_TEXTREL;
1966 }
1967 }
1968#undef add_dynamic_entry
1969
1970 return true;
1971}
1972
1973#define LARCH_LD_STACK_DEPTH 16
1974static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1975static size_t larch_stack_top = 0;
1976
1977static bfd_reloc_status_type
1978loongarch_push (int64_t val)
1979{
1980 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1981 return bfd_reloc_outofrange;
1982 larch_opc_stack[larch_stack_top++] = val;
1983 return bfd_reloc_ok;
1984}
1985
1986static bfd_reloc_status_type
1987loongarch_pop (int64_t *val)
1988{
1989 if (larch_stack_top == 0)
1990 return bfd_reloc_outofrange;
1991 BFD_ASSERT (val);
1992 *val = larch_opc_stack[--larch_stack_top];
1993 return bfd_reloc_ok;
1994}
1995
1996static bfd_reloc_status_type
1997loongarch_top (int64_t *val)
1998{
1999 if (larch_stack_top == 0)
2000 return bfd_reloc_outofrange;
2001 BFD_ASSERT (val);
2002 *val = larch_opc_stack[larch_stack_top - 1];
2003 return bfd_reloc_ok;
2004}
2005
2006static void
2007loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
2008{
6d13722a 2009 BFD_ASSERT (s && s->contents);
e214f8db 2010 const struct elf_backend_data *bed;
2011 bfd_byte *loc;
2012
2013 bed = get_elf_backend_data (abfd);
6d13722a 2014 if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
2015 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
e214f8db 2016 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
2017 bed->s->swap_reloca_out (abfd, rel, loc);
2018}
2019
2020/* Check rel->r_offset in range of contents. */
2021static bfd_reloc_status_type
2022loongarch_check_offset (const Elf_Internal_Rela *rel,
2023 const asection *input_section)
2024{
2025 if (0 == strcmp(input_section->name, ".text")
2026 && rel->r_offset > input_section->size)
2027 return bfd_reloc_overflow;
2028
2029 return bfd_reloc_ok;
2030}
2031
e214f8db 2032#define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2033 ({ \
2034 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2035 if (ret == bfd_reloc_ok) \
2036 { \
2037 ret = loongarch_pop (&op1); \
2038 if (ret == bfd_reloc_ok) \
2039 ret = loongarch_push (op3); \
2040 } \
2041 ret; \
2042 })
2043
dc5f359e 2044/* Write immediate to instructions. */
2045
e214f8db 2046static bfd_reloc_status_type
2047loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
2048 const asection *input_section ATTRIBUTE_UNUSED,
2049 reloc_howto_type *howto, bfd *input_bfd,
748594bc 2050 bfd_byte *contents, bfd_vma reloc_val)
e214f8db 2051{
dc5f359e 2052 /* Adjust the immediate based on alignment and
2053 its position in the instruction. */
1b6fccd2 2054 if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
748594bc 2055 return bfd_reloc_overflow;
2056
dc5f359e 2057 int bits = bfd_get_reloc_size (howto) * 8;
2058 uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
2059
2060 /* Write immediate to instruction. */
2061 insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
748594bc 2062
e214f8db 2063 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
2064
2065 return bfd_reloc_ok;
2066}
2067
e214f8db 2068static bfd_reloc_status_type
2069perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
2070 reloc_howto_type *howto, bfd_vma value,
2071 bfd *input_bfd, bfd_byte *contents)
2072{
e214f8db 2073 int64_t opr1, opr2, opr3;
2074 bfd_reloc_status_type r = bfd_reloc_ok;
2075 int bits = bfd_get_reloc_size (howto) * 8;
2076
e214f8db 2077 switch (ELFNN_R_TYPE (rel->r_info))
2078 {
2079 case R_LARCH_SOP_PUSH_PCREL:
2080 case R_LARCH_SOP_PUSH_ABSOLUTE:
2081 case R_LARCH_SOP_PUSH_GPREL:
2082 case R_LARCH_SOP_PUSH_TLS_TPREL:
2083 case R_LARCH_SOP_PUSH_TLS_GOT:
2084 case R_LARCH_SOP_PUSH_TLS_GD:
2085 case R_LARCH_SOP_PUSH_PLT_PCREL:
2086 r = loongarch_push (value);
2087 break;
2088
2089 case R_LARCH_SOP_PUSH_DUP:
2090 r = loongarch_pop (&opr1);
2091 if (r == bfd_reloc_ok)
2092 {
2093 r = loongarch_push (opr1);
2094 if (r == bfd_reloc_ok)
2095 r = loongarch_push (opr1);
2096 }
2097 break;
2098
2099 case R_LARCH_SOP_ASSERT:
2100 r = loongarch_pop (&opr1);
2101 if (r != bfd_reloc_ok || !opr1)
2102 r = bfd_reloc_notsupported;
2103 break;
2104
2105 case R_LARCH_SOP_NOT:
2106 r = loongarch_pop (&opr1);
2107 if (r == bfd_reloc_ok)
2108 r = loongarch_push (!opr1);
2109 break;
2110
2111 case R_LARCH_SOP_SUB:
2112 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
2113 break;
2114
2115 case R_LARCH_SOP_SL:
2116 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
2117 break;
2118
2119 case R_LARCH_SOP_SR:
2120 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
2121 break;
2122
2123 case R_LARCH_SOP_AND:
2124 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
2125 break;
2126
2127 case R_LARCH_SOP_ADD:
2128 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
2129 break;
2130
2131 case R_LARCH_SOP_IF_ELSE:
2132 r = loongarch_pop (&opr3);
2133 if (r == bfd_reloc_ok)
2134 {
2135 r = loongarch_pop (&opr2);
2136 if (r == bfd_reloc_ok)
2137 {
2138 r = loongarch_pop (&opr1);
2139 if (r == bfd_reloc_ok)
2140 r = loongarch_push (opr1 ? opr2 : opr3);
2141 }
2142 }
2143 break;
2144
2145 case R_LARCH_SOP_POP_32_S_10_5:
2146 case R_LARCH_SOP_POP_32_S_10_12:
2147 case R_LARCH_SOP_POP_32_S_10_16:
2148 case R_LARCH_SOP_POP_32_S_10_16_S2:
6d13722a 2149 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2150 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
e214f8db 2151 case R_LARCH_SOP_POP_32_S_5_20:
e214f8db 2152 case R_LARCH_SOP_POP_32_U_10_12:
748594bc 2153 case R_LARCH_SOP_POP_32_U:
e214f8db 2154 r = loongarch_pop (&opr1);
2155 if (r != bfd_reloc_ok)
2156 break;
2157 r = loongarch_check_offset (rel, input_section);
2158 if (r != bfd_reloc_ok)
2159 break;
2160
2161 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2162 howto, input_bfd,
748594bc 2163 contents, (bfd_vma)opr1);
e214f8db 2164 break;
2165
e214f8db 2166 case R_LARCH_TLS_DTPREL32:
2167 case R_LARCH_32:
2168 case R_LARCH_TLS_DTPREL64:
2169 case R_LARCH_64:
2170 r = loongarch_check_offset (rel, input_section);
2171 if (r != bfd_reloc_ok)
2172 break;
2173
2174 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2175 break;
2176
1b6fccd2 2177 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2178 Because set/sub reloc pair not support multi-thread. While add/sub
2179 reloc pair process order not affect the final result.
2180
2181 For add/sub reloc, the original value will be involved in the
2182 calculation. In order not to add/sub extra value, we write 0 to symbol
2183 address at assembly time.
2184
2185 add/sub reloc bits determined by the value after symbol subtraction,
2186 not symbol value.
2187
2188 add/sub reloc save part of the symbol value, so we only need to
2189 save howto->dst_mask bits. */
2190 case R_LARCH_ADD6:
2191 case R_LARCH_SUB6:
2192 {
2193 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2194 contents + rel->r_offset);
2195 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2196 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2197 r = bfd_reloc_ok;
2198 break;
2199 }
2200
2201 /* Not need to read the original value, just write the new value. */
e214f8db 2202 case R_LARCH_ADD8:
2203 case R_LARCH_ADD16:
2204 case R_LARCH_ADD24:
2205 case R_LARCH_ADD32:
2206 case R_LARCH_ADD64:
e214f8db 2207 case R_LARCH_SUB8:
2208 case R_LARCH_SUB16:
2209 case R_LARCH_SUB24:
2210 case R_LARCH_SUB32:
2211 case R_LARCH_SUB64:
1b6fccd2 2212 {
2213 /* Because add/sub reloc is processed separately,
2214 so the high bits is invalid. */
2215 bfd_vma word = value & howto->dst_mask;
2216 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2217 r = bfd_reloc_ok;
e214f8db 2218 break;
1b6fccd2 2219 }
e214f8db 2220
1b6fccd2 2221 case R_LARCH_ADD_ULEB128:
2222 case R_LARCH_SUB_ULEB128:
2223 {
2224 unsigned int len = 0;
2225 /* Before write uleb128, first read it to get it's length. */
2226 _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2227 loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2228 r = bfd_reloc_ok;
2229 break;
2230 }
e214f8db 2231
98011207 2232 /* For eh_frame and debug info. */
2233 case R_LARCH_32_PCREL:
be1ebb67 2234 case R_LARCH_64_PCREL:
1b6fccd2 2235 {
2236 value -= sec_addr (input_section) + rel->r_offset;
2237 value += rel->r_addend;
2238 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2239 contents + rel->r_offset);
2240 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2241 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2242 r = bfd_reloc_ok;
2243 break;
2244 }
98011207 2245
6d13722a 2246 /* New reloc type.
2247 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2248 case R_LARCH_B16:
2249 case R_LARCH_B21:
2250 case R_LARCH_B26:
2251 case R_LARCH_ABS_HI20:
2252 case R_LARCH_ABS_LO12:
2253 case R_LARCH_ABS64_LO20:
2254 case R_LARCH_ABS64_HI12:
2255 case R_LARCH_PCALA_HI20:
2256 case R_LARCH_PCALA_LO12:
2257 case R_LARCH_PCALA64_LO20:
2258 case R_LARCH_PCALA64_HI12:
2259 case R_LARCH_GOT_PC_HI20:
2260 case R_LARCH_GOT_PC_LO12:
2261 case R_LARCH_GOT64_PC_LO20:
2262 case R_LARCH_GOT64_PC_HI12:
2263 case R_LARCH_GOT_HI20:
2264 case R_LARCH_GOT_LO12:
2265 case R_LARCH_GOT64_LO20:
2266 case R_LARCH_GOT64_HI12:
2267 case R_LARCH_TLS_LE_HI20:
2268 case R_LARCH_TLS_LE_LO12:
aae8784c 2269 case R_LARCH_TLS_LE_HI20_R:
2270 case R_LARCH_TLS_LE_LO12_R:
6d13722a 2271 case R_LARCH_TLS_LE64_LO20:
2272 case R_LARCH_TLS_LE64_HI12:
2273 case R_LARCH_TLS_IE_PC_HI20:
2274 case R_LARCH_TLS_IE_PC_LO12:
2275 case R_LARCH_TLS_IE64_PC_LO20:
2276 case R_LARCH_TLS_IE64_PC_HI12:
2277 case R_LARCH_TLS_IE_HI20:
2278 case R_LARCH_TLS_IE_LO12:
2279 case R_LARCH_TLS_IE64_LO20:
2280 case R_LARCH_TLS_IE64_HI12:
2281 case R_LARCH_TLS_LD_PC_HI20:
2282 case R_LARCH_TLS_LD_HI20:
2283 case R_LARCH_TLS_GD_PC_HI20:
2284 case R_LARCH_TLS_GD_HI20:
1b6fccd2 2285 case R_LARCH_PCREL20_S2:
dc5f359e 2286 case R_LARCH_CALL36:
4f248d61
LC
2287 case R_LARCH_TLS_DESC_PC_HI20:
2288 case R_LARCH_TLS_DESC_PC_LO12:
2289 case R_LARCH_TLS_DESC64_PC_LO20:
2290 case R_LARCH_TLS_DESC64_PC_HI12:
2291 case R_LARCH_TLS_DESC_HI20:
2292 case R_LARCH_TLS_DESC_LO12:
2293 case R_LARCH_TLS_DESC64_LO20:
2294 case R_LARCH_TLS_DESC64_HI12:
ae296cc4 2295 case R_LARCH_TLS_LD_PCREL20_S2:
2296 case R_LARCH_TLS_GD_PCREL20_S2:
2297 case R_LARCH_TLS_DESC_PCREL20_S2:
6d13722a 2298 r = loongarch_check_offset (rel, input_section);
2299 if (r != bfd_reloc_ok)
2300 break;
2301
2302 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2303 howto, input_bfd,
2304 contents, value);
2305 break;
2306
4f248d61
LC
2307 case R_LARCH_TLS_DESC_LD:
2308 case R_LARCH_TLS_DESC_CALL:
2309 r = bfd_reloc_ok;
2310 break;
2311
6d13722a 2312 case R_LARCH_RELAX:
aae8784c 2313 case R_LARCH_TLS_LE_ADD_R:
6d13722a 2314 break;
2315
e214f8db 2316 default:
2317 r = bfd_reloc_notsupported;
2318 }
2319 return r;
2320}
2321
2322#define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2323static struct
2324{
2325 bfd *bfd;
2326 asection *section;
2327 bfd_vma r_offset;
2328 int r_type;
2329 bfd_vma relocation;
2330 Elf_Internal_Sym *sym;
2331 struct elf_link_hash_entry *h;
2332 bfd_vma addend;
2333 int64_t top_then;
2334} larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2335static size_t larch_reloc_queue_head = 0;
2336static size_t larch_reloc_queue_tail = 0;
2337
2338static const char *
2339loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2340 Elf_Internal_Sym *sym)
2341{
2342 const char *ret = NULL;
2343 if (sym)
2344 ret = bfd_elf_string_from_elf_section (input_bfd,
2345 elf_symtab_hdr (input_bfd).sh_link,
2346 sym->st_name);
2347 else if (h)
2348 ret = h->root.root.string;
2349
2350 if (ret == NULL || *ret == '\0')
2351 ret = "<nameless>";
2352 return ret;
2353}
2354
2355static void
2356loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2357 bfd_vma r_offset, Elf_Internal_Sym *sym,
2358 struct elf_link_hash_entry *h, bfd_vma addend)
2359{
2360 if ((larch_reloc_queue_head == 0
2361 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2362 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2363 larch_reloc_queue_head =
2364 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2365 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2366 larch_reloc_queue[larch_reloc_queue_tail].section = section;
2367 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2368 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2369 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2370 larch_reloc_queue[larch_reloc_queue_tail].h = h;
2371 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2372 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2373 larch_reloc_queue_tail =
2374 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2375}
2376
2377static void
2378loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2379{
2380 size_t i = larch_reloc_queue_head;
2381 bfd *a_bfd = NULL;
2382 asection *section = NULL;
2383 bfd_vma r_offset = 0;
2384 int inited = 0;
2385 p ("Dump relocate record:\n");
2386 p ("stack top\t\trelocation name\t\tsymbol");
2387 while (i != larch_reloc_queue_tail)
2388 {
2389 if (a_bfd != larch_reloc_queue[i].bfd
2390 || section != larch_reloc_queue[i].section
2391 || r_offset != larch_reloc_queue[i].r_offset)
2392 {
2393 a_bfd = larch_reloc_queue[i].bfd;
2394 section = larch_reloc_queue[i].section;
2395 r_offset = larch_reloc_queue[i].r_offset;
2396 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2397 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2398 }
2399
2400 if (!inited)
2401 inited = 1, p ("...\n");
2402
2403 reloc_howto_type *howto =
2404 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2405 larch_reloc_queue[i].r_type);
2406 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2407 howto ? howto->name : "<unknown reloc>",
2408 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2409 larch_reloc_queue[i].sym));
2410
2411 long addend = larch_reloc_queue[i].addend;
2412 if (addend < 0)
2413 p (" - %ld", -addend);
2414 else if (0 < addend)
2415 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2416
2417 p ("\n");
2418 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2419 }
2420 p ("\n"
2421 "-- Record dump end --\n\n");
2422}
2423
e214f8db 2424static bool
2425loongarch_reloc_is_fatal (struct bfd_link_info *info,
2426 bfd *input_bfd,
2427 asection *input_section,
2428 Elf_Internal_Rela *rel,
2429 reloc_howto_type *howto,
2430 bfd_reloc_status_type rtype,
2431 bool is_undefweak,
2432 const char *name,
2433 const char *msg)
2434{
2435 bool fatal = true;
2436 switch (rtype)
2437 {
2438 /* 'dangerous' means we do it but can't promise it's ok
2439 'unsupport' means out of ability of relocation type
2440 'undefined' means we can't deal with the undefined symbol. */
2441 case bfd_reloc_undefined:
2442 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2443 rel->r_offset, true);
2444 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2445 input_bfd, input_section, rel->r_offset,
2446 howto->name,
2447 is_undefweak ? "[undefweak] " : "", name, msg);
2448 break;
2449 case bfd_reloc_dangerous:
2450 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2451 input_bfd, input_section, rel->r_offset,
2452 howto->name,
2453 is_undefweak ? "[undefweak] " : "", name, msg);
2454 fatal = false;
2455 break;
2456 case bfd_reloc_notsupported:
2457 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2458 input_bfd, input_section, rel->r_offset,
2459 howto->name,
2460 is_undefweak ? "[undefweak] " : "", name, msg);
2461 break;
2462 default:
2463 break;
2464 }
2465 return fatal;
2466}
2467
378535f2 2468/* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2469 hi20 immediate need to add 0x1.
2470 For example: pc 0x120000000, symbol 0x120000812
2471 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2472 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2473 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2474
2475 At run:
2476 pcalau12i $t0, hi20 (0x1)
2477 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2478 addi.d $t0, $t0, lo12 (0x812)
2479 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2480 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2481 = 0x120000812
2482 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2483 error.
2484 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
6d13722a 2485#define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2486 ({ \
1b6fccd2 2487 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
378535f2 2488 relocation = (relocation & ~(bfd_vma)0xfff) \
2489 - (pc & ~(bfd_vma)0xfff); \
1b6fccd2 2490 if (__lo > 0x7ff) \
6d13722a 2491 relocation += 0x1000; \
6d13722a 2492 })
2493
aae8784c 2494/* Handle problems caused by symbol extensions in TLS LE, The processing
2495 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
2496#define RELOCATE_TLS_TP32_HI20(relocation) \
2497 ({ \
2498 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2499 if (__lo > 0x7ff) \
2500 relocation += 0x800; \
2501 relocation = relocation & ~(bfd_vma)0xfff; \
2502 })
2503
378535f2 2504/* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2505 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2506 = 0x712347ffff000
2507 lo12: 0x1812348ffff812 & 0xfff = 0x812
2508 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2509 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2510 hi12: 0x0
2511
2512 pcalau12i $t1, hi20 (0x80000)
2513 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2514 = 0x11000010000100 + 0xffffffff80000000
2515 = 0x10ffff90000000
2516 addi.d $t0, $zero, lo12 (0x812)
2517 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2518 lo20 need to sub 0x1)
85ad846e 2519 lu32i.d $t0, lo20 (0x71234)
378535f2 2520 $t0 = {0x71234, 0xfffff812}
2521 = 0x71234fffff812
2522 lu52i.d $t0, hi12 (0x0)
2523 $t0 = {0x0, 0x71234fffff812}
2524 = 0x71234fffff812
2525 add.d $t1, $t1, $t0
2526 $t1 = 0x10ffff90000000 + 0x71234fffff812
2527 = 0x1812348ffff812. */
6d13722a 2528#define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2529 ({ \
378535f2 2530 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2531 relocation = (relocation & ~(bfd_vma)0xfff) \
2532 - (pc & ~(bfd_vma)0xfff); \
1b6fccd2 2533 if (__lo > 0x7ff) \
378535f2 2534 relocation += (0x1000 - 0x100000000); \
2535 if (relocation & 0x80000000) \
2536 relocation += 0x100000000; \
6d13722a 2537 })
e214f8db 2538
3898e04b
LC
2539/* Transition instruction sequence to relax instruction sequence. */
2540static bool
2541loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
2542 int r_type, struct elf_link_hash_entry *h,
2543 struct bfd_link_info *info)
2544{
2545 bool local_exec = bfd_link_executable (info)
2546 && SYMBOL_REFERENCES_LOCAL (info, h);
2547 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
2548 unsigned long insn;
2549
2550 switch (r_type)
2551 {
2552 case R_LARCH_TLS_DESC_PC_HI20:
2553 if (local_exec)
2554 /* DESC -> LE relaxation:
2555 pcalalau12i $a0,%desc_pc_hi20(var) =>
2556 lu12i.w $a0,%le_hi20(var)
2557 */
2558 bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
2559 contents + rel->r_offset);
2560
2561 /* DESC -> IE relaxation:
2562 pcalalau12i $a0,%desc_pc_hi20(var) =>
2563 pcalalau12i $a0,%ie_pc_hi20(var)
2564 */
2565 return true;
2566
2567 case R_LARCH_TLS_DESC_PC_LO12:
2568 if (local_exec)
2569 {
2570 /* DESC -> LE relaxation:
2571 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2572 ori $a0,$a0,le_lo12(var)
2573 */
2574 insn = LARCH_ORI | LARCH_RD_RJ_A0;
2575 bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
2576 contents + rel->r_offset);
2577 }
2578 else
2579 {
2580 /* DESC -> IE relaxation:
2581 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2582 ld.d $a0,$a0,%%ie_pc_lo12
2583 */
2584 bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
2585 contents + rel->r_offset);
2586 }
2587 return true;
2588
2589 case R_LARCH_TLS_DESC_LD:
2590 case R_LARCH_TLS_DESC_CALL:
2591 /* DESC -> LE/IE relaxation:
2592 ld.d $ra,$a0,%desc_ld(var) => NOP
2593 jirl $ra,$ra,%desc_call(var) => NOP
2594 */
2595 bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
2596 return true;
2597
2598 case R_LARCH_TLS_IE_PC_HI20:
2599 if (local_exec)
2600 {
2601 /* IE -> LE relaxation:
2602 pcalalau12i $rd,%ie_pc_hi20(var) =>
2603 lu12i.w $rd,%le_hi20(var)
2604 */
2605 insn = bfd_getl32 (contents + rel->r_offset);
2606 bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
2607 contents + rel->r_offset);
2608 }
2609 return true;
2610
2611 case R_LARCH_TLS_IE_PC_LO12:
2612 if (local_exec)
2613 {
2614 /* IE -> LE relaxation:
2615 ld.d $rd,$rj,%%ie_pc_lo12 =>
2616 ori $rd,$rj,le_lo12(var)
2617 */
2618 insn = bfd_getl32 (contents + rel->r_offset);
2619 bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
2620 contents + rel->r_offset);
2621 }
2622 return true;
2623 }
2624
2625 return false;
2626}
2627
2628
e214f8db 2629static int
2630loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2631 bfd *input_bfd, asection *input_section,
2632 bfd_byte *contents, Elf_Internal_Rela *relocs,
2633 Elf_Internal_Sym *local_syms,
2634 asection **local_sections)
2635{
2636 Elf_Internal_Rela *rel;
2637 Elf_Internal_Rela *relend;
2638 bool fatal = false;
2639 asection *sreloc = elf_section_data (input_section)->sreloc;
2640 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2641 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2642 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2643 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2644 bool is_pic = bfd_link_pic (info);
2645 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2646 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2647 asection *got = htab->elf.sgot;
2648
2649 relend = relocs + input_section->reloc_count;
2650 for (rel = relocs; rel < relend; rel++)
2651 {
3898e04b 2652 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
e214f8db 2653 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2654 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2655 reloc_howto_type *howto = NULL;
2656 asection *sec = NULL;
2657 Elf_Internal_Sym *sym = NULL;
2658 struct elf_link_hash_entry *h = NULL;
2659 const char *name;
2660 bfd_reloc_status_type r = bfd_reloc_ok;
4f248d61 2661 bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
3898e04b 2662 unsigned int relaxed_r_type;
e214f8db 2663 bool resolved_local, resolved_dynly, resolved_to_const;
2664 char tls_type;
4f248d61 2665 bfd_vma relocation, off, ie_off, desc_off;
e214f8db 2666 int i, j;
2667
2668 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2669 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2670 || r_type == R_LARCH_GNU_VTENTRY)
2671 continue;
2672
2673 /* This is a final link. */
2674 if (r_symndx < symtab_hdr->sh_info)
2675 {
2676 is_undefweak = false;
2677 unresolved_reloc = false;
2678 sym = local_syms + r_symndx;
2679 sec = local_sections[r_symndx];
2680 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2681
2682 /* Relocate against local STT_GNU_IFUNC symbol. */
2683 if (!bfd_link_relocatable (info)
2684 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2685 {
2686 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2687 false);
2688 if (h == NULL)
2689 abort ();
2690
2691 /* Set STT_GNU_IFUNC symbol value. */
2692 h->root.u.def.value = sym->st_value;
2693 h->root.u.def.section = sec;
2694 }
2695 defined_local = true;
2696 resolved_local = true;
2697 resolved_dynly = false;
2698 resolved_to_const = false;
6d13722a 2699
2700 /* Calc in funtion elf_link_input_bfd,
2701 * if #define elf_backend_rela_normal to 1. */
e214f8db 2702 if (bfd_link_relocatable (info)
2703 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6d13722a 2704 continue;
e214f8db 2705 }
2706 else
2707 {
2708 bool warned, ignored;
2709
2710 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2711 r_symndx, symtab_hdr, sym_hashes,
2712 h, sec, relocation,
2713 unresolved_reloc, warned, ignored);
2714 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2715
2716 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2717 symbol. And 'dynamic_undefined_weak' specify what to do when
2718 meeting undefweak. */
2719
2720 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2721 {
2722 defined_local = false;
2723 resolved_local = false;
2724 resolved_to_const = (!is_dyn || h->dynindx == -1
2725 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2726 resolved_dynly = !resolved_local && !resolved_to_const;
2727 }
2728 else if (warned)
2729 {
2730 /* Symbol undefined offen means failed already. I don't know why
2731 'warned' here but I guess it want to continue relocating as if
2732 no error occures to find other errors as more as possible. */
2733
2734 /* To avoid generating warning messages about truncated
2735 relocations, set the relocation's address to be the same as
2736 the start of this section. */
2737 relocation = (input_section->output_section
2738 ? input_section->output_section->vma
2739 : 0);
2740
2741 defined_local = relocation != 0;
2742 resolved_local = defined_local;
2743 resolved_to_const = !resolved_local;
2744 resolved_dynly = false;
2745 }
2746 else
2747 {
2748 defined_local = !unresolved_reloc && !ignored;
2749 resolved_local =
2750 defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2751 resolved_dynly = !resolved_local;
2752 resolved_to_const = !resolved_local && !resolved_dynly;
2753 }
2754 }
2755
2756 name = loongarch_sym_name (input_bfd, h, sym);
2757
2758 if (sec != NULL && discarded_section (sec))
2759 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2760 1, relend, howto, 0, contents);
2761
2762 if (bfd_link_relocatable (info))
2763 continue;
2764
2765 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2766 from removed linkonce sections, or sections discarded by a linker
2767 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2768 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2769 {
2770 defined_local = false;
2771 resolved_local = false;
2772 resolved_dynly = false;
2773 resolved_to_const = true;
2774 }
2775
6d13722a 2776 /* The ifunc reference generate plt. */
d218dba3 2777 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
e214f8db 2778 {
e214f8db 2779 defined_local = true;
2780 resolved_local = true;
2781 resolved_dynly = false;
2782 resolved_to_const = false;
2783 relocation = sec_addr (plt) + h->plt.offset;
2784 }
2785
2786 unresolved_reloc = resolved_dynly;
2787
2788 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2789
d218dba3 2790 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
e214f8db 2791
2792 BFD_ASSERT (!resolved_local || defined_local);
2793
3898e04b
LC
2794 relaxed_r_type = loongarch_tls_transition (info, r_type, h, input_bfd, r_symndx);
2795 if (relaxed_r_type != r_type)
2796 {
2797 howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type);
2798 BFD_ASSERT (howto != NULL);
2799
2800 if (loongarch_tls_relax (input_bfd, input_section, rel, r_type, h, info))
2801 r_type = relaxed_r_type;
2802 }
2803
4f248d61 2804 is_desc = false;
e214f8db 2805 is_ie = false;
2806 switch (r_type)
2807 {
2808 case R_LARCH_MARK_PCREL:
2809 case R_LARCH_MARK_LA:
2810 case R_LARCH_NONE:
2811 r = bfd_reloc_continue;
2812 unresolved_reloc = false;
2813 break;
2814
2815 case R_LARCH_32:
2816 case R_LARCH_64:
2817 if (resolved_dynly || (is_pic && resolved_local))
2818 {
2819 Elf_Internal_Rela outrel;
2820
2821 /* When generating a shared object, these relocations are copied
2822 into the output file to be resolved at run time. */
2823
2824 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2825 input_section,
2826 rel->r_offset);
2827
2828 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2829 && (input_section->flags & SEC_ALLOC));
2830
2831 outrel.r_offset += sec_addr (input_section);
d218dba3 2832
bc2a35c0 2833 /* A pointer point to a ifunc symbol. */
2834 if (h && h->type == STT_GNU_IFUNC)
d218dba3 2835 {
bc2a35c0 2836 if (h->dynindx == -1)
2837 {
2838 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2839 outrel.r_addend = (h->root.u.def.value
2840 + h->root.u.def.section->output_section->vma
2841 + h->root.u.def.section->output_offset);
2842 }
2843 else
2844 {
2845 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2846 outrel.r_addend = 0;
2847 }
d218dba3 2848
bc2a35c0 2849 if (SYMBOL_REFERENCES_LOCAL (info, h))
2850 {
2851
2852 if (htab->elf.splt != NULL)
2853 sreloc = htab->elf.srelgot;
2854 else
2855 sreloc = htab->elf.irelplt;
2856 }
d218dba3 2857 else
bc2a35c0 2858 {
2859
2860 if (bfd_link_pic (info))
2861 sreloc = htab->elf.irelifunc;
2862 else if (htab->elf.splt != NULL)
2863 sreloc = htab->elf.srelgot;
2864 else
2865 sreloc = htab->elf.irelplt;
2866 }
d218dba3 2867 }
2868 else if (resolved_dynly)
e214f8db 2869 {
6d13722a 2870 if (h->dynindx == -1)
2871 {
2872 if (h->root.type == bfd_link_hash_undefined)
2873 (*info->callbacks->undefined_symbol)
2874 (info, name, input_bfd, input_section,
2875 rel->r_offset, true);
2876
2877 outrel.r_info = ELFNN_R_INFO (0, r_type);
2878 }
2879 else
2880 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2881
e214f8db 2882 outrel.r_addend = rel->r_addend;
2883 }
2884 else
2885 {
2886 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2887 outrel.r_addend = relocation + rel->r_addend;
2888 }
2889
6d13722a 2890 /* No alloc space of func allocate_dynrelocs. */
2891 if (unresolved_reloc
2892 && !(h && (h->is_weakalias || !h->dyn_relocs)))
e214f8db 2893 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2894 }
2895
2896 relocation += rel->r_addend;
2897 break;
2898
1b6fccd2 2899 case R_LARCH_ADD6:
e214f8db 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:
1b6fccd2 2905 {
2906 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2907 contents + rel->r_offset);
2908 relocation = old_value + relocation + rel->r_addend;
2909 break;
2910 }
2911
2912 case R_LARCH_SUB6:
e214f8db 2913 case R_LARCH_SUB8:
2914 case R_LARCH_SUB16:
2915 case R_LARCH_SUB24:
2916 case R_LARCH_SUB32:
2917 case R_LARCH_SUB64:
1b6fccd2 2918 {
2919 bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2920 contents + rel->r_offset);
2921 relocation = old_value - relocation - rel->r_addend;
2922 break;
2923 }
2924
2925 case R_LARCH_ADD_ULEB128:
2926 case R_LARCH_SUB_ULEB128:
2927 {
2928 /* Get the value and length of the uleb128 data. */
2929 unsigned int len = 0;
2930 bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2931 contents + rel->r_offset, &len);
2932
2933 if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2934 relocation = old_value + relocation + rel->r_addend;
2935 else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2936 relocation = old_value - relocation - rel->r_addend;
2937
2938 bfd_vma mask = (1 << (7 * len)) - 1;
2939 relocation &= mask;
2940 break;
2941 }
e214f8db 2942
2943 case R_LARCH_TLS_DTPREL32:
2944 case R_LARCH_TLS_DTPREL64:
2945 if (resolved_dynly)
2946 {
2947 Elf_Internal_Rela outrel;
2948
2949 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2950 input_section,
2951 rel->r_offset);
2952 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2953 && (input_section->flags & SEC_ALLOC));
2954 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2955 outrel.r_offset += sec_addr (input_section);
2956 outrel.r_addend = rel->r_addend;
2957 if (unresolved_reloc)
2958 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2959 break;
2960 }
2961
2962 if (resolved_to_const)
2963 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2964 rel, howto,
2965 bfd_reloc_notsupported,
2966 is_undefweak, name,
2967 "Internal:");
d218dba3 2968 if (resolved_local)
2969 {
2970 if (!elf_hash_table (info)->tls_sec)
2971 {
2972 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2973 input_section, rel, howto, bfd_reloc_notsupported,
2974 is_undefweak, name, "TLS section not be created");
2975 }
2976 else
2977 relocation -= elf_hash_table (info)->tls_sec->vma;
2978 }
2979 else
2980 {
2981 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2982 input_section, rel, howto, bfd_reloc_undefined,
2983 is_undefweak, name,
2984 "TLS LE just can be resolved local only.");
2985 }
2986
e214f8db 2987 break;
2988
2989 case R_LARCH_SOP_PUSH_TLS_TPREL:
2990 if (resolved_local)
2991 {
2992 if (!elf_hash_table (info)->tls_sec)
2993 fatal = (loongarch_reloc_is_fatal
2994 (info, input_bfd, input_section, rel, howto,
2995 bfd_reloc_notsupported, is_undefweak, name,
2996 "TLS section not be created"));
2997 else
2998 relocation -= elf_hash_table (info)->tls_sec->vma;
2999 }
3000 else
3001 fatal = (loongarch_reloc_is_fatal
3002 (info, input_bfd, input_section, rel, howto,
3003 bfd_reloc_undefined, is_undefweak, name,
3004 "TLS LE just can be resolved local only."));
3005 break;
3006
3007 case R_LARCH_SOP_PUSH_ABSOLUTE:
3008 if (is_undefweak)
3009 {
3010 if (resolved_dynly)
3011 fatal = (loongarch_reloc_is_fatal
3012 (info, input_bfd, input_section, rel, howto,
3013 bfd_reloc_dangerous, is_undefweak, name,
3014 "Someone require us to resolve undefweak "
3015 "symbol dynamically. \n"
3016 "But this reloc can't be done. "
3017 "I think I can't throw error "
3018 "for this\n"
3019 "so I resolved it to 0. "
3020 "I suggest to re-compile with '-fpic'."));
3021
3022 relocation = 0;
3023 unresolved_reloc = false;
3024 break;
3025 }
3026
3027 if (resolved_to_const)
3028 {
3029 relocation += rel->r_addend;
3030 break;
3031 }
3032
3033 if (is_pic)
3034 {
3035 fatal = (loongarch_reloc_is_fatal
3036 (info, input_bfd, input_section, rel, howto,
3037 bfd_reloc_notsupported, is_undefweak, name,
3038 "Under PIC we don't know load address. Re-compile "
3039 "with '-fpic'?"));
3040 break;
3041 }
3042
3043 if (resolved_dynly)
3044 {
3045 if (!(plt && h && h->plt.offset != MINUS_ONE))
3046 {
3047 fatal = (loongarch_reloc_is_fatal
3048 (info, input_bfd, input_section, rel, howto,
3049 bfd_reloc_undefined, is_undefweak, name,
3050 "Can't be resolved dynamically. Try to re-compile "
3051 "with '-fpic'?"));
3052 break;
3053 }
3054
3055 if (rel->r_addend != 0)
3056 {
3057 fatal = (loongarch_reloc_is_fatal
3058 (info, input_bfd, input_section, rel, howto,
3059 bfd_reloc_notsupported, is_undefweak, name,
3060 "Shouldn't be with r_addend."));
3061 break;
3062 }
3063
3064 relocation = sec_addr (plt) + h->plt.offset;
3065 unresolved_reloc = false;
3066 break;
3067 }
3068
3069 if (resolved_local)
3070 {
3071 relocation += rel->r_addend;
3072 break;
3073 }
3074
3075 break;
3076
3077 case R_LARCH_SOP_PUSH_PCREL:
3078 case R_LARCH_SOP_PUSH_PLT_PCREL:
3079 unresolved_reloc = false;
3080
6d13722a 3081 if (is_undefweak)
e214f8db 3082 {
3083 i = 0, j = 0;
3084 relocation = 0;
3085 if (resolved_dynly)
3086 {
3087 if (h && h->plt.offset != MINUS_ONE)
3088 i = 1, j = 2;
3089 else
3090 fatal = (loongarch_reloc_is_fatal
3091 (info, input_bfd, input_section, rel, howto,
3092 bfd_reloc_dangerous, is_undefweak, name,
3093 "Undefweak need to be resolved dynamically, "
3094 "but PLT stub doesn't represent."));
3095 }
3096 }
3097 else
3098 {
3099 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
3100 {
3101 fatal = (loongarch_reloc_is_fatal
3102 (info, input_bfd, input_section, rel, howto,
3103 bfd_reloc_undefined, is_undefweak, name,
3104 "PLT stub does not represent and "
3105 "symbol not defined."));
3106 break;
3107 }
3108
3109 if (resolved_local)
3110 i = 0, j = 2;
3111 else /* if (resolved_dynly) */
3112 {
3113 if (!(h && h->plt.offset != MINUS_ONE))
3114 fatal = (loongarch_reloc_is_fatal
3115 (info, input_bfd, input_section, rel, howto,
3116 bfd_reloc_dangerous, is_undefweak, name,
3117 "Internal: PLT stub doesn't represent. "
3118 "Resolve it with pcrel"));
3119 i = 1, j = 3;
3120 }
3121 }
3122
3123 for (; i < j; i++)
3124 {
3125 if ((i & 1) == 0 && defined_local)
3126 {
3127 relocation -= pc;
3128 relocation += rel->r_addend;
3129 break;
3130 }
3131
3132 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
3133 {
3134 if (rel->r_addend != 0)
3135 {
3136 fatal = (loongarch_reloc_is_fatal
3137 (info, input_bfd, input_section, rel, howto,
3138 bfd_reloc_notsupported, is_undefweak, name,
3139 "PLT shouldn't be with r_addend."));
3140 break;
3141 }
3142 relocation = sec_addr (plt) + h->plt.offset - pc;
3143 break;
3144 }
3145 }
3146 break;
3147
3148 case R_LARCH_SOP_PUSH_GPREL:
3149 unresolved_reloc = false;
3150
3151 if (rel->r_addend != 0)
3152 {
3153 fatal = (loongarch_reloc_is_fatal
3154 (info, input_bfd, input_section, rel, howto,
3155 bfd_reloc_notsupported, is_undefweak, name,
3156 "Shouldn't be with r_addend."));
3157 break;
3158 }
3159
3160 if (h != NULL)
3161 {
6d13722a 3162 off = h->got.offset & (~1);
e214f8db 3163
6d13722a 3164 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
e214f8db 3165 {
3166 fatal = (loongarch_reloc_is_fatal
3167 (info, input_bfd, input_section, rel, howto,
3168 bfd_reloc_notsupported, is_undefweak, name,
3169 "Internal: GOT entry doesn't represent."));
3170 break;
3171 }
3172
d218dba3 3173 /* Hidden symbol not has .got entry, only .got.plt entry
3174 so gprel is (plt - got). */
6d13722a 3175 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
d218dba3 3176 {
3177 if (h->plt.offset == (bfd_vma) -1)
3178 {
3179 abort();
3180 }
3181
3182 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3183 off = plt_index * GOT_ENTRY_SIZE;
3184
3185 if (htab->elf.splt != NULL)
3186 {
3187 /* Section .plt header is 2 times of plt entry. */
6d13722a 3188 off = sec_addr (htab->elf.sgotplt) + off
3189 - sec_addr (htab->elf.sgot);
d218dba3 3190 }
3191 else
3192 {
3193 /* Section iplt not has plt header. */
6d13722a 3194 off = sec_addr (htab->elf.igotplt) + off
3195 - sec_addr (htab->elf.sgot);
d218dba3 3196 }
3197 }
3198
6d13722a 3199 if ((h->got.offset & 1) == 0)
e214f8db 3200 {
6d13722a 3201 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3202 bfd_link_pic (info), h)
3203 && ((bfd_link_pic (info)
3204 && SYMBOL_REFERENCES_LOCAL (info, h))))
e214f8db 3205 {
6d13722a 3206 /* This is actually a static link, or it is a
3207 -Bsymbolic link and the symbol is defined
3208 locally, or the symbol was forced to be local
3209 because of a version file. We must initialize
3210 this entry in the global offset table. Since the
3211 offset must always be a multiple of the word size,
3212 we use the least significant bit to record whether
3213 we have initialized it already.
3214
3215 When doing a dynamic link, we create a rela.got
3216 relocation entry to initialize the value. This
3217 is done in the finish_dynamic_symbol routine. */
3218
3219 if (resolved_dynly)
3220 {
3221 fatal = (loongarch_reloc_is_fatal
3222 (info, input_bfd, input_section, rel, howto,
3223 bfd_reloc_dangerous, is_undefweak, name,
3224 "Internal: here shouldn't dynamic."));
3225 }
e214f8db 3226
6d13722a 3227 if (!(defined_local || resolved_to_const))
3228 {
3229 fatal = (loongarch_reloc_is_fatal
3230 (info, input_bfd, input_section, rel, howto,
3231 bfd_reloc_undefined, is_undefweak, name,
3232 "Internal: "));
3233 break;
3234 }
e214f8db 3235
6d13722a 3236 asection *s;
3237 Elf_Internal_Rela outrel;
3238 /* We need to generate a R_LARCH_RELATIVE reloc
3239 for the dynamic linker. */
3240 s = htab->elf.srelgot;
3241 if (!s)
d218dba3 3242 {
6d13722a 3243 fatal = loongarch_reloc_is_fatal
3244 (info, input_bfd,
3245 input_section, rel, howto,
3246 bfd_reloc_notsupported, is_undefweak, name,
3247 "Internal: '.rel.got' not represent");
3248 break;
d218dba3 3249 }
6d13722a 3250
3251 outrel.r_offset = sec_addr (got) + off;
3252 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3253 outrel.r_addend = relocation; /* Link-time addr. */
3254 loongarch_elf_append_rela (output_bfd, s, &outrel);
e214f8db 3255 }
6d13722a 3256 bfd_put_NN (output_bfd, relocation, got->contents + off);
3257 h->got.offset |= 1;
e214f8db 3258 }
3259 }
3260 else
3261 {
3262 if (!local_got_offsets)
3263 {
3264 fatal = (loongarch_reloc_is_fatal
3265 (info, input_bfd, input_section, rel, howto,
3266 bfd_reloc_notsupported, is_undefweak, name,
3267 "Internal: local got offsets not reporesent."));
3268 break;
3269 }
3270
6d13722a 3271 off = local_got_offsets[r_symndx] & (~1);
e214f8db 3272
6d13722a 3273 if (local_got_offsets[r_symndx] == MINUS_ONE)
e214f8db 3274 {
3275 fatal = (loongarch_reloc_is_fatal
3276 (info, input_bfd, input_section, rel, howto,
3277 bfd_reloc_notsupported, is_undefweak, name,
3278 "Internal: GOT entry doesn't represent."));
3279 break;
3280 }
3281
3282 /* The offset must always be a multiple of the word size.
3283 So, we can use the least significant bit to record
3284 whether we have already processed this entry. */
8b4d46df 3285 if ((local_got_offsets[r_symndx] & 1) == 0)
e214f8db 3286 {
3287 if (is_pic)
3288 {
3289 asection *s;
3290 Elf_Internal_Rela outrel;
3291 /* We need to generate a R_LARCH_RELATIVE reloc
3292 for the dynamic linker. */
3293 s = htab->elf.srelgot;
3294 if (!s)
3295 {
3296 fatal = (loongarch_reloc_is_fatal
3297 (info, input_bfd, input_section, rel, howto,
3298 bfd_reloc_notsupported, is_undefweak, name,
3299 "Internal: '.rel.got' not represent"));
3300 break;
3301 }
3302
3303 outrel.r_offset = sec_addr (got) + off;
3304 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3305 outrel.r_addend = relocation; /* Link-time addr. */
3306 loongarch_elf_append_rela (output_bfd, s, &outrel);
3307 }
3308
3309 bfd_put_NN (output_bfd, relocation, got->contents + off);
3310 local_got_offsets[r_symndx] |= 1;
3311 }
3312 }
3313 relocation = off;
6d13722a 3314
e214f8db 3315 break;
3316
3317 case R_LARCH_SOP_PUSH_TLS_GOT:
3318 case R_LARCH_SOP_PUSH_TLS_GD:
6d13722a 3319 {
3320 unresolved_reloc = false;
3321 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3322 is_ie = true;
3323
3324 bfd_vma got_off = 0;
3325 if (h != NULL)
3326 {
3327 got_off = h->got.offset;
3328 h->got.offset |= 1;
3329 }
3330 else
3331 {
3332 got_off = local_got_offsets[r_symndx];
3333 local_got_offsets[r_symndx] |= 1;
3334 }
3335
3336 BFD_ASSERT (got_off != MINUS_ONE);
3337
3338 ie_off = 0;
3339 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3340 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3341 ie_off = 2 * GOT_ENTRY_SIZE;
3342
3343 if ((got_off & 1) == 0)
3344 {
3345 Elf_Internal_Rela rela;
3346 asection *srel = htab->elf.srelgot;
3347 bfd_vma tls_block_off = 0;
3348
3349 if (SYMBOL_REFERENCES_LOCAL (info, h))
3350 {
3351 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3352 tls_block_off = relocation
3353 - elf_hash_table (info)->tls_sec->vma;
3354 }
3355
3356 if (tls_type & GOT_TLS_GD)
3357 {
3358 rela.r_offset = sec_addr (got) + got_off;
3359 rela.r_addend = 0;
3360 if (SYMBOL_REFERENCES_LOCAL (info, h))
3361 {
3362 /* Local sym, used in exec, set module id 1. */
3363 if (bfd_link_executable (info))
3364 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3365 else
3366 {
3367 rela.r_info = ELFNN_R_INFO (0,
3368 R_LARCH_TLS_DTPMODNN);
3369 loongarch_elf_append_rela (output_bfd, srel, &rela);
3370 }
3371
3372 bfd_put_NN (output_bfd, tls_block_off,
3373 got->contents + got_off + GOT_ENTRY_SIZE);
3374 }
3375 /* Dynamic resolved. */
3376 else
3377 {
3378 /* Dynamic relocate module id. */
3379 rela.r_info = ELFNN_R_INFO (h->dynindx,
3380 R_LARCH_TLS_DTPMODNN);
3381 loongarch_elf_append_rela (output_bfd, srel, &rela);
3382
3383 /* Dynamic relocate offset of block. */
3384 rela.r_offset += GOT_ENTRY_SIZE;
3385 rela.r_info = ELFNN_R_INFO (h->dynindx,
3386 R_LARCH_TLS_DTPRELNN);
3387 loongarch_elf_append_rela (output_bfd, srel, &rela);
3388 }
3389 }
3390 if (tls_type & GOT_TLS_IE)
3391 {
3392 rela.r_offset = sec_addr (got) + got_off + ie_off;
3393 if (SYMBOL_REFERENCES_LOCAL (info, h))
3394 {
3395 /* Local sym, used in exec, set module id 1. */
3396 if (!bfd_link_executable (info))
3397 {
3398 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3399 rela.r_addend = tls_block_off;
3400 loongarch_elf_append_rela (output_bfd, srel, &rela);
3401 }
3402
3403 bfd_put_NN (output_bfd, tls_block_off,
3404 got->contents + got_off + ie_off);
3405 }
3406 /* Dynamic resolved. */
3407 else
3408 {
3409 /* Dynamic relocate offset of block. */
3410 rela.r_info = ELFNN_R_INFO (h->dynindx,
3411 R_LARCH_TLS_TPRELNN);
3412 rela.r_addend = 0;
3413 loongarch_elf_append_rela (output_bfd, srel, &rela);
3414 }
3415 }
3416 }
3417
3418 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3419 }
3420 break;
3421
3422 /* New reloc types. */
dc5f359e 3423 case R_LARCH_B16:
6d13722a 3424 case R_LARCH_B21:
3425 case R_LARCH_B26:
dc5f359e 3426 case R_LARCH_CALL36:
e214f8db 3427 unresolved_reloc = false;
6d13722a 3428 if (is_undefweak)
3429 {
3430 relocation = 0;
3431 }
e214f8db 3432
6d13722a 3433 if (resolved_local)
e214f8db 3434 {
6d13722a 3435 relocation -= pc;
3436 relocation += rel->r_addend;
3437 }
3438 else if (resolved_dynly)
3439 {
3440 BFD_ASSERT (h
3441 && (h->plt.offset != MINUS_ONE
3442 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3443 && rel->r_addend == 0);
3444 if (h && h->plt.offset == MINUS_ONE
3445 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3446 {
3447 relocation -= pc;
3448 relocation += rel->r_addend;
3449 }
3450 else
3451 relocation = sec_addr (plt) + h->plt.offset - pc;
3452 }
3453
3454 break;
3455
3456 case R_LARCH_ABS_HI20:
3457 case R_LARCH_ABS_LO12:
3458 case R_LARCH_ABS64_LO20:
3459 case R_LARCH_ABS64_HI12:
3460 BFD_ASSERT (!is_pic);
3461
3462 if (is_undefweak)
3463 {
3464 BFD_ASSERT (resolved_dynly);
3465 relocation = 0;
e214f8db 3466 break;
3467 }
6d13722a 3468 else if (resolved_to_const || resolved_local)
3469 {
3470 relocation += rel->r_addend;
3471 }
3472 else if (resolved_dynly)
3473 {
3474 unresolved_reloc = false;
3475 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3476 && rel->r_addend == 0);
3477 relocation = sec_addr (plt) + h->plt.offset;
3478 }
3479
3480 break;
3481
1b6fccd2 3482 case R_LARCH_PCREL20_S2:
3483 unresolved_reloc = false;
3484 if (h && h->plt.offset != MINUS_ONE)
3485 relocation = sec_addr (plt) + h->plt.offset;
3486 else
3487 relocation += rel->r_addend;
3488 relocation -= pc;
3489 break;
3490
6d13722a 3491 case R_LARCH_PCALA_HI20:
3492 unresolved_reloc = false;
3493 if (h && h->plt.offset != MINUS_ONE)
3494 relocation = sec_addr (plt) + h->plt.offset;
3495 else
3496 relocation += rel->r_addend;
e214f8db 3497
6d13722a 3498 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3499
3500 break;
3501
aae8784c 3502 case R_LARCH_TLS_LE_HI20_R:
3503 relocation -= elf_hash_table (info)->tls_sec->vma;
3504
3505 RELOCATE_TLS_TP32_HI20 (relocation);
3506
3507 break;
3508
6d13722a 3509 case R_LARCH_PCALA_LO12:
3510 /* Not support if sym_addr in 2k page edge.
3511 pcalau12i pc_hi20 (sym_addr)
3512 ld.w/d pc_lo12 (sym_addr)
3513 ld.w/d pc_lo12 (sym_addr + x)
3514 ...
3515 can not calc correct address
3516 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3517
3518 if (h && h->plt.offset != MINUS_ONE)
3519 relocation = sec_addr (plt) + h->plt.offset;
3520 else
3521 relocation += rel->r_addend;
e214f8db 3522
27121f67
NC
3523 /* For 2G jump, generate pcalau12i, jirl. */
3524 /* If use jirl, turns to R_LARCH_B16. */
3525 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3526 if ((insn & 0x4c000000) == 0x4c000000)
e214f8db 3527 {
1b6fccd2 3528 relocation &= 0xfff;
3529 /* Signed extend. */
3530 relocation = (relocation ^ 0x800) - 0x800;
3531
27121f67
NC
3532 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3533 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
e214f8db 3534 }
6d13722a 3535 break;
e214f8db 3536
6d13722a 3537 case R_LARCH_PCALA64_LO20:
3538 case R_LARCH_PCALA64_HI12:
3539 if (h && h->plt.offset != MINUS_ONE)
bc2a35c0 3540 relocation = sec_addr (plt) + h->plt.offset;
6d13722a 3541 else
3542 relocation += rel->r_addend;
3543
3544 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3545
3546 break;
3547
3548 case R_LARCH_GOT_PC_HI20:
3549 case R_LARCH_GOT_HI20:
3550 /* Calc got offset. */
3551 {
3552 unresolved_reloc = false;
3553 BFD_ASSERT (rel->r_addend == 0);
3554
3555 bfd_vma got_off = 0;
3556 if (h != NULL)
3557 {
3558 /* GOT ref or ifunc. */
3559 BFD_ASSERT (h->got.offset != MINUS_ONE
3560 || h->type == STT_GNU_IFUNC);
3561
3562 got_off = h->got.offset & (~(bfd_vma)1);
3563 /* Hidden symbol not has got entry,
3564 * only got.plt entry so it is (plt - got). */
3565 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3566 {
3567 bfd_vma idx;
3568 if (htab->elf.splt != NULL)
3569 {
3570 idx = (h->plt.offset - PLT_HEADER_SIZE)
3571 / PLT_ENTRY_SIZE;
3572 got_off = sec_addr (htab->elf.sgotplt)
3573 + GOTPLT_HEADER_SIZE
3574 + (idx * GOT_ENTRY_SIZE)
3575 - sec_addr (htab->elf.sgot);
3576 }
3577 else
3578 {
3579 idx = h->plt.offset / PLT_ENTRY_SIZE;
3580 got_off = sec_addr (htab->elf.sgotplt)
3581 + (idx * GOT_ENTRY_SIZE)
3582 - sec_addr (htab->elf.sgot);
3583 }
3584 }
3585
3586 if ((h->got.offset & 1) == 0)
3587 {
3588 /* We need to generate a R_LARCH_RELATIVE reloc once
3589 * in loongarch_elf_finish_dynamic_symbol or now,
3590 * call finish_dyn && nopic
3591 * or !call finish_dyn && pic. */
3592 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3593 bfd_link_pic (info),
3594 h)
3595 && bfd_link_pic (info)
3596 && SYMBOL_REFERENCES_LOCAL (info, h))
3597 {
3598 Elf_Internal_Rela rela;
3599 rela.r_offset = sec_addr (got) + got_off;
3600 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3601 rela.r_addend = relocation;
3602 loongarch_elf_append_rela (output_bfd,
3603 htab->elf.srelgot, &rela);
3604 }
3605 h->got.offset |= 1;
6224a6c2
XR
3606 bfd_put_NN (output_bfd, relocation,
3607 got->contents + got_off);
6d13722a 3608 }
3609 }
3610 else
3611 {
3612 BFD_ASSERT (local_got_offsets
3613 && local_got_offsets[r_symndx] != MINUS_ONE);
3614
3615 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3616 if ((local_got_offsets[r_symndx] & 1) == 0)
3617 {
3618 if (bfd_link_pic (info))
3619 {
3620 Elf_Internal_Rela rela;
3621 rela.r_offset = sec_addr (got) + got_off;
3622 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3623 rela.r_addend = relocation;
3624 loongarch_elf_append_rela (output_bfd,
3625 htab->elf.srelgot, &rela);
3626 }
3627 local_got_offsets[r_symndx] |= 1;
3628 }
6224a6c2 3629 bfd_put_NN (output_bfd, relocation, got->contents + got_off);
6d13722a 3630 }
3631
6d13722a 3632 relocation = got_off + sec_addr (got);
3633 }
3634
3635 if (r_type == R_LARCH_GOT_PC_HI20)
3636 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3637
3638 break;
3639
3640 case R_LARCH_GOT_PC_LO12:
3641 case R_LARCH_GOT64_PC_LO20:
3642 case R_LARCH_GOT64_PC_HI12:
3643 case R_LARCH_GOT_LO12:
3644 case R_LARCH_GOT64_LO20:
3645 case R_LARCH_GOT64_HI12:
3646 {
3647 unresolved_reloc = false;
3648 bfd_vma got_off;
3649 if (h)
3650 got_off = h->got.offset & (~(bfd_vma)1);
3651 else
3652 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3653
3654 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3655 {
3656 bfd_vma idx;
3657 if (htab->elf.splt != NULL)
3658 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3659 else
3660 idx = h->plt.offset / PLT_ENTRY_SIZE;
3661
3662 got_off = sec_addr (htab->elf.sgotplt)
3663 + GOTPLT_HEADER_SIZE
3664 + (idx * GOT_ENTRY_SIZE)
3665 - sec_addr (htab->elf.sgot);
3666 }
1b6fccd2 3667
6d13722a 3668 relocation = got_off + sec_addr (got);
3669 }
3670
1b6fccd2 3671 if (r_type == R_LARCH_GOT64_PC_HI12
3672 || r_type == R_LARCH_GOT64_PC_LO20)
6d13722a 3673 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3674
3675 break;
3676
3677 case R_LARCH_TLS_LE_HI20:
3678 case R_LARCH_TLS_LE_LO12:
aae8784c 3679 case R_LARCH_TLS_LE_LO12_R:
6d13722a 3680 case R_LARCH_TLS_LE64_LO20:
3681 case R_LARCH_TLS_LE64_HI12:
3682 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3683
3684 relocation -= elf_hash_table (info)->tls_sec->vma;
3685 break;
3686
3687 /* TLS IE LD/GD process separately is troublesome.
3688 When a symbol is both ie and LD/GD, h->got.off |= 1
3689 make only one type be relocated. We must use
3690 h->got.offset |= 1 and h->got.offset |= 2
3691 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3692 (IE LD/GD and reusable GOT reloc) must change to
3693 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3694 as a tag.
3695 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3696 can be omitted. */
3697 case R_LARCH_TLS_IE_PC_HI20:
3698 case R_LARCH_TLS_IE_HI20:
3699 case R_LARCH_TLS_LD_PC_HI20:
3700 case R_LARCH_TLS_LD_HI20:
3701 case R_LARCH_TLS_GD_PC_HI20:
3702 case R_LARCH_TLS_GD_HI20:
4f248d61
LC
3703 case R_LARCH_TLS_DESC_PC_HI20:
3704 case R_LARCH_TLS_DESC_HI20:
ae296cc4 3705 case R_LARCH_TLS_LD_PCREL20_S2:
3706 case R_LARCH_TLS_GD_PCREL20_S2:
3707 case R_LARCH_TLS_DESC_PCREL20_S2:
6d13722a 3708 BFD_ASSERT (rel->r_addend == 0);
3709 unresolved_reloc = false;
3710
3711 if (r_type == R_LARCH_TLS_IE_PC_HI20
3712 || r_type == R_LARCH_TLS_IE_HI20)
3713 is_ie = true;
3714
4f248d61 3715 if (r_type == R_LARCH_TLS_DESC_PC_HI20
ae296cc4 3716 || r_type == R_LARCH_TLS_DESC_HI20
3717 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
4f248d61
LC
3718 is_desc = true;
3719
6d13722a 3720 bfd_vma got_off = 0;
e214f8db 3721 if (h != NULL)
3722 {
6d13722a 3723 got_off = h->got.offset;
e214f8db 3724 h->got.offset |= 1;
3725 }
3726 else
3727 {
6d13722a 3728 got_off = local_got_offsets[r_symndx];
e214f8db 3729 local_got_offsets[r_symndx] |= 1;
3730 }
3731
6d13722a 3732 BFD_ASSERT (got_off != MINUS_ONE);
e214f8db 3733
6d13722a 3734 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
4f248d61
LC
3735
3736 /* If a tls variable is accessed in multiple ways, GD uses
3737 the first two slots of GOT, desc follows with two slots,
3738 and IE uses one slot at the end. */
3739 desc_off = 0;
3740 if (GOT_TLS_GD_BOTH_P (tls_type))
3741 desc_off = 2 * GOT_ENTRY_SIZE;
3742
3743 ie_off = 0;
3744 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3745 ie_off = 4 * GOT_ENTRY_SIZE;
3746 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
e214f8db 3747 ie_off = 2 * GOT_ENTRY_SIZE;
3748
6d13722a 3749 if ((got_off & 1) == 0)
e214f8db 3750 {
6d13722a 3751 Elf_Internal_Rela rela;
3752 asection *relgot = htab->elf.srelgot;
e214f8db 3753 bfd_vma tls_block_off = 0;
e214f8db 3754
6d13722a 3755 if (SYMBOL_REFERENCES_LOCAL (info, h))
e214f8db 3756 {
6d13722a 3757 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3758 tls_block_off = relocation
3759 - elf_hash_table (info)->tls_sec->vma;
e214f8db 3760 }
3761
3762 if (tls_type & GOT_TLS_GD)
3763 {
6d13722a 3764 rela.r_offset = sec_addr (got) + got_off;
3765 rela.r_addend = 0;
3766 if (SYMBOL_REFERENCES_LOCAL (info, h))
e214f8db 3767 {
6d13722a 3768 /* Local sym, used in exec, set module id 1. */
3769 if (bfd_link_executable (info))
3770 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3771 else
3772 {
3773 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3774 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3775 }
e214f8db 3776
6d13722a 3777 bfd_put_NN (output_bfd, tls_block_off,
3778 got->contents + got_off + GOT_ENTRY_SIZE);
3779 }
3780 /* Dynamic resolved. */
3781 else
e214f8db 3782 {
6d13722a 3783 /* Dynamic relocate module id. */
3784 rela.r_info = ELFNN_R_INFO (h->dynindx,
3785 R_LARCH_TLS_DTPMODNN);
3786 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3787
3788 /* Dynamic relocate offset of block. */
3789 rela.r_offset += GOT_ENTRY_SIZE;
3790 rela.r_info = ELFNN_R_INFO (h->dynindx,
3791 R_LARCH_TLS_DTPRELNN);
3792 loongarch_elf_append_rela (output_bfd, relgot, &rela);
e214f8db 3793 }
3794 }
4f248d61
LC
3795 if (tls_type & GOT_TLS_GDESC)
3796 {
3797 /* Unless it is a static link, DESC always emits a
3798 dynamic relocation. */
3799 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
3800 rela.r_offset = sec_addr (got) + got_off + desc_off;
3801 rela.r_addend = 0;
3802 if (indx == 0)
3803 rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
3804
3805 rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
3806 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3807 bfd_put_NN (output_bfd, 0,
3808 got->contents + got_off + desc_off);
3809 }
e214f8db 3810 if (tls_type & GOT_TLS_IE)
3811 {
6d13722a 3812 rela.r_offset = sec_addr (got) + got_off + ie_off;
3813 if (SYMBOL_REFERENCES_LOCAL (info, h))
e214f8db 3814 {
6d13722a 3815 /* Local sym, used in exec, set module id 1. */
3816 if (!bfd_link_executable (info))
d218dba3 3817 {
6d13722a 3818 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3819 rela.r_addend = tls_block_off;
3820 loongarch_elf_append_rela (output_bfd, relgot, &rela);
d218dba3 3821 }
6d13722a 3822
3823 bfd_put_NN (output_bfd, tls_block_off,
3824 got->contents + got_off + ie_off);
3825 }
3826 /* Dynamic resolved. */
3827 else
3828 {
3829 /* Dynamic relocate offset of block. */
3830 rela.r_info = ELFNN_R_INFO (h->dynindx,
3831 R_LARCH_TLS_TPRELNN);
3832 rela.r_addend = 0;
3833 loongarch_elf_append_rela (output_bfd, relgot, &rela);
e214f8db 3834 }
3835 }
3836 }
4f248d61
LC
3837 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
3838 if (is_desc)
3839 relocation += desc_off;
3840 else if (is_ie)
3841 relocation += ie_off;
6d13722a 3842
3843 if (r_type == R_LARCH_TLS_LD_PC_HI20
3844 || r_type == R_LARCH_TLS_GD_PC_HI20
4f248d61
LC
3845 || r_type == R_LARCH_TLS_IE_PC_HI20
3846 || r_type == R_LARCH_TLS_DESC_PC_HI20)
6d13722a 3847 RELOCATE_CALC_PC32_HI20 (relocation, pc);
ae296cc4 3848 else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
3849 || r_type == R_LARCH_TLS_GD_PCREL20_S2
3850 || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3851 relocation -= pc;
3852 /* else {} ABS relocations. */
6d13722a 3853 break;
3854
4f248d61
LC
3855 case R_LARCH_TLS_DESC_PC_LO12:
3856 case R_LARCH_TLS_DESC64_PC_LO20:
3857 case R_LARCH_TLS_DESC64_PC_HI12:
3858 case R_LARCH_TLS_DESC_LO12:
3859 case R_LARCH_TLS_DESC64_LO20:
3860 case R_LARCH_TLS_DESC64_HI12:
3861 {
3862 unresolved_reloc = false;
3863
3864 if (h)
3865 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3866 else
3867 relocation = sec_addr (got)
3868 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3869
3870 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3871 /* Use both TLS_GD and TLS_DESC. */
3872 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
3873 relocation += 2 * GOT_ENTRY_SIZE;
3874 }
3875
3876 if (r_type == R_LARCH_TLS_DESC64_PC_LO20
3877 || r_type == R_LARCH_TLS_DESC64_PC_HI12)
3878 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3879
3880 break;
3881
3882 case R_LARCH_TLS_DESC_LD:
3883 case R_LARCH_TLS_DESC_CALL:
3884 unresolved_reloc = false;
3885 break;
3886
6d13722a 3887 case R_LARCH_TLS_IE_PC_LO12:
3888 case R_LARCH_TLS_IE64_PC_LO20:
3889 case R_LARCH_TLS_IE64_PC_HI12:
3890 case R_LARCH_TLS_IE_LO12:
3891 case R_LARCH_TLS_IE64_LO20:
3892 case R_LARCH_TLS_IE64_HI12:
3893 unresolved_reloc = false;
3894
3895 if (h)
4f248d61 3896 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
6d13722a 3897 else
3898 relocation = sec_addr (got)
4f248d61 3899 + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
6d13722a 3900
3901 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
4f248d61
LC
3902 /* Use TLS_GD TLS_DESC and TLS_IE. */
3903 if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3904 relocation += 4 * GOT_ENTRY_SIZE;
3905 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
3906 else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
6d13722a 3907 relocation += 2 * GOT_ENTRY_SIZE;
3908
1b6fccd2 3909 if (r_type == R_LARCH_TLS_IE64_PC_LO20
3910 || r_type == R_LARCH_TLS_IE64_PC_HI12)
6d13722a 3911 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3912
3913 break;
e214f8db 3914
6d13722a 3915 case R_LARCH_RELAX:
1b6fccd2 3916 case R_LARCH_ALIGN:
3917 r = bfd_reloc_continue;
3918 unresolved_reloc = false;
e214f8db 3919 break;
3920
3921 default:
3922 break;
3923 }
3924
3925 if (fatal)
3926 break;
3927
3928 do
3929 {
3930 /* 'unresolved_reloc' means we haven't done it yet.
3931 We need help of dynamic linker to fix this memory location up. */
3932 if (!unresolved_reloc)
3933 break;
3934
3935 if (_bfd_elf_section_offset (output_bfd, info, input_section,
3936 rel->r_offset) == MINUS_ONE)
3937 /* WHY? May because it's invalid so skip checking.
6d13722a 3938 But why dynamic reloc a invalid section? */
e214f8db 3939 break;
3940
3941 if (input_section->output_section->flags & SEC_DEBUGGING)
3942 {
3943 fatal = (loongarch_reloc_is_fatal
3944 (info, input_bfd, input_section, rel, howto,
3945 bfd_reloc_dangerous, is_undefweak, name,
3946 "Seems dynamic linker not process "
3947 "sections 'SEC_DEBUGGING'."));
3948 }
3949 if (!is_dyn)
3950 break;
3951
3952 if ((info->flags & DF_TEXTREL) == 0)
3953 if (input_section->output_section->flags & SEC_READONLY)
3954 info->flags |= DF_TEXTREL;
3955 }
3956 while (0);
3957
3958 if (fatal)
3959 break;
3960
3961 loongarch_record_one_reloc (input_bfd, input_section, r_type,
3962 rel->r_offset, sym, h, rel->r_addend);
3963
3964 if (r != bfd_reloc_continue)
3965 r = perform_relocation (rel, input_section, howto, relocation,
3966 input_bfd, contents);
3967
3968 switch (r)
3969 {
3970 case bfd_reloc_dangerous:
3971 case bfd_reloc_continue:
3972 case bfd_reloc_ok:
3973 continue;
3974
3975 case bfd_reloc_overflow:
3976 /* Overflow value can't be filled in. */
3977 loongarch_dump_reloc_record (info->callbacks->info);
3978 info->callbacks->reloc_overflow
3979 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3980 input_bfd, input_section, rel->r_offset);
3981 break;
3982
3983 case bfd_reloc_outofrange:
3984 /* Stack state incorrect. */
3985 loongarch_dump_reloc_record (info->callbacks->info);
3986 info->callbacks->info
3987 ("%X%H: Internal stack state is incorrect.\n"
3988 "Want to push to full stack or pop from empty stack?\n",
3989 input_bfd, input_section, rel->r_offset);
3990 break;
3991
3992 case bfd_reloc_notsupported:
3993 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3994 input_section, rel->r_offset);
3995 break;
3996
3997 default:
3998 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3999 input_section, rel->r_offset);
4000 break;
4001 }
4002
4003 fatal = true;
e214f8db 4004 }
4005
4006 return !fatal;
4007}
4008
1b6fccd2 4009static bool
4010loongarch_relax_delete_bytes (bfd *abfd,
4011 asection *sec,
4012 bfd_vma addr,
4013 size_t count,
4014 struct bfd_link_info *link_info)
4015{
4016 unsigned int i, symcount;
4017 bfd_vma toaddr = sec->size;
4018 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
4019 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4020 unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
4021 struct bfd_elf_section_data *data = elf_section_data (sec);
4022 bfd_byte *contents = data->this_hdr.contents;
4023
4024 /* Actually delete the bytes. */
4025 sec->size -= count;
4026 memmove (contents + addr, contents + addr + count, toaddr - addr - count);
4027
4028 /* Adjust the location of all of the relocs. Note that we need not
4029 adjust the addends, since all PC-relative references must be against
4030 symbols, which we will adjust below. */
4031 for (i = 0; i < sec->reloc_count; i++)
4032 if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
4033 data->relocs[i].r_offset -= count;
4034
4035 /* Adjust the local symbols defined in this section. */
4036 for (i = 0; i < symtab_hdr->sh_info; i++)
4037 {
4038 Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
4039 if (sym->st_shndx == sec_shndx)
4040 {
4041 /* If the symbol is in the range of memory we just moved, we
4042 have to adjust its value. */
4043 if (sym->st_value > addr && sym->st_value <= toaddr)
4044 sym->st_value -= count;
4045
4046 /* If the symbol *spans* the bytes we just deleted (i.e. its
4047 *end* is in the moved bytes but its *start* isn't), then we
4048 must adjust its size.
4049
4050 This test needs to use the original value of st_value, otherwise
4051 we might accidentally decrease size when deleting bytes right
4052 before the symbol. But since deleted relocs can't span across
4053 symbols, we can't have both a st_value and a st_size decrease,
4054 so it is simpler to just use an else. */
4055 else if (sym->st_value <= addr
4056 && sym->st_value + sym->st_size > addr
4057 && sym->st_value + sym->st_size <= toaddr)
4058 sym->st_size -= count;
4059 }
4060 }
4061
4062 /* Now adjust the global symbols defined in this section. */
4063 symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
4064 - symtab_hdr->sh_info);
4065
4066 for (i = 0; i < symcount; i++)
4067 {
4068 struct elf_link_hash_entry *sym_hash = sym_hashes[i];
4069
4070 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4071 containing the definition of __wrap_SYMBOL, includes a direct
4072 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4073 the same symbol (which is __wrap_SYMBOL), but still exist as two
4074 different symbols in 'sym_hashes', we don't want to adjust
4075 the global symbol __wrap_SYMBOL twice.
4076
4077 The same problem occurs with symbols that are versioned_hidden, as
4078 foo becomes an alias for foo@BAR, and hence they need the same
4079 treatment. */
4080 if (link_info->wrap_hash != NULL
4081 || sym_hash->versioned != unversioned)
4082 {
4083 struct elf_link_hash_entry **cur_sym_hashes;
4084
4085 /* Loop only over the symbols which have already been checked. */
4086 for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
4087 cur_sym_hashes++)
4088 {
4089 /* If the current symbol is identical to 'sym_hash', that means
4090 the symbol was already adjusted (or at least checked). */
4091 if (*cur_sym_hashes == sym_hash)
4092 break;
4093 }
4094 /* Don't adjust the symbol again. */
4095 if (cur_sym_hashes < &sym_hashes[i])
4096 continue;
4097 }
4098
4099 if ((sym_hash->root.type == bfd_link_hash_defined
4100 || sym_hash->root.type == bfd_link_hash_defweak)
4101 && sym_hash->root.u.def.section == sec)
4102 {
4103 /* As above, adjust the value if needed. */
4104 if (sym_hash->root.u.def.value > addr
4105 && sym_hash->root.u.def.value <= toaddr)
4106 sym_hash->root.u.def.value -= count;
4107
4108 /* As above, adjust the size if needed. */
4109 else if (sym_hash->root.u.def.value <= addr
4110 && sym_hash->root.u.def.value + sym_hash->size > addr
4111 && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
4112 sym_hash->size -= count;
4113 }
4114 }
4115
4116 return true;
4117}
aae8784c 4118/* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4119 there are three situations in which an assembly instruction sequence needs to
4120 be relaxed:
4121 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4122
4123 Case 1:
4124 in this case, the rd register in the st.{w/d} instruction does not store the
4125 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4126 symbolic address, and then obtains the rd + le_lo12_r address through the
4127 st.w instruction feature.
4128 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4129
4130 before relax: after relax:
4131
4132 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4133 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4134 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4135
4136 Case 2:
4137 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4138
4139 before relax: after relax:
4140
4141 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4142 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4143 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4144
4145 Case 3:
4146 in this case,the rs register in addi.{w/d} stores the full address of the tls
4147 symbol (tp + le_hi20_r + le_lo12_r).
4148
4149 before relax: after relax:
4150
4151 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4152 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4153 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4154*/
4155static bool
4156loongarch_relax_tls_le (bfd *abfd, asection *sec,
4157 Elf_Internal_Rela *rel,
4158 struct bfd_link_info *link_info,
4159 bfd_vma symval)
4160{
4161 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4162 uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
4163 static uint32_t insn_rj,insn_rd;
4164 symval = symval - elf_hash_table (link_info)->tls_sec->vma;
4165 /* Whether the symbol offset is in the interval (offset < 0x800). */
4166 if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
4167 {
4168 switch (ELFNN_R_TYPE (rel->r_info))
4169 {
4170 case R_LARCH_TLS_LE_HI20_R:
4171 case R_LARCH_TLS_LE_ADD_R:
4172 /* delete insn. */
4173 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4174 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
4175 break;
4176 case R_LARCH_TLS_LE_LO12_R:
4177 /* Change rj to $tp. */
4178 insn_rj = 0x2 << 5;
4179 /* Get rd register. */
4180 insn_rd = insn & 0x1f;
4181 /* Write symbol offset. */
4182 symval <<= 10;
4183 /* Writes the modified instruction. */
4184 insn = insn & 0xffc00000;
4185 insn = insn | symval | insn_rj | insn_rd;
4186 bfd_put (32, abfd, insn, contents + rel->r_offset);
4187 break;
4188 default:
4189 break;
4190 }
4191 }
4192 return true;
4193}
1b6fccd2 4194
4195/* Relax pcalau12i,addi.d => pcaddi. */
4196static bool
4f2469d0 4197loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
4e94082d 4198 Elf_Internal_Rela *rel_hi, bfd_vma symval,
b130a084 4199 struct bfd_link_info *info, bool *again)
1b6fccd2 4200{
4201 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4202 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4203 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4204 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4205 uint32_t rd = pca & 0x1f;
4f2469d0 4206
4207 /* This section's output_offset need to subtract the bytes of instructions
4208 relaxed by the previous sections, so it needs to be updated beforehand.
4209 size_input_section already took care of updating it after relaxation,
4210 so we additionally update once here. */
4211 sec->output_offset = sec->output_section->size;
1b6fccd2 4212 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4f2469d0 4213
4214 /* If pc and symbol not in the same segment, add/sub segment alignment.
4215 FIXME: if there are multiple readonly segments? */
4216 if (!(sym_sec->flags & SEC_READONLY))
4217 {
4218 if (symval > pc)
4219 pc -= info->maxpagesize;
4220 else if (symval < pc)
4221 pc += info->maxpagesize;
4222 }
4223
1b6fccd2 4224 const uint32_t addi_d = 0x02c00000;
4225 const uint32_t pcaddi = 0x18000000;
4226
4227 /* Is pcalau12i + addi.d insns? */
4228 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
4229 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4230 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4231 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4232 || ((add & addi_d) != addi_d)
4233 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4234 || ((add & 0x1f) != rd)
4235 || (((add >> 5) & 0x1f) != rd)
4236 /* Can be relaxed to pcaddi? */
4237 || (symval & 0x3) /* 4 bytes align. */
4238 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4239 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4240 return false;
4241
b130a084 4242 /* Continue next relax trip. */
4243 *again = true;
4244
1b6fccd2 4245 pca = pcaddi | rd;
4246 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4247
4248 /* Adjust relocations. */
4249 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4250 R_LARCH_PCREL20_S2);
4e94082d 4251 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4252
4253 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
1b6fccd2 4254
4255 return true;
4256}
4257
4258/* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
4259static bool
4260loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
4261 Elf_Internal_Rela *rel_hi)
4262{
4263 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4264 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4265 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4266 uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
4267 uint32_t rd = pca & 0x1f;
4268 const uint32_t ld_d = 0x28c00000;
4269 uint32_t addi_d = 0x02c00000;
4270
4271 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
4272 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4273 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4274 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4275 || ((ld & 0x1f) != rd)
4276 || (((ld >> 5) & 0x1f) != rd)
4277 || ((ld & ld_d) != ld_d))
4278 return false;
4279
4280 addi_d = addi_d | (rd << 5) | rd;
4281 bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
4282
4283 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4284 R_LARCH_PCALA_HI20);
4285 rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
4286 R_LARCH_PCALA_LO12);
4287 return true;
4288}
4289
4290/* Called by after_allocation to set the information of data segment
4291 before relaxing. */
4292
4293void
4294bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
4295 int *data_segment_phase)
4296{
4297 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4298 htab->data_segment_phase = data_segment_phase;
4299}
4300
4301/* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4302 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
4303static bool
4304loongarch_relax_align (bfd *abfd, asection *sec,
4305 asection *sym_sec,
4306 struct bfd_link_info *link_info,
4307 Elf_Internal_Rela *rel,
4308 bfd_vma symval)
4309{
c3d507ab 4310 bfd_vma addend, max = 0, alignment = 1;
1b6fccd2 4311
c3d507ab 4312 int index = ELFNN_R_SYM (rel->r_info);
4313 if (index > 0)
4314 {
4315 alignment = 1 << (rel->r_addend & 0xff);
4316 max = rel->r_addend >> 8;
4317 }
4318 else
4319 alignment = rel->r_addend + 4;
1b6fccd2 4320
c3d507ab 4321 addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
4322 symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */
4323 bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
4324 bfd_vma need_nop_bytes = aligned_addr - symval; /* */
1b6fccd2 4325
4326 /* Make sure there are enough NOPs to actually achieve the alignment. */
c3d507ab 4327 if (addend < need_nop_bytes)
1b6fccd2 4328 {
4329 _bfd_error_handler
4330 (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
4331 "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
4332 abfd, sym_sec, (uint64_t) rel->r_offset,
c3d507ab 4333 (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
1b6fccd2 4334 bfd_set_error (bfd_error_bad_value);
4335 return false;
4336 }
4337
c3d507ab 4338 /* Once we've handled an R_LARCH_ALIGN in a section,
4339 we can't relax anything else in this section. */
4340 sec->sec_flg0 = true;
1b6fccd2 4341 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4342
c3d507ab 4343 /* If skipping more bytes than the specified maximum,
4344 then the alignment is not done at all and delete all NOPs. */
4345 if (max > 0 && need_nop_bytes > max)
4346 return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
4347 addend, link_info);
4348
1b6fccd2 4349 /* If the number of NOPs is already correct, there's nothing to do. */
c3d507ab 4350 if (need_nop_bytes == addend)
1b6fccd2 4351 return true;
4352
1b6fccd2 4353 /* Delete the excess NOPs. */
c3d507ab 4354 return loongarch_relax_delete_bytes (abfd, sec,
4355 rel->r_offset + need_nop_bytes,
4356 addend - need_nop_bytes, link_info);
1b6fccd2 4357}
4358
ae296cc4 4359/* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
4360static bool
4361loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
4362 Elf_Internal_Rela *rel_hi, bfd_vma symval,
4363 struct bfd_link_info *info, bool *again)
4364{
4365 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4366 Elf_Internal_Rela *rel_lo = rel_hi + 2;
4367 uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4368 uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4369 uint32_t rd = pca & 0x1f;
4370
4371 /* This section's output_offset need to subtract the bytes of instructions
4372 relaxed by the previous sections, so it needs to be updated beforehand.
4373 size_input_section already took care of updating it after relaxation,
4374 so we additionally update once here. */
4375 sec->output_offset = sec->output_section->size;
4376 bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4377
4378 /* If pc and symbol not in the same segment, add/sub segment alignment.
4379 FIXME: if there are multiple readonly segments? */
4380 if (!(sym_sec->flags & SEC_READONLY))
4381 {
4382 if (symval > pc)
4383 pc -= info->maxpagesize;
4384 else if (symval < pc)
4385 pc += info->maxpagesize;
4386 }
4387
4388 const uint32_t addi_d = 0x02c00000;
4389 const uint32_t pcaddi = 0x18000000;
4390
4391 /* Is pcalau12i + addi.d insns? */
4392 if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
4393 && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
4394 || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4395 || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4396 || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4397 || ((add & addi_d) != addi_d)
4398 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4399 || ((add & 0x1f) != rd)
4400 || (((add >> 5) & 0x1f) != rd)
4401 /* Can be relaxed to pcaddi? */
4402 || (symval & 0x3) /* 4 bytes align. */
4403 || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4404 || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4405 return false;
4406
4407 /* Continue next relax trip. */
4408 *again = true;
4409
4410 pca = pcaddi | rd;
4411 bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4412
4413 /* Adjust relocations. */
4414 switch (ELFNN_R_TYPE (rel_hi->r_info))
4415 {
4416 case R_LARCH_TLS_LD_PC_HI20:
4417 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4418 R_LARCH_TLS_LD_PCREL20_S2);
4419 break;
4420 case R_LARCH_TLS_GD_PC_HI20:
4421 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4422 R_LARCH_TLS_GD_PCREL20_S2);
4423 break;
4424 case R_LARCH_TLS_DESC_PC_HI20:
4425 rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4426 R_LARCH_TLS_DESC_PCREL20_S2);
4427 break;
4428 default:
4429 break;
4430 }
4431 rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4432
4433 loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4434
4435 return true;
4436}
4437
1b6fccd2 4438static bool
4439loongarch_elf_relax_section (bfd *abfd, asection *sec,
4440 struct bfd_link_info *info,
4441 bool *again)
4442{
4443 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
1b6fccd2 4444 struct bfd_elf_section_data *data = elf_section_data (sec);
c3d507ab 4445 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
1b6fccd2 4446 Elf_Internal_Rela *relocs;
4447 *again = false;
4448
4449 if (bfd_link_relocatable (info)
4450 || sec->sec_flg0
4451 || (sec->flags & SEC_RELOC) == 0
4452 || sec->reloc_count == 0
1b6fccd2 4453 || (info->disable_target_specific_optimizations
4454 && info->relax_pass == 0)
4455 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4456 and defined in ld/ldexp.h. */
4457 || *(htab->data_segment_phase) == 4)
4458 return true;
4459
4460 if (data->relocs)
4461 relocs = data->relocs;
4462 else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
4463 info->keep_memory)))
4464 return true;
4465
4466 if (!data->this_hdr.contents
4467 && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
4468 return true;
4469
4470 if (symtab_hdr->sh_info != 0
4471 && !symtab_hdr->contents
4472 && !(symtab_hdr->contents =
4473 (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
4474 symtab_hdr->sh_info,
4475 0, NULL, NULL, NULL)))
4476 return true;
4477
c3d507ab 4478 data->relocs = relocs;
1b6fccd2 4479
4480 for (unsigned int i = 0; i < sec->reloc_count; i++)
4481 {
ae296cc4 4482 char symtype;
1b6fccd2 4483 bfd_vma symval;
ae296cc4 4484 asection *sym_sec;
1b6fccd2 4485 bool local_got = false;
ae296cc4 4486 Elf_Internal_Rela *rel = relocs + i;
1b6fccd2 4487 struct elf_link_hash_entry *h = NULL;
ae296cc4 4488 unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
4489 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1b6fccd2 4490
ae296cc4 4491 /* Four kind of relocations:
4492 Normal: symval is the symbol address.
4493 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4494 added by this relocation, and then adds 4 more.
4495 R_LARCH_CALL36: symval is the symbol address for local symbols,
4496 or the PLT entry address of the symbol. (Todo)
4497 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4498 of the symbol. */
1b6fccd2 4499 if (r_symndx < symtab_hdr->sh_info)
4500 {
4501 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
4502 + r_symndx;
4503 if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4504 continue;
4505
ae296cc4 4506 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4507 || R_LARCH_TLS_GD_PC_HI20 == r_type
4508 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4509 {
4510 if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
4511 continue;
4512 else
4513 {
4514 sym_sec = htab->elf.sgot;
4515 symval = elf_local_got_offsets (abfd)[r_symndx];
4516 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4517 r_symndx);
4518 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4519 && GOT_TLS_GD_BOTH_P (tls_type))
4520 symval += 2 * GOT_ENTRY_SIZE;
4521 }
4522 }
4523 else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
1b6fccd2 4524 {
4525 sym_sec = sec;
4526 symval = rel->r_offset;
4527 }
4528 else
4529 {
4530 sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
4531 symval = sym->st_value;
4532 }
4533 symtype = ELF_ST_TYPE (sym->st_info);
4534 }
4535 else
4536 {
4537 r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
4538 h = elf_sym_hashes (abfd)[r_symndx];
4539
4540 while (h->root.type == bfd_link_hash_indirect
4541 || h->root.type == bfd_link_hash_warning)
4542 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4543
4544 /* Disable the relaxation for ifunc. */
4545 if (h != NULL && h->type == STT_GNU_IFUNC)
4546 continue;
4547
ae296cc4 4548 /* The GOT entry of tls symbols must in current execute file or
4549 shared object. */
4550 if (R_LARCH_TLS_LD_PC_HI20 == r_type
4551 || R_LARCH_TLS_GD_PC_HI20 == r_type
4552 || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4553 {
4554 if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
4555 continue;
4556 else
4557 {
4558 sym_sec = htab->elf.sgot;
4559 symval = h->got.offset;
4560 char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4561 r_symndx);
4562 if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4563 && GOT_TLS_GD_BOTH_P (tls_type))
4564 symval += 2 * GOT_ENTRY_SIZE;
4565 }
4566 }
4567 else if ((h->root.type == bfd_link_hash_defined
c3d507ab 4568 || h->root.type == bfd_link_hash_defweak)
4569 && h->root.u.def.section != NULL
4570 && h->root.u.def.section->output_section != NULL)
1b6fccd2 4571 {
4572 symval = h->root.u.def.value;
4573 sym_sec = h->root.u.def.section;
4574 }
4575 else
4576 continue;
4577
15aacf32 4578 if (h && SYMBOL_REFERENCES_LOCAL (info, h))
1b6fccd2 4579 local_got = true;
4580 symtype = h->type;
4581 }
4582
4583 if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
4584 && (sym_sec->flags & SEC_MERGE))
4585 {
4586 if (symtype == STT_SECTION)
4587 symval += rel->r_addend;
4588
4589 symval = _bfd_merged_section_offset (abfd, &sym_sec,
4590 elf_section_data (sym_sec)->sec_info,
4591 symval);
4592
4593 if (symtype != STT_SECTION)
4594 symval += rel->r_addend;
4595 }
ae296cc4 4596 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
c3d507ab 4597 + (alingmeng - 4).
4598 If r_symndx is 0, alignmeng-4 is r_addend.
4599 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
4600 else if (R_LARCH_ALIGN == r_type)
4601 if (r_symndx > 0)
4602 symval += ((1 << (rel->r_addend & 0xff)) - 4);
4603 else
4604 symval += rel->r_addend;
1b6fccd2 4605 else
4606 symval += rel->r_addend;
4607
4608 symval += sec_addr (sym_sec);
4609
c3d507ab 4610 switch (r_type)
1b6fccd2 4611 {
4612 case R_LARCH_ALIGN:
8338aecd 4613 if (1 == info->relax_pass)
1b6fccd2 4614 loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
4615 break;
4616 case R_LARCH_DELETE:
36317477 4617 if (1 == info->relax_pass)
1b6fccd2 4618 {
4619 loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4620 rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4621 }
4622 break;
aae8784c 4623 case R_LARCH_TLS_LE_HI20_R:
4624 case R_LARCH_TLS_LE_LO12_R:
4625 case R_LARCH_TLS_LE_ADD_R:
4626 if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
4627 loongarch_relax_tls_le (abfd, sec, rel, info, symval);
4628 break;
4629
1b6fccd2 4630 case R_LARCH_PCALA_HI20:
36317477 4631 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4f2469d0 4632 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4633 info, again);
1b6fccd2 4634 break;
4635 case R_LARCH_GOT_PC_HI20:
36317477 4636 if (local_got && 0 == info->relax_pass
4637 && (i + 4) <= sec->reloc_count)
1b6fccd2 4638 {
1b6fccd2 4639 if (loongarch_relax_pcala_ld (abfd, sec, rel))
4f2469d0 4640 loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
b130a084 4641 info, again);
1b6fccd2 4642 }
4643 break;
ae296cc4 4644
4645 case R_LARCH_TLS_LD_PC_HI20:
4646 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4647 loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4648 info, again);
4649 break;
4650
4651 case R_LARCH_TLS_GD_PC_HI20:
4652 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4653 loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4654 info, again);
4655 break;
4656
4657 case R_LARCH_TLS_DESC_PC_HI20:
4658 if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4659 loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4660 info, again);
4661 break;
4662
1b6fccd2 4663 default:
4664 break;
4665 }
4666 }
4667
4668 return true;
4669}
4670
e214f8db 4671/* Finish up dynamic symbol handling. We set the contents of various
4672 dynamic sections here. */
4673
4674static bool
4675loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
4676 struct bfd_link_info *info,
4677 struct elf_link_hash_entry *h,
4678 Elf_Internal_Sym *sym)
4679{
4680 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4681 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
e214f8db 4682
4683 if (h->plt.offset != MINUS_ONE)
4684 {
4685 size_t i, plt_idx;
d218dba3 4686 asection *plt, *gotplt, *relplt;
e214f8db 4687 bfd_vma got_address;
4688 uint32_t plt_entry[PLT_ENTRY_INSNS];
4689 bfd_byte *loc;
4690 Elf_Internal_Rela rela;
4691
e214f8db 4692 if (htab->elf.splt)
4693 {
4694 BFD_ASSERT ((h->type == STT_GNU_IFUNC
4695 && SYMBOL_REFERENCES_LOCAL (info, h))
4696 || h->dynindx != -1);
4697
4698 plt = htab->elf.splt;
4699 gotplt = htab->elf.sgotplt;
bc2a35c0 4700 if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4701 relplt = htab->elf.srelgot;
4702 else
4703 relplt = htab->elf.srelplt;
d218dba3 4704 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
e214f8db 4705 got_address =
4706 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4707 }
4708 else /* if (htab->elf.iplt) */
4709 {
4710 BFD_ASSERT (h->type == STT_GNU_IFUNC
4711 && SYMBOL_REFERENCES_LOCAL (info, h));
4712
4713 plt = htab->elf.iplt;
4714 gotplt = htab->elf.igotplt;
4715 relplt = htab->elf.irelplt;
d218dba3 4716 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
e214f8db 4717 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4718 }
4719
4720 /* Find out where the .plt entry should go. */
4721 loc = plt->contents + h->plt.offset;
4722
4723 /* Fill in the PLT entry itself. */
4724 if (!loongarch_make_plt_entry (got_address,
4725 sec_addr (plt) + h->plt.offset,
4726 plt_entry))
4727 return false;
4728
4729 for (i = 0; i < PLT_ENTRY_INSNS; i++)
4730 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4731
6d13722a 4732 /* Fill in the initial value of the got.plt entry. */
e214f8db 4733 loc = gotplt->contents + (got_address - sec_addr (gotplt));
4734 bfd_put_NN (output_bfd, sec_addr (plt), loc);
4735
4736 rela.r_offset = got_address;
d218dba3 4737
bc2a35c0 4738 /* TRUE if this is a PLT reference to a local IFUNC. */
4739 if (PLT_LOCAL_IFUNC_P (info, h)
4740 && (relplt == htab->elf.srelgot
4741 || relplt == htab->elf.irelplt))
4742 {
ae2e4d40
XR
4743 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4744 rela.r_addend = (h->root.u.def.value
bc2a35c0 4745 + h->root.u.def.section->output_section->vma
4746 + h->root.u.def.section->output_offset);
bc2a35c0 4747
b5c37946 4748 loongarch_elf_append_rela (output_bfd, relplt, &rela);
bc2a35c0 4749 }
4750 else
4751 {
4752 /* Fill in the entry in the rela.plt section. */
4753 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4754 rela.r_addend = 0;
4755 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
4756 bed->s->swap_reloca_out (output_bfd, &rela, loc);
4757 }
e214f8db 4758
4759 if (!h->def_regular)
4760 {
4761 /* Mark the symbol as undefined, rather than as defined in
4762 the .plt section. Leave the value alone. */
4763 sym->st_shndx = SHN_UNDEF;
4764 /* If the symbol is weak, we do need to clear the value.
4765 Otherwise, the PLT entry would provide a definition for
4766 the symbol even if the symbol wasn't defined anywhere,
4767 and so the symbol would never be NULL. */
4768 if (!h->ref_regular_nonweak)
4769 sym->st_value = 0;
4770 }
4771 }
4772
4773 if (h->got.offset != MINUS_ONE
4774 /* TLS got entry have been handled in elf_relocate_section. */
4f248d61
LC
4775 && !(loongarch_elf_hash_entry (h)->tls_type
4776 & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
6d13722a 4777 /* Have allocated got entry but not allocated rela before. */
e214f8db 4778 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4779 {
4780 asection *sgot, *srela;
4781 Elf_Internal_Rela rela;
6d13722a 4782 bfd_vma off = h->got.offset & ~(bfd_vma)1;
e214f8db 4783
4784 /* This symbol has an entry in the GOT. Set it up. */
e214f8db 4785 sgot = htab->elf.sgot;
4786 srela = htab->elf.srelgot;
4787 BFD_ASSERT (sgot && srela);
4788
4789 rela.r_offset = sec_addr (sgot) + off;
4790
d218dba3 4791 if (h->def_regular
4792 && h->type == STT_GNU_IFUNC)
e214f8db 4793 {
d218dba3 4794 if(h->plt.offset == MINUS_ONE)
4795 {
4796 if (htab->elf.splt == NULL)
4797 srela = htab->elf.irelplt;
4798
4799 if (SYMBOL_REFERENCES_LOCAL (info, h))
4800 {
4801 asection *sec = h->root.u.def.section;
4802 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4803 rela.r_addend = h->root.u.def.value + sec->output_section->vma
4804 + sec->output_offset;
4805 bfd_put_NN (output_bfd, 0, sgot->contents + off);
4806 }
4807 else
4808 {
d218dba3 4809 BFD_ASSERT (h->dynindx != -1);
4810 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4811 rela.r_addend = 0;
4812 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
4813 }
4814 }
4815 else if(bfd_link_pic (info))
e214f8db 4816 {
d218dba3 4817 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4818 rela.r_addend = 0;
4819 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
e214f8db 4820 }
4821 else
4822 {
d218dba3 4823 asection *plt;
4824 /* For non-shared object, we can't use .got.plt, which
4825 contains the real function address if we need pointer
4826 equality. We load the GOT entry with the PLT entry. */
4827 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4828 bfd_put_NN (output_bfd,
4829 (plt->output_section->vma
4830 + plt->output_offset
4831 + h->plt.offset),
4832 sgot->contents + off);
4833 return true;
e214f8db 4834 }
4835 }
4836 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4837 {
e214f8db 4838 asection *sec = h->root.u.def.section;
4839 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4840 rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4841 + sec->output_offset);
4842 }
4843 else
4844 {
e214f8db 4845 BFD_ASSERT (h->dynindx != -1);
4846 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4847 rela.r_addend = 0;
4848 }
4849
4850 loongarch_elf_append_rela (output_bfd, srela, &rela);
4851 }
4852
e214f8db 4853 /* Mark some specially defined symbols as absolute. */
4854 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4855 sym->st_shndx = SHN_ABS;
4856
4857 return true;
4858}
4859
4860/* Finish up the dynamic sections. */
4861
4862static bool
4863loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4864 asection *sdyn)
4865{
4866 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4867 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4868 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4869 bfd_byte *dyncon, *dynconend;
4870
4871 dynconend = sdyn->contents + sdyn->size;
4872 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4873 {
4874 Elf_Internal_Dyn dyn;
4875 asection *s;
4876 int skipped = 0;
4877
4878 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4879
4880 switch (dyn.d_tag)
4881 {
4882 case DT_PLTGOT:
4883 s = htab->elf.sgotplt;
4884 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4885 break;
4886 case DT_JMPREL:
4887 s = htab->elf.srelplt;
4888 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4889 break;
4890 case DT_PLTRELSZ:
4891 s = htab->elf.srelplt;
4892 dyn.d_un.d_val = s->size;
4893 break;
4894 case DT_TEXTREL:
4895 if ((info->flags & DF_TEXTREL) == 0)
4896 skipped = 1;
4897 break;
4898 case DT_FLAGS:
4899 if ((info->flags & DF_TEXTREL) == 0)
4900 dyn.d_un.d_val &= ~DF_TEXTREL;
4901 break;
4902 }
4903 if (skipped)
4904 skipped_size += dynsize;
4905 else
4906 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4907 }
4908 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
4909 memset (dyncon - skipped_size, 0, skipped_size);
4910 return true;
4911}
4912
4913/* Finish up local dynamic symbol handling. We set the contents of
4914 various dynamic sections here. */
4915
b5c37946 4916static int
e214f8db 4917elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4918{
4919 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4920 struct bfd_link_info *info = (struct bfd_link_info *) inf;
4921
4922 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4923}
4924
b5c37946
SJ
4925/* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4926 this function is called before elf_link_sort_relocs.
4927 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4928 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
4929
4930static bool
4931elf_loongarch_output_arch_local_syms
4932 (bfd *output_bfd ATTRIBUTE_UNUSED,
4933 struct bfd_link_info *info,
4934 void *flaginfo ATTRIBUTE_UNUSED,
4935 int (*func) (void *, const char *,
4936 Elf_Internal_Sym *,
4937 asection *,
4938 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4939{
4940 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4941 if (htab == NULL)
4942 return false;
4943
4944 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4945 htab_traverse (htab->loc_hash_table,
4946 elfNN_loongarch_finish_local_dynamic_symbol,
4947 info);
4948
4949 return true;
4950}
4951
e214f8db 4952static bool
4953loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
4954 struct bfd_link_info *info)
4955{
4956 bfd *dynobj;
4957 asection *sdyn, *plt, *gotplt = NULL;
4958 struct loongarch_elf_link_hash_table *htab;
4959
4960 htab = loongarch_elf_hash_table (info);
4961 BFD_ASSERT (htab);
4962 dynobj = htab->elf.dynobj;
4963 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
4964
4965 if (elf_hash_table (info)->dynamic_sections_created)
4966 {
4967 BFD_ASSERT (htab->elf.splt && sdyn);
4968
4969 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
4970 return false;
4971 }
4972
d218dba3 4973 plt = htab->elf.splt;
4974 gotplt = htab->elf.sgotplt;
e214f8db 4975
4976 if (plt && 0 < plt->size)
4977 {
4978 size_t i;
4979 uint32_t plt_header[PLT_HEADER_INSNS];
4980 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
4981 plt_header))
4982 return false;
4983
4984 for (i = 0; i < PLT_HEADER_INSNS; i++)
4985 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
4986
4987 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
4988 PLT_ENTRY_SIZE;
4989 }
4990
4991 if (htab->elf.sgotplt)
4992 {
4993 asection *output_section = htab->elf.sgotplt->output_section;
4994
4995 if (bfd_is_abs_section (output_section))
4996 {
4997 _bfd_error_handler (_("discarded output section: `%pA'"),
4998 htab->elf.sgotplt);
4999 return false;
5000 }
5001
5002 if (0 < htab->elf.sgotplt->size)
5003 {
5004 /* Write the first two entries in .got.plt, needed for the dynamic
5005 linker. */
5006 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
5007
5008 bfd_put_NN (output_bfd, (bfd_vma) 0,
5009 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
5010 }
5011
5012 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5013 }
5014
5015 if (htab->elf.sgot)
5016 {
5017 asection *output_section = htab->elf.sgot->output_section;
5018
5019 if (0 < htab->elf.sgot->size)
5020 {
5021 /* Set the first entry in the global offset table to the address of
5022 the dynamic section. */
5023 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
5024 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
5025 }
5026
5027 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5028 }
5029
e214f8db 5030 return true;
5031}
5032
5033/* Return address for Ith PLT stub in section PLT, for relocation REL
5034 or (bfd_vma) -1 if it should not be included. */
5035
5036static bfd_vma
5037loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
5038 const arelent *rel ATTRIBUTE_UNUSED)
5039{
5040 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
5041}
5042
5043static enum elf_reloc_type_class
5044loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5045 const asection *rel_sec ATTRIBUTE_UNUSED,
5046 const Elf_Internal_Rela *rela)
5047{
5048 struct loongarch_elf_link_hash_table *htab;
5049 htab = loongarch_elf_hash_table (info);
5050
5051 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
5052 {
5053 /* Check relocation against STT_GNU_IFUNC symbol if there are
5054 dynamic symbols. */
5055 bfd *abfd = info->output_bfd;
5056 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5057 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
5058 if (r_symndx != STN_UNDEF)
5059 {
5060 Elf_Internal_Sym sym;
5061 if (!bed->s->swap_symbol_in (abfd,
5062 htab->elf.dynsym->contents
5063 + r_symndx * bed->s->sizeof_sym,
5064 0, &sym))
5065 {
5066 /* xgettext:c-format */
5067 _bfd_error_handler (_("%pB symbol number %lu references"
5068 " nonexistent SHT_SYMTAB_SHNDX section"),
5069 abfd, r_symndx);
5070 /* Ideally an error class should be returned here. */
5071 }
5072 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5073 return reloc_class_ifunc;
5074 }
5075 }
5076
5077 switch (ELFNN_R_TYPE (rela->r_info))
5078 {
5079 case R_LARCH_IRELATIVE:
5080 return reloc_class_ifunc;
5081 case R_LARCH_RELATIVE:
5082 return reloc_class_relative;
5083 case R_LARCH_JUMP_SLOT:
5084 return reloc_class_plt;
5085 case R_LARCH_COPY:
5086 return reloc_class_copy;
5087 default:
5088 return reloc_class_normal;
5089 }
5090}
5091
5092/* Copy the extra info we tack onto an elf_link_hash_entry. */
5093
5094static void
5095loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
5096 struct elf_link_hash_entry *dir,
5097 struct elf_link_hash_entry *ind)
5098{
d218dba3 5099 struct elf_link_hash_entry *edir, *eind;
e214f8db 5100
d218dba3 5101 edir = dir;
5102 eind = ind;
e214f8db 5103
5104 if (eind->dyn_relocs != NULL)
5105 {
5106 if (edir->dyn_relocs != NULL)
5107 {
5108 struct elf_dyn_relocs **pp;
5109 struct elf_dyn_relocs *p;
5110
5111 /* Add reloc counts against the indirect sym to the direct sym
5112 list. Merge any entries against the same section. */
5113 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
5114 {
5115 struct elf_dyn_relocs *q;
5116
5117 for (q = edir->dyn_relocs; q != NULL; q = q->next)
5118 if (q->sec == p->sec)
5119 {
5120 q->pc_count += p->pc_count;
5121 q->count += p->count;
5122 *pp = p->next;
5123 break;
5124 }
5125 if (q == NULL)
5126 pp = &p->next;
5127 }
5128 *pp = edir->dyn_relocs;
5129 }
5130
5131 edir->dyn_relocs = eind->dyn_relocs;
5132 eind->dyn_relocs = NULL;
5133 }
5134
5135 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
5136 {
d218dba3 5137 loongarch_elf_hash_entry(edir)->tls_type
5138 = loongarch_elf_hash_entry(eind)->tls_type;
5139 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
e214f8db 5140 }
5141 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
5142}
5143
5144#define PRSTATUS_SIZE 0x1d8
5145#define PRSTATUS_OFFSET_PR_CURSIG 0xc
5146#define PRSTATUS_OFFSET_PR_PID 0x20
5147#define ELF_GREGSET_T_SIZE 0x168
5148#define PRSTATUS_OFFSET_PR_REG 0x70
5149
5150/* Support for core dump NOTE sections. */
5151
5152static bool
5153loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
5154{
5155 switch (note->descsz)
5156 {
5157 default:
5158 return false;
5159
5160 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
5161 case PRSTATUS_SIZE:
5162 /* pr_cursig */
5163 elf_tdata (abfd)->core->signal =
5164 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
5165
5166 /* pr_pid */
5167 elf_tdata (abfd)->core->lwpid =
5168 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
5169 break;
5170 }
5171
5172 /* Make a ".reg/999" section. */
5173 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
5174 note->descpos
5175 + PRSTATUS_OFFSET_PR_REG);
5176}
5177
5178#define PRPSINFO_SIZE 0x88
5179#define PRPSINFO_OFFSET_PR_PID 0x18
5180#define PRPSINFO_OFFSET_PR_FNAME 0x28
5181#define PRPSINFO_SIZEOF_PR_FNAME 0x10
5182#define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
5183#define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
5184
e214f8db 5185static bool
5186loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
5187{
5188 switch (note->descsz)
5189 {
5190 default:
5191 return false;
5192
5193 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
5194 case PRPSINFO_SIZE:
5195 /* pr_pid */
5196 elf_tdata (abfd)->core->pid =
5197 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
5198
5199 /* pr_fname */
5200 elf_tdata (abfd)->core->program =
5201 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
5202 PRPSINFO_SIZEOF_PR_FNAME);
5203
5204 /* pr_psargs */
5205 elf_tdata (abfd)->core->command =
5206 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
5207 PRPSINFO_SIZEOF_PR_PS_ARGS);
5208 break;
5209 }
5210
5211 /* Note that for some reason, a spurious space is tacked
5212 onto the end of the args in some (at least one anyway)
5213 implementations, so strip it off if it exists. */
5214
5215 {
5216 char *command = elf_tdata (abfd)->core->command;
5217 int n = strlen (command);
5218
5219 if (0 < n && command[n - 1] == ' ')
5220 command[n - 1] = '\0';
5221 }
5222
5223 return true;
5224}
5225
5226/* Set the right mach type. */
5227static bool
5228loongarch_elf_object_p (bfd *abfd)
5229{
5230 /* There are only two mach types in LoongArch currently. */
5231 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
5232 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
5233 else
5234 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
5235 return true;
5236}
5237
5238static asection *
5239loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
5240 Elf_Internal_Rela *rel,
5241 struct elf_link_hash_entry *h,
5242 Elf_Internal_Sym *sym)
5243{
5244 if (h != NULL)
5245 switch (ELFNN_R_TYPE (rel->r_info))
5246 {
5247 case R_LARCH_GNU_VTINHERIT:
5248 case R_LARCH_GNU_VTENTRY:
5249 return NULL;
5250 }
5251
5252 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
5253}
5254
e6f601b7 5255/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
5256 executable PLT slots where the executable never takes the address of those
5257 functions, the function symbols are not added to the hash table. */
5258
5259static bool
5260elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
5261{
5262 if (h->plt.offset != (bfd_vma) -1
5263 && !h->def_regular
5264 && !h->pointer_equality_needed)
5265 return false;
5266
5267 return _bfd_elf_hash_symbol (h);
5268}
5269
e214f8db 5270#define TARGET_LITTLE_SYM loongarch_elfNN_vec
5271#define TARGET_LITTLE_NAME "elfNN-loongarch"
5272#define ELF_ARCH bfd_arch_loongarch
5273#define ELF_TARGET_ID LARCH_ELF_DATA
5274#define ELF_MACHINE_CODE EM_LOONGARCH
5275#define ELF_MAXPAGESIZE 0x4000
5276#define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5277#define bfd_elfNN_bfd_link_hash_table_create \
5278 loongarch_elf_link_hash_table_create
5279#define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5280#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
5281#define elf_info_to_howto loongarch_info_to_howto_rela
5282#define bfd_elfNN_bfd_merge_private_bfd_data \
5283 elfNN_loongarch_merge_private_bfd_data
5284
5285#define elf_backend_reloc_type_class loongarch_reloc_type_class
5286#define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5287#define elf_backend_create_dynamic_sections \
5288 loongarch_elf_create_dynamic_sections
5289#define elf_backend_check_relocs loongarch_elf_check_relocs
5290#define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5291#define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
5292#define elf_backend_relocate_section loongarch_elf_relocate_section
5293#define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
b5c37946
SJ
5294#define elf_backend_output_arch_local_syms \
5295 elf_loongarch_output_arch_local_syms
e214f8db 5296#define elf_backend_finish_dynamic_sections \
5297 loongarch_elf_finish_dynamic_sections
5298#define elf_backend_object_p loongarch_elf_object_p
5299#define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5300#define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5301#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5302#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
e6f601b7 5303#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
1b6fccd2 5304#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
e214f8db 5305
3233ad1e 5306#define elf_backend_dtrel_excludes_plt 1
5307
e214f8db 5308#include "elfNN-target.h"