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