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