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