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