33c85e5207c79cb628226e327390df37fb300ef2
[binutils-gdb.git] / bfd / elfnn-loongarch.c
1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2022 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
31 static bool
32 loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
33 Elf_Internal_Rela *dst)
34 {
35 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
36 ELFNN_R_TYPE (dst->r_info));
37 return cache_ptr->howto != NULL;
38 }
39
40 /* LoongArch ELF linker hash entry. */
41 struct loongarch_elf_link_hash_entry
42 {
43 struct elf_link_hash_entry elf;
44
45 #define GOT_UNKNOWN 0
46 #define GOT_NORMAL 1
47 #define GOT_TLS_GD 2
48 #define GOT_TLS_IE 4
49 #define GOT_TLS_LE 8
50 char tls_type;
51 };
52
53 #define loongarch_elf_hash_entry(ent) \
54 ((struct loongarch_elf_link_hash_entry *) (ent))
55
56 struct _bfd_loongarch_elf_obj_tdata
57 {
58 struct elf_obj_tdata root;
59
60 /* The tls_type for each local got entry. */
61 char *local_got_tls_type;
62 };
63
64 #define _bfd_loongarch_elf_tdata(abfd) \
65 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
66
67 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
68 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
69
70 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
71 (*((h) != NULL \
72 ? &loongarch_elf_hash_entry (h)->tls_type \
73 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
74
75 #define is_loongarch_elf(bfd) \
76 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
77 && elf_tdata (bfd) != NULL \
78 && elf_object_id (bfd) == LARCH_ELF_DATA)
79
80 struct loongarch_elf_link_hash_table
81 {
82 struct elf_link_hash_table elf;
83
84 /* Short-cuts to get to dynamic linker sections. */
85 asection *sdyntdata;
86
87 /* Small local sym to section mapping cache. */
88 struct sym_cache sym_cache;
89
90 /* Used by local STT_GNU_IFUNC symbols. */
91 htab_t loc_hash_table;
92 void *loc_hash_memory;
93
94 /* The max alignment of output sections. */
95 bfd_vma max_alignment;
96 };
97
98 /* Get the LoongArch ELF linker hash table from a link_info structure. */
99 #define loongarch_elf_hash_table(p) \
100 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
101 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
102 : NULL)
103
104 #define MINUS_ONE ((bfd_vma) 0 - 1)
105
106 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
107
108 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
109 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
110
111 #define PLT_HEADER_INSNS 8
112 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
113
114 #define PLT_ENTRY_INSNS 4
115 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
116
117 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
118
119 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
120
121 #define elf_backend_want_got_plt 1
122
123 #define elf_backend_plt_readonly 1
124
125 #define elf_backend_want_plt_sym 1
126 #define elf_backend_plt_alignment 4
127 #define elf_backend_can_gc_sections 1
128 #define elf_backend_can_refcount 1
129 #define elf_backend_want_got_sym 1
130
131 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
132
133 #define elf_backend_want_dynrelro 1
134 #define elf_backend_rela_normal 1
135 #define elf_backend_default_execstack 0
136
137 /* Generate a PLT header. */
138
139 static bool
140 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
141 uint32_t *entry)
142 {
143 bfd_vma pcrel = got_plt_addr - plt_header_addr;
144 bfd_vma hi, lo;
145
146 if (pcrel + 0x80000800 > 0xffffffff)
147 {
148 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
149 bfd_set_error (bfd_error_bad_value);
150 return false;
151 }
152 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
153 lo = pcrel & 0xfff;
154
155 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
156 sub.[wd] $t1, $t1, $t3
157 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
158 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
159 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
160 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
161 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
162 jirl $r0, $t3, 0 */
163
164 if (GOT_ENTRY_SIZE == 8)
165 {
166 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
167 entry[1] = 0x0011bdad;
168 entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
169 entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
170 entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
171 entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
172 entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
173 entry[7] = 0x4c0001e0;
174 }
175 else
176 {
177 entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
178 entry[1] = 0x00113dad;
179 entry[2] = 0x288001cf | (lo & 0xfff) << 10;
180 entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
181 entry[4] = 0x028001cc | (lo & 0xfff) << 10;
182 entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
183 entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
184 entry[7] = 0x4c0001e0;
185 }
186 return true;
187 }
188
189 /* Generate a PLT entry. */
190
191 static bool
192 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
193 uint32_t *entry)
194 {
195 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
196 bfd_vma hi, lo;
197
198 if (pcrel + 0x80000800 > 0xffffffff)
199 {
200 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
201 bfd_set_error (bfd_error_bad_value);
202 return false;
203 }
204 hi = ((pcrel + 0x800) >> 12) & 0xfffff;
205 lo = pcrel & 0xfff;
206
207 entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
208 entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
209 | (lo & 0xfff) << 10);
210 entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
211 entry[3] = 0x03400000; /* nop */
212
213 return true;
214 }
215
216 /* Create an entry in an LoongArch ELF linker hash table. */
217
218 static struct bfd_hash_entry *
219 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
220 const char *string)
221 {
222 struct loongarch_elf_link_hash_entry *eh;
223
224 /* Allocate the structure if it has not already been allocated by a
225 subclass. */
226 if (entry == NULL)
227 {
228 entry = bfd_hash_allocate (table, sizeof (*eh));
229 if (entry == NULL)
230 return entry;
231 }
232
233 /* Call the allocation method of the superclass. */
234 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
235 if (entry != NULL)
236 {
237 eh = (struct loongarch_elf_link_hash_entry *) entry;
238 eh->tls_type = GOT_UNKNOWN;
239 }
240
241 return entry;
242 }
243
244 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
245 for local symbol so that we can handle local STT_GNU_IFUNC symbols
246 as global symbol. We reuse indx and dynstr_index for local symbol
247 hash since they aren't used by global symbols in this backend. */
248
249 static hashval_t
250 elfNN_loongarch_local_htab_hash (const void *ptr)
251 {
252 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
253 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
254 }
255
256 /* Compare local hash entries. */
257
258 static int
259 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
260 {
261 struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
262 struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
263
264 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
265 }
266
267 /* Find and/or create a hash entry for local symbol. */
268 static struct elf_link_hash_entry *
269 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
270 bfd *abfd, const Elf_Internal_Rela *rel,
271 bool create)
272 {
273 struct loongarch_elf_link_hash_entry e, *ret;
274 asection *sec = abfd->sections;
275 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
276 void **slot;
277
278 e.elf.indx = sec->id;
279 e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
280 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
281 create ? INSERT : NO_INSERT);
282
283 if (!slot)
284 return NULL;
285
286 if (*slot)
287 {
288 ret = (struct loongarch_elf_link_hash_entry *) *slot;
289 return &ret->elf;
290 }
291
292 ret = ((struct loongarch_elf_link_hash_entry *)
293 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
294 sizeof (struct loongarch_elf_link_hash_entry)));
295 if (ret)
296 {
297 memset (ret, 0, sizeof (*ret));
298 ret->elf.indx = sec->id;
299 ret->elf.pointer_equality_needed = 0;
300 ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
301 ret->elf.dynindx = -1;
302 ret->elf.needs_plt = 0;
303 ret->elf.plt.refcount = -1;
304 ret->elf.got.refcount = -1;
305 ret->elf.def_dynamic = 0;
306 ret->elf.def_regular = 1;
307 ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */
308 ret->elf.ref_regular = 0;
309 ret->elf.forced_local = 1;
310 ret->elf.root.type = bfd_link_hash_defined;
311 *slot = ret;
312 }
313 return &ret->elf;
314 }
315
316 /* Destroy an LoongArch elf linker hash table. */
317
318 static void
319 elfNN_loongarch_link_hash_table_free (bfd *obfd)
320 {
321 struct loongarch_elf_link_hash_table *ret;
322 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
323
324 if (ret->loc_hash_table)
325 htab_delete (ret->loc_hash_table);
326 if (ret->loc_hash_memory)
327 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
328
329 _bfd_elf_link_hash_table_free (obfd);
330 }
331
332 /* Create a LoongArch ELF linker hash table. */
333
334 static struct bfd_link_hash_table *
335 loongarch_elf_link_hash_table_create (bfd *abfd)
336 {
337 struct loongarch_elf_link_hash_table *ret;
338 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
339
340 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
341 if (ret == NULL)
342 return NULL;
343
344 if (!_bfd_elf_link_hash_table_init
345 (&ret->elf, abfd, link_hash_newfunc,
346 sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
347 {
348 free (ret);
349 return NULL;
350 }
351
352 ret->max_alignment = MINUS_ONE;
353
354 ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
355 elfNN_loongarch_local_htab_eq, NULL);
356 ret->loc_hash_memory = objalloc_create ();
357 if (!ret->loc_hash_table || !ret->loc_hash_memory)
358 {
359 elfNN_loongarch_link_hash_table_free (abfd);
360 return NULL;
361 }
362 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
363
364 return &ret->elf.root;
365 }
366
367 /* Merge backend specific data from an object file to the output
368 object file when linking. */
369
370 static bool
371 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
372 {
373 bfd *obfd = info->output_bfd;
374 flagword in_flags = elf_elfheader (ibfd)->e_flags;
375 flagword out_flags = elf_elfheader (obfd)->e_flags;
376
377 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
378 return true;
379
380 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
381 {
382 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
383 "the selected emulation:\n"
384 " target emulation `%s' does not match `%s'"),
385 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
386 return false;
387 }
388
389 if (!_bfd_elf_merge_object_attributes (ibfd, info))
390 return false;
391
392 /* If the input BFD is not a dynamic object and it does not contain any
393 non-data sections, do not account its ABI. For example, various
394 packages produces such data-only relocatable objects with
395 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
396 But they are compatible with all ABIs. */
397 if (!(ibfd->flags & DYNAMIC))
398 {
399 asection *sec;
400 bool have_code_sections = false;
401 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
402 if ((bfd_section_flags (sec)
403 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
404 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
405 {
406 have_code_sections = true;
407 break;
408 }
409 if (!have_code_sections)
410 return true;
411 }
412
413 if (!elf_flags_init (obfd))
414 {
415 elf_flags_init (obfd) = true;
416 elf_elfheader (obfd)->e_flags = in_flags;
417 return true;
418 }
419
420 /* Disallow linking different ABIs. */
421 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
422 {
423 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
424 goto fail;
425 }
426
427 return true;
428
429 fail:
430 bfd_set_error (bfd_error_bad_value);
431 return false;
432 }
433
434 /* Create the .got section. */
435
436 static bool
437 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
438 {
439 flagword flags;
440 char *name;
441 asection *s, *s_got;
442 struct elf_link_hash_entry *h;
443 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
444 struct elf_link_hash_table *htab = elf_hash_table (info);
445
446 /* This function may be called more than once. */
447 if (htab->sgot != NULL)
448 return true;
449
450 flags = bed->dynamic_sec_flags;
451 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
452 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
453
454 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
455 return false;
456 htab->srelgot = s;
457
458 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
459 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
460 return false;
461 htab->sgot = s;
462
463 /* The first bit of the global offset table is the header. */
464 s->size += bed->got_header_size;
465
466 if (bed->want_got_plt)
467 {
468 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
469 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
470 return false;
471 htab->sgotplt = s;
472
473 /* Reserve room for the header. */
474 s->size = GOTPLT_HEADER_SIZE;
475 }
476
477 if (bed->want_got_sym)
478 {
479 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
480 section. We don't do this in the linker script because we don't want
481 to define the symbol if we are not creating a global offset table. */
482 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
483 "_GLOBAL_OFFSET_TABLE_");
484 elf_hash_table (info)->hgot = h;
485 if (h == NULL)
486 return false;
487 }
488 return true;
489 }
490
491 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
492 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
493 hash table. */
494
495 static bool
496 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
497 {
498 struct loongarch_elf_link_hash_table *htab;
499
500 htab = loongarch_elf_hash_table (info);
501 BFD_ASSERT (htab != NULL);
502
503 if (!loongarch_elf_create_got_section (dynobj, info))
504 return false;
505
506 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
507 return false;
508
509 if (!bfd_link_pic (info))
510 htab->sdyntdata
511 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
512 SEC_ALLOC | SEC_THREAD_LOCAL);
513
514 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
515 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
516 abort ();
517
518 return true;
519 }
520
521 static bool
522 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
523 struct bfd_link_info *info,
524 struct elf_link_hash_entry *h,
525 unsigned long symndx,
526 char tls_type)
527 {
528 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
529 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
530
531 /* This is a global offset table entry for a local symbol. */
532 if (elf_local_got_refcounts (abfd) == NULL)
533 {
534 bfd_size_type size =
535 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
536 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
537 return false;
538 _bfd_loongarch_elf_local_got_tls_type (abfd) =
539 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
540 }
541
542 switch (tls_type)
543 {
544 case GOT_NORMAL:
545 case GOT_TLS_GD:
546 case GOT_TLS_IE:
547 /* Need GOT. */
548 if (htab->elf.sgot == NULL
549 && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
550 return false;
551 if (h)
552 {
553 if (h->got.refcount < 0)
554 h->got.refcount = 0;
555 h->got.refcount++;
556 }
557 else
558 elf_local_got_refcounts (abfd)[symndx]++;
559 break;
560 case GOT_TLS_LE:
561 /* No need for GOT. */
562 break;
563 default:
564 _bfd_error_handler (_("Internal error: unreachable."));
565 return false;
566 }
567
568 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
569 *new_tls_type |= tls_type;
570 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
571 {
572 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
573 "thread local symbol"),
574 abfd,
575 h ? h->root.root.string : "<local>");
576 return false;
577 }
578
579 return true;
580 }
581
582 /* Look through the relocs for a section during the first phase, and
583 allocate space in the global offset table or procedure linkage
584 table. */
585
586 static bool
587 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
588 asection *sec, const Elf_Internal_Rela *relocs)
589 {
590 struct loongarch_elf_link_hash_table *htab;
591 Elf_Internal_Shdr *symtab_hdr;
592 struct elf_link_hash_entry **sym_hashes;
593 const Elf_Internal_Rela *rel;
594 asection *sreloc = NULL;
595
596 if (bfd_link_relocatable (info))
597 return true;
598
599 htab = loongarch_elf_hash_table (info);
600 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
601 sym_hashes = elf_sym_hashes (abfd);
602
603 if (htab->elf.dynobj == NULL)
604 htab->elf.dynobj = abfd;
605
606 for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
607 {
608 unsigned int r_type;
609 unsigned int r_symndx;
610 struct elf_link_hash_entry *h;
611 Elf_Internal_Sym *isym = NULL;
612
613 r_symndx = ELFNN_R_SYM (rel->r_info);
614 r_type = ELFNN_R_TYPE (rel->r_info);
615
616 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
617 {
618 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
619 return false;
620 }
621
622 if (r_symndx < symtab_hdr->sh_info)
623 {
624 /* A local symbol. */
625 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
626 if (isym == NULL)
627 return false;
628
629 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
630 {
631 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
632 if (h == NULL)
633 return false;
634
635 h->type = STT_GNU_IFUNC;
636 h->ref_regular = 1;
637 }
638 else
639 h = NULL;
640 }
641 else
642 {
643 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
644 while (h->root.type == bfd_link_hash_indirect
645 || h->root.type == bfd_link_hash_warning)
646 h = (struct elf_link_hash_entry *) h->root.u.i.link;
647 }
648
649 /* It is referenced by a non-shared object. */
650 if (h != NULL)
651 h->ref_regular = 1;
652
653 if (h && h->type == STT_GNU_IFUNC)
654 {
655 if (htab->elf.dynobj == NULL)
656 htab->elf.dynobj = abfd;
657
658 /* Create 'irelifunc' in PIC object. */
659 if (bfd_link_pic (info)
660 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
661 return false;
662 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
663 else if (!htab->elf.splt
664 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
665 return false;
666 /* Create the ifunc sections, iplt and ipltgot, for static
667 executables. */
668 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
669 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
670 return false;
671
672 if (h->plt.refcount < 0)
673 h->plt.refcount = 0;
674 h->plt.refcount++;
675 h->needs_plt = 1;
676
677 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
678 }
679
680 int need_dynreloc = 0;
681 int only_need_pcrel = 0;
682
683 switch (r_type)
684 {
685 case R_LARCH_GOT_PC_HI20:
686 case R_LARCH_GOT_HI20:
687 case R_LARCH_SOP_PUSH_GPREL:
688 /* For la.global. */
689 if (h)
690 h->pointer_equality_needed = 1;
691 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
692 r_symndx,
693 GOT_NORMAL))
694 return false;
695 break;
696
697 case R_LARCH_TLS_LD_PC_HI20:
698 case R_LARCH_TLS_LD_HI20:
699 case R_LARCH_TLS_GD_PC_HI20:
700 case R_LARCH_TLS_GD_HI20:
701 case R_LARCH_SOP_PUSH_TLS_GD:
702 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
703 r_symndx,
704 GOT_TLS_GD))
705 return false;
706 break;
707
708 case R_LARCH_TLS_IE_PC_HI20:
709 case R_LARCH_TLS_IE_HI20:
710 case R_LARCH_SOP_PUSH_TLS_GOT:
711 if (bfd_link_pic (info))
712 /* May fail for lazy-bind. */
713 info->flags |= DF_STATIC_TLS;
714
715 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
716 r_symndx,
717 GOT_TLS_IE))
718 return false;
719 break;
720
721 case R_LARCH_TLS_LE_HI20:
722 case R_LARCH_SOP_PUSH_TLS_TPREL:
723 if (!bfd_link_executable (info))
724 return false;
725
726 info->flags |= DF_STATIC_TLS;
727
728 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
729 r_symndx,
730 GOT_TLS_LE))
731 return false;
732 break;
733
734 case R_LARCH_ABS_HI20:
735 case R_LARCH_SOP_PUSH_ABSOLUTE:
736 if (h != NULL)
737 /* If this reloc is in a read-only section, we might
738 need a copy reloc. We can't check reliably at this
739 stage whether the section is read-only, as input
740 sections have not yet been mapped to output sections.
741 Tentatively set the flag for now, and correct in
742 adjust_dynamic_symbol. */
743 h->non_got_ref = 1;
744 break;
745
746 case R_LARCH_PCALA_HI20:
747 if (h != NULL)
748 {
749 /* For pcalau12i + jirl. */
750 h->needs_plt = 1;
751 if (h->plt.refcount < 0)
752 h->plt.refcount = 0;
753 h->plt.refcount++;
754
755 h->non_got_ref = 1;
756 h->pointer_equality_needed = 1;
757 }
758
759 break;
760
761 case R_LARCH_B21:
762 case R_LARCH_B16:
763 case R_LARCH_B26:
764 if (h != NULL)
765 {
766 h->needs_plt = 1;
767 if (!bfd_link_pic (info))
768 h->non_got_ref = 1;
769
770 /* We try to create PLT stub for all non-local function. */
771 if (h->plt.refcount < 0)
772 h->plt.refcount = 0;
773 h->plt.refcount++;
774 }
775
776 break;
777
778 case R_LARCH_SOP_PUSH_PCREL:
779 if (h != NULL)
780 {
781 if (!bfd_link_pic (info))
782 h->non_got_ref = 1;
783
784 /* We try to create PLT stub for all non-local function. */
785 if (h->plt.refcount < 0)
786 h->plt.refcount = 0;
787 h->plt.refcount++;
788 h->pointer_equality_needed = 1;
789 }
790
791 break;
792
793 case R_LARCH_SOP_PUSH_PLT_PCREL:
794 /* This symbol requires a procedure linkage table entry. We
795 actually build the entry in adjust_dynamic_symbol,
796 because this might be a case of linking PIC code without
797 linking in any dynamic objects, in which case we don't
798 need to generate a procedure linkage table after all. */
799 if (h != NULL)
800 {
801 h->needs_plt = 1;
802 if (h->plt.refcount < 0)
803 h->plt.refcount = 0;
804 h->plt.refcount++;
805 }
806 break;
807
808 case R_LARCH_TLS_DTPREL32:
809 case R_LARCH_TLS_DTPREL64:
810 need_dynreloc = 1;
811 only_need_pcrel = 1;
812 break;
813
814 case R_LARCH_JUMP_SLOT:
815 case R_LARCH_32:
816 case R_LARCH_64:
817
818 need_dynreloc = 1;
819
820 /* If resolved symbol is defined in this object,
821 1. Under pie, the symbol is known. We convert it
822 into R_LARCH_RELATIVE and need load-addr still.
823 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
824 3. Under dll, R_LARCH_NN can't be changed normally, since
825 its defination could be covered by the one in executable.
826 For symbolic, we convert it into R_LARCH_RELATIVE.
827 Thus, only under pde, it needs pcrel only. We discard it. */
828 only_need_pcrel = bfd_link_pde (info);
829
830 if (h != NULL
831 && (!bfd_link_pic (info)
832 || h->type == STT_GNU_IFUNC))
833 {
834 /* This reloc might not bind locally. */
835 h->non_got_ref = 1;
836 h->pointer_equality_needed = 1;
837
838 if (!h->def_regular
839 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
840 {
841 /* We may need a .plt entry if the symbol is a function
842 defined in a shared lib or is a function referenced
843 from the code or read-only section. */
844 h->plt.refcount += 1;
845 }
846 }
847 break;
848
849 case R_LARCH_GNU_VTINHERIT:
850 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
851 return false;
852 break;
853
854 case R_LARCH_GNU_VTENTRY:
855 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
856 return false;
857 break;
858
859 default:
860 break;
861 }
862
863 /* Record some info for sizing and allocating dynamic entry. */
864 if (need_dynreloc && (sec->flags & SEC_ALLOC))
865 {
866 /* When creating a shared object, we must copy these
867 relocs into the output file. We create a reloc
868 section in dynobj and make room for the reloc. */
869 struct elf_dyn_relocs *p;
870 struct elf_dyn_relocs **head;
871
872 if (sreloc == NULL)
873 {
874 sreloc
875 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
876 LARCH_ELF_LOG_WORD_BYTES,
877 abfd, /*rela?*/ true);
878 if (sreloc == NULL)
879 return false;
880 }
881
882 /* If this is a global symbol, we count the number of
883 relocations we need for this symbol. */
884 if (h != NULL)
885 head = &h->dyn_relocs;
886 else
887 {
888 /* Track dynamic relocs needed for local syms too.
889 We really need local syms available to do this
890 easily. Oh well. */
891
892 asection *s;
893 void *vpp;
894
895 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
896 if (s == NULL)
897 s = sec;
898
899 vpp = &elf_section_data (s)->local_dynrel;
900 head = (struct elf_dyn_relocs **) vpp;
901 }
902
903 p = *head;
904 if (p == NULL || p->sec != sec)
905 {
906 bfd_size_type amt = sizeof *p;
907 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
908 if (p == NULL)
909 return false;
910 p->next = *head;
911 *head = p;
912 p->sec = sec;
913 p->count = 0;
914 p->pc_count = 0;
915 }
916
917 p->count++;
918 p->pc_count += only_need_pcrel;
919 }
920 }
921
922 return true;
923 }
924
925 /* Find dynamic relocs for H that apply to read-only sections. */
926
927 static asection *
928 readonly_dynrelocs (struct elf_link_hash_entry *h)
929 {
930 struct elf_dyn_relocs *p;
931
932 for (p = h->dyn_relocs; p != NULL; p = p->next)
933 {
934 asection *s = p->sec->output_section;
935
936 if (s != NULL && (s->flags & SEC_READONLY) != 0)
937 return p->sec;
938 }
939 return NULL;
940 }
941
942 /* Adjust a symbol defined by a dynamic object and referenced by a
943 regular object. The current definition is in some section of the
944 dynamic object, but we're not including those sections. We have to
945 change the definition to something the rest of the link can
946 understand. */
947 static bool
948 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
949 struct elf_link_hash_entry *h)
950 {
951 struct loongarch_elf_link_hash_table *htab;
952 bfd *dynobj;
953
954 htab = loongarch_elf_hash_table (info);
955 BFD_ASSERT (htab != NULL);
956
957 dynobj = htab->elf.dynobj;
958
959 /* Make sure we know what is going on here. */
960 BFD_ASSERT (dynobj != NULL
961 && (h->needs_plt || h->type == STT_GNU_IFUNC || h->is_weakalias
962 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
963
964 /* If this is a function, put it in the procedure linkage table. We
965 will fill in the contents of the procedure linkage table later
966 (although we could actually do it here). */
967 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
968 {
969 if (h->plt.refcount < 0
970 || (h->type != STT_GNU_IFUNC
971 && (SYMBOL_REFERENCES_LOCAL (info, h)
972 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
973 && h->root.type == bfd_link_hash_undefweak))))
974 {
975 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
976 in an input file, but the symbol was never referred to by a
977 dynamic object, or if all references were garbage collected.
978 In such a case, we don't actually need to build a PLT entry. */
979 h->plt.offset = MINUS_ONE;
980 h->needs_plt = 0;
981 }
982 else
983 h->needs_plt = 1;
984
985 return true;
986 }
987 else
988 h->plt.offset = MINUS_ONE;
989
990 /* If this is a weak symbol, and there is a real definition, the
991 processor independent code will have arranged for us to see the
992 real definition first, and we can just use the same value. */
993 if (h->is_weakalias)
994 {
995 struct elf_link_hash_entry *def = weakdef (h);
996 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
997 h->root.u.def.section = def->root.u.def.section;
998 h->root.u.def.value = def->root.u.def.value;
999 return true;
1000 }
1001
1002 /* R_LARCH_COPY is not adept glibc, not to generate. */
1003 /* Can not print anything, because make check ld. */
1004 return true;
1005 }
1006
1007 /* Allocate space in .plt, .got and associated reloc sections for
1008 dynamic relocs. */
1009
1010 static bool
1011 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1012 {
1013 struct bfd_link_info *info;
1014 struct loongarch_elf_link_hash_table *htab;
1015 struct elf_dyn_relocs *p;
1016
1017 if (h->root.type == bfd_link_hash_indirect)
1018 return true;
1019
1020 if (h->type == STT_GNU_IFUNC
1021 && h->def_regular)
1022 return true;
1023
1024 info = (struct bfd_link_info *) inf;
1025 htab = loongarch_elf_hash_table (info);
1026 bool dyn = htab->elf.dynamic_sections_created;
1027 BFD_ASSERT (htab != NULL);
1028
1029 do
1030 {
1031 asection *plt, *gotplt, *relplt;
1032
1033 if (!h->needs_plt)
1034 break;
1035
1036 h->needs_plt = 0;
1037
1038 if (htab->elf.splt)
1039 {
1040 if (h->dynindx == -1 && !h->forced_local && dyn
1041 && h->root.type == bfd_link_hash_undefweak)
1042 {
1043 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1044 return false;
1045 }
1046
1047 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1048 && h->type != STT_GNU_IFUNC)
1049 break;
1050
1051 plt = htab->elf.splt;
1052 gotplt = htab->elf.sgotplt;
1053 relplt = htab->elf.srelplt;
1054 }
1055 else if (htab->elf.iplt)
1056 {
1057 /* .iplt only for IFUNC. */
1058 if (h->type != STT_GNU_IFUNC)
1059 break;
1060
1061 plt = htab->elf.iplt;
1062 gotplt = htab->elf.igotplt;
1063 relplt = htab->elf.irelplt;
1064 }
1065 else
1066 break;
1067
1068 if (plt->size == 0)
1069 plt->size = PLT_HEADER_SIZE;
1070
1071 h->plt.offset = plt->size;
1072 plt->size += PLT_ENTRY_SIZE;
1073 gotplt->size += GOT_ENTRY_SIZE;
1074 relplt->size += sizeof (ElfNN_External_Rela);
1075
1076 /* If this symbol is not defined in a regular file, and we are
1077 not generating a shared library, then set the symbol to this
1078 location in the .plt. This is required to make function
1079 pointers compare as equal between the normal executable and
1080 the shared library. */
1081 if (!bfd_link_pic (info)
1082 && !h->def_regular)
1083 {
1084 h->root.u.def.section = plt;
1085 h->root.u.def.value = h->plt.offset;
1086 }
1087
1088 h->needs_plt = 1;
1089 }
1090 while (0);
1091
1092 if (!h->needs_plt)
1093 h->plt.offset = MINUS_ONE;
1094
1095 if (0 < h->got.refcount)
1096 {
1097 asection *s;
1098 int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1099
1100 /* Make sure this symbol is output as a dynamic symbol.
1101 Undefined weak syms won't yet be marked as dynamic. */
1102 if (h->dynindx == -1 && !h->forced_local && dyn
1103 && h->root.type == bfd_link_hash_undefweak)
1104 {
1105 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1106 return false;
1107 }
1108
1109 s = htab->elf.sgot;
1110 h->got.offset = s->size;
1111 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
1112 {
1113 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1114 if (tls_type & GOT_TLS_GD)
1115 {
1116 s->size += 2 * GOT_ENTRY_SIZE;
1117 if (bfd_link_executable (info))
1118 {
1119 /* Link exe and not defined local. */
1120 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1121 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1122 }
1123 else
1124 {
1125 if (SYMBOL_REFERENCES_LOCAL (info, h))
1126 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1127 else
1128 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1129 }
1130 }
1131
1132 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1133 if (tls_type & GOT_TLS_IE)
1134 {
1135 s->size += GOT_ENTRY_SIZE;
1136
1137 if (bfd_link_executable (info))
1138 {
1139 /* Link exe and not defined local. */
1140 if (!SYMBOL_REFERENCES_LOCAL (info, h))
1141 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1142 }
1143 else
1144 {
1145 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1146 }
1147 }
1148 }
1149 else
1150 {
1151 s->size += GOT_ENTRY_SIZE;
1152 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1153 || h->root.type != bfd_link_hash_undefweak)
1154 && (bfd_link_pic (info)
1155 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1156 h))
1157 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1158 /* Undefined weak symbol in static PIE resolves to 0 without
1159 any dynamic relocations. */
1160 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1161 }
1162 }
1163 else
1164 h->got.offset = MINUS_ONE;
1165
1166 if (h->dyn_relocs == NULL)
1167 return true;
1168
1169 /* Extra dynamic relocate,
1170 * R_LARCH_64
1171 * R_LARCH_TLS_DTPRELNN
1172 * R_LARCH_JUMP_SLOT
1173 * R_LARCH_NN. */
1174
1175 if (SYMBOL_CALLS_LOCAL (info, h))
1176 {
1177 struct elf_dyn_relocs **pp;
1178
1179 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1180 {
1181 p->count -= p->pc_count;
1182 p->pc_count = 0;
1183 if (p->count == 0)
1184 *pp = p->next;
1185 else
1186 pp = &p->next;
1187 }
1188 }
1189
1190 if (h->root.type == bfd_link_hash_undefweak)
1191 {
1192 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1193 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1194 || (!bfd_link_pic (info) && h->non_got_ref))
1195 h->dyn_relocs = NULL;
1196 else if (h->dynindx == -1 && !h->forced_local)
1197 {
1198 /* Make sure this symbol is output as a dynamic symbol.
1199 Undefined weak syms won't yet be marked as dynamic. */
1200 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1201 return false;
1202
1203 if (h->dynindx == -1)
1204 h->dyn_relocs = NULL;
1205 }
1206 }
1207
1208 for (p = h->dyn_relocs; p != NULL; p = p->next)
1209 {
1210 asection *sreloc = elf_section_data (p->sec)->sreloc;
1211 sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1212 }
1213
1214 return true;
1215 }
1216
1217 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1218 For local def and ref ifunc,
1219 dynamic relocations are stored in
1220 1. rela.srelgot section in dynamic object (dll or exec).
1221 2. rela.irelplt section in static executable.
1222 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1223 instead of rela.srelplt. Glibc ELF loader will not support
1224 R_LARCH_IRELATIVE relocation in rela.plt. */
1225
1226 static bool
1227 local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1228 struct elf_link_hash_entry *h,
1229 struct elf_dyn_relocs **head,
1230 unsigned int plt_entry_size,
1231 unsigned int plt_header_size,
1232 unsigned int got_entry_size,
1233 bool avoid_plt)
1234 {
1235 asection *plt, *gotplt, *relplt;
1236 struct elf_dyn_relocs *p;
1237 unsigned int sizeof_reloc;
1238 const struct elf_backend_data *bed;
1239 struct elf_link_hash_table *htab;
1240 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1241 bool use_plt = !avoid_plt || h->plt.refcount > 0;
1242 bool need_dynreloc = !use_plt || bfd_link_pic (info);
1243
1244 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1245 in executable or it isn't referenced via PLT, the address of
1246 the resolved function may be used. But in non-PIC executable,
1247 the address of its plt slot may be used. Pointer equality may
1248 not work correctly. PIE or non-PLT reference should be used if
1249 pointer equality is required here.
1250
1251 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1252 backend should change it to the normal function and set its address
1253 to its PLT entry which should be resolved by R_*_IRELATIVE at
1254 run-time. All external references should be resolved to its PLT in
1255 executable. */
1256 if (!need_dynreloc
1257 && !(bfd_link_pde (info) && h->def_regular)
1258 && (h->dynindx != -1
1259 || info->export_dynamic)
1260 && h->pointer_equality_needed)
1261 {
1262 info->callbacks->einfo
1263 /* xgettext:c-format. */
1264 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1265 "equality in `%pB' can not be used when making an "
1266 "executable; recompile with -fPIE and relink with -pie\n"),
1267 h->root.root.string,
1268 h->root.u.def.section->owner);
1269 bfd_set_error (bfd_error_bad_value);
1270 return false;
1271 }
1272
1273 htab = elf_hash_table (info);
1274
1275 /* When the symbol is marked with regular reference, if PLT isn't used
1276 or we are building a PIC object, we must keep dynamic relocation
1277 if there is non-GOT reference and use PLT if there is PC-relative
1278 reference. */
1279 if (need_dynreloc && h->ref_regular)
1280 {
1281 bool keep = false;
1282 for (p = *head; p != NULL; p = p->next)
1283 if (p->count)
1284 {
1285 h->non_got_ref = 1;
1286 /* Need dynamic relocations for non-GOT reference. */
1287 keep = true;
1288 if (p->pc_count)
1289 {
1290 /* Must use PLT for PC-relative reference. */
1291 use_plt = true;
1292 need_dynreloc = bfd_link_pic (info);
1293 break;
1294 }
1295 }
1296 if (keep)
1297 goto keep;
1298 }
1299
1300 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1301 if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1302 {
1303 h->got = htab->init_got_offset;
1304 h->plt = htab->init_plt_offset;
1305 *head = NULL;
1306 return true;
1307 }
1308
1309 /* Return and discard space for dynamic relocations against it if
1310 it is never referenced. */
1311 if (!h->ref_regular)
1312 {
1313 if (h->plt.refcount > 0
1314 || h->got.refcount > 0)
1315 abort ();
1316 h->got = htab->init_got_offset;
1317 h->plt = htab->init_plt_offset;
1318 *head = NULL;
1319 return true;
1320 }
1321
1322 keep:
1323 bed = get_elf_backend_data (info->output_bfd);
1324 if (bed->rela_plts_and_copies_p)
1325 sizeof_reloc = bed->s->sizeof_rela;
1326 else
1327 sizeof_reloc = bed->s->sizeof_rel;
1328
1329 /* When building a static executable, use iplt, igot.plt and
1330 rela.iplt sections for STT_GNU_IFUNC symbols. */
1331 if (htab->splt != NULL)
1332 {
1333 plt = htab->splt;
1334 gotplt = htab->sgotplt;
1335 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1336 relplt = htab->srelgot;
1337
1338 /* If this is the first plt entry and PLT is used, make room for
1339 the special first entry. */
1340 if (plt->size == 0 && use_plt)
1341 plt->size += plt_header_size;
1342 }
1343 else
1344 {
1345 plt = htab->iplt;
1346 gotplt = htab->igotplt;
1347 relplt = htab->irelplt;
1348 }
1349
1350 if (use_plt)
1351 {
1352 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1353 the original value for R_*_IRELATIVE. */
1354 h->plt.offset = plt->size;
1355
1356 /* Make room for this entry in the plt/iplt section. */
1357 plt->size += plt_entry_size;
1358
1359 /* We also need to make an entry in the got.plt/got.iplt section,
1360 which will be placed in the got section by the linker script. */
1361 gotplt->size += got_entry_size;
1362 }
1363
1364 /* We also need to make an entry in the rela.plt/.rela.iplt
1365 section for GOTPLT relocation if PLT is used. */
1366 if (use_plt)
1367 {
1368 relplt->size += sizeof_reloc;
1369 relplt->reloc_count++;
1370 }
1371
1372 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1373 there is a non-GOT reference in a PIC object or PLT isn't used. */
1374 if (!need_dynreloc || !h->non_got_ref)
1375 *head = NULL;
1376
1377 /* Finally, allocate space. */
1378 p = *head;
1379 if (p != NULL)
1380 {
1381 bfd_size_type count = 0;
1382 do
1383 {
1384 count += p->count;
1385 p = p->next;
1386 }
1387 while (p != NULL);
1388
1389 htab->ifunc_resolvers = count != 0;
1390
1391 /* Dynamic relocations are stored in
1392 1. rela.srelgot section in PIC object.
1393 2. rela.srelgot section in dynamic executable.
1394 3. rela.irelplt section in static executable. */
1395 if (htab->splt != NULL)
1396 htab->srelgot->size += count * sizeof_reloc;
1397 else
1398 {
1399 relplt->size += count * sizeof_reloc;
1400 relplt->reloc_count += count;
1401 }
1402 }
1403
1404 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1405 and got has the PLT entry adddress. We will load the GOT entry
1406 with the PLT entry in finish_dynamic_symbol if it is used. For
1407 branch, it uses got.plt. For symbol value, if PLT is used,
1408 1. Use got.plt in a PIC object if it is forced local or not
1409 dynamic.
1410 2. Use got.plt in a non-PIC object if pointer equality isn't
1411 needed.
1412 3. Use got.plt in PIE.
1413 4. Use got.plt if got isn't used.
1414 5. Otherwise use got so that it can be shared among different
1415 objects at run-time.
1416 If PLT isn't used, always use got for symbol value.
1417 We only need to relocate got entry in PIC object or in dynamic
1418 executable without PLT. */
1419 if (use_plt
1420 && (h->got.refcount <= 0
1421 || (bfd_link_pic (info)
1422 && (h->dynindx == -1
1423 || h->forced_local))
1424 || (
1425 !h->pointer_equality_needed)
1426 || htab->sgot == NULL))
1427 {
1428 /* Use got.plt. */
1429 h->got.offset = (bfd_vma) -1;
1430 }
1431 else
1432 {
1433 if (!use_plt)
1434 {
1435 /* PLT isn't used. */
1436 h->plt.offset = (bfd_vma) -1;
1437 }
1438 if (h->got.refcount <= 0)
1439 {
1440 /* GOT isn't need when there are only relocations for static
1441 pointers. */
1442 h->got.offset = (bfd_vma) -1;
1443 }
1444 else
1445 {
1446 h->got.offset = htab->sgot->size;
1447 htab->sgot->size += got_entry_size;
1448 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1449 used. Otherwise, the GOT entry will be filled with the PLT
1450 entry and dynamic GOT relocation isn't needed. */
1451 if (need_dynreloc)
1452 {
1453 /* For non-static executable, dynamic GOT relocation is in
1454 rela.got section, but for static executable, it is
1455 in rela.iplt section. */
1456 if (htab->splt != NULL)
1457 htab->srelgot->size += sizeof_reloc;
1458 else
1459 {
1460 relplt->size += sizeof_reloc;
1461 relplt->reloc_count++;
1462 }
1463 }
1464 }
1465 }
1466
1467 return true;
1468 }
1469
1470 /* Allocate space in .plt, .got and associated reloc sections for
1471 ifunc dynamic relocs. */
1472
1473 static bool
1474 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1475 {
1476 struct bfd_link_info *info;
1477 /* An example of a bfd_link_hash_indirect symbol is versioned
1478 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1479 -> __gxx_personality_v0(bfd_link_hash_defined)
1480
1481 There is no need to process bfd_link_hash_indirect symbols here
1482 because we will also be presented with the concrete instance of
1483 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1484 called to copy all relevant data from the generic to the concrete
1485 symbol instance. */
1486 if (h->root.type == bfd_link_hash_indirect)
1487 return true;
1488
1489 if (h->root.type == bfd_link_hash_warning)
1490 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1491
1492 info = (struct bfd_link_info *) inf;
1493
1494 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1495 here if it is defined and referenced in a non-shared object. */
1496 if (h->type == STT_GNU_IFUNC && h->def_regular)
1497 {
1498 if (SYMBOL_REFERENCES_LOCAL (info, h))
1499 return local_allocate_ifunc_dyn_relocs (info, h,
1500 &h->dyn_relocs,
1501 PLT_ENTRY_SIZE,
1502 PLT_HEADER_SIZE,
1503 GOT_ENTRY_SIZE,
1504 false);
1505 else
1506 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1507 &h->dyn_relocs,
1508 PLT_ENTRY_SIZE,
1509 PLT_HEADER_SIZE,
1510 GOT_ENTRY_SIZE,
1511 false);
1512 }
1513
1514 return true;
1515 }
1516
1517 /* Allocate space in .plt, .got and associated reloc sections for
1518 ifunc dynamic relocs. */
1519
1520 static bool
1521 elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1522 {
1523 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1524
1525 if (h->type != STT_GNU_IFUNC
1526 || !h->def_regular
1527 || !h->ref_regular
1528 || !h->forced_local
1529 || h->root.type != bfd_link_hash_defined)
1530 abort ();
1531
1532 return elfNN_allocate_ifunc_dynrelocs (h, inf);
1533 }
1534
1535 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1536 read-only sections. */
1537
1538 static bool
1539 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1540 {
1541 asection *sec;
1542
1543 if (h->root.type == bfd_link_hash_indirect)
1544 return true;
1545
1546 sec = readonly_dynrelocs (h);
1547 if (sec != NULL)
1548 {
1549 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1550
1551 info->flags |= DF_TEXTREL;
1552 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1553 "read-only section `%pA'\n"),
1554 sec->owner, h->root.root.string, sec);
1555
1556 /* Not an error, just cut short the traversal. */
1557 return false;
1558 }
1559 return true;
1560 }
1561
1562 static bool
1563 loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1564 struct bfd_link_info *info)
1565 {
1566 struct loongarch_elf_link_hash_table *htab;
1567 bfd *dynobj;
1568 asection *s;
1569 bfd *ibfd;
1570
1571 htab = loongarch_elf_hash_table (info);
1572 BFD_ASSERT (htab != NULL);
1573 dynobj = htab->elf.dynobj;
1574 BFD_ASSERT (dynobj != NULL);
1575
1576 if (htab->elf.dynamic_sections_created)
1577 {
1578 /* Set the contents of the .interp section to the interpreter. */
1579 if (bfd_link_executable (info) && !info->nointerp)
1580 {
1581 const char *interpreter;
1582 flagword flags = elf_elfheader (output_bfd)->e_flags;
1583 s = bfd_get_linker_section (dynobj, ".interp");
1584 BFD_ASSERT (s != NULL);
1585 if (EF_LOONGARCH_IS_ILP32 (flags))
1586 interpreter = "/lib32/ld.so.1";
1587 else if (EF_LOONGARCH_IS_LP64 (flags))
1588 interpreter = "/lib64/ld.so.1";
1589 else
1590 interpreter = "/lib/ld.so.1";
1591 s->contents = (unsigned char *) interpreter;
1592 s->size = strlen (interpreter) + 1;
1593 }
1594 }
1595
1596 /* Set up .got offsets for local syms, and space for local dynamic
1597 relocs. */
1598 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1599 {
1600 bfd_signed_vma *local_got;
1601 bfd_signed_vma *end_local_got;
1602 char *local_tls_type;
1603 bfd_size_type locsymcount;
1604 Elf_Internal_Shdr *symtab_hdr;
1605 asection *srel;
1606
1607 if (!is_loongarch_elf (ibfd))
1608 continue;
1609
1610 for (s = ibfd->sections; s != NULL; s = s->next)
1611 {
1612 struct elf_dyn_relocs *p;
1613
1614 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1615 {
1616 p->count -= p->pc_count;
1617 if (!bfd_is_abs_section (p->sec)
1618 && bfd_is_abs_section (p->sec->output_section))
1619 {
1620 /* Input section has been discarded, either because
1621 it is a copy of a linkonce section or due to
1622 linker script /DISCARD/, so we'll be discarding
1623 the relocs too. */
1624 }
1625 else if (0 < p->count)
1626 {
1627 srel = elf_section_data (p->sec)->sreloc;
1628 srel->size += p->count * sizeof (ElfNN_External_Rela);
1629 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1630 info->flags |= DF_TEXTREL;
1631 }
1632 }
1633 }
1634
1635 local_got = elf_local_got_refcounts (ibfd);
1636 if (!local_got)
1637 continue;
1638
1639 symtab_hdr = &elf_symtab_hdr (ibfd);
1640 locsymcount = symtab_hdr->sh_info;
1641 end_local_got = local_got + locsymcount;
1642 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1643 s = htab->elf.sgot;
1644 srel = htab->elf.srelgot;
1645 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1646 {
1647 if (0 < *local_got)
1648 {
1649 *local_got = s->size;
1650
1651 /* TLS gd use two got. */
1652 if (*local_tls_type & GOT_TLS_GD)
1653 s->size += GOT_ENTRY_SIZE * 2;
1654 else
1655 /* Normal got, tls ie/ld use one got. */
1656 s->size += GOT_ENTRY_SIZE;
1657
1658 if (bfd_link_executable (info)
1659 && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
1660 ;/* Do nothing. */
1661 else
1662 {
1663 srel->size += sizeof (ElfNN_External_Rela);
1664 }
1665 }
1666 else
1667 *local_got = MINUS_ONE;
1668 }
1669 }
1670
1671 /* Allocate global sym .plt and .got entries, and space for global
1672 sym dynamic relocs. */
1673 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1674
1675 /* Allocate global ifunc sym .plt and .got entries, and space for global
1676 ifunc sym dynamic relocs. */
1677 elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
1678
1679 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1680 htab_traverse (htab->loc_hash_table,
1681 (void *) elfNN_allocate_local_ifunc_dynrelocs, info);
1682
1683 /* Don't allocate .got.plt section if there are no PLT. */
1684 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1685 && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1686 htab->elf.sgotplt->size = 0;
1687
1688 /* The check_relocs and adjust_dynamic_symbol entry points have
1689 determined the sizes of the various dynamic sections. Allocate
1690 memory for them. */
1691 for (s = dynobj->sections; s != NULL; s = s->next)
1692 {
1693 if ((s->flags & SEC_LINKER_CREATED) == 0)
1694 continue;
1695
1696 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1697 || s == htab->elf.sgotplt || s == htab->elf.igotplt
1698 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1699 {
1700 /* Strip this section if we don't need it; see the
1701 comment below. */
1702 }
1703 else if (strncmp (s->name, ".rela", 5) == 0)
1704 {
1705 if (s->size != 0)
1706 {
1707 /* We use the reloc_count field as a counter if we need
1708 to copy relocs into the output file. */
1709 s->reloc_count = 0;
1710 }
1711 }
1712 else
1713 {
1714 /* It's not one of our sections. */
1715 continue;
1716 }
1717
1718 if (s->size == 0)
1719 {
1720 /* If we don't need this section, strip it from the
1721 output file. This is mostly to handle .rela.bss and
1722 .rela.plt. We must create both sections in
1723 create_dynamic_sections, because they must be created
1724 before the linker maps input sections to output
1725 sections. The linker does that before
1726 adjust_dynamic_symbol is called, and it is that
1727 function which decides whether anything needs to go
1728 into these sections. */
1729 s->flags |= SEC_EXCLUDE;
1730 continue;
1731 }
1732
1733 if ((s->flags & SEC_HAS_CONTENTS) == 0)
1734 continue;
1735
1736 /* Allocate memory for the section contents. Zero the memory
1737 for the benefit of .rela.plt, which has 4 unused entries
1738 at the beginning, and we don't want garbage. */
1739 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1740 if (s->contents == NULL)
1741 return false;
1742 }
1743
1744 if (elf_hash_table (info)->dynamic_sections_created)
1745 {
1746 /* Add some entries to the .dynamic section. We fill in the
1747 values later, in loongarch_elf_finish_dynamic_sections, but we
1748 must add the entries now so that we get the correct size for
1749 the .dynamic section. The DT_DEBUG entry is filled in by the
1750 dynamic linker and used by the debugger. */
1751 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1752
1753 if (bfd_link_executable (info))
1754 {
1755 if (!add_dynamic_entry (DT_DEBUG, 0))
1756 return false;
1757 }
1758
1759 if (htab->elf.srelplt->size != 0)
1760 {
1761 if (!add_dynamic_entry (DT_PLTGOT, 0)
1762 || !add_dynamic_entry (DT_PLTRELSZ, 0)
1763 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1764 || !add_dynamic_entry (DT_JMPREL, 0))
1765 return false;
1766 }
1767
1768 if (!add_dynamic_entry (DT_RELA, 0)
1769 || !add_dynamic_entry (DT_RELASZ, 0)
1770 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1771 return false;
1772
1773 /* If any dynamic relocs apply to a read-only section,
1774 then we need a DT_TEXTREL entry. */
1775 if ((info->flags & DF_TEXTREL) == 0)
1776 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1777
1778 if (info->flags & DF_TEXTREL)
1779 {
1780 if (!add_dynamic_entry (DT_TEXTREL, 0))
1781 return false;
1782 /* Clear the DF_TEXTREL flag. It will be set again if we
1783 write out an actual text relocation; we may not, because
1784 at this point we do not know whether e.g. any .eh_frame
1785 absolute relocations have been converted to PC-relative. */
1786 info->flags &= ~DF_TEXTREL;
1787 }
1788 }
1789 #undef add_dynamic_entry
1790
1791 return true;
1792 }
1793
1794 #define LARCH_LD_STACK_DEPTH 16
1795 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1796 static size_t larch_stack_top = 0;
1797
1798 static bfd_reloc_status_type
1799 loongarch_push (int64_t val)
1800 {
1801 if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1802 return bfd_reloc_outofrange;
1803 larch_opc_stack[larch_stack_top++] = val;
1804 return bfd_reloc_ok;
1805 }
1806
1807 static bfd_reloc_status_type
1808 loongarch_pop (int64_t *val)
1809 {
1810 if (larch_stack_top == 0)
1811 return bfd_reloc_outofrange;
1812 BFD_ASSERT (val);
1813 *val = larch_opc_stack[--larch_stack_top];
1814 return bfd_reloc_ok;
1815 }
1816
1817 static bfd_reloc_status_type
1818 loongarch_top (int64_t *val)
1819 {
1820 if (larch_stack_top == 0)
1821 return bfd_reloc_outofrange;
1822 BFD_ASSERT (val);
1823 *val = larch_opc_stack[larch_stack_top - 1];
1824 return bfd_reloc_ok;
1825 }
1826
1827 static void
1828 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
1829 {
1830 BFD_ASSERT (s && s->contents);
1831 const struct elf_backend_data *bed;
1832 bfd_byte *loc;
1833
1834 bed = get_elf_backend_data (abfd);
1835 if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
1836 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
1837 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
1838 bed->s->swap_reloca_out (abfd, rel, loc);
1839 }
1840
1841 /* Check rel->r_offset in range of contents. */
1842 static bfd_reloc_status_type
1843 loongarch_check_offset (const Elf_Internal_Rela *rel,
1844 const asection *input_section)
1845 {
1846 if (0 == strcmp(input_section->name, ".text")
1847 && rel->r_offset > input_section->size)
1848 return bfd_reloc_overflow;
1849
1850 return bfd_reloc_ok;
1851 }
1852
1853 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
1854 ({ \
1855 bfd_reloc_status_type ret = loongarch_pop (&op2); \
1856 if (ret == bfd_reloc_ok) \
1857 { \
1858 ret = loongarch_pop (&op1); \
1859 if (ret == bfd_reloc_ok) \
1860 ret = loongarch_push (op3); \
1861 } \
1862 ret; \
1863 })
1864
1865 static bfd_reloc_status_type
1866 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
1867 const asection *input_section ATTRIBUTE_UNUSED,
1868 reloc_howto_type *howto, bfd *input_bfd,
1869 bfd_byte *contents, bfd_vma reloc_val)
1870 {
1871 int bits = bfd_get_reloc_size (howto) * 8;
1872 uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
1873
1874 if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
1875 return bfd_reloc_overflow;
1876
1877 insn = (insn & (uint32_t)howto->src_mask)
1878 | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
1879
1880 bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
1881
1882 return bfd_reloc_ok;
1883 }
1884
1885 static bfd_reloc_status_type
1886 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
1887 reloc_howto_type *howto, bfd_vma value,
1888 bfd *input_bfd, bfd_byte *contents)
1889 {
1890 int64_t opr1, opr2, opr3;
1891 bfd_reloc_status_type r = bfd_reloc_ok;
1892 int bits = bfd_get_reloc_size (howto) * 8;
1893
1894 switch (ELFNN_R_TYPE (rel->r_info))
1895 {
1896 case R_LARCH_SOP_PUSH_PCREL:
1897 case R_LARCH_SOP_PUSH_ABSOLUTE:
1898 case R_LARCH_SOP_PUSH_GPREL:
1899 case R_LARCH_SOP_PUSH_TLS_TPREL:
1900 case R_LARCH_SOP_PUSH_TLS_GOT:
1901 case R_LARCH_SOP_PUSH_TLS_GD:
1902 case R_LARCH_SOP_PUSH_PLT_PCREL:
1903 r = loongarch_push (value);
1904 break;
1905
1906 case R_LARCH_SOP_PUSH_DUP:
1907 r = loongarch_pop (&opr1);
1908 if (r == bfd_reloc_ok)
1909 {
1910 r = loongarch_push (opr1);
1911 if (r == bfd_reloc_ok)
1912 r = loongarch_push (opr1);
1913 }
1914 break;
1915
1916 case R_LARCH_SOP_ASSERT:
1917 r = loongarch_pop (&opr1);
1918 if (r != bfd_reloc_ok || !opr1)
1919 r = bfd_reloc_notsupported;
1920 break;
1921
1922 case R_LARCH_SOP_NOT:
1923 r = loongarch_pop (&opr1);
1924 if (r == bfd_reloc_ok)
1925 r = loongarch_push (!opr1);
1926 break;
1927
1928 case R_LARCH_SOP_SUB:
1929 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
1930 break;
1931
1932 case R_LARCH_SOP_SL:
1933 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
1934 break;
1935
1936 case R_LARCH_SOP_SR:
1937 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
1938 break;
1939
1940 case R_LARCH_SOP_AND:
1941 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
1942 break;
1943
1944 case R_LARCH_SOP_ADD:
1945 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
1946 break;
1947
1948 case R_LARCH_SOP_IF_ELSE:
1949 r = loongarch_pop (&opr3);
1950 if (r == bfd_reloc_ok)
1951 {
1952 r = loongarch_pop (&opr2);
1953 if (r == bfd_reloc_ok)
1954 {
1955 r = loongarch_pop (&opr1);
1956 if (r == bfd_reloc_ok)
1957 r = loongarch_push (opr1 ? opr2 : opr3);
1958 }
1959 }
1960 break;
1961
1962 case R_LARCH_SOP_POP_32_S_10_5:
1963 case R_LARCH_SOP_POP_32_S_10_12:
1964 case R_LARCH_SOP_POP_32_S_10_16:
1965 case R_LARCH_SOP_POP_32_S_10_16_S2:
1966 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
1967 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
1968 case R_LARCH_SOP_POP_32_S_5_20:
1969 case R_LARCH_SOP_POP_32_U_10_12:
1970 case R_LARCH_SOP_POP_32_U:
1971 r = loongarch_pop (&opr1);
1972 if (r != bfd_reloc_ok)
1973 break;
1974 r = loongarch_check_offset (rel, input_section);
1975 if (r != bfd_reloc_ok)
1976 break;
1977
1978 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
1979 howto, input_bfd,
1980 contents, (bfd_vma)opr1);
1981 break;
1982
1983 case R_LARCH_TLS_DTPREL32:
1984 case R_LARCH_32:
1985 case R_LARCH_TLS_DTPREL64:
1986 case R_LARCH_64:
1987 r = loongarch_check_offset (rel, input_section);
1988 if (r != bfd_reloc_ok)
1989 break;
1990
1991 bfd_put (bits, input_bfd, value, contents + rel->r_offset);
1992 break;
1993
1994 case R_LARCH_ADD8:
1995 case R_LARCH_ADD16:
1996 case R_LARCH_ADD24:
1997 case R_LARCH_ADD32:
1998 case R_LARCH_ADD64:
1999 r = loongarch_check_offset (rel, input_section);
2000 if (r != bfd_reloc_ok)
2001 break;
2002
2003 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
2004 bfd_put (bits, input_bfd, opr1 + value, contents + rel->r_offset);
2005 break;
2006
2007 case R_LARCH_SUB8:
2008 case R_LARCH_SUB16:
2009 case R_LARCH_SUB24:
2010 case R_LARCH_SUB32:
2011 case R_LARCH_SUB64:
2012 r = loongarch_check_offset (rel, input_section);
2013 if (r != bfd_reloc_ok)
2014 break;
2015
2016 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
2017 bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
2018 break;
2019
2020 /* For eh_frame and debug info. */
2021 case R_LARCH_32_PCREL:
2022 value -= sec_addr (input_section) + rel->r_offset;
2023 value += rel->r_addend;
2024 bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2025 contents + rel->r_offset);
2026 word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2027 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2028 r = bfd_reloc_ok;
2029 break;
2030
2031 /* New reloc type.
2032 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2033 case R_LARCH_B16:
2034 case R_LARCH_B21:
2035 case R_LARCH_B26:
2036 case R_LARCH_ABS_HI20:
2037 case R_LARCH_ABS_LO12:
2038 case R_LARCH_ABS64_LO20:
2039 case R_LARCH_ABS64_HI12:
2040 case R_LARCH_PCALA_HI20:
2041 case R_LARCH_PCALA_LO12:
2042 case R_LARCH_PCALA64_LO20:
2043 case R_LARCH_PCALA64_HI12:
2044 case R_LARCH_GOT_PC_HI20:
2045 case R_LARCH_GOT_PC_LO12:
2046 case R_LARCH_GOT64_PC_LO20:
2047 case R_LARCH_GOT64_PC_HI12:
2048 case R_LARCH_GOT_HI20:
2049 case R_LARCH_GOT_LO12:
2050 case R_LARCH_GOT64_LO20:
2051 case R_LARCH_GOT64_HI12:
2052 case R_LARCH_TLS_LE_HI20:
2053 case R_LARCH_TLS_LE_LO12:
2054 case R_LARCH_TLS_LE64_LO20:
2055 case R_LARCH_TLS_LE64_HI12:
2056 case R_LARCH_TLS_IE_PC_HI20:
2057 case R_LARCH_TLS_IE_PC_LO12:
2058 case R_LARCH_TLS_IE64_PC_LO20:
2059 case R_LARCH_TLS_IE64_PC_HI12:
2060 case R_LARCH_TLS_IE_HI20:
2061 case R_LARCH_TLS_IE_LO12:
2062 case R_LARCH_TLS_IE64_LO20:
2063 case R_LARCH_TLS_IE64_HI12:
2064 case R_LARCH_TLS_LD_PC_HI20:
2065 case R_LARCH_TLS_LD_HI20:
2066 case R_LARCH_TLS_GD_PC_HI20:
2067 case R_LARCH_TLS_GD_HI20:
2068 r = loongarch_check_offset (rel, input_section);
2069 if (r != bfd_reloc_ok)
2070 break;
2071
2072 r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2073 howto, input_bfd,
2074 contents, value);
2075 break;
2076
2077 case R_LARCH_RELAX:
2078 break;
2079
2080 default:
2081 r = bfd_reloc_notsupported;
2082 }
2083 return r;
2084 }
2085
2086 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2087 static struct
2088 {
2089 bfd *bfd;
2090 asection *section;
2091 bfd_vma r_offset;
2092 int r_type;
2093 bfd_vma relocation;
2094 Elf_Internal_Sym *sym;
2095 struct elf_link_hash_entry *h;
2096 bfd_vma addend;
2097 int64_t top_then;
2098 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2099 static size_t larch_reloc_queue_head = 0;
2100 static size_t larch_reloc_queue_tail = 0;
2101
2102 static const char *
2103 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2104 Elf_Internal_Sym *sym)
2105 {
2106 const char *ret = NULL;
2107 if (sym)
2108 ret = bfd_elf_string_from_elf_section (input_bfd,
2109 elf_symtab_hdr (input_bfd).sh_link,
2110 sym->st_name);
2111 else if (h)
2112 ret = h->root.root.string;
2113
2114 if (ret == NULL || *ret == '\0')
2115 ret = "<nameless>";
2116 return ret;
2117 }
2118
2119 static void
2120 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2121 bfd_vma r_offset, Elf_Internal_Sym *sym,
2122 struct elf_link_hash_entry *h, bfd_vma addend)
2123 {
2124 if ((larch_reloc_queue_head == 0
2125 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2126 || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2127 larch_reloc_queue_head =
2128 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2129 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2130 larch_reloc_queue[larch_reloc_queue_tail].section = section;
2131 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2132 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2133 larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2134 larch_reloc_queue[larch_reloc_queue_tail].h = h;
2135 larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2136 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2137 larch_reloc_queue_tail =
2138 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2139 }
2140
2141 static void
2142 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2143 {
2144 size_t i = larch_reloc_queue_head;
2145 bfd *a_bfd = NULL;
2146 asection *section = NULL;
2147 bfd_vma r_offset = 0;
2148 int inited = 0;
2149 p ("Dump relocate record:\n");
2150 p ("stack top\t\trelocation name\t\tsymbol");
2151 while (i != larch_reloc_queue_tail)
2152 {
2153 if (a_bfd != larch_reloc_queue[i].bfd
2154 || section != larch_reloc_queue[i].section
2155 || r_offset != larch_reloc_queue[i].r_offset)
2156 {
2157 a_bfd = larch_reloc_queue[i].bfd;
2158 section = larch_reloc_queue[i].section;
2159 r_offset = larch_reloc_queue[i].r_offset;
2160 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2161 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2162 }
2163
2164 if (!inited)
2165 inited = 1, p ("...\n");
2166
2167 reloc_howto_type *howto =
2168 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2169 larch_reloc_queue[i].r_type);
2170 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2171 howto ? howto->name : "<unknown reloc>",
2172 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2173 larch_reloc_queue[i].sym));
2174
2175 long addend = larch_reloc_queue[i].addend;
2176 if (addend < 0)
2177 p (" - %ld", -addend);
2178 else if (0 < addend)
2179 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2180
2181 p ("\n");
2182 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2183 }
2184 p ("\n"
2185 "-- Record dump end --\n\n");
2186 }
2187
2188 static bool
2189 loongarch_reloc_is_fatal (struct bfd_link_info *info,
2190 bfd *input_bfd,
2191 asection *input_section,
2192 Elf_Internal_Rela *rel,
2193 reloc_howto_type *howto,
2194 bfd_reloc_status_type rtype,
2195 bool is_undefweak,
2196 const char *name,
2197 const char *msg)
2198 {
2199 bool fatal = true;
2200 switch (rtype)
2201 {
2202 /* 'dangerous' means we do it but can't promise it's ok
2203 'unsupport' means out of ability of relocation type
2204 'undefined' means we can't deal with the undefined symbol. */
2205 case bfd_reloc_undefined:
2206 info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2207 rel->r_offset, true);
2208 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2209 input_bfd, input_section, rel->r_offset,
2210 howto->name,
2211 is_undefweak ? "[undefweak] " : "", name, msg);
2212 break;
2213 case bfd_reloc_dangerous:
2214 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2215 input_bfd, input_section, rel->r_offset,
2216 howto->name,
2217 is_undefweak ? "[undefweak] " : "", name, msg);
2218 fatal = false;
2219 break;
2220 case bfd_reloc_notsupported:
2221 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2222 input_bfd, input_section, rel->r_offset,
2223 howto->name,
2224 is_undefweak ? "[undefweak] " : "", name, msg);
2225 break;
2226 default:
2227 break;
2228 }
2229 return fatal;
2230 }
2231
2232 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2233 ({ \
2234 bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
2235 pc = pc & (~(bfd_vma)0xfff); \
2236 if (lo > 0x7ff) \
2237 { \
2238 relocation += 0x1000; \
2239 } \
2240 relocation &= ~(bfd_vma)0xfff; \
2241 relocation -= pc; \
2242 })
2243
2244 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2245 ({ \
2246 bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
2247 if (lo > 0x7ff) \
2248 { \
2249 relocation -= 0x100000000; \
2250 } \
2251 relocation -= (pc & ~(bfd_vma)0xffffffff); \
2252 })
2253
2254 static int
2255 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2256 bfd *input_bfd, asection *input_section,
2257 bfd_byte *contents, Elf_Internal_Rela *relocs,
2258 Elf_Internal_Sym *local_syms,
2259 asection **local_sections)
2260 {
2261 Elf_Internal_Rela *rel;
2262 Elf_Internal_Rela *relend;
2263 bool fatal = false;
2264 asection *sreloc = elf_section_data (input_section)->sreloc;
2265 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2266 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2267 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2268 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2269 bool is_pic = bfd_link_pic (info);
2270 bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2271 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2272 asection *got = htab->elf.sgot;
2273
2274 relend = relocs + input_section->reloc_count;
2275 for (rel = relocs; rel < relend; rel++)
2276 {
2277 int r_type = ELFNN_R_TYPE (rel->r_info);
2278 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2279 bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2280 reloc_howto_type *howto = NULL;
2281 asection *sec = NULL;
2282 Elf_Internal_Sym *sym = NULL;
2283 struct elf_link_hash_entry *h = NULL;
2284 const char *name;
2285 bfd_reloc_status_type r = bfd_reloc_ok;
2286 bool is_ie, is_undefweak, unresolved_reloc, defined_local;
2287 bool resolved_local, resolved_dynly, resolved_to_const;
2288 char tls_type;
2289 bfd_vma relocation, off, ie_off;
2290 int i, j;
2291
2292 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2293 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2294 || r_type == R_LARCH_GNU_VTENTRY)
2295 continue;
2296
2297 /* This is a final link. */
2298 if (r_symndx < symtab_hdr->sh_info)
2299 {
2300 is_undefweak = false;
2301 unresolved_reloc = false;
2302 sym = local_syms + r_symndx;
2303 sec = local_sections[r_symndx];
2304 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2305
2306 /* Relocate against local STT_GNU_IFUNC symbol. */
2307 if (!bfd_link_relocatable (info)
2308 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2309 {
2310 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2311 false);
2312 if (h == NULL)
2313 abort ();
2314
2315 /* Set STT_GNU_IFUNC symbol value. */
2316 h->root.u.def.value = sym->st_value;
2317 h->root.u.def.section = sec;
2318 }
2319 defined_local = true;
2320 resolved_local = true;
2321 resolved_dynly = false;
2322 resolved_to_const = false;
2323
2324 /* Calc in funtion elf_link_input_bfd,
2325 * if #define elf_backend_rela_normal to 1. */
2326 if (bfd_link_relocatable (info)
2327 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2328 continue;
2329 }
2330 else
2331 {
2332 bool warned, ignored;
2333
2334 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2335 r_symndx, symtab_hdr, sym_hashes,
2336 h, sec, relocation,
2337 unresolved_reloc, warned, ignored);
2338 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2339
2340 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2341 symbol. And 'dynamic_undefined_weak' specify what to do when
2342 meeting undefweak. */
2343
2344 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2345 {
2346 defined_local = false;
2347 resolved_local = false;
2348 resolved_to_const = (!is_dyn || h->dynindx == -1
2349 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2350 resolved_dynly = !resolved_local && !resolved_to_const;
2351 }
2352 else if (warned)
2353 {
2354 /* Symbol undefined offen means failed already. I don't know why
2355 'warned' here but I guess it want to continue relocating as if
2356 no error occures to find other errors as more as possible. */
2357
2358 /* To avoid generating warning messages about truncated
2359 relocations, set the relocation's address to be the same as
2360 the start of this section. */
2361 relocation = (input_section->output_section
2362 ? input_section->output_section->vma
2363 : 0);
2364
2365 defined_local = relocation != 0;
2366 resolved_local = defined_local;
2367 resolved_to_const = !resolved_local;
2368 resolved_dynly = false;
2369 }
2370 else
2371 {
2372 defined_local = !unresolved_reloc && !ignored;
2373 resolved_local =
2374 defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2375 resolved_dynly = !resolved_local;
2376 resolved_to_const = !resolved_local && !resolved_dynly;
2377 }
2378 }
2379
2380 name = loongarch_sym_name (input_bfd, h, sym);
2381
2382 if (sec != NULL && discarded_section (sec))
2383 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2384 1, relend, howto, 0, contents);
2385
2386 if (bfd_link_relocatable (info))
2387 continue;
2388
2389 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2390 from removed linkonce sections, or sections discarded by a linker
2391 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2392 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2393 {
2394 defined_local = false;
2395 resolved_local = false;
2396 resolved_dynly = false;
2397 resolved_to_const = true;
2398 }
2399
2400 /* The ifunc reference generate plt. */
2401 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2402 {
2403 defined_local = true;
2404 resolved_local = true;
2405 resolved_dynly = false;
2406 resolved_to_const = false;
2407 relocation = sec_addr (plt) + h->plt.offset;
2408 }
2409
2410 unresolved_reloc = resolved_dynly;
2411
2412 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2413
2414 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2415
2416 BFD_ASSERT (!resolved_local || defined_local);
2417
2418 is_ie = false;
2419 switch (r_type)
2420 {
2421 case R_LARCH_MARK_PCREL:
2422 case R_LARCH_MARK_LA:
2423 case R_LARCH_NONE:
2424 r = bfd_reloc_continue;
2425 unresolved_reloc = false;
2426 break;
2427
2428 case R_LARCH_32:
2429 case R_LARCH_64:
2430 if (resolved_dynly || (is_pic && resolved_local))
2431 {
2432 Elf_Internal_Rela outrel;
2433
2434 /* When generating a shared object, these relocations are copied
2435 into the output file to be resolved at run time. */
2436
2437 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2438 input_section,
2439 rel->r_offset);
2440
2441 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2442 && (input_section->flags & SEC_ALLOC));
2443
2444 outrel.r_offset += sec_addr (input_section);
2445
2446 /* A pointer point to a ifunc symbol. */
2447 if (h && h->type == STT_GNU_IFUNC)
2448 {
2449 if (h->dynindx == -1)
2450 {
2451 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2452 outrel.r_addend = (h->root.u.def.value
2453 + h->root.u.def.section->output_section->vma
2454 + h->root.u.def.section->output_offset);
2455 }
2456 else
2457 {
2458 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2459 outrel.r_addend = 0;
2460 }
2461
2462 if (SYMBOL_REFERENCES_LOCAL (info, h))
2463 {
2464
2465 if (htab->elf.splt != NULL)
2466 sreloc = htab->elf.srelgot;
2467 else
2468 sreloc = htab->elf.irelplt;
2469 }
2470 else
2471 {
2472
2473 if (bfd_link_pic (info))
2474 sreloc = htab->elf.irelifunc;
2475 else if (htab->elf.splt != NULL)
2476 sreloc = htab->elf.srelgot;
2477 else
2478 sreloc = htab->elf.irelplt;
2479 }
2480 }
2481 else if (resolved_dynly)
2482 {
2483 if (h->dynindx == -1)
2484 {
2485 if (h->root.type == bfd_link_hash_undefined)
2486 (*info->callbacks->undefined_symbol)
2487 (info, name, input_bfd, input_section,
2488 rel->r_offset, true);
2489
2490 outrel.r_info = ELFNN_R_INFO (0, r_type);
2491 }
2492 else
2493 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2494
2495 outrel.r_addend = rel->r_addend;
2496 }
2497 else
2498 {
2499 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2500 outrel.r_addend = relocation + rel->r_addend;
2501 }
2502
2503 /* No alloc space of func allocate_dynrelocs. */
2504 if (unresolved_reloc
2505 && !(h && (h->is_weakalias || !h->dyn_relocs)))
2506 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2507 }
2508
2509 relocation += rel->r_addend;
2510 break;
2511
2512 case R_LARCH_ADD8:
2513 case R_LARCH_ADD16:
2514 case R_LARCH_ADD24:
2515 case R_LARCH_ADD32:
2516 case R_LARCH_ADD64:
2517 case R_LARCH_SUB8:
2518 case R_LARCH_SUB16:
2519 case R_LARCH_SUB24:
2520 case R_LARCH_SUB32:
2521 case R_LARCH_SUB64:
2522 if (resolved_dynly)
2523 fatal = (loongarch_reloc_is_fatal
2524 (info, input_bfd, input_section, rel, howto,
2525 bfd_reloc_undefined, is_undefweak, name,
2526 "Can't be resolved dynamically. "
2527 "If this procedure is hand-written assembly,\n"
2528 "there must be something like '.dword sym1 - sym2' "
2529 "to generate these relocs\n"
2530 "and we can't get known link-time address of "
2531 "these symbols."));
2532 else
2533 relocation += rel->r_addend;
2534 break;
2535
2536 case R_LARCH_TLS_DTPREL32:
2537 case R_LARCH_TLS_DTPREL64:
2538 if (resolved_dynly)
2539 {
2540 Elf_Internal_Rela outrel;
2541
2542 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2543 input_section,
2544 rel->r_offset);
2545 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2546 && (input_section->flags & SEC_ALLOC));
2547 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2548 outrel.r_offset += sec_addr (input_section);
2549 outrel.r_addend = rel->r_addend;
2550 if (unresolved_reloc)
2551 loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2552 break;
2553 }
2554
2555 if (resolved_to_const)
2556 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2557 rel, howto,
2558 bfd_reloc_notsupported,
2559 is_undefweak, name,
2560 "Internal:");
2561 if (resolved_local)
2562 {
2563 if (!elf_hash_table (info)->tls_sec)
2564 {
2565 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2566 input_section, rel, howto, bfd_reloc_notsupported,
2567 is_undefweak, name, "TLS section not be created");
2568 }
2569 else
2570 relocation -= elf_hash_table (info)->tls_sec->vma;
2571 }
2572 else
2573 {
2574 fatal = loongarch_reloc_is_fatal (info, input_bfd,
2575 input_section, rel, howto, bfd_reloc_undefined,
2576 is_undefweak, name,
2577 "TLS LE just can be resolved local only.");
2578 }
2579
2580 break;
2581
2582 case R_LARCH_SOP_PUSH_TLS_TPREL:
2583 if (resolved_local)
2584 {
2585 if (!elf_hash_table (info)->tls_sec)
2586 fatal = (loongarch_reloc_is_fatal
2587 (info, input_bfd, input_section, rel, howto,
2588 bfd_reloc_notsupported, is_undefweak, name,
2589 "TLS section not be created"));
2590 else
2591 relocation -= elf_hash_table (info)->tls_sec->vma;
2592 }
2593 else
2594 fatal = (loongarch_reloc_is_fatal
2595 (info, input_bfd, input_section, rel, howto,
2596 bfd_reloc_undefined, is_undefweak, name,
2597 "TLS LE just can be resolved local only."));
2598 break;
2599
2600 case R_LARCH_SOP_PUSH_ABSOLUTE:
2601 if (is_undefweak)
2602 {
2603 if (resolved_dynly)
2604 fatal = (loongarch_reloc_is_fatal
2605 (info, input_bfd, input_section, rel, howto,
2606 bfd_reloc_dangerous, is_undefweak, name,
2607 "Someone require us to resolve undefweak "
2608 "symbol dynamically. \n"
2609 "But this reloc can't be done. "
2610 "I think I can't throw error "
2611 "for this\n"
2612 "so I resolved it to 0. "
2613 "I suggest to re-compile with '-fpic'."));
2614
2615 relocation = 0;
2616 unresolved_reloc = false;
2617 break;
2618 }
2619
2620 if (resolved_to_const)
2621 {
2622 relocation += rel->r_addend;
2623 break;
2624 }
2625
2626 if (is_pic)
2627 {
2628 fatal = (loongarch_reloc_is_fatal
2629 (info, input_bfd, input_section, rel, howto,
2630 bfd_reloc_notsupported, is_undefweak, name,
2631 "Under PIC we don't know load address. Re-compile "
2632 "with '-fpic'?"));
2633 break;
2634 }
2635
2636 if (resolved_dynly)
2637 {
2638 if (!(plt && h && h->plt.offset != MINUS_ONE))
2639 {
2640 fatal = (loongarch_reloc_is_fatal
2641 (info, input_bfd, input_section, rel, howto,
2642 bfd_reloc_undefined, is_undefweak, name,
2643 "Can't be resolved dynamically. Try to re-compile "
2644 "with '-fpic'?"));
2645 break;
2646 }
2647
2648 if (rel->r_addend != 0)
2649 {
2650 fatal = (loongarch_reloc_is_fatal
2651 (info, input_bfd, input_section, rel, howto,
2652 bfd_reloc_notsupported, is_undefweak, name,
2653 "Shouldn't be with r_addend."));
2654 break;
2655 }
2656
2657 relocation = sec_addr (plt) + h->plt.offset;
2658 unresolved_reloc = false;
2659 break;
2660 }
2661
2662 if (resolved_local)
2663 {
2664 relocation += rel->r_addend;
2665 break;
2666 }
2667
2668 break;
2669
2670 case R_LARCH_SOP_PUSH_PCREL:
2671 case R_LARCH_SOP_PUSH_PLT_PCREL:
2672 unresolved_reloc = false;
2673
2674 if (is_undefweak)
2675 {
2676 i = 0, j = 0;
2677 relocation = 0;
2678 if (resolved_dynly)
2679 {
2680 if (h && h->plt.offset != MINUS_ONE)
2681 i = 1, j = 2;
2682 else
2683 fatal = (loongarch_reloc_is_fatal
2684 (info, input_bfd, input_section, rel, howto,
2685 bfd_reloc_dangerous, is_undefweak, name,
2686 "Undefweak need to be resolved dynamically, "
2687 "but PLT stub doesn't represent."));
2688 }
2689 }
2690 else
2691 {
2692 if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
2693 {
2694 fatal = (loongarch_reloc_is_fatal
2695 (info, input_bfd, input_section, rel, howto,
2696 bfd_reloc_undefined, is_undefweak, name,
2697 "PLT stub does not represent and "
2698 "symbol not defined."));
2699 break;
2700 }
2701
2702 if (resolved_local)
2703 i = 0, j = 2;
2704 else /* if (resolved_dynly) */
2705 {
2706 if (!(h && h->plt.offset != MINUS_ONE))
2707 fatal = (loongarch_reloc_is_fatal
2708 (info, input_bfd, input_section, rel, howto,
2709 bfd_reloc_dangerous, is_undefweak, name,
2710 "Internal: PLT stub doesn't represent. "
2711 "Resolve it with pcrel"));
2712 i = 1, j = 3;
2713 }
2714 }
2715
2716 for (; i < j; i++)
2717 {
2718 if ((i & 1) == 0 && defined_local)
2719 {
2720 relocation -= pc;
2721 relocation += rel->r_addend;
2722 break;
2723 }
2724
2725 if ((i & 1) && h && h->plt.offset != MINUS_ONE)
2726 {
2727 if (rel->r_addend != 0)
2728 {
2729 fatal = (loongarch_reloc_is_fatal
2730 (info, input_bfd, input_section, rel, howto,
2731 bfd_reloc_notsupported, is_undefweak, name,
2732 "PLT shouldn't be with r_addend."));
2733 break;
2734 }
2735 relocation = sec_addr (plt) + h->plt.offset - pc;
2736 break;
2737 }
2738 }
2739 break;
2740
2741 case R_LARCH_SOP_PUSH_GPREL:
2742 unresolved_reloc = false;
2743
2744 if (rel->r_addend != 0)
2745 {
2746 fatal = (loongarch_reloc_is_fatal
2747 (info, input_bfd, input_section, rel, howto,
2748 bfd_reloc_notsupported, is_undefweak, name,
2749 "Shouldn't be with r_addend."));
2750 break;
2751 }
2752
2753 if (h != NULL)
2754 {
2755 off = h->got.offset & (~1);
2756
2757 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
2758 {
2759 fatal = (loongarch_reloc_is_fatal
2760 (info, input_bfd, input_section, rel, howto,
2761 bfd_reloc_notsupported, is_undefweak, name,
2762 "Internal: GOT entry doesn't represent."));
2763 break;
2764 }
2765
2766 /* Hidden symbol not has .got entry, only .got.plt entry
2767 so gprel is (plt - got). */
2768 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
2769 {
2770 if (h->plt.offset == (bfd_vma) -1)
2771 {
2772 abort();
2773 }
2774
2775 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2776 off = plt_index * GOT_ENTRY_SIZE;
2777
2778 if (htab->elf.splt != NULL)
2779 {
2780 /* Section .plt header is 2 times of plt entry. */
2781 off = sec_addr (htab->elf.sgotplt) + off
2782 - sec_addr (htab->elf.sgot);
2783 }
2784 else
2785 {
2786 /* Section iplt not has plt header. */
2787 off = sec_addr (htab->elf.igotplt) + off
2788 - sec_addr (htab->elf.sgot);
2789 }
2790 }
2791
2792 if ((h->got.offset & 1) == 0)
2793 {
2794 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
2795 bfd_link_pic (info), h)
2796 && ((bfd_link_pic (info)
2797 && SYMBOL_REFERENCES_LOCAL (info, h))))
2798 {
2799 /* This is actually a static link, or it is a
2800 -Bsymbolic link and the symbol is defined
2801 locally, or the symbol was forced to be local
2802 because of a version file. We must initialize
2803 this entry in the global offset table. Since the
2804 offset must always be a multiple of the word size,
2805 we use the least significant bit to record whether
2806 we have initialized it already.
2807
2808 When doing a dynamic link, we create a rela.got
2809 relocation entry to initialize the value. This
2810 is done in the finish_dynamic_symbol routine. */
2811
2812 if (resolved_dynly)
2813 {
2814 fatal = (loongarch_reloc_is_fatal
2815 (info, input_bfd, input_section, rel, howto,
2816 bfd_reloc_dangerous, is_undefweak, name,
2817 "Internal: here shouldn't dynamic."));
2818 }
2819
2820 if (!(defined_local || resolved_to_const))
2821 {
2822 fatal = (loongarch_reloc_is_fatal
2823 (info, input_bfd, input_section, rel, howto,
2824 bfd_reloc_undefined, is_undefweak, name,
2825 "Internal: "));
2826 break;
2827 }
2828
2829 asection *s;
2830 Elf_Internal_Rela outrel;
2831 /* We need to generate a R_LARCH_RELATIVE reloc
2832 for the dynamic linker. */
2833 s = htab->elf.srelgot;
2834 if (!s)
2835 {
2836 fatal = loongarch_reloc_is_fatal
2837 (info, input_bfd,
2838 input_section, rel, howto,
2839 bfd_reloc_notsupported, is_undefweak, name,
2840 "Internal: '.rel.got' not represent");
2841 break;
2842 }
2843
2844 outrel.r_offset = sec_addr (got) + off;
2845 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2846 outrel.r_addend = relocation; /* Link-time addr. */
2847 loongarch_elf_append_rela (output_bfd, s, &outrel);
2848 }
2849 bfd_put_NN (output_bfd, relocation, got->contents + off);
2850 h->got.offset |= 1;
2851 }
2852 }
2853 else
2854 {
2855 if (!local_got_offsets)
2856 {
2857 fatal = (loongarch_reloc_is_fatal
2858 (info, input_bfd, input_section, rel, howto,
2859 bfd_reloc_notsupported, is_undefweak, name,
2860 "Internal: local got offsets not reporesent."));
2861 break;
2862 }
2863
2864 off = local_got_offsets[r_symndx] & (~1);
2865
2866 if (local_got_offsets[r_symndx] == MINUS_ONE)
2867 {
2868 fatal = (loongarch_reloc_is_fatal
2869 (info, input_bfd, input_section, rel, howto,
2870 bfd_reloc_notsupported, is_undefweak, name,
2871 "Internal: GOT entry doesn't represent."));
2872 break;
2873 }
2874
2875 /* The offset must always be a multiple of the word size.
2876 So, we can use the least significant bit to record
2877 whether we have already processed this entry. */
2878 if (local_got_offsets[r_symndx] == 0)
2879 {
2880 if (is_pic)
2881 {
2882 asection *s;
2883 Elf_Internal_Rela outrel;
2884 /* We need to generate a R_LARCH_RELATIVE reloc
2885 for the dynamic linker. */
2886 s = htab->elf.srelgot;
2887 if (!s)
2888 {
2889 fatal = (loongarch_reloc_is_fatal
2890 (info, input_bfd, input_section, rel, howto,
2891 bfd_reloc_notsupported, is_undefweak, name,
2892 "Internal: '.rel.got' not represent"));
2893 break;
2894 }
2895
2896 outrel.r_offset = sec_addr (got) + off;
2897 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2898 outrel.r_addend = relocation; /* Link-time addr. */
2899 loongarch_elf_append_rela (output_bfd, s, &outrel);
2900 }
2901
2902 bfd_put_NN (output_bfd, relocation, got->contents + off);
2903 local_got_offsets[r_symndx] |= 1;
2904 }
2905 }
2906 relocation = off;
2907
2908 break;
2909
2910 case R_LARCH_SOP_PUSH_TLS_GOT:
2911 case R_LARCH_SOP_PUSH_TLS_GD:
2912 {
2913 unresolved_reloc = false;
2914 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
2915 is_ie = true;
2916
2917 bfd_vma got_off = 0;
2918 if (h != NULL)
2919 {
2920 got_off = h->got.offset;
2921 h->got.offset |= 1;
2922 }
2923 else
2924 {
2925 got_off = local_got_offsets[r_symndx];
2926 local_got_offsets[r_symndx] |= 1;
2927 }
2928
2929 BFD_ASSERT (got_off != MINUS_ONE);
2930
2931 ie_off = 0;
2932 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
2933 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
2934 ie_off = 2 * GOT_ENTRY_SIZE;
2935
2936 if ((got_off & 1) == 0)
2937 {
2938 Elf_Internal_Rela rela;
2939 asection *srel = htab->elf.srelgot;
2940 bfd_vma tls_block_off = 0;
2941
2942 if (SYMBOL_REFERENCES_LOCAL (info, h))
2943 {
2944 BFD_ASSERT (elf_hash_table (info)->tls_sec);
2945 tls_block_off = relocation
2946 - elf_hash_table (info)->tls_sec->vma;
2947 }
2948
2949 if (tls_type & GOT_TLS_GD)
2950 {
2951 rela.r_offset = sec_addr (got) + got_off;
2952 rela.r_addend = 0;
2953 if (SYMBOL_REFERENCES_LOCAL (info, h))
2954 {
2955 /* Local sym, used in exec, set module id 1. */
2956 if (bfd_link_executable (info))
2957 bfd_put_NN (output_bfd, 1, got->contents + got_off);
2958 else
2959 {
2960 rela.r_info = ELFNN_R_INFO (0,
2961 R_LARCH_TLS_DTPMODNN);
2962 loongarch_elf_append_rela (output_bfd, srel, &rela);
2963 }
2964
2965 bfd_put_NN (output_bfd, tls_block_off,
2966 got->contents + got_off + GOT_ENTRY_SIZE);
2967 }
2968 /* Dynamic resolved. */
2969 else
2970 {
2971 /* Dynamic relocate module id. */
2972 rela.r_info = ELFNN_R_INFO (h->dynindx,
2973 R_LARCH_TLS_DTPMODNN);
2974 loongarch_elf_append_rela (output_bfd, srel, &rela);
2975
2976 /* Dynamic relocate offset of block. */
2977 rela.r_offset += GOT_ENTRY_SIZE;
2978 rela.r_info = ELFNN_R_INFO (h->dynindx,
2979 R_LARCH_TLS_DTPRELNN);
2980 loongarch_elf_append_rela (output_bfd, srel, &rela);
2981 }
2982 }
2983 if (tls_type & GOT_TLS_IE)
2984 {
2985 rela.r_offset = sec_addr (got) + got_off + ie_off;
2986 if (SYMBOL_REFERENCES_LOCAL (info, h))
2987 {
2988 /* Local sym, used in exec, set module id 1. */
2989 if (!bfd_link_executable (info))
2990 {
2991 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
2992 rela.r_addend = tls_block_off;
2993 loongarch_elf_append_rela (output_bfd, srel, &rela);
2994 }
2995
2996 bfd_put_NN (output_bfd, tls_block_off,
2997 got->contents + got_off + ie_off);
2998 }
2999 /* Dynamic resolved. */
3000 else
3001 {
3002 /* Dynamic relocate offset of block. */
3003 rela.r_info = ELFNN_R_INFO (h->dynindx,
3004 R_LARCH_TLS_TPRELNN);
3005 rela.r_addend = 0;
3006 loongarch_elf_append_rela (output_bfd, srel, &rela);
3007 }
3008 }
3009 }
3010
3011 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3012 }
3013 break;
3014
3015 /* New reloc types. */
3016 case R_LARCH_B21:
3017 case R_LARCH_B26:
3018 case R_LARCH_B16:
3019 unresolved_reloc = false;
3020 if (is_undefweak)
3021 {
3022 relocation = 0;
3023 }
3024
3025 if (resolved_local)
3026 {
3027 relocation -= pc;
3028 relocation += rel->r_addend;
3029 }
3030 else if (resolved_dynly)
3031 {
3032 BFD_ASSERT (h
3033 && (h->plt.offset != MINUS_ONE
3034 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3035 && rel->r_addend == 0);
3036 if (h && h->plt.offset == MINUS_ONE
3037 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3038 {
3039 relocation -= pc;
3040 relocation += rel->r_addend;
3041 }
3042 else
3043 relocation = sec_addr (plt) + h->plt.offset - pc;
3044 }
3045
3046 break;
3047
3048 case R_LARCH_ABS_HI20:
3049 case R_LARCH_ABS_LO12:
3050 case R_LARCH_ABS64_LO20:
3051 case R_LARCH_ABS64_HI12:
3052 BFD_ASSERT (!is_pic);
3053
3054 if (is_undefweak)
3055 {
3056 BFD_ASSERT (resolved_dynly);
3057 relocation = 0;
3058 break;
3059 }
3060 else if (resolved_to_const || resolved_local)
3061 {
3062 relocation += rel->r_addend;
3063 }
3064 else if (resolved_dynly)
3065 {
3066 unresolved_reloc = false;
3067 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3068 && rel->r_addend == 0);
3069 relocation = sec_addr (plt) + h->plt.offset;
3070 }
3071
3072 break;
3073
3074 case R_LARCH_PCALA_HI20:
3075 unresolved_reloc = false;
3076 if (h && h->plt.offset != MINUS_ONE)
3077 relocation = sec_addr (plt) + h->plt.offset;
3078 else
3079 relocation += rel->r_addend;
3080
3081 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3082
3083 break;
3084
3085 case R_LARCH_PCALA_LO12:
3086 /* Not support if sym_addr in 2k page edge.
3087 pcalau12i pc_hi20 (sym_addr)
3088 ld.w/d pc_lo12 (sym_addr)
3089 ld.w/d pc_lo12 (sym_addr + x)
3090 ...
3091 can not calc correct address
3092 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3093
3094 if (h && h->plt.offset != MINUS_ONE)
3095 relocation = sec_addr (plt) + h->plt.offset;
3096 else
3097 relocation += rel->r_addend;
3098
3099 relocation &= 0xfff;
3100 /* Signed extend. */
3101 relocation = (relocation ^ 0x800) - 0x800;
3102
3103 /* For 2G jump, generate pcalau12i, jirl. */
3104 /* If use jirl, turns to R_LARCH_B16. */
3105 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3106 if ((insn & 0x4c000000) == 0x4c000000)
3107 {
3108 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3109 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3110 }
3111 break;
3112
3113 case R_LARCH_PCALA64_LO20:
3114 case R_LARCH_PCALA64_HI12:
3115 if (h && h->plt.offset != MINUS_ONE)
3116 relocation = sec_addr (plt) + h->plt.offset;
3117 else
3118 relocation += rel->r_addend;
3119
3120 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3121
3122 break;
3123
3124 case R_LARCH_GOT_PC_HI20:
3125 case R_LARCH_GOT_HI20:
3126 /* Calc got offset. */
3127 {
3128 unresolved_reloc = false;
3129 BFD_ASSERT (rel->r_addend == 0);
3130
3131 bfd_vma got_off = 0;
3132 if (h != NULL)
3133 {
3134 /* GOT ref or ifunc. */
3135 BFD_ASSERT (h->got.offset != MINUS_ONE
3136 || h->type == STT_GNU_IFUNC);
3137
3138 got_off = h->got.offset & (~(bfd_vma)1);
3139 /* Hidden symbol not has got entry,
3140 * only got.plt entry so it is (plt - got). */
3141 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3142 {
3143 bfd_vma idx;
3144 if (htab->elf.splt != NULL)
3145 {
3146 idx = (h->plt.offset - PLT_HEADER_SIZE)
3147 / PLT_ENTRY_SIZE;
3148 got_off = sec_addr (htab->elf.sgotplt)
3149 + GOTPLT_HEADER_SIZE
3150 + (idx * GOT_ENTRY_SIZE)
3151 - sec_addr (htab->elf.sgot);
3152 }
3153 else
3154 {
3155 idx = h->plt.offset / PLT_ENTRY_SIZE;
3156 got_off = sec_addr (htab->elf.sgotplt)
3157 + (idx * GOT_ENTRY_SIZE)
3158 - sec_addr (htab->elf.sgot);
3159 }
3160 }
3161
3162 if ((h->got.offset & 1) == 0)
3163 {
3164 /* We need to generate a R_LARCH_RELATIVE reloc once
3165 * in loongarch_elf_finish_dynamic_symbol or now,
3166 * call finish_dyn && nopic
3167 * or !call finish_dyn && pic. */
3168 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3169 bfd_link_pic (info),
3170 h)
3171 && bfd_link_pic (info)
3172 && SYMBOL_REFERENCES_LOCAL (info, h))
3173 {
3174 Elf_Internal_Rela rela;
3175 rela.r_offset = sec_addr (got) + got_off;
3176 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3177 rela.r_addend = relocation;
3178 loongarch_elf_append_rela (output_bfd,
3179 htab->elf.srelgot, &rela);
3180 }
3181 h->got.offset |= 1;
3182 bfd_put_NN (output_bfd, relocation,
3183 got->contents + got_off);
3184 }
3185 }
3186 else
3187 {
3188 BFD_ASSERT (local_got_offsets
3189 && local_got_offsets[r_symndx] != MINUS_ONE);
3190
3191 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3192 if ((local_got_offsets[r_symndx] & 1) == 0)
3193 {
3194 if (bfd_link_pic (info))
3195 {
3196 Elf_Internal_Rela rela;
3197 rela.r_offset = sec_addr (got) + got_off;
3198 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3199 rela.r_addend = relocation;
3200 loongarch_elf_append_rela (output_bfd,
3201 htab->elf.srelgot, &rela);
3202 }
3203 local_got_offsets[r_symndx] |= 1;
3204 }
3205 bfd_put_NN (output_bfd, relocation, got->contents + got_off);
3206 }
3207
3208 relocation = got_off + sec_addr (got);
3209 }
3210
3211 if (r_type == R_LARCH_GOT_PC_HI20)
3212 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3213
3214 break;
3215
3216 case R_LARCH_GOT_PC_LO12:
3217 case R_LARCH_GOT64_PC_LO20:
3218 case R_LARCH_GOT64_PC_HI12:
3219 case R_LARCH_GOT_LO12:
3220 case R_LARCH_GOT64_LO20:
3221 case R_LARCH_GOT64_HI12:
3222 {
3223 unresolved_reloc = false;
3224 bfd_vma got_off;
3225 if (h)
3226 got_off = h->got.offset & (~(bfd_vma)1);
3227 else
3228 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3229
3230 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3231 {
3232 bfd_vma idx;
3233 if (htab->elf.splt != NULL)
3234 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3235 else
3236 idx = h->plt.offset / PLT_ENTRY_SIZE;
3237
3238 got_off = sec_addr (htab->elf.sgotplt)
3239 + GOTPLT_HEADER_SIZE
3240 + (idx * GOT_ENTRY_SIZE)
3241 - sec_addr (htab->elf.sgot);
3242 }
3243 relocation = got_off + sec_addr (got);
3244 }
3245
3246 if (r_type == R_LARCH_GOT_PC_LO12)
3247 relocation &= (bfd_vma)0xfff;
3248 else if (r_type == R_LARCH_GOT64_PC_LO20
3249 || r_type == R_LARCH_GOT64_PC_HI12)
3250 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3251
3252 break;
3253
3254 case R_LARCH_TLS_LE_HI20:
3255 case R_LARCH_TLS_LE_LO12:
3256 case R_LARCH_TLS_LE64_LO20:
3257 case R_LARCH_TLS_LE64_HI12:
3258 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3259
3260 relocation -= elf_hash_table (info)->tls_sec->vma;
3261 break;
3262
3263 /* TLS IE LD/GD process separately is troublesome.
3264 When a symbol is both ie and LD/GD, h->got.off |= 1
3265 make only one type be relocated. We must use
3266 h->got.offset |= 1 and h->got.offset |= 2
3267 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3268 (IE LD/GD and reusable GOT reloc) must change to
3269 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3270 as a tag.
3271 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3272 can be omitted. */
3273 case R_LARCH_TLS_IE_PC_HI20:
3274 case R_LARCH_TLS_IE_HI20:
3275 case R_LARCH_TLS_LD_PC_HI20:
3276 case R_LARCH_TLS_LD_HI20:
3277 case R_LARCH_TLS_GD_PC_HI20:
3278 case R_LARCH_TLS_GD_HI20:
3279 BFD_ASSERT (rel->r_addend == 0);
3280 unresolved_reloc = false;
3281
3282 if (r_type == R_LARCH_TLS_IE_PC_HI20
3283 || r_type == R_LARCH_TLS_IE_HI20)
3284 is_ie = true;
3285
3286 bfd_vma got_off = 0;
3287 if (h != NULL)
3288 {
3289 got_off = h->got.offset;
3290 h->got.offset |= 1;
3291 }
3292 else
3293 {
3294 got_off = local_got_offsets[r_symndx];
3295 local_got_offsets[r_symndx] |= 1;
3296 }
3297
3298 BFD_ASSERT (got_off != MINUS_ONE);
3299
3300 ie_off = 0;
3301 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3302 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3303 ie_off = 2 * GOT_ENTRY_SIZE;
3304
3305 if ((got_off & 1) == 0)
3306 {
3307 Elf_Internal_Rela rela;
3308 asection *relgot = htab->elf.srelgot;
3309 bfd_vma tls_block_off = 0;
3310
3311 if (SYMBOL_REFERENCES_LOCAL (info, h))
3312 {
3313 BFD_ASSERT (elf_hash_table (info)->tls_sec);
3314 tls_block_off = relocation
3315 - elf_hash_table (info)->tls_sec->vma;
3316 }
3317
3318 if (tls_type & GOT_TLS_GD)
3319 {
3320 rela.r_offset = sec_addr (got) + got_off;
3321 rela.r_addend = 0;
3322 if (SYMBOL_REFERENCES_LOCAL (info, h))
3323 {
3324 /* Local sym, used in exec, set module id 1. */
3325 if (bfd_link_executable (info))
3326 bfd_put_NN (output_bfd, 1, got->contents + got_off);
3327 else
3328 {
3329 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3330 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3331 }
3332
3333 bfd_put_NN (output_bfd, tls_block_off,
3334 got->contents + got_off + GOT_ENTRY_SIZE);
3335 }
3336 /* Dynamic resolved. */
3337 else
3338 {
3339 /* Dynamic relocate module id. */
3340 rela.r_info = ELFNN_R_INFO (h->dynindx,
3341 R_LARCH_TLS_DTPMODNN);
3342 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3343
3344 /* Dynamic relocate offset of block. */
3345 rela.r_offset += GOT_ENTRY_SIZE;
3346 rela.r_info = ELFNN_R_INFO (h->dynindx,
3347 R_LARCH_TLS_DTPRELNN);
3348 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3349 }
3350 }
3351 if (tls_type & GOT_TLS_IE)
3352 {
3353 rela.r_offset = sec_addr (got) + got_off + ie_off;
3354 if (SYMBOL_REFERENCES_LOCAL (info, h))
3355 {
3356 /* Local sym, used in exec, set module id 1. */
3357 if (!bfd_link_executable (info))
3358 {
3359 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3360 rela.r_addend = tls_block_off;
3361 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3362 }
3363
3364 bfd_put_NN (output_bfd, tls_block_off,
3365 got->contents + got_off + ie_off);
3366 }
3367 /* Dynamic resolved. */
3368 else
3369 {
3370 /* Dynamic relocate offset of block. */
3371 rela.r_info = ELFNN_R_INFO (h->dynindx,
3372 R_LARCH_TLS_TPRELNN);
3373 rela.r_addend = 0;
3374 loongarch_elf_append_rela (output_bfd, relgot, &rela);
3375 }
3376 }
3377 }
3378 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
3379 + (is_ie ? ie_off : 0);
3380
3381 if (r_type == R_LARCH_TLS_LD_PC_HI20
3382 || r_type == R_LARCH_TLS_GD_PC_HI20
3383 || r_type == R_LARCH_TLS_IE_PC_HI20)
3384 RELOCATE_CALC_PC32_HI20 (relocation, pc);
3385
3386 break;
3387
3388 case R_LARCH_TLS_IE_PC_LO12:
3389 case R_LARCH_TLS_IE64_PC_LO20:
3390 case R_LARCH_TLS_IE64_PC_HI12:
3391 case R_LARCH_TLS_IE_LO12:
3392 case R_LARCH_TLS_IE64_LO20:
3393 case R_LARCH_TLS_IE64_HI12:
3394 unresolved_reloc = false;
3395
3396 if (h)
3397 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
3398 else
3399 relocation = sec_addr (got)
3400 + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
3401
3402 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3403 /* Use both TLS_GD and TLS_IE. */
3404 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3405 relocation += 2 * GOT_ENTRY_SIZE;
3406
3407 if (r_type == R_LARCH_TLS_IE_PC_LO12)
3408 relocation &= (bfd_vma)0xfff;
3409 else if (r_type == R_LARCH_TLS_IE64_PC_LO20
3410 || r_type == R_LARCH_TLS_IE64_PC_HI12)
3411 RELOCATE_CALC_PC64_HI32 (relocation, pc);
3412
3413 break;
3414
3415 case R_LARCH_RELAX:
3416 break;
3417
3418 default:
3419 break;
3420 }
3421
3422 if (fatal)
3423 break;
3424
3425 do
3426 {
3427 /* 'unresolved_reloc' means we haven't done it yet.
3428 We need help of dynamic linker to fix this memory location up. */
3429 if (!unresolved_reloc)
3430 break;
3431
3432 if (_bfd_elf_section_offset (output_bfd, info, input_section,
3433 rel->r_offset) == MINUS_ONE)
3434 /* WHY? May because it's invalid so skip checking.
3435 But why dynamic reloc a invalid section? */
3436 break;
3437
3438 if (input_section->output_section->flags & SEC_DEBUGGING)
3439 {
3440 fatal = (loongarch_reloc_is_fatal
3441 (info, input_bfd, input_section, rel, howto,
3442 bfd_reloc_dangerous, is_undefweak, name,
3443 "Seems dynamic linker not process "
3444 "sections 'SEC_DEBUGGING'."));
3445 }
3446 if (!is_dyn)
3447 break;
3448
3449 if ((info->flags & DF_TEXTREL) == 0)
3450 if (input_section->output_section->flags & SEC_READONLY)
3451 info->flags |= DF_TEXTREL;
3452 }
3453 while (0);
3454
3455 if (fatal)
3456 break;
3457
3458 loongarch_record_one_reloc (input_bfd, input_section, r_type,
3459 rel->r_offset, sym, h, rel->r_addend);
3460
3461 if (r != bfd_reloc_continue)
3462 r = perform_relocation (rel, input_section, howto, relocation,
3463 input_bfd, contents);
3464
3465 switch (r)
3466 {
3467 case bfd_reloc_dangerous:
3468 case bfd_reloc_continue:
3469 case bfd_reloc_ok:
3470 continue;
3471
3472 case bfd_reloc_overflow:
3473 /* Overflow value can't be filled in. */
3474 loongarch_dump_reloc_record (info->callbacks->info);
3475 info->callbacks->reloc_overflow
3476 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3477 input_bfd, input_section, rel->r_offset);
3478 break;
3479
3480 case bfd_reloc_outofrange:
3481 /* Stack state incorrect. */
3482 loongarch_dump_reloc_record (info->callbacks->info);
3483 info->callbacks->info
3484 ("%X%H: Internal stack state is incorrect.\n"
3485 "Want to push to full stack or pop from empty stack?\n",
3486 input_bfd, input_section, rel->r_offset);
3487 break;
3488
3489 case bfd_reloc_notsupported:
3490 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3491 input_section, rel->r_offset);
3492 break;
3493
3494 default:
3495 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3496 input_section, rel->r_offset);
3497 break;
3498 }
3499
3500 fatal = true;
3501 }
3502
3503 return !fatal;
3504 }
3505
3506 /* Finish up dynamic symbol handling. We set the contents of various
3507 dynamic sections here. */
3508
3509 static bool
3510 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
3511 struct bfd_link_info *info,
3512 struct elf_link_hash_entry *h,
3513 Elf_Internal_Sym *sym)
3514 {
3515 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3516 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3517 asection *rela_dyn = bfd_get_section_by_name (output_bfd, ".rela.dyn");
3518 struct bfd_link_order *lo = NULL;
3519 Elf_Internal_Rela *slot = NULL, *last_slot = NULL;
3520
3521 if (rela_dyn)
3522 lo = rela_dyn->map_head.link_order;
3523
3524 if (h->plt.offset != MINUS_ONE)
3525 {
3526 size_t i, plt_idx;
3527 asection *plt, *gotplt, *relplt;
3528 bfd_vma got_address;
3529 uint32_t plt_entry[PLT_ENTRY_INSNS];
3530 bfd_byte *loc;
3531 Elf_Internal_Rela rela;
3532 asection *rela_sec = NULL;
3533
3534 if (htab->elf.splt)
3535 {
3536 BFD_ASSERT ((h->type == STT_GNU_IFUNC
3537 && SYMBOL_REFERENCES_LOCAL (info, h))
3538 || h->dynindx != -1);
3539
3540 plt = htab->elf.splt;
3541 gotplt = htab->elf.sgotplt;
3542 if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
3543 relplt = htab->elf.srelgot;
3544 else
3545 relplt = htab->elf.srelplt;
3546 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3547 got_address =
3548 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
3549 }
3550 else /* if (htab->elf.iplt) */
3551 {
3552 BFD_ASSERT (h->type == STT_GNU_IFUNC
3553 && SYMBOL_REFERENCES_LOCAL (info, h));
3554
3555 plt = htab->elf.iplt;
3556 gotplt = htab->elf.igotplt;
3557 relplt = htab->elf.irelplt;
3558 plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
3559 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
3560 }
3561
3562 /* Find out where the .plt entry should go. */
3563 loc = plt->contents + h->plt.offset;
3564
3565 /* Fill in the PLT entry itself. */
3566 if (!loongarch_make_plt_entry (got_address,
3567 sec_addr (plt) + h->plt.offset,
3568 plt_entry))
3569 return false;
3570
3571 for (i = 0; i < PLT_ENTRY_INSNS; i++)
3572 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
3573
3574 /* Fill in the initial value of the got.plt entry. */
3575 loc = gotplt->contents + (got_address - sec_addr (gotplt));
3576 bfd_put_NN (output_bfd, sec_addr (plt), loc);
3577
3578 rela.r_offset = got_address;
3579
3580 /* TRUE if this is a PLT reference to a local IFUNC. */
3581 if (PLT_LOCAL_IFUNC_P (info, h)
3582 && (relplt == htab->elf.srelgot
3583 || relplt == htab->elf.irelplt))
3584 {
3585 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
3586 rela.r_addend = (h->root.u.def.value
3587 + h->root.u.def.section->output_section->vma
3588 + h->root.u.def.section->output_offset);
3589
3590 /* Find the space after dyn sort. */
3591 while (slot == last_slot || slot->r_offset != 0)
3592 {
3593 if (slot != last_slot)
3594 {
3595 slot++;
3596 continue;
3597 }
3598
3599 BFD_ASSERT (lo != NULL);
3600 rela_sec = lo->u.indirect.section;
3601 lo = lo->next;
3602
3603 slot = (Elf_Internal_Rela *)rela_sec->contents;
3604 last_slot = (Elf_Internal_Rela *)(rela_sec->contents +
3605 rela_sec->size);
3606 }
3607
3608 bed->s->swap_reloca_out (output_bfd, &rela, (bfd_byte *)slot);
3609 rela_sec->reloc_count++;
3610 }
3611 else
3612 {
3613 /* Fill in the entry in the rela.plt section. */
3614 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
3615 rela.r_addend = 0;
3616 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
3617 bed->s->swap_reloca_out (output_bfd, &rela, loc);
3618 }
3619
3620 if (!h->def_regular)
3621 {
3622 /* Mark the symbol as undefined, rather than as defined in
3623 the .plt section. Leave the value alone. */
3624 sym->st_shndx = SHN_UNDEF;
3625 /* If the symbol is weak, we do need to clear the value.
3626 Otherwise, the PLT entry would provide a definition for
3627 the symbol even if the symbol wasn't defined anywhere,
3628 and so the symbol would never be NULL. */
3629 if (!h->ref_regular_nonweak)
3630 sym->st_value = 0;
3631 }
3632 }
3633
3634 if (h->got.offset != MINUS_ONE
3635 /* TLS got entry have been handled in elf_relocate_section. */
3636 && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
3637 /* Have allocated got entry but not allocated rela before. */
3638 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
3639 {
3640 asection *sgot, *srela;
3641 Elf_Internal_Rela rela;
3642 bfd_vma off = h->got.offset & ~(bfd_vma)1;
3643
3644 /* This symbol has an entry in the GOT. Set it up. */
3645 sgot = htab->elf.sgot;
3646 srela = htab->elf.srelgot;
3647 BFD_ASSERT (sgot && srela);
3648
3649 rela.r_offset = sec_addr (sgot) + off;
3650
3651 if (h->def_regular
3652 && h->type == STT_GNU_IFUNC)
3653 {
3654 if(h->plt.offset == MINUS_ONE)
3655 {
3656 if (htab->elf.splt == NULL)
3657 srela = htab->elf.irelplt;
3658
3659 if (SYMBOL_REFERENCES_LOCAL (info, h))
3660 {
3661 asection *sec = h->root.u.def.section;
3662 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
3663 rela.r_addend = h->root.u.def.value + sec->output_section->vma
3664 + sec->output_offset;
3665 bfd_put_NN (output_bfd, 0, sgot->contents + off);
3666 }
3667 else
3668 {
3669 BFD_ASSERT (h->dynindx != -1);
3670 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3671 rela.r_addend = 0;
3672 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
3673 }
3674 }
3675 else if(bfd_link_pic (info))
3676 {
3677 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3678 rela.r_addend = 0;
3679 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
3680 }
3681 else
3682 {
3683 asection *plt;
3684 /* For non-shared object, we can't use .got.plt, which
3685 contains the real function address if we need pointer
3686 equality. We load the GOT entry with the PLT entry. */
3687 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
3688 bfd_put_NN (output_bfd,
3689 (plt->output_section->vma
3690 + plt->output_offset
3691 + h->plt.offset),
3692 sgot->contents + off);
3693 return true;
3694 }
3695 }
3696 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
3697 {
3698 asection *sec = h->root.u.def.section;
3699 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3700 rela.r_addend = (h->root.u.def.value + sec->output_section->vma
3701 + sec->output_offset);
3702 }
3703 else
3704 {
3705 BFD_ASSERT (h->dynindx != -1);
3706 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3707 rela.r_addend = 0;
3708 }
3709
3710 loongarch_elf_append_rela (output_bfd, srela, &rela);
3711 }
3712
3713 /* Mark some specially defined symbols as absolute. */
3714 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
3715 sym->st_shndx = SHN_ABS;
3716
3717 return true;
3718 }
3719
3720 /* Finish up the dynamic sections. */
3721
3722 static bool
3723 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
3724 asection *sdyn)
3725 {
3726 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3727 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3728 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
3729 bfd_byte *dyncon, *dynconend;
3730
3731 dynconend = sdyn->contents + sdyn->size;
3732 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
3733 {
3734 Elf_Internal_Dyn dyn;
3735 asection *s;
3736 int skipped = 0;
3737
3738 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
3739
3740 switch (dyn.d_tag)
3741 {
3742 case DT_PLTGOT:
3743 s = htab->elf.sgotplt;
3744 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3745 break;
3746 case DT_JMPREL:
3747 s = htab->elf.srelplt;
3748 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3749 break;
3750 case DT_PLTRELSZ:
3751 s = htab->elf.srelplt;
3752 dyn.d_un.d_val = s->size;
3753 break;
3754 case DT_TEXTREL:
3755 if ((info->flags & DF_TEXTREL) == 0)
3756 skipped = 1;
3757 break;
3758 case DT_FLAGS:
3759 if ((info->flags & DF_TEXTREL) == 0)
3760 dyn.d_un.d_val &= ~DF_TEXTREL;
3761 break;
3762 }
3763 if (skipped)
3764 skipped_size += dynsize;
3765 else
3766 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
3767 }
3768 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
3769 memset (dyncon - skipped_size, 0, skipped_size);
3770 return true;
3771 }
3772
3773 /* Finish up local dynamic symbol handling. We set the contents of
3774 various dynamic sections here. */
3775
3776 static bool
3777 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
3778 {
3779 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
3780 struct bfd_link_info *info = (struct bfd_link_info *) inf;
3781
3782 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
3783 }
3784
3785 static bool
3786 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
3787 struct bfd_link_info *info)
3788 {
3789 bfd *dynobj;
3790 asection *sdyn, *plt, *gotplt = NULL;
3791 struct loongarch_elf_link_hash_table *htab;
3792
3793 htab = loongarch_elf_hash_table (info);
3794 BFD_ASSERT (htab);
3795 dynobj = htab->elf.dynobj;
3796 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3797
3798 if (elf_hash_table (info)->dynamic_sections_created)
3799 {
3800 BFD_ASSERT (htab->elf.splt && sdyn);
3801
3802 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
3803 return false;
3804 }
3805
3806 plt = htab->elf.splt;
3807 gotplt = htab->elf.sgotplt;
3808
3809 if (plt && 0 < plt->size)
3810 {
3811 size_t i;
3812 uint32_t plt_header[PLT_HEADER_INSNS];
3813 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
3814 plt_header))
3815 return false;
3816
3817 for (i = 0; i < PLT_HEADER_INSNS; i++)
3818 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
3819
3820 elf_section_data (plt->output_section)->this_hdr.sh_entsize =
3821 PLT_ENTRY_SIZE;
3822 }
3823
3824 if (htab->elf.sgotplt)
3825 {
3826 asection *output_section = htab->elf.sgotplt->output_section;
3827
3828 if (bfd_is_abs_section (output_section))
3829 {
3830 _bfd_error_handler (_("discarded output section: `%pA'"),
3831 htab->elf.sgotplt);
3832 return false;
3833 }
3834
3835 if (0 < htab->elf.sgotplt->size)
3836 {
3837 /* Write the first two entries in .got.plt, needed for the dynamic
3838 linker. */
3839 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
3840
3841 bfd_put_NN (output_bfd, (bfd_vma) 0,
3842 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
3843 }
3844
3845 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3846 }
3847
3848 if (htab->elf.sgot)
3849 {
3850 asection *output_section = htab->elf.sgot->output_section;
3851
3852 if (0 < htab->elf.sgot->size)
3853 {
3854 /* Set the first entry in the global offset table to the address of
3855 the dynamic section. */
3856 bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
3857 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
3858 }
3859
3860 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3861 }
3862
3863 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
3864 htab_traverse (htab->loc_hash_table,
3865 (void *) elfNN_loongarch_finish_local_dynamic_symbol, info);
3866
3867 return true;
3868 }
3869
3870 /* Return address for Ith PLT stub in section PLT, for relocation REL
3871 or (bfd_vma) -1 if it should not be included. */
3872
3873 static bfd_vma
3874 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
3875 const arelent *rel ATTRIBUTE_UNUSED)
3876 {
3877 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
3878 }
3879
3880 static enum elf_reloc_type_class
3881 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
3882 const asection *rel_sec ATTRIBUTE_UNUSED,
3883 const Elf_Internal_Rela *rela)
3884 {
3885 struct loongarch_elf_link_hash_table *htab;
3886 htab = loongarch_elf_hash_table (info);
3887
3888 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
3889 {
3890 /* Check relocation against STT_GNU_IFUNC symbol if there are
3891 dynamic symbols. */
3892 bfd *abfd = info->output_bfd;
3893 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3894 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
3895 if (r_symndx != STN_UNDEF)
3896 {
3897 Elf_Internal_Sym sym;
3898 if (!bed->s->swap_symbol_in (abfd,
3899 htab->elf.dynsym->contents
3900 + r_symndx * bed->s->sizeof_sym,
3901 0, &sym))
3902 {
3903 /* xgettext:c-format */
3904 _bfd_error_handler (_("%pB symbol number %lu references"
3905 " nonexistent SHT_SYMTAB_SHNDX section"),
3906 abfd, r_symndx);
3907 /* Ideally an error class should be returned here. */
3908 }
3909 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
3910 return reloc_class_ifunc;
3911 }
3912 }
3913
3914 switch (ELFNN_R_TYPE (rela->r_info))
3915 {
3916 case R_LARCH_IRELATIVE:
3917 return reloc_class_ifunc;
3918 case R_LARCH_RELATIVE:
3919 return reloc_class_relative;
3920 case R_LARCH_JUMP_SLOT:
3921 return reloc_class_plt;
3922 case R_LARCH_COPY:
3923 return reloc_class_copy;
3924 default:
3925 return reloc_class_normal;
3926 }
3927 }
3928
3929 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3930
3931 static void
3932 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
3933 struct elf_link_hash_entry *dir,
3934 struct elf_link_hash_entry *ind)
3935 {
3936 struct elf_link_hash_entry *edir, *eind;
3937
3938 edir = dir;
3939 eind = ind;
3940
3941 if (eind->dyn_relocs != NULL)
3942 {
3943 if (edir->dyn_relocs != NULL)
3944 {
3945 struct elf_dyn_relocs **pp;
3946 struct elf_dyn_relocs *p;
3947
3948 /* Add reloc counts against the indirect sym to the direct sym
3949 list. Merge any entries against the same section. */
3950 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
3951 {
3952 struct elf_dyn_relocs *q;
3953
3954 for (q = edir->dyn_relocs; q != NULL; q = q->next)
3955 if (q->sec == p->sec)
3956 {
3957 q->pc_count += p->pc_count;
3958 q->count += p->count;
3959 *pp = p->next;
3960 break;
3961 }
3962 if (q == NULL)
3963 pp = &p->next;
3964 }
3965 *pp = edir->dyn_relocs;
3966 }
3967
3968 edir->dyn_relocs = eind->dyn_relocs;
3969 eind->dyn_relocs = NULL;
3970 }
3971
3972 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
3973 {
3974 loongarch_elf_hash_entry(edir)->tls_type
3975 = loongarch_elf_hash_entry(eind)->tls_type;
3976 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
3977 }
3978 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3979 }
3980
3981 #define PRSTATUS_SIZE 0x1d8
3982 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
3983 #define PRSTATUS_OFFSET_PR_PID 0x20
3984 #define ELF_GREGSET_T_SIZE 0x168
3985 #define PRSTATUS_OFFSET_PR_REG 0x70
3986
3987 /* Support for core dump NOTE sections. */
3988
3989 static bool
3990 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3991 {
3992 switch (note->descsz)
3993 {
3994 default:
3995 return false;
3996
3997 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
3998 case PRSTATUS_SIZE:
3999 /* pr_cursig */
4000 elf_tdata (abfd)->core->signal =
4001 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
4002
4003 /* pr_pid */
4004 elf_tdata (abfd)->core->lwpid =
4005 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
4006 break;
4007 }
4008
4009 /* Make a ".reg/999" section. */
4010 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
4011 note->descpos
4012 + PRSTATUS_OFFSET_PR_REG);
4013 }
4014
4015 #define PRPSINFO_SIZE 0x88
4016 #define PRPSINFO_OFFSET_PR_PID 0x18
4017 #define PRPSINFO_OFFSET_PR_FNAME 0x28
4018 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
4019 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
4020 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
4021
4022 static bool
4023 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4024 {
4025 switch (note->descsz)
4026 {
4027 default:
4028 return false;
4029
4030 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
4031 case PRPSINFO_SIZE:
4032 /* pr_pid */
4033 elf_tdata (abfd)->core->pid =
4034 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
4035
4036 /* pr_fname */
4037 elf_tdata (abfd)->core->program =
4038 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
4039 PRPSINFO_SIZEOF_PR_FNAME);
4040
4041 /* pr_psargs */
4042 elf_tdata (abfd)->core->command =
4043 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
4044 PRPSINFO_SIZEOF_PR_PS_ARGS);
4045 break;
4046 }
4047
4048 /* Note that for some reason, a spurious space is tacked
4049 onto the end of the args in some (at least one anyway)
4050 implementations, so strip it off if it exists. */
4051
4052 {
4053 char *command = elf_tdata (abfd)->core->command;
4054 int n = strlen (command);
4055
4056 if (0 < n && command[n - 1] == ' ')
4057 command[n - 1] = '\0';
4058 }
4059
4060 return true;
4061 }
4062
4063 /* Set the right mach type. */
4064 static bool
4065 loongarch_elf_object_p (bfd *abfd)
4066 {
4067 /* There are only two mach types in LoongArch currently. */
4068 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
4069 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
4070 else
4071 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
4072 return true;
4073 }
4074
4075 static asection *
4076 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
4077 Elf_Internal_Rela *rel,
4078 struct elf_link_hash_entry *h,
4079 Elf_Internal_Sym *sym)
4080 {
4081 if (h != NULL)
4082 switch (ELFNN_R_TYPE (rel->r_info))
4083 {
4084 case R_LARCH_GNU_VTINHERIT:
4085 case R_LARCH_GNU_VTENTRY:
4086 return NULL;
4087 }
4088
4089 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
4090 }
4091
4092 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
4093 executable PLT slots where the executable never takes the address of those
4094 functions, the function symbols are not added to the hash table. */
4095
4096 static bool
4097 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
4098 {
4099 if (h->plt.offset != (bfd_vma) -1
4100 && !h->def_regular
4101 && !h->pointer_equality_needed)
4102 return false;
4103
4104 return _bfd_elf_hash_symbol (h);
4105 }
4106
4107 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
4108 #define TARGET_LITTLE_NAME "elfNN-loongarch"
4109 #define ELF_ARCH bfd_arch_loongarch
4110 #define ELF_TARGET_ID LARCH_ELF_DATA
4111 #define ELF_MACHINE_CODE EM_LOONGARCH
4112 #define ELF_MAXPAGESIZE 0x4000
4113 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
4114 #define bfd_elfNN_bfd_link_hash_table_create \
4115 loongarch_elf_link_hash_table_create
4116 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
4117 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
4118 #define elf_info_to_howto loongarch_info_to_howto_rela
4119 #define bfd_elfNN_bfd_merge_private_bfd_data \
4120 elfNN_loongarch_merge_private_bfd_data
4121
4122 #define elf_backend_reloc_type_class loongarch_reloc_type_class
4123 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
4124 #define elf_backend_create_dynamic_sections \
4125 loongarch_elf_create_dynamic_sections
4126 #define elf_backend_check_relocs loongarch_elf_check_relocs
4127 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
4128 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
4129 #define elf_backend_relocate_section loongarch_elf_relocate_section
4130 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
4131 #define elf_backend_finish_dynamic_sections \
4132 loongarch_elf_finish_dynamic_sections
4133 #define elf_backend_object_p loongarch_elf_object_p
4134 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
4135 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
4136 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
4137 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
4138 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
4139
4140 #include "elfNN-target.h"