1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
3 Contributed by Loongson Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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/>. */
28 #include "elf/loongarch.h"
29 #include "elfxx-loongarch.h"
30 #include "opcode/loongarch.h"
33 loongarch_info_to_howto_rela (bfd
*abfd
, arelent
*cache_ptr
,
34 Elf_Internal_Rela
*dst
)
36 cache_ptr
->howto
= loongarch_elf_rtype_to_howto (abfd
,
37 ELFNN_R_TYPE (dst
->r_info
));
38 return cache_ptr
->howto
!= NULL
;
41 /* LoongArch ELF linker hash entry. */
42 struct loongarch_elf_link_hash_entry
44 struct elf_link_hash_entry elf
;
51 #define GOT_TLS_GDESC 16
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))
60 #define loongarch_elf_hash_entry(ent) \
61 ((struct loongarch_elf_link_hash_entry *) (ent))
63 struct _bfd_loongarch_elf_obj_tdata
65 struct elf_obj_tdata root
;
67 /* The tls_type for each local got entry. */
68 char *local_got_tls_type
;
71 #define _bfd_loongarch_elf_tdata(abfd) \
72 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
74 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
75 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
77 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
79 ? &loongarch_elf_hash_entry (h)->tls_type \
80 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
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)
93 struct loongarch_elf_link_hash_table
95 struct elf_link_hash_table elf
;
97 /* Short-cuts to get to dynamic linker sections. */
100 /* Small local sym to section mapping cache. */
101 struct sym_cache sym_cache
;
103 /* Used by local STT_GNU_IFUNC symbols. */
104 htab_t loc_hash_table
;
105 void *loc_hash_memory
;
107 /* The max alignment of output sections. */
108 bfd_vma max_alignment
;
110 /* The data segment phase, don't relax the section
111 when it is exp_seg_relro_adjust. */
112 int *data_segment_phase
;
114 /* Array of relative relocs to be emitted in DT_RELR format. */
115 bfd_size_type relr_alloc
;
116 bfd_size_type relr_count
;
117 struct relr_entry
*relr
;
119 /* Sorted output addresses of above relative relocs. */
120 bfd_vma
*relr_sorted
;
122 /* Layout recomputation count. */
123 bfd_size_type relr_layout_iter
;
126 struct loongarch_elf_section_data
128 struct bfd_elf_section_data elf
;
130 /* &htab->relr[i] where i is the smallest number s.t.
131 elf_section_data (htab->relr[i].sec) == &elf.
132 NULL if there exists no such i. */
133 struct relr_entry
*relr
;
136 /* We need an additional field in elf_section_data to handle complex
137 interactions between DT_RELR and relaxation. */
139 loongarch_elf_new_section_hook (bfd
*abfd
, asection
*sec
)
141 if (!sec
->used_by_bfd
)
143 struct loongarch_elf_section_data
*sdata
;
144 size_t amt
= sizeof (*sdata
);
146 sdata
= bfd_zalloc (abfd
, amt
);
149 sec
->used_by_bfd
= sdata
;
152 return _bfd_elf_new_section_hook (abfd
, sec
);
155 #define loongarch_elf_section_data(x) \
156 ((struct loongarch_elf_section_data *) elf_section_data (x))
158 /* Get the LoongArch ELF linker hash table from a link_info structure. */
159 #define loongarch_elf_hash_table(p) \
160 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
161 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
164 #define MINUS_ONE ((bfd_vma) 0 - 1)
166 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
168 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
169 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
171 #define PLT_HEADER_INSNS 8
172 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
174 #define PLT_ENTRY_INSNS 4
175 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
177 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
179 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT
180 resolver _dl_runtime_resolve, the other is used for link map. */
181 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
183 #define elf_backend_want_got_plt 1
185 #define elf_backend_plt_readonly 1
187 #define elf_backend_want_plt_sym 1
188 #define elf_backend_plt_alignment 4
189 #define elf_backend_can_gc_sections 1
190 #define elf_backend_can_refcount 1
191 #define elf_backend_want_got_sym 1
193 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
195 #define elf_backend_want_dynrelro 1
196 #define elf_backend_rela_normal 1
197 #define elf_backend_default_execstack 0
199 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
200 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
201 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
202 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
203 || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
204 || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
205 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
207 #define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \
208 ((R_TYPE) == R_LARCH_TLS_LE_HI20 \
209 || (R_TYPE) == R_LARCH_TLS_LE_LO12 \
210 || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
211 || (R_TYPE) == R_LARCH_TLS_LE64_HI12)
213 /* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx,
214 and set NEED_RELOC to true used in allocate_dynrelocs and
215 loongarch_elf_relocate_section for TLS GD/IE. */
216 #define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
220 && (H)->dynindx != -1 \
221 && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \
222 bfd_link_pic (INFO), (H))) \
223 (INDX) = (H)->dynindx; \
225 || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
226 || (H)->root.type != bfd_link_hash_undefweak) \
227 && (!bfd_link_executable (INFO) \
229 (NEED_RELOC) = true; \
233 /* TL;DR always use it in this file instead when you want to type
234 SYMBOL_REFERENCES_LOCAL.
236 It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local
237 protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but
238 let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people.
240 We do generate a PLT entry when someone attempts to la.pcrel an external
241 function. But we never really implemented "R_LARCH_COPY", thus we've
242 never supported la.pcrel an external symbol unless the loaded address is
243 only used for locating a function to be called. Thus the PLT entry is
244 a normal PLT entry, not intended to be a so-called "canonical PLT entry"
245 on the ports supporting copy relocation. So attempting to la.pcrel an
246 external function will just break pointer equality, even it's a
247 STV_DEFAULT function:
251 void check(void *p) {assert(p == check);}
253 extern void check(void *);
254 int main(void) { check(check); }
255 $ cc t.c -fPIC -shared -o t.so
256 $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. -fpie -pie
258 a.out: t.c:2: check: Assertion `p == check' failed.
261 Thus handling STV_PROTECTED function specially just fixes nothing:
262 adding -fvisibility=protected compiling t.c will not magically fix
263 the inequality. The only possible and correct fix is not to use
264 -mdirect-extern-access.
266 So we should remove this special handling, because it's only an
267 unsuccessful workaround for invalid code and it's penalizing valid
269 #define LARCH_REF_LOCAL(info, h) \
270 (_bfd_elf_symbol_refs_local_p ((h), (info), true))
272 /* Generate a PLT header. */
275 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
278 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
281 if (pcrel
+ 0x80000800 > 0xffffffff)
283 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
284 bfd_set_error (bfd_error_bad_value
);
287 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
290 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
291 sub.[wd] $t1, $t1, $t3
292 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
293 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
294 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
295 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
296 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
299 if (GOT_ENTRY_SIZE
== 8)
301 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
302 entry
[1] = 0x0011bdad;
303 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
304 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
305 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
306 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
307 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
308 entry
[7] = 0x4c0001e0;
312 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
313 entry
[1] = 0x00113dad;
314 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
315 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
316 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
317 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
318 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
319 entry
[7] = 0x4c0001e0;
324 /* Generate a PLT entry. */
327 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
330 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
333 if (pcrel
+ 0x80000800 > 0xffffffff)
335 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
336 bfd_set_error (bfd_error_bad_value
);
339 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
342 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
343 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
344 | (lo
& 0xfff) << 10);
345 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
346 entry
[3] = 0x03400000; /* nop */
351 /* Create an entry in an LoongArch ELF linker hash table. */
353 static struct bfd_hash_entry
*
354 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
357 struct loongarch_elf_link_hash_entry
*eh
;
359 /* Allocate the structure if it has not already been allocated by a
363 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
368 /* Call the allocation method of the superclass. */
369 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
372 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
373 eh
->tls_type
= GOT_UNKNOWN
;
379 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
380 for local symbol so that we can handle local STT_GNU_IFUNC symbols
381 as global symbol. We reuse indx and dynstr_index for local symbol
382 hash since they aren't used by global symbols in this backend. */
385 elfNN_loongarch_local_htab_hash (const void *ptr
)
387 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
388 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
391 /* Compare local hash entries. */
394 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
396 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
397 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
399 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
402 /* Find and/or create a hash entry for local symbol. */
403 static struct elf_link_hash_entry
*
404 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
405 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
408 struct loongarch_elf_link_hash_entry e
, *ret
;
409 asection
*sec
= abfd
->sections
;
410 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
413 e
.elf
.indx
= sec
->id
;
414 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
415 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
416 create
? INSERT
: NO_INSERT
);
423 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
427 ret
= ((struct loongarch_elf_link_hash_entry
*)
428 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
429 sizeof (struct loongarch_elf_link_hash_entry
)));
432 memset (ret
, 0, sizeof (*ret
));
433 ret
->elf
.indx
= sec
->id
;
434 ret
->elf
.pointer_equality_needed
= 0;
435 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
436 ret
->elf
.dynindx
= -1;
437 ret
->elf
.needs_plt
= 0;
438 ret
->elf
.plt
.refcount
= -1;
439 ret
->elf
.got
.refcount
= -1;
440 ret
->elf
.def_dynamic
= 0;
441 ret
->elf
.def_regular
= 1;
442 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
443 ret
->elf
.ref_regular
= 0;
444 ret
->elf
.forced_local
= 1;
445 ret
->elf
.root
.type
= bfd_link_hash_defined
;
451 /* Destroy an LoongArch elf linker hash table. */
454 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
456 struct loongarch_elf_link_hash_table
*ret
;
457 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
459 if (ret
->loc_hash_table
)
460 htab_delete (ret
->loc_hash_table
);
461 if (ret
->loc_hash_memory
)
462 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
464 _bfd_elf_link_hash_table_free (obfd
);
467 /* Create a LoongArch ELF linker hash table. */
469 static struct bfd_link_hash_table
*
470 loongarch_elf_link_hash_table_create (bfd
*abfd
)
472 struct loongarch_elf_link_hash_table
*ret
;
473 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
475 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
479 if (!_bfd_elf_link_hash_table_init
480 (&ret
->elf
, abfd
, link_hash_newfunc
,
481 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
487 ret
->max_alignment
= MINUS_ONE
;
489 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
490 elfNN_loongarch_local_htab_eq
, NULL
);
491 ret
->loc_hash_memory
= objalloc_create ();
492 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
494 elfNN_loongarch_link_hash_table_free (abfd
);
497 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
499 return &ret
->elf
.root
;
502 /* Merge backend specific data from an object file to the output
503 object file when linking. */
506 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
508 bfd
*obfd
= info
->output_bfd
;
509 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
510 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
512 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
515 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
517 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
518 "the selected emulation:\n"
519 " target emulation `%s' does not match `%s'"),
520 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
524 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
527 /* If the input BFD is not a dynamic object and it does not contain any
528 non-data sections, do not account its ABI. For example, various
529 packages produces such data-only relocatable objects with
530 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
531 But they are compatible with all ABIs. */
532 if (!(ibfd
->flags
& DYNAMIC
))
535 bool have_code_sections
= false;
536 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
537 if ((bfd_section_flags (sec
)
538 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
539 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
541 have_code_sections
= true;
544 if (!have_code_sections
)
548 if (!elf_flags_init (obfd
))
550 elf_flags_init (obfd
) = true;
551 elf_elfheader (obfd
)->e_flags
= in_flags
;
554 else if (out_flags
!= in_flags
)
556 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags
)
557 && EF_LOONGARCH_IS_OBJ_V1 (in_flags
))
558 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags
)
559 && EF_LOONGARCH_IS_OBJ_V1 (out_flags
)))
561 elf_elfheader (obfd
)->e_flags
|= EF_LOONGARCH_OBJABI_V1
;
562 out_flags
= elf_elfheader (obfd
)->e_flags
;
563 in_flags
= out_flags
;
567 /* Disallow linking different ABIs. */
568 /* Only check relocation version.
569 The obj_v0 is compatible with obj_v1. */
570 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
572 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
579 bfd_set_error (bfd_error_bad_value
);
583 /* Create the .got section. */
586 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
591 struct elf_link_hash_entry
*h
;
592 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
593 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
595 /* This function may be called more than once. */
596 if (htab
->sgot
!= NULL
)
599 flags
= bed
->dynamic_sec_flags
;
600 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
601 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
603 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
607 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
608 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
612 /* The first bit of the global offset table is the header. */
613 s
->size
+= bed
->got_header_size
;
615 if (bed
->want_got_plt
)
617 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
618 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
622 /* Reserve room for the header. */
623 s
->size
= GOTPLT_HEADER_SIZE
;
626 if (bed
->want_got_sym
)
628 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
629 section. We don't do this in the linker script because we don't want
630 to define the symbol if we are not creating a global offset table. */
631 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
632 "_GLOBAL_OFFSET_TABLE_");
633 elf_hash_table (info
)->hgot
= h
;
640 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
641 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
645 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
647 struct loongarch_elf_link_hash_table
*htab
;
649 htab
= loongarch_elf_hash_table (info
);
650 BFD_ASSERT (htab
!= NULL
);
652 if (!loongarch_elf_create_got_section (dynobj
, info
))
655 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
658 if (!bfd_link_pic (info
))
660 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
661 SEC_ALLOC
| SEC_THREAD_LOCAL
);
663 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
664 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
671 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
672 struct bfd_link_info
*info
,
673 struct elf_link_hash_entry
*h
,
674 unsigned long symndx
,
677 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
678 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
680 /* This is a global offset table entry for a local symbol. */
681 if (elf_local_got_refcounts (abfd
) == NULL
)
684 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
685 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
687 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
688 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
698 if (htab
->elf
.sgot
== NULL
699 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
703 if (h
->got
.refcount
< 0)
708 elf_local_got_refcounts (abfd
)[symndx
]++;
711 /* No need for GOT. */
714 _bfd_error_handler (_("Internal error: unreachable."));
718 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
719 *new_tls_type
|= tls_type
;
721 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
722 if ((*new_tls_type
& GOT_TLS_IE
) && (*new_tls_type
& GOT_TLS_GDESC
))
723 *new_tls_type
&= ~ (GOT_TLS_GDESC
);
724 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
726 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
727 "thread local symbol"),
729 h
? h
->root
.root
.string
: "<local>");
737 loongarch_reloc_got_type (unsigned int r_type
)
741 case R_LARCH_TLS_DESC_PC_HI20
:
742 case R_LARCH_TLS_DESC_PC_LO12
:
743 case R_LARCH_TLS_DESC_LD
:
744 case R_LARCH_TLS_DESC_CALL
:
745 return GOT_TLS_GDESC
;
747 case R_LARCH_TLS_IE_PC_HI20
:
748 case R_LARCH_TLS_IE_PC_LO12
:
757 /* Return true if tls type transition can be performed. */
759 loongarch_can_trans_tls (bfd
*input_bfd
,
760 struct bfd_link_info
*info
,
761 struct elf_link_hash_entry
*h
,
762 unsigned int r_symndx
,
765 char symbol_tls_type
;
766 unsigned int reloc_got_type
;
768 /* Only TLS DESC/IE in normal code mode will perform type
770 if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type
))
773 /* Obtaining tls got type here may occur before
774 loongarch_elf_record_tls_and_got_reference, so it is necessary
775 to ensure that tls got type has been initialized, otherwise it
776 is set to GOT_UNKNOWN. */
777 symbol_tls_type
= GOT_UNKNOWN
;
778 if (_bfd_loongarch_elf_local_got_tls_type (input_bfd
) || h
)
779 symbol_tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
781 reloc_got_type
= loongarch_reloc_got_type (r_type
);
783 if (symbol_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
786 if (! bfd_link_executable (info
))
789 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
795 /* The type of relocation that can be transitioned. */
797 loongarch_tls_transition_without_check (struct bfd_link_info
*info
,
799 struct elf_link_hash_entry
*h
)
801 bool local_exec
= bfd_link_executable (info
)
802 && LARCH_REF_LOCAL (info
, h
);
806 case R_LARCH_TLS_DESC_PC_HI20
:
808 ? R_LARCH_TLS_LE_HI20
809 : R_LARCH_TLS_IE_PC_HI20
);
811 case R_LARCH_TLS_DESC_PC_LO12
:
813 ? R_LARCH_TLS_LE_LO12
814 : R_LARCH_TLS_IE_PC_LO12
);
816 case R_LARCH_TLS_DESC_LD
:
817 case R_LARCH_TLS_DESC_CALL
:
820 case R_LARCH_TLS_IE_PC_HI20
:
821 return local_exec
? R_LARCH_TLS_LE_HI20
: r_type
;
823 case R_LARCH_TLS_IE_PC_LO12
:
824 return local_exec
? R_LARCH_TLS_LE_LO12
: r_type
;
834 loongarch_tls_transition (bfd
*input_bfd
,
835 struct bfd_link_info
*info
,
836 struct elf_link_hash_entry
*h
,
837 unsigned int r_symndx
,
840 if (! loongarch_can_trans_tls (input_bfd
, info
, h
, r_symndx
, r_type
))
843 return loongarch_tls_transition_without_check (info
, r_type
, h
);
847 bad_static_reloc (bfd
*abfd
, const Elf_Internal_Rela
*rel
, asection
*sec
,
848 unsigned r_type
, struct elf_link_hash_entry
*h
,
849 Elf_Internal_Sym
*isym
)
851 /* We propably can improve the information to tell users that they should
852 be recompile the code with -fPIC or -fPIE, just like what x86 does. */
853 reloc_howto_type
* r
= loongarch_elf_rtype_to_howto (abfd
, r_type
);
854 const char *name
= NULL
;
857 name
= h
->root
.root
.string
;
859 name
= bfd_elf_string_from_elf_section (abfd
,
860 elf_symtab_hdr (abfd
).sh_link
,
862 if (name
== NULL
|| *name
== '\0')
865 (*_bfd_error_handler
)
866 (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
867 "a shared object; recompile with -fPIC"),
868 abfd
, sec
, (long) rel
->r_offset
, r
? r
->name
: _("<unknown>"), name
);
869 bfd_set_error (bfd_error_bad_value
);
873 /* Look through the relocs for a section during the first phase, and
874 allocate space in the global offset table or procedure linkage
878 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
879 asection
*sec
, const Elf_Internal_Rela
*relocs
)
881 struct loongarch_elf_link_hash_table
*htab
;
882 Elf_Internal_Shdr
*symtab_hdr
;
883 struct elf_link_hash_entry
**sym_hashes
;
884 const Elf_Internal_Rela
*rel
;
885 asection
*sreloc
= NULL
;
887 if (bfd_link_relocatable (info
))
890 htab
= loongarch_elf_hash_table (info
);
891 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
892 sym_hashes
= elf_sym_hashes (abfd
);
894 if (htab
->elf
.dynobj
== NULL
)
895 htab
->elf
.dynobj
= abfd
;
897 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
900 unsigned int r_symndx
;
901 struct elf_link_hash_entry
*h
;
902 bool is_abs_symbol
= false;
903 Elf_Internal_Sym
*isym
= NULL
;
905 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
906 r_type
= ELFNN_R_TYPE (rel
->r_info
);
908 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
910 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
914 if (r_symndx
< symtab_hdr
->sh_info
)
916 /* A local symbol. */
917 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
921 is_abs_symbol
= isym
->st_shndx
== SHN_ABS
;
922 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
924 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
928 h
->type
= STT_GNU_IFUNC
;
936 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
937 while (h
->root
.type
== bfd_link_hash_indirect
938 || h
->root
.type
== bfd_link_hash_warning
)
939 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
940 is_abs_symbol
= bfd_is_abs_symbol (&h
->root
);
943 /* It is referenced by a non-shared object. */
947 if (h
&& h
->type
== STT_GNU_IFUNC
)
949 if (htab
->elf
.dynobj
== NULL
)
950 htab
->elf
.dynobj
= abfd
;
952 /* Create 'irelifunc' in PIC object. */
953 if (bfd_link_pic (info
)
954 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
956 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
957 else if (!htab
->elf
.splt
958 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
960 /* Create the ifunc sections, iplt and ipltgot, for static
962 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
963 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
966 if (h
->plt
.refcount
< 0)
971 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
974 int need_dynreloc
= 0;
975 int only_need_pcrel
= 0;
977 /* Type transitions are only possible with relocations accompanied
979 if (rel
+ 1 != relocs
+ sec
->reloc_count
980 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
)
981 r_type
= loongarch_tls_transition (abfd
, info
, h
, r_symndx
, r_type
);
983 /* I don't want to spend time supporting DT_RELR with old object
984 files doing stack-based relocs. */
985 if (info
->enable_dt_relr
986 && r_type
>= R_LARCH_SOP_PUSH_PCREL
987 && r_type
<= R_LARCH_SOP_POP_32_U
)
989 /* xgettext:c-format */
990 _bfd_error_handler (_("%pB: stack based reloc type (%u) is not "
991 "supported with -z pack-relative-relocs"),
998 case R_LARCH_GOT_PC_HI20
:
999 case R_LARCH_GOT_HI20
:
1000 case R_LARCH_SOP_PUSH_GPREL
:
1001 /* For la.global. */
1003 h
->pointer_equality_needed
= 1;
1004 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1010 case R_LARCH_TLS_LD_PC_HI20
:
1011 case R_LARCH_TLS_LD_HI20
:
1012 case R_LARCH_TLS_GD_PC_HI20
:
1013 case R_LARCH_TLS_GD_HI20
:
1014 case R_LARCH_SOP_PUSH_TLS_GD
:
1015 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1021 case R_LARCH_TLS_IE_PC_HI20
:
1022 case R_LARCH_TLS_IE_HI20
:
1023 case R_LARCH_SOP_PUSH_TLS_GOT
:
1024 if (bfd_link_pic (info
))
1025 /* May fail for lazy-bind. */
1026 info
->flags
|= DF_STATIC_TLS
;
1028 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1034 case R_LARCH_TLS_LE_HI20
:
1035 case R_LARCH_TLS_LE_HI20_R
:
1036 case R_LARCH_SOP_PUSH_TLS_TPREL
:
1037 if (!bfd_link_executable (info
))
1038 return bad_static_reloc (abfd
, rel
, sec
, r_type
, h
, isym
);
1040 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1046 case R_LARCH_TLS_DESC_PC_HI20
:
1047 case R_LARCH_TLS_DESC_HI20
:
1048 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1054 case R_LARCH_ABS_HI20
:
1055 if (bfd_link_pic (info
))
1056 return bad_static_reloc (abfd
, rel
, sec
, r_type
, h
, isym
);
1059 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1061 /* If this reloc is in a read-only section, we might
1062 need a copy reloc. We can't check reliably at this
1063 stage whether the section is read-only, as input
1064 sections have not yet been mapped to output sections.
1065 Tentatively set the flag for now, and correct in
1066 adjust_dynamic_symbol. */
1070 /* For normal cmodel, pcalau12i + addi.d/w used to data.
1071 For first version medium cmodel, pcalau12i + jirl are used to
1072 function call, it need to creat PLT entry for STT_FUNC and
1073 STT_GNU_IFUNC type symbol. */
1074 case R_LARCH_PCALA_HI20
:
1075 if (h
!= NULL
&& (STT_FUNC
== h
->type
|| STT_GNU_IFUNC
== h
->type
))
1077 /* For pcalau12i + jirl. */
1079 if (h
->plt
.refcount
< 0)
1080 h
->plt
.refcount
= 0;
1084 h
->pointer_equality_needed
= 1;
1092 case R_LARCH_CALL36
:
1096 if (!bfd_link_pic (info
))
1099 /* We try to create PLT stub for all non-local function. */
1100 if (h
->plt
.refcount
< 0)
1101 h
->plt
.refcount
= 0;
1107 case R_LARCH_SOP_PUSH_PCREL
:
1110 if (!bfd_link_pic (info
))
1113 /* We try to create PLT stub for all non-local function. */
1114 if (h
->plt
.refcount
< 0)
1115 h
->plt
.refcount
= 0;
1117 h
->pointer_equality_needed
= 1;
1122 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1123 /* This symbol requires a procedure linkage table entry. We
1124 actually build the entry in adjust_dynamic_symbol,
1125 because this might be a case of linking PIC code without
1126 linking in any dynamic objects, in which case we don't
1127 need to generate a procedure linkage table after all. */
1131 if (h
->plt
.refcount
< 0)
1132 h
->plt
.refcount
= 0;
1137 case R_LARCH_TLS_DTPREL32
:
1138 case R_LARCH_TLS_DTPREL64
:
1140 only_need_pcrel
= 1;
1145 && bfd_link_pic (info
)
1146 && (sec
->flags
& SEC_ALLOC
) != 0)
1151 (_("%pB: relocation R_LARCH_32 against non-absolute "
1152 "symbol `%s' cannot be used in ELFCLASS64 when "
1153 "making a shared object or PIE"),
1154 abfd
, h
? h
->root
.root
.string
: "a local symbol");
1155 bfd_set_error (bfd_error_bad_value
);
1161 case R_LARCH_JUMP_SLOT
:
1164 /* Resolved to const. */
1170 /* If resolved symbol is defined in this object,
1171 1. Under pie, the symbol is known. We convert it
1172 into R_LARCH_RELATIVE and need load-addr still.
1173 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
1174 3. Under dll, R_LARCH_NN can't be changed normally, since
1175 its defination could be covered by the one in executable.
1176 For symbolic, we convert it into R_LARCH_RELATIVE.
1177 Thus, only under pde, it needs pcrel only. We discard it. */
1178 only_need_pcrel
= bfd_link_pde (info
);
1181 && (!bfd_link_pic (info
)
1182 || h
->type
== STT_GNU_IFUNC
))
1184 /* This reloc might not bind locally. */
1186 h
->pointer_equality_needed
= 1;
1189 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
1191 /* We may need a .plt entry if the symbol is a function
1192 defined in a shared lib or is a function referenced
1193 from the code or read-only section. */
1194 h
->plt
.refcount
+= 1;
1199 case R_LARCH_GNU_VTINHERIT
:
1200 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1204 case R_LARCH_GNU_VTENTRY
:
1205 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1210 /* Check against irrational R_LARCH_ALIGN relocs which may cause
1211 removing an odd number of bytes and disrupt DT_RELR. */
1212 if (rel
->r_offset
% 4 != 0)
1214 /* xgettext:c-format */
1215 _bfd_error_handler (
1216 _("%pB: R_LARCH_ALIGN with offset %" PRId64
" not aligned "
1217 "to instruction boundary"),
1218 abfd
, (uint64_t) rel
->r_offset
);
1227 /* Record some info for sizing and allocating dynamic entry. */
1228 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
1230 /* When creating a shared object, we must copy these
1231 relocs into the output file. We create a reloc
1232 section in dynobj and make room for the reloc. */
1233 struct elf_dyn_relocs
*p
;
1234 struct elf_dyn_relocs
**head
;
1239 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
1240 LARCH_ELF_LOG_WORD_BYTES
,
1241 abfd
, /*rela?*/ true);
1246 /* If this is a global symbol, we count the number of
1247 relocations we need for this symbol. */
1249 head
= &h
->dyn_relocs
;
1252 /* Track dynamic relocs needed for local syms too.
1253 We really need local syms available to do this
1259 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1263 vpp
= &elf_section_data (s
)->local_dynrel
;
1264 head
= (struct elf_dyn_relocs
**) vpp
;
1268 if (p
== NULL
|| p
->sec
!= sec
)
1270 bfd_size_type amt
= sizeof *p
;
1271 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
1282 p
->pc_count
+= only_need_pcrel
;
1289 /* Find dynamic relocs for H that apply to read-only sections. */
1292 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
1294 struct elf_dyn_relocs
*p
;
1296 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1298 asection
*s
= p
->sec
->output_section
;
1300 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
1306 /* Adjust a symbol defined by a dynamic object and referenced by a
1307 regular object. The current definition is in some section of the
1308 dynamic object, but we're not including those sections. We have to
1309 change the definition to something the rest of the link can
1312 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
1313 struct elf_link_hash_entry
*h
)
1315 struct loongarch_elf_link_hash_table
*htab
;
1318 htab
= loongarch_elf_hash_table (info
);
1319 BFD_ASSERT (htab
!= NULL
);
1321 dynobj
= htab
->elf
.dynobj
;
1323 /* Make sure we know what is going on here. */
1324 BFD_ASSERT (dynobj
!= NULL
1326 || h
->type
== STT_GNU_IFUNC
1330 && !h
->def_regular
)));
1332 /* If this is a function, put it in the procedure linkage table. We
1333 will fill in the contents of the procedure linkage table later
1334 (although we could actually do it here). */
1335 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
1337 if (h
->plt
.refcount
<= 0
1338 || (h
->type
!= STT_GNU_IFUNC
1339 && (LARCH_REF_LOCAL (info
, h
)
1340 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1341 && h
->root
.type
== bfd_link_hash_undefweak
))))
1343 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1344 in an input file, but the symbol was never referred to by a
1345 dynamic object, or if all references were garbage collected.
1346 In such a case, we don't actually need to build a PLT entry. */
1347 h
->plt
.offset
= MINUS_ONE
;
1354 h
->plt
.offset
= MINUS_ONE
;
1356 /* If this is a weak symbol, and there is a real definition, the
1357 processor independent code will have arranged for us to see the
1358 real definition first, and we can just use the same value. */
1359 if (h
->is_weakalias
)
1361 struct elf_link_hash_entry
*def
= weakdef (h
);
1362 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
1363 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
1364 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
1368 /* R_LARCH_COPY is not adept glibc, not to generate. */
1369 /* Can not print anything, because make check ld. */
1373 /* Allocate space in .plt, .got and associated reloc sections for
1377 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1379 struct bfd_link_info
*info
;
1380 struct loongarch_elf_link_hash_table
*htab
;
1381 struct elf_dyn_relocs
*p
;
1383 if (h
->root
.type
== bfd_link_hash_indirect
)
1386 if (h
->type
== STT_GNU_IFUNC
1390 info
= (struct bfd_link_info
*) inf
;
1391 htab
= loongarch_elf_hash_table (info
);
1392 bool dyn
= htab
->elf
.dynamic_sections_created
;
1393 BFD_ASSERT (htab
!= NULL
);
1397 asection
*plt
, *gotplt
, *relplt
;
1406 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1407 && h
->root
.type
== bfd_link_hash_undefweak
)
1409 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1413 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1414 && h
->type
!= STT_GNU_IFUNC
)
1417 plt
= htab
->elf
.splt
;
1418 gotplt
= htab
->elf
.sgotplt
;
1419 relplt
= htab
->elf
.srelplt
;
1421 else if (htab
->elf
.iplt
)
1423 /* .iplt only for IFUNC. */
1424 if (h
->type
!= STT_GNU_IFUNC
)
1427 plt
= htab
->elf
.iplt
;
1428 gotplt
= htab
->elf
.igotplt
;
1429 relplt
= htab
->elf
.irelplt
;
1435 plt
->size
= PLT_HEADER_SIZE
;
1437 h
->plt
.offset
= plt
->size
;
1438 plt
->size
+= PLT_ENTRY_SIZE
;
1439 gotplt
->size
+= GOT_ENTRY_SIZE
;
1440 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1442 /* If this symbol is not defined in a regular file, and we are
1443 not generating a shared library, then set the symbol to this
1444 location in the .plt. This is required to make function
1445 pointers compare as equal between the normal executable and
1446 the shared library. */
1447 if (!bfd_link_pic (info
)
1450 h
->root
.u
.def
.section
= plt
;
1451 h
->root
.u
.def
.value
= h
->plt
.offset
;
1459 h
->plt
.offset
= MINUS_ONE
;
1461 if (0 < h
->got
.refcount
)
1464 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1466 /* Make sure this symbol is output as a dynamic symbol.
1467 Undefined weak syms won't yet be marked as dynamic. */
1468 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1469 && h
->root
.type
== bfd_link_hash_undefweak
)
1471 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1476 h
->got
.offset
= s
->size
;
1477 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1480 bool need_reloc
= false;
1481 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, dyn
, h
, indx
,
1483 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1484 if (tls_type
& GOT_TLS_GD
)
1486 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1488 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1491 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1492 if (tls_type
& GOT_TLS_IE
)
1494 s
->size
+= GOT_ENTRY_SIZE
;
1496 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1499 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1500 if (tls_type
& GOT_TLS_GDESC
)
1502 s
->size
+= GOT_ENTRY_SIZE
* 2;
1503 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1509 s
->size
+= GOT_ENTRY_SIZE
;
1510 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1511 || h
->root
.type
!= bfd_link_hash_undefweak
)
1512 && (bfd_link_pic (info
)
1513 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
),
1515 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1516 /* Undefined weak symbol in static PIE resolves to 0 without
1517 any dynamic relocations. */
1518 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1522 h
->got
.offset
= MINUS_ONE
;
1524 if (h
->dyn_relocs
== NULL
)
1527 /* Extra dynamic relocate,
1529 * R_LARCH_TLS_DTPRELNN
1533 if (SYMBOL_CALLS_LOCAL (info
, h
))
1535 struct elf_dyn_relocs
**pp
;
1537 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1539 p
->count
-= p
->pc_count
;
1548 if (h
->root
.type
== bfd_link_hash_undefweak
)
1550 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
)
1551 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1552 || (!bfd_link_pic (info
) && h
->non_got_ref
))
1553 h
->dyn_relocs
= NULL
;
1554 else if (h
->dynindx
== -1 && !h
->forced_local
)
1556 /* Make sure this symbol is output as a dynamic symbol.
1557 Undefined weak syms won't yet be marked as dynamic. */
1558 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1561 if (h
->dynindx
== -1)
1562 h
->dyn_relocs
= NULL
;
1566 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1568 if (discarded_section (p
->sec
))
1570 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1571 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1577 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1578 For local def and ref ifunc,
1579 dynamic relocations are stored in
1580 1. rela.srelgot section in dynamic object (dll or exec).
1581 2. rela.irelplt section in static executable.
1582 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1583 instead of rela.srelplt. Glibc ELF loader will not support
1584 R_LARCH_IRELATIVE relocation in rela.plt. */
1587 local_allocate_ifunc_dyn_relocs (struct bfd_link_info
*info
,
1588 struct elf_link_hash_entry
*h
,
1589 struct elf_dyn_relocs
**head
,
1590 unsigned int plt_entry_size
,
1591 unsigned int plt_header_size
,
1592 unsigned int got_entry_size
,
1595 asection
*plt
, *gotplt
, *relplt
;
1596 struct elf_dyn_relocs
*p
;
1597 unsigned int sizeof_reloc
;
1598 const struct elf_backend_data
*bed
;
1599 struct elf_link_hash_table
*htab
;
1600 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1601 bool use_plt
= !avoid_plt
|| h
->plt
.refcount
> 0;
1602 bool need_dynreloc
= !use_plt
|| bfd_link_pic (info
);
1604 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1605 in executable or it isn't referenced via PLT, the address of
1606 the resolved function may be used. But in non-PIC executable,
1607 the address of its plt slot may be used. Pointer equality may
1608 not work correctly. PIE or non-PLT reference should be used if
1609 pointer equality is required here.
1611 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1612 backend should change it to the normal function and set its address
1613 to its PLT entry which should be resolved by R_*_IRELATIVE at
1614 run-time. All external references should be resolved to its PLT in
1617 && !(bfd_link_pde (info
) && h
->def_regular
)
1618 && (h
->dynindx
!= -1
1619 || info
->export_dynamic
)
1620 && h
->pointer_equality_needed
)
1622 info
->callbacks
->einfo
1623 /* xgettext:c-format. */
1624 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1625 "equality in `%pB' can not be used when making an "
1626 "executable; recompile with -fPIE and relink with -pie\n"),
1627 h
->root
.root
.string
,
1628 h
->root
.u
.def
.section
->owner
);
1629 bfd_set_error (bfd_error_bad_value
);
1633 htab
= elf_hash_table (info
);
1635 /* When the symbol is marked with regular reference, if PLT isn't used
1636 or we are building a PIC object, we must keep dynamic relocation
1637 if there is non-GOT reference and use PLT if there is PC-relative
1639 if (need_dynreloc
&& h
->ref_regular
)
1642 for (p
= *head
; p
!= NULL
; p
= p
->next
)
1646 /* Need dynamic relocations for non-GOT reference. */
1650 /* Must use PLT for PC-relative reference. */
1652 need_dynreloc
= bfd_link_pic (info
);
1660 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1661 if (h
->plt
.refcount
<= 0 && h
->got
.refcount
<= 0)
1663 h
->got
= htab
->init_got_offset
;
1664 h
->plt
= htab
->init_plt_offset
;
1669 /* Return and discard space for dynamic relocations against it if
1670 it is never referenced. */
1671 if (!h
->ref_regular
)
1673 if (h
->plt
.refcount
> 0
1674 || h
->got
.refcount
> 0)
1676 h
->got
= htab
->init_got_offset
;
1677 h
->plt
= htab
->init_plt_offset
;
1683 bed
= get_elf_backend_data (info
->output_bfd
);
1684 if (bed
->rela_plts_and_copies_p
)
1685 sizeof_reloc
= bed
->s
->sizeof_rela
;
1687 sizeof_reloc
= bed
->s
->sizeof_rel
;
1689 /* When building a static executable, use iplt, igot.plt and
1690 rela.iplt sections for STT_GNU_IFUNC symbols. */
1691 if (htab
->splt
!= NULL
)
1694 gotplt
= htab
->sgotplt
;
1695 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1696 relplt
= htab
->srelgot
;
1698 /* If this is the first plt entry and PLT is used, make room for
1699 the special first entry. */
1700 if (plt
->size
== 0 && use_plt
)
1701 plt
->size
+= plt_header_size
;
1706 gotplt
= htab
->igotplt
;
1707 relplt
= htab
->irelplt
;
1712 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1713 the original value for R_*_IRELATIVE. */
1714 h
->plt
.offset
= plt
->size
;
1716 /* Make room for this entry in the plt/iplt section. */
1717 plt
->size
+= plt_entry_size
;
1719 /* We also need to make an entry in the got.plt/got.iplt section,
1720 which will be placed in the got section by the linker script. */
1721 gotplt
->size
+= got_entry_size
;
1724 /* We also need to make an entry in the rela.plt/.rela.iplt
1725 section for GOTPLT relocation if PLT is used. */
1728 relplt
->size
+= sizeof_reloc
;
1729 relplt
->reloc_count
++;
1732 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1733 there is a non-GOT reference in a PIC object or PLT isn't used. */
1734 if (!need_dynreloc
|| !h
->non_got_ref
)
1737 /* Finally, allocate space. */
1741 bfd_size_type count
= 0;
1749 htab
->ifunc_resolvers
= count
!= 0;
1751 /* Dynamic relocations are stored in
1752 1. rela.srelgot section in PIC object.
1753 2. rela.srelgot section in dynamic executable.
1754 3. rela.irelplt section in static executable. */
1755 if (htab
->splt
!= NULL
)
1756 htab
->srelgot
->size
+= count
* sizeof_reloc
;
1759 relplt
->size
+= count
* sizeof_reloc
;
1760 relplt
->reloc_count
+= count
;
1764 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1765 and got has the PLT entry adddress. We will load the GOT entry
1766 with the PLT entry in finish_dynamic_symbol if it is used. For
1767 branch, it uses got.plt. For symbol value, if PLT is used,
1768 1. Use got.plt in a PIC object if it is forced local or not
1770 2. Use got.plt in a non-PIC object if pointer equality isn't
1772 3. Use got.plt in PIE.
1773 4. Use got.plt if got isn't used.
1774 5. Otherwise use got so that it can be shared among different
1775 objects at run-time.
1776 If PLT isn't used, always use got for symbol value.
1777 We only need to relocate got entry in PIC object or in dynamic
1778 executable without PLT. */
1780 && (h
->got
.refcount
<= 0
1781 || (bfd_link_pic (info
)
1782 && (h
->dynindx
== -1
1783 || h
->forced_local
))
1785 !h
->pointer_equality_needed
)
1786 || htab
->sgot
== NULL
))
1789 h
->got
.offset
= (bfd_vma
) -1;
1795 /* PLT isn't used. */
1796 h
->plt
.offset
= (bfd_vma
) -1;
1798 if (h
->got
.refcount
<= 0)
1800 /* GOT isn't need when there are only relocations for static
1802 h
->got
.offset
= (bfd_vma
) -1;
1806 h
->got
.offset
= htab
->sgot
->size
;
1807 htab
->sgot
->size
+= got_entry_size
;
1808 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1809 used. Otherwise, the GOT entry will be filled with the PLT
1810 entry and dynamic GOT relocation isn't needed. */
1813 /* For non-static executable, dynamic GOT relocation is in
1814 rela.got section, but for static executable, it is
1815 in rela.iplt section. */
1816 if (htab
->splt
!= NULL
)
1817 htab
->srelgot
->size
+= sizeof_reloc
;
1820 relplt
->size
+= sizeof_reloc
;
1821 relplt
->reloc_count
++;
1830 /* Allocate space in .plt, .got and associated reloc sections for
1831 ifunc dynamic relocs. */
1834 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
1835 struct bfd_link_info
*info
,
1838 /* An example of a bfd_link_hash_indirect symbol is versioned
1839 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1840 -> __gxx_personality_v0(bfd_link_hash_defined)
1842 There is no need to process bfd_link_hash_indirect symbols here
1843 because we will also be presented with the concrete instance of
1844 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1845 called to copy all relevant data from the generic to the concrete
1847 if (h
->root
.type
== bfd_link_hash_indirect
)
1850 if (h
->root
.type
== bfd_link_hash_warning
)
1851 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1853 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1854 here if it is defined and referenced in a non-shared object. */
1855 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
1857 if (ref_local
&& LARCH_REF_LOCAL (info
, h
))
1858 return local_allocate_ifunc_dyn_relocs (info
, h
,
1864 else if (!ref_local
&& !LARCH_REF_LOCAL (info
, h
))
1865 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1877 elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry
*h
,
1880 return elfNN_allocate_ifunc_dynrelocs (h
, (struct bfd_link_info
*) info
,
1885 elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry
*h
,
1888 return elfNN_allocate_ifunc_dynrelocs (h
, (struct bfd_link_info
*) info
,
1892 /* Allocate space in .plt, .got and associated reloc sections for
1893 ifunc dynamic relocs. */
1896 elfNN_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
1898 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1900 if (h
->type
!= STT_GNU_IFUNC
1904 || h
->root
.type
!= bfd_link_hash_defined
)
1907 return elfNN_allocate_ifunc_dynrelocs_ref_local (h
, inf
);
1910 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1911 read-only sections. */
1914 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1918 if (h
->root
.type
== bfd_link_hash_indirect
)
1921 sec
= readonly_dynrelocs (h
);
1924 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1926 info
->flags
|= DF_TEXTREL
;
1927 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1928 "read-only section `%pA'\n"),
1929 sec
->owner
, h
->root
.root
.string
, sec
);
1931 /* Not an error, just cut short the traversal. */
1938 record_relr (struct loongarch_elf_link_hash_table
*htab
, asection
*sec
,
1939 bfd_vma off
, asection
*sreloc
)
1941 struct relr_entry
**sec_relr
= &loongarch_elf_section_data (sec
)->relr
;
1943 /* Undo the relocation section size accounting. */
1944 BFD_ASSERT (sreloc
->size
>= sizeof (ElfNN_External_Rela
));
1945 sreloc
->size
-= sizeof (ElfNN_External_Rela
);
1947 BFD_ASSERT (off
% 2 == 0 && sec
->alignment_power
> 0);
1948 if (htab
->relr_count
>= htab
->relr_alloc
)
1950 if (htab
->relr_alloc
== 0)
1951 htab
->relr_alloc
= 4096;
1953 htab
->relr_alloc
*= 2;
1955 htab
->relr
= bfd_realloc (htab
->relr
,
1956 htab
->relr_alloc
* sizeof (*htab
->relr
));
1960 htab
->relr
[htab
->relr_count
].sec
= sec
;
1961 htab
->relr
[htab
->relr_count
].off
= off
;
1962 if (*sec_relr
== NULL
)
1963 *sec_relr
= &htab
->relr
[htab
->relr_count
];
1969 record_relr_local_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
)
1971 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
1972 char *local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (input_bfd
);
1973 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
1974 struct loongarch_elf_link_hash_table
*htab
=
1975 loongarch_elf_hash_table (info
);
1977 if (!local_got_offsets
|| !local_tls_type
|| !bfd_link_pic (info
))
1980 for (unsigned i
= 0; i
< symtab_hdr
->sh_info
; i
++)
1982 bfd_vma off
= local_got_offsets
[i
];
1984 /* FIXME: If the local symbol is in SHN_ABS then emitting
1985 a relative relocation is not correct, but it seems to be wrong
1986 in loongarch_elf_relocate_section too. */
1987 if (local_tls_type
[i
] == GOT_NORMAL
1988 && !record_relr (htab
, htab
->elf
.sgot
, off
, htab
->elf
.srelgot
))
1996 record_relr_dyn_got_relocs (struct elf_link_hash_entry
*h
, void *inf
)
1998 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
1999 struct loongarch_elf_link_hash_table
*htab
=
2000 loongarch_elf_hash_table (info
);
2002 if (h
->root
.type
== bfd_link_hash_indirect
)
2004 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
2006 if (h
->got
.refcount
<= 0)
2008 if (loongarch_elf_hash_entry (h
)->tls_type
2009 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
2011 if (!bfd_link_pic (info
))
2014 /* On LoongArch a GOT entry for undefined weak symbol is never relocated
2015 with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus
2016 the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or
2017 relocated with R_LARCH_NN (otherwise). */
2018 if (h
->root
.type
== bfd_link_hash_undefweak
)
2021 if (!LARCH_REF_LOCAL (info
, h
))
2023 if (bfd_is_abs_symbol (&h
->root
))
2026 if (!record_relr (htab
, htab
->elf
.sgot
, h
->got
.offset
,
2034 record_relr_non_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
,
2038 struct loongarch_elf_link_hash_table
*htab
;
2039 Elf_Internal_Rela
*relocs
, *rel
, *rel_end
;
2040 Elf_Internal_Shdr
*symtab_hdr
;
2041 struct elf_link_hash_entry
**sym_hashes
;
2043 if (!bfd_link_pic (info
))
2045 if (sec
->reloc_count
== 0)
2047 if ((sec
->flags
& (SEC_RELOC
| SEC_ALLOC
| SEC_DEBUGGING
))
2048 != (SEC_RELOC
| SEC_ALLOC
))
2050 if (sec
->alignment_power
== 0)
2052 if (discarded_section (sec
))
2055 sreloc
= elf_section_data (sec
)->sreloc
;
2059 htab
= loongarch_elf_hash_table (info
);
2060 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2061 sym_hashes
= elf_sym_hashes (input_bfd
);
2062 relocs
= _bfd_elf_link_info_read_relocs (input_bfd
, info
, sec
, NULL
,
2063 NULL
, info
->keep_memory
);
2064 BFD_ASSERT (relocs
!= NULL
);
2065 rel_end
= relocs
+ sec
->reloc_count
;
2066 for (rel
= relocs
; rel
< rel_end
; rel
++)
2068 unsigned r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2069 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
2070 struct elf_link_hash_entry
*h
= NULL
;
2071 asection
*def_sec
= NULL
;
2073 if ((r_type
!= R_LARCH_64
&& r_type
!= R_LARCH_32
)
2074 || rel
->r_offset
% 2 != 0)
2077 /* The logical below must match loongarch_elf_relocate_section. */
2078 if (r_symndx
< symtab_hdr
->sh_info
)
2080 /* A local symbol. */
2081 Elf_Internal_Sym
*isym
;
2082 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, input_bfd
,
2084 BFD_ASSERT(isym
!= NULL
);
2086 /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for
2087 R_LARCH_NN, not R_LARCH_RELATIVE. */
2088 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
2090 def_sec
= bfd_section_from_elf_index (input_bfd
, isym
->st_shndx
);
2094 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2095 while (h
->root
.type
== bfd_link_hash_indirect
2096 || h
->root
.type
== bfd_link_hash_warning
)
2097 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2099 /* Filter out symbols that cannot have a relative reloc. */
2100 if (h
->dyn_relocs
== NULL
)
2102 if (bfd_is_abs_symbol (&h
->root
))
2104 if (h
->type
== STT_GNU_IFUNC
)
2107 if (h
->root
.type
== bfd_link_hash_defined
2108 || h
->root
.type
== bfd_link_hash_defweak
)
2109 def_sec
= h
->root
.u
.def
.section
;
2111 /* On LoongArch an R_LARCH_NN against undefined weak symbol
2112 is never converted to R_LARCH_RELATIVE: we don't have
2113 -z dynamic-undefined-weak, thus the reloc is either removed
2114 (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */
2115 if (h
->root
.type
== bfd_link_hash_undefweak
)
2118 if (!LARCH_REF_LOCAL (info
, h
))
2122 if (!def_sec
|| discarded_section (def_sec
))
2125 if (!record_relr (htab
, sec
, rel
->r_offset
, sreloc
))
2133 cmp_relr_addr (const void *p
, const void *q
)
2135 const bfd_vma
*a
= p
, *b
= q
;
2136 return (*a
> *b
) - (*a
< *b
);
2140 sort_relr (struct bfd_link_info
*info
,
2141 struct loongarch_elf_link_hash_table
*htab
)
2143 if (htab
->relr_count
== 0)
2146 bfd_vma
*addr
= htab
->relr_sorted
;
2149 addr
= bfd_malloc (htab
->relr_count
* sizeof (*addr
));
2152 htab
->relr_sorted
= addr
;
2155 for (bfd_size_type i
= 0; i
< htab
->relr_count
; i
++)
2157 bfd_vma off
= _bfd_elf_section_offset (info
->output_bfd
, info
,
2160 addr
[i
] = htab
->relr
[i
].sec
->output_section
->vma
2161 + htab
->relr
[i
].sec
->output_offset
+ off
;
2163 qsort(addr
, htab
->relr_count
, sizeof (*addr
), cmp_relr_addr
);
2168 loongarch_elf_size_relative_relocs (struct bfd_link_info
*info
,
2171 struct loongarch_elf_link_hash_table
*htab
=
2172 loongarch_elf_hash_table (info
);
2173 asection
*srelrdyn
= htab
->elf
.srelrdyn
;
2175 *need_layout
= false;
2177 if (!sort_relr (info
, htab
))
2179 bfd_vma
*addr
= htab
->relr_sorted
;
2181 BFD_ASSERT (srelrdyn
!= NULL
);
2182 bfd_size_type oldsize
= srelrdyn
->size
;
2184 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
2186 bfd_vma base
= addr
[i
];
2188 srelrdyn
->size
+= NN
/ 8;
2192 bfd_size_type start_i
= i
;
2193 while (i
< htab
->relr_count
2194 && addr
[i
] - base
< (NN
- 1) * (NN
/ 8)
2195 && (addr
[i
] - base
) % (NN
/ 8) == 0)
2199 srelrdyn
->size
+= NN
/ 8;
2200 base
+= (NN
- 1) * (NN
/ 8);
2203 if (srelrdyn
->size
!= oldsize
)
2205 *need_layout
= true;
2206 /* Stop after a few iterations in case the layout does not converge,
2207 but we can only stop when the size would shrink (and pad the
2208 spare space with 1. */
2209 if (htab
->relr_layout_iter
++ > 5 && srelrdyn
->size
< oldsize
)
2211 srelrdyn
->size
= oldsize
;
2212 *need_layout
= false;
2219 loongarch_elf_finish_relative_relocs (struct bfd_link_info
*info
)
2221 struct loongarch_elf_link_hash_table
*htab
=
2222 loongarch_elf_hash_table (info
);
2223 asection
*srelrdyn
= htab
->elf
.srelrdyn
;
2224 bfd
*dynobj
= htab
->elf
.dynobj
;
2226 if (!srelrdyn
|| srelrdyn
->size
== 0)
2229 srelrdyn
->contents
= bfd_alloc (dynobj
, srelrdyn
->size
);
2230 if (!srelrdyn
->contents
)
2233 bfd_vma
*addr
= htab
->relr_sorted
;
2234 bfd_byte
*loc
= srelrdyn
->contents
;
2235 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
2237 bfd_vma base
= addr
[i
];
2239 bfd_put_NN (dynobj
, base
, loc
);
2245 while (i
< htab
->relr_count
)
2247 bfd_vma delta
= addr
[i
] - base
;
2248 if (delta
>= (NN
- 1) * (NN
/ 8) || delta
% (NN
/ 8) != 0)
2250 bits
|= (uintNN_t
) 1 << (delta
/ (NN
/ 8));
2255 bfd_put_NN (dynobj
, (bits
<< 1) | 1, loc
);
2257 base
+= (NN
- 1) * (NN
/ 8);
2262 htab
->relr_sorted
= NULL
;
2264 /* Pad any excess with 1's, a do-nothing encoding. */
2265 while (loc
< srelrdyn
->contents
+ srelrdyn
->size
)
2267 bfd_put_NN (dynobj
, 1, loc
);
2275 loongarch_elf_late_size_sections (bfd
*output_bfd
,
2276 struct bfd_link_info
*info
)
2278 struct loongarch_elf_link_hash_table
*htab
;
2283 htab
= loongarch_elf_hash_table (info
);
2284 BFD_ASSERT (htab
!= NULL
);
2285 dynobj
= htab
->elf
.dynobj
;
2289 if (htab
->elf
.dynamic_sections_created
)
2291 /* Set the contents of the .interp section to the interpreter. */
2292 if (bfd_link_executable (info
) && !info
->nointerp
)
2294 const char *interpreter
;
2295 s
= bfd_get_linker_section (dynobj
, ".interp");
2296 BFD_ASSERT (s
!= NULL
);
2298 if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS32
)
2299 interpreter
= "/lib32/ld.so.1";
2300 else if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS64
)
2301 interpreter
= "/lib64/ld.so.1";
2303 interpreter
= "/lib/ld.so.1";
2305 s
->contents
= (unsigned char *) interpreter
;
2306 s
->size
= strlen (interpreter
) + 1;
2310 /* Set up .got offsets for local syms, and space for local dynamic
2312 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2314 bfd_signed_vma
*local_got
;
2315 bfd_signed_vma
*end_local_got
;
2316 char *local_tls_type
;
2317 bfd_size_type locsymcount
;
2318 Elf_Internal_Shdr
*symtab_hdr
;
2321 if (!is_loongarch_elf (ibfd
))
2324 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2326 struct elf_dyn_relocs
*p
;
2328 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
2330 p
->count
-= p
->pc_count
;
2331 if (!bfd_is_abs_section (p
->sec
)
2332 && bfd_is_abs_section (p
->sec
->output_section
))
2334 /* Input section has been discarded, either because
2335 it is a copy of a linkonce section or due to
2336 linker script /DISCARD/, so we'll be discarding
2339 else if (0 < p
->count
)
2341 srel
= elf_section_data (p
->sec
)->sreloc
;
2342 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
2343 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
2344 info
->flags
|= DF_TEXTREL
;
2349 local_got
= elf_local_got_refcounts (ibfd
);
2353 symtab_hdr
= &elf_symtab_hdr (ibfd
);
2354 locsymcount
= symtab_hdr
->sh_info
;
2355 end_local_got
= local_got
+ locsymcount
;
2356 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
2358 srel
= htab
->elf
.srelgot
;
2359 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
2363 *local_got
= s
->size
;
2364 if (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
2366 /* TLS gd use two got. */
2367 if (*local_tls_type
& GOT_TLS_GD
)
2369 s
->size
+= 2 * GOT_ENTRY_SIZE
;
2370 if (!bfd_link_executable (info
))
2371 srel
->size
+= sizeof (ElfNN_External_Rela
);
2374 /* TLS_DESC use two got. */
2375 if (*local_tls_type
& GOT_TLS_GDESC
)
2377 s
->size
+= 2 * GOT_ENTRY_SIZE
;
2378 srel
->size
+= sizeof (ElfNN_External_Rela
);
2381 /* TLS ie and use one got. */
2382 if (*local_tls_type
& GOT_TLS_IE
)
2384 s
->size
+= GOT_ENTRY_SIZE
;
2385 if (!bfd_link_executable (info
))
2386 srel
->size
+= sizeof (ElfNN_External_Rela
);
2391 s
->size
+= GOT_ENTRY_SIZE
;
2392 srel
->size
+= sizeof (ElfNN_External_Rela
);
2396 *local_got
= MINUS_ONE
;
2400 /* Allocate global sym .plt and .got entries, and space for global
2401 sym dynamic relocs. */
2402 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
2404 /* Allocate global ifunc sym .plt and .got entries, and space for
2405 *preemptible* ifunc sym dynamic relocs. Note that we must do it
2406 for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN
2407 ifuncs) before doing it for any non-preemptible ifunc symbol:
2408 assuming we are not so careful, when we link a shared library the
2409 correlation of .plt and .rela.plt might look like:
2411 idx in .plt idx in .rela.plt
2415 hidden_ifunc1@plt 3 None: it's in .rela.got
2416 hidden_ifunc2@plt 4 None: it's in .rela.got
2417 normal_ifunc1@plt 5 != 3
2418 normal_ifunc2@plt 6 != 4
2419 local_ifunc@plt 7 None: it's in .rela.got
2421 Now oops the indices for normal_ifunc{1,2} in .rela.plt were different
2422 from the indices in .plt :(. This would break finish_dynamic_symbol
2423 which assumes the index in .rela.plt matches the index in .plt.
2425 So let's be careful and make it correct:
2427 idx in .plt idx in .rela.plt
2431 normal_ifunc1@plt 3 3
2432 normal_ifunc2@plt 4 4
2433 hidden_ifunc1@plt 5 None: it's in .rela.got
2434 hidden_ifunc2@plt 6 None: it's in .rela.got
2435 local_ifunc@plt 7 None: it's in .rela.got
2437 Now normal_ifuncs first. */
2438 elf_link_hash_traverse (&htab
->elf
,
2439 elfNN_allocate_ifunc_dynrelocs_ref_global
, info
);
2441 /* Next hidden_ifuncs follows. */
2442 elf_link_hash_traverse (&htab
->elf
,
2443 elfNN_allocate_ifunc_dynrelocs_ref_local
, info
);
2445 /* Finally local_ifuncs. */
2446 htab_traverse (htab
->loc_hash_table
,
2447 elfNN_allocate_local_ifunc_dynrelocs
, info
);
2449 /* Don't allocate .got.plt section if there are no PLT. */
2450 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
2451 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
2452 htab
->elf
.sgotplt
->size
= 0;
2454 if (info
->enable_dt_relr
&& !bfd_link_relocatable (info
))
2456 elf_link_hash_traverse (&htab
->elf
, record_relr_dyn_got_relocs
, info
);
2458 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2460 if (!is_loongarch_elf (ibfd
))
2463 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2464 if (!record_relr_non_got_relocs (ibfd
, info
, s
))
2467 if (!record_relr_local_got_relocs (ibfd
, info
))
2472 /* The check_relocs and adjust_dynamic_symbol entry points have
2473 determined the sizes of the various dynamic sections. Allocate
2475 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2477 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
2480 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
2481 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
2482 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
2484 /* Strip this section if we don't need it; see the
2487 else if (strncmp (s
->name
, ".rela", 5) == 0)
2491 /* We use the reloc_count field as a counter if we need
2492 to copy relocs into the output file. */
2496 else if (s
== htab
->elf
.srelrdyn
&& htab
->relr_count
== 0)
2498 /* Remove .relr.dyn based on relr_count, not size, since
2499 it is not sized yet. */
2500 s
->flags
|= SEC_EXCLUDE
;
2501 /* Allocate contents later. */
2506 /* It's not one of our sections. */
2512 /* If we don't need this section, strip it from the
2513 output file. This is mostly to handle .rela.bss and
2514 .rela.plt. We must create both sections in
2515 create_dynamic_sections, because they must be created
2516 before the linker maps input sections to output
2517 sections. The linker does that before
2518 adjust_dynamic_symbol is called, and it is that
2519 function which decides whether anything needs to go
2520 into these sections. */
2521 s
->flags
|= SEC_EXCLUDE
;
2525 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
2528 /* Allocate memory for the section contents. Zero the memory
2529 for the benefit of .rela.plt, which has 4 unused entries
2530 at the beginning, and we don't want garbage. */
2531 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
2532 if (s
->contents
== NULL
)
2536 if (elf_hash_table (info
)->dynamic_sections_created
)
2538 /* Add some entries to the .dynamic section. We fill in the
2539 values later, in loongarch_elf_finish_dynamic_sections, but we
2540 must add the entries now so that we get the correct size for
2541 the .dynamic section. The DT_DEBUG entry is filled in by the
2542 dynamic linker and used by the debugger. */
2543 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2545 if (bfd_link_executable (info
))
2547 if (!add_dynamic_entry (DT_DEBUG
, 0))
2551 if (htab
->elf
.srelplt
->size
!= 0)
2553 if (!add_dynamic_entry (DT_PLTGOT
, 0)
2554 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
2555 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2556 || !add_dynamic_entry (DT_JMPREL
, 0))
2560 if (!add_dynamic_entry (DT_RELA
, 0)
2561 || !add_dynamic_entry (DT_RELASZ
, 0)
2562 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2565 /* If any dynamic relocs apply to a read-only section,
2566 then we need a DT_TEXTREL entry. */
2567 if ((info
->flags
& DF_TEXTREL
) == 0)
2568 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
2570 if (info
->flags
& DF_TEXTREL
)
2572 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2574 /* Clear the DF_TEXTREL flag. It will be set again if we
2575 write out an actual text relocation; we may not, because
2576 at this point we do not know whether e.g. any .eh_frame
2577 absolute relocations have been converted to PC-relative. */
2578 info
->flags
&= ~DF_TEXTREL
;
2581 #undef add_dynamic_entry
2586 #define LARCH_LD_STACK_DEPTH 16
2587 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
2588 static size_t larch_stack_top
= 0;
2590 static bfd_reloc_status_type
2591 loongarch_push (int64_t val
)
2593 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
2594 return bfd_reloc_outofrange
;
2595 larch_opc_stack
[larch_stack_top
++] = val
;
2596 return bfd_reloc_ok
;
2599 static bfd_reloc_status_type
2600 loongarch_pop (int64_t *val
)
2602 if (larch_stack_top
== 0)
2603 return bfd_reloc_outofrange
;
2605 *val
= larch_opc_stack
[--larch_stack_top
];
2606 return bfd_reloc_ok
;
2609 static bfd_reloc_status_type
2610 loongarch_top (int64_t *val
)
2612 if (larch_stack_top
== 0)
2613 return bfd_reloc_outofrange
;
2615 *val
= larch_opc_stack
[larch_stack_top
- 1];
2616 return bfd_reloc_ok
;
2620 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
2622 BFD_ASSERT (s
&& s
->contents
);
2623 const struct elf_backend_data
*bed
;
2626 bed
= get_elf_backend_data (abfd
);
2627 if (!(s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
))
2628 BFD_ASSERT (s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
);
2629 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
2630 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
2633 /* Check rel->r_offset in range of contents. */
2634 static bfd_reloc_status_type
2635 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
2636 const asection
*input_section
)
2638 if (0 == strcmp(input_section
->name
, ".text")
2639 && rel
->r_offset
> input_section
->size
)
2640 return bfd_reloc_overflow
;
2642 return bfd_reloc_ok
;
2645 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2647 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2648 if (ret == bfd_reloc_ok) \
2650 ret = loongarch_pop (&op1); \
2651 if (ret == bfd_reloc_ok) \
2652 ret = loongarch_push (op3); \
2657 /* Write immediate to instructions. */
2659 static bfd_reloc_status_type
2660 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
2661 const asection
*input_section ATTRIBUTE_UNUSED
,
2662 reloc_howto_type
*howto
, bfd
*input_bfd
,
2663 bfd_byte
*contents
, bfd_vma reloc_val
)
2665 /* Adjust the immediate based on alignment and
2666 its position in the instruction. */
2667 if (!loongarch_adjust_reloc_bitsfield (input_bfd
, howto
, &reloc_val
))
2668 return bfd_reloc_overflow
;
2670 int bits
= bfd_get_reloc_size (howto
) * 8;
2671 uint64_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
2673 /* Write immediate to instruction. */
2674 insn
= (insn
& ~howto
->dst_mask
) | (reloc_val
& howto
->dst_mask
);
2676 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
2678 return bfd_reloc_ok
;
2681 static bfd_reloc_status_type
2682 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
2683 reloc_howto_type
*howto
, bfd_vma value
,
2684 bfd
*input_bfd
, bfd_byte
*contents
)
2686 int64_t opr1
, opr2
, opr3
;
2687 bfd_reloc_status_type r
= bfd_reloc_ok
;
2688 int bits
= bfd_get_reloc_size (howto
) * 8;
2690 switch (ELFNN_R_TYPE (rel
->r_info
))
2692 case R_LARCH_SOP_PUSH_PCREL
:
2693 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2694 case R_LARCH_SOP_PUSH_GPREL
:
2695 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2696 case R_LARCH_SOP_PUSH_TLS_GOT
:
2697 case R_LARCH_SOP_PUSH_TLS_GD
:
2698 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2699 r
= loongarch_push (value
);
2702 case R_LARCH_SOP_PUSH_DUP
:
2703 r
= loongarch_pop (&opr1
);
2704 if (r
== bfd_reloc_ok
)
2706 r
= loongarch_push (opr1
);
2707 if (r
== bfd_reloc_ok
)
2708 r
= loongarch_push (opr1
);
2712 case R_LARCH_SOP_ASSERT
:
2713 r
= loongarch_pop (&opr1
);
2714 if (r
!= bfd_reloc_ok
|| !opr1
)
2715 r
= bfd_reloc_notsupported
;
2718 case R_LARCH_SOP_NOT
:
2719 r
= loongarch_pop (&opr1
);
2720 if (r
== bfd_reloc_ok
)
2721 r
= loongarch_push (!opr1
);
2724 case R_LARCH_SOP_SUB
:
2725 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
2728 case R_LARCH_SOP_SL
:
2729 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
2732 case R_LARCH_SOP_SR
:
2733 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
2736 case R_LARCH_SOP_AND
:
2737 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
2740 case R_LARCH_SOP_ADD
:
2741 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
2744 case R_LARCH_SOP_IF_ELSE
:
2745 r
= loongarch_pop (&opr3
);
2746 if (r
== bfd_reloc_ok
)
2748 r
= loongarch_pop (&opr2
);
2749 if (r
== bfd_reloc_ok
)
2751 r
= loongarch_pop (&opr1
);
2752 if (r
== bfd_reloc_ok
)
2753 r
= loongarch_push (opr1
? opr2
: opr3
);
2758 case R_LARCH_SOP_POP_32_S_10_5
:
2759 case R_LARCH_SOP_POP_32_S_10_12
:
2760 case R_LARCH_SOP_POP_32_S_10_16
:
2761 case R_LARCH_SOP_POP_32_S_10_16_S2
:
2762 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
2763 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
2764 case R_LARCH_SOP_POP_32_S_5_20
:
2765 case R_LARCH_SOP_POP_32_U_10_12
:
2766 case R_LARCH_SOP_POP_32_U
:
2767 r
= loongarch_pop (&opr1
);
2768 if (r
!= bfd_reloc_ok
)
2770 r
= loongarch_check_offset (rel
, input_section
);
2771 if (r
!= bfd_reloc_ok
)
2774 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2776 contents
, (bfd_vma
)opr1
);
2779 case R_LARCH_TLS_DTPREL32
:
2781 case R_LARCH_TLS_DTPREL64
:
2783 r
= loongarch_check_offset (rel
, input_section
);
2784 if (r
!= bfd_reloc_ok
)
2787 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
2790 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2791 Because set/sub reloc pair not support multi-thread. While add/sub
2792 reloc pair process order not affect the final result.
2794 For add/sub reloc, the original value will be involved in the
2795 calculation. In order not to add/sub extra value, we write 0 to symbol
2796 address at assembly time.
2798 add/sub reloc bits determined by the value after symbol subtraction,
2801 add/sub reloc save part of the symbol value, so we only need to
2802 save howto->dst_mask bits. */
2806 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2807 contents
+ rel
->r_offset
);
2808 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2809 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2814 /* Not need to read the original value, just write the new value. */
2826 /* Because add/sub reloc is processed separately,
2827 so the high bits is invalid. */
2828 bfd_vma word
= value
& howto
->dst_mask
;
2829 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2834 case R_LARCH_ADD_ULEB128
:
2835 case R_LARCH_SUB_ULEB128
:
2837 unsigned int len
= 0;
2838 /* Before write uleb128, first read it to get it's length. */
2839 _bfd_read_unsigned_leb128 (input_bfd
, contents
+ rel
->r_offset
, &len
);
2840 loongarch_write_unsigned_leb128 (contents
+ rel
->r_offset
, len
, value
);
2845 /* For eh_frame and debug info. */
2846 case R_LARCH_32_PCREL
:
2847 case R_LARCH_64_PCREL
:
2849 value
-= sec_addr (input_section
) + rel
->r_offset
;
2850 value
+= rel
->r_addend
;
2851 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2852 contents
+ rel
->r_offset
);
2853 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2854 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2860 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2864 case R_LARCH_ABS_HI20
:
2865 case R_LARCH_ABS_LO12
:
2866 case R_LARCH_ABS64_LO20
:
2867 case R_LARCH_ABS64_HI12
:
2868 case R_LARCH_PCALA_HI20
:
2869 case R_LARCH_PCALA_LO12
:
2870 case R_LARCH_PCALA64_LO20
:
2871 case R_LARCH_PCALA64_HI12
:
2872 case R_LARCH_GOT_PC_HI20
:
2873 case R_LARCH_GOT_PC_LO12
:
2874 case R_LARCH_GOT64_PC_LO20
:
2875 case R_LARCH_GOT64_PC_HI12
:
2876 case R_LARCH_GOT_HI20
:
2877 case R_LARCH_GOT_LO12
:
2878 case R_LARCH_GOT64_LO20
:
2879 case R_LARCH_GOT64_HI12
:
2880 case R_LARCH_TLS_LE_HI20
:
2881 case R_LARCH_TLS_LE_LO12
:
2882 case R_LARCH_TLS_LE_HI20_R
:
2883 case R_LARCH_TLS_LE_LO12_R
:
2884 case R_LARCH_TLS_LE64_LO20
:
2885 case R_LARCH_TLS_LE64_HI12
:
2886 case R_LARCH_TLS_IE_PC_HI20
:
2887 case R_LARCH_TLS_IE_PC_LO12
:
2888 case R_LARCH_TLS_IE64_PC_LO20
:
2889 case R_LARCH_TLS_IE64_PC_HI12
:
2890 case R_LARCH_TLS_IE_HI20
:
2891 case R_LARCH_TLS_IE_LO12
:
2892 case R_LARCH_TLS_IE64_LO20
:
2893 case R_LARCH_TLS_IE64_HI12
:
2894 case R_LARCH_TLS_LD_PC_HI20
:
2895 case R_LARCH_TLS_LD_HI20
:
2896 case R_LARCH_TLS_GD_PC_HI20
:
2897 case R_LARCH_TLS_GD_HI20
:
2898 case R_LARCH_PCREL20_S2
:
2899 case R_LARCH_CALL36
:
2900 case R_LARCH_TLS_DESC_PC_HI20
:
2901 case R_LARCH_TLS_DESC_PC_LO12
:
2902 case R_LARCH_TLS_DESC64_PC_LO20
:
2903 case R_LARCH_TLS_DESC64_PC_HI12
:
2904 case R_LARCH_TLS_DESC_HI20
:
2905 case R_LARCH_TLS_DESC_LO12
:
2906 case R_LARCH_TLS_DESC64_LO20
:
2907 case R_LARCH_TLS_DESC64_HI12
:
2908 case R_LARCH_TLS_LD_PCREL20_S2
:
2909 case R_LARCH_TLS_GD_PCREL20_S2
:
2910 case R_LARCH_TLS_DESC_PCREL20_S2
:
2911 r
= loongarch_check_offset (rel
, input_section
);
2912 if (r
!= bfd_reloc_ok
)
2915 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2920 case R_LARCH_TLS_DESC_LD
:
2921 case R_LARCH_TLS_DESC_CALL
:
2926 case R_LARCH_TLS_LE_ADD_R
:
2930 r
= bfd_reloc_notsupported
;
2935 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2943 Elf_Internal_Sym
*sym
;
2944 struct elf_link_hash_entry
*h
;
2947 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
2948 static size_t larch_reloc_queue_head
= 0;
2949 static size_t larch_reloc_queue_tail
= 0;
2952 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
2953 Elf_Internal_Sym
*sym
)
2955 const char *ret
= NULL
;
2957 ret
= bfd_elf_string_from_elf_section (input_bfd
,
2958 elf_symtab_hdr (input_bfd
).sh_link
,
2961 ret
= h
->root
.root
.string
;
2963 if (ret
== NULL
|| *ret
== '\0')
2969 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
2970 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
2971 struct elf_link_hash_entry
*h
, bfd_vma addend
)
2973 if ((larch_reloc_queue_head
== 0
2974 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
2975 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
2976 larch_reloc_queue_head
=
2977 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2978 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
2979 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
2980 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
2981 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
2982 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
2983 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
2984 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
2985 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
2986 larch_reloc_queue_tail
=
2987 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2991 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
2993 size_t i
= larch_reloc_queue_head
;
2995 asection
*section
= NULL
;
2996 bfd_vma r_offset
= 0;
2998 p ("Dump relocate record:\n");
2999 p ("stack top\t\trelocation name\t\tsymbol");
3000 while (i
!= larch_reloc_queue_tail
)
3002 if (a_bfd
!= larch_reloc_queue
[i
].bfd
3003 || section
!= larch_reloc_queue
[i
].section
3004 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
3006 a_bfd
= larch_reloc_queue
[i
].bfd
;
3007 section
= larch_reloc_queue
[i
].section
;
3008 r_offset
= larch_reloc_queue
[i
].r_offset
;
3009 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
3010 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
3014 inited
= 1, p ("...\n");
3016 reloc_howto_type
*howto
=
3017 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
3018 larch_reloc_queue
[i
].r_type
);
3019 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
3020 howto
? howto
->name
: "<unknown reloc>",
3021 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
3022 larch_reloc_queue
[i
].sym
));
3024 long addend
= larch_reloc_queue
[i
].addend
;
3026 p (" - %ld", -addend
);
3027 else if (0 < addend
)
3028 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
3031 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
3034 "-- Record dump end --\n\n");
3038 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
3040 asection
*input_section
,
3041 Elf_Internal_Rela
*rel
,
3042 reloc_howto_type
*howto
,
3043 bfd_reloc_status_type rtype
,
3051 /* 'dangerous' means we do it but can't promise it's ok
3052 'unsupport' means out of ability of relocation type
3053 'undefined' means we can't deal with the undefined symbol. */
3054 case bfd_reloc_undefined
:
3055 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
3056 rel
->r_offset
, true);
3057 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3058 input_bfd
, input_section
, rel
->r_offset
,
3060 is_undefweak
? "[undefweak] " : "", name
, msg
);
3062 case bfd_reloc_dangerous
:
3063 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
3064 input_bfd
, input_section
, rel
->r_offset
,
3066 is_undefweak
? "[undefweak] " : "", name
, msg
);
3069 case bfd_reloc_notsupported
:
3070 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3071 input_bfd
, input_section
, rel
->r_offset
,
3073 is_undefweak
? "[undefweak] " : "", name
, msg
);
3081 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
3082 hi20 immediate need to add 0x1.
3083 For example: pc 0x120000000, symbol 0x120000812
3084 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
3085 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
3086 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
3089 pcalau12i $t0, hi20 (0x1)
3090 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
3091 addi.d $t0, $t0, lo12 (0x812)
3092 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
3093 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
3095 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
3097 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
3098 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
3100 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3101 relocation = (relocation & ~(bfd_vma)0xfff) \
3102 - (pc & ~(bfd_vma)0xfff); \
3104 relocation += 0x1000; \
3107 /* Handle problems caused by symbol extensions in TLS LE, The processing
3108 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
3109 #define RELOCATE_TLS_TP32_HI20(relocation) \
3111 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3113 relocation += 0x800; \
3114 relocation = relocation & ~(bfd_vma)0xfff; \
3117 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
3118 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
3120 lo12: 0x1812348ffff812 & 0xfff = 0x812
3121 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
3122 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
3125 pcalau12i $t1, hi20 (0x80000)
3126 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
3127 = 0x11000010000100 + 0xffffffff80000000
3129 addi.d $t0, $zero, lo12 (0x812)
3130 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
3131 lo20 need to sub 0x1)
3132 lu32i.d $t0, lo20 (0x71234)
3133 $t0 = {0x71234, 0xfffff812}
3135 lu52i.d $t0, hi12 (0x0)
3136 $t0 = {0x0, 0x71234fffff812}
3139 $t1 = 0x10ffff90000000 + 0x71234fffff812
3140 = 0x1812348ffff812. */
3141 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
3143 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
3144 relocation = (relocation & ~(bfd_vma)0xfff) \
3145 - ((pc) & ~(bfd_vma)0xfff); \
3147 relocation += (0x1000 - 0x100000000); \
3148 if (relocation & 0x80000000) \
3149 relocation += 0x100000000; \
3153 /* Compute the tp/dtp offset of a tls symbol.
3154 It is dtp offset in dynamic tls model (gd/ld) and tp
3155 offset in static tls model (ie/le). Both offsets are
3156 calculated the same way on LoongArch, so the same
3157 function is used. */
3159 tlsoff (struct bfd_link_info
*info
, bfd_vma addr
)
3161 /* If tls_sec is NULL, we should have signalled an error already. */
3162 if (elf_hash_table (info
)->tls_sec
== NULL
)
3164 return addr
- elf_hash_table (info
)->tls_sec
->vma
;
3168 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
3169 bfd
*input_bfd
, asection
*input_section
,
3170 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
3171 Elf_Internal_Sym
*local_syms
,
3172 asection
**local_sections
)
3174 Elf_Internal_Rela
*rel
;
3175 Elf_Internal_Rela
*relend
;
3177 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
3178 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3179 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
3180 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
3181 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
3182 bool is_pic
= bfd_link_pic (info
);
3183 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
3184 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
3185 asection
*got
= htab
->elf
.sgot
;
3187 relend
= relocs
+ input_section
->reloc_count
;
3188 for (rel
= relocs
; rel
< relend
; rel
++)
3190 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
3191 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3192 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
3193 reloc_howto_type
*howto
= NULL
;
3194 asection
*sec
= NULL
;
3195 Elf_Internal_Sym
*sym
= NULL
;
3196 struct elf_link_hash_entry
*h
= NULL
;
3198 bfd_reloc_status_type r
= bfd_reloc_ok
;
3199 bool is_ie
, is_desc
, is_undefweak
, unresolved_reloc
, defined_local
;
3200 bool resolved_local
, resolved_dynly
, resolved_to_const
;
3202 bfd_vma relocation
, off
, ie_off
, desc_off
;
3205 /* When an unrecognized relocation is encountered, which usually
3206 occurs when using a newer assembler but an older linker, an error
3207 should be reported instead of continuing to the next relocation. */
3208 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
3210 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
3212 if (r_type
== R_LARCH_GNU_VTINHERIT
|| r_type
== R_LARCH_GNU_VTENTRY
)
3215 /* This is a final link. */
3216 if (r_symndx
< symtab_hdr
->sh_info
)
3218 is_undefweak
= false;
3219 unresolved_reloc
= false;
3220 sym
= local_syms
+ r_symndx
;
3221 sec
= local_sections
[r_symndx
];
3222 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
3224 /* Relocate against local STT_GNU_IFUNC symbol. */
3225 if (!bfd_link_relocatable (info
)
3226 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
3228 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
3233 /* Set STT_GNU_IFUNC symbol value. */
3234 h
->root
.u
.def
.value
= sym
->st_value
;
3235 h
->root
.u
.def
.section
= sec
;
3237 defined_local
= true;
3238 resolved_local
= true;
3239 resolved_dynly
= false;
3240 resolved_to_const
= false;
3242 /* Calc in funtion elf_link_input_bfd,
3243 * if #define elf_backend_rela_normal to 1. */
3244 if (bfd_link_relocatable (info
)
3245 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3250 bool warned
, ignored
;
3252 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
3253 r_symndx
, symtab_hdr
, sym_hashes
,
3255 unresolved_reloc
, warned
, ignored
);
3256 /* Here means symbol isn't local symbol only and 'h != NULL'. */
3258 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
3259 symbol. And 'dynamic_undefined_weak' specify what to do when
3260 meeting undefweak. */
3262 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
3264 defined_local
= false;
3265 resolved_local
= false;
3266 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
3267 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
3268 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
3272 /* Symbol undefined offen means failed already. I don't know why
3273 'warned' here but I guess it want to continue relocating as if
3274 no error occures to find other errors as more as possible. */
3276 /* To avoid generating warning messages about truncated
3277 relocations, set the relocation's address to be the same as
3278 the start of this section. */
3279 relocation
= (input_section
->output_section
3280 ? input_section
->output_section
->vma
3283 defined_local
= relocation
!= 0;
3284 resolved_local
= defined_local
;
3285 resolved_to_const
= !resolved_local
;
3286 resolved_dynly
= false;
3290 defined_local
= !unresolved_reloc
&& !ignored
;
3292 defined_local
&& LARCH_REF_LOCAL (info
, h
);
3293 resolved_dynly
= !resolved_local
;
3294 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
3298 name
= loongarch_sym_name (input_bfd
, h
, sym
);
3300 if (sec
!= NULL
&& discarded_section (sec
))
3301 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
3302 1, relend
, howto
, 0, contents
);
3304 if (bfd_link_relocatable (info
))
3307 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
3308 from removed linkonce sections, or sections discarded by a linker
3309 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
3310 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
3312 defined_local
= false;
3313 resolved_local
= false;
3314 resolved_dynly
= false;
3315 resolved_to_const
= true;
3318 /* The ifunc reference generate plt. */
3319 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
3321 defined_local
= true;
3322 resolved_local
= true;
3323 resolved_dynly
= false;
3324 resolved_to_const
= false;
3325 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3328 unresolved_reloc
= resolved_dynly
;
3330 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
3332 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
3334 BFD_ASSERT (!resolved_local
|| defined_local
);
3340 case R_LARCH_MARK_PCREL
:
3341 case R_LARCH_MARK_LA
:
3343 r
= bfd_reloc_continue
;
3344 unresolved_reloc
= false;
3349 if (resolved_dynly
|| (is_pic
&& resolved_local
))
3351 Elf_Internal_Rela outrel
;
3353 /* When generating a shared object, these relocations are copied
3354 into the output file to be resolved at run time. */
3356 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
3360 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
3361 && (input_section
->flags
& SEC_ALLOC
));
3363 outrel
.r_offset
+= sec_addr (input_section
);
3365 /* A pointer point to a ifunc symbol. */
3366 if (h
&& h
->type
== STT_GNU_IFUNC
)
3368 if (h
->dynindx
== -1)
3370 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
3371 outrel
.r_addend
= (h
->root
.u
.def
.value
3372 + h
->root
.u
.def
.section
->output_section
->vma
3373 + h
->root
.u
.def
.section
->output_offset
);
3377 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
3378 outrel
.r_addend
= 0;
3381 if (LARCH_REF_LOCAL (info
, h
))
3384 if (htab
->elf
.splt
!= NULL
)
3385 sreloc
= htab
->elf
.srelgot
;
3387 sreloc
= htab
->elf
.irelplt
;
3392 if (bfd_link_pic (info
))
3393 sreloc
= htab
->elf
.irelifunc
;
3394 else if (htab
->elf
.splt
!= NULL
)
3395 sreloc
= htab
->elf
.srelgot
;
3397 sreloc
= htab
->elf
.irelplt
;
3400 else if (resolved_dynly
)
3402 if (h
->dynindx
== -1)
3403 outrel
.r_info
= ELFNN_R_INFO (0, r_type
);
3405 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
3407 outrel
.r_addend
= rel
->r_addend
;
3411 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3412 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3415 /* No alloc space of func allocate_dynrelocs.
3416 No alloc space of invalid R_LARCH_32 in ELFCLASS64. */
3417 if (unresolved_reloc
3418 && (ARCH_SIZE
== 32 || r_type
!= R_LARCH_32
)
3419 && !(h
&& (h
->is_weakalias
|| !h
->dyn_relocs
)))
3421 if (info
->enable_dt_relr
3422 && (ELFNN_R_TYPE (outrel
.r_info
) == R_LARCH_RELATIVE
)
3423 && input_section
->alignment_power
!= 0
3424 && rel
->r_offset
% 2 == 0)
3425 /* Don't emit a relative relocation that is packed,
3426 only apply the addend (as if we are applying the
3427 original R_LARCH_NN reloc in a PDE). */
3428 r
= perform_relocation (rel
, input_section
, howto
,
3429 relocation
, input_bfd
,
3432 loongarch_elf_append_rela (output_bfd
, sreloc
,
3437 relocation
+= rel
->r_addend
;
3447 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
3448 contents
+ rel
->r_offset
);
3449 relocation
= old_value
+ relocation
+ rel
->r_addend
;
3460 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
3461 contents
+ rel
->r_offset
);
3462 relocation
= old_value
- relocation
- rel
->r_addend
;
3466 case R_LARCH_ADD_ULEB128
:
3467 case R_LARCH_SUB_ULEB128
:
3469 /* Get the value and length of the uleb128 data. */
3470 unsigned int len
= 0;
3471 bfd_vma old_value
= _bfd_read_unsigned_leb128 (input_bfd
,
3472 contents
+ rel
->r_offset
, &len
);
3474 if (R_LARCH_ADD_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
3475 relocation
= old_value
+ relocation
+ rel
->r_addend
;
3476 else if (R_LARCH_SUB_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
3477 relocation
= old_value
- relocation
- rel
->r_addend
;
3479 bfd_vma mask
= (1 << (7 * len
)) - 1;
3484 case R_LARCH_TLS_DTPREL32
:
3485 case R_LARCH_TLS_DTPREL64
:
3488 Elf_Internal_Rela outrel
;
3490 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
3493 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
3494 && (input_section
->flags
& SEC_ALLOC
));
3495 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
3496 outrel
.r_offset
+= sec_addr (input_section
);
3497 outrel
.r_addend
= rel
->r_addend
;
3498 if (unresolved_reloc
)
3499 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
3503 if (resolved_to_const
)
3504 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
3506 bfd_reloc_notsupported
,
3511 if (!elf_hash_table (info
)->tls_sec
)
3513 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
3514 input_section
, rel
, howto
, bfd_reloc_notsupported
,
3515 is_undefweak
, name
, "TLS section not be created");
3518 relocation
= tlsoff (info
, relocation
);
3522 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
3523 input_section
, rel
, howto
, bfd_reloc_undefined
,
3525 "TLS LE just can be resolved local only.");
3530 case R_LARCH_SOP_PUSH_TLS_TPREL
:
3533 if (!elf_hash_table (info
)->tls_sec
)
3534 fatal
= (loongarch_reloc_is_fatal
3535 (info
, input_bfd
, input_section
, rel
, howto
,
3536 bfd_reloc_notsupported
, is_undefweak
, name
,
3537 "TLS section not be created"));
3539 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
3542 fatal
= (loongarch_reloc_is_fatal
3543 (info
, input_bfd
, input_section
, rel
, howto
,
3544 bfd_reloc_undefined
, is_undefweak
, name
,
3545 "TLS LE just can be resolved local only."));
3548 case R_LARCH_SOP_PUSH_ABSOLUTE
:
3552 fatal
= (loongarch_reloc_is_fatal
3553 (info
, input_bfd
, input_section
, rel
, howto
,
3554 bfd_reloc_dangerous
, is_undefweak
, name
,
3555 "Someone require us to resolve undefweak "
3556 "symbol dynamically. \n"
3557 "But this reloc can't be done. "
3558 "I think I can't throw error "
3560 "so I resolved it to 0. "
3561 "I suggest to re-compile with '-fpic'."));
3564 unresolved_reloc
= false;
3568 if (resolved_to_const
)
3570 relocation
+= rel
->r_addend
;
3576 fatal
= (loongarch_reloc_is_fatal
3577 (info
, input_bfd
, input_section
, rel
, howto
,
3578 bfd_reloc_notsupported
, is_undefweak
, name
,
3579 "Under PIC we don't know load address. Re-compile "
3586 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
3588 fatal
= (loongarch_reloc_is_fatal
3589 (info
, input_bfd
, input_section
, rel
, howto
,
3590 bfd_reloc_undefined
, is_undefweak
, name
,
3591 "Can't be resolved dynamically. Try to re-compile "
3596 if (rel
->r_addend
!= 0)
3598 fatal
= (loongarch_reloc_is_fatal
3599 (info
, input_bfd
, input_section
, rel
, howto
,
3600 bfd_reloc_notsupported
, is_undefweak
, name
,
3601 "Shouldn't be with r_addend."));
3605 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3606 unresolved_reloc
= false;
3612 relocation
+= rel
->r_addend
;
3618 case R_LARCH_SOP_PUSH_PCREL
:
3619 case R_LARCH_SOP_PUSH_PLT_PCREL
:
3620 unresolved_reloc
= false;
3628 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3631 fatal
= (loongarch_reloc_is_fatal
3632 (info
, input_bfd
, input_section
, rel
, howto
,
3633 bfd_reloc_dangerous
, is_undefweak
, name
,
3634 "Undefweak need to be resolved dynamically, "
3635 "but PLT stub doesn't represent."));
3640 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
3642 fatal
= (loongarch_reloc_is_fatal
3643 (info
, input_bfd
, input_section
, rel
, howto
,
3644 bfd_reloc_undefined
, is_undefweak
, name
,
3645 "PLT stub does not represent and "
3646 "symbol not defined."));
3652 else /* if (resolved_dynly) */
3654 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
3655 fatal
= (loongarch_reloc_is_fatal
3656 (info
, input_bfd
, input_section
, rel
, howto
,
3657 bfd_reloc_dangerous
, is_undefweak
, name
,
3658 "Internal: PLT stub doesn't represent. "
3659 "Resolve it with pcrel"));
3666 if ((i
& 1) == 0 && defined_local
)
3669 relocation
+= rel
->r_addend
;
3673 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
3675 if (rel
->r_addend
!= 0)
3677 fatal
= (loongarch_reloc_is_fatal
3678 (info
, input_bfd
, input_section
, rel
, howto
,
3679 bfd_reloc_notsupported
, is_undefweak
, name
,
3680 "PLT shouldn't be with r_addend."));
3683 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3689 case R_LARCH_SOP_PUSH_GPREL
:
3690 unresolved_reloc
= false;
3692 if (rel
->r_addend
!= 0)
3694 fatal
= (loongarch_reloc_is_fatal
3695 (info
, input_bfd
, input_section
, rel
, howto
,
3696 bfd_reloc_notsupported
, is_undefweak
, name
,
3697 "Shouldn't be with r_addend."));
3703 off
= h
->got
.offset
& (~1);
3705 if (h
->got
.offset
== MINUS_ONE
&& h
->type
!= STT_GNU_IFUNC
)
3707 fatal
= (loongarch_reloc_is_fatal
3708 (info
, input_bfd
, input_section
, rel
, howto
,
3709 bfd_reloc_notsupported
, is_undefweak
, name
,
3710 "Internal: GOT entry doesn't represent."));
3714 /* Hidden symbol not has .got entry, only .got.plt entry
3715 so gprel is (plt - got). */
3716 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3718 if (h
->plt
.offset
== (bfd_vma
) -1)
3723 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3724 off
= plt_index
* GOT_ENTRY_SIZE
;
3726 if (htab
->elf
.splt
!= NULL
)
3728 /* Section .plt header is 2 times of plt entry. */
3729 off
= sec_addr (htab
->elf
.sgotplt
) + off
3730 - sec_addr (htab
->elf
.sgot
);
3734 /* Section iplt not has plt header. */
3735 off
= sec_addr (htab
->elf
.igotplt
) + off
3736 - sec_addr (htab
->elf
.sgot
);
3740 if ((h
->got
.offset
& 1) == 0)
3742 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3743 bfd_link_pic (info
), h
)
3744 && ((bfd_link_pic (info
)
3745 && LARCH_REF_LOCAL (info
, h
))))
3747 /* This is actually a static link, or it is a
3748 -Bsymbolic link and the symbol is defined
3749 locally, or the symbol was forced to be local
3750 because of a version file. We must initialize
3751 this entry in the global offset table. Since the
3752 offset must always be a multiple of the word size,
3753 we use the least significant bit to record whether
3754 we have initialized it already.
3756 When doing a dynamic link, we create a rela.got
3757 relocation entry to initialize the value. This
3758 is done in the finish_dynamic_symbol routine. */
3762 fatal
= (loongarch_reloc_is_fatal
3763 (info
, input_bfd
, input_section
, rel
, howto
,
3764 bfd_reloc_dangerous
, is_undefweak
, name
,
3765 "Internal: here shouldn't dynamic."));
3768 if (!(defined_local
|| resolved_to_const
))
3770 fatal
= (loongarch_reloc_is_fatal
3771 (info
, input_bfd
, input_section
, rel
, howto
,
3772 bfd_reloc_undefined
, is_undefweak
, name
,
3778 Elf_Internal_Rela outrel
;
3779 /* We need to generate a R_LARCH_RELATIVE reloc
3780 for the dynamic linker. */
3781 s
= htab
->elf
.srelgot
;
3784 fatal
= loongarch_reloc_is_fatal
3786 input_section
, rel
, howto
,
3787 bfd_reloc_notsupported
, is_undefweak
, name
,
3788 "Internal: '.rel.got' not represent");
3792 outrel
.r_offset
= sec_addr (got
) + off
;
3793 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3794 outrel
.r_addend
= relocation
; /* Link-time addr. */
3795 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3797 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3803 if (!local_got_offsets
)
3805 fatal
= (loongarch_reloc_is_fatal
3806 (info
, input_bfd
, input_section
, rel
, howto
,
3807 bfd_reloc_notsupported
, is_undefweak
, name
,
3808 "Internal: local got offsets not reporesent."));
3812 off
= local_got_offsets
[r_symndx
] & (~1);
3814 if (local_got_offsets
[r_symndx
] == MINUS_ONE
)
3816 fatal
= (loongarch_reloc_is_fatal
3817 (info
, input_bfd
, input_section
, rel
, howto
,
3818 bfd_reloc_notsupported
, is_undefweak
, name
,
3819 "Internal: GOT entry doesn't represent."));
3823 /* The offset must always be a multiple of the word size.
3824 So, we can use the least significant bit to record
3825 whether we have already processed this entry. */
3826 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3831 Elf_Internal_Rela outrel
;
3832 /* We need to generate a R_LARCH_RELATIVE reloc
3833 for the dynamic linker. */
3834 s
= htab
->elf
.srelgot
;
3837 fatal
= (loongarch_reloc_is_fatal
3838 (info
, input_bfd
, input_section
, rel
, howto
,
3839 bfd_reloc_notsupported
, is_undefweak
, name
,
3840 "Internal: '.rel.got' not represent"));
3844 outrel
.r_offset
= sec_addr (got
) + off
;
3845 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3846 outrel
.r_addend
= relocation
; /* Link-time addr. */
3847 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3850 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3851 local_got_offsets
[r_symndx
] |= 1;
3858 case R_LARCH_SOP_PUSH_TLS_GOT
:
3859 case R_LARCH_SOP_PUSH_TLS_GD
:
3861 unresolved_reloc
= false;
3862 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
3865 bfd_vma got_off
= 0;
3868 got_off
= h
->got
.offset
;
3873 got_off
= local_got_offsets
[r_symndx
];
3874 local_got_offsets
[r_symndx
] |= 1;
3877 BFD_ASSERT (got_off
!= MINUS_ONE
);
3880 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3881 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3882 ie_off
= 2 * GOT_ENTRY_SIZE
;
3884 if ((got_off
& 1) == 0)
3886 Elf_Internal_Rela rela
;
3887 asection
*srel
= htab
->elf
.srelgot
;
3888 bfd_vma tls_block_off
= 0;
3890 if (LARCH_REF_LOCAL (info
, h
))
3892 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3893 tls_block_off
= relocation
3894 - elf_hash_table (info
)->tls_sec
->vma
;
3897 if (tls_type
& GOT_TLS_GD
)
3899 rela
.r_offset
= sec_addr (got
) + got_off
;
3901 if (LARCH_REF_LOCAL (info
, h
))
3903 /* Local sym, used in exec, set module id 1. */
3904 if (bfd_link_executable (info
))
3905 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3908 rela
.r_info
= ELFNN_R_INFO (0,
3909 R_LARCH_TLS_DTPMODNN
);
3910 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3913 bfd_put_NN (output_bfd
, tls_block_off
,
3914 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3916 /* Dynamic resolved. */
3919 /* Dynamic relocate module id. */
3920 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3921 R_LARCH_TLS_DTPMODNN
);
3922 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3924 /* Dynamic relocate offset of block. */
3925 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3926 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3927 R_LARCH_TLS_DTPRELNN
);
3928 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3931 if (tls_type
& GOT_TLS_IE
)
3933 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3934 if (LARCH_REF_LOCAL (info
, h
))
3936 /* Local sym, used in exec, set module id 1. */
3937 if (!bfd_link_executable (info
))
3939 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3940 rela
.r_addend
= tls_block_off
;
3941 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3944 bfd_put_NN (output_bfd
, tls_block_off
,
3945 got
->contents
+ got_off
+ ie_off
);
3947 /* Dynamic resolved. */
3950 /* Dynamic relocate offset of block. */
3951 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3952 R_LARCH_TLS_TPRELNN
);
3954 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3959 relocation
= (got_off
& (~(bfd_vma
)1)) + (is_ie
? ie_off
: 0);
3963 /* New reloc types. */
3967 case R_LARCH_CALL36
:
3968 unresolved_reloc
= false;
3977 relocation
+= rel
->r_addend
;
3979 else if (resolved_dynly
)
3982 && (h
->plt
.offset
!= MINUS_ONE
3983 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3984 && rel
->r_addend
== 0);
3985 if (h
&& h
->plt
.offset
== MINUS_ONE
3986 && ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3989 relocation
+= rel
->r_addend
;
3992 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3997 case R_LARCH_ABS_HI20
:
3998 case R_LARCH_ABS_LO12
:
3999 case R_LARCH_ABS64_LO20
:
4000 case R_LARCH_ABS64_HI12
:
4004 BFD_ASSERT (resolved_dynly
);
4008 else if (resolved_to_const
|| resolved_local
)
4010 relocation
+= rel
->r_addend
;
4012 else if (resolved_dynly
)
4014 unresolved_reloc
= false;
4015 BFD_ASSERT ((plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
)
4016 && rel
->r_addend
== 0);
4017 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4022 case R_LARCH_PCREL20_S2
:
4023 unresolved_reloc
= false;
4024 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4025 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4027 relocation
+= rel
->r_addend
;
4031 case R_LARCH_PCALA_HI20
:
4032 unresolved_reloc
= false;
4033 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4034 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4036 relocation
+= rel
->r_addend
;
4038 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4041 case R_LARCH_TLS_LE_HI20_R
:
4042 relocation
+= rel
->r_addend
;
4043 relocation
= tlsoff (info
, relocation
);
4044 RELOCATE_TLS_TP32_HI20 (relocation
);
4047 case R_LARCH_PCALA_LO12
:
4048 /* Not support if sym_addr in 2k page edge.
4049 pcalau12i pc_hi20 (sym_addr)
4050 ld.w/d pc_lo12 (sym_addr)
4051 ld.w/d pc_lo12 (sym_addr + x)
4053 can not calc correct address
4054 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
4056 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4057 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4059 relocation
+= rel
->r_addend
;
4061 /* For 2G jump, generate pcalau12i, jirl. */
4062 /* If use jirl, turns to R_LARCH_B16. */
4063 uint32_t insn
= bfd_get (32, input_bfd
, contents
+ rel
->r_offset
);
4064 if ((insn
& 0x4c000000) == 0x4c000000)
4066 relocation
&= 0xfff;
4067 /* Signed extend. */
4068 relocation
= (relocation
^ 0x800) - 0x800;
4070 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_B16
);
4071 howto
= loongarch_elf_rtype_to_howto (input_bfd
, R_LARCH_B16
);
4075 case R_LARCH_PCALA64_HI12
:
4078 case R_LARCH_PCALA64_LO20
:
4079 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4080 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4082 relocation
+= rel
->r_addend
;
4084 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4088 case R_LARCH_GOT_PC_HI20
:
4089 case R_LARCH_GOT_HI20
:
4090 /* Calc got offset. */
4092 unresolved_reloc
= false;
4093 BFD_ASSERT (rel
->r_addend
== 0);
4095 bfd_vma got_off
= 0;
4098 /* GOT ref or ifunc. */
4099 BFD_ASSERT (h
->got
.offset
!= MINUS_ONE
4100 || h
->type
== STT_GNU_IFUNC
);
4102 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
4103 /* Hidden symbol not has got entry,
4104 * only got.plt entry so it is (plt - got). */
4105 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
4108 if (htab
->elf
.splt
!= NULL
)
4110 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
)
4112 got_off
= sec_addr (htab
->elf
.sgotplt
)
4113 + GOTPLT_HEADER_SIZE
4114 + (idx
* GOT_ENTRY_SIZE
)
4115 - sec_addr (htab
->elf
.sgot
);
4119 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4120 got_off
= sec_addr (htab
->elf
.sgotplt
)
4121 + (idx
* GOT_ENTRY_SIZE
)
4122 - sec_addr (htab
->elf
.sgot
);
4126 if ((h
->got
.offset
& 1) == 0)
4128 /* We need to generate a R_LARCH_RELATIVE reloc once
4129 * in loongarch_elf_finish_dynamic_symbol or now,
4130 * call finish_dyn && nopic
4131 * or !call finish_dyn && pic. */
4132 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
4133 bfd_link_pic (info
),
4135 && bfd_link_pic (info
)
4136 && LARCH_REF_LOCAL (info
, h
))
4138 Elf_Internal_Rela rela
;
4139 rela
.r_offset
= sec_addr (got
) + got_off
;
4140 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4141 rela
.r_addend
= relocation
;
4142 loongarch_elf_append_rela (output_bfd
,
4143 htab
->elf
.srelgot
, &rela
);
4146 bfd_put_NN (output_bfd
, relocation
,
4147 got
->contents
+ got_off
);
4152 BFD_ASSERT (local_got_offsets
4153 && local_got_offsets
[r_symndx
] != MINUS_ONE
);
4155 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
4156 if ((local_got_offsets
[r_symndx
] & 1) == 0)
4158 if (bfd_link_pic (info
) && !info
->enable_dt_relr
)
4160 Elf_Internal_Rela rela
;
4161 rela
.r_offset
= sec_addr (got
) + got_off
;
4162 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4163 rela
.r_addend
= relocation
;
4164 loongarch_elf_append_rela (output_bfd
,
4165 htab
->elf
.srelgot
, &rela
);
4167 local_got_offsets
[r_symndx
] |= 1;
4169 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ got_off
);
4172 relocation
= got_off
+ sec_addr (got
);
4175 if (r_type
== R_LARCH_GOT_PC_HI20
)
4176 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4180 case R_LARCH_GOT_PC_LO12
:
4181 case R_LARCH_GOT64_PC_LO20
:
4182 case R_LARCH_GOT64_PC_HI12
:
4183 case R_LARCH_GOT_LO12
:
4184 case R_LARCH_GOT64_LO20
:
4185 case R_LARCH_GOT64_HI12
:
4187 unresolved_reloc
= false;
4190 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
4192 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
4194 if (h
&& h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
4197 if (htab
->elf
.splt
!= NULL
)
4198 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4200 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4202 got_off
= sec_addr (htab
->elf
.sgotplt
)
4203 + GOTPLT_HEADER_SIZE
4204 + (idx
* GOT_ENTRY_SIZE
)
4205 - sec_addr (htab
->elf
.sgot
);
4208 relocation
= got_off
+ sec_addr (got
);
4211 if (r_type
== R_LARCH_GOT64_PC_HI12
)
4212 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4213 else if (r_type
== R_LARCH_GOT64_PC_LO20
)
4214 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4218 case R_LARCH_TLS_LE_HI20
:
4219 case R_LARCH_TLS_LE_LO12
:
4220 case R_LARCH_TLS_LE_LO12_R
:
4221 case R_LARCH_TLS_LE64_LO20
:
4222 case R_LARCH_TLS_LE64_HI12
:
4223 BFD_ASSERT (resolved_local
&& elf_hash_table (info
)->tls_sec
);
4225 relocation
+= rel
->r_addend
;
4226 relocation
= tlsoff (info
, relocation
);
4229 /* TLS IE LD/GD process separately is troublesome.
4230 When a symbol is both ie and LD/GD, h->got.off |= 1
4231 make only one type be relocated. We must use
4232 h->got.offset |= 1 and h->got.offset |= 2
4233 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
4234 (IE LD/GD and reusable GOT reloc) must change to
4235 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
4237 Now, LD and GD is both GOT_TLS_GD type, LD seems to
4239 case R_LARCH_TLS_IE_PC_HI20
:
4240 case R_LARCH_TLS_IE_HI20
:
4241 case R_LARCH_TLS_LD_PC_HI20
:
4242 case R_LARCH_TLS_LD_HI20
:
4243 case R_LARCH_TLS_GD_PC_HI20
:
4244 case R_LARCH_TLS_GD_HI20
:
4245 case R_LARCH_TLS_DESC_PC_HI20
:
4246 case R_LARCH_TLS_DESC_HI20
:
4247 case R_LARCH_TLS_LD_PCREL20_S2
:
4248 case R_LARCH_TLS_GD_PCREL20_S2
:
4249 case R_LARCH_TLS_DESC_PCREL20_S2
:
4250 BFD_ASSERT (rel
->r_addend
== 0);
4251 unresolved_reloc
= false;
4253 if (r_type
== R_LARCH_TLS_IE_PC_HI20
4254 || r_type
== R_LARCH_TLS_IE_HI20
)
4257 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
4258 || r_type
== R_LARCH_TLS_DESC_HI20
4259 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4262 bfd_vma got_off
= 0;
4265 got_off
= h
->got
.offset
;
4270 got_off
= local_got_offsets
[r_symndx
];
4271 local_got_offsets
[r_symndx
] |= 1;
4274 BFD_ASSERT (got_off
!= MINUS_ONE
);
4276 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4278 /* If a tls variable is accessed in multiple ways, GD uses
4279 the first two slots of GOT, desc follows with two slots,
4280 and IE uses one slot at the end. */
4282 if (tls_type
& GOT_TLS_GD
)
4283 off
+= 2 * GOT_ENTRY_SIZE
;
4285 if (tls_type
& GOT_TLS_GDESC
)
4286 off
+= 2 * GOT_ENTRY_SIZE
;
4289 if ((got_off
& 1) == 0)
4291 Elf_Internal_Rela rela
;
4292 asection
*relgot
= htab
->elf
.srelgot
;
4295 bool need_reloc
= false;
4296 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, is_dyn
, h
, indx
,
4299 if (tls_type
& GOT_TLS_GD
)
4303 /* Dynamic resolved Module ID. */
4304 rela
.r_offset
= sec_addr (got
) + got_off
;
4306 rela
.r_info
= ELFNN_R_INFO (indx
,R_LARCH_TLS_DTPMODNN
);
4307 bfd_put_NN (output_bfd
, 0, got
->contents
+ got_off
);
4308 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4312 /* Local symbol, tp offset has been known. */
4313 BFD_ASSERT (! unresolved_reloc
);
4314 bfd_put_NN (output_bfd
,
4315 tlsoff (info
, relocation
),
4316 (got
->contents
+ got_off
+ GOT_ENTRY_SIZE
));
4320 /* Dynamic resolved block offset. */
4321 bfd_put_NN (output_bfd
, 0,
4322 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
4323 rela
.r_info
= ELFNN_R_INFO (indx
,
4324 R_LARCH_TLS_DTPRELNN
);
4325 rela
.r_offset
+= GOT_ENTRY_SIZE
;
4326 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4331 /* In a static link or an executable link with the symbol
4332 binding locally. Mark it as belonging to module 1. */
4333 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
4334 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
4335 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
4338 if (tls_type
& GOT_TLS_GDESC
)
4340 /* Unless it is a static link, DESC always emits a
4341 dynamic relocation. */
4342 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
4343 rela
.r_offset
= sec_addr (got
) + got_off
+ desc_off
;
4346 rela
.r_addend
= tlsoff (info
, relocation
);
4348 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_DESCNN
);
4349 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4350 bfd_put_NN (output_bfd
, 0,
4351 got
->contents
+ got_off
+ desc_off
);
4353 if (tls_type
& GOT_TLS_IE
)
4357 bfd_put_NN (output_bfd
, 0,
4358 got
->contents
+ got_off
+ ie_off
);
4359 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
4363 rela
.r_addend
= tlsoff (info
, relocation
);
4364 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_TPRELNN
);
4365 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4369 /* In a static link or an executable link with the symbol
4370 bindinglocally, compute offset directly. */
4371 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
4372 got
->contents
+ got_off
+ ie_off
);
4376 relocation
= (got_off
& (~(bfd_vma
)1)) + sec_addr (got
);
4378 relocation
+= desc_off
;
4380 relocation
+= ie_off
;
4382 if (r_type
== R_LARCH_TLS_LD_PC_HI20
4383 || r_type
== R_LARCH_TLS_GD_PC_HI20
4384 || r_type
== R_LARCH_TLS_IE_PC_HI20
4385 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
4386 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4387 else if (r_type
== R_LARCH_TLS_LD_PCREL20_S2
4388 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
4389 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4391 /* else {} ABS relocations. */
4394 case R_LARCH_TLS_DESC_PC_LO12
:
4395 case R_LARCH_TLS_DESC64_PC_LO20
:
4396 case R_LARCH_TLS_DESC64_PC_HI12
:
4397 case R_LARCH_TLS_DESC_LO12
:
4398 case R_LARCH_TLS_DESC64_LO20
:
4399 case R_LARCH_TLS_DESC64_HI12
:
4401 unresolved_reloc
= false;
4404 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
4406 relocation
= sec_addr (got
)
4407 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
4409 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4410 /* Use both TLS_GD and TLS_DESC. */
4411 if (GOT_TLS_GD_BOTH_P (tls_type
))
4412 relocation
+= 2 * GOT_ENTRY_SIZE
;
4414 if (r_type
== R_LARCH_TLS_DESC64_PC_LO20
)
4415 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4416 else if (r_type
== R_LARCH_TLS_DESC64_PC_HI12
)
4417 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4422 case R_LARCH_TLS_DESC_LD
:
4423 case R_LARCH_TLS_DESC_CALL
:
4424 unresolved_reloc
= false;
4427 case R_LARCH_TLS_IE_PC_LO12
:
4428 case R_LARCH_TLS_IE64_PC_LO20
:
4429 case R_LARCH_TLS_IE64_PC_HI12
:
4430 case R_LARCH_TLS_IE_LO12
:
4431 case R_LARCH_TLS_IE64_LO20
:
4432 case R_LARCH_TLS_IE64_HI12
:
4433 unresolved_reloc
= false;
4436 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
4438 relocation
= sec_addr (got
)
4439 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
4441 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4442 /* Use TLS_GD TLS_DESC and TLS_IE. */
4443 if (GOT_TLS_GD_BOTH_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
4444 relocation
+= 4 * GOT_ENTRY_SIZE
;
4445 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
4446 else if (GOT_TLS_GD_ANY_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
4447 relocation
+= 2 * GOT_ENTRY_SIZE
;
4449 if (r_type
== R_LARCH_TLS_IE64_PC_LO20
)
4450 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4451 else if (r_type
== R_LARCH_TLS_IE64_PC_HI12
)
4452 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4458 r
= bfd_reloc_continue
;
4459 unresolved_reloc
= false;
4471 /* 'unresolved_reloc' means we haven't done it yet.
4472 We need help of dynamic linker to fix this memory location up. */
4473 if (!unresolved_reloc
)
4476 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
4477 rel
->r_offset
) == MINUS_ONE
)
4478 /* WHY? May because it's invalid so skip checking.
4479 But why dynamic reloc a invalid section? */
4482 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
4484 fatal
= (loongarch_reloc_is_fatal
4485 (info
, input_bfd
, input_section
, rel
, howto
,
4486 bfd_reloc_dangerous
, is_undefweak
, name
,
4487 "Seems dynamic linker not process "
4488 "sections 'SEC_DEBUGGING'."));
4493 if ((info
->flags
& DF_TEXTREL
) == 0)
4494 if (input_section
->output_section
->flags
& SEC_READONLY
)
4495 info
->flags
|= DF_TEXTREL
;
4502 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
4503 rel
->r_offset
, sym
, h
, rel
->r_addend
);
4505 if (r
!= bfd_reloc_continue
)
4506 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
4507 input_bfd
, contents
);
4511 case bfd_reloc_dangerous
:
4512 case bfd_reloc_continue
:
4516 case bfd_reloc_overflow
:
4517 /* Overflow value can't be filled in. */
4518 loongarch_dump_reloc_record (info
->callbacks
->info
);
4519 info
->callbacks
->reloc_overflow
4520 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
4521 input_bfd
, input_section
, rel
->r_offset
);
4522 if (r_type
== R_LARCH_PCREL20_S2
4523 || r_type
== R_LARCH_TLS_LD_PCREL20_S2
4524 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
4525 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4526 _bfd_error_handler (_("recompile with 'gcc -mno-relax' or"
4527 " 'as -mno-relax' or 'ld --no-relax'"));
4530 case bfd_reloc_outofrange
:
4531 /* Stack state incorrect. */
4532 loongarch_dump_reloc_record (info
->callbacks
->info
);
4533 info
->callbacks
->info
4534 ("%X%H: Internal stack state is incorrect.\n"
4535 "Want to push to full stack or pop from empty stack?\n",
4536 input_bfd
, input_section
, rel
->r_offset
);
4539 case bfd_reloc_notsupported
:
4540 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
4541 input_section
, rel
->r_offset
);
4545 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
4546 input_section
, rel
->r_offset
);
4557 loongarch_relax_delete_bytes (bfd
*abfd
,
4561 struct bfd_link_info
*link_info
)
4563 unsigned int i
, symcount
;
4564 bfd_vma toaddr
= sec
->size
;
4565 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (abfd
);
4566 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
4567 unsigned int sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
4568 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
4569 bfd_byte
*contents
= data
->this_hdr
.contents
;
4570 struct relr_entry
*relr
= loongarch_elf_section_data (sec
)->relr
;
4571 struct loongarch_elf_link_hash_table
*htab
=
4572 loongarch_elf_hash_table (link_info
);
4573 struct relr_entry
*relr_end
= NULL
;
4575 if (htab
->relr_count
)
4576 relr_end
= htab
->relr
+ htab
->relr_count
;
4578 /* Actually delete the bytes. */
4580 memmove (contents
+ addr
, contents
+ addr
+ count
, toaddr
- addr
- count
);
4582 /* Adjust the location of all of the relocs. Note that we need not
4583 adjust the addends, since all PC-relative references must be against
4584 symbols, which we will adjust below. */
4585 for (i
= 0; i
< sec
->reloc_count
; i
++)
4586 if (data
->relocs
[i
].r_offset
> addr
&& data
->relocs
[i
].r_offset
< toaddr
)
4587 data
->relocs
[i
].r_offset
-= count
;
4589 /* Likewise for relative relocs to be packed into .relr. */
4590 for (; relr
&& relr
< relr_end
&& relr
->sec
== sec
; relr
++)
4591 if (relr
->off
> addr
&& relr
->off
< toaddr
)
4594 /* Adjust the local symbols defined in this section. */
4595 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
4597 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
+ i
;
4598 if (sym
->st_shndx
== sec_shndx
)
4600 /* If the symbol is in the range of memory we just moved, we
4601 have to adjust its value. */
4602 if (sym
->st_value
> addr
&& sym
->st_value
<= toaddr
)
4603 sym
->st_value
-= count
;
4605 /* If the symbol *spans* the bytes we just deleted (i.e. its
4606 *end* is in the moved bytes but its *start* isn't), then we
4607 must adjust its size.
4609 This test needs to use the original value of st_value, otherwise
4610 we might accidentally decrease size when deleting bytes right
4611 before the symbol. But since deleted relocs can't span across
4612 symbols, we can't have both a st_value and a st_size decrease,
4613 so it is simpler to just use an else. */
4614 else if (sym
->st_value
<= addr
4615 && sym
->st_value
+ sym
->st_size
> addr
4616 && sym
->st_value
+ sym
->st_size
<= toaddr
)
4617 sym
->st_size
-= count
;
4621 /* Now adjust the global symbols defined in this section. */
4622 symcount
= ((symtab_hdr
->sh_size
/ sizeof (ElfNN_External_Sym
))
4623 - symtab_hdr
->sh_info
);
4625 for (i
= 0; i
< symcount
; i
++)
4627 struct elf_link_hash_entry
*sym_hash
= sym_hashes
[i
];
4629 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4630 containing the definition of __wrap_SYMBOL, includes a direct
4631 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4632 the same symbol (which is __wrap_SYMBOL), but still exist as two
4633 different symbols in 'sym_hashes', we don't want to adjust
4634 the global symbol __wrap_SYMBOL twice.
4636 The same problem occurs with symbols that are versioned_hidden, as
4637 foo becomes an alias for foo@BAR, and hence they need the same
4639 if (link_info
->wrap_hash
!= NULL
4640 || sym_hash
->versioned
!= unversioned
)
4642 struct elf_link_hash_entry
**cur_sym_hashes
;
4644 /* Loop only over the symbols which have already been checked. */
4645 for (cur_sym_hashes
= sym_hashes
; cur_sym_hashes
< &sym_hashes
[i
];
4648 /* If the current symbol is identical to 'sym_hash', that means
4649 the symbol was already adjusted (or at least checked). */
4650 if (*cur_sym_hashes
== sym_hash
)
4653 /* Don't adjust the symbol again. */
4654 if (cur_sym_hashes
< &sym_hashes
[i
])
4658 if ((sym_hash
->root
.type
== bfd_link_hash_defined
4659 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
4660 && sym_hash
->root
.u
.def
.section
== sec
)
4662 /* As above, adjust the value if needed. */
4663 if (sym_hash
->root
.u
.def
.value
> addr
4664 && sym_hash
->root
.u
.def
.value
<= toaddr
)
4665 sym_hash
->root
.u
.def
.value
-= count
;
4667 /* As above, adjust the size if needed. */
4668 else if (sym_hash
->root
.u
.def
.value
<= addr
4669 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
4670 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
<= toaddr
)
4671 sym_hash
->size
-= count
;
4678 /* Start perform TLS type transition.
4679 Currently there are three cases of relocation handled here:
4680 DESC -> IE, DEC -> LE and IE -> LE. */
4682 loongarch_tls_perform_trans (bfd
*abfd
, asection
*sec
,
4683 Elf_Internal_Rela
*rel
,
4684 struct elf_link_hash_entry
*h
,
4685 struct bfd_link_info
*info
)
4688 bool local_exec
= bfd_link_executable (info
)
4689 && LARCH_REF_LOCAL (info
, h
);
4690 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4691 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
4692 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4696 case R_LARCH_TLS_DESC_PC_HI20
:
4699 /* DESC -> LE relaxation:
4700 pcalalau12i $a0,%desc_pc_hi20(var) =>
4701 lu12i.w $a0,%le_hi20(var)
4703 bfd_put (32, abfd
, LARCH_LU12I_W
| LARCH_RD_A0
,
4704 contents
+ rel
->r_offset
);
4705 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4709 /* DESC -> IE relaxation:
4710 pcalalau12i $a0,%desc_pc_hi20(var) =>
4711 pcalalau12i $a0,%ie_pc_hi20(var)
4713 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_HI20
);
4717 case R_LARCH_TLS_DESC_PC_LO12
:
4720 /* DESC -> LE relaxation:
4721 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4722 ori $a0,$a0,le_lo12(var)
4724 insn
= LARCH_ORI
| LARCH_RD_RJ_A0
;
4725 bfd_put (32, abfd
, LARCH_ORI
| LARCH_RD_RJ_A0
,
4726 contents
+ rel
->r_offset
);
4727 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4731 /* DESC -> IE relaxation:
4732 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4733 ld.d $a0,$a0,%ie_pc_lo12(var)
4735 bfd_put (32, abfd
, LARCH_LD_D
| LARCH_RD_RJ_A0
,
4736 contents
+ rel
->r_offset
);
4737 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_LO12
);
4741 case R_LARCH_TLS_DESC_LD
:
4742 case R_LARCH_TLS_DESC_CALL
:
4743 /* DESC -> LE/IE relaxation:
4744 ld.d $ra,$a0,%desc_ld(var) => NOP
4745 jirl $ra,$ra,%desc_call(var) => NOP
4747 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4748 bfd_put (32, abfd
, LARCH_NOP
, contents
+ rel
->r_offset
);
4749 /* link with -relax option will delete NOP. */
4750 if (!info
->disable_target_specific_optimizations
)
4751 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4754 case R_LARCH_TLS_IE_PC_HI20
:
4757 /* IE -> LE relaxation:
4758 pcalalau12i $rd,%ie_pc_hi20(var) =>
4759 lu12i.w $rd,%le_hi20(var)
4761 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4762 bfd_put (32, abfd
, LARCH_LU12I_W
| (insn
& 0x1f),
4763 contents
+ rel
->r_offset
);
4764 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4768 case R_LARCH_TLS_IE_PC_LO12
:
4771 /* IE -> LE relaxation:
4772 ld.d $rd,$rj,%%ie_pc_lo12(var) =>
4773 ori $rd,$rj,le_lo12(var)
4775 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4776 bfd_put (32, abfd
, LARCH_ORI
| (insn
& 0x3ff),
4777 contents
+ rel
->r_offset
);
4778 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4787 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4788 there are three situations in which an assembly instruction sequence needs to
4790 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4793 in this case, the rd register in the st.{w/d} instruction does not store the
4794 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4795 symbolic address, and then obtains the rd + le_lo12_r address through the
4796 st.w instruction feature.
4797 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4799 before relax: after relax:
4801 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4802 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4803 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4806 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4808 before relax: after relax:
4810 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4811 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4812 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4815 in this case,the rs register in addi.{w/d} stores the full address of the tls
4816 symbol (tp + le_hi20_r + le_lo12_r).
4818 before relax: after relax:
4820 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4821 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4822 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4825 For relocation of all old LE instruction sequences, whether it is
4826 a normal code model or an extreme code model, relaxation will be
4827 performed when the relaxation conditions are met.
4830 lu12i.w $rd,%le_hi20(sym) => (deleted)
4831 ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4834 lu12i.w $rd,%le_hi20(sym) => (deleted)
4835 ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4836 lu32i.d $rd,%le64_lo20(sym) => (deleted)
4837 lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted)
4840 loongarch_relax_tls_le (bfd
*abfd
, asection
*sec
,
4841 Elf_Internal_Rela
*rel
,
4842 struct bfd_link_info
*link_info
,
4845 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4846 uint32_t insn
= bfd_get (32, abfd
, contents
+ rel
->r_offset
);
4847 static uint32_t insn_rj
,insn_rd
;
4848 symval
= symval
- elf_hash_table (link_info
)->tls_sec
->vma
;
4849 /* The old LE instruction sequence can be relaxed when the symbol offset
4850 is smaller than the 12-bit range. */
4851 if (ELFNN_R_TYPE ((rel
+ 1)->r_info
) == R_LARCH_RELAX
&& (symval
<= 0xfff))
4853 switch (ELFNN_R_TYPE (rel
->r_info
))
4855 /*if offset < 0x800, then perform the new le instruction
4857 case R_LARCH_TLS_LE_HI20_R
:
4858 case R_LARCH_TLS_LE_ADD_R
:
4862 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4863 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4868 case R_LARCH_TLS_LE_LO12_R
:
4871 /* Change rj to $tp. */
4873 /* Get rd register. */
4874 insn_rd
= insn
& 0x1f;
4875 /* Write symbol offset. */
4877 /* Writes the modified instruction. */
4878 insn
= insn
& 0xffc00000;
4879 insn
= insn
| symval
| insn_rj
| insn_rd
;
4880 bfd_put (32, abfd
, insn
, contents
+ rel
->r_offset
);
4884 case R_LARCH_TLS_LE_HI20
:
4885 case R_LARCH_TLS_LE64_LO20
:
4886 case R_LARCH_TLS_LE64_HI12
:
4887 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4888 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4892 case R_LARCH_TLS_LE_LO12
:
4893 bfd_put (32, abfd
, LARCH_ORI
| (insn
& 0x1f),
4894 contents
+ rel
->r_offset
);
4904 /* Whether two sections in the same segment. */
4906 loongarch_two_sections_in_same_segment (bfd
*abfd
, asection
*a
, asection
*b
)
4908 struct elf_segment_map
*m
;
4909 for (m
= elf_seg_map (abfd
); m
!= NULL
; m
= m
->next
)
4913 for (i
= m
->count
- 1; i
>= 0; i
--)
4915 if (m
->sections
[i
] == a
)
4917 if (m
->sections
[i
] == b
)
4928 /* Relax pcalau12i,addi.d => pcaddi. */
4930 loongarch_relax_pcala_addi (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4931 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4932 struct bfd_link_info
*info
, bool *again
,
4933 bfd_vma max_alignment
)
4935 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4936 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4937 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4938 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4939 uint32_t rd
= pca
& 0x1f;
4941 /* This section's output_offset need to subtract the bytes of instructions
4942 relaxed by the previous sections, so it needs to be updated beforehand.
4943 size_input_section already took care of updating it after relaxation,
4944 so we additionally update once here. */
4945 sec
->output_offset
= sec
->output_section
->size
;
4946 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
4948 /* If pc and symbol not in the same segment, add/sub segment alignment. */
4949 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
4950 sec
->output_section
,
4951 sym_sec
->output_section
))
4952 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
4956 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
4957 else if (symval
< pc
)
4958 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
4960 const uint32_t addi_d
= 0x02c00000;
4961 const uint32_t pcaddi
= 0x18000000;
4963 /* Is pcalau12i + addi.d insns? */
4964 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_PCALA_LO12
)
4965 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4966 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4967 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4968 || ((add
& addi_d
) != addi_d
)
4969 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4970 || ((add
& 0x1f) != rd
)
4971 || (((add
>> 5) & 0x1f) != rd
)
4972 /* Can be relaxed to pcaddi? */
4973 || (symval
& 0x3) /* 4 bytes align. */
4974 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
4975 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
4978 /* Continue next relax trip. */
4982 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
4984 /* Adjust relocations. */
4985 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4986 R_LARCH_PCREL20_S2
);
4987 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4989 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
4995 tail36 $t0, f -> b f. */
4997 loongarch_relax_call36 (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4998 Elf_Internal_Rela
*rel
, bfd_vma symval
,
4999 struct bfd_link_info
*info
, bool *again
,
5000 bfd_vma max_alignment
)
5002 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5003 uint32_t jirl
= bfd_get (32, abfd
, contents
+ rel
->r_offset
+ 4);
5004 uint32_t rd
= jirl
& 0x1f;
5006 /* This section's output_offset need to subtract the bytes of instructions
5007 relaxed by the previous sections, so it needs to be updated beforehand.
5008 size_input_section already took care of updating it after relaxation,
5009 so we additionally update once here. */
5010 sec
->output_offset
= sec
->output_section
->size
;
5011 bfd_vma pc
= sec_addr (sec
) + rel
->r_offset
;
5013 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5014 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
5015 sec
->output_section
,
5016 sym_sec
->output_section
))
5017 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
5021 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
5022 else if (symval
< pc
)
5023 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
5025 const uint32_t jirl_opcode
= 0x4c000000;
5027 /* Is pcalau12i + addi.d insns? */
5028 if ((ELFNN_R_TYPE ((rel
+ 1)->r_info
) != R_LARCH_RELAX
)
5029 || ((jirl
& jirl_opcode
) != jirl_opcode
)
5030 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xf8000000)
5031 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x7fffffc))
5034 /* Continue next relax trip. */
5037 const uint32_t bl
= 0x54000000;
5038 const uint32_t b
= 0x50000000;
5041 bfd_put (32, abfd
, bl
, contents
+ rel
->r_offset
);
5043 bfd_put (32, abfd
, b
, contents
+ rel
->r_offset
);
5045 /* Adjust relocations. */
5046 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
), R_LARCH_B26
);
5047 /* Delete jirl instruction. */
5048 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
+ 4, 4, info
);
5052 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
5054 loongarch_relax_pcala_ld (bfd
*abfd
, asection
*sec
,
5055 Elf_Internal_Rela
*rel_hi
)
5057 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5058 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
5059 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
5060 uint32_t ld
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
5061 uint32_t rd
= pca
& 0x1f;
5062 const uint32_t ld_d
= 0x28c00000;
5063 uint32_t addi_d
= 0x02c00000;
5065 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
)
5066 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
5067 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
5068 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
5069 || ((ld
& 0x1f) != rd
)
5070 || (((ld
>> 5) & 0x1f) != rd
)
5071 || ((ld
& ld_d
) != ld_d
))
5074 addi_d
= addi_d
| (rd
<< 5) | rd
;
5075 bfd_put (32, abfd
, addi_d
, contents
+ rel_lo
->r_offset
);
5077 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5078 R_LARCH_PCALA_HI20
);
5079 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_lo
->r_info
),
5080 R_LARCH_PCALA_LO12
);
5084 /* Called by after_allocation to set the information of data segment
5088 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info
*info
,
5089 int *data_segment_phase
)
5091 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5092 htab
->data_segment_phase
= data_segment_phase
;
5095 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
5096 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
5098 loongarch_relax_align (bfd
*abfd
, asection
*sec
,
5100 struct bfd_link_info
*link_info
,
5101 Elf_Internal_Rela
*rel
,
5104 bfd_vma addend
, max
= 0, alignment
= 1;
5106 int sym_index
= ELFNN_R_SYM (rel
->r_info
);
5109 alignment
= 1 << (rel
->r_addend
& 0xff);
5110 max
= rel
->r_addend
>> 8;
5113 alignment
= rel
->r_addend
+ 4;
5115 addend
= alignment
- 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
5116 symval
-= addend
; /* The address of first NOP added by R_LARCH_ALIGN. */
5117 bfd_vma aligned_addr
= ((symval
- 1) & ~(alignment
- 1)) + alignment
;
5118 bfd_vma need_nop_bytes
= aligned_addr
- symval
; /* */
5120 /* Make sure there are enough NOPs to actually achieve the alignment. */
5121 if (addend
< need_nop_bytes
)
5124 (_("%pB(%pA+%#" PRIx64
"): %" PRId64
" bytes required for alignment "
5125 "to %" PRId64
"-byte boundary, but only %" PRId64
" present"),
5126 abfd
, sym_sec
, (uint64_t) rel
->r_offset
,
5127 (int64_t) need_nop_bytes
, (int64_t) alignment
, (int64_t) addend
);
5128 bfd_set_error (bfd_error_bad_value
);
5132 /* Once we've handled an R_LARCH_ALIGN in a section,
5133 we can't relax anything else in this section. */
5134 sec
->sec_flg0
= true;
5135 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5137 /* If skipping more bytes than the specified maximum,
5138 then the alignment is not done at all and delete all NOPs. */
5139 if (max
> 0 && need_nop_bytes
> max
)
5140 return loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
5143 /* If the number of NOPs is already correct, there's nothing to do. */
5144 if (need_nop_bytes
== addend
)
5147 /* Delete the excess NOPs. */
5148 return loongarch_relax_delete_bytes (abfd
, sec
,
5149 rel
->r_offset
+ need_nop_bytes
,
5150 addend
- need_nop_bytes
, link_info
);
5153 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
5155 loongarch_relax_tls_ld_gd_desc (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
5156 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
5157 struct bfd_link_info
*info
, bool *again
,
5158 bfd_vma max_alignment
)
5160 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5161 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
5162 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
5163 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
5164 uint32_t rd
= pca
& 0x1f;
5166 /* This section's output_offset need to subtract the bytes of instructions
5167 relaxed by the previous sections, so it needs to be updated beforehand.
5168 size_input_section already took care of updating it after relaxation,
5169 so we additionally update once here. */
5170 sec
->output_offset
= sec
->output_section
->size
;
5171 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
5173 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5174 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
5175 sec
->output_section
,
5176 sym_sec
->output_section
))
5177 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
5181 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
5182 else if (symval
< pc
)
5183 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
5185 const uint32_t addi_d
= 0x02c00000;
5186 const uint32_t pcaddi
= 0x18000000;
5188 /* Is pcalau12i + addi.d insns? */
5189 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
5190 && ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_TLS_DESC_PC_LO12
)
5191 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
5192 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
5193 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
5194 || ((add
& addi_d
) != addi_d
)
5195 /* Is pcalau12i $rd + addi.d $rd,$rd? */
5196 || ((add
& 0x1f) != rd
)
5197 || (((add
>> 5) & 0x1f) != rd
)
5198 /* Can be relaxed to pcaddi? */
5199 || (symval
& 0x3) /* 4 bytes align. */
5200 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
5201 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
5204 /* Continue next relax trip. */
5208 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
5210 /* Adjust relocations. */
5211 switch (ELFNN_R_TYPE (rel_hi
->r_info
))
5213 case R_LARCH_TLS_LD_PC_HI20
:
5214 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5215 R_LARCH_TLS_LD_PCREL20_S2
);
5217 case R_LARCH_TLS_GD_PC_HI20
:
5218 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5219 R_LARCH_TLS_GD_PCREL20_S2
);
5221 case R_LARCH_TLS_DESC_PC_HI20
:
5222 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5223 R_LARCH_TLS_DESC_PCREL20_S2
);
5228 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5230 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
5235 /* Traverse all output sections and return the max alignment. */
5238 loongarch_get_max_alignment (asection
*sec
)
5241 unsigned int max_alignment_power
= 0;
5243 for (o
= sec
->output_section
->owner
->sections
; o
!= NULL
; o
= o
->next
)
5244 if (o
->alignment_power
> max_alignment_power
)
5245 max_alignment_power
= o
->alignment_power
;
5247 return (bfd_vma
) 1 << max_alignment_power
;
5251 loongarch_elf_relax_section (bfd
*abfd
, asection
*sec
,
5252 struct bfd_link_info
*info
,
5255 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5256 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
5257 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (abfd
);
5258 Elf_Internal_Rela
*relocs
;
5260 bfd_vma max_alignment
= 0;
5262 if (bfd_link_relocatable (info
)
5264 || (sec
->flags
& SEC_RELOC
) == 0
5265 || sec
->reloc_count
== 0
5266 || (info
->disable_target_specific_optimizations
5267 && info
->relax_pass
== 0)
5268 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
5269 and defined in ld/ldexp.h. */
5270 || *(htab
->data_segment_phase
) == 4)
5274 relocs
= data
->relocs
;
5275 else if (!(relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
5276 info
->keep_memory
)))
5279 if (!data
->this_hdr
.contents
5280 && !bfd_malloc_and_get_section (abfd
, sec
, &data
->this_hdr
.contents
))
5283 if (symtab_hdr
->sh_info
!= 0
5284 && !symtab_hdr
->contents
5285 && !(symtab_hdr
->contents
=
5286 (unsigned char *) bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
5287 symtab_hdr
->sh_info
,
5288 0, NULL
, NULL
, NULL
)))
5291 data
->relocs
= relocs
;
5293 /* Estimate the maximum alignment for all output sections once time
5294 should be enough. */
5295 max_alignment
= htab
->max_alignment
;
5296 if (max_alignment
== (bfd_vma
) -1)
5298 max_alignment
= loongarch_get_max_alignment (sec
);
5299 htab
->max_alignment
= max_alignment
;
5302 for (unsigned int i
= 0; i
< sec
->reloc_count
; i
++)
5307 bool local_got
= false;
5308 Elf_Internal_Rela
*rel
= relocs
+ i
;
5309 struct elf_link_hash_entry
*h
= NULL
;
5310 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
5311 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5313 /* Four kind of relocations:
5314 Normal: symval is the symbol address.
5315 R_LARCH_ALIGN: symval is the address of the last NOP instruction
5316 added by this relocation, and then adds 4 more.
5317 R_LARCH_CALL36: symval is the symbol address for local symbols,
5318 or the PLT entry address of the symbol. (Todo)
5319 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
5320 of the symbol if transition is not possible. */
5321 if (r_symndx
< symtab_hdr
->sh_info
)
5323 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)symtab_hdr
->contents
5325 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
5328 /* Only TLS instruction sequences that are accompanied by
5329 R_LARCH_RELAX and cannot perform type transition can be
5331 if (R_LARCH_TLS_LD_PC_HI20
== r_type
5332 || R_LARCH_TLS_GD_PC_HI20
== r_type
5333 || (R_LARCH_TLS_DESC_PC_HI20
== r_type
5334 && (i
+ 1 != sec
->reloc_count
)
5335 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
5336 && ! loongarch_can_trans_tls (abfd
, info
, h
,
5339 sym_sec
= htab
->elf
.sgot
;
5340 symval
= elf_local_got_offsets (abfd
)[r_symndx
];
5341 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
5343 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
5344 && GOT_TLS_GD_BOTH_P (tls_type
))
5345 symval
+= 2 * GOT_ENTRY_SIZE
;
5347 else if (sym
->st_shndx
== SHN_UNDEF
|| R_LARCH_ALIGN
== r_type
)
5350 symval
= rel
->r_offset
;
5354 sym_sec
= elf_elfsections (abfd
)[sym
->st_shndx
]->bfd_section
;
5355 symval
= sym
->st_value
;
5357 symtype
= ELF_ST_TYPE (sym
->st_info
);
5361 r_symndx
= ELFNN_R_SYM (rel
->r_info
) - symtab_hdr
->sh_info
;
5362 h
= elf_sym_hashes (abfd
)[r_symndx
];
5364 while (h
->root
.type
== bfd_link_hash_indirect
5365 || h
->root
.type
== bfd_link_hash_warning
)
5366 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
5368 /* Disable the relaxation for ifunc. */
5369 if (h
!= NULL
&& h
->type
== STT_GNU_IFUNC
)
5372 /* The GOT entry of tls symbols must in current execute file or
5374 if (R_LARCH_TLS_LD_PC_HI20
== r_type
5375 || R_LARCH_TLS_GD_PC_HI20
== r_type
5376 || (R_LARCH_TLS_DESC_PC_HI20
== r_type
5377 && (i
+ 1 != sec
->reloc_count
)
5378 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
5379 && !loongarch_can_trans_tls (abfd
, info
, h
,
5382 sym_sec
= htab
->elf
.sgot
;
5383 symval
= h
->got
.offset
;
5384 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
5386 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
5387 && GOT_TLS_GD_BOTH_P (tls_type
))
5388 symval
+= 2 * GOT_ENTRY_SIZE
;
5390 else if ((h
->root
.type
== bfd_link_hash_defined
5391 || h
->root
.type
== bfd_link_hash_defweak
)
5392 && h
->root
.u
.def
.section
!= NULL
5393 && h
->root
.u
.def
.section
->output_section
!= NULL
)
5395 symval
= h
->root
.u
.def
.value
;
5396 sym_sec
= h
->root
.u
.def
.section
;
5401 if (h
&& LARCH_REF_LOCAL (info
, h
))
5406 if (sym_sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
5407 && (sym_sec
->flags
& SEC_MERGE
))
5409 if (symtype
== STT_SECTION
)
5410 symval
+= rel
->r_addend
;
5412 symval
= _bfd_merged_section_offset (abfd
, &sym_sec
,
5413 elf_section_data (sym_sec
)->sec_info
,
5416 if (symtype
!= STT_SECTION
)
5417 symval
+= rel
->r_addend
;
5419 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
5421 If r_symndx is 0, alignmeng-4 is r_addend.
5422 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
5423 else if (R_LARCH_ALIGN
== r_type
)
5425 symval
+= ((1 << (rel
->r_addend
& 0xff)) - 4);
5427 symval
+= rel
->r_addend
;
5429 symval
+= rel
->r_addend
;
5431 symval
+= sec_addr (sym_sec
);
5433 /* If the conditions for tls type transition are met, type
5434 transition is performed instead of relax.
5435 During the transition from DESC->IE/LE, there are 2 situations
5436 depending on the different configurations of the relax/norelax
5438 If the -relax option is used, the extra nops will be removed,
5439 and this transition is performed in pass 0.
5440 If the --no-relax option is used, nop will be retained, and
5441 this transition is performed in pass 1. */
5442 if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type
)
5443 && (i
+ 1 != sec
->reloc_count
)
5444 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
5445 && loongarch_can_trans_tls (abfd
, info
, h
, r_symndx
, r_type
))
5447 loongarch_tls_perform_trans (abfd
, sec
, rel
, h
, info
);
5448 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5454 if (1 == info
->relax_pass
)
5455 loongarch_relax_align (abfd
, sec
, sym_sec
, info
, rel
, symval
);
5458 case R_LARCH_DELETE
:
5459 if (1 == info
->relax_pass
)
5461 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
5462 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5465 case R_LARCH_CALL36
:
5466 if (0 == info
->relax_pass
&& (i
+ 2) <= sec
->reloc_count
)
5467 loongarch_relax_call36 (abfd
, sec
, sym_sec
, rel
, symval
,
5468 info
, again
, max_alignment
);
5471 case R_LARCH_TLS_LE_HI20_R
:
5472 case R_LARCH_TLS_LE_LO12_R
:
5473 case R_LARCH_TLS_LE_ADD_R
:
5474 case R_LARCH_TLS_LE_HI20
:
5475 case R_LARCH_TLS_LE_LO12
:
5476 case R_LARCH_TLS_LE64_LO20
:
5477 case R_LARCH_TLS_LE64_HI12
:
5478 if (0 == info
->relax_pass
&& (i
+ 2) <= sec
->reloc_count
)
5479 loongarch_relax_tls_le (abfd
, sec
, rel
, info
, symval
);
5482 case R_LARCH_PCALA_HI20
:
5483 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
5484 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
5485 info
, again
, max_alignment
);
5488 case R_LARCH_GOT_PC_HI20
:
5489 if (local_got
&& 0 == info
->relax_pass
5490 && (i
+ 4) <= sec
->reloc_count
)
5492 if (loongarch_relax_pcala_ld (abfd
, sec
, rel
))
5493 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
5494 info
, again
, max_alignment
);
5498 case R_LARCH_TLS_LD_PC_HI20
:
5499 case R_LARCH_TLS_GD_PC_HI20
:
5500 case R_LARCH_TLS_DESC_PC_HI20
:
5501 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
5502 loongarch_relax_tls_ld_gd_desc (abfd
, sec
, sym_sec
, rel
, symval
,
5503 info
, again
, max_alignment
);
5514 /* Finish up dynamic symbol handling. We set the contents of various
5515 dynamic sections here. */
5518 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
5519 struct bfd_link_info
*info
,
5520 struct elf_link_hash_entry
*h
,
5521 Elf_Internal_Sym
*sym
)
5523 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5524 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
5526 if (h
->plt
.offset
!= MINUS_ONE
)
5529 asection
*plt
, *gotplt
, *relplt
;
5530 bfd_vma got_address
;
5531 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
5533 Elf_Internal_Rela rela
;
5537 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
5538 && LARCH_REF_LOCAL (info
, h
))
5539 || h
->dynindx
!= -1);
5541 plt
= htab
->elf
.splt
;
5542 gotplt
= htab
->elf
.sgotplt
;
5543 if (h
->type
== STT_GNU_IFUNC
&& LARCH_REF_LOCAL (info
, h
))
5544 relplt
= htab
->elf
.srelgot
;
5546 relplt
= htab
->elf
.srelplt
;
5547 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
5549 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
5551 else /* if (htab->elf.iplt) */
5553 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
5554 && LARCH_REF_LOCAL (info
, h
));
5556 plt
= htab
->elf
.iplt
;
5557 gotplt
= htab
->elf
.igotplt
;
5558 relplt
= htab
->elf
.irelplt
;
5559 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
5560 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
5563 /* Find out where the .plt entry should go. */
5564 loc
= plt
->contents
+ h
->plt
.offset
;
5566 /* Fill in the PLT entry itself. */
5567 if (!loongarch_make_plt_entry (got_address
,
5568 sec_addr (plt
) + h
->plt
.offset
,
5572 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
5573 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
5575 /* Fill in the initial value of the got.plt entry. */
5576 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
5577 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
5579 rela
.r_offset
= got_address
;
5581 /* TRUE if this is a PLT reference to a local IFUNC. */
5582 if (PLT_LOCAL_IFUNC_P (info
, h
)
5583 && (relplt
== htab
->elf
.srelgot
5584 || relplt
== htab
->elf
.irelplt
))
5586 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
5587 rela
.r_addend
= (h
->root
.u
.def
.value
5588 + h
->root
.u
.def
.section
->output_section
->vma
5589 + h
->root
.u
.def
.section
->output_offset
);
5591 loongarch_elf_append_rela (output_bfd
, relplt
, &rela
);
5595 /* Fill in the entry in the rela.plt section. */
5596 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
5598 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
5599 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
5602 if (!h
->def_regular
)
5604 /* Mark the symbol as undefined, rather than as defined in
5605 the .plt section. Leave the value alone. */
5606 sym
->st_shndx
= SHN_UNDEF
;
5607 /* If the symbol is weak, we do need to clear the value.
5608 Otherwise, the PLT entry would provide a definition for
5609 the symbol even if the symbol wasn't defined anywhere,
5610 and so the symbol would never be NULL. */
5611 if (!h
->ref_regular_nonweak
)
5616 if (h
->got
.offset
!= MINUS_ONE
5617 /* TLS got entry have been handled in elf_relocate_section. */
5618 && !(loongarch_elf_hash_entry (h
)->tls_type
5619 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
5620 /* Have allocated got entry but not allocated rela before. */
5621 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
5623 asection
*sgot
, *srela
;
5624 Elf_Internal_Rela rela
;
5625 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
)1;
5627 /* This symbol has an entry in the GOT. Set it up. */
5628 sgot
= htab
->elf
.sgot
;
5629 srela
= htab
->elf
.srelgot
;
5630 BFD_ASSERT (sgot
&& srela
);
5632 rela
.r_offset
= sec_addr (sgot
) + off
;
5635 && h
->type
== STT_GNU_IFUNC
)
5637 if(h
->plt
.offset
== MINUS_ONE
)
5639 if (htab
->elf
.splt
== NULL
)
5640 srela
= htab
->elf
.irelplt
;
5642 if (LARCH_REF_LOCAL (info
, h
))
5644 asection
*sec
= h
->root
.u
.def
.section
;
5645 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
5646 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
5647 + sec
->output_offset
;
5648 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
5652 BFD_ASSERT (h
->dynindx
!= -1);
5653 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5655 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
5658 else if(bfd_link_pic (info
))
5660 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5662 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
5667 /* For non-shared object, we can't use .got.plt, which
5668 contains the real function address if we need pointer
5669 equality. We load the GOT entry with the PLT entry. */
5670 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
5671 bfd_put_NN (output_bfd
,
5672 (plt
->output_section
->vma
5673 + plt
->output_offset
5675 sgot
->contents
+ off
);
5679 else if (bfd_link_pic (info
) && LARCH_REF_LOCAL (info
, h
))
5681 asection
*sec
= h
->root
.u
.def
.section
;
5682 bfd_vma linkaddr
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
5683 + sec
->output_offset
;
5685 /* Don't emit relative relocs if they are packed, but we need
5686 to write the addend (link-time addr) into the GOT then. */
5687 if (info
->enable_dt_relr
)
5689 bfd_put_NN (output_bfd
, linkaddr
, sgot
->contents
+ off
);
5690 goto skip_got_reloc
;
5692 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
5693 rela
.r_addend
= linkaddr
;
5697 BFD_ASSERT (h
->dynindx
!= -1);
5698 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5702 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
5706 /* Mark some specially defined symbols as absolute. */
5707 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
5708 sym
->st_shndx
= SHN_ABS
;
5713 /* Finish up the dynamic sections. */
5716 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
5719 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5720 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
5721 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
5722 bfd_byte
*dyncon
, *dynconend
;
5724 dynconend
= sdyn
->contents
+ sdyn
->size
;
5725 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
5727 Elf_Internal_Dyn dyn
;
5731 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
5736 s
= htab
->elf
.sgotplt
;
5737 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5740 s
= htab
->elf
.srelplt
;
5741 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5744 s
= htab
->elf
.srelplt
;
5745 dyn
.d_un
.d_val
= s
->size
;
5748 if ((info
->flags
& DF_TEXTREL
) == 0)
5752 if ((info
->flags
& DF_TEXTREL
) == 0)
5753 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
5757 skipped_size
+= dynsize
;
5759 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
5761 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
5762 memset (dyncon
- skipped_size
, 0, skipped_size
);
5766 /* Finish up local dynamic symbol handling. We set the contents of
5767 various dynamic sections here. */
5770 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
5772 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
5773 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
5775 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
5778 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
5779 this function is called before elf_link_sort_relocs.
5780 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
5781 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
5784 elf_loongarch_output_arch_local_syms
5785 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
5786 struct bfd_link_info
*info
,
5787 void *flaginfo ATTRIBUTE_UNUSED
,
5788 int (*func
) (void *, const char *,
5791 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
5793 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5797 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5798 htab_traverse (htab
->loc_hash_table
,
5799 elfNN_loongarch_finish_local_dynamic_symbol
,
5806 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
5807 struct bfd_link_info
*info
)
5810 asection
*sdyn
, *plt
, *gotplt
= NULL
;
5811 struct loongarch_elf_link_hash_table
*htab
;
5813 htab
= loongarch_elf_hash_table (info
);
5815 dynobj
= htab
->elf
.dynobj
;
5816 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
5818 if (elf_hash_table (info
)->dynamic_sections_created
)
5820 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
5822 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
5826 plt
= htab
->elf
.splt
;
5827 gotplt
= htab
->elf
.sgotplt
;
5829 if (plt
&& 0 < plt
->size
)
5832 uint32_t plt_header
[PLT_HEADER_INSNS
];
5833 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
5837 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
5838 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
5840 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
5844 if (htab
->elf
.sgotplt
)
5846 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
5848 if (bfd_is_abs_section (output_section
))
5850 _bfd_error_handler (_("discarded output section: `%pA'"),
5855 if (0 < htab
->elf
.sgotplt
->size
)
5857 /* Write the first two entries in .got.plt, needed for the dynamic
5859 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
5861 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5862 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
5865 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5870 asection
*output_section
= htab
->elf
.sgot
->output_section
;
5872 if (0 < htab
->elf
.sgot
->size
)
5874 /* Set the first entry in the global offset table to the address of
5875 the dynamic section. */
5876 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
5877 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
5880 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5886 /* Return address for Ith PLT stub in section PLT, for relocation REL
5887 or (bfd_vma) -1 if it should not be included. */
5890 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
5891 const arelent
*rel ATTRIBUTE_UNUSED
)
5893 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
5896 static enum elf_reloc_type_class
5897 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5898 const asection
*rel_sec ATTRIBUTE_UNUSED
,
5899 const Elf_Internal_Rela
*rela
)
5901 struct loongarch_elf_link_hash_table
*htab
;
5902 htab
= loongarch_elf_hash_table (info
);
5904 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
5906 /* Check relocation against STT_GNU_IFUNC symbol if there are
5908 bfd
*abfd
= info
->output_bfd
;
5909 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
5910 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
5911 if (r_symndx
!= STN_UNDEF
)
5913 Elf_Internal_Sym sym
;
5914 if (!bed
->s
->swap_symbol_in (abfd
,
5915 htab
->elf
.dynsym
->contents
5916 + r_symndx
* bed
->s
->sizeof_sym
,
5919 /* xgettext:c-format */
5920 _bfd_error_handler (_("%pB symbol number %lu references"
5921 " nonexistent SHT_SYMTAB_SHNDX section"),
5923 /* Ideally an error class should be returned here. */
5925 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
5926 return reloc_class_ifunc
;
5930 switch (ELFNN_R_TYPE (rela
->r_info
))
5932 case R_LARCH_IRELATIVE
:
5933 return reloc_class_ifunc
;
5934 case R_LARCH_RELATIVE
:
5935 return reloc_class_relative
;
5936 case R_LARCH_JUMP_SLOT
:
5937 return reloc_class_plt
;
5939 return reloc_class_copy
;
5941 return reloc_class_normal
;
5945 /* Copy the extra info we tack onto an elf_link_hash_entry. */
5948 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
5949 struct elf_link_hash_entry
*dir
,
5950 struct elf_link_hash_entry
*ind
)
5952 struct elf_link_hash_entry
*edir
, *eind
;
5957 if (eind
->dyn_relocs
!= NULL
)
5959 if (edir
->dyn_relocs
!= NULL
)
5961 struct elf_dyn_relocs
**pp
;
5962 struct elf_dyn_relocs
*p
;
5964 /* Add reloc counts against the indirect sym to the direct sym
5965 list. Merge any entries against the same section. */
5966 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
5968 struct elf_dyn_relocs
*q
;
5970 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
5971 if (q
->sec
== p
->sec
)
5973 q
->pc_count
+= p
->pc_count
;
5974 q
->count
+= p
->count
;
5981 *pp
= edir
->dyn_relocs
;
5984 edir
->dyn_relocs
= eind
->dyn_relocs
;
5985 eind
->dyn_relocs
= NULL
;
5988 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
5990 loongarch_elf_hash_entry(edir
)->tls_type
5991 = loongarch_elf_hash_entry(eind
)->tls_type
;
5992 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
5994 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
5997 #define PRSTATUS_SIZE 0x1d8
5998 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
5999 #define PRSTATUS_OFFSET_PR_PID 0x20
6000 #define ELF_GREGSET_T_SIZE 0x168
6001 #define PRSTATUS_OFFSET_PR_REG 0x70
6003 /* Support for core dump NOTE sections. */
6006 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
6008 switch (note
->descsz
)
6013 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
6016 elf_tdata (abfd
)->core
->signal
=
6017 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
6020 elf_tdata (abfd
)->core
->lwpid
=
6021 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
6025 /* Make a ".reg/999" section. */
6026 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
6028 + PRSTATUS_OFFSET_PR_REG
);
6031 #define PRPSINFO_SIZE 0x88
6032 #define PRPSINFO_OFFSET_PR_PID 0x18
6033 #define PRPSINFO_OFFSET_PR_FNAME 0x28
6034 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
6035 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
6036 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
6039 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
6041 switch (note
->descsz
)
6046 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
6049 elf_tdata (abfd
)->core
->pid
=
6050 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
6053 elf_tdata (abfd
)->core
->program
=
6054 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
6055 PRPSINFO_SIZEOF_PR_FNAME
);
6058 elf_tdata (abfd
)->core
->command
=
6059 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
6060 PRPSINFO_SIZEOF_PR_PS_ARGS
);
6064 /* Note that for some reason, a spurious space is tacked
6065 onto the end of the args in some (at least one anyway)
6066 implementations, so strip it off if it exists. */
6069 char *command
= elf_tdata (abfd
)->core
->command
;
6070 int n
= strlen (command
);
6072 if (0 < n
&& command
[n
- 1] == ' ')
6073 command
[n
- 1] = '\0';
6079 /* Set the right mach type. */
6081 loongarch_elf_object_p (bfd
*abfd
)
6083 /* There are only two mach types in LoongArch currently. */
6084 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
6085 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
6087 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
6092 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
6093 Elf_Internal_Rela
*rel
,
6094 struct elf_link_hash_entry
*h
,
6095 Elf_Internal_Sym
*sym
)
6098 switch (ELFNN_R_TYPE (rel
->r_info
))
6100 case R_LARCH_GNU_VTINHERIT
:
6101 case R_LARCH_GNU_VTENTRY
:
6105 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
6108 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
6109 executable PLT slots where the executable never takes the address of those
6110 functions, the function symbols are not added to the hash table. */
6113 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
6115 if (h
->plt
.offset
!= (bfd_vma
) -1
6117 && !h
->pointer_equality_needed
)
6120 return _bfd_elf_hash_symbol (h
);
6123 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
6124 #define TARGET_LITTLE_NAME "elfNN-loongarch"
6125 #define ELF_ARCH bfd_arch_loongarch
6126 #define ELF_TARGET_ID LARCH_ELF_DATA
6127 #define ELF_MACHINE_CODE EM_LOONGARCH
6128 #define ELF_MAXPAGESIZE 0x4000
6129 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
6130 #define bfd_elfNN_bfd_link_hash_table_create \
6131 loongarch_elf_link_hash_table_create
6132 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
6133 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
6134 #define elf_info_to_howto loongarch_info_to_howto_rela
6135 #define bfd_elfNN_bfd_merge_private_bfd_data \
6136 elfNN_loongarch_merge_private_bfd_data
6138 #define elf_backend_reloc_type_class loongarch_reloc_type_class
6139 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
6140 #define elf_backend_create_dynamic_sections \
6141 loongarch_elf_create_dynamic_sections
6142 #define elf_backend_check_relocs loongarch_elf_check_relocs
6143 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
6144 #define elf_backend_late_size_sections loongarch_elf_late_size_sections
6145 #define elf_backend_relocate_section loongarch_elf_relocate_section
6146 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
6147 #define elf_backend_output_arch_local_syms \
6148 elf_loongarch_output_arch_local_syms
6149 #define elf_backend_finish_dynamic_sections \
6150 loongarch_elf_finish_dynamic_sections
6151 #define elf_backend_object_p loongarch_elf_object_p
6152 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
6153 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
6154 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
6155 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
6156 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
6157 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
6158 #define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs
6159 #define elf_backend_finish_relative_relocs \
6160 loongarch_elf_finish_relative_relocs
6161 #define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook
6163 #define elf_backend_dtrel_excludes_plt 1
6165 #include "elfNN-target.h"