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