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)
87 struct loongarch_elf_link_hash_table
89 struct elf_link_hash_table elf
;
91 /* Short-cuts to get to dynamic linker sections. */
94 /* Small local sym to section mapping cache. */
95 struct sym_cache sym_cache
;
97 /* Used by local STT_GNU_IFUNC symbols. */
98 htab_t loc_hash_table
;
99 void *loc_hash_memory
;
101 /* The max alignment of output sections. */
102 bfd_vma max_alignment
;
104 /* The data segment phase, don't relax the section
105 when it is exp_seg_relro_adjust. */
106 int *data_segment_phase
;
109 /* Get the LoongArch ELF linker hash table from a link_info structure. */
110 #define loongarch_elf_hash_table(p) \
111 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
112 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
115 #define MINUS_ONE ((bfd_vma) 0 - 1)
117 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
119 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
120 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
122 #define PLT_HEADER_INSNS 8
123 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
125 #define PLT_ENTRY_INSNS 4
126 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
128 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
130 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT
131 resolver _dl_runtime_resolve, the other is used for link map. */
132 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
134 #define elf_backend_want_got_plt 1
136 #define elf_backend_plt_readonly 1
138 #define elf_backend_want_plt_sym 1
139 #define elf_backend_plt_alignment 4
140 #define elf_backend_can_gc_sections 1
141 #define elf_backend_can_refcount 1
142 #define elf_backend_want_got_sym 1
144 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
146 #define elf_backend_want_dynrelro 1
147 #define elf_backend_rela_normal 1
148 #define elf_backend_default_execstack 0
150 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
151 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
152 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
153 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
154 || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
155 || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
156 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
158 #define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \
159 ((R_TYPE) == R_LARCH_TLS_LE_HI20 \
160 || (R_TYPE) == R_LARCH_TLS_LE_LO12 \
161 || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
162 || (R_TYPE) == R_LARCH_TLS_LE64_HI12)
164 /* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx,
165 and set NEED_RELOC to true used in allocate_dynrelocs and
166 loongarch_elf_relocate_section for TLS GD/IE. */
167 #define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
171 && (H)->dynindx != -1 \
172 && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \
173 bfd_link_pic (INFO), (H))) \
174 (INDX) = (H)->dynindx; \
176 || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
177 || (H)->root.type != bfd_link_hash_undefweak) \
178 && (!bfd_link_executable (INFO) \
180 (NEED_RELOC) = true; \
185 /* Generate a PLT header. */
188 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
191 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
194 if (pcrel
+ 0x80000800 > 0xffffffff)
196 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
197 bfd_set_error (bfd_error_bad_value
);
200 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
203 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
204 sub.[wd] $t1, $t1, $t3
205 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
206 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
207 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
208 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
209 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
212 if (GOT_ENTRY_SIZE
== 8)
214 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
215 entry
[1] = 0x0011bdad;
216 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
217 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
218 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
219 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
220 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
221 entry
[7] = 0x4c0001e0;
225 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
226 entry
[1] = 0x00113dad;
227 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
228 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
229 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
230 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
231 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
232 entry
[7] = 0x4c0001e0;
237 /* Generate a PLT entry. */
240 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
243 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
246 if (pcrel
+ 0x80000800 > 0xffffffff)
248 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
249 bfd_set_error (bfd_error_bad_value
);
252 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
255 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
256 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
257 | (lo
& 0xfff) << 10);
258 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
259 entry
[3] = 0x03400000; /* nop */
264 /* Create an entry in an LoongArch ELF linker hash table. */
266 static struct bfd_hash_entry
*
267 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
270 struct loongarch_elf_link_hash_entry
*eh
;
272 /* Allocate the structure if it has not already been allocated by a
276 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
281 /* Call the allocation method of the superclass. */
282 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
285 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
286 eh
->tls_type
= GOT_UNKNOWN
;
292 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
293 for local symbol so that we can handle local STT_GNU_IFUNC symbols
294 as global symbol. We reuse indx and dynstr_index for local symbol
295 hash since they aren't used by global symbols in this backend. */
298 elfNN_loongarch_local_htab_hash (const void *ptr
)
300 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
301 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
304 /* Compare local hash entries. */
307 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
309 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
310 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
312 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
315 /* Find and/or create a hash entry for local symbol. */
316 static struct elf_link_hash_entry
*
317 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
318 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
321 struct loongarch_elf_link_hash_entry e
, *ret
;
322 asection
*sec
= abfd
->sections
;
323 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
326 e
.elf
.indx
= sec
->id
;
327 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
328 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
329 create
? INSERT
: NO_INSERT
);
336 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
340 ret
= ((struct loongarch_elf_link_hash_entry
*)
341 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
342 sizeof (struct loongarch_elf_link_hash_entry
)));
345 memset (ret
, 0, sizeof (*ret
));
346 ret
->elf
.indx
= sec
->id
;
347 ret
->elf
.pointer_equality_needed
= 0;
348 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
349 ret
->elf
.dynindx
= -1;
350 ret
->elf
.needs_plt
= 0;
351 ret
->elf
.plt
.refcount
= -1;
352 ret
->elf
.got
.refcount
= -1;
353 ret
->elf
.def_dynamic
= 0;
354 ret
->elf
.def_regular
= 1;
355 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
356 ret
->elf
.ref_regular
= 0;
357 ret
->elf
.forced_local
= 1;
358 ret
->elf
.root
.type
= bfd_link_hash_defined
;
364 /* Destroy an LoongArch elf linker hash table. */
367 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
369 struct loongarch_elf_link_hash_table
*ret
;
370 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
372 if (ret
->loc_hash_table
)
373 htab_delete (ret
->loc_hash_table
);
374 if (ret
->loc_hash_memory
)
375 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
377 _bfd_elf_link_hash_table_free (obfd
);
380 /* Create a LoongArch ELF linker hash table. */
382 static struct bfd_link_hash_table
*
383 loongarch_elf_link_hash_table_create (bfd
*abfd
)
385 struct loongarch_elf_link_hash_table
*ret
;
386 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
388 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
392 if (!_bfd_elf_link_hash_table_init
393 (&ret
->elf
, abfd
, link_hash_newfunc
,
394 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
400 ret
->max_alignment
= MINUS_ONE
;
402 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
403 elfNN_loongarch_local_htab_eq
, NULL
);
404 ret
->loc_hash_memory
= objalloc_create ();
405 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
407 elfNN_loongarch_link_hash_table_free (abfd
);
410 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
412 return &ret
->elf
.root
;
415 /* Merge backend specific data from an object file to the output
416 object file when linking. */
419 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
421 bfd
*obfd
= info
->output_bfd
;
422 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
423 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
425 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
428 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
430 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
431 "the selected emulation:\n"
432 " target emulation `%s' does not match `%s'"),
433 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
437 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
440 /* If the input BFD is not a dynamic object and it does not contain any
441 non-data sections, do not account its ABI. For example, various
442 packages produces such data-only relocatable objects with
443 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
444 But they are compatible with all ABIs. */
445 if (!(ibfd
->flags
& DYNAMIC
))
448 bool have_code_sections
= false;
449 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
450 if ((bfd_section_flags (sec
)
451 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
452 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
454 have_code_sections
= true;
457 if (!have_code_sections
)
461 if (!elf_flags_init (obfd
))
463 elf_flags_init (obfd
) = true;
464 elf_elfheader (obfd
)->e_flags
= in_flags
;
467 else if (out_flags
!= in_flags
)
469 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags
)
470 && EF_LOONGARCH_IS_OBJ_V1 (in_flags
))
471 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags
)
472 && EF_LOONGARCH_IS_OBJ_V1 (out_flags
)))
474 elf_elfheader (obfd
)->e_flags
|= EF_LOONGARCH_OBJABI_V1
;
475 out_flags
= elf_elfheader (obfd
)->e_flags
;
476 in_flags
= out_flags
;
480 /* Disallow linking different ABIs. */
481 /* Only check relocation version.
482 The obj_v0 is compatible with obj_v1. */
483 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
485 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
492 bfd_set_error (bfd_error_bad_value
);
496 /* Create the .got section. */
499 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
504 struct elf_link_hash_entry
*h
;
505 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
506 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
508 /* This function may be called more than once. */
509 if (htab
->sgot
!= NULL
)
512 flags
= bed
->dynamic_sec_flags
;
513 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
514 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
516 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
520 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
521 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
525 /* The first bit of the global offset table is the header. */
526 s
->size
+= bed
->got_header_size
;
528 if (bed
->want_got_plt
)
530 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
531 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
535 /* Reserve room for the header. */
536 s
->size
= GOTPLT_HEADER_SIZE
;
539 if (bed
->want_got_sym
)
541 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
542 section. We don't do this in the linker script because we don't want
543 to define the symbol if we are not creating a global offset table. */
544 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
545 "_GLOBAL_OFFSET_TABLE_");
546 elf_hash_table (info
)->hgot
= h
;
553 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
554 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
558 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
560 struct loongarch_elf_link_hash_table
*htab
;
562 htab
= loongarch_elf_hash_table (info
);
563 BFD_ASSERT (htab
!= NULL
);
565 if (!loongarch_elf_create_got_section (dynobj
, info
))
568 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
571 if (!bfd_link_pic (info
))
573 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
574 SEC_ALLOC
| SEC_THREAD_LOCAL
);
576 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
577 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
584 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
585 struct bfd_link_info
*info
,
586 struct elf_link_hash_entry
*h
,
587 unsigned long symndx
,
590 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
591 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
593 /* This is a global offset table entry for a local symbol. */
594 if (elf_local_got_refcounts (abfd
) == NULL
)
597 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
598 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
600 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
601 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
611 if (htab
->elf
.sgot
== NULL
612 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
616 if (h
->got
.refcount
< 0)
621 elf_local_got_refcounts (abfd
)[symndx
]++;
624 /* No need for GOT. */
627 _bfd_error_handler (_("Internal error: unreachable."));
631 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
632 *new_tls_type
|= tls_type
;
634 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
635 if ((*new_tls_type
& GOT_TLS_IE
) && (*new_tls_type
& GOT_TLS_GDESC
))
636 *new_tls_type
&= ~ (GOT_TLS_GDESC
);
637 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
639 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
640 "thread local symbol"),
642 h
? h
->root
.root
.string
: "<local>");
650 loongarch_reloc_got_type (unsigned int r_type
)
654 case R_LARCH_TLS_DESC_PC_HI20
:
655 case R_LARCH_TLS_DESC_PC_LO12
:
656 case R_LARCH_TLS_DESC_LD
:
657 case R_LARCH_TLS_DESC_CALL
:
658 return GOT_TLS_GDESC
;
660 case R_LARCH_TLS_IE_PC_HI20
:
661 case R_LARCH_TLS_IE_PC_LO12
:
670 /* Return true if tls type transition can be performed. */
672 loongarch_can_trans_tls (bfd
*input_bfd
,
673 struct bfd_link_info
*info
,
674 struct elf_link_hash_entry
*h
,
675 unsigned int r_symndx
,
678 char symbol_tls_type
;
679 unsigned int reloc_got_type
;
681 /* Only TLS DESC/IE in normal code mode will perform type
683 if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type
))
686 /* Obtaining tls got type here may occur before
687 loongarch_elf_record_tls_and_got_reference, so it is necessary
688 to ensure that tls got type has been initialized, otherwise it
689 is set to GOT_UNKNOWN. */
690 symbol_tls_type
= GOT_UNKNOWN
;
691 if (_bfd_loongarch_elf_local_got_tls_type (input_bfd
) || h
)
692 symbol_tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
694 reloc_got_type
= loongarch_reloc_got_type (r_type
);
696 if (symbol_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
699 if (! bfd_link_executable (info
))
702 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
708 /* The type of relocation that can be transitioned. */
710 loongarch_tls_transition_without_check (struct bfd_link_info
*info
,
712 struct elf_link_hash_entry
*h
)
714 bool local_exec
= bfd_link_executable (info
)
715 && SYMBOL_REFERENCES_LOCAL (info
, h
);
719 case R_LARCH_TLS_DESC_PC_HI20
:
721 ? R_LARCH_TLS_LE_HI20
722 : R_LARCH_TLS_IE_PC_HI20
);
724 case R_LARCH_TLS_DESC_PC_LO12
:
726 ? R_LARCH_TLS_LE_LO12
727 : R_LARCH_TLS_IE_PC_LO12
);
729 case R_LARCH_TLS_DESC_LD
:
730 case R_LARCH_TLS_DESC_CALL
:
733 case R_LARCH_TLS_IE_PC_HI20
:
734 return local_exec
? R_LARCH_TLS_LE_HI20
: r_type
;
736 case R_LARCH_TLS_IE_PC_LO12
:
737 return local_exec
? R_LARCH_TLS_LE_LO12
: r_type
;
747 loongarch_tls_transition (bfd
*input_bfd
,
748 struct bfd_link_info
*info
,
749 struct elf_link_hash_entry
*h
,
750 unsigned int r_symndx
,
753 if (! loongarch_can_trans_tls (input_bfd
, info
, h
, r_symndx
, r_type
))
756 return loongarch_tls_transition_without_check (info
, r_type
, h
);
759 /* Look through the relocs for a section during the first phase, and
760 allocate space in the global offset table or procedure linkage
764 bad_static_reloc (bfd
*abfd
, const Elf_Internal_Rela
*rel
, asection
*sec
,
765 unsigned r_type
, struct elf_link_hash_entry
*h
,
766 Elf_Internal_Sym
*isym
)
768 /* We propably can improve the information to tell users that they should
769 be recompile the code with -fPIC or -fPIE, just like what x86 does. */
770 reloc_howto_type
* r
= loongarch_elf_rtype_to_howto (abfd
, r_type
);
771 const char *name
= NULL
;
774 name
= h
->root
.root
.string
;
776 name
= bfd_elf_string_from_elf_section (abfd
,
777 elf_symtab_hdr (abfd
).sh_link
,
779 if (name
== NULL
|| *name
== '\0')
782 (*_bfd_error_handler
)
783 (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
784 "a shared object; recompile with -fPIC"),
785 abfd
, sec
, (long) rel
->r_offset
, r
? r
->name
: _("<unknown>"), name
);
786 bfd_set_error (bfd_error_bad_value
);
791 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
792 asection
*sec
, const Elf_Internal_Rela
*relocs
)
794 struct loongarch_elf_link_hash_table
*htab
;
795 Elf_Internal_Shdr
*symtab_hdr
;
796 struct elf_link_hash_entry
**sym_hashes
;
797 const Elf_Internal_Rela
*rel
;
798 asection
*sreloc
= NULL
;
800 if (bfd_link_relocatable (info
))
803 htab
= loongarch_elf_hash_table (info
);
804 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
805 sym_hashes
= elf_sym_hashes (abfd
);
807 if (htab
->elf
.dynobj
== NULL
)
808 htab
->elf
.dynobj
= abfd
;
810 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
813 unsigned int r_symndx
;
814 struct elf_link_hash_entry
*h
;
815 Elf_Internal_Sym
*isym
= NULL
;
817 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
818 r_type
= ELFNN_R_TYPE (rel
->r_info
);
820 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
822 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
826 if (r_symndx
< symtab_hdr
->sh_info
)
828 /* A local symbol. */
829 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
833 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
835 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
839 h
->type
= STT_GNU_IFUNC
;
847 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
848 while (h
->root
.type
== bfd_link_hash_indirect
849 || h
->root
.type
== bfd_link_hash_warning
)
850 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
853 /* It is referenced by a non-shared object. */
857 if (h
&& h
->type
== STT_GNU_IFUNC
)
859 if (htab
->elf
.dynobj
== NULL
)
860 htab
->elf
.dynobj
= abfd
;
862 /* Create 'irelifunc' in PIC object. */
863 if (bfd_link_pic (info
)
864 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
866 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
867 else if (!htab
->elf
.splt
868 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
870 /* Create the ifunc sections, iplt and ipltgot, for static
872 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
873 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
876 if (h
->plt
.refcount
< 0)
881 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
884 int need_dynreloc
= 0;
885 int only_need_pcrel
= 0;
887 /* Type transitions are only possible with relocations accompanied
889 if (rel
+ 1 != relocs
+ sec
->reloc_count
890 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
)
891 r_type
= loongarch_tls_transition (abfd
, info
, h
, r_symndx
, r_type
);
894 case R_LARCH_GOT_PC_HI20
:
895 case R_LARCH_GOT_HI20
:
896 case R_LARCH_SOP_PUSH_GPREL
:
899 h
->pointer_equality_needed
= 1;
900 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
906 case R_LARCH_TLS_LD_PC_HI20
:
907 case R_LARCH_TLS_LD_HI20
:
908 case R_LARCH_TLS_GD_PC_HI20
:
909 case R_LARCH_TLS_GD_HI20
:
910 case R_LARCH_SOP_PUSH_TLS_GD
:
911 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
917 case R_LARCH_TLS_IE_PC_HI20
:
918 case R_LARCH_TLS_IE_HI20
:
919 case R_LARCH_SOP_PUSH_TLS_GOT
:
920 if (bfd_link_pic (info
))
921 /* May fail for lazy-bind. */
922 info
->flags
|= DF_STATIC_TLS
;
924 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
930 case R_LARCH_TLS_LE_HI20
:
931 case R_LARCH_TLS_LE_HI20_R
:
932 case R_LARCH_SOP_PUSH_TLS_TPREL
:
933 if (!bfd_link_executable (info
))
934 return bad_static_reloc (abfd
, rel
, sec
, r_type
, h
, isym
);
936 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
942 case R_LARCH_TLS_DESC_PC_HI20
:
943 case R_LARCH_TLS_DESC_HI20
:
944 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
950 case R_LARCH_ABS_HI20
:
951 case R_LARCH_SOP_PUSH_ABSOLUTE
:
952 if (bfd_link_pic (info
))
953 return bad_static_reloc (abfd
, rel
, sec
, r_type
, h
, isym
);
956 /* If this reloc is in a read-only section, we might
957 need a copy reloc. We can't check reliably at this
958 stage whether the section is read-only, as input
959 sections have not yet been mapped to output sections.
960 Tentatively set the flag for now, and correct in
961 adjust_dynamic_symbol. */
965 /* For normal cmodel, pcalau12i + addi.d/w used to data.
966 For first version medium cmodel, pcalau12i + jirl are used to
967 function call, it need to creat PLT entry for STT_FUNC and
968 STT_GNU_IFUNC type symbol. */
969 case R_LARCH_PCALA_HI20
:
970 if (h
!= NULL
&& (STT_FUNC
== h
->type
|| STT_GNU_IFUNC
== h
->type
))
972 /* For pcalau12i + jirl. */
974 if (h
->plt
.refcount
< 0)
979 h
->pointer_equality_needed
= 1;
991 if (!bfd_link_pic (info
))
994 /* We try to create PLT stub for all non-local function. */
995 if (h
->plt
.refcount
< 0)
1002 case R_LARCH_SOP_PUSH_PCREL
:
1005 if (!bfd_link_pic (info
))
1008 /* We try to create PLT stub for all non-local function. */
1009 if (h
->plt
.refcount
< 0)
1010 h
->plt
.refcount
= 0;
1012 h
->pointer_equality_needed
= 1;
1017 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1018 /* This symbol requires a procedure linkage table entry. We
1019 actually build the entry in adjust_dynamic_symbol,
1020 because this might be a case of linking PIC code without
1021 linking in any dynamic objects, in which case we don't
1022 need to generate a procedure linkage table after all. */
1026 if (h
->plt
.refcount
< 0)
1027 h
->plt
.refcount
= 0;
1032 case R_LARCH_TLS_DTPREL32
:
1033 case R_LARCH_TLS_DTPREL64
:
1035 only_need_pcrel
= 1;
1038 case R_LARCH_JUMP_SLOT
:
1044 /* If resolved symbol is defined in this object,
1045 1. Under pie, the symbol is known. We convert it
1046 into R_LARCH_RELATIVE and need load-addr still.
1047 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
1048 3. Under dll, R_LARCH_NN can't be changed normally, since
1049 its defination could be covered by the one in executable.
1050 For symbolic, we convert it into R_LARCH_RELATIVE.
1051 Thus, only under pde, it needs pcrel only. We discard it. */
1052 only_need_pcrel
= bfd_link_pde (info
);
1055 && (!bfd_link_pic (info
)
1056 || h
->type
== STT_GNU_IFUNC
))
1058 /* This reloc might not bind locally. */
1060 h
->pointer_equality_needed
= 1;
1063 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
1065 /* We may need a .plt entry if the symbol is a function
1066 defined in a shared lib or is a function referenced
1067 from the code or read-only section. */
1068 h
->plt
.refcount
+= 1;
1073 case R_LARCH_GNU_VTINHERIT
:
1074 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1078 case R_LARCH_GNU_VTENTRY
:
1079 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1087 /* Record some info for sizing and allocating dynamic entry. */
1088 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
1090 /* When creating a shared object, we must copy these
1091 relocs into the output file. We create a reloc
1092 section in dynobj and make room for the reloc. */
1093 struct elf_dyn_relocs
*p
;
1094 struct elf_dyn_relocs
**head
;
1099 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
1100 LARCH_ELF_LOG_WORD_BYTES
,
1101 abfd
, /*rela?*/ true);
1106 /* If this is a global symbol, we count the number of
1107 relocations we need for this symbol. */
1109 head
= &h
->dyn_relocs
;
1112 /* Track dynamic relocs needed for local syms too.
1113 We really need local syms available to do this
1119 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1123 vpp
= &elf_section_data (s
)->local_dynrel
;
1124 head
= (struct elf_dyn_relocs
**) vpp
;
1128 if (p
== NULL
|| p
->sec
!= sec
)
1130 bfd_size_type amt
= sizeof *p
;
1131 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
1142 p
->pc_count
+= only_need_pcrel
;
1149 /* Find dynamic relocs for H that apply to read-only sections. */
1152 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
1154 struct elf_dyn_relocs
*p
;
1156 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1158 asection
*s
= p
->sec
->output_section
;
1160 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
1166 /* Adjust a symbol defined by a dynamic object and referenced by a
1167 regular object. The current definition is in some section of the
1168 dynamic object, but we're not including those sections. We have to
1169 change the definition to something the rest of the link can
1172 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
1173 struct elf_link_hash_entry
*h
)
1175 struct loongarch_elf_link_hash_table
*htab
;
1178 htab
= loongarch_elf_hash_table (info
);
1179 BFD_ASSERT (htab
!= NULL
);
1181 dynobj
= htab
->elf
.dynobj
;
1183 /* Make sure we know what is going on here. */
1184 BFD_ASSERT (dynobj
!= NULL
1186 || h
->type
== STT_GNU_IFUNC
1190 && !h
->def_regular
)));
1192 /* If this is a function, put it in the procedure linkage table. We
1193 will fill in the contents of the procedure linkage table later
1194 (although we could actually do it here). */
1195 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
1197 if (h
->plt
.refcount
<= 0
1198 || (h
->type
!= STT_GNU_IFUNC
1199 && (SYMBOL_REFERENCES_LOCAL (info
, h
)
1200 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1201 && h
->root
.type
== bfd_link_hash_undefweak
))))
1203 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1204 in an input file, but the symbol was never referred to by a
1205 dynamic object, or if all references were garbage collected.
1206 In such a case, we don't actually need to build a PLT entry. */
1207 h
->plt
.offset
= MINUS_ONE
;
1214 h
->plt
.offset
= MINUS_ONE
;
1216 /* If this is a weak symbol, and there is a real definition, the
1217 processor independent code will have arranged for us to see the
1218 real definition first, and we can just use the same value. */
1219 if (h
->is_weakalias
)
1221 struct elf_link_hash_entry
*def
= weakdef (h
);
1222 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
1223 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
1224 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
1228 /* R_LARCH_COPY is not adept glibc, not to generate. */
1229 /* Can not print anything, because make check ld. */
1233 /* Allocate space in .plt, .got and associated reloc sections for
1237 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1239 struct bfd_link_info
*info
;
1240 struct loongarch_elf_link_hash_table
*htab
;
1241 struct elf_dyn_relocs
*p
;
1243 if (h
->root
.type
== bfd_link_hash_indirect
)
1246 if (h
->type
== STT_GNU_IFUNC
1250 info
= (struct bfd_link_info
*) inf
;
1251 htab
= loongarch_elf_hash_table (info
);
1252 bool dyn
= htab
->elf
.dynamic_sections_created
;
1253 BFD_ASSERT (htab
!= NULL
);
1257 asection
*plt
, *gotplt
, *relplt
;
1266 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1267 && h
->root
.type
== bfd_link_hash_undefweak
)
1269 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1273 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1274 && h
->type
!= STT_GNU_IFUNC
)
1277 plt
= htab
->elf
.splt
;
1278 gotplt
= htab
->elf
.sgotplt
;
1279 relplt
= htab
->elf
.srelplt
;
1281 else if (htab
->elf
.iplt
)
1283 /* .iplt only for IFUNC. */
1284 if (h
->type
!= STT_GNU_IFUNC
)
1287 plt
= htab
->elf
.iplt
;
1288 gotplt
= htab
->elf
.igotplt
;
1289 relplt
= htab
->elf
.irelplt
;
1295 plt
->size
= PLT_HEADER_SIZE
;
1297 h
->plt
.offset
= plt
->size
;
1298 plt
->size
+= PLT_ENTRY_SIZE
;
1299 gotplt
->size
+= GOT_ENTRY_SIZE
;
1300 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1302 /* If this symbol is not defined in a regular file, and we are
1303 not generating a shared library, then set the symbol to this
1304 location in the .plt. This is required to make function
1305 pointers compare as equal between the normal executable and
1306 the shared library. */
1307 if (!bfd_link_pic (info
)
1310 h
->root
.u
.def
.section
= plt
;
1311 h
->root
.u
.def
.value
= h
->plt
.offset
;
1319 h
->plt
.offset
= MINUS_ONE
;
1321 if (0 < h
->got
.refcount
)
1324 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1326 /* Make sure this symbol is output as a dynamic symbol.
1327 Undefined weak syms won't yet be marked as dynamic. */
1328 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1329 && h
->root
.type
== bfd_link_hash_undefweak
)
1331 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1336 h
->got
.offset
= s
->size
;
1337 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1340 bool need_reloc
= false;
1341 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, dyn
, h
, indx
,
1343 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1344 if (tls_type
& GOT_TLS_GD
)
1346 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1348 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1351 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1352 if (tls_type
& GOT_TLS_IE
)
1354 s
->size
+= GOT_ENTRY_SIZE
;
1356 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1359 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1360 if (tls_type
& GOT_TLS_GDESC
)
1362 s
->size
+= GOT_ENTRY_SIZE
* 2;
1363 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1369 s
->size
+= GOT_ENTRY_SIZE
;
1370 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1371 || h
->root
.type
!= bfd_link_hash_undefweak
)
1372 && (bfd_link_pic (info
)
1373 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
),
1375 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1376 /* Undefined weak symbol in static PIE resolves to 0 without
1377 any dynamic relocations. */
1378 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1382 h
->got
.offset
= MINUS_ONE
;
1384 if (h
->dyn_relocs
== NULL
)
1387 /* Extra dynamic relocate,
1389 * R_LARCH_TLS_DTPRELNN
1393 if (SYMBOL_CALLS_LOCAL (info
, h
))
1395 struct elf_dyn_relocs
**pp
;
1397 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1399 p
->count
-= p
->pc_count
;
1408 if (h
->root
.type
== bfd_link_hash_undefweak
)
1410 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
)
1411 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1412 || (!bfd_link_pic (info
) && h
->non_got_ref
))
1413 h
->dyn_relocs
= NULL
;
1414 else if (h
->dynindx
== -1 && !h
->forced_local
)
1416 /* Make sure this symbol is output as a dynamic symbol.
1417 Undefined weak syms won't yet be marked as dynamic. */
1418 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1421 if (h
->dynindx
== -1)
1422 h
->dyn_relocs
= NULL
;
1426 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1428 if (discarded_section (p
->sec
))
1430 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1431 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1437 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1438 For local def and ref ifunc,
1439 dynamic relocations are stored in
1440 1. rela.srelgot section in dynamic object (dll or exec).
1441 2. rela.irelplt section in static executable.
1442 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1443 instead of rela.srelplt. Glibc ELF loader will not support
1444 R_LARCH_IRELATIVE relocation in rela.plt. */
1447 local_allocate_ifunc_dyn_relocs (struct bfd_link_info
*info
,
1448 struct elf_link_hash_entry
*h
,
1449 struct elf_dyn_relocs
**head
,
1450 unsigned int plt_entry_size
,
1451 unsigned int plt_header_size
,
1452 unsigned int got_entry_size
,
1455 asection
*plt
, *gotplt
, *relplt
;
1456 struct elf_dyn_relocs
*p
;
1457 unsigned int sizeof_reloc
;
1458 const struct elf_backend_data
*bed
;
1459 struct elf_link_hash_table
*htab
;
1460 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1461 bool use_plt
= !avoid_plt
|| h
->plt
.refcount
> 0;
1462 bool need_dynreloc
= !use_plt
|| bfd_link_pic (info
);
1464 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1465 in executable or it isn't referenced via PLT, the address of
1466 the resolved function may be used. But in non-PIC executable,
1467 the address of its plt slot may be used. Pointer equality may
1468 not work correctly. PIE or non-PLT reference should be used if
1469 pointer equality is required here.
1471 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1472 backend should change it to the normal function and set its address
1473 to its PLT entry which should be resolved by R_*_IRELATIVE at
1474 run-time. All external references should be resolved to its PLT in
1477 && !(bfd_link_pde (info
) && h
->def_regular
)
1478 && (h
->dynindx
!= -1
1479 || info
->export_dynamic
)
1480 && h
->pointer_equality_needed
)
1482 info
->callbacks
->einfo
1483 /* xgettext:c-format. */
1484 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1485 "equality in `%pB' can not be used when making an "
1486 "executable; recompile with -fPIE and relink with -pie\n"),
1487 h
->root
.root
.string
,
1488 h
->root
.u
.def
.section
->owner
);
1489 bfd_set_error (bfd_error_bad_value
);
1493 htab
= elf_hash_table (info
);
1495 /* When the symbol is marked with regular reference, if PLT isn't used
1496 or we are building a PIC object, we must keep dynamic relocation
1497 if there is non-GOT reference and use PLT if there is PC-relative
1499 if (need_dynreloc
&& h
->ref_regular
)
1502 for (p
= *head
; p
!= NULL
; p
= p
->next
)
1506 /* Need dynamic relocations for non-GOT reference. */
1510 /* Must use PLT for PC-relative reference. */
1512 need_dynreloc
= bfd_link_pic (info
);
1520 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1521 if (h
->plt
.refcount
<= 0 && h
->got
.refcount
<= 0)
1523 h
->got
= htab
->init_got_offset
;
1524 h
->plt
= htab
->init_plt_offset
;
1529 /* Return and discard space for dynamic relocations against it if
1530 it is never referenced. */
1531 if (!h
->ref_regular
)
1533 if (h
->plt
.refcount
> 0
1534 || h
->got
.refcount
> 0)
1536 h
->got
= htab
->init_got_offset
;
1537 h
->plt
= htab
->init_plt_offset
;
1543 bed
= get_elf_backend_data (info
->output_bfd
);
1544 if (bed
->rela_plts_and_copies_p
)
1545 sizeof_reloc
= bed
->s
->sizeof_rela
;
1547 sizeof_reloc
= bed
->s
->sizeof_rel
;
1549 /* When building a static executable, use iplt, igot.plt and
1550 rela.iplt sections for STT_GNU_IFUNC symbols. */
1551 if (htab
->splt
!= NULL
)
1554 gotplt
= htab
->sgotplt
;
1555 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1556 relplt
= htab
->srelgot
;
1558 /* If this is the first plt entry and PLT is used, make room for
1559 the special first entry. */
1560 if (plt
->size
== 0 && use_plt
)
1561 plt
->size
+= plt_header_size
;
1566 gotplt
= htab
->igotplt
;
1567 relplt
= htab
->irelplt
;
1572 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1573 the original value for R_*_IRELATIVE. */
1574 h
->plt
.offset
= plt
->size
;
1576 /* Make room for this entry in the plt/iplt section. */
1577 plt
->size
+= plt_entry_size
;
1579 /* We also need to make an entry in the got.plt/got.iplt section,
1580 which will be placed in the got section by the linker script. */
1581 gotplt
->size
+= got_entry_size
;
1584 /* We also need to make an entry in the rela.plt/.rela.iplt
1585 section for GOTPLT relocation if PLT is used. */
1588 relplt
->size
+= sizeof_reloc
;
1589 relplt
->reloc_count
++;
1592 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1593 there is a non-GOT reference in a PIC object or PLT isn't used. */
1594 if (!need_dynreloc
|| !h
->non_got_ref
)
1597 /* Finally, allocate space. */
1601 bfd_size_type count
= 0;
1609 htab
->ifunc_resolvers
= count
!= 0;
1611 /* Dynamic relocations are stored in
1612 1. rela.srelgot section in PIC object.
1613 2. rela.srelgot section in dynamic executable.
1614 3. rela.irelplt section in static executable. */
1615 if (htab
->splt
!= NULL
)
1616 htab
->srelgot
->size
+= count
* sizeof_reloc
;
1619 relplt
->size
+= count
* sizeof_reloc
;
1620 relplt
->reloc_count
+= count
;
1624 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1625 and got has the PLT entry adddress. We will load the GOT entry
1626 with the PLT entry in finish_dynamic_symbol if it is used. For
1627 branch, it uses got.plt. For symbol value, if PLT is used,
1628 1. Use got.plt in a PIC object if it is forced local or not
1630 2. Use got.plt in a non-PIC object if pointer equality isn't
1632 3. Use got.plt in PIE.
1633 4. Use got.plt if got isn't used.
1634 5. Otherwise use got so that it can be shared among different
1635 objects at run-time.
1636 If PLT isn't used, always use got for symbol value.
1637 We only need to relocate got entry in PIC object or in dynamic
1638 executable without PLT. */
1640 && (h
->got
.refcount
<= 0
1641 || (bfd_link_pic (info
)
1642 && (h
->dynindx
== -1
1643 || h
->forced_local
))
1645 !h
->pointer_equality_needed
)
1646 || htab
->sgot
== NULL
))
1649 h
->got
.offset
= (bfd_vma
) -1;
1655 /* PLT isn't used. */
1656 h
->plt
.offset
= (bfd_vma
) -1;
1658 if (h
->got
.refcount
<= 0)
1660 /* GOT isn't need when there are only relocations for static
1662 h
->got
.offset
= (bfd_vma
) -1;
1666 h
->got
.offset
= htab
->sgot
->size
;
1667 htab
->sgot
->size
+= got_entry_size
;
1668 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1669 used. Otherwise, the GOT entry will be filled with the PLT
1670 entry and dynamic GOT relocation isn't needed. */
1673 /* For non-static executable, dynamic GOT relocation is in
1674 rela.got section, but for static executable, it is
1675 in rela.iplt section. */
1676 if (htab
->splt
!= NULL
)
1677 htab
->srelgot
->size
+= sizeof_reloc
;
1680 relplt
->size
+= sizeof_reloc
;
1681 relplt
->reloc_count
++;
1690 /* Allocate space in .plt, .got and associated reloc sections for
1691 ifunc dynamic relocs. */
1694 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1696 struct bfd_link_info
*info
;
1697 /* An example of a bfd_link_hash_indirect symbol is versioned
1698 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1699 -> __gxx_personality_v0(bfd_link_hash_defined)
1701 There is no need to process bfd_link_hash_indirect symbols here
1702 because we will also be presented with the concrete instance of
1703 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1704 called to copy all relevant data from the generic to the concrete
1706 if (h
->root
.type
== bfd_link_hash_indirect
)
1709 if (h
->root
.type
== bfd_link_hash_warning
)
1710 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1712 info
= (struct bfd_link_info
*) inf
;
1714 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1715 here if it is defined and referenced in a non-shared object. */
1716 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
1718 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1719 return local_allocate_ifunc_dyn_relocs (info
, h
,
1726 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1737 /* Allocate space in .plt, .got and associated reloc sections for
1738 ifunc dynamic relocs. */
1741 elfNN_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
1743 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1745 if (h
->type
!= STT_GNU_IFUNC
1749 || h
->root
.type
!= bfd_link_hash_defined
)
1752 return elfNN_allocate_ifunc_dynrelocs (h
, inf
);
1755 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1756 read-only sections. */
1759 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1763 if (h
->root
.type
== bfd_link_hash_indirect
)
1766 sec
= readonly_dynrelocs (h
);
1769 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1771 info
->flags
|= DF_TEXTREL
;
1772 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1773 "read-only section `%pA'\n"),
1774 sec
->owner
, h
->root
.root
.string
, sec
);
1776 /* Not an error, just cut short the traversal. */
1783 loongarch_elf_late_size_sections (bfd
*output_bfd
,
1784 struct bfd_link_info
*info
)
1786 struct loongarch_elf_link_hash_table
*htab
;
1791 htab
= loongarch_elf_hash_table (info
);
1792 BFD_ASSERT (htab
!= NULL
);
1793 dynobj
= htab
->elf
.dynobj
;
1797 if (htab
->elf
.dynamic_sections_created
)
1799 /* Set the contents of the .interp section to the interpreter. */
1800 if (bfd_link_executable (info
) && !info
->nointerp
)
1802 const char *interpreter
;
1803 s
= bfd_get_linker_section (dynobj
, ".interp");
1804 BFD_ASSERT (s
!= NULL
);
1806 if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS32
)
1807 interpreter
= "/lib32/ld.so.1";
1808 else if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS64
)
1809 interpreter
= "/lib64/ld.so.1";
1811 interpreter
= "/lib/ld.so.1";
1813 s
->contents
= (unsigned char *) interpreter
;
1814 s
->size
= strlen (interpreter
) + 1;
1818 /* Set up .got offsets for local syms, and space for local dynamic
1820 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
1822 bfd_signed_vma
*local_got
;
1823 bfd_signed_vma
*end_local_got
;
1824 char *local_tls_type
;
1825 bfd_size_type locsymcount
;
1826 Elf_Internal_Shdr
*symtab_hdr
;
1829 if (!is_loongarch_elf (ibfd
))
1832 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
1834 struct elf_dyn_relocs
*p
;
1836 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
1838 p
->count
-= p
->pc_count
;
1839 if (!bfd_is_abs_section (p
->sec
)
1840 && bfd_is_abs_section (p
->sec
->output_section
))
1842 /* Input section has been discarded, either because
1843 it is a copy of a linkonce section or due to
1844 linker script /DISCARD/, so we'll be discarding
1847 else if (0 < p
->count
)
1849 srel
= elf_section_data (p
->sec
)->sreloc
;
1850 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1851 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
1852 info
->flags
|= DF_TEXTREL
;
1857 local_got
= elf_local_got_refcounts (ibfd
);
1861 symtab_hdr
= &elf_symtab_hdr (ibfd
);
1862 locsymcount
= symtab_hdr
->sh_info
;
1863 end_local_got
= local_got
+ locsymcount
;
1864 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
1866 srel
= htab
->elf
.srelgot
;
1867 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
1871 *local_got
= s
->size
;
1872 if (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1874 /* TLS gd use two got. */
1875 if (*local_tls_type
& GOT_TLS_GD
)
1877 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1878 if (!bfd_link_executable (info
))
1879 srel
->size
+= sizeof (ElfNN_External_Rela
);
1882 /* TLS_DESC use two got. */
1883 if (*local_tls_type
& GOT_TLS_GDESC
)
1885 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1886 srel
->size
+= sizeof (ElfNN_External_Rela
);
1889 /* TLS ie and use one got. */
1890 if (*local_tls_type
& GOT_TLS_IE
)
1892 s
->size
+= GOT_ENTRY_SIZE
;
1893 if (!bfd_link_executable (info
))
1894 srel
->size
+= sizeof (ElfNN_External_Rela
);
1899 s
->size
+= GOT_ENTRY_SIZE
;
1900 srel
->size
+= sizeof (ElfNN_External_Rela
);
1904 *local_got
= MINUS_ONE
;
1908 /* Allocate global sym .plt and .got entries, and space for global
1909 sym dynamic relocs. */
1910 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
1912 /* Allocate global ifunc sym .plt and .got entries, and space for global
1913 ifunc sym dynamic relocs. */
1914 elf_link_hash_traverse (&htab
->elf
, elfNN_allocate_ifunc_dynrelocs
, info
);
1916 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1917 htab_traverse (htab
->loc_hash_table
,
1918 elfNN_allocate_local_ifunc_dynrelocs
, info
);
1920 /* Don't allocate .got.plt section if there are no PLT. */
1921 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
1922 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
1923 htab
->elf
.sgotplt
->size
= 0;
1925 /* The check_relocs and adjust_dynamic_symbol entry points have
1926 determined the sizes of the various dynamic sections. Allocate
1928 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
1930 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
1933 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
1934 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
1935 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
1937 /* Strip this section if we don't need it; see the
1940 else if (strncmp (s
->name
, ".rela", 5) == 0)
1944 /* We use the reloc_count field as a counter if we need
1945 to copy relocs into the output file. */
1951 /* It's not one of our sections. */
1957 /* If we don't need this section, strip it from the
1958 output file. This is mostly to handle .rela.bss and
1959 .rela.plt. We must create both sections in
1960 create_dynamic_sections, because they must be created
1961 before the linker maps input sections to output
1962 sections. The linker does that before
1963 adjust_dynamic_symbol is called, and it is that
1964 function which decides whether anything needs to go
1965 into these sections. */
1966 s
->flags
|= SEC_EXCLUDE
;
1970 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
1973 /* Allocate memory for the section contents. Zero the memory
1974 for the benefit of .rela.plt, which has 4 unused entries
1975 at the beginning, and we don't want garbage. */
1976 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
1977 if (s
->contents
== NULL
)
1981 if (elf_hash_table (info
)->dynamic_sections_created
)
1983 /* Add some entries to the .dynamic section. We fill in the
1984 values later, in loongarch_elf_finish_dynamic_sections, but we
1985 must add the entries now so that we get the correct size for
1986 the .dynamic section. The DT_DEBUG entry is filled in by the
1987 dynamic linker and used by the debugger. */
1988 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1990 if (bfd_link_executable (info
))
1992 if (!add_dynamic_entry (DT_DEBUG
, 0))
1996 if (htab
->elf
.srelplt
->size
!= 0)
1998 if (!add_dynamic_entry (DT_PLTGOT
, 0)
1999 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
2000 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2001 || !add_dynamic_entry (DT_JMPREL
, 0))
2005 if (!add_dynamic_entry (DT_RELA
, 0)
2006 || !add_dynamic_entry (DT_RELASZ
, 0)
2007 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2010 /* If any dynamic relocs apply to a read-only section,
2011 then we need a DT_TEXTREL entry. */
2012 if ((info
->flags
& DF_TEXTREL
) == 0)
2013 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
2015 if (info
->flags
& DF_TEXTREL
)
2017 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2019 /* Clear the DF_TEXTREL flag. It will be set again if we
2020 write out an actual text relocation; we may not, because
2021 at this point we do not know whether e.g. any .eh_frame
2022 absolute relocations have been converted to PC-relative. */
2023 info
->flags
&= ~DF_TEXTREL
;
2026 #undef add_dynamic_entry
2031 #define LARCH_LD_STACK_DEPTH 16
2032 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
2033 static size_t larch_stack_top
= 0;
2035 static bfd_reloc_status_type
2036 loongarch_push (int64_t val
)
2038 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
2039 return bfd_reloc_outofrange
;
2040 larch_opc_stack
[larch_stack_top
++] = val
;
2041 return bfd_reloc_ok
;
2044 static bfd_reloc_status_type
2045 loongarch_pop (int64_t *val
)
2047 if (larch_stack_top
== 0)
2048 return bfd_reloc_outofrange
;
2050 *val
= larch_opc_stack
[--larch_stack_top
];
2051 return bfd_reloc_ok
;
2054 static bfd_reloc_status_type
2055 loongarch_top (int64_t *val
)
2057 if (larch_stack_top
== 0)
2058 return bfd_reloc_outofrange
;
2060 *val
= larch_opc_stack
[larch_stack_top
- 1];
2061 return bfd_reloc_ok
;
2065 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
2067 BFD_ASSERT (s
&& s
->contents
);
2068 const struct elf_backend_data
*bed
;
2071 bed
= get_elf_backend_data (abfd
);
2072 if (!(s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
))
2073 BFD_ASSERT (s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
);
2074 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
2075 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
2078 /* Check rel->r_offset in range of contents. */
2079 static bfd_reloc_status_type
2080 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
2081 const asection
*input_section
)
2083 if (0 == strcmp(input_section
->name
, ".text")
2084 && rel
->r_offset
> input_section
->size
)
2085 return bfd_reloc_overflow
;
2087 return bfd_reloc_ok
;
2090 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2092 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2093 if (ret == bfd_reloc_ok) \
2095 ret = loongarch_pop (&op1); \
2096 if (ret == bfd_reloc_ok) \
2097 ret = loongarch_push (op3); \
2102 /* Write immediate to instructions. */
2104 static bfd_reloc_status_type
2105 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
2106 const asection
*input_section ATTRIBUTE_UNUSED
,
2107 reloc_howto_type
*howto
, bfd
*input_bfd
,
2108 bfd_byte
*contents
, bfd_vma reloc_val
)
2110 /* Adjust the immediate based on alignment and
2111 its position in the instruction. */
2112 if (!loongarch_adjust_reloc_bitsfield (input_bfd
, howto
, &reloc_val
))
2113 return bfd_reloc_overflow
;
2115 int bits
= bfd_get_reloc_size (howto
) * 8;
2116 uint64_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
2118 /* Write immediate to instruction. */
2119 insn
= (insn
& ~howto
->dst_mask
) | (reloc_val
& howto
->dst_mask
);
2121 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
2123 return bfd_reloc_ok
;
2126 static bfd_reloc_status_type
2127 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
2128 reloc_howto_type
*howto
, bfd_vma value
,
2129 bfd
*input_bfd
, bfd_byte
*contents
)
2131 int64_t opr1
, opr2
, opr3
;
2132 bfd_reloc_status_type r
= bfd_reloc_ok
;
2133 int bits
= bfd_get_reloc_size (howto
) * 8;
2135 switch (ELFNN_R_TYPE (rel
->r_info
))
2137 case R_LARCH_SOP_PUSH_PCREL
:
2138 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2139 case R_LARCH_SOP_PUSH_GPREL
:
2140 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2141 case R_LARCH_SOP_PUSH_TLS_GOT
:
2142 case R_LARCH_SOP_PUSH_TLS_GD
:
2143 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2144 r
= loongarch_push (value
);
2147 case R_LARCH_SOP_PUSH_DUP
:
2148 r
= loongarch_pop (&opr1
);
2149 if (r
== bfd_reloc_ok
)
2151 r
= loongarch_push (opr1
);
2152 if (r
== bfd_reloc_ok
)
2153 r
= loongarch_push (opr1
);
2157 case R_LARCH_SOP_ASSERT
:
2158 r
= loongarch_pop (&opr1
);
2159 if (r
!= bfd_reloc_ok
|| !opr1
)
2160 r
= bfd_reloc_notsupported
;
2163 case R_LARCH_SOP_NOT
:
2164 r
= loongarch_pop (&opr1
);
2165 if (r
== bfd_reloc_ok
)
2166 r
= loongarch_push (!opr1
);
2169 case R_LARCH_SOP_SUB
:
2170 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
2173 case R_LARCH_SOP_SL
:
2174 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
2177 case R_LARCH_SOP_SR
:
2178 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
2181 case R_LARCH_SOP_AND
:
2182 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
2185 case R_LARCH_SOP_ADD
:
2186 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
2189 case R_LARCH_SOP_IF_ELSE
:
2190 r
= loongarch_pop (&opr3
);
2191 if (r
== bfd_reloc_ok
)
2193 r
= loongarch_pop (&opr2
);
2194 if (r
== bfd_reloc_ok
)
2196 r
= loongarch_pop (&opr1
);
2197 if (r
== bfd_reloc_ok
)
2198 r
= loongarch_push (opr1
? opr2
: opr3
);
2203 case R_LARCH_SOP_POP_32_S_10_5
:
2204 case R_LARCH_SOP_POP_32_S_10_12
:
2205 case R_LARCH_SOP_POP_32_S_10_16
:
2206 case R_LARCH_SOP_POP_32_S_10_16_S2
:
2207 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
2208 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
2209 case R_LARCH_SOP_POP_32_S_5_20
:
2210 case R_LARCH_SOP_POP_32_U_10_12
:
2211 case R_LARCH_SOP_POP_32_U
:
2212 r
= loongarch_pop (&opr1
);
2213 if (r
!= bfd_reloc_ok
)
2215 r
= loongarch_check_offset (rel
, input_section
);
2216 if (r
!= bfd_reloc_ok
)
2219 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2221 contents
, (bfd_vma
)opr1
);
2224 case R_LARCH_TLS_DTPREL32
:
2226 case R_LARCH_TLS_DTPREL64
:
2228 r
= loongarch_check_offset (rel
, input_section
);
2229 if (r
!= bfd_reloc_ok
)
2232 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
2235 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2236 Because set/sub reloc pair not support multi-thread. While add/sub
2237 reloc pair process order not affect the final result.
2239 For add/sub reloc, the original value will be involved in the
2240 calculation. In order not to add/sub extra value, we write 0 to symbol
2241 address at assembly time.
2243 add/sub reloc bits determined by the value after symbol subtraction,
2246 add/sub reloc save part of the symbol value, so we only need to
2247 save howto->dst_mask bits. */
2251 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2252 contents
+ rel
->r_offset
);
2253 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2254 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2259 /* Not need to read the original value, just write the new value. */
2271 /* Because add/sub reloc is processed separately,
2272 so the high bits is invalid. */
2273 bfd_vma word
= value
& howto
->dst_mask
;
2274 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2279 case R_LARCH_ADD_ULEB128
:
2280 case R_LARCH_SUB_ULEB128
:
2282 unsigned int len
= 0;
2283 /* Before write uleb128, first read it to get it's length. */
2284 _bfd_read_unsigned_leb128 (input_bfd
, contents
+ rel
->r_offset
, &len
);
2285 loongarch_write_unsigned_leb128 (contents
+ rel
->r_offset
, len
, value
);
2290 /* For eh_frame and debug info. */
2291 case R_LARCH_32_PCREL
:
2292 case R_LARCH_64_PCREL
:
2294 value
-= sec_addr (input_section
) + rel
->r_offset
;
2295 value
+= rel
->r_addend
;
2296 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2297 contents
+ rel
->r_offset
);
2298 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2299 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2305 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2309 case R_LARCH_ABS_HI20
:
2310 case R_LARCH_ABS_LO12
:
2311 case R_LARCH_ABS64_LO20
:
2312 case R_LARCH_ABS64_HI12
:
2313 case R_LARCH_PCALA_HI20
:
2314 case R_LARCH_PCALA_LO12
:
2315 case R_LARCH_PCALA64_LO20
:
2316 case R_LARCH_PCALA64_HI12
:
2317 case R_LARCH_GOT_PC_HI20
:
2318 case R_LARCH_GOT_PC_LO12
:
2319 case R_LARCH_GOT64_PC_LO20
:
2320 case R_LARCH_GOT64_PC_HI12
:
2321 case R_LARCH_GOT_HI20
:
2322 case R_LARCH_GOT_LO12
:
2323 case R_LARCH_GOT64_LO20
:
2324 case R_LARCH_GOT64_HI12
:
2325 case R_LARCH_TLS_LE_HI20
:
2326 case R_LARCH_TLS_LE_LO12
:
2327 case R_LARCH_TLS_LE_HI20_R
:
2328 case R_LARCH_TLS_LE_LO12_R
:
2329 case R_LARCH_TLS_LE64_LO20
:
2330 case R_LARCH_TLS_LE64_HI12
:
2331 case R_LARCH_TLS_IE_PC_HI20
:
2332 case R_LARCH_TLS_IE_PC_LO12
:
2333 case R_LARCH_TLS_IE64_PC_LO20
:
2334 case R_LARCH_TLS_IE64_PC_HI12
:
2335 case R_LARCH_TLS_IE_HI20
:
2336 case R_LARCH_TLS_IE_LO12
:
2337 case R_LARCH_TLS_IE64_LO20
:
2338 case R_LARCH_TLS_IE64_HI12
:
2339 case R_LARCH_TLS_LD_PC_HI20
:
2340 case R_LARCH_TLS_LD_HI20
:
2341 case R_LARCH_TLS_GD_PC_HI20
:
2342 case R_LARCH_TLS_GD_HI20
:
2343 case R_LARCH_PCREL20_S2
:
2344 case R_LARCH_CALL36
:
2345 case R_LARCH_TLS_DESC_PC_HI20
:
2346 case R_LARCH_TLS_DESC_PC_LO12
:
2347 case R_LARCH_TLS_DESC64_PC_LO20
:
2348 case R_LARCH_TLS_DESC64_PC_HI12
:
2349 case R_LARCH_TLS_DESC_HI20
:
2350 case R_LARCH_TLS_DESC_LO12
:
2351 case R_LARCH_TLS_DESC64_LO20
:
2352 case R_LARCH_TLS_DESC64_HI12
:
2353 case R_LARCH_TLS_LD_PCREL20_S2
:
2354 case R_LARCH_TLS_GD_PCREL20_S2
:
2355 case R_LARCH_TLS_DESC_PCREL20_S2
:
2356 r
= loongarch_check_offset (rel
, input_section
);
2357 if (r
!= bfd_reloc_ok
)
2360 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2365 case R_LARCH_TLS_DESC_LD
:
2366 case R_LARCH_TLS_DESC_CALL
:
2371 case R_LARCH_TLS_LE_ADD_R
:
2375 r
= bfd_reloc_notsupported
;
2380 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2388 Elf_Internal_Sym
*sym
;
2389 struct elf_link_hash_entry
*h
;
2392 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
2393 static size_t larch_reloc_queue_head
= 0;
2394 static size_t larch_reloc_queue_tail
= 0;
2397 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
2398 Elf_Internal_Sym
*sym
)
2400 const char *ret
= NULL
;
2402 ret
= bfd_elf_string_from_elf_section (input_bfd
,
2403 elf_symtab_hdr (input_bfd
).sh_link
,
2406 ret
= h
->root
.root
.string
;
2408 if (ret
== NULL
|| *ret
== '\0')
2414 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
2415 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
2416 struct elf_link_hash_entry
*h
, bfd_vma addend
)
2418 if ((larch_reloc_queue_head
== 0
2419 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
2420 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
2421 larch_reloc_queue_head
=
2422 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2423 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
2424 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
2425 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
2426 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
2427 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
2428 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
2429 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
2430 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
2431 larch_reloc_queue_tail
=
2432 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2436 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
2438 size_t i
= larch_reloc_queue_head
;
2440 asection
*section
= NULL
;
2441 bfd_vma r_offset
= 0;
2443 p ("Dump relocate record:\n");
2444 p ("stack top\t\trelocation name\t\tsymbol");
2445 while (i
!= larch_reloc_queue_tail
)
2447 if (a_bfd
!= larch_reloc_queue
[i
].bfd
2448 || section
!= larch_reloc_queue
[i
].section
2449 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
2451 a_bfd
= larch_reloc_queue
[i
].bfd
;
2452 section
= larch_reloc_queue
[i
].section
;
2453 r_offset
= larch_reloc_queue
[i
].r_offset
;
2454 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
2455 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
2459 inited
= 1, p ("...\n");
2461 reloc_howto_type
*howto
=
2462 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
2463 larch_reloc_queue
[i
].r_type
);
2464 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
2465 howto
? howto
->name
: "<unknown reloc>",
2466 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
2467 larch_reloc_queue
[i
].sym
));
2469 long addend
= larch_reloc_queue
[i
].addend
;
2471 p (" - %ld", -addend
);
2472 else if (0 < addend
)
2473 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
2476 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2479 "-- Record dump end --\n\n");
2483 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
2485 asection
*input_section
,
2486 Elf_Internal_Rela
*rel
,
2487 reloc_howto_type
*howto
,
2488 bfd_reloc_status_type rtype
,
2496 /* 'dangerous' means we do it but can't promise it's ok
2497 'unsupport' means out of ability of relocation type
2498 'undefined' means we can't deal with the undefined symbol. */
2499 case bfd_reloc_undefined
:
2500 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
2501 rel
->r_offset
, true);
2502 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2503 input_bfd
, input_section
, rel
->r_offset
,
2505 is_undefweak
? "[undefweak] " : "", name
, msg
);
2507 case bfd_reloc_dangerous
:
2508 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2509 input_bfd
, input_section
, rel
->r_offset
,
2511 is_undefweak
? "[undefweak] " : "", name
, msg
);
2514 case bfd_reloc_notsupported
:
2515 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2516 input_bfd
, input_section
, rel
->r_offset
,
2518 is_undefweak
? "[undefweak] " : "", name
, msg
);
2526 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2527 hi20 immediate need to add 0x1.
2528 For example: pc 0x120000000, symbol 0x120000812
2529 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2530 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2531 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2534 pcalau12i $t0, hi20 (0x1)
2535 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2536 addi.d $t0, $t0, lo12 (0x812)
2537 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2538 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2540 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2542 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
2543 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2545 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2546 relocation = (relocation & ~(bfd_vma)0xfff) \
2547 - (pc & ~(bfd_vma)0xfff); \
2549 relocation += 0x1000; \
2552 /* Handle problems caused by symbol extensions in TLS LE, The processing
2553 is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
2554 #define RELOCATE_TLS_TP32_HI20(relocation) \
2556 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2558 relocation += 0x800; \
2559 relocation = relocation & ~(bfd_vma)0xfff; \
2562 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2563 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2565 lo12: 0x1812348ffff812 & 0xfff = 0x812
2566 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2567 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2570 pcalau12i $t1, hi20 (0x80000)
2571 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2572 = 0x11000010000100 + 0xffffffff80000000
2574 addi.d $t0, $zero, lo12 (0x812)
2575 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2576 lo20 need to sub 0x1)
2577 lu32i.d $t0, lo20 (0x71234)
2578 $t0 = {0x71234, 0xfffff812}
2580 lu52i.d $t0, hi12 (0x0)
2581 $t0 = {0x0, 0x71234fffff812}
2584 $t1 = 0x10ffff90000000 + 0x71234fffff812
2585 = 0x1812348ffff812. */
2586 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2588 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2589 relocation = (relocation & ~(bfd_vma)0xfff) \
2590 - ((pc) & ~(bfd_vma)0xfff); \
2592 relocation += (0x1000 - 0x100000000); \
2593 if (relocation & 0x80000000) \
2594 relocation += 0x100000000; \
2598 /* Compute the tp/dtp offset of a tls symbol.
2599 It is dtp offset in dynamic tls model (gd/ld) and tp
2600 offset in static tls model (ie/le). Both offsets are
2601 calculated the same way on LoongArch, so the same
2602 function is used. */
2604 tlsoff (struct bfd_link_info
*info
, bfd_vma addr
)
2606 /* If tls_sec is NULL, we should have signalled an error already. */
2607 if (elf_hash_table (info
)->tls_sec
== NULL
)
2609 return addr
- elf_hash_table (info
)->tls_sec
->vma
;
2614 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
2615 bfd
*input_bfd
, asection
*input_section
,
2616 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
2617 Elf_Internal_Sym
*local_syms
,
2618 asection
**local_sections
)
2620 Elf_Internal_Rela
*rel
;
2621 Elf_Internal_Rela
*relend
;
2623 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
2624 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
2625 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2626 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
2627 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
2628 bool is_pic
= bfd_link_pic (info
);
2629 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
2630 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
2631 asection
*got
= htab
->elf
.sgot
;
2633 relend
= relocs
+ input_section
->reloc_count
;
2634 for (rel
= relocs
; rel
< relend
; rel
++)
2636 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
2637 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2638 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
2639 reloc_howto_type
*howto
= NULL
;
2640 asection
*sec
= NULL
;
2641 Elf_Internal_Sym
*sym
= NULL
;
2642 struct elf_link_hash_entry
*h
= NULL
;
2644 bfd_reloc_status_type r
= bfd_reloc_ok
;
2645 bool is_ie
, is_desc
, is_undefweak
, unresolved_reloc
, defined_local
;
2646 bool resolved_local
, resolved_dynly
, resolved_to_const
;
2648 bfd_vma relocation
, off
, ie_off
, desc_off
;
2651 /* When an unrecognized relocation is encountered, which usually
2652 occurs when using a newer assembler but an older linker, an error
2653 should be reported instead of continuing to the next relocation. */
2654 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
2656 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
2658 if (r_type
== R_LARCH_GNU_VTINHERIT
|| r_type
== R_LARCH_GNU_VTENTRY
)
2661 /* This is a final link. */
2662 if (r_symndx
< symtab_hdr
->sh_info
)
2664 is_undefweak
= false;
2665 unresolved_reloc
= false;
2666 sym
= local_syms
+ r_symndx
;
2667 sec
= local_sections
[r_symndx
];
2668 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
2670 /* Relocate against local STT_GNU_IFUNC symbol. */
2671 if (!bfd_link_relocatable (info
)
2672 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2674 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
2679 /* Set STT_GNU_IFUNC symbol value. */
2680 h
->root
.u
.def
.value
= sym
->st_value
;
2681 h
->root
.u
.def
.section
= sec
;
2683 defined_local
= true;
2684 resolved_local
= true;
2685 resolved_dynly
= false;
2686 resolved_to_const
= false;
2688 /* Calc in funtion elf_link_input_bfd,
2689 * if #define elf_backend_rela_normal to 1. */
2690 if (bfd_link_relocatable (info
)
2691 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2696 bool warned
, ignored
;
2698 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2699 r_symndx
, symtab_hdr
, sym_hashes
,
2701 unresolved_reloc
, warned
, ignored
);
2702 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2704 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2705 symbol. And 'dynamic_undefined_weak' specify what to do when
2706 meeting undefweak. */
2708 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
2710 defined_local
= false;
2711 resolved_local
= false;
2712 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
2713 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
2714 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
2718 /* Symbol undefined offen means failed already. I don't know why
2719 'warned' here but I guess it want to continue relocating as if
2720 no error occures to find other errors as more as possible. */
2722 /* To avoid generating warning messages about truncated
2723 relocations, set the relocation's address to be the same as
2724 the start of this section. */
2725 relocation
= (input_section
->output_section
2726 ? input_section
->output_section
->vma
2729 defined_local
= relocation
!= 0;
2730 resolved_local
= defined_local
;
2731 resolved_to_const
= !resolved_local
;
2732 resolved_dynly
= false;
2736 defined_local
= !unresolved_reloc
&& !ignored
;
2738 defined_local
&& SYMBOL_REFERENCES_LOCAL (info
, h
);
2739 resolved_dynly
= !resolved_local
;
2740 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
2744 name
= loongarch_sym_name (input_bfd
, h
, sym
);
2746 if (sec
!= NULL
&& discarded_section (sec
))
2747 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
2748 1, relend
, howto
, 0, contents
);
2750 if (bfd_link_relocatable (info
))
2753 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2754 from removed linkonce sections, or sections discarded by a linker
2755 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2756 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
2758 defined_local
= false;
2759 resolved_local
= false;
2760 resolved_dynly
= false;
2761 resolved_to_const
= true;
2764 /* The ifunc reference generate plt. */
2765 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
2767 defined_local
= true;
2768 resolved_local
= true;
2769 resolved_dynly
= false;
2770 resolved_to_const
= false;
2771 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2774 unresolved_reloc
= resolved_dynly
;
2776 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
2778 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2780 BFD_ASSERT (!resolved_local
|| defined_local
);
2786 case R_LARCH_MARK_PCREL
:
2787 case R_LARCH_MARK_LA
:
2789 r
= bfd_reloc_continue
;
2790 unresolved_reloc
= false;
2795 if (resolved_dynly
|| (is_pic
&& resolved_local
))
2797 Elf_Internal_Rela outrel
;
2799 /* When generating a shared object, these relocations are copied
2800 into the output file to be resolved at run time. */
2802 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2806 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2807 && (input_section
->flags
& SEC_ALLOC
));
2809 outrel
.r_offset
+= sec_addr (input_section
);
2811 /* A pointer point to a ifunc symbol. */
2812 if (h
&& h
->type
== STT_GNU_IFUNC
)
2814 if (h
->dynindx
== -1)
2816 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2817 outrel
.r_addend
= (h
->root
.u
.def
.value
2818 + h
->root
.u
.def
.section
->output_section
->vma
2819 + h
->root
.u
.def
.section
->output_offset
);
2823 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2824 outrel
.r_addend
= 0;
2827 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
2830 if (htab
->elf
.splt
!= NULL
)
2831 sreloc
= htab
->elf
.srelgot
;
2833 sreloc
= htab
->elf
.irelplt
;
2838 if (bfd_link_pic (info
))
2839 sreloc
= htab
->elf
.irelifunc
;
2840 else if (htab
->elf
.splt
!= NULL
)
2841 sreloc
= htab
->elf
.srelgot
;
2843 sreloc
= htab
->elf
.irelplt
;
2846 else if (resolved_dynly
)
2848 if (h
->dynindx
== -1)
2849 outrel
.r_info
= ELFNN_R_INFO (0, r_type
);
2851 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2853 outrel
.r_addend
= rel
->r_addend
;
2857 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2858 outrel
.r_addend
= relocation
+ rel
->r_addend
;
2861 /* No alloc space of func allocate_dynrelocs. */
2862 if (unresolved_reloc
2863 && !(h
&& (h
->is_weakalias
|| !h
->dyn_relocs
)))
2864 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2867 relocation
+= rel
->r_addend
;
2877 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2878 contents
+ rel
->r_offset
);
2879 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2890 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2891 contents
+ rel
->r_offset
);
2892 relocation
= old_value
- relocation
- rel
->r_addend
;
2896 case R_LARCH_ADD_ULEB128
:
2897 case R_LARCH_SUB_ULEB128
:
2899 /* Get the value and length of the uleb128 data. */
2900 unsigned int len
= 0;
2901 bfd_vma old_value
= _bfd_read_unsigned_leb128 (input_bfd
,
2902 contents
+ rel
->r_offset
, &len
);
2904 if (R_LARCH_ADD_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2905 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2906 else if (R_LARCH_SUB_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2907 relocation
= old_value
- relocation
- rel
->r_addend
;
2909 bfd_vma mask
= (1 << (7 * len
)) - 1;
2914 case R_LARCH_TLS_DTPREL32
:
2915 case R_LARCH_TLS_DTPREL64
:
2918 Elf_Internal_Rela outrel
;
2920 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2923 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2924 && (input_section
->flags
& SEC_ALLOC
));
2925 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2926 outrel
.r_offset
+= sec_addr (input_section
);
2927 outrel
.r_addend
= rel
->r_addend
;
2928 if (unresolved_reloc
)
2929 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2933 if (resolved_to_const
)
2934 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
2936 bfd_reloc_notsupported
,
2941 if (!elf_hash_table (info
)->tls_sec
)
2943 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2944 input_section
, rel
, howto
, bfd_reloc_notsupported
,
2945 is_undefweak
, name
, "TLS section not be created");
2948 relocation
= tlsoff (info
, relocation
);
2952 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2953 input_section
, rel
, howto
, bfd_reloc_undefined
,
2955 "TLS LE just can be resolved local only.");
2960 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2963 if (!elf_hash_table (info
)->tls_sec
)
2964 fatal
= (loongarch_reloc_is_fatal
2965 (info
, input_bfd
, input_section
, rel
, howto
,
2966 bfd_reloc_notsupported
, is_undefweak
, name
,
2967 "TLS section not be created"));
2969 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2972 fatal
= (loongarch_reloc_is_fatal
2973 (info
, input_bfd
, input_section
, rel
, howto
,
2974 bfd_reloc_undefined
, is_undefweak
, name
,
2975 "TLS LE just can be resolved local only."));
2978 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2982 fatal
= (loongarch_reloc_is_fatal
2983 (info
, input_bfd
, input_section
, rel
, howto
,
2984 bfd_reloc_dangerous
, is_undefweak
, name
,
2985 "Someone require us to resolve undefweak "
2986 "symbol dynamically. \n"
2987 "But this reloc can't be done. "
2988 "I think I can't throw error "
2990 "so I resolved it to 0. "
2991 "I suggest to re-compile with '-fpic'."));
2994 unresolved_reloc
= false;
2998 if (resolved_to_const
)
3000 relocation
+= rel
->r_addend
;
3006 fatal
= (loongarch_reloc_is_fatal
3007 (info
, input_bfd
, input_section
, rel
, howto
,
3008 bfd_reloc_notsupported
, is_undefweak
, name
,
3009 "Under PIC we don't know load address. Re-compile "
3016 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
3018 fatal
= (loongarch_reloc_is_fatal
3019 (info
, input_bfd
, input_section
, rel
, howto
,
3020 bfd_reloc_undefined
, is_undefweak
, name
,
3021 "Can't be resolved dynamically. Try to re-compile "
3026 if (rel
->r_addend
!= 0)
3028 fatal
= (loongarch_reloc_is_fatal
3029 (info
, input_bfd
, input_section
, rel
, howto
,
3030 bfd_reloc_notsupported
, is_undefweak
, name
,
3031 "Shouldn't be with r_addend."));
3035 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3036 unresolved_reloc
= false;
3042 relocation
+= rel
->r_addend
;
3048 case R_LARCH_SOP_PUSH_PCREL
:
3049 case R_LARCH_SOP_PUSH_PLT_PCREL
:
3050 unresolved_reloc
= false;
3058 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3061 fatal
= (loongarch_reloc_is_fatal
3062 (info
, input_bfd
, input_section
, rel
, howto
,
3063 bfd_reloc_dangerous
, is_undefweak
, name
,
3064 "Undefweak need to be resolved dynamically, "
3065 "but PLT stub doesn't represent."));
3070 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
3072 fatal
= (loongarch_reloc_is_fatal
3073 (info
, input_bfd
, input_section
, rel
, howto
,
3074 bfd_reloc_undefined
, is_undefweak
, name
,
3075 "PLT stub does not represent and "
3076 "symbol not defined."));
3082 else /* if (resolved_dynly) */
3084 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
3085 fatal
= (loongarch_reloc_is_fatal
3086 (info
, input_bfd
, input_section
, rel
, howto
,
3087 bfd_reloc_dangerous
, is_undefweak
, name
,
3088 "Internal: PLT stub doesn't represent. "
3089 "Resolve it with pcrel"));
3096 if ((i
& 1) == 0 && defined_local
)
3099 relocation
+= rel
->r_addend
;
3103 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
3105 if (rel
->r_addend
!= 0)
3107 fatal
= (loongarch_reloc_is_fatal
3108 (info
, input_bfd
, input_section
, rel
, howto
,
3109 bfd_reloc_notsupported
, is_undefweak
, name
,
3110 "PLT shouldn't be with r_addend."));
3113 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3119 case R_LARCH_SOP_PUSH_GPREL
:
3120 unresolved_reloc
= false;
3122 if (rel
->r_addend
!= 0)
3124 fatal
= (loongarch_reloc_is_fatal
3125 (info
, input_bfd
, input_section
, rel
, howto
,
3126 bfd_reloc_notsupported
, is_undefweak
, name
,
3127 "Shouldn't be with r_addend."));
3133 off
= h
->got
.offset
& (~1);
3135 if (h
->got
.offset
== MINUS_ONE
&& h
->type
!= STT_GNU_IFUNC
)
3137 fatal
= (loongarch_reloc_is_fatal
3138 (info
, input_bfd
, input_section
, rel
, howto
,
3139 bfd_reloc_notsupported
, is_undefweak
, name
,
3140 "Internal: GOT entry doesn't represent."));
3144 /* Hidden symbol not has .got entry, only .got.plt entry
3145 so gprel is (plt - got). */
3146 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3148 if (h
->plt
.offset
== (bfd_vma
) -1)
3153 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3154 off
= plt_index
* GOT_ENTRY_SIZE
;
3156 if (htab
->elf
.splt
!= NULL
)
3158 /* Section .plt header is 2 times of plt entry. */
3159 off
= sec_addr (htab
->elf
.sgotplt
) + off
3160 - sec_addr (htab
->elf
.sgot
);
3164 /* Section iplt not has plt header. */
3165 off
= sec_addr (htab
->elf
.igotplt
) + off
3166 - sec_addr (htab
->elf
.sgot
);
3170 if ((h
->got
.offset
& 1) == 0)
3172 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3173 bfd_link_pic (info
), h
)
3174 && ((bfd_link_pic (info
)
3175 && SYMBOL_REFERENCES_LOCAL (info
, h
))))
3177 /* This is actually a static link, or it is a
3178 -Bsymbolic link and the symbol is defined
3179 locally, or the symbol was forced to be local
3180 because of a version file. We must initialize
3181 this entry in the global offset table. Since the
3182 offset must always be a multiple of the word size,
3183 we use the least significant bit to record whether
3184 we have initialized it already.
3186 When doing a dynamic link, we create a rela.got
3187 relocation entry to initialize the value. This
3188 is done in the finish_dynamic_symbol routine. */
3192 fatal
= (loongarch_reloc_is_fatal
3193 (info
, input_bfd
, input_section
, rel
, howto
,
3194 bfd_reloc_dangerous
, is_undefweak
, name
,
3195 "Internal: here shouldn't dynamic."));
3198 if (!(defined_local
|| resolved_to_const
))
3200 fatal
= (loongarch_reloc_is_fatal
3201 (info
, input_bfd
, input_section
, rel
, howto
,
3202 bfd_reloc_undefined
, is_undefweak
, name
,
3208 Elf_Internal_Rela outrel
;
3209 /* We need to generate a R_LARCH_RELATIVE reloc
3210 for the dynamic linker. */
3211 s
= htab
->elf
.srelgot
;
3214 fatal
= loongarch_reloc_is_fatal
3216 input_section
, rel
, howto
,
3217 bfd_reloc_notsupported
, is_undefweak
, name
,
3218 "Internal: '.rel.got' not represent");
3222 outrel
.r_offset
= sec_addr (got
) + off
;
3223 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3224 outrel
.r_addend
= relocation
; /* Link-time addr. */
3225 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3227 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3233 if (!local_got_offsets
)
3235 fatal
= (loongarch_reloc_is_fatal
3236 (info
, input_bfd
, input_section
, rel
, howto
,
3237 bfd_reloc_notsupported
, is_undefweak
, name
,
3238 "Internal: local got offsets not reporesent."));
3242 off
= local_got_offsets
[r_symndx
] & (~1);
3244 if (local_got_offsets
[r_symndx
] == MINUS_ONE
)
3246 fatal
= (loongarch_reloc_is_fatal
3247 (info
, input_bfd
, input_section
, rel
, howto
,
3248 bfd_reloc_notsupported
, is_undefweak
, name
,
3249 "Internal: GOT entry doesn't represent."));
3253 /* The offset must always be a multiple of the word size.
3254 So, we can use the least significant bit to record
3255 whether we have already processed this entry. */
3256 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3261 Elf_Internal_Rela outrel
;
3262 /* We need to generate a R_LARCH_RELATIVE reloc
3263 for the dynamic linker. */
3264 s
= htab
->elf
.srelgot
;
3267 fatal
= (loongarch_reloc_is_fatal
3268 (info
, input_bfd
, input_section
, rel
, howto
,
3269 bfd_reloc_notsupported
, is_undefweak
, name
,
3270 "Internal: '.rel.got' not represent"));
3274 outrel
.r_offset
= sec_addr (got
) + off
;
3275 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3276 outrel
.r_addend
= relocation
; /* Link-time addr. */
3277 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3280 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3281 local_got_offsets
[r_symndx
] |= 1;
3288 case R_LARCH_SOP_PUSH_TLS_GOT
:
3289 case R_LARCH_SOP_PUSH_TLS_GD
:
3291 unresolved_reloc
= false;
3292 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
3295 bfd_vma got_off
= 0;
3298 got_off
= h
->got
.offset
;
3303 got_off
= local_got_offsets
[r_symndx
];
3304 local_got_offsets
[r_symndx
] |= 1;
3307 BFD_ASSERT (got_off
!= MINUS_ONE
);
3310 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3311 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3312 ie_off
= 2 * GOT_ENTRY_SIZE
;
3314 if ((got_off
& 1) == 0)
3316 Elf_Internal_Rela rela
;
3317 asection
*srel
= htab
->elf
.srelgot
;
3318 bfd_vma tls_block_off
= 0;
3320 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3322 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3323 tls_block_off
= relocation
3324 - elf_hash_table (info
)->tls_sec
->vma
;
3327 if (tls_type
& GOT_TLS_GD
)
3329 rela
.r_offset
= sec_addr (got
) + got_off
;
3331 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3333 /* Local sym, used in exec, set module id 1. */
3334 if (bfd_link_executable (info
))
3335 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3338 rela
.r_info
= ELFNN_R_INFO (0,
3339 R_LARCH_TLS_DTPMODNN
);
3340 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3343 bfd_put_NN (output_bfd
, tls_block_off
,
3344 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3346 /* Dynamic resolved. */
3349 /* Dynamic relocate module id. */
3350 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3351 R_LARCH_TLS_DTPMODNN
);
3352 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3354 /* Dynamic relocate offset of block. */
3355 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3356 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3357 R_LARCH_TLS_DTPRELNN
);
3358 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3361 if (tls_type
& GOT_TLS_IE
)
3363 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3364 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3366 /* Local sym, used in exec, set module id 1. */
3367 if (!bfd_link_executable (info
))
3369 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3370 rela
.r_addend
= tls_block_off
;
3371 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3374 bfd_put_NN (output_bfd
, tls_block_off
,
3375 got
->contents
+ got_off
+ ie_off
);
3377 /* Dynamic resolved. */
3380 /* Dynamic relocate offset of block. */
3381 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3382 R_LARCH_TLS_TPRELNN
);
3384 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3389 relocation
= (got_off
& (~(bfd_vma
)1)) + (is_ie
? ie_off
: 0);
3393 /* New reloc types. */
3397 case R_LARCH_CALL36
:
3398 unresolved_reloc
= false;
3407 relocation
+= rel
->r_addend
;
3409 else if (resolved_dynly
)
3412 && (h
->plt
.offset
!= MINUS_ONE
3413 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3414 && rel
->r_addend
== 0);
3415 if (h
&& h
->plt
.offset
== MINUS_ONE
3416 && ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3419 relocation
+= rel
->r_addend
;
3422 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3427 case R_LARCH_ABS_HI20
:
3428 case R_LARCH_ABS_LO12
:
3429 case R_LARCH_ABS64_LO20
:
3430 case R_LARCH_ABS64_HI12
:
3434 BFD_ASSERT (resolved_dynly
);
3438 else if (resolved_to_const
|| resolved_local
)
3440 relocation
+= rel
->r_addend
;
3442 else if (resolved_dynly
)
3444 unresolved_reloc
= false;
3445 BFD_ASSERT ((plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
)
3446 && rel
->r_addend
== 0);
3447 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3452 case R_LARCH_PCREL20_S2
:
3453 unresolved_reloc
= false;
3454 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3455 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3457 relocation
+= rel
->r_addend
;
3461 case R_LARCH_PCALA_HI20
:
3462 unresolved_reloc
= false;
3463 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3464 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3466 relocation
+= rel
->r_addend
;
3468 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3471 case R_LARCH_TLS_LE_HI20_R
:
3472 relocation
+= rel
->r_addend
;
3473 relocation
= tlsoff (info
, relocation
);
3474 RELOCATE_TLS_TP32_HI20 (relocation
);
3477 case R_LARCH_PCALA_LO12
:
3478 /* Not support if sym_addr in 2k page edge.
3479 pcalau12i pc_hi20 (sym_addr)
3480 ld.w/d pc_lo12 (sym_addr)
3481 ld.w/d pc_lo12 (sym_addr + x)
3483 can not calc correct address
3484 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3486 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3487 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3489 relocation
+= rel
->r_addend
;
3491 /* For 2G jump, generate pcalau12i, jirl. */
3492 /* If use jirl, turns to R_LARCH_B16. */
3493 uint32_t insn
= bfd_get (32, input_bfd
, contents
+ rel
->r_offset
);
3494 if ((insn
& 0x4c000000) == 0x4c000000)
3496 relocation
&= 0xfff;
3497 /* Signed extend. */
3498 relocation
= (relocation
^ 0x800) - 0x800;
3500 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_B16
);
3501 howto
= loongarch_elf_rtype_to_howto (input_bfd
, R_LARCH_B16
);
3505 case R_LARCH_PCALA64_HI12
:
3508 case R_LARCH_PCALA64_LO20
:
3509 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3510 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3512 relocation
+= rel
->r_addend
;
3514 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
3518 case R_LARCH_GOT_PC_HI20
:
3519 case R_LARCH_GOT_HI20
:
3520 /* Calc got offset. */
3522 unresolved_reloc
= false;
3523 BFD_ASSERT (rel
->r_addend
== 0);
3525 bfd_vma got_off
= 0;
3528 /* GOT ref or ifunc. */
3529 BFD_ASSERT (h
->got
.offset
!= MINUS_ONE
3530 || h
->type
== STT_GNU_IFUNC
);
3532 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3533 /* Hidden symbol not has got entry,
3534 * only got.plt entry so it is (plt - got). */
3535 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3538 if (htab
->elf
.splt
!= NULL
)
3540 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
)
3542 got_off
= sec_addr (htab
->elf
.sgotplt
)
3543 + GOTPLT_HEADER_SIZE
3544 + (idx
* GOT_ENTRY_SIZE
)
3545 - sec_addr (htab
->elf
.sgot
);
3549 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3550 got_off
= sec_addr (htab
->elf
.sgotplt
)
3551 + (idx
* GOT_ENTRY_SIZE
)
3552 - sec_addr (htab
->elf
.sgot
);
3556 if ((h
->got
.offset
& 1) == 0)
3558 /* We need to generate a R_LARCH_RELATIVE reloc once
3559 * in loongarch_elf_finish_dynamic_symbol or now,
3560 * call finish_dyn && nopic
3561 * or !call finish_dyn && pic. */
3562 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3563 bfd_link_pic (info
),
3565 && bfd_link_pic (info
)
3566 && SYMBOL_REFERENCES_LOCAL (info
, h
))
3568 Elf_Internal_Rela rela
;
3569 rela
.r_offset
= sec_addr (got
) + got_off
;
3570 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3571 rela
.r_addend
= relocation
;
3572 loongarch_elf_append_rela (output_bfd
,
3573 htab
->elf
.srelgot
, &rela
);
3576 bfd_put_NN (output_bfd
, relocation
,
3577 got
->contents
+ got_off
);
3582 BFD_ASSERT (local_got_offsets
3583 && local_got_offsets
[r_symndx
] != MINUS_ONE
);
3585 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3586 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3588 if (bfd_link_pic (info
))
3590 Elf_Internal_Rela rela
;
3591 rela
.r_offset
= sec_addr (got
) + got_off
;
3592 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3593 rela
.r_addend
= relocation
;
3594 loongarch_elf_append_rela (output_bfd
,
3595 htab
->elf
.srelgot
, &rela
);
3597 local_got_offsets
[r_symndx
] |= 1;
3599 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ got_off
);
3602 relocation
= got_off
+ sec_addr (got
);
3605 if (r_type
== R_LARCH_GOT_PC_HI20
)
3606 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3610 case R_LARCH_GOT_PC_LO12
:
3611 case R_LARCH_GOT64_PC_LO20
:
3612 case R_LARCH_GOT64_PC_HI12
:
3613 case R_LARCH_GOT_LO12
:
3614 case R_LARCH_GOT64_LO20
:
3615 case R_LARCH_GOT64_HI12
:
3617 unresolved_reloc
= false;
3620 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3622 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3624 if (h
&& h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3627 if (htab
->elf
.splt
!= NULL
)
3628 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
3630 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3632 got_off
= sec_addr (htab
->elf
.sgotplt
)
3633 + GOTPLT_HEADER_SIZE
3634 + (idx
* GOT_ENTRY_SIZE
)
3635 - sec_addr (htab
->elf
.sgot
);
3638 relocation
= got_off
+ sec_addr (got
);
3641 if (r_type
== R_LARCH_GOT64_PC_HI12
)
3642 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
3643 else if (r_type
== R_LARCH_GOT64_PC_LO20
)
3644 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
3648 case R_LARCH_TLS_LE_HI20
:
3649 case R_LARCH_TLS_LE_LO12
:
3650 case R_LARCH_TLS_LE_LO12_R
:
3651 case R_LARCH_TLS_LE64_LO20
:
3652 case R_LARCH_TLS_LE64_HI12
:
3653 BFD_ASSERT (resolved_local
&& elf_hash_table (info
)->tls_sec
);
3655 relocation
+= rel
->r_addend
;
3656 relocation
= tlsoff (info
, relocation
);
3659 /* TLS IE LD/GD process separately is troublesome.
3660 When a symbol is both ie and LD/GD, h->got.off |= 1
3661 make only one type be relocated. We must use
3662 h->got.offset |= 1 and h->got.offset |= 2
3663 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3664 (IE LD/GD and reusable GOT reloc) must change to
3665 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3667 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3669 case R_LARCH_TLS_IE_PC_HI20
:
3670 case R_LARCH_TLS_IE_HI20
:
3671 case R_LARCH_TLS_LD_PC_HI20
:
3672 case R_LARCH_TLS_LD_HI20
:
3673 case R_LARCH_TLS_GD_PC_HI20
:
3674 case R_LARCH_TLS_GD_HI20
:
3675 case R_LARCH_TLS_DESC_PC_HI20
:
3676 case R_LARCH_TLS_DESC_HI20
:
3677 case R_LARCH_TLS_LD_PCREL20_S2
:
3678 case R_LARCH_TLS_GD_PCREL20_S2
:
3679 case R_LARCH_TLS_DESC_PCREL20_S2
:
3680 BFD_ASSERT (rel
->r_addend
== 0);
3681 unresolved_reloc
= false;
3683 if (r_type
== R_LARCH_TLS_IE_PC_HI20
3684 || r_type
== R_LARCH_TLS_IE_HI20
)
3687 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
3688 || r_type
== R_LARCH_TLS_DESC_HI20
3689 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
3692 bfd_vma got_off
= 0;
3695 got_off
= h
->got
.offset
;
3700 got_off
= local_got_offsets
[r_symndx
];
3701 local_got_offsets
[r_symndx
] |= 1;
3704 BFD_ASSERT (got_off
!= MINUS_ONE
);
3706 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3708 /* If a tls variable is accessed in multiple ways, GD uses
3709 the first two slots of GOT, desc follows with two slots,
3710 and IE uses one slot at the end. */
3712 if (tls_type
& GOT_TLS_GD
)
3713 off
+= 2 * GOT_ENTRY_SIZE
;
3715 if (tls_type
& GOT_TLS_GDESC
)
3716 off
+= 2 * GOT_ENTRY_SIZE
;
3719 if ((got_off
& 1) == 0)
3721 Elf_Internal_Rela rela
;
3722 asection
*relgot
= htab
->elf
.srelgot
;
3725 bool need_reloc
= false;
3726 LARCH_TLS_GD_IE_NEED_DYN_RELOC (info
, is_dyn
, h
, indx
,
3729 if (tls_type
& GOT_TLS_GD
)
3733 /* Dynamic resolved Module ID. */
3734 rela
.r_offset
= sec_addr (got
) + got_off
;
3736 rela
.r_info
= ELFNN_R_INFO (indx
,R_LARCH_TLS_DTPMODNN
);
3737 bfd_put_NN (output_bfd
, 0, got
->contents
+ got_off
);
3738 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3742 /* Local symbol, tp offset has been known. */
3743 BFD_ASSERT (! unresolved_reloc
);
3744 bfd_put_NN (output_bfd
,
3745 tlsoff (info
, relocation
),
3746 (got
->contents
+ got_off
+ GOT_ENTRY_SIZE
));
3750 /* Dynamic resolved block offset. */
3751 bfd_put_NN (output_bfd
, 0,
3752 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3753 rela
.r_info
= ELFNN_R_INFO (indx
,
3754 R_LARCH_TLS_DTPRELNN
);
3755 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3756 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3761 /* In a static link or an executable link with the symbol
3762 binding locally. Mark it as belonging to module 1. */
3763 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3764 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
3765 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3768 if (tls_type
& GOT_TLS_GDESC
)
3770 /* Unless it is a static link, DESC always emits a
3771 dynamic relocation. */
3772 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
3773 rela
.r_offset
= sec_addr (got
) + got_off
+ desc_off
;
3776 rela
.r_addend
= tlsoff (info
, relocation
);
3778 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_DESCNN
);
3779 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3780 bfd_put_NN (output_bfd
, 0,
3781 got
->contents
+ got_off
+ desc_off
);
3783 if (tls_type
& GOT_TLS_IE
)
3787 bfd_put_NN (output_bfd
, 0,
3788 got
->contents
+ got_off
+ ie_off
);
3789 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3793 rela
.r_addend
= tlsoff (info
, relocation
);
3794 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_TPRELNN
);
3795 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3799 /* In a static link or an executable link with the symbol
3800 bindinglocally, compute offset directly. */
3801 bfd_put_NN (output_bfd
, tlsoff (info
, relocation
),
3802 got
->contents
+ got_off
+ ie_off
);
3806 relocation
= (got_off
& (~(bfd_vma
)1)) + sec_addr (got
);
3808 relocation
+= desc_off
;
3810 relocation
+= ie_off
;
3812 if (r_type
== R_LARCH_TLS_LD_PC_HI20
3813 || r_type
== R_LARCH_TLS_GD_PC_HI20
3814 || r_type
== R_LARCH_TLS_IE_PC_HI20
3815 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
3816 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3817 else if (r_type
== R_LARCH_TLS_LD_PCREL20_S2
3818 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
3819 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
3821 /* else {} ABS relocations. */
3824 case R_LARCH_TLS_DESC_PC_LO12
:
3825 case R_LARCH_TLS_DESC64_PC_LO20
:
3826 case R_LARCH_TLS_DESC64_PC_HI12
:
3827 case R_LARCH_TLS_DESC_LO12
:
3828 case R_LARCH_TLS_DESC64_LO20
:
3829 case R_LARCH_TLS_DESC64_HI12
:
3831 unresolved_reloc
= false;
3834 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
3836 relocation
= sec_addr (got
)
3837 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
3839 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3840 /* Use both TLS_GD and TLS_DESC. */
3841 if (GOT_TLS_GD_BOTH_P (tls_type
))
3842 relocation
+= 2 * GOT_ENTRY_SIZE
;
3844 if (r_type
== R_LARCH_TLS_DESC64_PC_LO20
)
3845 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
3846 else if (r_type
== R_LARCH_TLS_DESC64_PC_HI12
)
3847 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
3852 case R_LARCH_TLS_DESC_LD
:
3853 case R_LARCH_TLS_DESC_CALL
:
3854 unresolved_reloc
= false;
3857 case R_LARCH_TLS_IE_PC_LO12
:
3858 case R_LARCH_TLS_IE64_PC_LO20
:
3859 case R_LARCH_TLS_IE64_PC_HI12
:
3860 case R_LARCH_TLS_IE_LO12
:
3861 case R_LARCH_TLS_IE64_LO20
:
3862 case R_LARCH_TLS_IE64_HI12
:
3863 unresolved_reloc
= false;
3866 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
3868 relocation
= sec_addr (got
)
3869 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
3871 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3872 /* Use TLS_GD TLS_DESC and TLS_IE. */
3873 if (GOT_TLS_GD_BOTH_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3874 relocation
+= 4 * GOT_ENTRY_SIZE
;
3875 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
3876 else if (GOT_TLS_GD_ANY_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3877 relocation
+= 2 * GOT_ENTRY_SIZE
;
3879 if (r_type
== R_LARCH_TLS_IE64_PC_LO20
)
3880 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 8);
3881 else if (r_type
== R_LARCH_TLS_IE64_PC_HI12
)
3882 RELOCATE_CALC_PC64_HI32 (relocation
, pc
- 12);
3888 r
= bfd_reloc_continue
;
3889 unresolved_reloc
= false;
3901 /* 'unresolved_reloc' means we haven't done it yet.
3902 We need help of dynamic linker to fix this memory location up. */
3903 if (!unresolved_reloc
)
3906 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
3907 rel
->r_offset
) == MINUS_ONE
)
3908 /* WHY? May because it's invalid so skip checking.
3909 But why dynamic reloc a invalid section? */
3912 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
3914 fatal
= (loongarch_reloc_is_fatal
3915 (info
, input_bfd
, input_section
, rel
, howto
,
3916 bfd_reloc_dangerous
, is_undefweak
, name
,
3917 "Seems dynamic linker not process "
3918 "sections 'SEC_DEBUGGING'."));
3923 if ((info
->flags
& DF_TEXTREL
) == 0)
3924 if (input_section
->output_section
->flags
& SEC_READONLY
)
3925 info
->flags
|= DF_TEXTREL
;
3932 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
3933 rel
->r_offset
, sym
, h
, rel
->r_addend
);
3935 if (r
!= bfd_reloc_continue
)
3936 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
3937 input_bfd
, contents
);
3941 case bfd_reloc_dangerous
:
3942 case bfd_reloc_continue
:
3946 case bfd_reloc_overflow
:
3947 /* Overflow value can't be filled in. */
3948 loongarch_dump_reloc_record (info
->callbacks
->info
);
3949 info
->callbacks
->reloc_overflow
3950 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
3951 input_bfd
, input_section
, rel
->r_offset
);
3954 case bfd_reloc_outofrange
:
3955 /* Stack state incorrect. */
3956 loongarch_dump_reloc_record (info
->callbacks
->info
);
3957 info
->callbacks
->info
3958 ("%X%H: Internal stack state is incorrect.\n"
3959 "Want to push to full stack or pop from empty stack?\n",
3960 input_bfd
, input_section
, rel
->r_offset
);
3963 case bfd_reloc_notsupported
:
3964 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
3965 input_section
, rel
->r_offset
);
3969 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
3970 input_section
, rel
->r_offset
);
3981 loongarch_relax_delete_bytes (bfd
*abfd
,
3985 struct bfd_link_info
*link_info
)
3987 unsigned int i
, symcount
;
3988 bfd_vma toaddr
= sec
->size
;
3989 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (abfd
);
3990 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
3991 unsigned int sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
3992 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
3993 bfd_byte
*contents
= data
->this_hdr
.contents
;
3995 /* Actually delete the bytes. */
3997 memmove (contents
+ addr
, contents
+ addr
+ count
, toaddr
- addr
- count
);
3999 /* Adjust the location of all of the relocs. Note that we need not
4000 adjust the addends, since all PC-relative references must be against
4001 symbols, which we will adjust below. */
4002 for (i
= 0; i
< sec
->reloc_count
; i
++)
4003 if (data
->relocs
[i
].r_offset
> addr
&& data
->relocs
[i
].r_offset
< toaddr
)
4004 data
->relocs
[i
].r_offset
-= count
;
4006 /* Adjust the local symbols defined in this section. */
4007 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
4009 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
+ i
;
4010 if (sym
->st_shndx
== sec_shndx
)
4012 /* If the symbol is in the range of memory we just moved, we
4013 have to adjust its value. */
4014 if (sym
->st_value
> addr
&& sym
->st_value
<= toaddr
)
4015 sym
->st_value
-= count
;
4017 /* If the symbol *spans* the bytes we just deleted (i.e. its
4018 *end* is in the moved bytes but its *start* isn't), then we
4019 must adjust its size.
4021 This test needs to use the original value of st_value, otherwise
4022 we might accidentally decrease size when deleting bytes right
4023 before the symbol. But since deleted relocs can't span across
4024 symbols, we can't have both a st_value and a st_size decrease,
4025 so it is simpler to just use an else. */
4026 else if (sym
->st_value
<= addr
4027 && sym
->st_value
+ sym
->st_size
> addr
4028 && sym
->st_value
+ sym
->st_size
<= toaddr
)
4029 sym
->st_size
-= count
;
4033 /* Now adjust the global symbols defined in this section. */
4034 symcount
= ((symtab_hdr
->sh_size
/ sizeof (ElfNN_External_Sym
))
4035 - symtab_hdr
->sh_info
);
4037 for (i
= 0; i
< symcount
; i
++)
4039 struct elf_link_hash_entry
*sym_hash
= sym_hashes
[i
];
4041 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4042 containing the definition of __wrap_SYMBOL, includes a direct
4043 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4044 the same symbol (which is __wrap_SYMBOL), but still exist as two
4045 different symbols in 'sym_hashes', we don't want to adjust
4046 the global symbol __wrap_SYMBOL twice.
4048 The same problem occurs with symbols that are versioned_hidden, as
4049 foo becomes an alias for foo@BAR, and hence they need the same
4051 if (link_info
->wrap_hash
!= NULL
4052 || sym_hash
->versioned
!= unversioned
)
4054 struct elf_link_hash_entry
**cur_sym_hashes
;
4056 /* Loop only over the symbols which have already been checked. */
4057 for (cur_sym_hashes
= sym_hashes
; cur_sym_hashes
< &sym_hashes
[i
];
4060 /* If the current symbol is identical to 'sym_hash', that means
4061 the symbol was already adjusted (or at least checked). */
4062 if (*cur_sym_hashes
== sym_hash
)
4065 /* Don't adjust the symbol again. */
4066 if (cur_sym_hashes
< &sym_hashes
[i
])
4070 if ((sym_hash
->root
.type
== bfd_link_hash_defined
4071 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
4072 && sym_hash
->root
.u
.def
.section
== sec
)
4074 /* As above, adjust the value if needed. */
4075 if (sym_hash
->root
.u
.def
.value
> addr
4076 && sym_hash
->root
.u
.def
.value
<= toaddr
)
4077 sym_hash
->root
.u
.def
.value
-= count
;
4079 /* As above, adjust the size if needed. */
4080 else if (sym_hash
->root
.u
.def
.value
<= addr
4081 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
4082 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
<= toaddr
)
4083 sym_hash
->size
-= count
;
4090 /* Start perform TLS type transition.
4091 Currently there are three cases of relocation handled here:
4092 DESC -> IE, DEC -> LE and IE -> LE. */
4094 loongarch_tls_perform_trans (bfd
*abfd
, asection
*sec
,
4095 Elf_Internal_Rela
*rel
,
4096 struct elf_link_hash_entry
*h
,
4097 struct bfd_link_info
*info
)
4100 bool local_exec
= bfd_link_executable (info
)
4101 && SYMBOL_REFERENCES_LOCAL (info
, h
);
4102 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4103 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
4104 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4108 case R_LARCH_TLS_DESC_PC_HI20
:
4111 /* DESC -> LE relaxation:
4112 pcalalau12i $a0,%desc_pc_hi20(var) =>
4113 lu12i.w $a0,%le_hi20(var)
4115 bfd_put (32, abfd
, LARCH_LU12I_W
| LARCH_RD_A0
,
4116 contents
+ rel
->r_offset
);
4117 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4121 /* DESC -> IE relaxation:
4122 pcalalau12i $a0,%desc_pc_hi20(var) =>
4123 pcalalau12i $a0,%ie_pc_hi20(var)
4125 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_HI20
);
4129 case R_LARCH_TLS_DESC_PC_LO12
:
4132 /* DESC -> LE relaxation:
4133 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4134 ori $a0,$a0,le_lo12(var)
4136 insn
= LARCH_ORI
| LARCH_RD_RJ_A0
;
4137 bfd_put (32, abfd
, LARCH_ORI
| LARCH_RD_RJ_A0
,
4138 contents
+ rel
->r_offset
);
4139 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4143 /* DESC -> IE relaxation:
4144 addi.d $a0,$a0,%desc_pc_lo12(var) =>
4145 ld.d $a0,$a0,%ie_pc_lo12(var)
4147 bfd_put (32, abfd
, LARCH_LD_D
| LARCH_RD_RJ_A0
,
4148 contents
+ rel
->r_offset
);
4149 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_IE_PC_LO12
);
4153 case R_LARCH_TLS_DESC_LD
:
4154 case R_LARCH_TLS_DESC_CALL
:
4155 /* DESC -> LE/IE relaxation:
4156 ld.d $ra,$a0,%desc_ld(var) => NOP
4157 jirl $ra,$ra,%desc_call(var) => NOP
4159 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4160 bfd_put (32, abfd
, LARCH_NOP
, contents
+ rel
->r_offset
);
4161 /* link with -relax option will delete NOP. */
4162 if (!info
->disable_target_specific_optimizations
)
4163 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4166 case R_LARCH_TLS_IE_PC_HI20
:
4169 /* IE -> LE relaxation:
4170 pcalalau12i $rd,%ie_pc_hi20(var) =>
4171 lu12i.w $rd,%le_hi20(var)
4173 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4174 bfd_put (32, abfd
, LARCH_LU12I_W
| (insn
& 0x1f),
4175 contents
+ rel
->r_offset
);
4176 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_HI20
);
4180 case R_LARCH_TLS_IE_PC_LO12
:
4183 /* IE -> LE relaxation:
4184 ld.d $rd,$rj,%%ie_pc_lo12(var) =>
4185 ori $rd,$rj,le_lo12(var)
4187 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4188 bfd_put (32, abfd
, LARCH_ORI
| (insn
& 0x3ff),
4189 contents
+ rel
->r_offset
);
4190 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_TLS_LE_LO12
);
4199 /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4200 there are three situations in which an assembly instruction sequence needs to
4202 symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4205 in this case, the rd register in the st.{w/d} instruction does not store the
4206 full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4207 symbolic address, and then obtains the rd + le_lo12_r address through the
4208 st.w instruction feature.
4209 this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4211 before relax: after relax:
4213 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4214 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4215 st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
4218 in this case, ld.{w/d} is similar to st.{w/d} in case1.
4220 before relax: after relax:
4222 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4223 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4224 ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
4227 in this case,the rs register in addi.{w/d} stores the full address of the tls
4228 symbol (tp + le_hi20_r + le_lo12_r).
4230 before relax: after relax:
4232 lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
4233 add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4234 addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4237 For relocation of all old LE instruction sequences, whether it is
4238 a normal code model or an extreme code model, relaxation will be
4239 performed when the relaxation conditions are met.
4242 lu12i.w $rd,%le_hi20(sym) => (deleted)
4243 ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4246 lu12i.w $rd,%le_hi20(sym) => (deleted)
4247 ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
4248 lu32i.d $rd,%le64_lo20(sym) => (deleted)
4249 lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted)
4252 loongarch_relax_tls_le (bfd
*abfd
, asection
*sec
,
4253 Elf_Internal_Rela
*rel
,
4254 struct bfd_link_info
*link_info
,
4257 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4258 uint32_t insn
= bfd_get (32, abfd
, contents
+ rel
->r_offset
);
4259 static uint32_t insn_rj
,insn_rd
;
4260 symval
= symval
- elf_hash_table (link_info
)->tls_sec
->vma
;
4261 /* The old LE instruction sequence can be relaxed when the symbol offset
4262 is smaller than the 12-bit range. */
4263 if (ELFNN_R_TYPE ((rel
+ 1)->r_info
) == R_LARCH_RELAX
&& (symval
<= 0xfff))
4265 switch (ELFNN_R_TYPE (rel
->r_info
))
4267 /*if offset < 0x800, then perform the new le instruction
4269 case R_LARCH_TLS_LE_HI20_R
:
4270 case R_LARCH_TLS_LE_ADD_R
:
4274 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4275 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4280 case R_LARCH_TLS_LE_LO12_R
:
4283 /* Change rj to $tp. */
4285 /* Get rd register. */
4286 insn_rd
= insn
& 0x1f;
4287 /* Write symbol offset. */
4289 /* Writes the modified instruction. */
4290 insn
= insn
& 0xffc00000;
4291 insn
= insn
| symval
| insn_rj
| insn_rd
;
4292 bfd_put (32, abfd
, insn
, contents
+ rel
->r_offset
);
4296 case R_LARCH_TLS_LE_HI20
:
4297 case R_LARCH_TLS_LE64_LO20
:
4298 case R_LARCH_TLS_LE64_HI12
:
4299 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4300 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4304 case R_LARCH_TLS_LE_LO12
:
4305 bfd_put (32, abfd
, LARCH_ORI
| (insn
& 0x1f),
4306 contents
+ rel
->r_offset
);
4316 /* Relax pcalau12i,addi.d => pcaddi. */
4318 loongarch_relax_pcala_addi (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4319 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4320 struct bfd_link_info
*info
, bool *again
,
4321 bfd_vma max_alignment
)
4323 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4324 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4325 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4326 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4327 uint32_t rd
= pca
& 0x1f;
4329 /* This section's output_offset need to subtract the bytes of instructions
4330 relaxed by the previous sections, so it needs to be updated beforehand.
4331 size_input_section already took care of updating it after relaxation,
4332 so we additionally update once here. */
4333 sec
->output_offset
= sec
->output_section
->size
;
4334 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
4336 /* If pc and symbol not in the same segment, add/sub segment alignment.
4337 FIXME: if there are multiple readonly segments? How to determine if
4338 two sections are in the same segment. */
4339 if (!(sym_sec
->flags
& SEC_READONLY
))
4341 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
4344 pc
-= max_alignment
;
4345 else if (symval
< pc
)
4346 pc
+= max_alignment
;
4350 pc
-= max_alignment
;
4351 else if (symval
< pc
)
4352 pc
+= max_alignment
;
4354 const uint32_t addi_d
= 0x02c00000;
4355 const uint32_t pcaddi
= 0x18000000;
4357 /* Is pcalau12i + addi.d insns? */
4358 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_PCALA_LO12
)
4359 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4360 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4361 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4362 || ((add
& addi_d
) != addi_d
)
4363 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4364 || ((add
& 0x1f) != rd
)
4365 || (((add
>> 5) & 0x1f) != rd
)
4366 /* Can be relaxed to pcaddi? */
4367 || (symval
& 0x3) /* 4 bytes align. */
4368 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
4369 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
4372 /* Continue next relax trip. */
4376 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
4378 /* Adjust relocations. */
4379 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4380 R_LARCH_PCREL20_S2
);
4381 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4383 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
4389 tail36 $t0, f -> b f. */
4391 loongarch_relax_call36 (bfd
*abfd
, asection
*sec
,
4392 Elf_Internal_Rela
*rel
, bfd_vma symval
,
4393 struct bfd_link_info
*info
, bool *again
,
4394 bfd_vma max_alignment
)
4396 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4397 uint32_t jirl
= bfd_get (32, abfd
, contents
+ rel
->r_offset
+ 4);
4398 uint32_t rd
= jirl
& 0x1f;
4400 /* This section's output_offset need to subtract the bytes of instructions
4401 relaxed by the previous sections, so it needs to be updated beforehand.
4402 size_input_section already took care of updating it after relaxation,
4403 so we additionally update once here. */
4404 sec
->output_offset
= sec
->output_section
->size
;
4405 bfd_vma pc
= sec_addr (sec
) + rel
->r_offset
;
4407 /* If pc and symbol not in the same segment, add/sub segment alignment.
4408 FIXME: if there are multiple readonly segments? How to determine if
4409 two sections are in the same segment. */
4411 pc
-= (max_alignment
> 4 ? max_alignment
: 0);
4412 else if (symval
< pc
)
4413 pc
+= (max_alignment
> 4 ? max_alignment
: 0);
4415 const uint32_t jirl_opcode
= 0x4c000000;
4417 /* Is pcalau12i + addi.d insns? */
4418 if ((ELFNN_R_TYPE ((rel
+ 1)->r_info
) != R_LARCH_RELAX
)
4419 || ((jirl
& jirl_opcode
) != jirl_opcode
)
4420 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xf8000000)
4421 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x7fffffc))
4424 /* Continue next relax trip. */
4427 const uint32_t bl
= 0x54000000;
4428 const uint32_t b
= 0x50000000;
4431 bfd_put (32, abfd
, bl
, contents
+ rel
->r_offset
);
4433 bfd_put (32, abfd
, b
, contents
+ rel
->r_offset
);
4435 /* Adjust relocations. */
4436 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
), R_LARCH_B26
);
4437 /* Delete jirl instruction. */
4438 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
+ 4, 4, info
);
4442 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
4444 loongarch_relax_pcala_ld (bfd
*abfd
, asection
*sec
,
4445 Elf_Internal_Rela
*rel_hi
)
4447 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4448 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4449 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4450 uint32_t ld
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4451 uint32_t rd
= pca
& 0x1f;
4452 const uint32_t ld_d
= 0x28c00000;
4453 uint32_t addi_d
= 0x02c00000;
4455 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
)
4456 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4457 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4458 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4459 || ((ld
& 0x1f) != rd
)
4460 || (((ld
>> 5) & 0x1f) != rd
)
4461 || ((ld
& ld_d
) != ld_d
))
4464 addi_d
= addi_d
| (rd
<< 5) | rd
;
4465 bfd_put (32, abfd
, addi_d
, contents
+ rel_lo
->r_offset
);
4467 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4468 R_LARCH_PCALA_HI20
);
4469 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_lo
->r_info
),
4470 R_LARCH_PCALA_LO12
);
4474 /* Called by after_allocation to set the information of data segment
4478 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info
*info
,
4479 int *data_segment_phase
)
4481 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4482 htab
->data_segment_phase
= data_segment_phase
;
4485 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4486 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
4488 loongarch_relax_align (bfd
*abfd
, asection
*sec
,
4490 struct bfd_link_info
*link_info
,
4491 Elf_Internal_Rela
*rel
,
4494 bfd_vma addend
, max
= 0, alignment
= 1;
4496 int sym_index
= ELFNN_R_SYM (rel
->r_info
);
4499 alignment
= 1 << (rel
->r_addend
& 0xff);
4500 max
= rel
->r_addend
>> 8;
4503 alignment
= rel
->r_addend
+ 4;
4505 addend
= alignment
- 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
4506 symval
-= addend
; /* The address of first NOP added by R_LARCH_ALIGN. */
4507 bfd_vma aligned_addr
= ((symval
- 1) & ~(alignment
- 1)) + alignment
;
4508 bfd_vma need_nop_bytes
= aligned_addr
- symval
; /* */
4510 /* Make sure there are enough NOPs to actually achieve the alignment. */
4511 if (addend
< need_nop_bytes
)
4514 (_("%pB(%pA+%#" PRIx64
"): %" PRId64
" bytes required for alignment "
4515 "to %" PRId64
"-byte boundary, but only %" PRId64
" present"),
4516 abfd
, sym_sec
, (uint64_t) rel
->r_offset
,
4517 (int64_t) need_nop_bytes
, (int64_t) alignment
, (int64_t) addend
);
4518 bfd_set_error (bfd_error_bad_value
);
4522 /* Once we've handled an R_LARCH_ALIGN in a section,
4523 we can't relax anything else in this section. */
4524 sec
->sec_flg0
= true;
4525 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4527 /* If skipping more bytes than the specified maximum,
4528 then the alignment is not done at all and delete all NOPs. */
4529 if (max
> 0 && need_nop_bytes
> max
)
4530 return loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4533 /* If the number of NOPs is already correct, there's nothing to do. */
4534 if (need_nop_bytes
== addend
)
4537 /* Delete the excess NOPs. */
4538 return loongarch_relax_delete_bytes (abfd
, sec
,
4539 rel
->r_offset
+ need_nop_bytes
,
4540 addend
- need_nop_bytes
, link_info
);
4543 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
4545 loongarch_relax_tls_ld_gd_desc (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4546 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4547 struct bfd_link_info
*info
, bool *again
,
4548 bfd_vma max_alignment
)
4550 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4551 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4552 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4553 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4554 uint32_t rd
= pca
& 0x1f;
4556 /* This section's output_offset need to subtract the bytes of instructions
4557 relaxed by the previous sections, so it needs to be updated beforehand.
4558 size_input_section already took care of updating it after relaxation,
4559 so we additionally update once here. */
4560 sec
->output_offset
= sec
->output_section
->size
;
4561 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
4563 /* If pc and symbol not in the same segment, add/sub segment alignment.
4564 FIXME: if there are multiple readonly segments? */
4565 if (!(sym_sec
->flags
& SEC_READONLY
))
4567 max_alignment
= info
->maxpagesize
> max_alignment
? info
->maxpagesize
4570 pc
-= max_alignment
;
4571 else if (symval
< pc
)
4572 pc
+= max_alignment
;
4576 pc
-= max_alignment
;
4577 else if (symval
< pc
)
4578 pc
+= max_alignment
;
4580 const uint32_t addi_d
= 0x02c00000;
4581 const uint32_t pcaddi
= 0x18000000;
4583 /* Is pcalau12i + addi.d insns? */
4584 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
4585 && ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_TLS_DESC_PC_LO12
)
4586 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4587 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4588 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4589 || ((add
& addi_d
) != addi_d
)
4590 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4591 || ((add
& 0x1f) != rd
)
4592 || (((add
>> 5) & 0x1f) != rd
)
4593 /* Can be relaxed to pcaddi? */
4594 || (symval
& 0x3) /* 4 bytes align. */
4595 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
4596 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
4599 /* Continue next relax trip. */
4603 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
4605 /* Adjust relocations. */
4606 switch (ELFNN_R_TYPE (rel_hi
->r_info
))
4608 case R_LARCH_TLS_LD_PC_HI20
:
4609 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4610 R_LARCH_TLS_LD_PCREL20_S2
);
4612 case R_LARCH_TLS_GD_PC_HI20
:
4613 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4614 R_LARCH_TLS_GD_PCREL20_S2
);
4616 case R_LARCH_TLS_DESC_PC_HI20
:
4617 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4618 R_LARCH_TLS_DESC_PCREL20_S2
);
4623 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4625 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
4630 /* Traverse all output sections and return the max alignment. */
4633 loongarch_get_max_alignment (asection
*sec
)
4636 unsigned int max_alignment_power
= 0;
4638 for (o
= sec
->output_section
->owner
->sections
; o
!= NULL
; o
= o
->next
)
4639 if (o
->alignment_power
> max_alignment_power
)
4640 max_alignment_power
= o
->alignment_power
;
4642 return (bfd_vma
) 1 << max_alignment_power
;
4646 loongarch_elf_relax_section (bfd
*abfd
, asection
*sec
,
4647 struct bfd_link_info
*info
,
4650 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4651 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
4652 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (abfd
);
4653 Elf_Internal_Rela
*relocs
;
4655 bfd_vma max_alignment
= 0;
4657 if (bfd_link_relocatable (info
)
4659 || (sec
->flags
& SEC_RELOC
) == 0
4660 || sec
->reloc_count
== 0
4661 || (info
->disable_target_specific_optimizations
4662 && info
->relax_pass
== 0)
4663 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4664 and defined in ld/ldexp.h. */
4665 || *(htab
->data_segment_phase
) == 4)
4669 relocs
= data
->relocs
;
4670 else if (!(relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
4671 info
->keep_memory
)))
4674 if (!data
->this_hdr
.contents
4675 && !bfd_malloc_and_get_section (abfd
, sec
, &data
->this_hdr
.contents
))
4678 if (symtab_hdr
->sh_info
!= 0
4679 && !symtab_hdr
->contents
4680 && !(symtab_hdr
->contents
=
4681 (unsigned char *) bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
4682 symtab_hdr
->sh_info
,
4683 0, NULL
, NULL
, NULL
)))
4686 data
->relocs
= relocs
;
4688 /* Estimate the maximum alignment for all output sections once time
4689 should be enough. */
4690 max_alignment
= htab
->max_alignment
;
4691 if (max_alignment
== (bfd_vma
) -1)
4693 max_alignment
= loongarch_get_max_alignment (sec
);
4694 htab
->max_alignment
= max_alignment
;
4697 for (unsigned int i
= 0; i
< sec
->reloc_count
; i
++)
4702 bool local_got
= false;
4703 Elf_Internal_Rela
*rel
= relocs
+ i
;
4704 struct elf_link_hash_entry
*h
= NULL
;
4705 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
4706 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4708 /* Four kind of relocations:
4709 Normal: symval is the symbol address.
4710 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4711 added by this relocation, and then adds 4 more.
4712 R_LARCH_CALL36: symval is the symbol address for local symbols,
4713 or the PLT entry address of the symbol. (Todo)
4714 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4715 of the symbol if transition is not possible. */
4716 if (r_symndx
< symtab_hdr
->sh_info
)
4718 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)symtab_hdr
->contents
4720 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
4723 /* Only TLS instruction sequences that are accompanied by
4724 R_LARCH_RELAX and cannot perform type transition can be
4726 if (R_LARCH_TLS_LD_PC_HI20
== r_type
4727 || R_LARCH_TLS_GD_PC_HI20
== r_type
4728 || (R_LARCH_TLS_DESC_PC_HI20
== r_type
4729 && (i
+ 1 != sec
->reloc_count
)
4730 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
4731 && ! loongarch_can_trans_tls (abfd
, info
, h
,
4734 sym_sec
= htab
->elf
.sgot
;
4735 symval
= elf_local_got_offsets (abfd
)[r_symndx
];
4736 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
4738 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
4739 && GOT_TLS_GD_BOTH_P (tls_type
))
4740 symval
+= 2 * GOT_ENTRY_SIZE
;
4742 else if (sym
->st_shndx
== SHN_UNDEF
|| R_LARCH_ALIGN
== r_type
)
4745 symval
= rel
->r_offset
;
4749 sym_sec
= elf_elfsections (abfd
)[sym
->st_shndx
]->bfd_section
;
4750 symval
= sym
->st_value
;
4752 symtype
= ELF_ST_TYPE (sym
->st_info
);
4756 r_symndx
= ELFNN_R_SYM (rel
->r_info
) - symtab_hdr
->sh_info
;
4757 h
= elf_sym_hashes (abfd
)[r_symndx
];
4759 while (h
->root
.type
== bfd_link_hash_indirect
4760 || h
->root
.type
== bfd_link_hash_warning
)
4761 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
4763 /* Disable the relaxation for ifunc. */
4764 if (h
!= NULL
&& h
->type
== STT_GNU_IFUNC
)
4767 /* The GOT entry of tls symbols must in current execute file or
4769 if (R_LARCH_TLS_LD_PC_HI20
== r_type
4770 || R_LARCH_TLS_GD_PC_HI20
== r_type
4771 || (R_LARCH_TLS_DESC_PC_HI20
== r_type
4772 && (i
+ 1 != sec
->reloc_count
)
4773 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
4774 && !loongarch_can_trans_tls (abfd
, info
, h
,
4777 sym_sec
= htab
->elf
.sgot
;
4778 symval
= h
->got
.offset
;
4779 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
4781 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
4782 && GOT_TLS_GD_BOTH_P (tls_type
))
4783 symval
+= 2 * GOT_ENTRY_SIZE
;
4785 else if ((h
->root
.type
== bfd_link_hash_defined
4786 || h
->root
.type
== bfd_link_hash_defweak
)
4787 && h
->root
.u
.def
.section
!= NULL
4788 && h
->root
.u
.def
.section
->output_section
!= NULL
)
4790 symval
= h
->root
.u
.def
.value
;
4791 sym_sec
= h
->root
.u
.def
.section
;
4796 if (h
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
4801 if (sym_sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
4802 && (sym_sec
->flags
& SEC_MERGE
))
4804 if (symtype
== STT_SECTION
)
4805 symval
+= rel
->r_addend
;
4807 symval
= _bfd_merged_section_offset (abfd
, &sym_sec
,
4808 elf_section_data (sym_sec
)->sec_info
,
4811 if (symtype
!= STT_SECTION
)
4812 symval
+= rel
->r_addend
;
4814 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
4816 If r_symndx is 0, alignmeng-4 is r_addend.
4817 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
4818 else if (R_LARCH_ALIGN
== r_type
)
4820 symval
+= ((1 << (rel
->r_addend
& 0xff)) - 4);
4822 symval
+= rel
->r_addend
;
4824 symval
+= rel
->r_addend
;
4826 symval
+= sec_addr (sym_sec
);
4828 /* If the conditions for tls type transition are met, type
4829 transition is performed instead of relax.
4830 During the transition from DESC->IE/LE, there are 2 situations
4831 depending on the different configurations of the relax/norelax
4833 If the -relax option is used, the extra nops will be removed,
4834 and this transition is performed in pass 0.
4835 If the --no-relax option is used, nop will be retained, and
4836 this transition is performed in pass 1. */
4837 if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type
)
4838 && (i
+ 1 != sec
->reloc_count
)
4839 && ELFNN_R_TYPE (rel
[1].r_info
) == R_LARCH_RELAX
4840 && loongarch_can_trans_tls (abfd
, info
, h
, r_symndx
, r_type
))
4842 loongarch_tls_perform_trans (abfd
, sec
, rel
, h
, info
);
4843 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4849 if (1 == info
->relax_pass
)
4850 loongarch_relax_align (abfd
, sec
, sym_sec
, info
, rel
, symval
);
4853 case R_LARCH_DELETE
:
4854 if (1 == info
->relax_pass
)
4856 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4857 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4860 case R_LARCH_CALL36
:
4861 if (0 == info
->relax_pass
&& (i
+ 2) <= sec
->reloc_count
)
4862 loongarch_relax_call36 (abfd
, sec
, rel
, symval
, info
, again
,
4866 case R_LARCH_TLS_LE_HI20_R
:
4867 case R_LARCH_TLS_LE_LO12_R
:
4868 case R_LARCH_TLS_LE_ADD_R
:
4869 case R_LARCH_TLS_LE_HI20
:
4870 case R_LARCH_TLS_LE_LO12
:
4871 case R_LARCH_TLS_LE64_LO20
:
4872 case R_LARCH_TLS_LE64_HI12
:
4873 if (0 == info
->relax_pass
&& (i
+ 2) <= sec
->reloc_count
)
4874 loongarch_relax_tls_le (abfd
, sec
, rel
, info
, symval
);
4877 case R_LARCH_PCALA_HI20
:
4878 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4879 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
4880 info
, again
, max_alignment
);
4883 case R_LARCH_GOT_PC_HI20
:
4884 if (local_got
&& 0 == info
->relax_pass
4885 && (i
+ 4) <= sec
->reloc_count
)
4887 if (loongarch_relax_pcala_ld (abfd
, sec
, rel
))
4888 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
4889 info
, again
, max_alignment
);
4893 case R_LARCH_TLS_LD_PC_HI20
:
4894 case R_LARCH_TLS_GD_PC_HI20
:
4895 case R_LARCH_TLS_DESC_PC_HI20
:
4896 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4897 loongarch_relax_tls_ld_gd_desc (abfd
, sec
, sym_sec
, rel
, symval
,
4898 info
, again
, max_alignment
);
4909 /* Finish up dynamic symbol handling. We set the contents of various
4910 dynamic sections here. */
4913 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
4914 struct bfd_link_info
*info
,
4915 struct elf_link_hash_entry
*h
,
4916 Elf_Internal_Sym
*sym
)
4918 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4919 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
4921 if (h
->plt
.offset
!= MINUS_ONE
)
4924 asection
*plt
, *gotplt
, *relplt
;
4925 bfd_vma got_address
;
4926 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
4928 Elf_Internal_Rela rela
;
4932 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
4933 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4934 || h
->dynindx
!= -1);
4936 plt
= htab
->elf
.splt
;
4937 gotplt
= htab
->elf
.sgotplt
;
4938 if (h
->type
== STT_GNU_IFUNC
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
4939 relplt
= htab
->elf
.srelgot
;
4941 relplt
= htab
->elf
.srelplt
;
4942 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4944 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
4946 else /* if (htab->elf.iplt) */
4948 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
4949 && SYMBOL_REFERENCES_LOCAL (info
, h
));
4951 plt
= htab
->elf
.iplt
;
4952 gotplt
= htab
->elf
.igotplt
;
4953 relplt
= htab
->elf
.irelplt
;
4954 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4955 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
4958 /* Find out where the .plt entry should go. */
4959 loc
= plt
->contents
+ h
->plt
.offset
;
4961 /* Fill in the PLT entry itself. */
4962 if (!loongarch_make_plt_entry (got_address
,
4963 sec_addr (plt
) + h
->plt
.offset
,
4967 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
4968 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
4970 /* Fill in the initial value of the got.plt entry. */
4971 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
4972 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
4974 rela
.r_offset
= got_address
;
4976 /* TRUE if this is a PLT reference to a local IFUNC. */
4977 if (PLT_LOCAL_IFUNC_P (info
, h
)
4978 && (relplt
== htab
->elf
.srelgot
4979 || relplt
== htab
->elf
.irelplt
))
4981 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
4982 rela
.r_addend
= (h
->root
.u
.def
.value
4983 + h
->root
.u
.def
.section
->output_section
->vma
4984 + h
->root
.u
.def
.section
->output_offset
);
4986 loongarch_elf_append_rela (output_bfd
, relplt
, &rela
);
4990 /* Fill in the entry in the rela.plt section. */
4991 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
4993 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
4994 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
4997 if (!h
->def_regular
)
4999 /* Mark the symbol as undefined, rather than as defined in
5000 the .plt section. Leave the value alone. */
5001 sym
->st_shndx
= SHN_UNDEF
;
5002 /* If the symbol is weak, we do need to clear the value.
5003 Otherwise, the PLT entry would provide a definition for
5004 the symbol even if the symbol wasn't defined anywhere,
5005 and so the symbol would never be NULL. */
5006 if (!h
->ref_regular_nonweak
)
5011 if (h
->got
.offset
!= MINUS_ONE
5012 /* TLS got entry have been handled in elf_relocate_section. */
5013 && !(loongarch_elf_hash_entry (h
)->tls_type
5014 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
5015 /* Have allocated got entry but not allocated rela before. */
5016 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
5018 asection
*sgot
, *srela
;
5019 Elf_Internal_Rela rela
;
5020 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
)1;
5022 /* This symbol has an entry in the GOT. Set it up. */
5023 sgot
= htab
->elf
.sgot
;
5024 srela
= htab
->elf
.srelgot
;
5025 BFD_ASSERT (sgot
&& srela
);
5027 rela
.r_offset
= sec_addr (sgot
) + off
;
5030 && h
->type
== STT_GNU_IFUNC
)
5032 if(h
->plt
.offset
== MINUS_ONE
)
5034 if (htab
->elf
.splt
== NULL
)
5035 srela
= htab
->elf
.irelplt
;
5037 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
5039 asection
*sec
= h
->root
.u
.def
.section
;
5040 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
5041 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
5042 + sec
->output_offset
;
5043 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
5047 BFD_ASSERT (h
->dynindx
!= -1);
5048 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5050 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
5053 else if(bfd_link_pic (info
))
5055 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5057 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
5062 /* For non-shared object, we can't use .got.plt, which
5063 contains the real function address if we need pointer
5064 equality. We load the GOT entry with the PLT entry. */
5065 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
5066 bfd_put_NN (output_bfd
,
5067 (plt
->output_section
->vma
5068 + plt
->output_offset
5070 sgot
->contents
+ off
);
5074 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
5076 asection
*sec
= h
->root
.u
.def
.section
;
5077 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
5078 rela
.r_addend
= (h
->root
.u
.def
.value
+ sec
->output_section
->vma
5079 + sec
->output_offset
);
5083 BFD_ASSERT (h
->dynindx
!= -1);
5084 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
5088 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
5091 /* Mark some specially defined symbols as absolute. */
5092 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
5093 sym
->st_shndx
= SHN_ABS
;
5098 /* Finish up the dynamic sections. */
5101 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
5104 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5105 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
5106 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
5107 bfd_byte
*dyncon
, *dynconend
;
5109 dynconend
= sdyn
->contents
+ sdyn
->size
;
5110 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
5112 Elf_Internal_Dyn dyn
;
5116 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
5121 s
= htab
->elf
.sgotplt
;
5122 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5125 s
= htab
->elf
.srelplt
;
5126 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
5129 s
= htab
->elf
.srelplt
;
5130 dyn
.d_un
.d_val
= s
->size
;
5133 if ((info
->flags
& DF_TEXTREL
) == 0)
5137 if ((info
->flags
& DF_TEXTREL
) == 0)
5138 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
5142 skipped_size
+= dynsize
;
5144 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
5146 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
5147 memset (dyncon
- skipped_size
, 0, skipped_size
);
5151 /* Finish up local dynamic symbol handling. We set the contents of
5152 various dynamic sections here. */
5155 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
5157 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
5158 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
5160 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
5163 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
5164 this function is called before elf_link_sort_relocs.
5165 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
5166 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
5169 elf_loongarch_output_arch_local_syms
5170 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
5171 struct bfd_link_info
*info
,
5172 void *flaginfo ATTRIBUTE_UNUSED
,
5173 int (*func
) (void *, const char *,
5176 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
5178 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
5182 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5183 htab_traverse (htab
->loc_hash_table
,
5184 elfNN_loongarch_finish_local_dynamic_symbol
,
5191 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
5192 struct bfd_link_info
*info
)
5195 asection
*sdyn
, *plt
, *gotplt
= NULL
;
5196 struct loongarch_elf_link_hash_table
*htab
;
5198 htab
= loongarch_elf_hash_table (info
);
5200 dynobj
= htab
->elf
.dynobj
;
5201 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
5203 if (elf_hash_table (info
)->dynamic_sections_created
)
5205 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
5207 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
5211 plt
= htab
->elf
.splt
;
5212 gotplt
= htab
->elf
.sgotplt
;
5214 if (plt
&& 0 < plt
->size
)
5217 uint32_t plt_header
[PLT_HEADER_INSNS
];
5218 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
5222 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
5223 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
5225 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
5229 if (htab
->elf
.sgotplt
)
5231 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
5233 if (bfd_is_abs_section (output_section
))
5235 _bfd_error_handler (_("discarded output section: `%pA'"),
5240 if (0 < htab
->elf
.sgotplt
->size
)
5242 /* Write the first two entries in .got.plt, needed for the dynamic
5244 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
5246 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5247 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
5250 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5255 asection
*output_section
= htab
->elf
.sgot
->output_section
;
5257 if (0 < htab
->elf
.sgot
->size
)
5259 /* Set the first entry in the global offset table to the address of
5260 the dynamic section. */
5261 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
5262 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
5265 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
5271 /* Return address for Ith PLT stub in section PLT, for relocation REL
5272 or (bfd_vma) -1 if it should not be included. */
5275 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
5276 const arelent
*rel ATTRIBUTE_UNUSED
)
5278 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
5281 static enum elf_reloc_type_class
5282 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5283 const asection
*rel_sec ATTRIBUTE_UNUSED
,
5284 const Elf_Internal_Rela
*rela
)
5286 struct loongarch_elf_link_hash_table
*htab
;
5287 htab
= loongarch_elf_hash_table (info
);
5289 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
5291 /* Check relocation against STT_GNU_IFUNC symbol if there are
5293 bfd
*abfd
= info
->output_bfd
;
5294 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
5295 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
5296 if (r_symndx
!= STN_UNDEF
)
5298 Elf_Internal_Sym sym
;
5299 if (!bed
->s
->swap_symbol_in (abfd
,
5300 htab
->elf
.dynsym
->contents
5301 + r_symndx
* bed
->s
->sizeof_sym
,
5304 /* xgettext:c-format */
5305 _bfd_error_handler (_("%pB symbol number %lu references"
5306 " nonexistent SHT_SYMTAB_SHNDX section"),
5308 /* Ideally an error class should be returned here. */
5310 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
5311 return reloc_class_ifunc
;
5315 switch (ELFNN_R_TYPE (rela
->r_info
))
5317 case R_LARCH_IRELATIVE
:
5318 return reloc_class_ifunc
;
5319 case R_LARCH_RELATIVE
:
5320 return reloc_class_relative
;
5321 case R_LARCH_JUMP_SLOT
:
5322 return reloc_class_plt
;
5324 return reloc_class_copy
;
5326 return reloc_class_normal
;
5330 /* Copy the extra info we tack onto an elf_link_hash_entry. */
5333 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
5334 struct elf_link_hash_entry
*dir
,
5335 struct elf_link_hash_entry
*ind
)
5337 struct elf_link_hash_entry
*edir
, *eind
;
5342 if (eind
->dyn_relocs
!= NULL
)
5344 if (edir
->dyn_relocs
!= NULL
)
5346 struct elf_dyn_relocs
**pp
;
5347 struct elf_dyn_relocs
*p
;
5349 /* Add reloc counts against the indirect sym to the direct sym
5350 list. Merge any entries against the same section. */
5351 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
5353 struct elf_dyn_relocs
*q
;
5355 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
5356 if (q
->sec
== p
->sec
)
5358 q
->pc_count
+= p
->pc_count
;
5359 q
->count
+= p
->count
;
5366 *pp
= edir
->dyn_relocs
;
5369 edir
->dyn_relocs
= eind
->dyn_relocs
;
5370 eind
->dyn_relocs
= NULL
;
5373 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
5375 loongarch_elf_hash_entry(edir
)->tls_type
5376 = loongarch_elf_hash_entry(eind
)->tls_type
;
5377 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
5379 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
5382 #define PRSTATUS_SIZE 0x1d8
5383 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
5384 #define PRSTATUS_OFFSET_PR_PID 0x20
5385 #define ELF_GREGSET_T_SIZE 0x168
5386 #define PRSTATUS_OFFSET_PR_REG 0x70
5388 /* Support for core dump NOTE sections. */
5391 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
5393 switch (note
->descsz
)
5398 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
5401 elf_tdata (abfd
)->core
->signal
=
5402 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
5405 elf_tdata (abfd
)->core
->lwpid
=
5406 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
5410 /* Make a ".reg/999" section. */
5411 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
5413 + PRSTATUS_OFFSET_PR_REG
);
5416 #define PRPSINFO_SIZE 0x88
5417 #define PRPSINFO_OFFSET_PR_PID 0x18
5418 #define PRPSINFO_OFFSET_PR_FNAME 0x28
5419 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
5420 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
5421 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
5424 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
5426 switch (note
->descsz
)
5431 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
5434 elf_tdata (abfd
)->core
->pid
=
5435 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
5438 elf_tdata (abfd
)->core
->program
=
5439 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
5440 PRPSINFO_SIZEOF_PR_FNAME
);
5443 elf_tdata (abfd
)->core
->command
=
5444 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
5445 PRPSINFO_SIZEOF_PR_PS_ARGS
);
5449 /* Note that for some reason, a spurious space is tacked
5450 onto the end of the args in some (at least one anyway)
5451 implementations, so strip it off if it exists. */
5454 char *command
= elf_tdata (abfd
)->core
->command
;
5455 int n
= strlen (command
);
5457 if (0 < n
&& command
[n
- 1] == ' ')
5458 command
[n
- 1] = '\0';
5464 /* Set the right mach type. */
5466 loongarch_elf_object_p (bfd
*abfd
)
5468 /* There are only two mach types in LoongArch currently. */
5469 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
5470 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
5472 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
5477 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
5478 Elf_Internal_Rela
*rel
,
5479 struct elf_link_hash_entry
*h
,
5480 Elf_Internal_Sym
*sym
)
5483 switch (ELFNN_R_TYPE (rel
->r_info
))
5485 case R_LARCH_GNU_VTINHERIT
:
5486 case R_LARCH_GNU_VTENTRY
:
5490 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
5493 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
5494 executable PLT slots where the executable never takes the address of those
5495 functions, the function symbols are not added to the hash table. */
5498 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
5500 if (h
->plt
.offset
!= (bfd_vma
) -1
5502 && !h
->pointer_equality_needed
)
5505 return _bfd_elf_hash_symbol (h
);
5508 /* If a relocation is rela_normal and the symbol associated with the
5509 relocation is STT_SECTION type, the addend of the relocation would add
5510 sec->output_offset when partial linking (ld -r).
5511 See elf_backend_data.rela_normal and elf_link_input_bfd().
5512 The addend of R_LARCH_ALIGN is used to represent the first and third
5513 expression of .align, it should be a constant when linking. */
5516 loongarch_elf_is_rela_normal (Elf_Internal_Rela
*rel
)
5518 if (R_LARCH_ALIGN
== ELFNN_R_TYPE (rel
->r_info
))
5523 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
5524 #define TARGET_LITTLE_NAME "elfNN-loongarch"
5525 #define ELF_ARCH bfd_arch_loongarch
5526 #define ELF_TARGET_ID LARCH_ELF_DATA
5527 #define ELF_MACHINE_CODE EM_LOONGARCH
5528 #define ELF_MAXPAGESIZE 0x4000
5529 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5530 #define bfd_elfNN_bfd_link_hash_table_create \
5531 loongarch_elf_link_hash_table_create
5532 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5533 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
5534 #define elf_info_to_howto loongarch_info_to_howto_rela
5535 #define bfd_elfNN_bfd_merge_private_bfd_data \
5536 elfNN_loongarch_merge_private_bfd_data
5538 #define elf_backend_reloc_type_class loongarch_reloc_type_class
5539 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5540 #define elf_backend_create_dynamic_sections \
5541 loongarch_elf_create_dynamic_sections
5542 #define elf_backend_check_relocs loongarch_elf_check_relocs
5543 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5544 #define elf_backend_late_size_sections loongarch_elf_late_size_sections
5545 #define elf_backend_relocate_section loongarch_elf_relocate_section
5546 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
5547 #define elf_backend_output_arch_local_syms \
5548 elf_loongarch_output_arch_local_syms
5549 #define elf_backend_finish_dynamic_sections \
5550 loongarch_elf_finish_dynamic_sections
5551 #define elf_backend_object_p loongarch_elf_object_p
5552 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5553 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5554 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5555 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
5556 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
5557 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
5558 #define elf_backend_is_rela_normal loongarch_elf_is_rela_normal
5560 #define elf_backend_dtrel_excludes_plt 1
5562 #include "elfNN-target.h"