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