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)
88 elfNN_loongarch_object (bfd
*abfd
)
90 return bfd_elf_allocate_object (abfd
,
91 sizeof (struct _bfd_loongarch_elf_obj_tdata
),
101 struct loongarch_elf_link_hash_table
103 struct elf_link_hash_table elf
;
105 /* Short-cuts to get to dynamic linker sections. */
108 /* Small local sym to section mapping cache. */
109 struct sym_cache sym_cache
;
111 /* Used by local STT_GNU_IFUNC symbols. */
112 htab_t loc_hash_table
;
113 void *loc_hash_memory
;
115 /* The max alignment of output sections. */
116 bfd_vma max_alignment
;
118 /* The data segment phase, don't relax the section
119 when it is exp_seg_relro_adjust. */
120 int *data_segment_phase
;
122 /* Array of relative relocs to be emitted in DT_RELR format. */
123 bfd_size_type relr_alloc
;
124 bfd_size_type relr_count
;
125 struct relr_entry
*relr
;
127 /* Sorted output addresses of above relative relocs. */
128 bfd_vma
*relr_sorted
;
130 /* Layout recomputation count. */
131 bfd_size_type relr_layout_iter
;
133 /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip
134 size_relative_relocs is updating the layout, relax_section may see
135 a partially updated state (some sections have vma updated but the
136 others do not), and it's unsafe to do the normal relaxation. */
137 bool layout_mutating_for_relr
;
140 struct loongarch_elf_section_data
142 struct bfd_elf_section_data elf
;
144 /* &htab->relr[i] where i is the smallest number s.t.
145 elf_section_data (htab->relr[i].sec) == &elf.
146 NULL if there exists no such i. */
147 struct relr_entry
*relr
;
150 /* We need an additional field in elf_section_data to handle complex
151 interactions between DT_RELR and relaxation. */
153 loongarch_elf_new_section_hook (bfd
*abfd
, asection
*sec
)
155 if (!sec
->used_by_bfd
)
157 struct loongarch_elf_section_data
*sdata
;
158 size_t amt
= sizeof (*sdata
);
160 sdata
= bfd_zalloc (abfd
, amt
);
163 sec
->used_by_bfd
= sdata
;
166 return _bfd_elf_new_section_hook (abfd
, sec
);
169 #define loongarch_elf_section_data(x) \
170 ((struct loongarch_elf_section_data *) elf_section_data (x))
172 /* Get the LoongArch ELF linker hash table from a link_info structure. */
173 #define loongarch_elf_hash_table(p) \
174 ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
176 #define MINUS_ONE ((bfd_vma) 0 - 1)
178 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
180 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
181 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
183 #define PLT_HEADER_INSNS 8
184 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
186 #define PLT_ENTRY_INSNS 4
187 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
189 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
191 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT
192 resolver _dl_runtime_resolve, the other is used for link map. */
193 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
195 #define elf_backend_want_got_plt 1
197 #define elf_backend_plt_readonly 1
199 #define elf_backend_want_plt_sym 1
200 #define elf_backend_plt_alignment 4
201 #define elf_backend_can_gc_sections 1
202 #define elf_backend_can_refcount 1
203 #define elf_backend_want_got_sym 1
205 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
207 #define elf_backend_want_dynrelro 1
208 #define elf_backend_rela_normal 1
209 #define elf_backend_default_execstack 0
211 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
212 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
213 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
214 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
215 || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
216 || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
217 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
219 #define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \
220 ((R_TYPE) == R_LARCH_TLS_LE_HI20 \
221 || (R_TYPE) == R_LARCH_TLS_LE_LO12 \
222 || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
223 || (R_TYPE) == R_LARCH_TLS_LE64_HI12)
225 /* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx,
226 and set NEED_RELOC to true used in allocate_dynrelocs and
227 loongarch_elf_relocate_section for TLS GD/IE. */
228 #define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
232 && (H)->dynindx != -1 \
233 && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \
234 bfd_link_pic (INFO), (H))) \
235 (INDX) = (H)->dynindx; \
237 || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
238 || (H)->root.type != bfd_link_hash_undefweak) \
239 && (!bfd_link_executable (INFO) \
241 (NEED_RELOC) = true; \
245 /* TL;DR always use it in this file instead when you want to type
246 SYMBOL_REFERENCES_LOCAL.
248 It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local
249 protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but
250 let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people.
252 We do generate a PLT entry when someone attempts to la.pcrel an external
253 function. But we never really implemented "R_LARCH_COPY", thus we've
254 never supported la.pcrel an external symbol unless the loaded address is
255 only used for locating a function to be called. Thus the PLT entry is
256 a normal PLT entry, not intended to be a so-called "canonical PLT entry"
257 on the ports supporting copy relocation. So attempting to la.pcrel an
258 external function will just break pointer equality, even it's a
259 STV_DEFAULT function:
263 void check(void *p) {assert(p == check);}
265 extern void check(void *);
266 int main(void) { check(check); }
267 $ cc t.c -fPIC -shared -o t.so
268 $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. -fpie -pie
270 a.out: t.c:2: check: Assertion `p == check' failed.
273 Thus handling STV_PROTECTED function specially just fixes nothing:
274 adding -fvisibility=protected compiling t.c will not magically fix
275 the inequality. The only possible and correct fix is not to use
276 -mdirect-extern-access.
278 So we should remove this special handling, because it's only an
279 unsuccessful workaround for invalid code and it's penalizing valid
281 #define LARCH_REF_LOCAL(info, h) \
282 (_bfd_elf_symbol_refs_local_p ((h), (info), true))
284 /* Generate a PLT header. */
287 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
290 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
293 if (pcrel
+ 0x80000800 > 0xffffffff)
295 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
296 bfd_set_error (bfd_error_bad_value
);
299 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
302 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
303 sub.[wd] $t1, $t1, $t3
304 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
305 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
306 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
307 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
308 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
311 if (GOT_ENTRY_SIZE
== 8)
313 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
314 entry
[1] = 0x0011bdad;
315 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
316 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
317 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
318 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
319 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
320 entry
[7] = 0x4c0001e0;
324 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
325 entry
[1] = 0x00113dad;
326 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
327 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
328 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
329 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
330 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
331 entry
[7] = 0x4c0001e0;
336 /* Generate a PLT entry. */
339 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
342 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
345 if (pcrel
+ 0x80000800 > 0xffffffff)
347 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
348 bfd_set_error (bfd_error_bad_value
);
351 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
354 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
355 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
356 | (lo
& 0xfff) << 10);
357 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
358 entry
[3] = 0x03400000; /* nop */
363 /* Create an entry in an LoongArch ELF linker hash table. */
365 static struct bfd_hash_entry
*
366 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
369 struct loongarch_elf_link_hash_entry
*eh
;
371 /* Allocate the structure if it has not already been allocated by a
375 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
380 /* Call the allocation method of the superclass. */
381 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
384 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
385 eh
->tls_type
= GOT_UNKNOWN
;
391 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
392 for local symbol so that we can handle local STT_GNU_IFUNC symbols
393 as global symbol. We reuse indx and dynstr_index for local symbol
394 hash since they aren't used by global symbols in this backend. */
397 elfNN_loongarch_local_htab_hash (const void *ptr
)
399 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
400 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
403 /* Compare local hash entries. */
406 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
408 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
409 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
411 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
414 /* Find and/or create a hash entry for local symbol. */
415 static struct elf_link_hash_entry
*
416 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
417 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
420 struct loongarch_elf_link_hash_entry e
, *ret
;
421 asection
*sec
= abfd
->sections
;
422 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
425 e
.elf
.indx
= sec
->id
;
426 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
427 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
428 create
? INSERT
: NO_INSERT
);
435 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
439 ret
= ((struct loongarch_elf_link_hash_entry
*)
440 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
441 sizeof (struct loongarch_elf_link_hash_entry
)));
444 memset (ret
, 0, sizeof (*ret
));
445 ret
->elf
.indx
= sec
->id
;
446 ret
->elf
.pointer_equality_needed
= 0;
447 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
448 ret
->elf
.dynindx
= -1;
449 ret
->elf
.needs_plt
= 0;
450 ret
->elf
.plt
.refcount
= -1;
451 ret
->elf
.got
.refcount
= -1;
452 ret
->elf
.def_dynamic
= 0;
453 ret
->elf
.def_regular
= 1;
454 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
455 ret
->elf
.ref_regular
= 0;
456 ret
->elf
.forced_local
= 1;
457 ret
->elf
.root
.type
= bfd_link_hash_defined
;
463 /* Destroy an LoongArch elf linker hash table. */
466 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
468 struct loongarch_elf_link_hash_table
*ret
;
469 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
471 if (ret
->loc_hash_table
)
472 htab_delete (ret
->loc_hash_table
);
473 if (ret
->loc_hash_memory
)
474 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
476 _bfd_elf_link_hash_table_free (obfd
);
479 /* Create a LoongArch ELF linker hash table. */
481 static struct bfd_link_hash_table
*
482 loongarch_elf_link_hash_table_create (bfd
*abfd
)
484 struct loongarch_elf_link_hash_table
*ret
;
485 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
487 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
491 if (!_bfd_elf_link_hash_table_init
492 (&ret
->elf
, abfd
, link_hash_newfunc
,
493 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
499 ret
->max_alignment
= MINUS_ONE
;
501 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
502 elfNN_loongarch_local_htab_eq
, NULL
);
503 ret
->loc_hash_memory
= objalloc_create ();
504 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
506 elfNN_loongarch_link_hash_table_free (abfd
);
509 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
511 return &ret
->elf
.root
;
514 /* Merge backend specific data from an object file to the output
515 object file when linking. */
518 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
520 bfd
*obfd
= info
->output_bfd
;
521 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
522 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
524 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
527 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
529 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
530 "the selected emulation:\n"
531 " target emulation `%s' does not match `%s'"),
532 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
536 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
539 /* If the input BFD is not a dynamic object and it does not contain any
540 non-data sections, do not account its ABI. For example, various
541 packages produces such data-only relocatable objects with
542 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
543 But they are compatible with all ABIs. */
544 if (!(ibfd
->flags
& DYNAMIC
))
547 bool have_code_sections
= false;
548 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
549 if ((bfd_section_flags (sec
)
550 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
551 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
553 have_code_sections
= true;
556 if (!have_code_sections
)
560 if (!elf_flags_init (obfd
))
562 elf_flags_init (obfd
) = true;
563 elf_elfheader (obfd
)->e_flags
= in_flags
;
566 else if (out_flags
!= in_flags
)
568 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags
)
569 && EF_LOONGARCH_IS_OBJ_V1 (in_flags
))
570 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags
)
571 && EF_LOONGARCH_IS_OBJ_V1 (out_flags
)))
573 elf_elfheader (obfd
)->e_flags
|= EF_LOONGARCH_OBJABI_V1
;
574 out_flags
= elf_elfheader (obfd
)->e_flags
;
575 in_flags
= out_flags
;
579 /* Disallow linking different ABIs. */
580 /* Only check relocation version.
581 The obj_v0 is compatible with obj_v1. */
582 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
584 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
591 bfd_set_error (bfd_error_bad_value
);
595 /* Create the .got section. */
598 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
603 struct elf_link_hash_entry
*h
;
604 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
605 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
607 /* This function may be called more than once. */
608 if (htab
->sgot
!= NULL
)
611 flags
= bed
->dynamic_sec_flags
;
612 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
613 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
615 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
619 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
620 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
624 /* The first bit of the global offset table is the header. */
625 s
->size
+= bed
->got_header_size
;
627 if (bed
->want_got_plt
)
629 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
630 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
634 /* Reserve room for the header. */
635 s
->size
= GOTPLT_HEADER_SIZE
;
638 if (bed
->want_got_sym
)
640 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
641 section. We don't do this in the linker script because we don't want
642 to define the symbol if we are not creating a global offset table. */
643 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
644 "_GLOBAL_OFFSET_TABLE_");
645 elf_hash_table (info
)->hgot
= h
;
652 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
653 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
657 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
659 struct loongarch_elf_link_hash_table
*htab
;
661 htab
= loongarch_elf_hash_table (info
);
662 BFD_ASSERT (htab
!= NULL
);
664 if (!loongarch_elf_create_got_section (dynobj
, info
))
667 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
670 if (!bfd_link_pic (info
))
672 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
673 SEC_ALLOC
| SEC_THREAD_LOCAL
);
675 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
676 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
683 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
684 struct bfd_link_info
*info
,
685 struct elf_link_hash_entry
*h
,
686 unsigned long symndx
,
689 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
690 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
692 /* This is a global offset table entry for a local symbol. */
693 if (elf_local_got_refcounts (abfd
) == NULL
)
696 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
697 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
699 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
700 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
710 if (htab
->elf
.sgot
== NULL
711 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
715 if (h
->got
.refcount
< 0)
720 elf_local_got_refcounts (abfd
)[symndx
]++;
723 /* No need for GOT. */
726 _bfd_error_handler (_("Internal error: unreachable."));
730 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
731 *new_tls_type
|= tls_type
;
733 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
734 if ((*new_tls_type
& GOT_TLS_IE
) && (*new_tls_type
& GOT_TLS_GDESC
))
735 *new_tls_type
&= ~ (GOT_TLS_GDESC
);
736 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
738 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
739 "thread local symbol"),
741 h
? h
->root
.root
.string
: "<local>");
749 loongarch_reloc_got_type (unsigned int r_type
)
753 case R_LARCH_TLS_DESC_PC_HI20
:
754 case R_LARCH_TLS_DESC_PC_LO12
:
755 case R_LARCH_TLS_DESC_LD
:
756 case R_LARCH_TLS_DESC_CALL
:
757 return GOT_TLS_GDESC
;
759 case R_LARCH_TLS_IE_PC_HI20
:
760 case R_LARCH_TLS_IE_PC_LO12
:
769 /* Return true if tls type transition can be performed. */
771 loongarch_can_trans_tls (bfd
*input_bfd
,
772 struct bfd_link_info
*info
,
773 struct elf_link_hash_entry
*h
,
774 unsigned int r_symndx
,
777 char symbol_tls_type
;
778 unsigned int reloc_got_type
;
780 /* Only TLS DESC/IE in normal code mode will perform type
782 if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type
))
785 /* Obtaining tls got type here may occur before
786 loongarch_elf_record_tls_and_got_reference, so it is necessary
787 to ensure that tls got type has been initialized, otherwise it
788 is set to GOT_UNKNOWN. */
789 symbol_tls_type
= GOT_UNKNOWN
;
790 if (_bfd_loongarch_elf_local_got_tls_type (input_bfd
) || h
)
791 symbol_tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
793 reloc_got_type
= loongarch_reloc_got_type (r_type
);
795 if (symbol_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
798 if (! bfd_link_executable (info
))
801 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
807 /* The type of relocation that can be transitioned. */
809 loongarch_tls_transition_without_check (struct bfd_link_info
*info
,
811 struct elf_link_hash_entry
*h
)
813 bool local_exec
= bfd_link_executable (info
)
814 && LARCH_REF_LOCAL (info
, h
);
818 case R_LARCH_TLS_DESC_PC_HI20
:
820 ? R_LARCH_TLS_LE_HI20
821 : R_LARCH_TLS_IE_PC_HI20
);
823 case R_LARCH_TLS_DESC_PC_LO12
:
825 ? R_LARCH_TLS_LE_LO12
826 : R_LARCH_TLS_IE_PC_LO12
);
828 case R_LARCH_TLS_DESC_LD
:
829 case R_LARCH_TLS_DESC_CALL
:
832 case R_LARCH_TLS_IE_PC_HI20
:
833 return local_exec
? R_LARCH_TLS_LE_HI20
: r_type
;
835 case R_LARCH_TLS_IE_PC_LO12
:
836 return local_exec
? R_LARCH_TLS_LE_LO12
: r_type
;
846 loongarch_tls_transition (bfd
*input_bfd
,
847 struct bfd_link_info
*info
,
848 struct elf_link_hash_entry
*h
,
849 unsigned int r_symndx
,
852 if (! loongarch_can_trans_tls (input_bfd
, info
, h
, r_symndx
, r_type
))
855 return loongarch_tls_transition_without_check (info
, r_type
, h
);
859 bad_static_reloc (struct bfd_link_info
*info
,
860 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
861 asection
*sec
, unsigned r_type
,
862 struct elf_link_hash_entry
*h
,
863 Elf_Internal_Sym
*isym
)
865 reloc_howto_type
* r
= loongarch_elf_rtype_to_howto (abfd
, r_type
);
868 const char *name
= NULL
;
871 name
= h
->root
.root
.string
;
873 name
= bfd_elf_string_from_elf_section (abfd
,
874 elf_symtab_hdr (abfd
).sh_link
,
876 if (name
== NULL
|| *name
== '\0')
879 if (bfd_link_dll (info
))
881 object
= _("a shared object");
882 pic
= _("; recompile with -fPIC");
886 if (bfd_link_pie (info
))
887 object
= _("a PIE object");
889 object
= _("a PDE object");
890 pic
= _("; recompile with -fPIE");
893 (*_bfd_error_handler
)
894 (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
896 abfd
, sec
, (long) rel
->r_offset
, r
? r
->name
: _("<unknown>"), name
, object
, pic
);
897 bfd_set_error (bfd_error_bad_value
);
901 /* Look through the relocs for a section during the first phase, and
902 allocate space in the global offset table or procedure linkage
906 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
907 asection
*sec
, const Elf_Internal_Rela
*relocs
)
909 struct loongarch_elf_link_hash_table
*htab
;
910 Elf_Internal_Shdr
*symtab_hdr
;
911 struct elf_link_hash_entry
**sym_hashes
;
912 const Elf_Internal_Rela
*rel
;
913 asection
*sreloc
= NULL
;
915 if (bfd_link_relocatable (info
))
918 htab
= loongarch_elf_hash_table (info
);
919 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
920 sym_hashes
= elf_sym_hashes (abfd
);
922 if (htab
->elf
.dynobj
== NULL
)
923 htab
->elf
.dynobj
= abfd
;
925 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
928 unsigned int r_symndx
;
929 struct elf_link_hash_entry
*h
;
930 bool is_abs_symbol
= false;
931 Elf_Internal_Sym
*isym
= NULL
;
933 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
934 r_type
= ELFNN_R_TYPE (rel
->r_info
);
936 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
938 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
942 if (r_symndx
< symtab_hdr
->sh_info
)
944 /* A local symbol. */
945 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
949 is_abs_symbol
= isym
->st_shndx
== SHN_ABS
;
950 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
952 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
956 h
->type
= STT_GNU_IFUNC
;
964 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
965 while (h
->root
.type
== bfd_link_hash_indirect
966 || h
->root
.type
== bfd_link_hash_warning
)
967 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
968 is_abs_symbol
= bfd_is_abs_symbol (&h
->root
);
971 /* It is referenced by a non-shared object. */
975 if (h
&& h
->type
== STT_GNU_IFUNC
)
977 if (htab
->elf
.dynobj
== NULL
)
978 htab
->elf
.dynobj
= abfd
;
980 /* Create 'irelifunc' in PIC object. */
981 if (bfd_link_pic (info
)
982 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
984 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
985 else if (!htab
->elf
.splt
986 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
988 /* Create the ifunc sections, iplt and ipltgot, for static
990 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
991 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
994 if (h
->plt
.refcount
< 0)
999 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
1002 int need_dynreloc
= 0;
1003 int only_need_pcrel
= 0;
1005 /* Type transitions are only possible with relocations accompanied
1006 by R_LARCH_RELAX. */
1007 if (rel
+ 1 != relocs
+ sec
->reloc_count
1008 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
)
1009 r_type
= loongarch_tls_transition (abfd
, info
, h
, r_symndx
, r_type
);
1011 /* I don't want to spend time supporting DT_RELR with old object
1012 files doing stack-based relocs. */
1013 if (info
->enable_dt_relr
1014 && r_type
>= R_LARCH_SOP_PUSH_PCREL
1015 && r_type
<= R_LARCH_SOP_POP_32_U
)
1017 /* xgettext:c-format */
1018 _bfd_error_handler (_("%pB: stack based reloc type (%u) is not "
1019 "supported with -z pack-relative-relocs"),
1026 case R_LARCH_GOT_PC_HI20
:
1027 case R_LARCH_GOT_HI20
:
1028 case R_LARCH_SOP_PUSH_GPREL
:
1029 /* For la.global. */
1031 h
->pointer_equality_needed
= 1;
1032 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1038 case R_LARCH_TLS_LD_PC_HI20
:
1039 case R_LARCH_TLS_LD_HI20
:
1040 case R_LARCH_TLS_GD_PC_HI20
:
1041 case R_LARCH_TLS_GD_HI20
:
1042 case R_LARCH_SOP_PUSH_TLS_GD
:
1043 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1049 case R_LARCH_TLS_IE_PC_HI20
:
1050 case R_LARCH_TLS_IE_HI20
:
1051 case R_LARCH_SOP_PUSH_TLS_GOT
:
1052 if (bfd_link_pic (info
))
1053 /* May fail for lazy-bind. */
1054 info
->flags
|= DF_STATIC_TLS
;
1056 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1062 case R_LARCH_TLS_LE_HI20
:
1063 case R_LARCH_TLS_LE_HI20_R
:
1064 case R_LARCH_SOP_PUSH_TLS_TPREL
:
1065 if (!bfd_link_executable (info
))
1066 return bad_static_reloc (info
, abfd
, rel
, sec
, r_type
, h
, isym
);
1068 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1074 case R_LARCH_TLS_DESC_PC_HI20
:
1075 case R_LARCH_TLS_DESC_HI20
:
1076 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
1082 case R_LARCH_ABS_HI20
:
1083 if (bfd_link_pic (info
))
1084 return bad_static_reloc (info
, abfd
, rel
, sec
, r_type
, h
, isym
);
1087 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1089 /* If this reloc is in a read-only section, we might
1090 need a copy reloc. We can't check reliably at this
1091 stage whether the section is read-only, as input
1092 sections have not yet been mapped to output sections.
1093 Tentatively set the flag for now, and correct in
1094 adjust_dynamic_symbol. */
1098 /* Since shared library global symbols interpose, any
1099 PC-relative relocations against external symbols
1100 should not be used to build shared libraries. */
1101 case R_LARCH_PCREL20_S2
:
1102 if (bfd_link_pic (info
)
1103 && (sec
->flags
& SEC_ALLOC
) != 0
1104 && (sec
->flags
& SEC_READONLY
) != 0
1105 && ! LARCH_REF_LOCAL (info
, h
))
1106 return bad_static_reloc (info
, abfd
, rel
, sec
, r_type
, h
, NULL
);
1110 /* For normal cmodel, pcalau12i + addi.d/w used to data.
1111 For first version medium cmodel, pcalau12i + jirl are used to
1112 function call, it need to creat PLT entry for STT_FUNC and
1113 STT_GNU_IFUNC type symbol. */
1114 case R_LARCH_PCALA_HI20
:
1115 if (h
!= NULL
&& (STT_FUNC
== h
->type
|| STT_GNU_IFUNC
== h
->type
))
1117 /* For pcalau12i + jirl. */
1119 if (h
->plt
.refcount
< 0)
1120 h
->plt
.refcount
= 0;
1124 h
->pointer_equality_needed
= 1;
1127 /* PC-relative relocations are allowed For first version
1128 medium cmodel function call. */
1129 if (h
!= NULL
&& !h
->needs_plt
1130 && bfd_link_pic (info
)
1131 && (sec
->flags
& SEC_ALLOC
) != 0
1132 && (sec
->flags
& SEC_READONLY
) != 0
1133 && ! LARCH_REF_LOCAL (info
, h
))
1134 return bad_static_reloc (info
, abfd
, rel
, sec
, r_type
, h
, NULL
);
1141 case R_LARCH_CALL36
:
1145 if (!bfd_link_pic (info
))
1148 /* We try to create PLT stub for all non-local function. */
1149 if (h
->plt
.refcount
< 0)
1150 h
->plt
.refcount
= 0;
1156 case R_LARCH_SOP_PUSH_PCREL
:
1159 if (!bfd_link_pic (info
))
1162 /* We try to create PLT stub for all non-local function. */
1163 if (h
->plt
.refcount
< 0)
1164 h
->plt
.refcount
= 0;
1166 h
->pointer_equality_needed
= 1;
1171 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1172 /* This symbol requires a procedure linkage table entry. We
1173 actually build the entry in adjust_dynamic_symbol,
1174 because this might be a case of linking PIC code without
1175 linking in any dynamic objects, in which case we don't
1176 need to generate a procedure linkage table after all. */
1180 if (h
->plt
.refcount
< 0)
1181 h
->plt
.refcount
= 0;
1186 case R_LARCH_TLS_DTPREL32
:
1187 case R_LARCH_TLS_DTPREL64
:
1189 only_need_pcrel
= 1;
1194 && bfd_link_pic (info
)
1195 && (sec
->flags
& SEC_ALLOC
) != 0)
1200 (_("%pB: relocation R_LARCH_32 against non-absolute "
1201 "symbol `%s' cannot be used in ELFCLASS64 when "
1202 "making a shared object or PIE"),
1203 abfd
, h
? h
->root
.root
.string
: "a local symbol");
1204 bfd_set_error (bfd_error_bad_value
);
1210 case R_LARCH_JUMP_SLOT
:
1213 /* Resolved to const. */
1219 /* If resolved symbol is defined in this object,
1220 1. Under pie, the symbol is known. We convert it
1221 into R_LARCH_RELATIVE and need load-addr still.
1222 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
1223 3. Under dll, R_LARCH_NN can't be changed normally, since
1224 its defination could be covered by the one in executable.
1225 For symbolic, we convert it into R_LARCH_RELATIVE.
1226 Thus, only under pde, it needs pcrel only. We discard it. */
1227 only_need_pcrel
= bfd_link_pde (info
);
1230 && (!bfd_link_pic (info
)
1231 || h
->type
== STT_GNU_IFUNC
))
1233 /* This reloc might not bind locally. */
1235 h
->pointer_equality_needed
= 1;
1238 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
1240 /* We may need a .plt entry if the symbol is a function
1241 defined in a shared lib or is a function referenced
1242 from the code or read-only section. */
1243 h
->plt
.refcount
+= 1;
1248 case R_LARCH_GNU_VTINHERIT
:
1249 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1253 case R_LARCH_GNU_VTENTRY
:
1254 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1259 /* Check against irrational R_LARCH_ALIGN relocs which may cause
1260 removing an odd number of bytes and disrupt DT_RELR. */
1261 if (rel
->r_offset
% 4 != 0)
1263 /* xgettext:c-format */
1264 _bfd_error_handler (
1265 _("%pB: R_LARCH_ALIGN with offset %" PRId64
" not aligned "
1266 "to instruction boundary"),
1267 abfd
, (uint64_t) rel
->r_offset
);
1276 /* Record some info for sizing and allocating dynamic entry. */
1277 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
1279 /* When creating a shared object, we must copy these
1280 relocs into the output file. We create a reloc
1281 section in dynobj and make room for the reloc. */
1282 struct elf_dyn_relocs
*p
;
1283 struct elf_dyn_relocs
**head
;
1288 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
1289 LARCH_ELF_LOG_WORD_BYTES
,
1290 abfd
, /*rela?*/ true);
1295 /* If this is a global symbol, we count the number of
1296 relocations we need for this symbol. */
1298 head
= &h
->dyn_relocs
;
1301 /* Track dynamic relocs needed for local syms too.
1302 We really need local syms available to do this
1308 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1312 vpp
= &elf_section_data (s
)->local_dynrel
;
1313 head
= (struct elf_dyn_relocs
**) vpp
;
1317 if (p
== NULL
|| p
->sec
!= sec
)
1319 bfd_size_type amt
= sizeof *p
;
1320 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
1331 p
->pc_count
+= only_need_pcrel
;
1338 /* Find dynamic relocs for H that apply to read-only sections. */
1341 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
1343 struct elf_dyn_relocs
*p
;
1345 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1347 asection
*s
= p
->sec
->output_section
;
1349 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
1355 /* Adjust a symbol defined by a dynamic object and referenced by a
1356 regular object. The current definition is in some section of the
1357 dynamic object, but we're not including those sections. We have to
1358 change the definition to something the rest of the link can
1361 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
1362 struct elf_link_hash_entry
*h
)
1364 struct loongarch_elf_link_hash_table
*htab
;
1367 htab
= loongarch_elf_hash_table (info
);
1368 BFD_ASSERT (htab
!= NULL
);
1370 dynobj
= htab
->elf
.dynobj
;
1372 /* Make sure we know what is going on here. */
1373 BFD_ASSERT (dynobj
!= NULL
1375 || h
->type
== STT_GNU_IFUNC
1379 && !h
->def_regular
)));
1381 /* If this is a function, put it in the procedure linkage table. We
1382 will fill in the contents of the procedure linkage table later
1383 (although we could actually do it here). */
1384 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
1386 if (h
->plt
.refcount
<= 0
1387 || (h
->type
!= STT_GNU_IFUNC
1388 && (LARCH_REF_LOCAL (info
, h
)
1389 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1390 && h
->root
.type
== bfd_link_hash_undefweak
))))
1392 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1393 in an input file, but the symbol was never referred to by a
1394 dynamic object, or if all references were garbage collected.
1395 In such a case, we don't actually need to build a PLT entry. */
1396 h
->plt
.offset
= MINUS_ONE
;
1403 h
->plt
.offset
= MINUS_ONE
;
1405 /* If this is a weak symbol, and there is a real definition, the
1406 processor independent code will have arranged for us to see the
1407 real definition first, and we can just use the same value. */
1408 if (h
->is_weakalias
)
1410 struct elf_link_hash_entry
*def
= weakdef (h
);
1411 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
1412 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
1413 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
1417 /* R_LARCH_COPY is not adept glibc, not to generate. */
1418 /* Can not print anything, because make check ld. */
1422 /* Allocate space in .plt, .got and associated reloc sections for
1426 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1428 struct bfd_link_info
*info
;
1429 struct loongarch_elf_link_hash_table
*htab
;
1430 struct elf_dyn_relocs
*p
;
1432 if (h
->root
.type
== bfd_link_hash_indirect
)
1435 if (h
->type
== STT_GNU_IFUNC
1439 info
= (struct bfd_link_info
*) inf
;
1440 htab
= loongarch_elf_hash_table (info
);
1441 bool dyn
= htab
->elf
.dynamic_sections_created
;
1442 BFD_ASSERT (htab
!= NULL
);
1446 asection
*plt
, *gotplt
, *relplt
;
1455 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1456 && h
->root
.type
== bfd_link_hash_undefweak
)
1458 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1462 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1463 && h
->type
!= STT_GNU_IFUNC
)
1466 plt
= htab
->elf
.splt
;
1467 gotplt
= htab
->elf
.sgotplt
;
1468 relplt
= htab
->elf
.srelplt
;
1470 else if (htab
->elf
.iplt
)
1472 /* .iplt only for IFUNC. */
1473 if (h
->type
!= STT_GNU_IFUNC
)
1476 plt
= htab
->elf
.iplt
;
1477 gotplt
= htab
->elf
.igotplt
;
1478 relplt
= htab
->elf
.irelplt
;
1484 plt
->size
= PLT_HEADER_SIZE
;
1486 h
->plt
.offset
= plt
->size
;
1487 plt
->size
+= PLT_ENTRY_SIZE
;
1488 gotplt
->size
+= GOT_ENTRY_SIZE
;
1489 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1491 /* If this symbol is not defined in a regular file, and we are
1492 not generating a shared library, then set the symbol to this
1493 location in the .plt. This is required to make function
1494 pointers compare as equal between the normal executable and
1495 the shared library. */
1496 if (!bfd_link_pic (info
)
1499 h
->root
.u
.def
.section
= plt
;
1500 h
->root
.u
.def
.value
= h
->plt
.offset
;
1508 h
->plt
.offset
= MINUS_ONE
;
1510 if (0 < h
->got
.refcount
)
1513 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1515 /* Make sure this symbol is output as a dynamic symbol.
1516 Undefined weak syms won't yet be marked as dynamic. */
1517 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1518 && h
->root
.type
== bfd_link_hash_undefweak
)
1520 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1525 h
->got
.offset
= s
->size
;
1526 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1529 bool need_reloc
= false;
1530 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, dyn
, h
, indx
,
1532 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1533 if (tls_type
& GOT_TLS_GD
)
1535 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1537 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1540 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1541 if (tls_type
& GOT_TLS_IE
)
1543 s
->size
+= GOT_ENTRY_SIZE
;
1545 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1548 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1549 if (tls_type
& GOT_TLS_GDESC
)
1551 s
->size
+= GOT_ENTRY_SIZE
* 2;
1552 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1558 s
->size
+= GOT_ENTRY_SIZE
;
1559 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1560 || h
->root
.type
!= bfd_link_hash_undefweak
)
1561 && (bfd_link_pic (info
)
1562 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
),
1564 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1565 /* Undefined weak symbol in static PIE resolves to 0 without
1566 any dynamic relocations. */
1567 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1571 h
->got
.offset
= MINUS_ONE
;
1573 if (h
->dyn_relocs
== NULL
)
1576 /* Extra dynamic relocate,
1578 * R_LARCH_TLS_DTPRELNN
1582 if (SYMBOL_CALLS_LOCAL (info
, h
))
1584 struct elf_dyn_relocs
**pp
;
1586 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1588 p
->count
-= p
->pc_count
;
1597 if (h
->root
.type
== bfd_link_hash_undefweak
)
1599 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
)
1600 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1601 || (!bfd_link_pic (info
) && h
->non_got_ref
))
1602 h
->dyn_relocs
= NULL
;
1603 else if (h
->dynindx
== -1 && !h
->forced_local
)
1605 /* Make sure this symbol is output as a dynamic symbol.
1606 Undefined weak syms won't yet be marked as dynamic. */
1607 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1610 if (h
->dynindx
== -1)
1611 h
->dyn_relocs
= NULL
;
1615 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1617 if (discarded_section (p
->sec
))
1619 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1620 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1626 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1627 For local def and ref ifunc,
1628 dynamic relocations are stored in
1629 1. rela.srelgot section in dynamic object (dll or exec).
1630 2. rela.irelplt section in static executable.
1631 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1632 instead of rela.srelplt. Glibc ELF loader will not support
1633 R_LARCH_IRELATIVE relocation in rela.plt. */
1636 local_allocate_ifunc_dyn_relocs (struct bfd_link_info
*info
,
1637 struct elf_link_hash_entry
*h
,
1638 struct elf_dyn_relocs
**head
,
1639 unsigned int plt_entry_size
,
1640 unsigned int plt_header_size
,
1641 unsigned int got_entry_size
,
1644 asection
*plt
, *gotplt
, *relplt
;
1645 struct elf_dyn_relocs
*p
;
1646 unsigned int sizeof_reloc
;
1647 const struct elf_backend_data
*bed
;
1648 struct elf_link_hash_table
*htab
;
1649 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1650 bool use_plt
= !avoid_plt
|| h
->plt
.refcount
> 0;
1651 bool need_dynreloc
= !use_plt
|| bfd_link_pic (info
);
1653 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1654 in executable or it isn't referenced via PLT, the address of
1655 the resolved function may be used. But in non-PIC executable,
1656 the address of its plt slot may be used. Pointer equality may
1657 not work correctly. PIE or non-PLT reference should be used if
1658 pointer equality is required here.
1660 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1661 backend should change it to the normal function and set its address
1662 to its PLT entry which should be resolved by R_*_IRELATIVE at
1663 run-time. All external references should be resolved to its PLT in
1666 && !(bfd_link_pde (info
) && h
->def_regular
)
1667 && (h
->dynindx
!= -1
1668 || info
->export_dynamic
)
1669 && h
->pointer_equality_needed
)
1671 info
->callbacks
->einfo
1672 /* xgettext:c-format. */
1673 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1674 "equality in `%pB' can not be used when making an "
1675 "executable; recompile with -fPIE and relink with -pie\n"),
1676 h
->root
.root
.string
,
1677 h
->root
.u
.def
.section
->owner
);
1678 bfd_set_error (bfd_error_bad_value
);
1682 htab
= elf_hash_table (info
);
1684 /* When the symbol is marked with regular reference, if PLT isn't used
1685 or we are building a PIC object, we must keep dynamic relocation
1686 if there is non-GOT reference and use PLT if there is PC-relative
1688 if (need_dynreloc
&& h
->ref_regular
)
1691 for (p
= *head
; p
!= NULL
; p
= p
->next
)
1695 /* Need dynamic relocations for non-GOT reference. */
1699 /* Must use PLT for PC-relative reference. */
1701 need_dynreloc
= bfd_link_pic (info
);
1709 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1710 if (h
->plt
.refcount
<= 0 && h
->got
.refcount
<= 0)
1712 h
->got
= htab
->init_got_offset
;
1713 h
->plt
= htab
->init_plt_offset
;
1718 /* Return and discard space for dynamic relocations against it if
1719 it is never referenced. */
1720 if (!h
->ref_regular
)
1722 if (h
->plt
.refcount
> 0
1723 || h
->got
.refcount
> 0)
1725 h
->got
= htab
->init_got_offset
;
1726 h
->plt
= htab
->init_plt_offset
;
1732 bed
= get_elf_backend_data (info
->output_bfd
);
1733 if (bed
->rela_plts_and_copies_p
)
1734 sizeof_reloc
= bed
->s
->sizeof_rela
;
1736 sizeof_reloc
= bed
->s
->sizeof_rel
;
1738 /* When building a static executable, use iplt, igot.plt and
1739 rela.iplt sections for STT_GNU_IFUNC symbols. */
1740 if (htab
->splt
!= NULL
)
1743 gotplt
= htab
->sgotplt
;
1744 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1745 relplt
= htab
->srelgot
;
1747 /* If this is the first plt entry and PLT is used, make room for
1748 the special first entry. */
1749 if (plt
->size
== 0 && use_plt
)
1750 plt
->size
+= plt_header_size
;
1755 gotplt
= htab
->igotplt
;
1756 relplt
= htab
->irelplt
;
1761 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1762 the original value for R_*_IRELATIVE. */
1763 h
->plt
.offset
= plt
->size
;
1765 /* Make room for this entry in the plt/iplt section. */
1766 plt
->size
+= plt_entry_size
;
1768 /* We also need to make an entry in the got.plt/got.iplt section,
1769 which will be placed in the got section by the linker script. */
1770 gotplt
->size
+= got_entry_size
;
1773 /* We also need to make an entry in the rela.plt/.rela.iplt
1774 section for GOTPLT relocation if PLT is used. */
1777 relplt
->size
+= sizeof_reloc
;
1778 relplt
->reloc_count
++;
1781 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1782 there is a non-GOT reference in a PIC object or PLT isn't used. */
1783 if (!need_dynreloc
|| !h
->non_got_ref
)
1786 /* Finally, allocate space. */
1790 bfd_size_type count
= 0;
1798 htab
->ifunc_resolvers
= count
!= 0;
1800 /* Dynamic relocations are stored in
1801 1. rela.srelgot section in PIC object.
1802 2. rela.srelgot section in dynamic executable.
1803 3. rela.irelplt section in static executable. */
1804 if (htab
->splt
!= NULL
)
1805 htab
->srelgot
->size
+= count
* sizeof_reloc
;
1808 relplt
->size
+= count
* sizeof_reloc
;
1809 relplt
->reloc_count
+= count
;
1813 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1814 and got has the PLT entry adddress. We will load the GOT entry
1815 with the PLT entry in finish_dynamic_symbol if it is used. For
1816 branch, it uses got.plt. For symbol value, if PLT is used,
1817 1. Use got.plt in a PIC object if it is forced local or not
1819 2. Use got.plt in a non-PIC object if pointer equality isn't
1821 3. Use got.plt in PIE.
1822 4. Use got.plt if got isn't used.
1823 5. Otherwise use got so that it can be shared among different
1824 objects at run-time.
1825 If PLT isn't used, always use got for symbol value.
1826 We only need to relocate got entry in PIC object or in dynamic
1827 executable without PLT. */
1829 && (h
->got
.refcount
<= 0
1830 || (bfd_link_pic (info
)
1831 && (h
->dynindx
== -1
1832 || h
->forced_local
))
1834 !h
->pointer_equality_needed
)
1835 || htab
->sgot
== NULL
))
1838 h
->got
.offset
= (bfd_vma
) -1;
1844 /* PLT isn't used. */
1845 h
->plt
.offset
= (bfd_vma
) -1;
1847 if (h
->got
.refcount
<= 0)
1849 /* GOT isn't need when there are only relocations for static
1851 h
->got
.offset
= (bfd_vma
) -1;
1855 h
->got
.offset
= htab
->sgot
->size
;
1856 htab
->sgot
->size
+= got_entry_size
;
1857 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1858 used. Otherwise, the GOT entry will be filled with the PLT
1859 entry and dynamic GOT relocation isn't needed. */
1862 /* For non-static executable, dynamic GOT relocation is in
1863 rela.got section, but for static executable, it is
1864 in rela.iplt section. */
1865 if (htab
->splt
!= NULL
)
1866 htab
->srelgot
->size
+= sizeof_reloc
;
1869 relplt
->size
+= sizeof_reloc
;
1870 relplt
->reloc_count
++;
1879 /* Allocate space in .plt, .got and associated reloc sections for
1880 ifunc dynamic relocs. */
1883 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
1884 struct bfd_link_info
*info
,
1887 /* An example of a bfd_link_hash_indirect symbol is versioned
1888 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1889 -> __gxx_personality_v0(bfd_link_hash_defined)
1891 There is no need to process bfd_link_hash_indirect symbols here
1892 because we will also be presented with the concrete instance of
1893 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1894 called to copy all relevant data from the generic to the concrete
1896 if (h
->root
.type
== bfd_link_hash_indirect
)
1899 if (h
->root
.type
== bfd_link_hash_warning
)
1900 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1902 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1903 here if it is defined and referenced in a non-shared object. */
1904 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
1906 if (ref_local
&& LARCH_REF_LOCAL (info
, h
))
1907 return local_allocate_ifunc_dyn_relocs (info
, h
,
1913 else if (!ref_local
&& !LARCH_REF_LOCAL (info
, h
))
1914 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1926 elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry
*h
,
1929 return elfNN_allocate_ifunc_dynrelocs (h
, (struct bfd_link_info
*) info
,
1934 elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry
*h
,
1937 return elfNN_allocate_ifunc_dynrelocs (h
, (struct bfd_link_info
*) info
,
1941 /* Allocate space in .plt, .got and associated reloc sections for
1942 ifunc dynamic relocs. */
1945 elfNN_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
1947 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1949 if (h
->type
!= STT_GNU_IFUNC
1953 || h
->root
.type
!= bfd_link_hash_defined
)
1956 return elfNN_allocate_ifunc_dynrelocs_ref_local (h
, inf
);
1959 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1960 read-only sections. */
1963 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1967 if (h
->root
.type
== bfd_link_hash_indirect
)
1970 sec
= readonly_dynrelocs (h
);
1973 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1975 info
->flags
|= DF_TEXTREL
;
1976 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1977 "read-only section `%pA'\n"),
1978 sec
->owner
, h
->root
.root
.string
, sec
);
1980 /* Not an error, just cut short the traversal. */
1987 record_relr (struct loongarch_elf_link_hash_table
*htab
, asection
*sec
,
1988 bfd_vma off
, asection
*sreloc
)
1990 struct relr_entry
**sec_relr
= &loongarch_elf_section_data (sec
)->relr
;
1992 /* Undo the relocation section size accounting. */
1993 BFD_ASSERT (sreloc
->size
>= sizeof (ElfNN_External_Rela
));
1994 sreloc
->size
-= sizeof (ElfNN_External_Rela
);
1996 BFD_ASSERT (off
% 2 == 0 && sec
->alignment_power
> 0);
1997 if (htab
->relr_count
>= htab
->relr_alloc
)
1999 if (htab
->relr_alloc
== 0)
2000 htab
->relr_alloc
= 4096;
2002 htab
->relr_alloc
*= 2;
2004 htab
->relr
= bfd_realloc (htab
->relr
,
2005 htab
->relr_alloc
* sizeof (*htab
->relr
));
2009 htab
->relr
[htab
->relr_count
].sec
= sec
;
2010 htab
->relr
[htab
->relr_count
].off
= off
;
2011 if (*sec_relr
== NULL
)
2012 *sec_relr
= &htab
->relr
[htab
->relr_count
];
2018 record_relr_local_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
)
2020 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
2021 char *local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (input_bfd
);
2022 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2023 struct loongarch_elf_link_hash_table
*htab
=
2024 loongarch_elf_hash_table (info
);
2026 if (!local_got_offsets
|| !local_tls_type
|| !bfd_link_pic (info
))
2029 for (unsigned i
= 0; i
< symtab_hdr
->sh_info
; i
++)
2031 bfd_vma off
= local_got_offsets
[i
];
2033 /* FIXME: If the local symbol is in SHN_ABS then emitting
2034 a relative relocation is not correct, but it seems to be wrong
2035 in loongarch_elf_relocate_section too. */
2036 if (local_tls_type
[i
] == GOT_NORMAL
2037 && !record_relr (htab
, htab
->elf
.sgot
, off
, htab
->elf
.srelgot
))
2045 record_relr_dyn_got_relocs (struct elf_link_hash_entry
*h
, void *inf
)
2047 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
2048 struct loongarch_elf_link_hash_table
*htab
=
2049 loongarch_elf_hash_table (info
);
2051 if (h
->root
.type
== bfd_link_hash_indirect
)
2053 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
2055 if (h
->got
.refcount
<= 0)
2057 if (loongarch_elf_hash_entry (h
)->tls_type
2058 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
2060 if (!bfd_link_pic (info
))
2063 /* On LoongArch a GOT entry for undefined weak symbol is never relocated
2064 with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus
2065 the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or
2066 relocated with R_LARCH_NN (otherwise). */
2067 if (h
->root
.type
== bfd_link_hash_undefweak
)
2070 if (!LARCH_REF_LOCAL (info
, h
))
2072 if (bfd_is_abs_symbol (&h
->root
))
2075 if (!record_relr (htab
, htab
->elf
.sgot
, h
->got
.offset
,
2083 record_relr_non_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
,
2087 struct loongarch_elf_link_hash_table
*htab
;
2088 Elf_Internal_Rela
*relocs
, *rel
, *rel_end
;
2089 Elf_Internal_Shdr
*symtab_hdr
;
2090 struct elf_link_hash_entry
**sym_hashes
;
2092 if (!bfd_link_pic (info
))
2094 if (sec
->reloc_count
== 0)
2096 if ((sec
->flags
& (SEC_RELOC
| SEC_ALLOC
| SEC_DEBUGGING
))
2097 != (SEC_RELOC
| SEC_ALLOC
))
2099 if (sec
->alignment_power
== 0)
2101 if (discarded_section (sec
))
2104 sreloc
= elf_section_data (sec
)->sreloc
;
2108 htab
= loongarch_elf_hash_table (info
);
2109 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2110 sym_hashes
= elf_sym_hashes (input_bfd
);
2111 relocs
= _bfd_elf_link_info_read_relocs (input_bfd
, info
, sec
, NULL
,
2112 NULL
, info
->keep_memory
);
2113 BFD_ASSERT (relocs
!= NULL
);
2114 rel_end
= relocs
+ sec
->reloc_count
;
2115 for (rel
= relocs
; rel
< rel_end
; rel
++)
2117 unsigned r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2118 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
2119 struct elf_link_hash_entry
*h
= NULL
;
2120 asection
*def_sec
= NULL
;
2122 if ((r_type
!= R_LARCH_64
&& r_type
!= R_LARCH_32
)
2123 || rel
->r_offset
% 2 != 0)
2126 /* The logical below must match loongarch_elf_relocate_section. */
2127 if (r_symndx
< symtab_hdr
->sh_info
)
2129 /* A local symbol. */
2130 Elf_Internal_Sym
*isym
;
2131 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, input_bfd
,
2133 BFD_ASSERT(isym
!= NULL
);
2135 /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for
2136 R_LARCH_NN, not R_LARCH_RELATIVE. */
2137 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
2139 def_sec
= bfd_section_from_elf_index (input_bfd
, isym
->st_shndx
);
2143 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2144 while (h
->root
.type
== bfd_link_hash_indirect
2145 || h
->root
.type
== bfd_link_hash_warning
)
2146 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2148 /* Filter out symbols that cannot have a relative reloc. */
2149 if (h
->dyn_relocs
== NULL
)
2151 if (bfd_is_abs_symbol (&h
->root
))
2153 if (h
->type
== STT_GNU_IFUNC
)
2156 if (h
->root
.type
== bfd_link_hash_defined
2157 || h
->root
.type
== bfd_link_hash_defweak
)
2158 def_sec
= h
->root
.u
.def
.section
;
2160 /* On LoongArch an R_LARCH_NN against undefined weak symbol
2161 is never converted to R_LARCH_RELATIVE: we don't have
2162 -z dynamic-undefined-weak, thus the reloc is either removed
2163 (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */
2164 if (h
->root
.type
== bfd_link_hash_undefweak
)
2167 if (!LARCH_REF_LOCAL (info
, h
))
2171 if (!def_sec
|| discarded_section (def_sec
))
2174 if (!record_relr (htab
, sec
, rel
->r_offset
, sreloc
))
2182 cmp_relr_addr (const void *p
, const void *q
)
2184 const bfd_vma
*a
= p
, *b
= q
;
2185 return (*a
> *b
) - (*a
< *b
);
2189 sort_relr (struct bfd_link_info
*info
,
2190 struct loongarch_elf_link_hash_table
*htab
)
2192 if (htab
->relr_count
== 0)
2195 bfd_vma
*addr
= htab
->relr_sorted
;
2198 addr
= bfd_malloc (htab
->relr_count
* sizeof (*addr
));
2201 htab
->relr_sorted
= addr
;
2204 for (bfd_size_type i
= 0; i
< htab
->relr_count
; i
++)
2206 bfd_vma off
= _bfd_elf_section_offset (info
->output_bfd
, info
,
2209 addr
[i
] = htab
->relr
[i
].sec
->output_section
->vma
2210 + htab
->relr
[i
].sec
->output_offset
+ off
;
2212 qsort(addr
, htab
->relr_count
, sizeof (*addr
), cmp_relr_addr
);
2217 loongarch_elf_size_relative_relocs (struct bfd_link_info
*info
,
2220 struct loongarch_elf_link_hash_table
*htab
=
2221 loongarch_elf_hash_table (info
);
2222 asection
*srelrdyn
= htab
->elf
.srelrdyn
;
2224 *need_layout
= false;
2226 if (!sort_relr (info
, htab
))
2228 bfd_vma
*addr
= htab
->relr_sorted
;
2230 BFD_ASSERT (srelrdyn
!= NULL
);
2231 bfd_size_type oldsize
= srelrdyn
->size
;
2233 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
2235 bfd_vma base
= addr
[i
];
2237 srelrdyn
->size
+= NN
/ 8;
2241 bfd_size_type start_i
= i
;
2242 while (i
< htab
->relr_count
2243 && addr
[i
] - base
< (NN
- 1) * (NN
/ 8)
2244 && (addr
[i
] - base
) % (NN
/ 8) == 0)
2248 srelrdyn
->size
+= NN
/ 8;
2249 base
+= (NN
- 1) * (NN
/ 8);
2252 if (srelrdyn
->size
!= oldsize
)
2254 *need_layout
= true;
2255 /* Stop after a few iterations in case the layout does not converge,
2256 but we can only stop when the size would shrink (and pad the
2257 spare space with 1. */
2258 if (htab
->relr_layout_iter
++ > 5 && srelrdyn
->size
< oldsize
)
2260 srelrdyn
->size
= oldsize
;
2261 *need_layout
= false;
2265 htab
->layout_mutating_for_relr
= *need_layout
;
2270 loongarch_elf_finish_relative_relocs (struct bfd_link_info
*info
)
2272 struct loongarch_elf_link_hash_table
*htab
=
2273 loongarch_elf_hash_table (info
);
2274 asection
*srelrdyn
= htab
->elf
.srelrdyn
;
2275 bfd
*dynobj
= htab
->elf
.dynobj
;
2277 if (!srelrdyn
|| srelrdyn
->size
== 0)
2280 srelrdyn
->contents
= bfd_alloc (dynobj
, srelrdyn
->size
);
2281 if (!srelrdyn
->contents
)
2284 bfd_vma
*addr
= htab
->relr_sorted
;
2285 bfd_byte
*loc
= srelrdyn
->contents
;
2286 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
2288 bfd_vma base
= addr
[i
];
2290 bfd_put_NN (dynobj
, base
, loc
);
2296 while (i
< htab
->relr_count
)
2298 bfd_vma delta
= addr
[i
] - base
;
2299 if (delta
>= (NN
- 1) * (NN
/ 8) || delta
% (NN
/ 8) != 0)
2301 bits
|= (uintNN_t
) 1 << (delta
/ (NN
/ 8));
2306 bfd_put_NN (dynobj
, (bits
<< 1) | 1, loc
);
2308 base
+= (NN
- 1) * (NN
/ 8);
2313 htab
->relr_sorted
= NULL
;
2315 /* Pad any excess with 1's, a do-nothing encoding. */
2316 while (loc
< srelrdyn
->contents
+ srelrdyn
->size
)
2318 bfd_put_NN (dynobj
, 1, loc
);
2326 loongarch_elf_late_size_sections (bfd
*output_bfd
,
2327 struct bfd_link_info
*info
)
2329 struct loongarch_elf_link_hash_table
*htab
;
2334 htab
= loongarch_elf_hash_table (info
);
2335 BFD_ASSERT (htab
!= NULL
);
2336 dynobj
= htab
->elf
.dynobj
;
2340 if (htab
->elf
.dynamic_sections_created
)
2342 /* Set the contents of the .interp section to the interpreter. */
2343 if (bfd_link_executable (info
) && !info
->nointerp
)
2345 const char *interpreter
;
2346 s
= bfd_get_linker_section (dynobj
, ".interp");
2347 BFD_ASSERT (s
!= NULL
);
2349 if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS32
)
2350 interpreter
= "/lib32/ld.so.1";
2351 else if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS64
)
2352 interpreter
= "/lib64/ld.so.1";
2354 interpreter
= "/lib/ld.so.1";
2356 s
->contents
= (unsigned char *) interpreter
;
2357 s
->size
= strlen (interpreter
) + 1;
2361 /* Set up .got offsets for local syms, and space for local dynamic
2363 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2365 bfd_signed_vma
*local_got
;
2366 bfd_signed_vma
*end_local_got
;
2367 char *local_tls_type
;
2368 bfd_size_type locsymcount
;
2369 Elf_Internal_Shdr
*symtab_hdr
;
2372 if (!is_loongarch_elf (ibfd
))
2375 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2377 struct elf_dyn_relocs
*p
;
2379 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
2381 p
->count
-= p
->pc_count
;
2382 if (!bfd_is_abs_section (p
->sec
)
2383 && bfd_is_abs_section (p
->sec
->output_section
))
2385 /* Input section has been discarded, either because
2386 it is a copy of a linkonce section or due to
2387 linker script /DISCARD/, so we'll be discarding
2390 else if (0 < p
->count
)
2392 srel
= elf_section_data (p
->sec
)->sreloc
;
2393 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
2394 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
2395 info
->flags
|= DF_TEXTREL
;
2400 local_got
= elf_local_got_refcounts (ibfd
);
2404 symtab_hdr
= &elf_symtab_hdr (ibfd
);
2405 locsymcount
= symtab_hdr
->sh_info
;
2406 end_local_got
= local_got
+ locsymcount
;
2407 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
2409 srel
= htab
->elf
.srelgot
;
2410 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
2414 *local_got
= s
->size
;
2415 if (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
2417 /* TLS gd use two got. */
2418 if (*local_tls_type
& GOT_TLS_GD
)
2420 s
->size
+= 2 * GOT_ENTRY_SIZE
;
2421 if (!bfd_link_executable (info
))
2422 srel
->size
+= sizeof (ElfNN_External_Rela
);
2425 /* TLS_DESC use two got. */
2426 if (*local_tls_type
& GOT_TLS_GDESC
)
2428 s
->size
+= 2 * GOT_ENTRY_SIZE
;
2429 srel
->size
+= sizeof (ElfNN_External_Rela
);
2432 /* TLS ie and use one got. */
2433 if (*local_tls_type
& GOT_TLS_IE
)
2435 s
->size
+= GOT_ENTRY_SIZE
;
2436 if (!bfd_link_executable (info
))
2437 srel
->size
+= sizeof (ElfNN_External_Rela
);
2442 s
->size
+= GOT_ENTRY_SIZE
;
2443 srel
->size
+= sizeof (ElfNN_External_Rela
);
2447 *local_got
= MINUS_ONE
;
2451 /* Allocate global sym .plt and .got entries, and space for global
2452 sym dynamic relocs. */
2453 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
2455 /* Allocate global ifunc sym .plt and .got entries, and space for
2456 *preemptible* ifunc sym dynamic relocs. Note that we must do it
2457 for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN
2458 ifuncs) before doing it for any non-preemptible ifunc symbol:
2459 assuming we are not so careful, when we link a shared library the
2460 correlation of .plt and .rela.plt might look like:
2462 idx in .plt idx in .rela.plt
2466 hidden_ifunc1@plt 3 None: it's in .rela.got
2467 hidden_ifunc2@plt 4 None: it's in .rela.got
2468 normal_ifunc1@plt 5 != 3
2469 normal_ifunc2@plt 6 != 4
2470 local_ifunc@plt 7 None: it's in .rela.got
2472 Now oops the indices for normal_ifunc{1,2} in .rela.plt were different
2473 from the indices in .plt :(. This would break finish_dynamic_symbol
2474 which assumes the index in .rela.plt matches the index in .plt.
2476 So let's be careful and make it correct:
2478 idx in .plt idx in .rela.plt
2482 normal_ifunc1@plt 3 3
2483 normal_ifunc2@plt 4 4
2484 hidden_ifunc1@plt 5 None: it's in .rela.got
2485 hidden_ifunc2@plt 6 None: it's in .rela.got
2486 local_ifunc@plt 7 None: it's in .rela.got
2488 Now normal_ifuncs first. */
2489 elf_link_hash_traverse (&htab
->elf
,
2490 elfNN_allocate_ifunc_dynrelocs_ref_global
, info
);
2492 /* Next hidden_ifuncs follows. */
2493 elf_link_hash_traverse (&htab
->elf
,
2494 elfNN_allocate_ifunc_dynrelocs_ref_local
, info
);
2496 /* Finally local_ifuncs. */
2497 htab_traverse (htab
->loc_hash_table
,
2498 elfNN_allocate_local_ifunc_dynrelocs
, info
);
2500 /* Don't allocate .got.plt section if there are no PLT. */
2501 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
2502 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
2503 htab
->elf
.sgotplt
->size
= 0;
2505 if (info
->enable_dt_relr
&& !bfd_link_relocatable (info
))
2507 elf_link_hash_traverse (&htab
->elf
, record_relr_dyn_got_relocs
, info
);
2509 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2511 if (!is_loongarch_elf (ibfd
))
2514 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2515 if (!record_relr_non_got_relocs (ibfd
, info
, s
))
2518 if (!record_relr_local_got_relocs (ibfd
, info
))
2523 /* The check_relocs and adjust_dynamic_symbol entry points have
2524 determined the sizes of the various dynamic sections. Allocate
2526 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2528 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
2531 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
2532 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
2533 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
2535 /* Strip this section if we don't need it; see the
2538 else if (strncmp (s
->name
, ".rela", 5) == 0)
2542 /* We use the reloc_count field as a counter if we need
2543 to copy relocs into the output file. */
2547 else if (s
== htab
->elf
.srelrdyn
&& htab
->relr_count
== 0)
2549 /* Remove .relr.dyn based on relr_count, not size, since
2550 it is not sized yet. */
2551 s
->flags
|= SEC_EXCLUDE
;
2552 /* Allocate contents later. */
2557 /* It's not one of our sections. */
2563 /* If we don't need this section, strip it from the
2564 output file. This is mostly to handle .rela.bss and
2565 .rela.plt. We must create both sections in
2566 create_dynamic_sections, because they must be created
2567 before the linker maps input sections to output
2568 sections. The linker does that before
2569 adjust_dynamic_symbol is called, and it is that
2570 function which decides whether anything needs to go
2571 into these sections. */
2572 s
->flags
|= SEC_EXCLUDE
;
2576 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
2579 /* Allocate memory for the section contents. Zero the memory
2580 for the benefit of .rela.plt, which has 4 unused entries
2581 at the beginning, and we don't want garbage. */
2582 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
2583 if (s
->contents
== NULL
)
2587 if (elf_hash_table (info
)->dynamic_sections_created
)
2589 /* Add some entries to the .dynamic section. We fill in the
2590 values later, in loongarch_elf_finish_dynamic_sections, but we
2591 must add the entries now so that we get the correct size for
2592 the .dynamic section. The DT_DEBUG entry is filled in by the
2593 dynamic linker and used by the debugger. */
2594 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2596 if (bfd_link_executable (info
))
2598 if (!add_dynamic_entry (DT_DEBUG
, 0))
2602 if (htab
->elf
.srelplt
->size
!= 0)
2604 if (!add_dynamic_entry (DT_PLTGOT
, 0)
2605 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
2606 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2607 || !add_dynamic_entry (DT_JMPREL
, 0))
2611 if (!add_dynamic_entry (DT_RELA
, 0)
2612 || !add_dynamic_entry (DT_RELASZ
, 0)
2613 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2616 /* If any dynamic relocs apply to a read-only section,
2617 then we need a DT_TEXTREL entry. */
2618 if ((info
->flags
& DF_TEXTREL
) == 0)
2619 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
2621 if (info
->flags
& DF_TEXTREL
)
2623 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2625 /* Clear the DF_TEXTREL flag. It will be set again if we
2626 write out an actual text relocation; we may not, because
2627 at this point we do not know whether e.g. any .eh_frame
2628 absolute relocations have been converted to PC-relative. */
2629 info
->flags
&= ~DF_TEXTREL
;
2632 #undef add_dynamic_entry
2637 #define LARCH_LD_STACK_DEPTH 16
2638 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
2639 static size_t larch_stack_top
= 0;
2641 static bfd_reloc_status_type
2642 loongarch_push (int64_t val
)
2644 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
2645 return bfd_reloc_outofrange
;
2646 larch_opc_stack
[larch_stack_top
++] = val
;
2647 return bfd_reloc_ok
;
2650 static bfd_reloc_status_type
2651 loongarch_pop (int64_t *val
)
2653 if (larch_stack_top
== 0)
2654 return bfd_reloc_outofrange
;
2656 *val
= larch_opc_stack
[--larch_stack_top
];
2657 return bfd_reloc_ok
;
2660 static bfd_reloc_status_type
2661 loongarch_top (int64_t *val
)
2663 if (larch_stack_top
== 0)
2664 return bfd_reloc_outofrange
;
2666 *val
= larch_opc_stack
[larch_stack_top
- 1];
2667 return bfd_reloc_ok
;
2671 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
2673 BFD_ASSERT (s
&& s
->contents
);
2674 const struct elf_backend_data
*bed
;
2677 bed
= get_elf_backend_data (abfd
);
2678 if (!(s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
))
2679 BFD_ASSERT (s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
);
2680 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
2681 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
2684 /* Check rel->r_offset in range of contents. */
2685 static bfd_reloc_status_type
2686 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
2687 const asection
*input_section
)
2689 if (0 == strcmp(input_section
->name
, ".text")
2690 && rel
->r_offset
> input_section
->size
)
2691 return bfd_reloc_overflow
;
2693 return bfd_reloc_ok
;
2696 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2698 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2699 if (ret == bfd_reloc_ok) \
2701 ret = loongarch_pop (&op1); \
2702 if (ret == bfd_reloc_ok) \
2703 ret = loongarch_push (op3); \
2708 /* Write immediate to instructions. */
2710 static bfd_reloc_status_type
2711 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
2712 const asection
*input_section ATTRIBUTE_UNUSED
,
2713 reloc_howto_type
*howto
, bfd
*input_bfd
,
2714 bfd_byte
*contents
, bfd_vma reloc_val
)
2716 /* Adjust the immediate based on alignment and
2717 its position in the instruction. */
2718 if (!loongarch_adjust_reloc_bitsfield (input_bfd
, howto
, &reloc_val
))
2719 return bfd_reloc_overflow
;
2721 int bits
= bfd_get_reloc_size (howto
) * 8;
2722 uint64_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
2724 /* Write immediate to instruction. */
2725 insn
= (insn
& ~howto
->dst_mask
) | (reloc_val
& howto
->dst_mask
);
2727 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
2729 return bfd_reloc_ok
;
2732 static bfd_reloc_status_type
2733 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
2734 reloc_howto_type
*howto
, bfd_vma value
,
2735 bfd
*input_bfd
, bfd_byte
*contents
)
2737 int64_t opr1
, opr2
, opr3
;
2738 bfd_reloc_status_type r
= bfd_reloc_ok
;
2739 int bits
= bfd_get_reloc_size (howto
) * 8;
2741 switch (ELFNN_R_TYPE (rel
->r_info
))
2743 case R_LARCH_SOP_PUSH_PCREL
:
2744 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2745 case R_LARCH_SOP_PUSH_GPREL
:
2746 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2747 case R_LARCH_SOP_PUSH_TLS_GOT
:
2748 case R_LARCH_SOP_PUSH_TLS_GD
:
2749 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2750 r
= loongarch_push (value
);
2753 case R_LARCH_SOP_PUSH_DUP
:
2754 r
= loongarch_pop (&opr1
);
2755 if (r
== bfd_reloc_ok
)
2757 r
= loongarch_push (opr1
);
2758 if (r
== bfd_reloc_ok
)
2759 r
= loongarch_push (opr1
);
2763 case R_LARCH_SOP_ASSERT
:
2764 r
= loongarch_pop (&opr1
);
2765 if (r
!= bfd_reloc_ok
|| !opr1
)
2766 r
= bfd_reloc_notsupported
;
2769 case R_LARCH_SOP_NOT
:
2770 r
= loongarch_pop (&opr1
);
2771 if (r
== bfd_reloc_ok
)
2772 r
= loongarch_push (!opr1
);
2775 case R_LARCH_SOP_SUB
:
2776 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
2779 case R_LARCH_SOP_SL
:
2780 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
2783 case R_LARCH_SOP_SR
:
2784 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
2787 case R_LARCH_SOP_AND
:
2788 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
2791 case R_LARCH_SOP_ADD
:
2792 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
2795 case R_LARCH_SOP_IF_ELSE
:
2796 r
= loongarch_pop (&opr3
);
2797 if (r
== bfd_reloc_ok
)
2799 r
= loongarch_pop (&opr2
);
2800 if (r
== bfd_reloc_ok
)
2802 r
= loongarch_pop (&opr1
);
2803 if (r
== bfd_reloc_ok
)
2804 r
= loongarch_push (opr1
? opr2
: opr3
);
2809 case R_LARCH_SOP_POP_32_S_10_5
:
2810 case R_LARCH_SOP_POP_32_S_10_12
:
2811 case R_LARCH_SOP_POP_32_S_10_16
:
2812 case R_LARCH_SOP_POP_32_S_10_16_S2
:
2813 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
2814 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
2815 case R_LARCH_SOP_POP_32_S_5_20
:
2816 case R_LARCH_SOP_POP_32_U_10_12
:
2817 case R_LARCH_SOP_POP_32_U
:
2818 r
= loongarch_pop (&opr1
);
2819 if (r
!= bfd_reloc_ok
)
2821 r
= loongarch_check_offset (rel
, input_section
);
2822 if (r
!= bfd_reloc_ok
)
2825 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2827 contents
, (bfd_vma
)opr1
);
2830 case R_LARCH_TLS_DTPREL32
:
2832 case R_LARCH_TLS_DTPREL64
:
2834 r
= loongarch_check_offset (rel
, input_section
);
2835 if (r
!= bfd_reloc_ok
)
2838 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
2841 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2842 Because set/sub reloc pair not support multi-thread. While add/sub
2843 reloc pair process order not affect the final result.
2845 For add/sub reloc, the original value will be involved in the
2846 calculation. In order not to add/sub extra value, we write 0 to symbol
2847 address at assembly time.
2849 add/sub reloc bits determined by the value after symbol subtraction,
2852 add/sub reloc save part of the symbol value, so we only need to
2853 save howto->dst_mask bits. */
2857 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2858 contents
+ rel
->r_offset
);
2859 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2860 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2865 /* Not need to read the original value, just write the new value. */
2877 /* Because add/sub reloc is processed separately,
2878 so the high bits is invalid. */
2879 bfd_vma word
= value
& howto
->dst_mask
;
2880 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2885 case R_LARCH_ADD_ULEB128
:
2886 case R_LARCH_SUB_ULEB128
:
2888 unsigned int len
= 0;
2889 /* Before write uleb128, first read it to get it's length. */
2890 _bfd_read_unsigned_leb128 (input_bfd
, contents
+ rel
->r_offset
, &len
);
2891 loongarch_write_unsigned_leb128 (contents
+ rel
->r_offset
, len
, value
);
2896 /* For eh_frame and debug info. */
2897 case R_LARCH_32_PCREL
:
2898 case R_LARCH_64_PCREL
:
2900 value
-= sec_addr (input_section
) + rel
->r_offset
;
2901 value
+= rel
->r_addend
;
2902 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2903 contents
+ rel
->r_offset
);
2904 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2905 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2911 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2915 case R_LARCH_ABS_HI20
:
2916 case R_LARCH_ABS_LO12
:
2917 case R_LARCH_ABS64_LO20
:
2918 case R_LARCH_ABS64_HI12
:
2919 case R_LARCH_PCALA_HI20
:
2920 case R_LARCH_PCALA_LO12
:
2921 case R_LARCH_PCALA64_LO20
:
2922 case R_LARCH_PCALA64_HI12
:
2923 case R_LARCH_GOT_PC_HI20
:
2924 case R_LARCH_GOT_PC_LO12
:
2925 case R_LARCH_GOT64_PC_LO20
:
2926 case R_LARCH_GOT64_PC_HI12
:
2927 case R_LARCH_GOT_HI20
:
2928 case R_LARCH_GOT_LO12
:
2929 case R_LARCH_GOT64_LO20
:
2930 case R_LARCH_GOT64_HI12
:
2931 case R_LARCH_TLS_LE_HI20
:
2932 case R_LARCH_TLS_LE_LO12
:
2933 case R_LARCH_TLS_LE_HI20_R
:
2934 case R_LARCH_TLS_LE_LO12_R
:
2935 case R_LARCH_TLS_LE64_LO20
:
2936 case R_LARCH_TLS_LE64_HI12
:
2937 case R_LARCH_TLS_IE_PC_HI20
:
2938 case R_LARCH_TLS_IE_PC_LO12
:
2939 case R_LARCH_TLS_IE64_PC_LO20
:
2940 case R_LARCH_TLS_IE64_PC_HI12
:
2941 case R_LARCH_TLS_IE_HI20
:
2942 case R_LARCH_TLS_IE_LO12
:
2943 case R_LARCH_TLS_IE64_LO20
:
2944 case R_LARCH_TLS_IE64_HI12
:
2945 case R_LARCH_TLS_LD_PC_HI20
:
2946 case R_LARCH_TLS_LD_HI20
:
2947 case R_LARCH_TLS_GD_PC_HI20
:
2948 case R_LARCH_TLS_GD_HI20
:
2949 case R_LARCH_PCREL20_S2
:
2950 case R_LARCH_CALL36
:
2951 case R_LARCH_TLS_DESC_PC_HI20
:
2952 case R_LARCH_TLS_DESC_PC_LO12
:
2953 case R_LARCH_TLS_DESC64_PC_LO20
:
2954 case R_LARCH_TLS_DESC64_PC_HI12
:
2955 case R_LARCH_TLS_DESC_HI20
:
2956 case R_LARCH_TLS_DESC_LO12
:
2957 case R_LARCH_TLS_DESC64_LO20
:
2958 case R_LARCH_TLS_DESC64_HI12
:
2959 case R_LARCH_TLS_LD_PCREL20_S2
:
2960 case R_LARCH_TLS_GD_PCREL20_S2
:
2961 case R_LARCH_TLS_DESC_PCREL20_S2
:
2962 r
= loongarch_check_offset (rel
, input_section
);
2963 if (r
!= bfd_reloc_ok
)
2966 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2971 case R_LARCH_TLS_DESC_LD
:
2972 case R_LARCH_TLS_DESC_CALL
:
2977 case R_LARCH_TLS_LE_ADD_R
:
2981 r
= bfd_reloc_notsupported
;
2986 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2994 Elf_Internal_Sym
*sym
;
2995 struct elf_link_hash_entry
*h
;
2998 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
2999 static size_t larch_reloc_queue_head
= 0;
3000 static size_t larch_reloc_queue_tail
= 0;
3003 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3004 Elf_Internal_Sym
*sym
)
3006 const char *ret
= NULL
;
3008 ret
= bfd_elf_string_from_elf_section (input_bfd
,
3009 elf_symtab_hdr (input_bfd
).sh_link
,
3012 ret
= h
->root
.root
.string
;
3014 if (ret
== NULL
|| *ret
== '\0')
3020 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
3021 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
3022 struct elf_link_hash_entry
*h
, bfd_vma addend
)
3024 if ((larch_reloc_queue_head
== 0
3025 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
3026 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
3027 larch_reloc_queue_head
=
3028 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
3029 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
3030 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
3031 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
3032 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
3033 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
3034 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
3035 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
3036 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
3037 larch_reloc_queue_tail
=
3038 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
3042 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
3044 size_t i
= larch_reloc_queue_head
;
3046 asection
*section
= NULL
;
3047 bfd_vma r_offset
= 0;
3049 p ("Dump relocate record:\n");
3050 p ("stack top\t\trelocation name\t\tsymbol");
3051 while (i
!= larch_reloc_queue_tail
)
3053 if (a_bfd
!= larch_reloc_queue
[i
].bfd
3054 || section
!= larch_reloc_queue
[i
].section
3055 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
3057 a_bfd
= larch_reloc_queue
[i
].bfd
;
3058 section
= larch_reloc_queue
[i
].section
;
3059 r_offset
= larch_reloc_queue
[i
].r_offset
;
3060 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
3061 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
3065 inited
= 1, p ("...\n");
3067 reloc_howto_type
*howto
=
3068 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
3069 larch_reloc_queue
[i
].r_type
);
3070 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
3071 howto
? howto
->name
: "<unknown reloc>",
3072 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
3073 larch_reloc_queue
[i
].sym
));
3075 long addend
= larch_reloc_queue
[i
].addend
;
3077 p (" - %ld", -addend
);
3078 else if (0 < addend
)
3079 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
3082 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
3085 "-- Record dump end --\n\n");
3089 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
3091 asection
*input_section
,
3092 Elf_Internal_Rela
*rel
,
3093 reloc_howto_type
*howto
,
3094 bfd_reloc_status_type rtype
,
3102 /* 'dangerous' means we do it but can't promise it's ok
3103 'unsupport' means out of ability of relocation type
3104 'undefined' means we can't deal with the undefined symbol. */
3105 case bfd_reloc_undefined
:
3106 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
3107 rel
->r_offset
, true);
3108 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3109 input_bfd
, input_section
, rel
->r_offset
,
3111 is_undefweak
? "[undefweak] " : "", name
, msg
);
3113 case bfd_reloc_dangerous
:
3114 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
3115 input_bfd
, input_section
, rel
->r_offset
,
3117 is_undefweak
? "[undefweak] " : "", name
, msg
);
3120 case bfd_reloc_notsupported
:
3121 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
3122 input_bfd
, input_section
, rel
->r_offset
,
3124 is_undefweak
? "[undefweak] " : "", name
, msg
);
3132 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
3133 hi20 immediate need to add 0x1.
3134 For example: pc 0x120000000, symbol 0x120000812
3135 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
3136 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
3137 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
3140 pcalau12i $t0, hi20 (0x1)
3141 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
3142 addi.d $t0, $t0, lo12 (0x812)
3143 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
3144 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
3146 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
3148 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
3149 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
3151 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3152 relocation = (relocation & ~(bfd_vma)0xfff) \
3153 - (pc & ~(bfd_vma)0xfff); \
3155 relocation += 0x1000; \
3158 /* Handle problems caused by symbol extensions in TLS LE, The processing
3159 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
3160 #define RELOCATE_TLS_TP32_HI20(relocation) \
3162 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
3164 relocation += 0x800; \
3165 relocation = relocation & ~(bfd_vma)0xfff; \
3168 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
3169 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
3171 lo12: 0x1812348ffff812 & 0xfff = 0x812
3172 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
3173 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
3176 pcalau12i $t1, hi20 (0x80000)
3177 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
3178 = 0x11000010000100 + 0xffffffff80000000
3180 addi.d $t0, $zero, lo12 (0x812)
3181 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
3182 lo20 need to sub 0x1)
3183 lu32i.d $t0, lo20 (0x71234)
3184 $t0 = {0x71234, 0xfffff812}
3186 lu52i.d $t0, hi12 (0x0)
3187 $t0 = {0x0, 0x71234fffff812}
3190 $t1 = 0x10ffff90000000 + 0x71234fffff812
3191 = 0x1812348ffff812. */
3192 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
3194 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
3195 relocation = (relocation & ~(bfd_vma)0xfff) \
3196 - ((pc) & ~(bfd_vma)0xfff); \
3198 relocation += (0x1000 - 0x100000000); \
3199 if (relocation & 0x80000000) \
3200 relocation += 0x100000000; \
3204 /* Compute the tp/dtp offset of a tls symbol.
3205 It is dtp offset in dynamic tls model (gd/ld) and tp
3206 offset in static tls model (ie/le). Both offsets are
3207 calculated the same way on LoongArch, so the same
3208 function is used. */
3210 tlsoff (struct bfd_link_info
*info
, bfd_vma addr
)
3212 /* If tls_sec is NULL, we should have signalled an error already. */
3213 if (elf_hash_table (info
)->tls_sec
== NULL
)
3215 return addr
- elf_hash_table (info
)->tls_sec
->vma
;
3219 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
3220 bfd
*input_bfd
, asection
*input_section
,
3221 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
3222 Elf_Internal_Sym
*local_syms
,
3223 asection
**local_sections
)
3225 Elf_Internal_Rela
*rel
;
3226 Elf_Internal_Rela
*relend
;
3228 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
3229 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3230 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
3231 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
3232 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
3233 bool is_pic
= bfd_link_pic (info
);
3234 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
3235 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
3236 asection
*got
= htab
->elf
.sgot
;
3238 relend
= relocs
+ input_section
->reloc_count
;
3239 for (rel
= relocs
; rel
< relend
; rel
++)
3241 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
3242 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3243 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
3244 reloc_howto_type
*howto
= NULL
;
3245 asection
*sec
= NULL
;
3246 Elf_Internal_Sym
*sym
= NULL
;
3247 struct elf_link_hash_entry
*h
= NULL
;
3249 bfd_reloc_status_type r
= bfd_reloc_ok
;
3250 bool is_ie
, is_desc
, is_undefweak
, unresolved_reloc
, defined_local
;
3251 bool resolved_local
, resolved_dynly
, resolved_to_const
;
3253 bfd_vma relocation
, off
, ie_off
, desc_off
;
3256 /* When an unrecognized relocation is encountered, which usually
3257 occurs when using a newer assembler but an older linker, an error
3258 should be reported instead of continuing to the next relocation. */
3259 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
3261 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
3263 if (r_type
== R_LARCH_GNU_VTINHERIT
|| r_type
== R_LARCH_GNU_VTENTRY
)
3266 /* This is a final link. */
3267 if (r_symndx
< symtab_hdr
->sh_info
)
3269 is_undefweak
= false;
3270 unresolved_reloc
= false;
3271 sym
= local_syms
+ r_symndx
;
3272 sec
= local_sections
[r_symndx
];
3273 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
3275 /* Relocate against local STT_GNU_IFUNC symbol. */
3276 if (!bfd_link_relocatable (info
)
3277 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
3279 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
3284 /* Set STT_GNU_IFUNC symbol value. */
3285 h
->root
.u
.def
.value
= sym
->st_value
;
3286 h
->root
.u
.def
.section
= sec
;
3288 defined_local
= true;
3289 resolved_local
= true;
3290 resolved_dynly
= false;
3291 resolved_to_const
= false;
3293 /* Calc in funtion elf_link_input_bfd,
3294 * if #define elf_backend_rela_normal to 1. */
3295 if (bfd_link_relocatable (info
)
3296 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3301 bool warned
, ignored
;
3303 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
3304 r_symndx
, symtab_hdr
, sym_hashes
,
3306 unresolved_reloc
, warned
, ignored
);
3307 /* Here means symbol isn't local symbol only and 'h != NULL'. */
3309 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
3310 symbol. And 'dynamic_undefined_weak' specify what to do when
3311 meeting undefweak. */
3313 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
3315 defined_local
= false;
3316 resolved_local
= false;
3317 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
3318 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
3319 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
3323 /* Symbol undefined offen means failed already. I don't know why
3324 'warned' here but I guess it want to continue relocating as if
3325 no error occures to find other errors as more as possible. */
3327 /* To avoid generating warning messages about truncated
3328 relocations, set the relocation's address to be the same as
3329 the start of this section. */
3330 relocation
= (input_section
->output_section
3331 ? input_section
->output_section
->vma
3334 defined_local
= relocation
!= 0;
3335 resolved_local
= defined_local
;
3336 resolved_to_const
= !resolved_local
;
3337 resolved_dynly
= false;
3341 defined_local
= !unresolved_reloc
&& !ignored
;
3343 defined_local
&& LARCH_REF_LOCAL (info
, h
);
3344 resolved_dynly
= !resolved_local
;
3345 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
3349 name
= loongarch_sym_name (input_bfd
, h
, sym
);
3351 if (sec
!= NULL
&& discarded_section (sec
))
3352 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
3353 1, relend
, howto
, 0, contents
);
3355 if (bfd_link_relocatable (info
))
3358 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
3359 from removed linkonce sections, or sections discarded by a linker
3360 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
3361 if (r_symndx
== STN_UNDEF
)
3363 defined_local
= false;
3364 resolved_local
= false;
3365 resolved_dynly
= false;
3366 resolved_to_const
= true;
3369 /* The ifunc reference generate plt. */
3370 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
3372 defined_local
= true;
3373 resolved_local
= true;
3374 resolved_dynly
= false;
3375 resolved_to_const
= false;
3376 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3379 unresolved_reloc
= resolved_dynly
;
3381 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
3383 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
3385 BFD_ASSERT (!resolved_local
|| defined_local
);
3391 case R_LARCH_MARK_PCREL
:
3392 case R_LARCH_MARK_LA
:
3394 r
= bfd_reloc_continue
;
3395 unresolved_reloc
= false;
3400 if (resolved_dynly
|| (is_pic
&& resolved_local
))
3402 Elf_Internal_Rela outrel
;
3404 /* When generating a shared object, these relocations are copied
3405 into the output file to be resolved at run time. */
3407 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
3411 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
3412 && (input_section
->flags
& SEC_ALLOC
));
3414 outrel
.r_offset
+= sec_addr (input_section
);
3416 /* A pointer point to a ifunc symbol. */
3417 if (h
&& h
->type
== STT_GNU_IFUNC
)
3419 if (h
->dynindx
== -1)
3421 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
3422 outrel
.r_addend
= (h
->root
.u
.def
.value
3423 + h
->root
.u
.def
.section
->output_section
->vma
3424 + h
->root
.u
.def
.section
->output_offset
);
3428 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
3429 outrel
.r_addend
= 0;
3432 if (LARCH_REF_LOCAL (info
, h
))
3435 if (htab
->elf
.splt
!= NULL
)
3436 sreloc
= htab
->elf
.srelgot
;
3438 sreloc
= htab
->elf
.irelplt
;
3443 if (bfd_link_pic (info
))
3444 sreloc
= htab
->elf
.irelifunc
;
3445 else if (htab
->elf
.splt
!= NULL
)
3446 sreloc
= htab
->elf
.srelgot
;
3448 sreloc
= htab
->elf
.irelplt
;
3451 else if (resolved_dynly
)
3453 if (h
->dynindx
== -1)
3454 outrel
.r_info
= ELFNN_R_INFO (0, r_type
);
3456 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
3458 outrel
.r_addend
= rel
->r_addend
;
3462 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3463 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3466 /* No alloc space of func allocate_dynrelocs.
3467 No alloc space of invalid R_LARCH_32 in ELFCLASS64. */
3468 if (unresolved_reloc
3469 && (ARCH_SIZE
== 32 || r_type
!= R_LARCH_32
)
3470 && !(h
&& (h
->is_weakalias
|| !h
->dyn_relocs
)))
3472 if (info
->enable_dt_relr
3473 && (ELFNN_R_TYPE (outrel
.r_info
) == R_LARCH_RELATIVE
)
3474 && input_section
->alignment_power
!= 0
3475 && rel
->r_offset
% 2 == 0)
3476 /* Don't emit a relative relocation that is packed,
3477 only apply the addend (as if we are applying the
3478 original R_LARCH_NN reloc in a PDE). */
3479 r
= perform_relocation (rel
, input_section
, howto
,
3480 relocation
, input_bfd
,
3483 loongarch_elf_append_rela (output_bfd
, sreloc
,
3488 relocation
+= rel
->r_addend
;
3498 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
3499 contents
+ rel
->r_offset
);
3500 relocation
= old_value
+ relocation
+ rel
->r_addend
;
3511 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
3512 contents
+ rel
->r_offset
);
3513 relocation
= old_value
- relocation
- rel
->r_addend
;
3517 case R_LARCH_ADD_ULEB128
:
3518 case R_LARCH_SUB_ULEB128
:
3520 /* Get the value and length of the uleb128 data. */
3521 unsigned int len
= 0;
3522 bfd_vma old_value
= _bfd_read_unsigned_leb128 (input_bfd
,
3523 contents
+ rel
->r_offset
, &len
);
3525 if (R_LARCH_ADD_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
3526 relocation
= old_value
+ relocation
+ rel
->r_addend
;
3527 else if (R_LARCH_SUB_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
3528 relocation
= old_value
- relocation
- rel
->r_addend
;
3530 bfd_vma mask
= (1 << (7 * len
)) - 1;
3535 case R_LARCH_TLS_DTPREL32
:
3536 case R_LARCH_TLS_DTPREL64
:
3539 Elf_Internal_Rela outrel
;
3541 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
3544 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
3545 && (input_section
->flags
& SEC_ALLOC
));
3546 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
3547 outrel
.r_offset
+= sec_addr (input_section
);
3548 outrel
.r_addend
= rel
->r_addend
;
3549 if (unresolved_reloc
)
3550 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
3554 if (resolved_to_const
)
3555 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
3557 bfd_reloc_notsupported
,
3562 if (!elf_hash_table (info
)->tls_sec
)
3564 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
3565 input_section
, rel
, howto
, bfd_reloc_notsupported
,
3566 is_undefweak
, name
, "TLS section not be created");
3569 relocation
= tlsoff (info
, relocation
);
3573 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
3574 input_section
, rel
, howto
, bfd_reloc_undefined
,
3576 "TLS LE just can be resolved local only.");
3581 case R_LARCH_SOP_PUSH_TLS_TPREL
:
3584 if (!elf_hash_table (info
)->tls_sec
)
3585 fatal
= (loongarch_reloc_is_fatal
3586 (info
, input_bfd
, input_section
, rel
, howto
,
3587 bfd_reloc_notsupported
, is_undefweak
, name
,
3588 "TLS section not be created"));
3590 relocation
= tlsoff (info
, relocation
);
3593 fatal
= (loongarch_reloc_is_fatal
3594 (info
, input_bfd
, input_section
, rel
, howto
,
3595 bfd_reloc_undefined
, is_undefweak
, name
,
3596 "TLS LE just can be resolved local only."));
3599 case R_LARCH_SOP_PUSH_ABSOLUTE
:
3603 fatal
= (loongarch_reloc_is_fatal
3604 (info
, input_bfd
, input_section
, rel
, howto
,
3605 bfd_reloc_dangerous
, is_undefweak
, name
,
3606 "Someone require us to resolve undefweak "
3607 "symbol dynamically. \n"
3608 "But this reloc can't be done. "
3609 "I think I can't throw error "
3611 "so I resolved it to 0. "
3612 "I suggest to re-compile with '-fpic'."));
3615 unresolved_reloc
= false;
3619 if (resolved_to_const
)
3621 relocation
+= rel
->r_addend
;
3627 fatal
= (loongarch_reloc_is_fatal
3628 (info
, input_bfd
, input_section
, rel
, howto
,
3629 bfd_reloc_notsupported
, is_undefweak
, name
,
3630 "Under PIC we don't know load address. Re-compile "
3637 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
3639 fatal
= (loongarch_reloc_is_fatal
3640 (info
, input_bfd
, input_section
, rel
, howto
,
3641 bfd_reloc_undefined
, is_undefweak
, name
,
3642 "Can't be resolved dynamically. Try to re-compile "
3647 if (rel
->r_addend
!= 0)
3649 fatal
= (loongarch_reloc_is_fatal
3650 (info
, input_bfd
, input_section
, rel
, howto
,
3651 bfd_reloc_notsupported
, is_undefweak
, name
,
3652 "Shouldn't be with r_addend."));
3656 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3657 unresolved_reloc
= false;
3663 relocation
+= rel
->r_addend
;
3669 case R_LARCH_SOP_PUSH_PCREL
:
3670 case R_LARCH_SOP_PUSH_PLT_PCREL
:
3671 unresolved_reloc
= false;
3679 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3682 fatal
= (loongarch_reloc_is_fatal
3683 (info
, input_bfd
, input_section
, rel
, howto
,
3684 bfd_reloc_dangerous
, is_undefweak
, name
,
3685 "Undefweak need to be resolved dynamically, "
3686 "but PLT stub doesn't represent."));
3691 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
3693 fatal
= (loongarch_reloc_is_fatal
3694 (info
, input_bfd
, input_section
, rel
, howto
,
3695 bfd_reloc_undefined
, is_undefweak
, name
,
3696 "PLT stub does not represent and "
3697 "symbol not defined."));
3703 else /* if (resolved_dynly) */
3705 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
3706 fatal
= (loongarch_reloc_is_fatal
3707 (info
, input_bfd
, input_section
, rel
, howto
,
3708 bfd_reloc_dangerous
, is_undefweak
, name
,
3709 "Internal: PLT stub doesn't represent. "
3710 "Resolve it with pcrel"));
3717 if ((i
& 1) == 0 && defined_local
)
3720 relocation
+= rel
->r_addend
;
3724 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
3726 if (rel
->r_addend
!= 0)
3728 fatal
= (loongarch_reloc_is_fatal
3729 (info
, input_bfd
, input_section
, rel
, howto
,
3730 bfd_reloc_notsupported
, is_undefweak
, name
,
3731 "PLT shouldn't be with r_addend."));
3734 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3740 case R_LARCH_SOP_PUSH_GPREL
:
3741 unresolved_reloc
= false;
3743 if (rel
->r_addend
!= 0)
3745 fatal
= (loongarch_reloc_is_fatal
3746 (info
, input_bfd
, input_section
, rel
, howto
,
3747 bfd_reloc_notsupported
, is_undefweak
, name
,
3748 "Shouldn't be with r_addend."));
3754 off
= h
->got
.offset
& (~1);
3756 if (h
->got
.offset
== MINUS_ONE
&& h
->type
!= STT_GNU_IFUNC
)
3758 fatal
= (loongarch_reloc_is_fatal
3759 (info
, input_bfd
, input_section
, rel
, howto
,
3760 bfd_reloc_notsupported
, is_undefweak
, name
,
3761 "Internal: GOT entry doesn't represent."));
3765 /* Hidden symbol not has .got entry, only .got.plt entry
3766 so gprel is (plt - got). */
3767 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3769 if (h
->plt
.offset
== (bfd_vma
) -1)
3774 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3775 off
= plt_index
* GOT_ENTRY_SIZE
;
3777 if (htab
->elf
.splt
!= NULL
)
3779 /* Section .plt header is 2 times of plt entry. */
3780 off
= sec_addr (htab
->elf
.sgotplt
) + off
3781 - sec_addr (htab
->elf
.sgot
);
3785 /* Section iplt not has plt header. */
3786 off
= sec_addr (htab
->elf
.igotplt
) + off
3787 - sec_addr (htab
->elf
.sgot
);
3791 if ((h
->got
.offset
& 1) == 0)
3793 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3794 bfd_link_pic (info
), h
)
3795 && ((bfd_link_pic (info
)
3796 && LARCH_REF_LOCAL (info
, h
))))
3798 /* This is actually a static link, or it is a
3799 -Bsymbolic link and the symbol is defined
3800 locally, or the symbol was forced to be local
3801 because of a version file. We must initialize
3802 this entry in the global offset table. Since the
3803 offset must always be a multiple of the word size,
3804 we use the least significant bit to record whether
3805 we have initialized it already.
3807 When doing a dynamic link, we create a rela.got
3808 relocation entry to initialize the value. This
3809 is done in the finish_dynamic_symbol routine. */
3813 fatal
= (loongarch_reloc_is_fatal
3814 (info
, input_bfd
, input_section
, rel
, howto
,
3815 bfd_reloc_dangerous
, is_undefweak
, name
,
3816 "Internal: here shouldn't dynamic."));
3819 if (!(defined_local
|| resolved_to_const
))
3821 fatal
= (loongarch_reloc_is_fatal
3822 (info
, input_bfd
, input_section
, rel
, howto
,
3823 bfd_reloc_undefined
, is_undefweak
, name
,
3829 Elf_Internal_Rela outrel
;
3830 /* We need to generate a R_LARCH_RELATIVE reloc
3831 for the dynamic linker. */
3832 s
= htab
->elf
.srelgot
;
3835 fatal
= loongarch_reloc_is_fatal
3837 input_section
, rel
, howto
,
3838 bfd_reloc_notsupported
, is_undefweak
, name
,
3839 "Internal: '.rel.got' not represent");
3843 outrel
.r_offset
= sec_addr (got
) + off
;
3844 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3845 outrel
.r_addend
= relocation
; /* Link-time addr. */
3846 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3848 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3854 if (!local_got_offsets
)
3856 fatal
= (loongarch_reloc_is_fatal
3857 (info
, input_bfd
, input_section
, rel
, howto
,
3858 bfd_reloc_notsupported
, is_undefweak
, name
,
3859 "Internal: local got offsets not reporesent."));
3863 off
= local_got_offsets
[r_symndx
] & (~1);
3865 if (local_got_offsets
[r_symndx
] == MINUS_ONE
)
3867 fatal
= (loongarch_reloc_is_fatal
3868 (info
, input_bfd
, input_section
, rel
, howto
,
3869 bfd_reloc_notsupported
, is_undefweak
, name
,
3870 "Internal: GOT entry doesn't represent."));
3874 /* The offset must always be a multiple of the word size.
3875 So, we can use the least significant bit to record
3876 whether we have already processed this entry. */
3877 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3882 Elf_Internal_Rela outrel
;
3883 /* We need to generate a R_LARCH_RELATIVE reloc
3884 for the dynamic linker. */
3885 s
= htab
->elf
.srelgot
;
3888 fatal
= (loongarch_reloc_is_fatal
3889 (info
, input_bfd
, input_section
, rel
, howto
,
3890 bfd_reloc_notsupported
, is_undefweak
, name
,
3891 "Internal: '.rel.got' not represent"));
3895 outrel
.r_offset
= sec_addr (got
) + off
;
3896 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3897 outrel
.r_addend
= relocation
; /* Link-time addr. */
3898 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3901 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3902 local_got_offsets
[r_symndx
] |= 1;
3909 case R_LARCH_SOP_PUSH_TLS_GOT
:
3910 case R_LARCH_SOP_PUSH_TLS_GD
:
3912 unresolved_reloc
= false;
3913 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
3916 bfd_vma got_off
= 0;
3919 got_off
= h
->got
.offset
;
3924 got_off
= local_got_offsets
[r_symndx
];
3925 local_got_offsets
[r_symndx
] |= 1;
3928 BFD_ASSERT (got_off
!= MINUS_ONE
);
3931 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3932 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3933 ie_off
= 2 * GOT_ENTRY_SIZE
;
3935 if ((got_off
& 1) == 0)
3937 Elf_Internal_Rela rela
;
3938 asection
*srel
= htab
->elf
.srelgot
;
3941 bool need_reloc
= false;
3942 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, is_dyn
, h
, indx
,
3945 if (tls_type
& GOT_TLS_GD
)
3949 /* Dynamic resolved Module ID. */
3950 rela
.r_offset
= sec_addr (got
) + got_off
;
3952 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_DTPMODNN
);
3953 bfd_put_NN (output_bfd
, 0, got
->contents
+ got_off
);
3954 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3958 /* Local symbol, tp offset has been known. */
3959 BFD_ASSERT (! unresolved_reloc
);
3960 bfd_put_NN (output_bfd
,
3961 tlsoff (info
, relocation
),
3962 (got
->contents
+ got_off
+ GOT_ENTRY_SIZE
));
3966 /* Dynamic resolved block offset. */
3967 bfd_put_NN (output_bfd
, 0,
3968 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3969 rela
.r_info
= ELFNN_R_INFO (indx
,
3970 R_LARCH_TLS_DTPRELNN
);
3971 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3972 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3977 /* In a static link or an executable link with the symbol
3978 binding locally. Mark it as belonging to module 1. */
3979 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3980 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
3981 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3984 if (tls_type
& GOT_TLS_IE
)
3988 bfd_put_NN (output_bfd
, 0,
3989 got
->contents
+ got_off
+ ie_off
);
3990 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3994 rela
.r_addend
= tlsoff (info
, relocation
);
3995 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_TPRELNN
);
3996 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
4000 /* In a static link or an executable link with the symbol
4001 binding locally, compute offset directly. */
4002 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
4003 got
->contents
+ got_off
+ ie_off
);
4008 relocation
= (got_off
& (~(bfd_vma
)1)) + (is_ie
? ie_off
: 0);
4012 /* New reloc types. */
4016 case R_LARCH_CALL36
:
4017 unresolved_reloc
= false;
4026 relocation
+= rel
->r_addend
;
4028 else if (resolved_dynly
)
4031 && (h
->plt
.offset
!= MINUS_ONE
4032 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
4033 && rel
->r_addend
== 0);
4034 if (h
&& h
->plt
.offset
== MINUS_ONE
4035 && ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
4038 relocation
+= rel
->r_addend
;
4041 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
4046 case R_LARCH_ABS_HI20
:
4047 case R_LARCH_ABS_LO12
:
4048 case R_LARCH_ABS64_LO20
:
4049 case R_LARCH_ABS64_HI12
:
4053 BFD_ASSERT (resolved_dynly
);
4057 else if (resolved_to_const
|| resolved_local
)
4059 relocation
+= rel
->r_addend
;
4061 else if (resolved_dynly
)
4063 unresolved_reloc
= false;
4064 BFD_ASSERT ((plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
)
4065 && rel
->r_addend
== 0);
4066 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4071 case R_LARCH_PCREL20_S2
:
4072 unresolved_reloc
= false;
4073 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4074 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4076 relocation
+= rel
->r_addend
;
4080 case R_LARCH_PCALA_HI20
:
4081 unresolved_reloc
= false;
4082 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4083 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4085 relocation
+= rel
->r_addend
;
4087 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4090 case R_LARCH_TLS_LE_HI20_R
:
4091 relocation
+= rel
->r_addend
;
4092 relocation
= tlsoff (info
, relocation
);
4093 RELOCATE_TLS_TP32_HI20 (relocation
);
4096 case R_LARCH_PCALA_LO12
:
4097 /* Not support if sym_addr in 2k page edge.
4098 pcalau12i pc_hi20 (sym_addr)
4099 ld.w/d pc_lo12 (sym_addr)
4100 ld.w/d pc_lo12 (sym_addr + x)
4102 can not calc correct address
4103 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
4105 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4106 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4108 relocation
+= rel
->r_addend
;
4110 /* For 2G jump, generate pcalau12i, jirl. */
4111 /* If use jirl, turns to R_LARCH_B16. */
4112 uint32_t insn
= bfd_get (32, input_bfd
, contents
+ rel
->r_offset
);
4113 if (LARCH_INSN_JIRL (insn
))
4115 relocation
&= 0xfff;
4116 /* Signed extend. */
4117 relocation
= (relocation
^ 0x800) - 0x800;
4119 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_B16
);
4120 howto
= loongarch_elf_rtype_to_howto (input_bfd
, R_LARCH_B16
);
4124 case R_LARCH_PCALA64_HI12
:
4127 case R_LARCH_PCALA64_LO20
:
4128 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
4129 relocation
= sec_addr (plt
) + h
->plt
.offset
;
4131 relocation
+= rel
->r_addend
;
4133 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4137 case R_LARCH_GOT_PC_HI20
:
4138 case R_LARCH_GOT_HI20
:
4139 /* Calc got offset. */
4141 unresolved_reloc
= false;
4142 BFD_ASSERT (rel
->r_addend
== 0);
4144 bfd_vma got_off
= 0;
4147 /* GOT ref or ifunc. */
4148 BFD_ASSERT (h
->got
.offset
!= MINUS_ONE
4149 || h
->type
== STT_GNU_IFUNC
);
4151 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
4152 /* Hidden symbol not has got entry,
4153 * only got.plt entry so it is (plt - got). */
4154 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
4157 if (htab
->elf
.splt
!= NULL
)
4159 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
)
4161 got_off
= sec_addr (htab
->elf
.sgotplt
)
4162 + GOTPLT_HEADER_SIZE
4163 + (idx
* GOT_ENTRY_SIZE
)
4164 - sec_addr (htab
->elf
.sgot
);
4168 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4169 got_off
= sec_addr (htab
->elf
.sgotplt
)
4170 + (idx
* GOT_ENTRY_SIZE
)
4171 - sec_addr (htab
->elf
.sgot
);
4175 if ((h
->got
.offset
& 1) == 0)
4177 /* We need to generate a R_LARCH_RELATIVE reloc once
4178 * in loongarch_elf_finish_dynamic_symbol or now,
4179 * call finish_dyn && nopic
4180 * or !call finish_dyn && pic. */
4181 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
4182 bfd_link_pic (info
),
4184 && !bfd_is_abs_section(h
->root
.u
.def
.section
)
4185 && bfd_link_pic (info
)
4186 && LARCH_REF_LOCAL (info
, h
)
4187 && !info
->enable_dt_relr
)
4189 Elf_Internal_Rela rela
;
4190 rela
.r_offset
= sec_addr (got
) + got_off
;
4191 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4192 rela
.r_addend
= relocation
;
4193 loongarch_elf_append_rela (output_bfd
,
4194 htab
->elf
.srelgot
, &rela
);
4197 bfd_put_NN (output_bfd
, relocation
,
4198 got
->contents
+ got_off
);
4203 BFD_ASSERT (local_got_offsets
4204 && local_got_offsets
[r_symndx
] != MINUS_ONE
);
4206 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
4207 if (sym
->st_shndx
!= SHN_ABS
4208 && (local_got_offsets
[r_symndx
] & 1) == 0)
4210 if (bfd_link_pic (info
) && !info
->enable_dt_relr
)
4212 Elf_Internal_Rela rela
;
4213 rela
.r_offset
= sec_addr (got
) + got_off
;
4214 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4215 rela
.r_addend
= relocation
;
4216 loongarch_elf_append_rela (output_bfd
,
4217 htab
->elf
.srelgot
, &rela
);
4219 local_got_offsets
[r_symndx
] |= 1;
4221 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ got_off
);
4224 relocation
= got_off
+ sec_addr (got
);
4227 if (r_type
== R_LARCH_GOT_PC_HI20
)
4228 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4232 case R_LARCH_GOT_PC_LO12
:
4233 case R_LARCH_GOT64_PC_LO20
:
4234 case R_LARCH_GOT64_PC_HI12
:
4235 case R_LARCH_GOT_LO12
:
4236 case R_LARCH_GOT64_LO20
:
4237 case R_LARCH_GOT64_HI12
:
4239 unresolved_reloc
= false;
4242 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
4244 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
4246 if (h
&& h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
4249 if (htab
->elf
.splt
!= NULL
)
4250 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4252 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4254 got_off
= sec_addr (htab
->elf
.sgotplt
)
4255 + GOTPLT_HEADER_SIZE
4256 + (idx
* GOT_ENTRY_SIZE
)
4257 - sec_addr (htab
->elf
.sgot
);
4260 relocation
= got_off
+ sec_addr (got
);
4263 if (r_type
== R_LARCH_GOT64_PC_HI12
)
4264 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4265 else if (r_type
== R_LARCH_GOT64_PC_LO20
)
4266 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4270 case R_LARCH_TLS_LE_HI20
:
4271 case R_LARCH_TLS_LE_LO12
:
4272 case R_LARCH_TLS_LE_LO12_R
:
4273 case R_LARCH_TLS_LE64_LO20
:
4274 case R_LARCH_TLS_LE64_HI12
:
4275 BFD_ASSERT (resolved_local
&& elf_hash_table (info
)->tls_sec
);
4277 relocation
+= rel
->r_addend
;
4278 relocation
= tlsoff (info
, relocation
);
4281 /* TLS IE LD/GD process separately is troublesome.
4282 When a symbol is both ie and LD/GD, h->got.off |= 1
4283 make only one type be relocated. We must use
4284 h->got.offset |= 1 and h->got.offset |= 2
4285 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
4286 (IE LD/GD and reusable GOT reloc) must change to
4287 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
4289 Now, LD and GD is both GOT_TLS_GD type, LD seems to
4291 case R_LARCH_TLS_IE_PC_HI20
:
4292 case R_LARCH_TLS_IE_HI20
:
4293 case R_LARCH_TLS_LD_PC_HI20
:
4294 case R_LARCH_TLS_LD_HI20
:
4295 case R_LARCH_TLS_GD_PC_HI20
:
4296 case R_LARCH_TLS_GD_HI20
:
4297 case R_LARCH_TLS_DESC_PC_HI20
:
4298 case R_LARCH_TLS_DESC_HI20
:
4299 case R_LARCH_TLS_LD_PCREL20_S2
:
4300 case R_LARCH_TLS_GD_PCREL20_S2
:
4301 case R_LARCH_TLS_DESC_PCREL20_S2
:
4302 BFD_ASSERT (rel
->r_addend
== 0);
4303 unresolved_reloc
= false;
4305 if (r_type
== R_LARCH_TLS_IE_PC_HI20
4306 || r_type
== R_LARCH_TLS_IE_HI20
)
4309 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
4310 || r_type
== R_LARCH_TLS_DESC_HI20
4311 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4314 bfd_vma got_off
= 0;
4317 got_off
= h
->got
.offset
;
4322 got_off
= local_got_offsets
[r_symndx
];
4323 local_got_offsets
[r_symndx
] |= 1;
4326 BFD_ASSERT (got_off
!= MINUS_ONE
);
4328 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4330 /* If a tls variable is accessed in multiple ways, GD uses
4331 the first two slots of GOT, desc follows with two slots,
4332 and IE uses one slot at the end. */
4334 if (tls_type
& GOT_TLS_GD
)
4335 off
+= 2 * GOT_ENTRY_SIZE
;
4337 if (tls_type
& GOT_TLS_GDESC
)
4338 off
+= 2 * GOT_ENTRY_SIZE
;
4341 if ((got_off
& 1) == 0)
4343 Elf_Internal_Rela rela
;
4344 asection
*relgot
= htab
->elf
.srelgot
;
4347 bool need_reloc
= false;
4348 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, is_dyn
, h
, indx
,
4351 if (tls_type
& GOT_TLS_GD
)
4355 /* Dynamic resolved Module ID. */
4356 rela
.r_offset
= sec_addr (got
) + got_off
;
4358 rela
.r_info
= ELFNN_R_INFO (indx
,R_LARCH_TLS_DTPMODNN
);
4359 bfd_put_NN (output_bfd
, 0, got
->contents
+ got_off
);
4360 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4364 /* Local symbol, tp offset has been known. */
4365 BFD_ASSERT (! unresolved_reloc
);
4366 bfd_put_NN (output_bfd
,
4367 tlsoff (info
, relocation
),
4368 (got
->contents
+ got_off
+ GOT_ENTRY_SIZE
));
4372 /* Dynamic resolved block offset. */
4373 bfd_put_NN (output_bfd
, 0,
4374 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
4375 rela
.r_info
= ELFNN_R_INFO (indx
,
4376 R_LARCH_TLS_DTPRELNN
);
4377 rela
.r_offset
+= GOT_ENTRY_SIZE
;
4378 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4383 /* In a static link or an executable link with the symbol
4384 binding locally. Mark it as belonging to module 1. */
4385 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
4386 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
4387 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
4390 if (tls_type
& GOT_TLS_GDESC
)
4392 /* Unless it is a static link, DESC always emits a
4393 dynamic relocation. */
4394 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
4395 rela
.r_offset
= sec_addr (got
) + got_off
+ desc_off
;
4398 rela
.r_addend
= tlsoff (info
, relocation
);
4400 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_DESCNN
);
4401 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4402 bfd_put_NN (output_bfd
, 0,
4403 got
->contents
+ got_off
+ desc_off
);
4405 if (tls_type
& GOT_TLS_IE
)
4409 bfd_put_NN (output_bfd
, 0,
4410 got
->contents
+ got_off
+ ie_off
);
4411 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
4415 rela
.r_addend
= tlsoff (info
, relocation
);
4416 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_TPRELNN
);
4417 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
4421 /* In a static link or an executable link with the symbol
4422 bindinglocally, compute offset directly. */
4423 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
4424 got
->contents
+ got_off
+ ie_off
);
4428 relocation
= (got_off
& (~(bfd_vma
)1)) + sec_addr (got
);
4430 relocation
+= desc_off
;
4432 relocation
+= ie_off
;
4434 if (r_type
== R_LARCH_TLS_LD_PC_HI20
4435 || r_type
== R_LARCH_TLS_GD_PC_HI20
4436 || r_type
== R_LARCH_TLS_IE_PC_HI20
4437 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
4438 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
4439 else if (r_type
== R_LARCH_TLS_LD_PCREL20_S2
4440 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
4441 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4443 /* else {} ABS relocations. */
4446 case R_LARCH_TLS_DESC_PC_LO12
:
4447 case R_LARCH_TLS_DESC64_PC_LO20
:
4448 case R_LARCH_TLS_DESC64_PC_HI12
:
4449 case R_LARCH_TLS_DESC_LO12
:
4450 case R_LARCH_TLS_DESC64_LO20
:
4451 case R_LARCH_TLS_DESC64_HI12
:
4453 unresolved_reloc
= false;
4456 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
4458 relocation
= sec_addr (got
)
4459 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
4461 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4462 /* Use both TLS_GD and TLS_DESC. */
4463 if (GOT_TLS_GD_BOTH_P (tls_type
))
4464 relocation
+= 2 * GOT_ENTRY_SIZE
;
4466 if (r_type
== R_LARCH_TLS_DESC64_PC_LO20
)
4467 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4468 else if (r_type
== R_LARCH_TLS_DESC64_PC_HI12
)
4469 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4474 case R_LARCH_TLS_DESC_LD
:
4475 case R_LARCH_TLS_DESC_CALL
:
4476 unresolved_reloc
= false;
4479 case R_LARCH_TLS_IE_PC_LO12
:
4480 case R_LARCH_TLS_IE64_PC_LO20
:
4481 case R_LARCH_TLS_IE64_PC_HI12
:
4482 case R_LARCH_TLS_IE_LO12
:
4483 case R_LARCH_TLS_IE64_LO20
:
4484 case R_LARCH_TLS_IE64_HI12
:
4485 unresolved_reloc
= false;
4488 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
4490 relocation
= sec_addr (got
)
4491 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
4493 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
4494 /* Use TLS_GD TLS_DESC and TLS_IE. */
4495 if (GOT_TLS_GD_BOTH_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
4496 relocation
+= 4 * GOT_ENTRY_SIZE
;
4497 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
4498 else if (GOT_TLS_GD_ANY_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
4499 relocation
+= 2 * GOT_ENTRY_SIZE
;
4501 if (r_type
== R_LARCH_TLS_IE64_PC_LO20
)
4502 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
4503 else if (r_type
== R_LARCH_TLS_IE64_PC_HI12
)
4504 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
4510 r
= bfd_reloc_continue
;
4511 unresolved_reloc
= false;
4523 /* 'unresolved_reloc' means we haven't done it yet.
4524 We need help of dynamic linker to fix this memory location up. */
4525 if (!unresolved_reloc
)
4528 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
4529 rel
->r_offset
) == MINUS_ONE
)
4530 /* WHY? May because it's invalid so skip checking.
4531 But why dynamic reloc a invalid section? */
4534 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
4536 fatal
= (loongarch_reloc_is_fatal
4537 (info
, input_bfd
, input_section
, rel
, howto
,
4538 bfd_reloc_dangerous
, is_undefweak
, name
,
4539 "Seems dynamic linker not process "
4540 "sections 'SEC_DEBUGGING'."));
4545 if ((info
->flags
& DF_TEXTREL
) == 0)
4546 if (input_section
->output_section
->flags
& SEC_READONLY
)
4547 info
->flags
|= DF_TEXTREL
;
4554 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
4555 rel
->r_offset
, sym
, h
, rel
->r_addend
);
4557 if (r
!= bfd_reloc_continue
)
4558 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
4559 input_bfd
, contents
);
4563 case bfd_reloc_dangerous
:
4564 case bfd_reloc_continue
:
4568 case bfd_reloc_overflow
:
4569 /* Overflow value can't be filled in. */
4570 loongarch_dump_reloc_record (info
->callbacks
->info
);
4571 info
->callbacks
->reloc_overflow
4572 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
4573 input_bfd
, input_section
, rel
->r_offset
);
4574 if (r_type
== R_LARCH_PCREL20_S2
4575 || r_type
== R_LARCH_TLS_LD_PCREL20_S2
4576 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
4577 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
4578 _bfd_error_handler (_("recompile with 'gcc -mno-relax' or"
4579 " 'as -mno-relax' or 'ld --no-relax'"));
4582 case bfd_reloc_outofrange
:
4583 /* Stack state incorrect. */
4584 loongarch_dump_reloc_record (info
->callbacks
->info
);
4585 info
->callbacks
->info
4586 ("%X%H: Internal stack state is incorrect.\n"
4587 "Want to push to full stack or pop from empty stack?\n",
4588 input_bfd
, input_section
, rel
->r_offset
);
4591 case bfd_reloc_notsupported
:
4592 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
4593 input_section
, rel
->r_offset
);
4597 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
4598 input_section
, rel
->r_offset
);
4609 loongarch_relax_delete_bytes (bfd
*abfd
,
4613 struct bfd_link_info
*link_info
)
4615 unsigned int i
, symcount
;
4616 bfd_vma toaddr
= sec
->size
;
4617 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (abfd
);
4618 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
4619 unsigned int sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
4620 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
4621 bfd_byte
*contents
= data
->this_hdr
.contents
;
4622 struct relr_entry
*relr
= loongarch_elf_section_data (sec
)->relr
;
4623 struct loongarch_elf_link_hash_table
*htab
=
4624 loongarch_elf_hash_table (link_info
);
4625 struct relr_entry
*relr_end
= NULL
;
4627 if (htab
->relr_count
)
4628 relr_end
= htab
->relr
+ htab
->relr_count
;
4630 /* Actually delete the bytes. */
4632 memmove (contents
+ addr
, contents
+ addr
+ count
, toaddr
- addr
- count
);
4634 /* Adjust the location of all of the relocs. Note that we need not
4635 adjust the addends, since all PC-relative references must be against
4636 symbols, which we will adjust below. */
4637 for (i
= 0; i
< sec
->reloc_count
; i
++)
4638 if (data
->relocs
[i
].r_offset
> addr
&& data
->relocs
[i
].r_offset
< toaddr
)
4639 data
->relocs
[i
].r_offset
-= count
;
4641 /* Likewise for relative relocs to be packed into .relr. */
4642 for (; relr
&& relr
< relr_end
&& relr
->sec
== sec
; relr
++)
4643 if (relr
->off
> addr
&& relr
->off
< toaddr
)
4646 /* Adjust the local symbols defined in this section. */
4647 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
4649 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
+ i
;
4650 if (sym
->st_shndx
== sec_shndx
)
4652 /* If the symbol is in the range of memory we just moved, we
4653 have to adjust its value. */
4654 if (sym
->st_value
> addr
&& sym
->st_value
<= toaddr
)
4655 sym
->st_value
-= count
;
4657 /* If the symbol *spans* the bytes we just deleted (i.e. its
4658 *end* is in the moved bytes but its *start* isn't), then we
4659 must adjust its size.
4661 This test needs to use the original value of st_value, otherwise
4662 we might accidentally decrease size when deleting bytes right
4663 before the symbol. But since deleted relocs can't span across
4664 symbols, we can't have both a st_value and a st_size decrease,
4665 so it is simpler to just use an else. */
4666 else if (sym
->st_value
<= addr
4667 && sym
->st_value
+ sym
->st_size
> addr
4668 && sym
->st_value
+ sym
->st_size
<= toaddr
)
4669 sym
->st_size
-= count
;
4673 /* Now adjust the global symbols defined in this section. */
4674 symcount
= ((symtab_hdr
->sh_size
/ sizeof (ElfNN_External_Sym
))
4675 - symtab_hdr
->sh_info
);
4677 for (i
= 0; i
< symcount
; i
++)
4679 struct elf_link_hash_entry
*sym_hash
= sym_hashes
[i
];
4681 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4682 containing the definition of __wrap_SYMBOL, includes a direct
4683 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4684 the same symbol (which is __wrap_SYMBOL), but still exist as two
4685 different symbols in 'sym_hashes', we don't want to adjust
4686 the global symbol __wrap_SYMBOL twice.
4688 The same problem occurs with symbols that are versioned_hidden, as
4689 foo becomes an alias for foo@BAR, and hence they need the same
4691 if (link_info
->wrap_hash
!= NULL
4692 || sym_hash
->versioned
!= unversioned
)
4694 struct elf_link_hash_entry
**cur_sym_hashes
;
4696 /* Loop only over the symbols which have already been checked. */
4697 for (cur_sym_hashes
= sym_hashes
; cur_sym_hashes
< &sym_hashes
[i
];
4700 /* If the current symbol is identical to 'sym_hash', that means
4701 the symbol was already adjusted (or at least checked). */
4702 if (*cur_sym_hashes
== sym_hash
)
4705 /* Don't adjust the symbol again. */
4706 if (cur_sym_hashes
< &sym_hashes
[i
])
4710 if ((sym_hash
->root
.type
== bfd_link_hash_defined
4711 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
4712 && sym_hash
->root
.u
.def
.section
== sec
)
4714 /* As above, adjust the value if needed. */
4715 if (sym_hash
->root
.u
.def
.value
> addr
4716 && sym_hash
->root
.u
.def
.value
<= toaddr
)
4717 sym_hash
->root
.u
.def
.value
-= count
;
4719 /* As above, adjust the size if needed. */
4720 else if (sym_hash
->root
.u
.def
.value
<= addr
4721 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
4722 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
<= toaddr
)
4723 sym_hash
->size
-= count
;
4730 /* Start perform TLS type transition.
4731 Currently there are three cases of relocation handled here:
4732 DESC -> IE, DEC -> LE and IE -> LE. */
4734 loongarch_tls_perform_trans (bfd
*abfd
, asection
*sec
,
4735 Elf_Internal_Rela
*rel
,
4736 struct elf_link_hash_entry
*h
,
4737 struct bfd_link_info
*info
)
4740 bool local_exec
= bfd_link_executable (info
)
4741 && LARCH_REF_LOCAL (info
, h
);
4742 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4743 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
4744 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4748 case R_LARCH_TLS_DESC_PC_HI20
:
4751 /* DESC -> LE relaxation:
4752 pcalalau12i $a0,%desc_pc_hi20(var) =>
4753 lu12i.w $a0,%le_hi20(var)
4755 bfd_put (32, abfd
, LARCH_OP_LU12I_W
| LARCH_RD_A0
,
4756 contents
+ rel
->r_offset
);
4757 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4761 /* DESC -> IE relaxation:
4762 pcalalau12i $a0,%desc_pc_hi20(var) =>
4763 pcalalau12i $a0,%ie_pc_hi20(var)
4765 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_HI20
);
4769 case R_LARCH_TLS_DESC_PC_LO12
:
4772 /* DESC -> LE relaxation:
4773 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4774 ori $a0,$a0,le_lo12(var)
4776 insn
= LARCH_OP_ORI
| LARCH_RD_RJ_A0
;
4777 bfd_put (32, abfd
, LARCH_OP_ORI
| LARCH_RD_RJ_A0
,
4778 contents
+ rel
->r_offset
);
4779 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4783 /* DESC -> IE relaxation:
4784 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4785 ld.d $a0,$a0,%ie_pc_lo12(var)
4787 bfd_put (32, abfd
, LARCH_OP_LD_D
| LARCH_RD_RJ_A0
,
4788 contents
+ rel
->r_offset
);
4789 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_LO12
);
4793 case R_LARCH_TLS_DESC_LD
:
4794 case R_LARCH_TLS_DESC_CALL
:
4795 /* DESC -> LE/IE relaxation:
4796 ld.d $ra,$a0,%desc_ld(var) => NOP
4797 jirl $ra,$ra,%desc_call(var) => NOP
4799 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4800 bfd_put (32, abfd
, LARCH_NOP
, contents
+ rel
->r_offset
);
4801 /* link with -relax option will delete NOP. */
4802 if (!info
->disable_target_specific_optimizations
)
4803 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4806 case R_LARCH_TLS_IE_PC_HI20
:
4809 /* IE -> LE relaxation:
4810 pcalalau12i $rd,%ie_pc_hi20(var) =>
4811 lu12i.w $rd,%le_hi20(var)
4813 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4814 bfd_put (32, abfd
, LARCH_OP_LU12I_W
| LARCH_GET_RD(insn
),
4815 contents
+ rel
->r_offset
);
4816 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4820 case R_LARCH_TLS_IE_PC_LO12
:
4823 /* IE -> LE relaxation:
4824 ld.d $rd,$rj,%%ie_pc_lo12(var) =>
4825 ori $rd,$rj,le_lo12(var)
4827 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4828 bfd_put (32, abfd
, LARCH_OP_ORI
| (insn
& 0x3ff),
4829 contents
+ rel
->r_offset
);
4830 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4839 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4840 there are three situations in which an assembly instruction sequence needs to
4842 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4845 in this case, the rd register in the st.{w/d} instruction does not store the
4846 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4847 symbolic address, and then obtains the rd + le_lo12_r address through the
4848 st.w instruction feature.
4849 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4851 before relax: after relax:
4853 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4854 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4855 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4858 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4860 before relax: after relax:
4862 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4863 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4864 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4867 in this case,the rs register in addi.{w/d} stores the full address of the tls
4868 symbol (tp + le_hi20_r + le_lo12_r).
4870 before relax: after relax:
4872 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4873 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4874 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4877 For relocation of all old LE instruction sequences, whether it is
4878 a normal code model or an extreme code model, relaxation will be
4879 performed when the relaxation conditions are met.
4882 lu12i.w $rd,%le_hi20(sym) => (deleted)
4883 ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4886 lu12i.w $rd,%le_hi20(sym) => (deleted)
4887 ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4888 lu32i.d $rd,%le64_lo20(sym) => (deleted)
4889 lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted)
4892 loongarch_relax_tls_le (bfd
*abfd
, asection
*sec
,
4893 asection
*sym_sec ATTRIBUTE_UNUSED
,
4894 Elf_Internal_Rela
*rel
, bfd_vma symval
,
4895 struct bfd_link_info
*link_info
,
4896 bool *agin ATTRIBUTE_UNUSED
,
4897 bfd_vma max_alignment ATTRIBUTE_UNUSED
)
4899 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4900 uint32_t insn
= bfd_get (32, abfd
, contents
+ rel
->r_offset
);
4901 static uint32_t insn_rj
,insn_rd
;
4902 symval
= symval
- elf_hash_table (link_info
)->tls_sec
->vma
;
4903 /* The old LE instruction sequence can be relaxed when the symbol offset
4904 is smaller than the 12-bit range. */
4905 if (symval
<= 0xfff)
4907 switch (ELFNN_R_TYPE (rel
->r_info
))
4909 /*if offset < 0x800, then perform the new le instruction
4911 case R_LARCH_TLS_LE_HI20_R
:
4912 case R_LARCH_TLS_LE_ADD_R
:
4916 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4917 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4922 case R_LARCH_TLS_LE_LO12_R
:
4925 /* Change rj to $tp. */
4927 /* Get rd register. */
4928 insn_rd
= LARCH_GET_RD (insn
);
4929 /* Write symbol offset. */
4931 /* Writes the modified instruction. */
4932 insn
= insn
& LARCH_MK_ADDI_D
;
4933 insn
= insn
| symval
| insn_rj
| insn_rd
;
4934 bfd_put (32, abfd
, insn
, contents
+ rel
->r_offset
);
4938 case R_LARCH_TLS_LE_HI20
:
4939 case R_LARCH_TLS_LE64_LO20
:
4940 case R_LARCH_TLS_LE64_HI12
:
4941 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4942 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4946 case R_LARCH_TLS_LE_LO12
:
4947 bfd_put (32, abfd
, LARCH_OP_ORI
| LARCH_GET_RD (insn
),
4948 contents
+ rel
->r_offset
);
4958 /* Whether two sections in the same segment. */
4960 loongarch_two_sections_in_same_segment (bfd
*abfd
, asection
*a
, asection
*b
)
4962 struct elf_segment_map
*m
;
4963 for (m
= elf_seg_map (abfd
); m
!= NULL
; m
= m
->next
)
4967 for (i
= m
->count
- 1; i
>= 0; i
--)
4969 if (m
->sections
[i
] == a
)
4971 if (m
->sections
[i
] == b
)
4982 /* Relax pcalau12i,addi.d => pcaddi. */
4984 loongarch_relax_pcala_addi (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4985 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4986 struct bfd_link_info
*info
, bool *again
,
4987 bfd_vma max_alignment
)
4989 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4990 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4991 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4992 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4993 uint32_t rd
= LARCH_GET_RD (pca
);
4995 /* This section's output_offset need to subtract the bytes of instructions
4996 relaxed by the previous sections, so it needs to be updated beforehand.
4997 size_input_section already took care of updating it after relaxation,
4998 so we additionally update once here. */
4999 sec
->output_offset
= sec
->output_section
->size
;
5000 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
5002 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5003 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
5004 sec
->output_section
,
5005 sym_sec
->output_section
))
5006 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
5010 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
5011 else if (symval
< pc
)
5012 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
5014 const uint32_t pcaddi
= LARCH_OP_PCADDI
;
5016 /* Is pcalau12i + addi.d insns? */
5017 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_PCALA_LO12
)
5018 || !LARCH_INSN_ADDI_D (add
)
5019 /* Is pcalau12i $rd + addi.d $rd,$rd? */
5020 || (LARCH_GET_RD (add
) != rd
)
5021 || (LARCH_GET_RJ (add
) != rd
)
5022 /* Can be relaxed to pcaddi? */
5023 || (symval
& 0x3) /* 4 bytes align. */
5024 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
5025 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
5028 /* Continue next relax trip. */
5032 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
5034 /* Adjust relocations. */
5035 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5036 R_LARCH_PCREL20_S2
);
5037 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5039 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
5045 tail36 $t0, f -> b f. */
5047 loongarch_relax_call36 (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
5048 Elf_Internal_Rela
*rel
, bfd_vma symval
,
5049 struct bfd_link_info
*info
, bool *again
,
5050 bfd_vma max_alignment
)
5052 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5053 uint32_t jirl
= bfd_get (32, abfd
, contents
+ rel
->r_offset
+ 4);
5054 uint32_t rd
= LARCH_GET_RD (jirl
);
5056 /* This section's output_offset need to subtract the bytes of instructions
5057 relaxed by the previous sections, so it needs to be updated beforehand.
5058 size_input_section already took care of updating it after relaxation,
5059 so we additionally update once here. */
5060 sec
->output_offset
= sec
->output_section
->size
;
5061 bfd_vma pc
= sec_addr (sec
) + rel
->r_offset
;
5063 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5064 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
5065 sec
->output_section
,
5066 sym_sec
->output_section
))
5067 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
5071 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
5072 else if (symval
< pc
)
5073 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
5075 /* Is pcalau12i + addi.d insns? */
5076 if (!LARCH_INSN_JIRL (jirl
)
5077 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xf8000000)
5078 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x7fffffc))
5081 /* Continue next relax trip. */
5084 const uint32_t bl
= LARCH_OP_BL
;
5085 const uint32_t b
= LARCH_OP_B
;
5088 bfd_put (32, abfd
, bl
, contents
+ rel
->r_offset
);
5090 bfd_put (32, abfd
, b
, contents
+ rel
->r_offset
);
5092 /* Adjust relocations. */
5093 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
), R_LARCH_B26
);
5094 /* Delete jirl instruction. */
5095 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
+ 4, 4, info
);
5099 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
5101 loongarch_relax_pcala_ld (bfd
*abfd
, asection
*sec
,
5102 asection
*sym_sec ATTRIBUTE_UNUSED
,
5103 Elf_Internal_Rela
*rel_hi
,
5104 bfd_vma symval ATTRIBUTE_UNUSED
,
5105 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5106 bool *again ATTRIBUTE_UNUSED
,
5107 bfd_vma max_alignment ATTRIBUTE_UNUSED
)
5109 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5110 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
5111 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
5112 uint32_t ld
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
5113 uint32_t rd
= LARCH_GET_RD (pca
);
5114 uint32_t addi_d
= LARCH_OP_ADDI_D
;
5116 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
)
5117 || (LARCH_GET_RD (ld
) != rd
)
5118 || (LARCH_GET_RJ (ld
) != rd
)
5119 || !LARCH_INSN_LD_D (ld
))
5122 addi_d
= addi_d
| (rd
<< 5) | rd
;
5123 bfd_put (32, abfd
, addi_d
, contents
+ rel_lo
->r_offset
);
5125 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5126 R_LARCH_PCALA_HI20
);
5127 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_lo
->r_info
),
5128 R_LARCH_PCALA_LO12
);
5132 /* Called by after_allocation to set the information of data segment
5136 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info
*info
,
5137 int *data_segment_phase
)
5139 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5140 htab
->data_segment_phase
= data_segment_phase
;
5143 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
5144 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
5146 loongarch_relax_align (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
5147 Elf_Internal_Rela
*rel
,
5148 bfd_vma symval ATTRIBUTE_UNUSED
,
5149 struct bfd_link_info
*link_info
,
5150 bool *again ATTRIBUTE_UNUSED
,
5151 bfd_vma max_alignment ATTRIBUTE_UNUSED
)
5153 bfd_vma addend
, max
= 0, alignment
= 1;
5155 int sym_index
= ELFNN_R_SYM (rel
->r_info
);
5158 alignment
= 1 << (rel
->r_addend
& 0xff);
5159 max
= rel
->r_addend
>> 8;
5162 alignment
= rel
->r_addend
+ 4;
5164 addend
= alignment
- 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
5165 symval
-= addend
; /* The address of first NOP added by R_LARCH_ALIGN. */
5166 bfd_vma aligned_addr
= ((symval
- 1) & ~(alignment
- 1)) + alignment
;
5167 bfd_vma need_nop_bytes
= aligned_addr
- symval
; /* */
5169 /* Make sure there are enough NOPs to actually achieve the alignment. */
5170 if (addend
< need_nop_bytes
)
5173 (_("%pB(%pA+%#" PRIx64
"): %" PRId64
" bytes required for alignment "
5174 "to %" PRId64
"-byte boundary, but only %" PRId64
" present"),
5175 abfd
, sym_sec
, (uint64_t) rel
->r_offset
,
5176 (int64_t) need_nop_bytes
, (int64_t) alignment
, (int64_t) addend
);
5177 bfd_set_error (bfd_error_bad_value
);
5181 /* Once we've handled an R_LARCH_ALIGN in a section,
5182 we can't relax anything else in this section. */
5183 sec
->sec_flg0
= true;
5184 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5186 /* If skipping more bytes than the specified maximum,
5187 then the alignment is not done at all and delete all NOPs. */
5188 if (max
> 0 && need_nop_bytes
> max
)
5189 return loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
5192 /* If the number of NOPs is already correct, there's nothing to do. */
5193 if (need_nop_bytes
== addend
)
5196 /* Delete the excess NOPs. */
5197 return loongarch_relax_delete_bytes (abfd
, sec
,
5198 rel
->r_offset
+ need_nop_bytes
,
5199 addend
- need_nop_bytes
, link_info
);
5202 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
5204 loongarch_relax_tls_ld_gd_desc (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
5205 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
5206 struct bfd_link_info
*info
, bool *again
,
5207 bfd_vma max_alignment
)
5209 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
5210 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
5211 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
5212 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
5213 uint32_t rd
= LARCH_GET_RD (pca
);
5215 /* This section's output_offset need to subtract the bytes of instructions
5216 relaxed by the previous sections, so it needs to be updated beforehand.
5217 size_input_section already took care of updating it after relaxation,
5218 so we additionally update once here. */
5219 sec
->output_offset
= sec
->output_section
->size
;
5220 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
5222 /* If pc and symbol not in the same segment, add/sub segment alignment. */
5223 if (!loongarch_two_sections_in_same_segment (info
->output_bfd
,
5224 sec
->output_section
,
5225 sym_sec
->output_section
))
5226 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
5230 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
5231 else if (symval
< pc
)
5232 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
5234 const uint32_t pcaddi
= LARCH_OP_PCADDI
;
5236 /* Is pcalau12i + addi.d insns? */
5237 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
5238 && ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_TLS_DESC_PC_LO12
)
5239 || !LARCH_INSN_ADDI_D (add
)
5240 /* Is pcalau12i $rd + addi.d $rd,$rd? */
5241 || (LARCH_GET_RD (add
) != rd
)
5242 || (LARCH_GET_RJ (add
) != rd
)
5243 /* Can be relaxed to pcaddi? */
5244 || (symval
& 0x3) /* 4 bytes align. */
5245 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
5246 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
5249 /* Continue next relax trip. */
5253 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
5255 /* Adjust relocations. */
5256 switch (ELFNN_R_TYPE (rel_hi
->r_info
))
5258 case R_LARCH_TLS_LD_PC_HI20
:
5259 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5260 R_LARCH_TLS_LD_PCREL20_S2
);
5262 case R_LARCH_TLS_GD_PC_HI20
:
5263 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5264 R_LARCH_TLS_GD_PCREL20_S2
);
5266 case R_LARCH_TLS_DESC_PC_HI20
:
5267 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
5268 R_LARCH_TLS_DESC_PCREL20_S2
);
5273 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
5275 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
5280 /* Traverse all output sections and return the max alignment. */
5283 loongarch_get_max_alignment (asection
*sec
)
5286 unsigned int max_alignment_power
= 0;
5288 for (o
= sec
->output_section
->owner
->sections
; o
!= NULL
; o
= o
->next
)
5289 if (o
->alignment_power
> max_alignment_power
)
5290 max_alignment_power
= o
->alignment_power
;
5292 return (bfd_vma
) 1 << max_alignment_power
;
5295 typedef bool (*relax_func_t
) (bfd
*, asection
*, asection
*,
5296 Elf_Internal_Rela
*, bfd_vma
,
5297 struct bfd_link_info
*, bool *,
5301 loongarch_elf_relax_section (bfd
*abfd
, asection
*sec
,
5302 struct bfd_link_info
*info
,
5307 if (!is_elf_hash_table (info
->hash
)
5308 || elf_hash_table_id (elf_hash_table (info
)) != LARCH_ELF_DATA
)
5311 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5313 /* It may happen that some sections have updated vma but the others do
5314 not. Go to the next relax trip (size_relative_relocs should have
5315 been demending another relax trip anyway). */
5316 if (htab
->layout_mutating_for_relr
)
5319 if (bfd_link_relocatable (info
)
5321 || sec
->reloc_count
== 0
5322 || (sec
->flags
& SEC_RELOC
) == 0
5323 || (sec
->flags
& SEC_HAS_CONTENTS
) == 0
5324 /* The exp_seg_relro_adjust is enum phase_enum (0x4). */
5325 || *(htab
->data_segment_phase
) == 4
5326 || (info
->disable_target_specific_optimizations
5327 && info
->relax_pass
== 0))
5330 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
5331 Elf_Internal_Rela
*relocs
;
5333 relocs
= data
->relocs
;
5334 else if (!(relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
5335 info
->keep_memory
)))
5337 data
->relocs
= relocs
;
5339 /* Read this BFD's contents if we haven't done so already. */
5340 if (!data
->this_hdr
.contents
5341 && !bfd_malloc_and_get_section (abfd
, sec
, &data
->this_hdr
.contents
))
5344 /* Read this BFD's symbols if we haven't done so already. */
5345 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (abfd
);
5346 if (symtab_hdr
->sh_info
!= 0
5347 && !symtab_hdr
->contents
5348 && !(symtab_hdr
->contents
=
5349 (unsigned char *) bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
5350 symtab_hdr
->sh_info
,
5351 0, NULL
, NULL
, NULL
)))
5354 /* Estimate the maximum alignment for all output sections once time
5355 should be enough. */
5356 bfd_vma max_alignment
= htab
->max_alignment
;
5357 if (max_alignment
== (bfd_vma
) -1)
5359 max_alignment
= loongarch_get_max_alignment (sec
);
5360 htab
->max_alignment
= max_alignment
;
5363 for (unsigned int i
= 0; i
< sec
->reloc_count
; i
++)
5368 bool local_got
= false;
5369 Elf_Internal_Rela
*rel
= relocs
+ i
;
5370 struct elf_link_hash_entry
*h
= NULL
;
5371 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
5372 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5374 if (r_symndx
>= symtab_hdr
->sh_info
)
5376 h
= elf_sym_hashes (abfd
)[r_symndx
- symtab_hdr
->sh_info
];
5377 while (h
->root
.type
== bfd_link_hash_indirect
5378 || h
->root
.type
== bfd_link_hash_warning
)
5379 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
5382 /* If the conditions for tls type transition are met, type
5383 transition is performed instead of relax.
5384 During the transition from DESC->IE/LE, there are 2 situations
5385 depending on the different configurations of the relax/norelax
5387 If the -relax option is used, the extra nops will be removed,
5388 and this transition is performed in pass 0.
5389 If the --no-relax option is used, nop will be retained, and
5390 this transition is performed in pass 1. */
5391 if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type
)
5392 && (i
+ 1 != sec
->reloc_count
)
5393 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
5394 && rel
->r_offset
== rel
[1].r_offset
5395 && loongarch_can_trans_tls (abfd
, info
, h
, r_symndx
, r_type
))
5397 loongarch_tls_perform_trans (abfd
, sec
, rel
, h
, info
);
5398 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5401 relax_func_t relax_func
= NULL
;
5402 if (info
->relax_pass
== 0)
5406 case R_LARCH_PCALA_HI20
:
5407 relax_func
= loongarch_relax_pcala_addi
;
5409 case R_LARCH_GOT_PC_HI20
:
5410 relax_func
= loongarch_relax_pcala_ld
;
5412 case R_LARCH_CALL36
:
5413 relax_func
= loongarch_relax_call36
;
5415 case R_LARCH_TLS_LE_HI20_R
:
5416 case R_LARCH_TLS_LE_LO12_R
:
5417 case R_LARCH_TLS_LE_ADD_R
:
5418 case R_LARCH_TLS_LE_HI20
:
5419 case R_LARCH_TLS_LE_LO12
:
5420 case R_LARCH_TLS_LE64_LO20
:
5421 case R_LARCH_TLS_LE64_HI12
:
5422 relax_func
= loongarch_relax_tls_le
;
5424 case R_LARCH_TLS_LD_PC_HI20
:
5425 case R_LARCH_TLS_GD_PC_HI20
:
5426 case R_LARCH_TLS_DESC_PC_HI20
:
5427 relax_func
= loongarch_relax_tls_ld_gd_desc
;
5433 /* Only relax this reloc if it is paired with R_RISCV_RELAX. */
5434 if (r_type
== R_LARCH_TLS_LD_PC_HI20
5435 || r_type
== R_LARCH_TLS_GD_PC_HI20
5436 || r_type
== R_LARCH_TLS_DESC_PC_HI20
5437 || r_type
== R_LARCH_PCALA_HI20
5438 || r_type
== R_LARCH_GOT_PC_HI20
)
5440 if ((i
+ 2) == sec
->reloc_count
- 1
5441 || ELFNN_R_TYPE ((rel
+ 1)->r_info
) != R_LARCH_RELAX
5442 || ELFNN_R_TYPE ((rel
+ 3)->r_info
) != R_LARCH_RELAX
5443 || rel
->r_offset
!= (rel
+ 1)->r_offset
5444 || (rel
+ 2)->r_offset
!= (rel
+ 3)->r_offset
5445 || rel
->r_offset
+ 4 != (rel
+ 2)->r_offset
)
5450 if (i
== sec
->reloc_count
- 1
5451 || ELFNN_R_TYPE ((rel
+ 1)->r_info
) != R_LARCH_RELAX
5452 || rel
->r_offset
!= (rel
+ 1)->r_offset
)
5456 else if (info
->relax_pass
== 1 && r_type
== R_LARCH_ALIGN
)
5457 relax_func
= loongarch_relax_align
;
5461 /* Four kind of relocations:
5462 Normal: symval is the symbol address.
5463 R_LARCH_ALIGN: symval is the address of the last NOP instruction
5464 added by this relocation, and then adds 4 more.
5465 R_LARCH_CALL36: symval is the symbol address for local symbols,
5466 or the PLT entry address of the symbol. (Todo)
5467 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
5468 of the symbol if transition is not possible. */
5469 if (r_symndx
< symtab_hdr
->sh_info
)
5471 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)symtab_hdr
->contents
5474 if ((ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
5475 && r_type
!= R_LARCH_CALL36
)
5476 || sym
->st_shndx
== SHN_ABS
)
5479 /* Only TLS instruction sequences that are accompanied by
5480 R_LARCH_RELAX and cannot perform type transition can be
5482 if (r_type
== R_LARCH_TLS_LD_PC_HI20
5483 || r_type
== R_LARCH_TLS_GD_PC_HI20
5484 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
5486 sym_sec
= htab
->elf
.sgot
;
5487 symval
= elf_local_got_offsets (abfd
)[r_symndx
];
5488 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
5490 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
5491 && GOT_TLS_GD_BOTH_P (tls_type
))
5492 symval
+= 2 * GOT_ENTRY_SIZE
;
5494 else if (sym
->st_shndx
== SHN_UNDEF
|| r_type
== R_LARCH_ALIGN
)
5497 symval
= rel
->r_offset
;
5501 sym_sec
= elf_elfsections (abfd
)[sym
->st_shndx
]->bfd_section
;
5502 symval
= sym
->st_value
;
5504 symtype
= ELF_ST_TYPE (sym
->st_info
);
5509 && ((h
->type
== STT_GNU_IFUNC
5510 && r_type
!= R_LARCH_CALL36
)
5511 || bfd_is_abs_section (h
->root
.u
.def
.section
)))
5514 /* The GOT entry of tls symbols must in current execute file or
5516 if (r_type
== R_LARCH_TLS_LD_PC_HI20
5517 || r_type
== R_LARCH_TLS_GD_PC_HI20
5518 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
5520 sym_sec
= htab
->elf
.sgot
;
5521 symval
= h
->got
.offset
;
5522 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
5524 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
5525 && GOT_TLS_GD_BOTH_P (tls_type
))
5526 symval
+= 2 * GOT_ENTRY_SIZE
;
5528 else if (h
->plt
.offset
!= MINUS_ONE
)
5530 sym_sec
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
5531 symval
= h
->plt
.offset
;
5533 /* Like loongarch_elf_relocate_section, set relocation(offset) to 0.
5534 Undefweak for other relocations handing in the future. */
5535 else if (h
->root
.type
== bfd_link_hash_undefweak
5536 && !h
->root
.linker_def
5537 && r_type
== R_LARCH_CALL36
)
5540 symval
= rel
->r_offset
;
5542 else if ((h
->root
.type
== bfd_link_hash_defined
5543 || h
->root
.type
== bfd_link_hash_defweak
)
5544 && h
->root
.u
.def
.section
!= NULL
5545 && h
->root
.u
.def
.section
->output_section
!= NULL
)
5547 sym_sec
= h
->root
.u
.def
.section
;
5548 symval
= h
->root
.u
.def
.value
;
5553 if (h
&& LARCH_REF_LOCAL (info
, h
))
5558 if (sym_sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
5559 && (sym_sec
->flags
& SEC_MERGE
))
5561 if (symtype
== STT_SECTION
)
5562 symval
+= rel
->r_addend
;
5564 symval
= _bfd_merged_section_offset (abfd
, &sym_sec
,
5565 elf_section_data (sym_sec
)->sec_info
,
5568 if (symtype
!= STT_SECTION
)
5569 symval
+= rel
->r_addend
;
5571 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
5573 If r_symndx is 0, alignmeng-4 is r_addend.
5574 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
5575 else if (r_type
== R_LARCH_ALIGN
)
5577 symval
+= ((1 << (rel
->r_addend
& 0xff)) - 4);
5579 symval
+= rel
->r_addend
;
5581 symval
+= rel
->r_addend
;
5583 symval
+= sec_addr (sym_sec
);
5585 if (r_type
== R_LARCH_GOT_PC_HI20
&& !local_got
)
5588 if (relax_func (abfd
, sec
, sym_sec
, rel
, symval
,
5589 info
, again
, max_alignment
)
5590 && relax_func
== loongarch_relax_pcala_ld
)
5591 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
5592 info
, again
, max_alignment
);
5598 /* Finish up dynamic symbol handling. We set the contents of various
5599 dynamic sections here. */
5602 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
5603 struct bfd_link_info
*info
,
5604 struct elf_link_hash_entry
*h
,
5605 Elf_Internal_Sym
*sym
)
5607 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5608 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
5610 if (h
->plt
.offset
!= MINUS_ONE
)
5613 asection
*plt
, *gotplt
, *relplt
;
5614 bfd_vma got_address
;
5615 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
5617 Elf_Internal_Rela rela
;
5621 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
5622 && LARCH_REF_LOCAL (info
, h
))
5623 || h
->dynindx
!= -1);
5625 plt
= htab
->elf
.splt
;
5626 gotplt
= htab
->elf
.sgotplt
;
5627 if (h
->type
== STT_GNU_IFUNC
&& LARCH_REF_LOCAL (info
, h
))
5628 relplt
= htab
->elf
.srelgot
;
5630 relplt
= htab
->elf
.srelplt
;
5631 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
5633 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
5635 else /* if (htab->elf.iplt) */
5637 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
5638 && LARCH_REF_LOCAL (info
, h
));
5640 plt
= htab
->elf
.iplt
;
5641 gotplt
= htab
->elf
.igotplt
;
5642 relplt
= htab
->elf
.irelplt
;
5643 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
5644 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
5647 /* Find out where the .plt entry should go. */
5648 loc
= plt
->contents
+ h
->plt
.offset
;
5650 /* Fill in the PLT entry itself. */
5651 if (!loongarch_make_plt_entry (got_address
,
5652 sec_addr (plt
) + h
->plt
.offset
,
5656 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
5657 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
5659 /* Fill in the initial value of the got.plt entry. */
5660 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
5661 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
5663 rela
.r_offset
= got_address
;
5665 /* TRUE if this is a PLT reference to a local IFUNC. */
5666 if (PLT_LOCAL_IFUNC_P (info
, h
)
5667 && (relplt
== htab
->elf
.srelgot
5668 || relplt
== htab
->elf
.irelplt
))
5670 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
5671 rela
.r_addend
= (h
->root
.u
.def
.value
5672 + h
->root
.u
.def
.section
->output_section
->vma
5673 + h
->root
.u
.def
.section
->output_offset
);
5675 loongarch_elf_append_rela (output_bfd
, relplt
, &rela
);
5679 /* Fill in the entry in the rela.plt section. */
5680 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
5682 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
5683 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
5686 if (!h
->def_regular
)
5688 /* Mark the symbol as undefined, rather than as defined in
5689 the .plt section. Leave the value alone. */
5690 sym
->st_shndx
= SHN_UNDEF
;
5691 /* If the symbol is weak, we do need to clear the value.
5692 Otherwise, the PLT entry would provide a definition for
5693 the symbol even if the symbol wasn't defined anywhere,
5694 and so the symbol would never be NULL. */
5695 if (!h
->ref_regular_nonweak
)
5700 if (h
->got
.offset
!= MINUS_ONE
5701 /* TLS got entry have been handled in elf_relocate_section. */
5702 && !(loongarch_elf_hash_entry (h
)->tls_type
5703 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
5704 /* Have allocated got entry but not allocated rela before. */
5705 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
5707 asection
*sgot
, *srela
;
5708 Elf_Internal_Rela rela
;
5709 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
)1;
5711 /* This symbol has an entry in the GOT. Set it up. */
5712 sgot
= htab
->elf
.sgot
;
5713 srela
= htab
->elf
.srelgot
;
5714 BFD_ASSERT (sgot
&& srela
);
5716 rela
.r_offset
= sec_addr (sgot
) + off
;
5719 && h
->type
== STT_GNU_IFUNC
)
5721 if(h
->plt
.offset
== MINUS_ONE
)
5723 if (htab
->elf
.splt
== NULL
)
5724 srela
= htab
->elf
.irelplt
;
5726 if (LARCH_REF_LOCAL (info
, h
))
5728 asection
*sec
= h
->root
.u
.def
.section
;
5729 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
5730 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
5731 + sec
->output_offset
;
5732 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
5736 BFD_ASSERT (h
->dynindx
!= -1);
5737 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5739 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
5742 else if(bfd_link_pic (info
))
5744 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5746 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
5751 /* For non-shared object, we can't use .got.plt, which
5752 contains the real function address if we need pointer
5753 equality. We load the GOT entry with the PLT entry. */
5754 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
5755 bfd_put_NN (output_bfd
,
5756 (plt
->output_section
->vma
5757 + plt
->output_offset
5759 sgot
->contents
+ off
);
5763 else if (bfd_link_pic (info
) && LARCH_REF_LOCAL (info
, h
))
5765 asection
*sec
= h
->root
.u
.def
.section
;
5766 bfd_vma linkaddr
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
5767 + sec
->output_offset
;
5769 /* Don't emit relative relocs if they are packed, but we need
5770 to write the addend (link-time addr) into the GOT then. */
5771 if (info
->enable_dt_relr
)
5773 bfd_put_NN (output_bfd
, linkaddr
, sgot
->contents
+ off
);
5774 goto skip_got_reloc
;
5776 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
5777 rela
.r_addend
= linkaddr
;
5781 BFD_ASSERT (h
->dynindx
!= -1);
5782 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5786 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
5790 /* Mark some specially defined symbols as absolute. */
5791 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
5792 sym
->st_shndx
= SHN_ABS
;
5797 /* Finish up the dynamic sections. */
5800 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
5803 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5804 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
5805 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
5806 bfd_byte
*dyncon
, *dynconend
;
5808 dynconend
= sdyn
->contents
+ sdyn
->size
;
5809 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
5811 Elf_Internal_Dyn dyn
;
5815 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
5820 s
= htab
->elf
.sgotplt
;
5821 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5824 s
= htab
->elf
.srelplt
;
5825 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5828 s
= htab
->elf
.srelplt
;
5829 dyn
.d_un
.d_val
= s
->size
;
5832 if ((info
->flags
& DF_TEXTREL
) == 0)
5836 if ((info
->flags
& DF_TEXTREL
) == 0)
5837 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
5841 skipped_size
+= dynsize
;
5843 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
5845 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
5846 memset (dyncon
- skipped_size
, 0, skipped_size
);
5850 /* Finish up local dynamic symbol handling. We set the contents of
5851 various dynamic sections here. */
5854 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
5856 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
5857 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
5859 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
5862 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
5863 this function is called before elf_link_sort_relocs.
5864 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
5865 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
5868 elf_loongarch_output_arch_local_syms
5869 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
5870 struct bfd_link_info
*info
,
5871 void *flaginfo ATTRIBUTE_UNUSED
,
5872 int (*func
) (void *, const char *,
5875 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
5877 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5881 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5882 htab_traverse (htab
->loc_hash_table
,
5883 elfNN_loongarch_finish_local_dynamic_symbol
,
5890 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
5891 struct bfd_link_info
*info
)
5894 asection
*sdyn
, *plt
, *gotplt
= NULL
;
5895 struct loongarch_elf_link_hash_table
*htab
;
5897 htab
= loongarch_elf_hash_table (info
);
5899 dynobj
= htab
->elf
.dynobj
;
5900 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
5902 if (elf_hash_table (info
)->dynamic_sections_created
)
5904 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
5906 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
5910 plt
= htab
->elf
.splt
;
5911 gotplt
= htab
->elf
.sgotplt
;
5913 if (plt
&& 0 < plt
->size
)
5916 uint32_t plt_header
[PLT_HEADER_INSNS
];
5917 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
5921 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
5922 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
5924 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
5928 if (htab
->elf
.sgotplt
)
5930 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
5932 if (bfd_is_abs_section (output_section
))
5934 _bfd_error_handler (_("discarded output section: `%pA'"),
5939 if (0 < htab
->elf
.sgotplt
->size
)
5941 /* Write the first two entries in .got.plt, needed for the dynamic
5943 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
5945 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5946 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
5949 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5954 asection
*output_section
= htab
->elf
.sgot
->output_section
;
5956 if (0 < htab
->elf
.sgot
->size
)
5958 /* Set the first entry in the global offset table to the address of
5959 the dynamic section. */
5960 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
5961 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
5964 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5970 /* Return address for Ith PLT stub in section PLT, for relocation REL
5971 or (bfd_vma) -1 if it should not be included. */
5974 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
5975 const arelent
*rel ATTRIBUTE_UNUSED
)
5977 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
5980 static enum elf_reloc_type_class
5981 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5982 const asection
*rel_sec ATTRIBUTE_UNUSED
,
5983 const Elf_Internal_Rela
*rela
)
5985 struct loongarch_elf_link_hash_table
*htab
;
5986 htab
= loongarch_elf_hash_table (info
);
5988 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
5990 /* Check relocation against STT_GNU_IFUNC symbol if there are
5992 bfd
*abfd
= info
->output_bfd
;
5993 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
5994 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
5995 if (r_symndx
!= STN_UNDEF
)
5997 Elf_Internal_Sym sym
;
5998 if (!bed
->s
->swap_symbol_in (abfd
,
5999 htab
->elf
.dynsym
->contents
6000 + r_symndx
* bed
->s
->sizeof_sym
,
6003 /* xgettext:c-format */
6004 _bfd_error_handler (_("%pB symbol number %lu references"
6005 " nonexistent SHT_SYMTAB_SHNDX section"),
6007 /* Ideally an error class should be returned here. */
6009 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
6010 return reloc_class_ifunc
;
6014 switch (ELFNN_R_TYPE (rela
->r_info
))
6016 case R_LARCH_IRELATIVE
:
6017 return reloc_class_ifunc
;
6018 case R_LARCH_RELATIVE
:
6019 return reloc_class_relative
;
6020 case R_LARCH_JUMP_SLOT
:
6021 return reloc_class_plt
;
6023 return reloc_class_copy
;
6025 return reloc_class_normal
;
6029 /* Copy the extra info we tack onto an elf_link_hash_entry. */
6032 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
6033 struct elf_link_hash_entry
*dir
,
6034 struct elf_link_hash_entry
*ind
)
6036 struct elf_link_hash_entry
*edir
, *eind
;
6041 if (eind
->dyn_relocs
!= NULL
)
6043 if (edir
->dyn_relocs
!= NULL
)
6045 struct elf_dyn_relocs
**pp
;
6046 struct elf_dyn_relocs
*p
;
6048 /* Add reloc counts against the indirect sym to the direct sym
6049 list. Merge any entries against the same section. */
6050 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
6052 struct elf_dyn_relocs
*q
;
6054 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
6055 if (q
->sec
== p
->sec
)
6057 q
->pc_count
+= p
->pc_count
;
6058 q
->count
+= p
->count
;
6065 *pp
= edir
->dyn_relocs
;
6068 edir
->dyn_relocs
= eind
->dyn_relocs
;
6069 eind
->dyn_relocs
= NULL
;
6072 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
6074 loongarch_elf_hash_entry(edir
)->tls_type
6075 = loongarch_elf_hash_entry(eind
)->tls_type
;
6076 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
6078 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
6081 #define PRSTATUS_SIZE 0x1d8
6082 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
6083 #define PRSTATUS_OFFSET_PR_PID 0x20
6084 #define ELF_GREGSET_T_SIZE 0x168
6085 #define PRSTATUS_OFFSET_PR_REG 0x70
6087 /* Support for core dump NOTE sections. */
6090 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
6092 switch (note
->descsz
)
6097 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
6100 elf_tdata (abfd
)->core
->signal
=
6101 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
6104 elf_tdata (abfd
)->core
->lwpid
=
6105 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
6109 /* Make a ".reg/999" section. */
6110 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
6112 + PRSTATUS_OFFSET_PR_REG
);
6115 #define PRPSINFO_SIZE 0x88
6116 #define PRPSINFO_OFFSET_PR_PID 0x18
6117 #define PRPSINFO_OFFSET_PR_FNAME 0x28
6118 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
6119 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
6120 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
6123 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
6125 switch (note
->descsz
)
6130 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
6133 elf_tdata (abfd
)->core
->pid
=
6134 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
6137 elf_tdata (abfd
)->core
->program
=
6138 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
6139 PRPSINFO_SIZEOF_PR_FNAME
);
6142 elf_tdata (abfd
)->core
->command
=
6143 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
6144 PRPSINFO_SIZEOF_PR_PS_ARGS
);
6148 /* Note that for some reason, a spurious space is tacked
6149 onto the end of the args in some (at least one anyway)
6150 implementations, so strip it off if it exists. */
6153 char *command
= elf_tdata (abfd
)->core
->command
;
6154 int n
= strlen (command
);
6156 if (0 < n
&& command
[n
- 1] == ' ')
6157 command
[n
- 1] = '\0';
6163 /* Set the right mach type. */
6165 loongarch_elf_object_p (bfd
*abfd
)
6167 /* There are only two mach types in LoongArch currently. */
6168 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
6169 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
6171 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
6176 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
6177 Elf_Internal_Rela
*rel
,
6178 struct elf_link_hash_entry
*h
,
6179 Elf_Internal_Sym
*sym
)
6182 switch (ELFNN_R_TYPE (rel
->r_info
))
6184 case R_LARCH_GNU_VTINHERIT
:
6185 case R_LARCH_GNU_VTENTRY
:
6189 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
6192 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
6193 executable PLT slots where the executable never takes the address of those
6194 functions, the function symbols are not added to the hash table. */
6197 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
6199 if (h
->plt
.offset
!= (bfd_vma
) -1
6201 && !h
->pointer_equality_needed
)
6204 return _bfd_elf_hash_symbol (h
);
6207 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
6208 #define TARGET_LITTLE_NAME "elfNN-loongarch"
6209 #define ELF_ARCH bfd_arch_loongarch
6210 #define ELF_TARGET_ID LARCH_ELF_DATA
6211 #define ELF_MACHINE_CODE EM_LOONGARCH
6212 #define ELF_MAXPAGESIZE 0x4000
6213 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
6214 #define bfd_elfNN_bfd_link_hash_table_create \
6215 loongarch_elf_link_hash_table_create
6216 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
6217 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
6218 #define elf_info_to_howto loongarch_info_to_howto_rela
6219 #define bfd_elfNN_mkobject \
6220 elfNN_loongarch_object
6221 #define bfd_elfNN_bfd_merge_private_bfd_data \
6222 elfNN_loongarch_merge_private_bfd_data
6224 #define elf_backend_reloc_type_class loongarch_reloc_type_class
6225 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
6226 #define elf_backend_create_dynamic_sections \
6227 loongarch_elf_create_dynamic_sections
6228 #define elf_backend_check_relocs loongarch_elf_check_relocs
6229 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
6230 #define elf_backend_late_size_sections loongarch_elf_late_size_sections
6231 #define elf_backend_relocate_section loongarch_elf_relocate_section
6232 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
6233 #define elf_backend_output_arch_local_syms \
6234 elf_loongarch_output_arch_local_syms
6235 #define elf_backend_finish_dynamic_sections \
6236 loongarch_elf_finish_dynamic_sections
6237 #define elf_backend_object_p loongarch_elf_object_p
6238 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
6239 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
6240 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
6241 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
6242 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
6243 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
6244 #define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs
6245 #define elf_backend_finish_relative_relocs \
6246 loongarch_elf_finish_relative_relocs
6247 #define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook
6249 #define elf_backend_dtrel_excludes_plt 1
6251 #include "elfNN-target.h"