1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2023 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 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
132 #define elf_backend_want_got_plt 1
134 #define elf_backend_plt_readonly 1
136 #define elf_backend_want_plt_sym 1
137 #define elf_backend_plt_alignment 4
138 #define elf_backend_can_gc_sections 1
139 #define elf_backend_can_refcount 1
140 #define elf_backend_want_got_sym 1
142 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
144 #define elf_backend_want_dynrelro 1
145 #define elf_backend_rela_normal 1
146 #define elf_backend_default_execstack 0
148 #define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE) \
149 ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
150 || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
151 || (R_TYPE) == R_LARCH_TLS_DESC_LD \
152 || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
154 #define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
155 ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
156 || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
158 /* Generate a PLT header. */
161 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
164 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
167 if (pcrel
+ 0x80000800 > 0xffffffff)
169 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
170 bfd_set_error (bfd_error_bad_value
);
173 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
176 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
177 sub.[wd] $t1, $t1, $t3
178 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
179 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
180 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
181 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
182 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
185 if (GOT_ENTRY_SIZE
== 8)
187 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
188 entry
[1] = 0x0011bdad;
189 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
190 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
191 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
192 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
193 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
194 entry
[7] = 0x4c0001e0;
198 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
199 entry
[1] = 0x00113dad;
200 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
201 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
202 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
203 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
204 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
205 entry
[7] = 0x4c0001e0;
210 /* Generate a PLT entry. */
213 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
216 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
219 if (pcrel
+ 0x80000800 > 0xffffffff)
221 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
222 bfd_set_error (bfd_error_bad_value
);
225 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
228 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
229 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
230 | (lo
& 0xfff) << 10);
231 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
232 entry
[3] = 0x03400000; /* nop */
237 /* Create an entry in an LoongArch ELF linker hash table. */
239 static struct bfd_hash_entry
*
240 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
243 struct loongarch_elf_link_hash_entry
*eh
;
245 /* Allocate the structure if it has not already been allocated by a
249 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
254 /* Call the allocation method of the superclass. */
255 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
258 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
259 eh
->tls_type
= GOT_UNKNOWN
;
265 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
266 for local symbol so that we can handle local STT_GNU_IFUNC symbols
267 as global symbol. We reuse indx and dynstr_index for local symbol
268 hash since they aren't used by global symbols in this backend. */
271 elfNN_loongarch_local_htab_hash (const void *ptr
)
273 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
274 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
277 /* Compare local hash entries. */
280 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
282 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
283 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
285 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
288 /* Find and/or create a hash entry for local symbol. */
289 static struct elf_link_hash_entry
*
290 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
291 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
294 struct loongarch_elf_link_hash_entry e
, *ret
;
295 asection
*sec
= abfd
->sections
;
296 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
299 e
.elf
.indx
= sec
->id
;
300 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
301 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
302 create
? INSERT
: NO_INSERT
);
309 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
313 ret
= ((struct loongarch_elf_link_hash_entry
*)
314 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
315 sizeof (struct loongarch_elf_link_hash_entry
)));
318 memset (ret
, 0, sizeof (*ret
));
319 ret
->elf
.indx
= sec
->id
;
320 ret
->elf
.pointer_equality_needed
= 0;
321 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
322 ret
->elf
.dynindx
= -1;
323 ret
->elf
.needs_plt
= 0;
324 ret
->elf
.plt
.refcount
= -1;
325 ret
->elf
.got
.refcount
= -1;
326 ret
->elf
.def_dynamic
= 0;
327 ret
->elf
.def_regular
= 1;
328 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
329 ret
->elf
.ref_regular
= 0;
330 ret
->elf
.forced_local
= 1;
331 ret
->elf
.root
.type
= bfd_link_hash_defined
;
337 /* Destroy an LoongArch elf linker hash table. */
340 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
342 struct loongarch_elf_link_hash_table
*ret
;
343 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
345 if (ret
->loc_hash_table
)
346 htab_delete (ret
->loc_hash_table
);
347 if (ret
->loc_hash_memory
)
348 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
350 _bfd_elf_link_hash_table_free (obfd
);
353 /* Create a LoongArch ELF linker hash table. */
355 static struct bfd_link_hash_table
*
356 loongarch_elf_link_hash_table_create (bfd
*abfd
)
358 struct loongarch_elf_link_hash_table
*ret
;
359 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
361 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
365 if (!_bfd_elf_link_hash_table_init
366 (&ret
->elf
, abfd
, link_hash_newfunc
,
367 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
373 ret
->max_alignment
= MINUS_ONE
;
375 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
376 elfNN_loongarch_local_htab_eq
, NULL
);
377 ret
->loc_hash_memory
= objalloc_create ();
378 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
380 elfNN_loongarch_link_hash_table_free (abfd
);
383 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
385 return &ret
->elf
.root
;
388 /* Merge backend specific data from an object file to the output
389 object file when linking. */
392 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
394 bfd
*obfd
= info
->output_bfd
;
395 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
396 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
398 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
401 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
403 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
404 "the selected emulation:\n"
405 " target emulation `%s' does not match `%s'"),
406 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
410 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
413 /* If the input BFD is not a dynamic object and it does not contain any
414 non-data sections, do not account its ABI. For example, various
415 packages produces such data-only relocatable objects with
416 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
417 But they are compatible with all ABIs. */
418 if (!(ibfd
->flags
& DYNAMIC
))
421 bool have_code_sections
= false;
422 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
423 if ((bfd_section_flags (sec
)
424 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
425 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
427 have_code_sections
= true;
430 if (!have_code_sections
)
434 if (!elf_flags_init (obfd
))
436 elf_flags_init (obfd
) = true;
437 elf_elfheader (obfd
)->e_flags
= in_flags
;
440 else if (out_flags
!= in_flags
)
442 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags
)
443 && EF_LOONGARCH_IS_OBJ_V1 (in_flags
))
444 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags
)
445 && EF_LOONGARCH_IS_OBJ_V1 (out_flags
)))
447 elf_elfheader (obfd
)->e_flags
|= EF_LOONGARCH_OBJABI_V1
;
448 out_flags
= elf_elfheader (obfd
)->e_flags
;
449 in_flags
= out_flags
;
453 /* Disallow linking different ABIs. */
454 /* Only check relocation version.
455 The obj_v0 is compatible with obj_v1. */
456 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
458 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
465 bfd_set_error (bfd_error_bad_value
);
469 /* Create the .got section. */
472 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
477 struct elf_link_hash_entry
*h
;
478 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
479 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
481 /* This function may be called more than once. */
482 if (htab
->sgot
!= NULL
)
485 flags
= bed
->dynamic_sec_flags
;
486 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
487 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
489 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
493 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
494 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
498 /* The first bit of the global offset table is the header. */
499 s
->size
+= bed
->got_header_size
;
501 if (bed
->want_got_plt
)
503 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
504 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
508 /* Reserve room for the header. */
509 s
->size
= GOTPLT_HEADER_SIZE
;
512 if (bed
->want_got_sym
)
514 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
515 section. We don't do this in the linker script because we don't want
516 to define the symbol if we are not creating a global offset table. */
517 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
518 "_GLOBAL_OFFSET_TABLE_");
519 elf_hash_table (info
)->hgot
= h
;
526 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
527 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
531 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
533 struct loongarch_elf_link_hash_table
*htab
;
535 htab
= loongarch_elf_hash_table (info
);
536 BFD_ASSERT (htab
!= NULL
);
538 if (!loongarch_elf_create_got_section (dynobj
, info
))
541 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
544 if (!bfd_link_pic (info
))
546 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
547 SEC_ALLOC
| SEC_THREAD_LOCAL
);
549 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
550 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
557 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
558 struct bfd_link_info
*info
,
559 struct elf_link_hash_entry
*h
,
560 unsigned long symndx
,
563 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
564 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
566 /* This is a global offset table entry for a local symbol. */
567 if (elf_local_got_refcounts (abfd
) == NULL
)
570 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
571 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
573 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
574 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
584 if (htab
->elf
.sgot
== NULL
585 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
589 if (h
->got
.refcount
< 0)
594 elf_local_got_refcounts (abfd
)[symndx
]++;
597 /* No need for GOT. */
600 _bfd_error_handler (_("Internal error: unreachable."));
604 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
605 *new_tls_type
|= tls_type
;
607 /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
608 if ((*new_tls_type
& GOT_TLS_IE
) && (*new_tls_type
& GOT_TLS_GDESC
))
609 *new_tls_type
&= ~ (GOT_TLS_GDESC
);
610 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
612 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
613 "thread local symbol"),
615 h
? h
->root
.root
.string
: "<local>");
623 loongarch_reloc_got_type (unsigned int r_type
)
627 case R_LARCH_TLS_DESC_PC_HI20
:
628 case R_LARCH_TLS_DESC_PC_LO12
:
629 case R_LARCH_TLS_DESC_LD
:
630 case R_LARCH_TLS_DESC_CALL
:
631 return GOT_TLS_GDESC
;
633 case R_LARCH_TLS_IE_PC_HI20
:
634 case R_LARCH_TLS_IE_PC_LO12
:
643 /* Return true if tls type transition can be performed. */
645 loongarch_can_relax_tls (struct bfd_link_info
*info
, unsigned int r_type
,
646 struct elf_link_hash_entry
*h
, bfd
*input_bfd
,
647 unsigned long r_symndx
)
649 char symbol_tls_type
;
650 unsigned int reloc_got_type
;
652 if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type
)
653 || IS_LOONGARCH_TLS_IE_RELOC (r_type
)))
656 symbol_tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
657 reloc_got_type
= loongarch_reloc_got_type (r_type
);
659 if (symbol_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
662 if (! bfd_link_executable (info
))
665 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
671 /* The type of relocation that can be transitioned. */
673 loongarch_tls_transition_without_check (struct bfd_link_info
*info
,
675 struct elf_link_hash_entry
*h
)
677 bool local_exec
= bfd_link_executable (info
)
678 && SYMBOL_REFERENCES_LOCAL (info
, h
);
682 case R_LARCH_TLS_DESC_PC_HI20
:
684 ? R_LARCH_TLS_LE_HI20
685 : R_LARCH_TLS_IE_PC_HI20
);
687 case R_LARCH_TLS_DESC_PC_LO12
:
689 ? R_LARCH_TLS_LE_LO12
690 : R_LARCH_TLS_IE_PC_LO12
);
692 case R_LARCH_TLS_DESC_LD
:
693 case R_LARCH_TLS_DESC_CALL
:
696 case R_LARCH_TLS_IE_PC_HI20
:
697 return local_exec
? R_LARCH_TLS_LE_HI20
: r_type
;
699 case R_LARCH_TLS_IE_PC_LO12
:
700 return local_exec
? R_LARCH_TLS_LE_LO12
: r_type
;
710 loongarch_tls_transition (struct bfd_link_info
*info
, unsigned int r_type
,
711 struct elf_link_hash_entry
*h
, bfd
*input_bfd
,
712 unsigned long r_symndx
)
714 if (! loongarch_can_relax_tls (info
, r_type
, h
, input_bfd
,r_symndx
))
717 return loongarch_tls_transition_without_check (info
, r_type
, h
);
720 /* Look through the relocs for a section during the first phase, and
721 allocate space in the global offset table or procedure linkage
725 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
726 asection
*sec
, const Elf_Internal_Rela
*relocs
)
728 struct loongarch_elf_link_hash_table
*htab
;
729 Elf_Internal_Shdr
*symtab_hdr
;
730 struct elf_link_hash_entry
**sym_hashes
;
731 const Elf_Internal_Rela
*rel
;
732 asection
*sreloc
= NULL
;
734 if (bfd_link_relocatable (info
))
737 htab
= loongarch_elf_hash_table (info
);
738 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
739 sym_hashes
= elf_sym_hashes (abfd
);
741 if (htab
->elf
.dynobj
== NULL
)
742 htab
->elf
.dynobj
= abfd
;
744 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
747 unsigned int r_symndx
;
748 struct elf_link_hash_entry
*h
;
749 Elf_Internal_Sym
*isym
= NULL
;
751 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
752 r_type
= ELFNN_R_TYPE (rel
->r_info
);
754 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
756 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
760 if (r_symndx
< symtab_hdr
->sh_info
)
762 /* A local symbol. */
763 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
767 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
769 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
773 h
->type
= STT_GNU_IFUNC
;
781 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
782 while (h
->root
.type
== bfd_link_hash_indirect
783 || h
->root
.type
== bfd_link_hash_warning
)
784 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
787 /* It is referenced by a non-shared object. */
791 if (h
&& h
->type
== STT_GNU_IFUNC
)
793 if (htab
->elf
.dynobj
== NULL
)
794 htab
->elf
.dynobj
= abfd
;
796 /* Create 'irelifunc' in PIC object. */
797 if (bfd_link_pic (info
)
798 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
800 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
801 else if (!htab
->elf
.splt
802 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
804 /* Create the ifunc sections, iplt and ipltgot, for static
806 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
807 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
810 if (h
->plt
.refcount
< 0)
815 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
818 int need_dynreloc
= 0;
819 int only_need_pcrel
= 0;
821 r_type
= loongarch_tls_transition (info
, r_type
, h
, abfd
, r_symndx
);
824 case R_LARCH_GOT_PC_HI20
:
825 case R_LARCH_GOT_HI20
:
826 case R_LARCH_SOP_PUSH_GPREL
:
829 h
->pointer_equality_needed
= 1;
830 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
836 case R_LARCH_TLS_LD_PC_HI20
:
837 case R_LARCH_TLS_LD_HI20
:
838 case R_LARCH_TLS_GD_PC_HI20
:
839 case R_LARCH_TLS_GD_HI20
:
840 case R_LARCH_SOP_PUSH_TLS_GD
:
841 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
847 case R_LARCH_TLS_IE_PC_HI20
:
848 case R_LARCH_TLS_IE_HI20
:
849 case R_LARCH_SOP_PUSH_TLS_GOT
:
850 if (bfd_link_pic (info
))
851 /* May fail for lazy-bind. */
852 info
->flags
|= DF_STATIC_TLS
;
854 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
860 case R_LARCH_TLS_LE_HI20
:
861 case R_LARCH_SOP_PUSH_TLS_TPREL
:
862 if (!bfd_link_executable (info
))
865 info
->flags
|= DF_STATIC_TLS
;
867 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
873 case R_LARCH_TLS_DESC_PC_HI20
:
874 case R_LARCH_TLS_DESC_HI20
:
875 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
881 case R_LARCH_ABS_HI20
:
882 case R_LARCH_SOP_PUSH_ABSOLUTE
:
884 /* If this reloc is in a read-only section, we might
885 need a copy reloc. We can't check reliably at this
886 stage whether the section is read-only, as input
887 sections have not yet been mapped to output sections.
888 Tentatively set the flag for now, and correct in
889 adjust_dynamic_symbol. */
893 case R_LARCH_PCALA_HI20
:
896 /* For pcalau12i + jirl. */
898 if (h
->plt
.refcount
< 0)
903 h
->pointer_equality_needed
= 1;
915 if (!bfd_link_pic (info
))
918 /* We try to create PLT stub for all non-local function. */
919 if (h
->plt
.refcount
< 0)
926 case R_LARCH_SOP_PUSH_PCREL
:
929 if (!bfd_link_pic (info
))
932 /* We try to create PLT stub for all non-local function. */
933 if (h
->plt
.refcount
< 0)
936 h
->pointer_equality_needed
= 1;
941 case R_LARCH_SOP_PUSH_PLT_PCREL
:
942 /* This symbol requires a procedure linkage table entry. We
943 actually build the entry in adjust_dynamic_symbol,
944 because this might be a case of linking PIC code without
945 linking in any dynamic objects, in which case we don't
946 need to generate a procedure linkage table after all. */
950 if (h
->plt
.refcount
< 0)
956 case R_LARCH_TLS_DTPREL32
:
957 case R_LARCH_TLS_DTPREL64
:
962 case R_LARCH_JUMP_SLOT
:
968 /* If resolved symbol is defined in this object,
969 1. Under pie, the symbol is known. We convert it
970 into R_LARCH_RELATIVE and need load-addr still.
971 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
972 3. Under dll, R_LARCH_NN can't be changed normally, since
973 its defination could be covered by the one in executable.
974 For symbolic, we convert it into R_LARCH_RELATIVE.
975 Thus, only under pde, it needs pcrel only. We discard it. */
976 only_need_pcrel
= bfd_link_pde (info
);
979 && (!bfd_link_pic (info
)
980 || h
->type
== STT_GNU_IFUNC
))
982 /* This reloc might not bind locally. */
984 h
->pointer_equality_needed
= 1;
987 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
989 /* We may need a .plt entry if the symbol is a function
990 defined in a shared lib or is a function referenced
991 from the code or read-only section. */
992 h
->plt
.refcount
+= 1;
997 case R_LARCH_GNU_VTINHERIT
:
998 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1002 case R_LARCH_GNU_VTENTRY
:
1003 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1011 /* Record some info for sizing and allocating dynamic entry. */
1012 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
1014 /* When creating a shared object, we must copy these
1015 relocs into the output file. We create a reloc
1016 section in dynobj and make room for the reloc. */
1017 struct elf_dyn_relocs
*p
;
1018 struct elf_dyn_relocs
**head
;
1023 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
1024 LARCH_ELF_LOG_WORD_BYTES
,
1025 abfd
, /*rela?*/ true);
1030 /* If this is a global symbol, we count the number of
1031 relocations we need for this symbol. */
1033 head
= &h
->dyn_relocs
;
1036 /* Track dynamic relocs needed for local syms too.
1037 We really need local syms available to do this
1043 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1047 vpp
= &elf_section_data (s
)->local_dynrel
;
1048 head
= (struct elf_dyn_relocs
**) vpp
;
1052 if (p
== NULL
|| p
->sec
!= sec
)
1054 bfd_size_type amt
= sizeof *p
;
1055 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
1066 p
->pc_count
+= only_need_pcrel
;
1073 /* Find dynamic relocs for H that apply to read-only sections. */
1076 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
1078 struct elf_dyn_relocs
*p
;
1080 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1082 asection
*s
= p
->sec
->output_section
;
1084 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
1090 /* Adjust a symbol defined by a dynamic object and referenced by a
1091 regular object. The current definition is in some section of the
1092 dynamic object, but we're not including those sections. We have to
1093 change the definition to something the rest of the link can
1096 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
1097 struct elf_link_hash_entry
*h
)
1099 struct loongarch_elf_link_hash_table
*htab
;
1102 htab
= loongarch_elf_hash_table (info
);
1103 BFD_ASSERT (htab
!= NULL
);
1105 dynobj
= htab
->elf
.dynobj
;
1107 /* Make sure we know what is going on here. */
1108 BFD_ASSERT (dynobj
!= NULL
1110 || h
->type
== STT_GNU_IFUNC
1114 && !h
->def_regular
)));
1116 /* If this is a function, put it in the procedure linkage table. We
1117 will fill in the contents of the procedure linkage table later
1118 (although we could actually do it here). */
1119 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
1121 if (h
->plt
.refcount
<= 0
1122 || (h
->type
!= STT_GNU_IFUNC
1123 && (SYMBOL_REFERENCES_LOCAL (info
, h
)
1124 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1125 && h
->root
.type
== bfd_link_hash_undefweak
))))
1127 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1128 in an input file, but the symbol was never referred to by a
1129 dynamic object, or if all references were garbage collected.
1130 In such a case, we don't actually need to build a PLT entry. */
1131 h
->plt
.offset
= MINUS_ONE
;
1138 h
->plt
.offset
= MINUS_ONE
;
1140 /* If this is a weak symbol, and there is a real definition, the
1141 processor independent code will have arranged for us to see the
1142 real definition first, and we can just use the same value. */
1143 if (h
->is_weakalias
)
1145 struct elf_link_hash_entry
*def
= weakdef (h
);
1146 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
1147 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
1148 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
1152 /* R_LARCH_COPY is not adept glibc, not to generate. */
1153 /* Can not print anything, because make check ld. */
1157 /* Allocate space in .plt, .got and associated reloc sections for
1161 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1163 struct bfd_link_info
*info
;
1164 struct loongarch_elf_link_hash_table
*htab
;
1165 struct elf_dyn_relocs
*p
;
1167 if (h
->root
.type
== bfd_link_hash_indirect
)
1170 if (h
->type
== STT_GNU_IFUNC
1174 info
= (struct bfd_link_info
*) inf
;
1175 htab
= loongarch_elf_hash_table (info
);
1176 bool dyn
= htab
->elf
.dynamic_sections_created
;
1177 BFD_ASSERT (htab
!= NULL
);
1181 asection
*plt
, *gotplt
, *relplt
;
1190 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1191 && h
->root
.type
== bfd_link_hash_undefweak
)
1193 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1197 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1198 && h
->type
!= STT_GNU_IFUNC
)
1201 plt
= htab
->elf
.splt
;
1202 gotplt
= htab
->elf
.sgotplt
;
1203 relplt
= htab
->elf
.srelplt
;
1205 else if (htab
->elf
.iplt
)
1207 /* .iplt only for IFUNC. */
1208 if (h
->type
!= STT_GNU_IFUNC
)
1211 plt
= htab
->elf
.iplt
;
1212 gotplt
= htab
->elf
.igotplt
;
1213 relplt
= htab
->elf
.irelplt
;
1219 plt
->size
= PLT_HEADER_SIZE
;
1221 h
->plt
.offset
= plt
->size
;
1222 plt
->size
+= PLT_ENTRY_SIZE
;
1223 gotplt
->size
+= GOT_ENTRY_SIZE
;
1224 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1226 /* If this symbol is not defined in a regular file, and we are
1227 not generating a shared library, then set the symbol to this
1228 location in the .plt. This is required to make function
1229 pointers compare as equal between the normal executable and
1230 the shared library. */
1231 if (!bfd_link_pic (info
)
1234 h
->root
.u
.def
.section
= plt
;
1235 h
->root
.u
.def
.value
= h
->plt
.offset
;
1243 h
->plt
.offset
= MINUS_ONE
;
1245 if (0 < h
->got
.refcount
)
1248 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1250 /* Make sure this symbol is output as a dynamic symbol.
1251 Undefined weak syms won't yet be marked as dynamic. */
1252 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1253 && h
->root
.type
== bfd_link_hash_undefweak
)
1255 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1260 h
->got
.offset
= s
->size
;
1261 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1263 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1264 if (tls_type
& GOT_TLS_GD
)
1266 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1267 if (bfd_link_executable (info
))
1269 /* Link exe and not defined local. */
1270 if (!SYMBOL_REFERENCES_LOCAL (info
, h
))
1271 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1275 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1276 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1278 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1282 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1283 if (tls_type
& GOT_TLS_IE
)
1285 s
->size
+= GOT_ENTRY_SIZE
;
1287 if (bfd_link_executable (info
))
1289 /* Link exe and not defined local. */
1290 if (!SYMBOL_REFERENCES_LOCAL (info
, h
))
1291 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1295 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1299 /* TLS_DESC needs one dynamic reloc and two GOT slot. */
1300 if (tls_type
& GOT_TLS_GDESC
)
1302 s
->size
+= GOT_ENTRY_SIZE
* 2;
1303 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1309 s
->size
+= GOT_ENTRY_SIZE
;
1310 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1311 || h
->root
.type
!= bfd_link_hash_undefweak
)
1312 && (bfd_link_pic (info
)
1313 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
),
1315 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1316 /* Undefined weak symbol in static PIE resolves to 0 without
1317 any dynamic relocations. */
1318 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1322 h
->got
.offset
= MINUS_ONE
;
1324 if (h
->dyn_relocs
== NULL
)
1327 /* Extra dynamic relocate,
1329 * R_LARCH_TLS_DTPRELNN
1333 if (SYMBOL_CALLS_LOCAL (info
, h
))
1335 struct elf_dyn_relocs
**pp
;
1337 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1339 p
->count
-= p
->pc_count
;
1348 if (h
->root
.type
== bfd_link_hash_undefweak
)
1350 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
)
1351 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1352 || (!bfd_link_pic (info
) && h
->non_got_ref
))
1353 h
->dyn_relocs
= NULL
;
1354 else if (h
->dynindx
== -1 && !h
->forced_local
)
1356 /* Make sure this symbol is output as a dynamic symbol.
1357 Undefined weak syms won't yet be marked as dynamic. */
1358 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1361 if (h
->dynindx
== -1)
1362 h
->dyn_relocs
= NULL
;
1366 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1368 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1369 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1375 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1376 For local def and ref ifunc,
1377 dynamic relocations are stored in
1378 1. rela.srelgot section in dynamic object (dll or exec).
1379 2. rela.irelplt section in static executable.
1380 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1381 instead of rela.srelplt. Glibc ELF loader will not support
1382 R_LARCH_IRELATIVE relocation in rela.plt. */
1385 local_allocate_ifunc_dyn_relocs (struct bfd_link_info
*info
,
1386 struct elf_link_hash_entry
*h
,
1387 struct elf_dyn_relocs
**head
,
1388 unsigned int plt_entry_size
,
1389 unsigned int plt_header_size
,
1390 unsigned int got_entry_size
,
1393 asection
*plt
, *gotplt
, *relplt
;
1394 struct elf_dyn_relocs
*p
;
1395 unsigned int sizeof_reloc
;
1396 const struct elf_backend_data
*bed
;
1397 struct elf_link_hash_table
*htab
;
1398 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1399 bool use_plt
= !avoid_plt
|| h
->plt
.refcount
> 0;
1400 bool need_dynreloc
= !use_plt
|| bfd_link_pic (info
);
1402 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1403 in executable or it isn't referenced via PLT, the address of
1404 the resolved function may be used. But in non-PIC executable,
1405 the address of its plt slot may be used. Pointer equality may
1406 not work correctly. PIE or non-PLT reference should be used if
1407 pointer equality is required here.
1409 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1410 backend should change it to the normal function and set its address
1411 to its PLT entry which should be resolved by R_*_IRELATIVE at
1412 run-time. All external references should be resolved to its PLT in
1415 && !(bfd_link_pde (info
) && h
->def_regular
)
1416 && (h
->dynindx
!= -1
1417 || info
->export_dynamic
)
1418 && h
->pointer_equality_needed
)
1420 info
->callbacks
->einfo
1421 /* xgettext:c-format. */
1422 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1423 "equality in `%pB' can not be used when making an "
1424 "executable; recompile with -fPIE and relink with -pie\n"),
1425 h
->root
.root
.string
,
1426 h
->root
.u
.def
.section
->owner
);
1427 bfd_set_error (bfd_error_bad_value
);
1431 htab
= elf_hash_table (info
);
1433 /* When the symbol is marked with regular reference, if PLT isn't used
1434 or we are building a PIC object, we must keep dynamic relocation
1435 if there is non-GOT reference and use PLT if there is PC-relative
1437 if (need_dynreloc
&& h
->ref_regular
)
1440 for (p
= *head
; p
!= NULL
; p
= p
->next
)
1444 /* Need dynamic relocations for non-GOT reference. */
1448 /* Must use PLT for PC-relative reference. */
1450 need_dynreloc
= bfd_link_pic (info
);
1458 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1459 if (h
->plt
.refcount
<= 0 && h
->got
.refcount
<= 0)
1461 h
->got
= htab
->init_got_offset
;
1462 h
->plt
= htab
->init_plt_offset
;
1467 /* Return and discard space for dynamic relocations against it if
1468 it is never referenced. */
1469 if (!h
->ref_regular
)
1471 if (h
->plt
.refcount
> 0
1472 || h
->got
.refcount
> 0)
1474 h
->got
= htab
->init_got_offset
;
1475 h
->plt
= htab
->init_plt_offset
;
1481 bed
= get_elf_backend_data (info
->output_bfd
);
1482 if (bed
->rela_plts_and_copies_p
)
1483 sizeof_reloc
= bed
->s
->sizeof_rela
;
1485 sizeof_reloc
= bed
->s
->sizeof_rel
;
1487 /* When building a static executable, use iplt, igot.plt and
1488 rela.iplt sections for STT_GNU_IFUNC symbols. */
1489 if (htab
->splt
!= NULL
)
1492 gotplt
= htab
->sgotplt
;
1493 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1494 relplt
= htab
->srelgot
;
1496 /* If this is the first plt entry and PLT is used, make room for
1497 the special first entry. */
1498 if (plt
->size
== 0 && use_plt
)
1499 plt
->size
+= plt_header_size
;
1504 gotplt
= htab
->igotplt
;
1505 relplt
= htab
->irelplt
;
1510 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1511 the original value for R_*_IRELATIVE. */
1512 h
->plt
.offset
= plt
->size
;
1514 /* Make room for this entry in the plt/iplt section. */
1515 plt
->size
+= plt_entry_size
;
1517 /* We also need to make an entry in the got.plt/got.iplt section,
1518 which will be placed in the got section by the linker script. */
1519 gotplt
->size
+= got_entry_size
;
1522 /* We also need to make an entry in the rela.plt/.rela.iplt
1523 section for GOTPLT relocation if PLT is used. */
1526 relplt
->size
+= sizeof_reloc
;
1527 relplt
->reloc_count
++;
1530 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1531 there is a non-GOT reference in a PIC object or PLT isn't used. */
1532 if (!need_dynreloc
|| !h
->non_got_ref
)
1535 /* Finally, allocate space. */
1539 bfd_size_type count
= 0;
1547 htab
->ifunc_resolvers
= count
!= 0;
1549 /* Dynamic relocations are stored in
1550 1. rela.srelgot section in PIC object.
1551 2. rela.srelgot section in dynamic executable.
1552 3. rela.irelplt section in static executable. */
1553 if (htab
->splt
!= NULL
)
1554 htab
->srelgot
->size
+= count
* sizeof_reloc
;
1557 relplt
->size
+= count
* sizeof_reloc
;
1558 relplt
->reloc_count
+= count
;
1562 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1563 and got has the PLT entry adddress. We will load the GOT entry
1564 with the PLT entry in finish_dynamic_symbol if it is used. For
1565 branch, it uses got.plt. For symbol value, if PLT is used,
1566 1. Use got.plt in a PIC object if it is forced local or not
1568 2. Use got.plt in a non-PIC object if pointer equality isn't
1570 3. Use got.plt in PIE.
1571 4. Use got.plt if got isn't used.
1572 5. Otherwise use got so that it can be shared among different
1573 objects at run-time.
1574 If PLT isn't used, always use got for symbol value.
1575 We only need to relocate got entry in PIC object or in dynamic
1576 executable without PLT. */
1578 && (h
->got
.refcount
<= 0
1579 || (bfd_link_pic (info
)
1580 && (h
->dynindx
== -1
1581 || h
->forced_local
))
1583 !h
->pointer_equality_needed
)
1584 || htab
->sgot
== NULL
))
1587 h
->got
.offset
= (bfd_vma
) -1;
1593 /* PLT isn't used. */
1594 h
->plt
.offset
= (bfd_vma
) -1;
1596 if (h
->got
.refcount
<= 0)
1598 /* GOT isn't need when there are only relocations for static
1600 h
->got
.offset
= (bfd_vma
) -1;
1604 h
->got
.offset
= htab
->sgot
->size
;
1605 htab
->sgot
->size
+= got_entry_size
;
1606 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1607 used. Otherwise, the GOT entry will be filled with the PLT
1608 entry and dynamic GOT relocation isn't needed. */
1611 /* For non-static executable, dynamic GOT relocation is in
1612 rela.got section, but for static executable, it is
1613 in rela.iplt section. */
1614 if (htab
->splt
!= NULL
)
1615 htab
->srelgot
->size
+= sizeof_reloc
;
1618 relplt
->size
+= sizeof_reloc
;
1619 relplt
->reloc_count
++;
1628 /* Allocate space in .plt, .got and associated reloc sections for
1629 ifunc dynamic relocs. */
1632 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1634 struct bfd_link_info
*info
;
1635 /* An example of a bfd_link_hash_indirect symbol is versioned
1636 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1637 -> __gxx_personality_v0(bfd_link_hash_defined)
1639 There is no need to process bfd_link_hash_indirect symbols here
1640 because we will also be presented with the concrete instance of
1641 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1642 called to copy all relevant data from the generic to the concrete
1644 if (h
->root
.type
== bfd_link_hash_indirect
)
1647 if (h
->root
.type
== bfd_link_hash_warning
)
1648 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1650 info
= (struct bfd_link_info
*) inf
;
1652 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1653 here if it is defined and referenced in a non-shared object. */
1654 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
1656 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1657 return local_allocate_ifunc_dyn_relocs (info
, h
,
1664 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1675 /* Allocate space in .plt, .got and associated reloc sections for
1676 ifunc dynamic relocs. */
1679 elfNN_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
1681 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1683 if (h
->type
!= STT_GNU_IFUNC
1687 || h
->root
.type
!= bfd_link_hash_defined
)
1690 return elfNN_allocate_ifunc_dynrelocs (h
, inf
);
1693 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1694 read-only sections. */
1697 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1701 if (h
->root
.type
== bfd_link_hash_indirect
)
1704 sec
= readonly_dynrelocs (h
);
1707 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1709 info
->flags
|= DF_TEXTREL
;
1710 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1711 "read-only section `%pA'\n"),
1712 sec
->owner
, h
->root
.root
.string
, sec
);
1714 /* Not an error, just cut short the traversal. */
1721 loongarch_elf_size_dynamic_sections (bfd
*output_bfd
,
1722 struct bfd_link_info
*info
)
1724 struct loongarch_elf_link_hash_table
*htab
;
1729 htab
= loongarch_elf_hash_table (info
);
1730 BFD_ASSERT (htab
!= NULL
);
1731 dynobj
= htab
->elf
.dynobj
;
1732 BFD_ASSERT (dynobj
!= NULL
);
1734 if (htab
->elf
.dynamic_sections_created
)
1736 /* Set the contents of the .interp section to the interpreter. */
1737 if (bfd_link_executable (info
) && !info
->nointerp
)
1739 const char *interpreter
;
1740 s
= bfd_get_linker_section (dynobj
, ".interp");
1741 BFD_ASSERT (s
!= NULL
);
1743 if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS32
)
1744 interpreter
= "/lib32/ld.so.1";
1745 else if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS64
)
1746 interpreter
= "/lib64/ld.so.1";
1748 interpreter
= "/lib/ld.so.1";
1750 s
->contents
= (unsigned char *) interpreter
;
1751 s
->size
= strlen (interpreter
) + 1;
1755 /* Set up .got offsets for local syms, and space for local dynamic
1757 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
1759 bfd_signed_vma
*local_got
;
1760 bfd_signed_vma
*end_local_got
;
1761 char *local_tls_type
;
1762 bfd_size_type locsymcount
;
1763 Elf_Internal_Shdr
*symtab_hdr
;
1766 if (!is_loongarch_elf (ibfd
))
1769 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
1771 struct elf_dyn_relocs
*p
;
1773 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
1775 p
->count
-= p
->pc_count
;
1776 if (!bfd_is_abs_section (p
->sec
)
1777 && bfd_is_abs_section (p
->sec
->output_section
))
1779 /* Input section has been discarded, either because
1780 it is a copy of a linkonce section or due to
1781 linker script /DISCARD/, so we'll be discarding
1784 else if (0 < p
->count
)
1786 srel
= elf_section_data (p
->sec
)->sreloc
;
1787 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1788 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
1789 info
->flags
|= DF_TEXTREL
;
1794 local_got
= elf_local_got_refcounts (ibfd
);
1798 symtab_hdr
= &elf_symtab_hdr (ibfd
);
1799 locsymcount
= symtab_hdr
->sh_info
;
1800 end_local_got
= local_got
+ locsymcount
;
1801 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
1803 srel
= htab
->elf
.srelgot
;
1804 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
1808 *local_got
= s
->size
;
1809 if (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
1811 /* TLS gd use two got. */
1812 if (*local_tls_type
& GOT_TLS_GD
)
1814 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1815 if (!bfd_link_executable (info
))
1816 srel
->size
+= sizeof (ElfNN_External_Rela
);
1819 /* TLS_DESC use two got. */
1820 if (*local_tls_type
& GOT_TLS_GDESC
)
1822 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1823 srel
->size
+= sizeof (ElfNN_External_Rela
);
1826 /* TLS ie and use one got. */
1827 if (*local_tls_type
& GOT_TLS_IE
)
1829 s
->size
+= GOT_ENTRY_SIZE
;
1830 if (!bfd_link_executable (info
))
1831 srel
->size
+= sizeof (ElfNN_External_Rela
);
1836 s
->size
+= GOT_ENTRY_SIZE
;
1837 srel
->size
+= sizeof (ElfNN_External_Rela
);
1841 *local_got
= MINUS_ONE
;
1845 /* Allocate global sym .plt and .got entries, and space for global
1846 sym dynamic relocs. */
1847 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
1849 /* Allocate global ifunc sym .plt and .got entries, and space for global
1850 ifunc sym dynamic relocs. */
1851 elf_link_hash_traverse (&htab
->elf
, elfNN_allocate_ifunc_dynrelocs
, info
);
1853 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1854 htab_traverse (htab
->loc_hash_table
,
1855 elfNN_allocate_local_ifunc_dynrelocs
, info
);
1857 /* Don't allocate .got.plt section if there are no PLT. */
1858 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
1859 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
1860 htab
->elf
.sgotplt
->size
= 0;
1862 /* The check_relocs and adjust_dynamic_symbol entry points have
1863 determined the sizes of the various dynamic sections. Allocate
1865 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
1867 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
1870 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
1871 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
1872 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
1874 /* Strip this section if we don't need it; see the
1877 else if (strncmp (s
->name
, ".rela", 5) == 0)
1881 /* We use the reloc_count field as a counter if we need
1882 to copy relocs into the output file. */
1888 /* It's not one of our sections. */
1894 /* If we don't need this section, strip it from the
1895 output file. This is mostly to handle .rela.bss and
1896 .rela.plt. We must create both sections in
1897 create_dynamic_sections, because they must be created
1898 before the linker maps input sections to output
1899 sections. The linker does that before
1900 adjust_dynamic_symbol is called, and it is that
1901 function which decides whether anything needs to go
1902 into these sections. */
1903 s
->flags
|= SEC_EXCLUDE
;
1907 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
1910 /* Allocate memory for the section contents. Zero the memory
1911 for the benefit of .rela.plt, which has 4 unused entries
1912 at the beginning, and we don't want garbage. */
1913 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
1914 if (s
->contents
== NULL
)
1918 if (elf_hash_table (info
)->dynamic_sections_created
)
1920 /* Add some entries to the .dynamic section. We fill in the
1921 values later, in loongarch_elf_finish_dynamic_sections, but we
1922 must add the entries now so that we get the correct size for
1923 the .dynamic section. The DT_DEBUG entry is filled in by the
1924 dynamic linker and used by the debugger. */
1925 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1927 if (bfd_link_executable (info
))
1929 if (!add_dynamic_entry (DT_DEBUG
, 0))
1933 if (htab
->elf
.srelplt
->size
!= 0)
1935 if (!add_dynamic_entry (DT_PLTGOT
, 0)
1936 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
1937 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
1938 || !add_dynamic_entry (DT_JMPREL
, 0))
1942 if (!add_dynamic_entry (DT_RELA
, 0)
1943 || !add_dynamic_entry (DT_RELASZ
, 0)
1944 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
1947 /* If any dynamic relocs apply to a read-only section,
1948 then we need a DT_TEXTREL entry. */
1949 if ((info
->flags
& DF_TEXTREL
) == 0)
1950 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
1952 if (info
->flags
& DF_TEXTREL
)
1954 if (!add_dynamic_entry (DT_TEXTREL
, 0))
1956 /* Clear the DF_TEXTREL flag. It will be set again if we
1957 write out an actual text relocation; we may not, because
1958 at this point we do not know whether e.g. any .eh_frame
1959 absolute relocations have been converted to PC-relative. */
1960 info
->flags
&= ~DF_TEXTREL
;
1963 #undef add_dynamic_entry
1968 #define LARCH_LD_STACK_DEPTH 16
1969 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
1970 static size_t larch_stack_top
= 0;
1972 static bfd_reloc_status_type
1973 loongarch_push (int64_t val
)
1975 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
1976 return bfd_reloc_outofrange
;
1977 larch_opc_stack
[larch_stack_top
++] = val
;
1978 return bfd_reloc_ok
;
1981 static bfd_reloc_status_type
1982 loongarch_pop (int64_t *val
)
1984 if (larch_stack_top
== 0)
1985 return bfd_reloc_outofrange
;
1987 *val
= larch_opc_stack
[--larch_stack_top
];
1988 return bfd_reloc_ok
;
1991 static bfd_reloc_status_type
1992 loongarch_top (int64_t *val
)
1994 if (larch_stack_top
== 0)
1995 return bfd_reloc_outofrange
;
1997 *val
= larch_opc_stack
[larch_stack_top
- 1];
1998 return bfd_reloc_ok
;
2002 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
2004 BFD_ASSERT (s
&& s
->contents
);
2005 const struct elf_backend_data
*bed
;
2008 bed
= get_elf_backend_data (abfd
);
2009 if (!(s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
))
2010 BFD_ASSERT (s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
);
2011 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
2012 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
2015 /* Check rel->r_offset in range of contents. */
2016 static bfd_reloc_status_type
2017 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
2018 const asection
*input_section
)
2020 if (0 == strcmp(input_section
->name
, ".text")
2021 && rel
->r_offset
> input_section
->size
)
2022 return bfd_reloc_overflow
;
2024 return bfd_reloc_ok
;
2027 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
2029 bfd_reloc_status_type ret = loongarch_pop (&op2); \
2030 if (ret == bfd_reloc_ok) \
2032 ret = loongarch_pop (&op1); \
2033 if (ret == bfd_reloc_ok) \
2034 ret = loongarch_push (op3); \
2039 /* Write immediate to instructions. */
2041 static bfd_reloc_status_type
2042 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
2043 const asection
*input_section ATTRIBUTE_UNUSED
,
2044 reloc_howto_type
*howto
, bfd
*input_bfd
,
2045 bfd_byte
*contents
, bfd_vma reloc_val
)
2047 /* Adjust the immediate based on alignment and
2048 its position in the instruction. */
2049 if (!loongarch_adjust_reloc_bitsfield (input_bfd
, howto
, &reloc_val
))
2050 return bfd_reloc_overflow
;
2052 int bits
= bfd_get_reloc_size (howto
) * 8;
2053 uint64_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
2055 /* Write immediate to instruction. */
2056 insn
= (insn
& ~howto
->dst_mask
) | (reloc_val
& howto
->dst_mask
);
2058 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
2060 return bfd_reloc_ok
;
2063 static bfd_reloc_status_type
2064 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
2065 reloc_howto_type
*howto
, bfd_vma value
,
2066 bfd
*input_bfd
, bfd_byte
*contents
)
2068 int64_t opr1
, opr2
, opr3
;
2069 bfd_reloc_status_type r
= bfd_reloc_ok
;
2070 int bits
= bfd_get_reloc_size (howto
) * 8;
2072 switch (ELFNN_R_TYPE (rel
->r_info
))
2074 case R_LARCH_SOP_PUSH_PCREL
:
2075 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2076 case R_LARCH_SOP_PUSH_GPREL
:
2077 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2078 case R_LARCH_SOP_PUSH_TLS_GOT
:
2079 case R_LARCH_SOP_PUSH_TLS_GD
:
2080 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2081 r
= loongarch_push (value
);
2084 case R_LARCH_SOP_PUSH_DUP
:
2085 r
= loongarch_pop (&opr1
);
2086 if (r
== bfd_reloc_ok
)
2088 r
= loongarch_push (opr1
);
2089 if (r
== bfd_reloc_ok
)
2090 r
= loongarch_push (opr1
);
2094 case R_LARCH_SOP_ASSERT
:
2095 r
= loongarch_pop (&opr1
);
2096 if (r
!= bfd_reloc_ok
|| !opr1
)
2097 r
= bfd_reloc_notsupported
;
2100 case R_LARCH_SOP_NOT
:
2101 r
= loongarch_pop (&opr1
);
2102 if (r
== bfd_reloc_ok
)
2103 r
= loongarch_push (!opr1
);
2106 case R_LARCH_SOP_SUB
:
2107 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
2110 case R_LARCH_SOP_SL
:
2111 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
2114 case R_LARCH_SOP_SR
:
2115 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
2118 case R_LARCH_SOP_AND
:
2119 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
2122 case R_LARCH_SOP_ADD
:
2123 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
2126 case R_LARCH_SOP_IF_ELSE
:
2127 r
= loongarch_pop (&opr3
);
2128 if (r
== bfd_reloc_ok
)
2130 r
= loongarch_pop (&opr2
);
2131 if (r
== bfd_reloc_ok
)
2133 r
= loongarch_pop (&opr1
);
2134 if (r
== bfd_reloc_ok
)
2135 r
= loongarch_push (opr1
? opr2
: opr3
);
2140 case R_LARCH_SOP_POP_32_S_10_5
:
2141 case R_LARCH_SOP_POP_32_S_10_12
:
2142 case R_LARCH_SOP_POP_32_S_10_16
:
2143 case R_LARCH_SOP_POP_32_S_10_16_S2
:
2144 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
2145 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
2146 case R_LARCH_SOP_POP_32_S_5_20
:
2147 case R_LARCH_SOP_POP_32_U_10_12
:
2148 case R_LARCH_SOP_POP_32_U
:
2149 r
= loongarch_pop (&opr1
);
2150 if (r
!= bfd_reloc_ok
)
2152 r
= loongarch_check_offset (rel
, input_section
);
2153 if (r
!= bfd_reloc_ok
)
2156 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2158 contents
, (bfd_vma
)opr1
);
2161 case R_LARCH_TLS_DTPREL32
:
2163 case R_LARCH_TLS_DTPREL64
:
2165 r
= loongarch_check_offset (rel
, input_section
);
2166 if (r
!= bfd_reloc_ok
)
2169 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
2172 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2173 Because set/sub reloc pair not support multi-thread. While add/sub
2174 reloc pair process order not affect the final result.
2176 For add/sub reloc, the original value will be involved in the
2177 calculation. In order not to add/sub extra value, we write 0 to symbol
2178 address at assembly time.
2180 add/sub reloc bits determined by the value after symbol subtraction,
2183 add/sub reloc save part of the symbol value, so we only need to
2184 save howto->dst_mask bits. */
2188 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2189 contents
+ rel
->r_offset
);
2190 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2191 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2196 /* Not need to read the original value, just write the new value. */
2208 /* Because add/sub reloc is processed separately,
2209 so the high bits is invalid. */
2210 bfd_vma word
= value
& howto
->dst_mask
;
2211 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2216 case R_LARCH_ADD_ULEB128
:
2217 case R_LARCH_SUB_ULEB128
:
2219 unsigned int len
= 0;
2220 /* Before write uleb128, first read it to get it's length. */
2221 _bfd_read_unsigned_leb128 (input_bfd
, contents
+ rel
->r_offset
, &len
);
2222 loongarch_write_unsigned_leb128 (contents
+ rel
->r_offset
, len
, value
);
2227 /* For eh_frame and debug info. */
2228 case R_LARCH_32_PCREL
:
2229 case R_LARCH_64_PCREL
:
2231 value
-= sec_addr (input_section
) + rel
->r_offset
;
2232 value
+= rel
->r_addend
;
2233 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2234 contents
+ rel
->r_offset
);
2235 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2236 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2242 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2246 case R_LARCH_ABS_HI20
:
2247 case R_LARCH_ABS_LO12
:
2248 case R_LARCH_ABS64_LO20
:
2249 case R_LARCH_ABS64_HI12
:
2250 case R_LARCH_PCALA_HI20
:
2251 case R_LARCH_PCALA_LO12
:
2252 case R_LARCH_PCALA64_LO20
:
2253 case R_LARCH_PCALA64_HI12
:
2254 case R_LARCH_GOT_PC_HI20
:
2255 case R_LARCH_GOT_PC_LO12
:
2256 case R_LARCH_GOT64_PC_LO20
:
2257 case R_LARCH_GOT64_PC_HI12
:
2258 case R_LARCH_GOT_HI20
:
2259 case R_LARCH_GOT_LO12
:
2260 case R_LARCH_GOT64_LO20
:
2261 case R_LARCH_GOT64_HI12
:
2262 case R_LARCH_TLS_LE_HI20
:
2263 case R_LARCH_TLS_LE_LO12
:
2264 case R_LARCH_TLS_LE64_LO20
:
2265 case R_LARCH_TLS_LE64_HI12
:
2266 case R_LARCH_TLS_IE_PC_HI20
:
2267 case R_LARCH_TLS_IE_PC_LO12
:
2268 case R_LARCH_TLS_IE64_PC_LO20
:
2269 case R_LARCH_TLS_IE64_PC_HI12
:
2270 case R_LARCH_TLS_IE_HI20
:
2271 case R_LARCH_TLS_IE_LO12
:
2272 case R_LARCH_TLS_IE64_LO20
:
2273 case R_LARCH_TLS_IE64_HI12
:
2274 case R_LARCH_TLS_LD_PC_HI20
:
2275 case R_LARCH_TLS_LD_HI20
:
2276 case R_LARCH_TLS_GD_PC_HI20
:
2277 case R_LARCH_TLS_GD_HI20
:
2278 case R_LARCH_PCREL20_S2
:
2279 case R_LARCH_CALL36
:
2280 case R_LARCH_TLS_DESC_PC_HI20
:
2281 case R_LARCH_TLS_DESC_PC_LO12
:
2282 case R_LARCH_TLS_DESC64_PC_LO20
:
2283 case R_LARCH_TLS_DESC64_PC_HI12
:
2284 case R_LARCH_TLS_DESC_HI20
:
2285 case R_LARCH_TLS_DESC_LO12
:
2286 case R_LARCH_TLS_DESC64_LO20
:
2287 case R_LARCH_TLS_DESC64_HI12
:
2288 case R_LARCH_TLS_LD_PCREL20_S2
:
2289 case R_LARCH_TLS_GD_PCREL20_S2
:
2290 case R_LARCH_TLS_DESC_PCREL20_S2
:
2291 r
= loongarch_check_offset (rel
, input_section
);
2292 if (r
!= bfd_reloc_ok
)
2295 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2300 case R_LARCH_TLS_DESC_LD
:
2301 case R_LARCH_TLS_DESC_CALL
:
2309 r
= bfd_reloc_notsupported
;
2314 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2322 Elf_Internal_Sym
*sym
;
2323 struct elf_link_hash_entry
*h
;
2326 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
2327 static size_t larch_reloc_queue_head
= 0;
2328 static size_t larch_reloc_queue_tail
= 0;
2331 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
2332 Elf_Internal_Sym
*sym
)
2334 const char *ret
= NULL
;
2336 ret
= bfd_elf_string_from_elf_section (input_bfd
,
2337 elf_symtab_hdr (input_bfd
).sh_link
,
2340 ret
= h
->root
.root
.string
;
2342 if (ret
== NULL
|| *ret
== '\0')
2348 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
2349 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
2350 struct elf_link_hash_entry
*h
, bfd_vma addend
)
2352 if ((larch_reloc_queue_head
== 0
2353 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
2354 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
2355 larch_reloc_queue_head
=
2356 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2357 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
2358 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
2359 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
2360 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
2361 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
2362 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
2363 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
2364 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
2365 larch_reloc_queue_tail
=
2366 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2370 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
2372 size_t i
= larch_reloc_queue_head
;
2374 asection
*section
= NULL
;
2375 bfd_vma r_offset
= 0;
2377 p ("Dump relocate record:\n");
2378 p ("stack top\t\trelocation name\t\tsymbol");
2379 while (i
!= larch_reloc_queue_tail
)
2381 if (a_bfd
!= larch_reloc_queue
[i
].bfd
2382 || section
!= larch_reloc_queue
[i
].section
2383 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
2385 a_bfd
= larch_reloc_queue
[i
].bfd
;
2386 section
= larch_reloc_queue
[i
].section
;
2387 r_offset
= larch_reloc_queue
[i
].r_offset
;
2388 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
2389 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
2393 inited
= 1, p ("...\n");
2395 reloc_howto_type
*howto
=
2396 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
2397 larch_reloc_queue
[i
].r_type
);
2398 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
2399 howto
? howto
->name
: "<unknown reloc>",
2400 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
2401 larch_reloc_queue
[i
].sym
));
2403 long addend
= larch_reloc_queue
[i
].addend
;
2405 p (" - %ld", -addend
);
2406 else if (0 < addend
)
2407 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
2410 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2413 "-- Record dump end --\n\n");
2417 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
2419 asection
*input_section
,
2420 Elf_Internal_Rela
*rel
,
2421 reloc_howto_type
*howto
,
2422 bfd_reloc_status_type rtype
,
2430 /* 'dangerous' means we do it but can't promise it's ok
2431 'unsupport' means out of ability of relocation type
2432 'undefined' means we can't deal with the undefined symbol. */
2433 case bfd_reloc_undefined
:
2434 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
2435 rel
->r_offset
, true);
2436 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2437 input_bfd
, input_section
, rel
->r_offset
,
2439 is_undefweak
? "[undefweak] " : "", name
, msg
);
2441 case bfd_reloc_dangerous
:
2442 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2443 input_bfd
, input_section
, rel
->r_offset
,
2445 is_undefweak
? "[undefweak] " : "", name
, msg
);
2448 case bfd_reloc_notsupported
:
2449 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2450 input_bfd
, input_section
, rel
->r_offset
,
2452 is_undefweak
? "[undefweak] " : "", name
, msg
);
2460 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2461 hi20 immediate need to add 0x1.
2462 For example: pc 0x120000000, symbol 0x120000812
2463 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2464 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2465 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2468 pcalau12i $t0, hi20 (0x1)
2469 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2470 addi.d $t0, $t0, lo12 (0x812)
2471 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2472 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2474 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2476 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
2477 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2479 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2480 relocation = (relocation & ~(bfd_vma)0xfff) \
2481 - (pc & ~(bfd_vma)0xfff); \
2483 relocation += 0x1000; \
2486 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2487 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2489 lo12: 0x1812348ffff812 & 0xfff = 0x812
2490 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2491 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2494 pcalau12i $t1, hi20 (0x80000)
2495 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2496 = 0x11000010000100 + 0xffffffff80000000
2498 addi.d $t0, $zero, lo12 (0x812)
2499 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2500 lo20 need to sub 0x1)
2501 lu32i.d $t0, lo20 (0x71234)
2502 $t0 = {0x71234, 0xfffff812}
2504 lu52i.d $t0, hi12 (0x0)
2505 $t0 = {0x0, 0x71234fffff812}
2508 $t1 = 0x10ffff90000000 + 0x71234fffff812
2509 = 0x1812348ffff812. */
2510 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2512 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2513 relocation = (relocation & ~(bfd_vma)0xfff) \
2514 - (pc & ~(bfd_vma)0xfff); \
2516 relocation += (0x1000 - 0x100000000); \
2517 if (relocation & 0x80000000) \
2518 relocation += 0x100000000; \
2521 /* Transition instruction sequence to relax instruction sequence. */
2523 loongarch_tls_relax (bfd
*abfd
, asection
*sec
, Elf_Internal_Rela
*rel
,
2524 int r_type
, struct elf_link_hash_entry
*h
,
2525 struct bfd_link_info
*info
)
2527 bool local_exec
= bfd_link_executable (info
)
2528 && SYMBOL_REFERENCES_LOCAL (info
, h
);
2529 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
2534 case R_LARCH_TLS_DESC_PC_HI20
:
2536 /* DESC -> LE relaxation:
2537 pcalalau12i $a0,%desc_pc_hi20(var) =>
2538 lu12i.w $a0,%le_hi20(var)
2540 bfd_put (32, abfd
, LARCH_LU12I_W
| LARCH_RD_A0
,
2541 contents
+ rel
->r_offset
);
2543 /* DESC -> IE relaxation:
2544 pcalalau12i $a0,%desc_pc_hi20(var) =>
2545 pcalalau12i $a0,%ie_pc_hi20(var)
2549 case R_LARCH_TLS_DESC_PC_LO12
:
2552 /* DESC -> LE relaxation:
2553 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2554 ori $a0,$a0,le_lo12(var)
2556 insn
= LARCH_ORI
| LARCH_RD_RJ_A0
;
2557 bfd_put (32, abfd
, LARCH_ORI
| LARCH_RD_RJ_A0
,
2558 contents
+ rel
->r_offset
);
2562 /* DESC -> IE relaxation:
2563 addi.d $a0,$a0,%desc_pc_lo12(var) =>
2564 ld.d $a0,$a0,%%ie_pc_lo12
2566 bfd_put (32, abfd
, LARCH_LD_D
| LARCH_RD_RJ_A0
,
2567 contents
+ rel
->r_offset
);
2571 case R_LARCH_TLS_DESC_LD
:
2572 case R_LARCH_TLS_DESC_CALL
:
2573 /* DESC -> LE/IE relaxation:
2574 ld.d $ra,$a0,%desc_ld(var) => NOP
2575 jirl $ra,$ra,%desc_call(var) => NOP
2577 bfd_put (32, abfd
, LARCH_NOP
, contents
+ rel
->r_offset
);
2580 case R_LARCH_TLS_IE_PC_HI20
:
2583 /* IE -> LE relaxation:
2584 pcalalau12i $rd,%ie_pc_hi20(var) =>
2585 lu12i.w $rd,%le_hi20(var)
2587 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
2588 bfd_put (32, abfd
, LARCH_LU12I_W
| (insn
& 0x1f),
2589 contents
+ rel
->r_offset
);
2593 case R_LARCH_TLS_IE_PC_LO12
:
2596 /* IE -> LE relaxation:
2597 ld.d $rd,$rj,%%ie_pc_lo12 =>
2598 ori $rd,$rj,le_lo12(var)
2600 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
2601 bfd_put (32, abfd
, LARCH_ORI
| (insn
& 0x3ff),
2602 contents
+ rel
->r_offset
);
2612 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
2613 bfd
*input_bfd
, asection
*input_section
,
2614 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
2615 Elf_Internal_Sym
*local_syms
,
2616 asection
**local_sections
)
2618 Elf_Internal_Rela
*rel
;
2619 Elf_Internal_Rela
*relend
;
2621 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
2622 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
2623 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2624 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
2625 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
2626 bool is_pic
= bfd_link_pic (info
);
2627 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
2628 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
2629 asection
*got
= htab
->elf
.sgot
;
2631 relend
= relocs
+ input_section
->reloc_count
;
2632 for (rel
= relocs
; rel
< relend
; rel
++)
2634 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
2635 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2636 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
2637 reloc_howto_type
*howto
= NULL
;
2638 asection
*sec
= NULL
;
2639 Elf_Internal_Sym
*sym
= NULL
;
2640 struct elf_link_hash_entry
*h
= NULL
;
2642 bfd_reloc_status_type r
= bfd_reloc_ok
;
2643 bool is_ie
, is_desc
, is_undefweak
, unresolved_reloc
, defined_local
;
2644 unsigned int relaxed_r_type
;
2645 bool resolved_local
, resolved_dynly
, resolved_to_const
;
2647 bfd_vma relocation
, off
, ie_off
, desc_off
;
2650 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
2651 if (howto
== NULL
|| r_type
== R_LARCH_GNU_VTINHERIT
2652 || r_type
== R_LARCH_GNU_VTENTRY
)
2655 /* This is a final link. */
2656 if (r_symndx
< symtab_hdr
->sh_info
)
2658 is_undefweak
= false;
2659 unresolved_reloc
= false;
2660 sym
= local_syms
+ r_symndx
;
2661 sec
= local_sections
[r_symndx
];
2662 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
2664 /* Relocate against local STT_GNU_IFUNC symbol. */
2665 if (!bfd_link_relocatable (info
)
2666 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2668 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
2673 /* Set STT_GNU_IFUNC symbol value. */
2674 h
->root
.u
.def
.value
= sym
->st_value
;
2675 h
->root
.u
.def
.section
= sec
;
2677 defined_local
= true;
2678 resolved_local
= true;
2679 resolved_dynly
= false;
2680 resolved_to_const
= false;
2682 /* Calc in funtion elf_link_input_bfd,
2683 * if #define elf_backend_rela_normal to 1. */
2684 if (bfd_link_relocatable (info
)
2685 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2690 bool warned
, ignored
;
2692 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2693 r_symndx
, symtab_hdr
, sym_hashes
,
2695 unresolved_reloc
, warned
, ignored
);
2696 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2698 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2699 symbol. And 'dynamic_undefined_weak' specify what to do when
2700 meeting undefweak. */
2702 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
2704 defined_local
= false;
2705 resolved_local
= false;
2706 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
2707 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
2708 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
2712 /* Symbol undefined offen means failed already. I don't know why
2713 'warned' here but I guess it want to continue relocating as if
2714 no error occures to find other errors as more as possible. */
2716 /* To avoid generating warning messages about truncated
2717 relocations, set the relocation's address to be the same as
2718 the start of this section. */
2719 relocation
= (input_section
->output_section
2720 ? input_section
->output_section
->vma
2723 defined_local
= relocation
!= 0;
2724 resolved_local
= defined_local
;
2725 resolved_to_const
= !resolved_local
;
2726 resolved_dynly
= false;
2730 defined_local
= !unresolved_reloc
&& !ignored
;
2732 defined_local
&& SYMBOL_REFERENCES_LOCAL (info
, h
);
2733 resolved_dynly
= !resolved_local
;
2734 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
2738 name
= loongarch_sym_name (input_bfd
, h
, sym
);
2740 if (sec
!= NULL
&& discarded_section (sec
))
2741 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
2742 1, relend
, howto
, 0, contents
);
2744 if (bfd_link_relocatable (info
))
2747 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2748 from removed linkonce sections, or sections discarded by a linker
2749 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2750 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
2752 defined_local
= false;
2753 resolved_local
= false;
2754 resolved_dynly
= false;
2755 resolved_to_const
= true;
2758 /* The ifunc reference generate plt. */
2759 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
2761 defined_local
= true;
2762 resolved_local
= true;
2763 resolved_dynly
= false;
2764 resolved_to_const
= false;
2765 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2768 unresolved_reloc
= resolved_dynly
;
2770 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
2772 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2774 BFD_ASSERT (!resolved_local
|| defined_local
);
2776 relaxed_r_type
= loongarch_tls_transition (info
, r_type
, h
, input_bfd
, r_symndx
);
2777 if (relaxed_r_type
!= r_type
)
2779 howto
= loongarch_elf_rtype_to_howto (input_bfd
, relaxed_r_type
);
2780 BFD_ASSERT (howto
!= NULL
);
2782 if (loongarch_tls_relax (input_bfd
, input_section
, rel
, r_type
, h
, info
))
2783 r_type
= relaxed_r_type
;
2790 case R_LARCH_MARK_PCREL
:
2791 case R_LARCH_MARK_LA
:
2793 r
= bfd_reloc_continue
;
2794 unresolved_reloc
= false;
2799 if (resolved_dynly
|| (is_pic
&& resolved_local
))
2801 Elf_Internal_Rela outrel
;
2803 /* When generating a shared object, these relocations are copied
2804 into the output file to be resolved at run time. */
2806 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2810 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2811 && (input_section
->flags
& SEC_ALLOC
));
2813 outrel
.r_offset
+= sec_addr (input_section
);
2815 /* A pointer point to a ifunc symbol. */
2816 if (h
&& h
->type
== STT_GNU_IFUNC
)
2818 if (h
->dynindx
== -1)
2820 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2821 outrel
.r_addend
= (h
->root
.u
.def
.value
2822 + h
->root
.u
.def
.section
->output_section
->vma
2823 + h
->root
.u
.def
.section
->output_offset
);
2827 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2828 outrel
.r_addend
= 0;
2831 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
2834 if (htab
->elf
.splt
!= NULL
)
2835 sreloc
= htab
->elf
.srelgot
;
2837 sreloc
= htab
->elf
.irelplt
;
2842 if (bfd_link_pic (info
))
2843 sreloc
= htab
->elf
.irelifunc
;
2844 else if (htab
->elf
.splt
!= NULL
)
2845 sreloc
= htab
->elf
.srelgot
;
2847 sreloc
= htab
->elf
.irelplt
;
2850 else if (resolved_dynly
)
2852 if (h
->dynindx
== -1)
2854 if (h
->root
.type
== bfd_link_hash_undefined
)
2855 (*info
->callbacks
->undefined_symbol
)
2856 (info
, name
, input_bfd
, input_section
,
2857 rel
->r_offset
, true);
2859 outrel
.r_info
= ELFNN_R_INFO (0, r_type
);
2862 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2864 outrel
.r_addend
= rel
->r_addend
;
2868 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2869 outrel
.r_addend
= relocation
+ rel
->r_addend
;
2872 /* No alloc space of func allocate_dynrelocs. */
2873 if (unresolved_reloc
2874 && !(h
&& (h
->is_weakalias
|| !h
->dyn_relocs
)))
2875 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2878 relocation
+= rel
->r_addend
;
2888 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2889 contents
+ rel
->r_offset
);
2890 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2901 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2902 contents
+ rel
->r_offset
);
2903 relocation
= old_value
- relocation
- rel
->r_addend
;
2907 case R_LARCH_ADD_ULEB128
:
2908 case R_LARCH_SUB_ULEB128
:
2910 /* Get the value and length of the uleb128 data. */
2911 unsigned int len
= 0;
2912 bfd_vma old_value
= _bfd_read_unsigned_leb128 (input_bfd
,
2913 contents
+ rel
->r_offset
, &len
);
2915 if (R_LARCH_ADD_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2916 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2917 else if (R_LARCH_SUB_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2918 relocation
= old_value
- relocation
- rel
->r_addend
;
2920 bfd_vma mask
= (1 << (7 * len
)) - 1;
2925 case R_LARCH_TLS_DTPREL32
:
2926 case R_LARCH_TLS_DTPREL64
:
2929 Elf_Internal_Rela outrel
;
2931 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2934 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2935 && (input_section
->flags
& SEC_ALLOC
));
2936 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2937 outrel
.r_offset
+= sec_addr (input_section
);
2938 outrel
.r_addend
= rel
->r_addend
;
2939 if (unresolved_reloc
)
2940 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2944 if (resolved_to_const
)
2945 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
2947 bfd_reloc_notsupported
,
2952 if (!elf_hash_table (info
)->tls_sec
)
2954 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2955 input_section
, rel
, howto
, bfd_reloc_notsupported
,
2956 is_undefweak
, name
, "TLS section not be created");
2959 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2963 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2964 input_section
, rel
, howto
, bfd_reloc_undefined
,
2966 "TLS LE just can be resolved local only.");
2971 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2974 if (!elf_hash_table (info
)->tls_sec
)
2975 fatal
= (loongarch_reloc_is_fatal
2976 (info
, input_bfd
, input_section
, rel
, howto
,
2977 bfd_reloc_notsupported
, is_undefweak
, name
,
2978 "TLS section not be created"));
2980 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2983 fatal
= (loongarch_reloc_is_fatal
2984 (info
, input_bfd
, input_section
, rel
, howto
,
2985 bfd_reloc_undefined
, is_undefweak
, name
,
2986 "TLS LE just can be resolved local only."));
2989 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2993 fatal
= (loongarch_reloc_is_fatal
2994 (info
, input_bfd
, input_section
, rel
, howto
,
2995 bfd_reloc_dangerous
, is_undefweak
, name
,
2996 "Someone require us to resolve undefweak "
2997 "symbol dynamically. \n"
2998 "But this reloc can't be done. "
2999 "I think I can't throw error "
3001 "so I resolved it to 0. "
3002 "I suggest to re-compile with '-fpic'."));
3005 unresolved_reloc
= false;
3009 if (resolved_to_const
)
3011 relocation
+= rel
->r_addend
;
3017 fatal
= (loongarch_reloc_is_fatal
3018 (info
, input_bfd
, input_section
, rel
, howto
,
3019 bfd_reloc_notsupported
, is_undefweak
, name
,
3020 "Under PIC we don't know load address. Re-compile "
3027 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
3029 fatal
= (loongarch_reloc_is_fatal
3030 (info
, input_bfd
, input_section
, rel
, howto
,
3031 bfd_reloc_undefined
, is_undefweak
, name
,
3032 "Can't be resolved dynamically. Try to re-compile "
3037 if (rel
->r_addend
!= 0)
3039 fatal
= (loongarch_reloc_is_fatal
3040 (info
, input_bfd
, input_section
, rel
, howto
,
3041 bfd_reloc_notsupported
, is_undefweak
, name
,
3042 "Shouldn't be with r_addend."));
3046 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3047 unresolved_reloc
= false;
3053 relocation
+= rel
->r_addend
;
3059 case R_LARCH_SOP_PUSH_PCREL
:
3060 case R_LARCH_SOP_PUSH_PLT_PCREL
:
3061 unresolved_reloc
= false;
3069 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3072 fatal
= (loongarch_reloc_is_fatal
3073 (info
, input_bfd
, input_section
, rel
, howto
,
3074 bfd_reloc_dangerous
, is_undefweak
, name
,
3075 "Undefweak need to be resolved dynamically, "
3076 "but PLT stub doesn't represent."));
3081 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
3083 fatal
= (loongarch_reloc_is_fatal
3084 (info
, input_bfd
, input_section
, rel
, howto
,
3085 bfd_reloc_undefined
, is_undefweak
, name
,
3086 "PLT stub does not represent and "
3087 "symbol not defined."));
3093 else /* if (resolved_dynly) */
3095 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
3096 fatal
= (loongarch_reloc_is_fatal
3097 (info
, input_bfd
, input_section
, rel
, howto
,
3098 bfd_reloc_dangerous
, is_undefweak
, name
,
3099 "Internal: PLT stub doesn't represent. "
3100 "Resolve it with pcrel"));
3107 if ((i
& 1) == 0 && defined_local
)
3110 relocation
+= rel
->r_addend
;
3114 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
3116 if (rel
->r_addend
!= 0)
3118 fatal
= (loongarch_reloc_is_fatal
3119 (info
, input_bfd
, input_section
, rel
, howto
,
3120 bfd_reloc_notsupported
, is_undefweak
, name
,
3121 "PLT shouldn't be with r_addend."));
3124 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3130 case R_LARCH_SOP_PUSH_GPREL
:
3131 unresolved_reloc
= false;
3133 if (rel
->r_addend
!= 0)
3135 fatal
= (loongarch_reloc_is_fatal
3136 (info
, input_bfd
, input_section
, rel
, howto
,
3137 bfd_reloc_notsupported
, is_undefweak
, name
,
3138 "Shouldn't be with r_addend."));
3144 off
= h
->got
.offset
& (~1);
3146 if (h
->got
.offset
== MINUS_ONE
&& h
->type
!= STT_GNU_IFUNC
)
3148 fatal
= (loongarch_reloc_is_fatal
3149 (info
, input_bfd
, input_section
, rel
, howto
,
3150 bfd_reloc_notsupported
, is_undefweak
, name
,
3151 "Internal: GOT entry doesn't represent."));
3155 /* Hidden symbol not has .got entry, only .got.plt entry
3156 so gprel is (plt - got). */
3157 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3159 if (h
->plt
.offset
== (bfd_vma
) -1)
3164 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3165 off
= plt_index
* GOT_ENTRY_SIZE
;
3167 if (htab
->elf
.splt
!= NULL
)
3169 /* Section .plt header is 2 times of plt entry. */
3170 off
= sec_addr (htab
->elf
.sgotplt
) + off
3171 - sec_addr (htab
->elf
.sgot
);
3175 /* Section iplt not has plt header. */
3176 off
= sec_addr (htab
->elf
.igotplt
) + off
3177 - sec_addr (htab
->elf
.sgot
);
3181 if ((h
->got
.offset
& 1) == 0)
3183 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3184 bfd_link_pic (info
), h
)
3185 && ((bfd_link_pic (info
)
3186 && SYMBOL_REFERENCES_LOCAL (info
, h
))))
3188 /* This is actually a static link, or it is a
3189 -Bsymbolic link and the symbol is defined
3190 locally, or the symbol was forced to be local
3191 because of a version file. We must initialize
3192 this entry in the global offset table. Since the
3193 offset must always be a multiple of the word size,
3194 we use the least significant bit to record whether
3195 we have initialized it already.
3197 When doing a dynamic link, we create a rela.got
3198 relocation entry to initialize the value. This
3199 is done in the finish_dynamic_symbol routine. */
3203 fatal
= (loongarch_reloc_is_fatal
3204 (info
, input_bfd
, input_section
, rel
, howto
,
3205 bfd_reloc_dangerous
, is_undefweak
, name
,
3206 "Internal: here shouldn't dynamic."));
3209 if (!(defined_local
|| resolved_to_const
))
3211 fatal
= (loongarch_reloc_is_fatal
3212 (info
, input_bfd
, input_section
, rel
, howto
,
3213 bfd_reloc_undefined
, is_undefweak
, name
,
3219 Elf_Internal_Rela outrel
;
3220 /* We need to generate a R_LARCH_RELATIVE reloc
3221 for the dynamic linker. */
3222 s
= htab
->elf
.srelgot
;
3225 fatal
= loongarch_reloc_is_fatal
3227 input_section
, rel
, howto
,
3228 bfd_reloc_notsupported
, is_undefweak
, name
,
3229 "Internal: '.rel.got' not represent");
3233 outrel
.r_offset
= sec_addr (got
) + off
;
3234 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3235 outrel
.r_addend
= relocation
; /* Link-time addr. */
3236 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3238 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3244 if (!local_got_offsets
)
3246 fatal
= (loongarch_reloc_is_fatal
3247 (info
, input_bfd
, input_section
, rel
, howto
,
3248 bfd_reloc_notsupported
, is_undefweak
, name
,
3249 "Internal: local got offsets not reporesent."));
3253 off
= local_got_offsets
[r_symndx
] & (~1);
3255 if (local_got_offsets
[r_symndx
] == MINUS_ONE
)
3257 fatal
= (loongarch_reloc_is_fatal
3258 (info
, input_bfd
, input_section
, rel
, howto
,
3259 bfd_reloc_notsupported
, is_undefweak
, name
,
3260 "Internal: GOT entry doesn't represent."));
3264 /* The offset must always be a multiple of the word size.
3265 So, we can use the least significant bit to record
3266 whether we have already processed this entry. */
3267 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3272 Elf_Internal_Rela outrel
;
3273 /* We need to generate a R_LARCH_RELATIVE reloc
3274 for the dynamic linker. */
3275 s
= htab
->elf
.srelgot
;
3278 fatal
= (loongarch_reloc_is_fatal
3279 (info
, input_bfd
, input_section
, rel
, howto
,
3280 bfd_reloc_notsupported
, is_undefweak
, name
,
3281 "Internal: '.rel.got' not represent"));
3285 outrel
.r_offset
= sec_addr (got
) + off
;
3286 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3287 outrel
.r_addend
= relocation
; /* Link-time addr. */
3288 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3291 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3292 local_got_offsets
[r_symndx
] |= 1;
3299 case R_LARCH_SOP_PUSH_TLS_GOT
:
3300 case R_LARCH_SOP_PUSH_TLS_GD
:
3302 unresolved_reloc
= false;
3303 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
3306 bfd_vma got_off
= 0;
3309 got_off
= h
->got
.offset
;
3314 got_off
= local_got_offsets
[r_symndx
];
3315 local_got_offsets
[r_symndx
] |= 1;
3318 BFD_ASSERT (got_off
!= MINUS_ONE
);
3321 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3322 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3323 ie_off
= 2 * GOT_ENTRY_SIZE
;
3325 if ((got_off
& 1) == 0)
3327 Elf_Internal_Rela rela
;
3328 asection
*srel
= htab
->elf
.srelgot
;
3329 bfd_vma tls_block_off
= 0;
3331 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3333 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3334 tls_block_off
= relocation
3335 - elf_hash_table (info
)->tls_sec
->vma
;
3338 if (tls_type
& GOT_TLS_GD
)
3340 rela
.r_offset
= sec_addr (got
) + got_off
;
3342 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3344 /* Local sym, used in exec, set module id 1. */
3345 if (bfd_link_executable (info
))
3346 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3349 rela
.r_info
= ELFNN_R_INFO (0,
3350 R_LARCH_TLS_DTPMODNN
);
3351 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3354 bfd_put_NN (output_bfd
, tls_block_off
,
3355 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3357 /* Dynamic resolved. */
3360 /* Dynamic relocate module id. */
3361 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3362 R_LARCH_TLS_DTPMODNN
);
3363 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3365 /* Dynamic relocate offset of block. */
3366 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3367 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3368 R_LARCH_TLS_DTPRELNN
);
3369 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3372 if (tls_type
& GOT_TLS_IE
)
3374 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3375 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3377 /* Local sym, used in exec, set module id 1. */
3378 if (!bfd_link_executable (info
))
3380 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3381 rela
.r_addend
= tls_block_off
;
3382 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3385 bfd_put_NN (output_bfd
, tls_block_off
,
3386 got
->contents
+ got_off
+ ie_off
);
3388 /* Dynamic resolved. */
3391 /* Dynamic relocate offset of block. */
3392 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3393 R_LARCH_TLS_TPRELNN
);
3395 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3400 relocation
= (got_off
& (~(bfd_vma
)1)) + (is_ie
? ie_off
: 0);
3404 /* New reloc types. */
3408 case R_LARCH_CALL36
:
3409 unresolved_reloc
= false;
3418 relocation
+= rel
->r_addend
;
3420 else if (resolved_dynly
)
3423 && (h
->plt
.offset
!= MINUS_ONE
3424 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3425 && rel
->r_addend
== 0);
3426 if (h
&& h
->plt
.offset
== MINUS_ONE
3427 && ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3430 relocation
+= rel
->r_addend
;
3433 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3438 case R_LARCH_ABS_HI20
:
3439 case R_LARCH_ABS_LO12
:
3440 case R_LARCH_ABS64_LO20
:
3441 case R_LARCH_ABS64_HI12
:
3442 BFD_ASSERT (!is_pic
);
3446 BFD_ASSERT (resolved_dynly
);
3450 else if (resolved_to_const
|| resolved_local
)
3452 relocation
+= rel
->r_addend
;
3454 else if (resolved_dynly
)
3456 unresolved_reloc
= false;
3457 BFD_ASSERT ((plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
)
3458 && rel
->r_addend
== 0);
3459 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3464 case R_LARCH_PCREL20_S2
:
3465 unresolved_reloc
= false;
3466 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3467 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3469 relocation
+= rel
->r_addend
;
3473 case R_LARCH_PCALA_HI20
:
3474 unresolved_reloc
= false;
3475 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3476 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3478 relocation
+= rel
->r_addend
;
3480 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3484 case R_LARCH_PCALA_LO12
:
3485 /* Not support if sym_addr in 2k page edge.
3486 pcalau12i pc_hi20 (sym_addr)
3487 ld.w/d pc_lo12 (sym_addr)
3488 ld.w/d pc_lo12 (sym_addr + x)
3490 can not calc correct address
3491 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3493 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3494 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3496 relocation
+= rel
->r_addend
;
3498 /* For 2G jump, generate pcalau12i, jirl. */
3499 /* If use jirl, turns to R_LARCH_B16. */
3500 uint32_t insn
= bfd_get (32, input_bfd
, contents
+ rel
->r_offset
);
3501 if ((insn
& 0x4c000000) == 0x4c000000)
3503 relocation
&= 0xfff;
3504 /* Signed extend. */
3505 relocation
= (relocation
^ 0x800) - 0x800;
3507 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_B16
);
3508 howto
= loongarch_elf_rtype_to_howto (input_bfd
, R_LARCH_B16
);
3512 case R_LARCH_PCALA64_LO20
:
3513 case R_LARCH_PCALA64_HI12
:
3514 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3515 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3517 relocation
+= rel
->r_addend
;
3519 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3523 case R_LARCH_GOT_PC_HI20
:
3524 case R_LARCH_GOT_HI20
:
3525 /* Calc got offset. */
3527 unresolved_reloc
= false;
3528 BFD_ASSERT (rel
->r_addend
== 0);
3530 bfd_vma got_off
= 0;
3533 /* GOT ref or ifunc. */
3534 BFD_ASSERT (h
->got
.offset
!= MINUS_ONE
3535 || h
->type
== STT_GNU_IFUNC
);
3537 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3538 /* Hidden symbol not has got entry,
3539 * only got.plt entry so it is (plt - got). */
3540 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3543 if (htab
->elf
.splt
!= NULL
)
3545 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
)
3547 got_off
= sec_addr (htab
->elf
.sgotplt
)
3548 + GOTPLT_HEADER_SIZE
3549 + (idx
* GOT_ENTRY_SIZE
)
3550 - sec_addr (htab
->elf
.sgot
);
3554 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3555 got_off
= sec_addr (htab
->elf
.sgotplt
)
3556 + (idx
* GOT_ENTRY_SIZE
)
3557 - sec_addr (htab
->elf
.sgot
);
3561 if ((h
->got
.offset
& 1) == 0)
3563 /* We need to generate a R_LARCH_RELATIVE reloc once
3564 * in loongarch_elf_finish_dynamic_symbol or now,
3565 * call finish_dyn && nopic
3566 * or !call finish_dyn && pic. */
3567 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3568 bfd_link_pic (info
),
3570 && bfd_link_pic (info
)
3571 && SYMBOL_REFERENCES_LOCAL (info
, h
))
3573 Elf_Internal_Rela rela
;
3574 rela
.r_offset
= sec_addr (got
) + got_off
;
3575 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3576 rela
.r_addend
= relocation
;
3577 loongarch_elf_append_rela (output_bfd
,
3578 htab
->elf
.srelgot
, &rela
);
3581 bfd_put_NN (output_bfd
, relocation
,
3582 got
->contents
+ got_off
);
3587 BFD_ASSERT (local_got_offsets
3588 && local_got_offsets
[r_symndx
] != MINUS_ONE
);
3590 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3591 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3593 if (bfd_link_pic (info
))
3595 Elf_Internal_Rela rela
;
3596 rela
.r_offset
= sec_addr (got
) + got_off
;
3597 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3598 rela
.r_addend
= relocation
;
3599 loongarch_elf_append_rela (output_bfd
,
3600 htab
->elf
.srelgot
, &rela
);
3602 local_got_offsets
[r_symndx
] |= 1;
3604 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ got_off
);
3607 relocation
= got_off
+ sec_addr (got
);
3610 if (r_type
== R_LARCH_GOT_PC_HI20
)
3611 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3615 case R_LARCH_GOT_PC_LO12
:
3616 case R_LARCH_GOT64_PC_LO20
:
3617 case R_LARCH_GOT64_PC_HI12
:
3618 case R_LARCH_GOT_LO12
:
3619 case R_LARCH_GOT64_LO20
:
3620 case R_LARCH_GOT64_HI12
:
3622 unresolved_reloc
= false;
3625 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3627 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3629 if (h
&& h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3632 if (htab
->elf
.splt
!= NULL
)
3633 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
3635 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3637 got_off
= sec_addr (htab
->elf
.sgotplt
)
3638 + GOTPLT_HEADER_SIZE
3639 + (idx
* GOT_ENTRY_SIZE
)
3640 - sec_addr (htab
->elf
.sgot
);
3643 relocation
= got_off
+ sec_addr (got
);
3646 if (r_type
== R_LARCH_GOT64_PC_HI12
3647 || r_type
== R_LARCH_GOT64_PC_LO20
)
3648 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3652 case R_LARCH_TLS_LE_HI20
:
3653 case R_LARCH_TLS_LE_LO12
:
3654 case R_LARCH_TLS_LE64_LO20
:
3655 case R_LARCH_TLS_LE64_HI12
:
3656 BFD_ASSERT (resolved_local
&& elf_hash_table (info
)->tls_sec
);
3658 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
3661 /* TLS IE LD/GD process separately is troublesome.
3662 When a symbol is both ie and LD/GD, h->got.off |= 1
3663 make only one type be relocated. We must use
3664 h->got.offset |= 1 and h->got.offset |= 2
3665 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3666 (IE LD/GD and reusable GOT reloc) must change to
3667 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3669 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3671 case R_LARCH_TLS_IE_PC_HI20
:
3672 case R_LARCH_TLS_IE_HI20
:
3673 case R_LARCH_TLS_LD_PC_HI20
:
3674 case R_LARCH_TLS_LD_HI20
:
3675 case R_LARCH_TLS_GD_PC_HI20
:
3676 case R_LARCH_TLS_GD_HI20
:
3677 case R_LARCH_TLS_DESC_PC_HI20
:
3678 case R_LARCH_TLS_DESC_HI20
:
3679 case R_LARCH_TLS_LD_PCREL20_S2
:
3680 case R_LARCH_TLS_GD_PCREL20_S2
:
3681 case R_LARCH_TLS_DESC_PCREL20_S2
:
3682 BFD_ASSERT (rel
->r_addend
== 0);
3683 unresolved_reloc
= false;
3685 if (r_type
== R_LARCH_TLS_IE_PC_HI20
3686 || r_type
== R_LARCH_TLS_IE_HI20
)
3689 if (r_type
== R_LARCH_TLS_DESC_PC_HI20
3690 || r_type
== R_LARCH_TLS_DESC_HI20
3691 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
3694 bfd_vma got_off
= 0;
3697 got_off
= h
->got
.offset
;
3702 got_off
= local_got_offsets
[r_symndx
];
3703 local_got_offsets
[r_symndx
] |= 1;
3706 BFD_ASSERT (got_off
!= MINUS_ONE
);
3708 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3710 /* If a tls variable is accessed in multiple ways, GD uses
3711 the first two slots of GOT, desc follows with two slots,
3712 and IE uses one slot at the end. */
3714 if (GOT_TLS_GD_BOTH_P (tls_type
))
3715 desc_off
= 2 * GOT_ENTRY_SIZE
;
3718 if (GOT_TLS_GD_BOTH_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3719 ie_off
= 4 * GOT_ENTRY_SIZE
;
3720 else if (GOT_TLS_GD_ANY_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3721 ie_off
= 2 * GOT_ENTRY_SIZE
;
3723 if ((got_off
& 1) == 0)
3725 Elf_Internal_Rela rela
;
3726 asection
*relgot
= htab
->elf
.srelgot
;
3727 bfd_vma tls_block_off
= 0;
3729 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3731 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3732 tls_block_off
= relocation
3733 - elf_hash_table (info
)->tls_sec
->vma
;
3736 if (tls_type
& GOT_TLS_GD
)
3738 rela
.r_offset
= sec_addr (got
) + got_off
;
3740 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3742 /* Local sym, used in exec, set module id 1. */
3743 if (bfd_link_executable (info
))
3744 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3747 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN
);
3748 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3751 bfd_put_NN (output_bfd
, tls_block_off
,
3752 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3754 /* Dynamic resolved. */
3757 /* Dynamic relocate module id. */
3758 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3759 R_LARCH_TLS_DTPMODNN
);
3760 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3762 /* Dynamic relocate offset of block. */
3763 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3764 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3765 R_LARCH_TLS_DTPRELNN
);
3766 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3769 if (tls_type
& GOT_TLS_GDESC
)
3771 /* Unless it is a static link, DESC always emits a
3772 dynamic relocation. */
3773 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
3774 rela
.r_offset
= sec_addr (got
) + got_off
+ desc_off
;
3777 rela
.r_addend
= relocation
- elf_hash_table (info
)->tls_sec
->vma
;
3779 rela
.r_info
= ELFNN_R_INFO (indx
, R_LARCH_TLS_DESCNN
);
3780 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3781 bfd_put_NN (output_bfd
, 0,
3782 got
->contents
+ got_off
+ desc_off
);
3784 if (tls_type
& GOT_TLS_IE
)
3786 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3787 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3789 /* Local sym, used in exec, set module id 1. */
3790 if (!bfd_link_executable (info
))
3792 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3793 rela
.r_addend
= tls_block_off
;
3794 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3797 bfd_put_NN (output_bfd
, tls_block_off
,
3798 got
->contents
+ got_off
+ ie_off
);
3800 /* Dynamic resolved. */
3803 /* Dynamic relocate offset of block. */
3804 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3805 R_LARCH_TLS_TPRELNN
);
3807 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3811 relocation
= (got_off
& (~(bfd_vma
)1)) + sec_addr (got
);
3813 relocation
+= desc_off
;
3815 relocation
+= ie_off
;
3817 if (r_type
== R_LARCH_TLS_LD_PC_HI20
3818 || r_type
== R_LARCH_TLS_GD_PC_HI20
3819 || r_type
== R_LARCH_TLS_IE_PC_HI20
3820 || r_type
== R_LARCH_TLS_DESC_PC_HI20
)
3821 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3822 else if (r_type
== R_LARCH_TLS_LD_PCREL20_S2
3823 || r_type
== R_LARCH_TLS_GD_PCREL20_S2
3824 || r_type
== R_LARCH_TLS_DESC_PCREL20_S2
)
3826 /* else {} ABS relocations. */
3829 case R_LARCH_TLS_DESC_PC_LO12
:
3830 case R_LARCH_TLS_DESC64_PC_LO20
:
3831 case R_LARCH_TLS_DESC64_PC_HI12
:
3832 case R_LARCH_TLS_DESC_LO12
:
3833 case R_LARCH_TLS_DESC64_LO20
:
3834 case R_LARCH_TLS_DESC64_HI12
:
3836 unresolved_reloc
= false;
3839 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
3841 relocation
= sec_addr (got
)
3842 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
3844 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3845 /* Use both TLS_GD and TLS_DESC. */
3846 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_GDESC
))
3847 relocation
+= 2 * GOT_ENTRY_SIZE
;
3850 if (r_type
== R_LARCH_TLS_DESC64_PC_LO20
3851 || r_type
== R_LARCH_TLS_DESC64_PC_HI12
)
3852 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3856 case R_LARCH_TLS_DESC_LD
:
3857 case R_LARCH_TLS_DESC_CALL
:
3858 unresolved_reloc
= false;
3861 case R_LARCH_TLS_IE_PC_LO12
:
3862 case R_LARCH_TLS_IE64_PC_LO20
:
3863 case R_LARCH_TLS_IE64_PC_HI12
:
3864 case R_LARCH_TLS_IE_LO12
:
3865 case R_LARCH_TLS_IE64_LO20
:
3866 case R_LARCH_TLS_IE64_HI12
:
3867 unresolved_reloc
= false;
3870 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)1));
3872 relocation
= sec_addr (got
)
3873 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)1));
3875 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3876 /* Use TLS_GD TLS_DESC and TLS_IE. */
3877 if (GOT_TLS_GD_BOTH_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3878 relocation
+= 4 * GOT_ENTRY_SIZE
;
3879 /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
3880 else if (GOT_TLS_GD_ANY_P (tls_type
) && (tls_type
& GOT_TLS_IE
))
3881 relocation
+= 2 * GOT_ENTRY_SIZE
;
3883 if (r_type
== R_LARCH_TLS_IE64_PC_LO20
3884 || r_type
== R_LARCH_TLS_IE64_PC_HI12
)
3885 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3891 r
= bfd_reloc_continue
;
3892 unresolved_reloc
= false;
3904 /* 'unresolved_reloc' means we haven't done it yet.
3905 We need help of dynamic linker to fix this memory location up. */
3906 if (!unresolved_reloc
)
3909 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
3910 rel
->r_offset
) == MINUS_ONE
)
3911 /* WHY? May because it's invalid so skip checking.
3912 But why dynamic reloc a invalid section? */
3915 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
3917 fatal
= (loongarch_reloc_is_fatal
3918 (info
, input_bfd
, input_section
, rel
, howto
,
3919 bfd_reloc_dangerous
, is_undefweak
, name
,
3920 "Seems dynamic linker not process "
3921 "sections 'SEC_DEBUGGING'."));
3926 if ((info
->flags
& DF_TEXTREL
) == 0)
3927 if (input_section
->output_section
->flags
& SEC_READONLY
)
3928 info
->flags
|= DF_TEXTREL
;
3935 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
3936 rel
->r_offset
, sym
, h
, rel
->r_addend
);
3938 if (r
!= bfd_reloc_continue
)
3939 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
3940 input_bfd
, contents
);
3944 case bfd_reloc_dangerous
:
3945 case bfd_reloc_continue
:
3949 case bfd_reloc_overflow
:
3950 /* Overflow value can't be filled in. */
3951 loongarch_dump_reloc_record (info
->callbacks
->info
);
3952 info
->callbacks
->reloc_overflow
3953 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
3954 input_bfd
, input_section
, rel
->r_offset
);
3957 case bfd_reloc_outofrange
:
3958 /* Stack state incorrect. */
3959 loongarch_dump_reloc_record (info
->callbacks
->info
);
3960 info
->callbacks
->info
3961 ("%X%H: Internal stack state is incorrect.\n"
3962 "Want to push to full stack or pop from empty stack?\n",
3963 input_bfd
, input_section
, rel
->r_offset
);
3966 case bfd_reloc_notsupported
:
3967 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
3968 input_section
, rel
->r_offset
);
3972 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
3973 input_section
, rel
->r_offset
);
3984 loongarch_relax_delete_bytes (bfd
*abfd
,
3988 struct bfd_link_info
*link_info
)
3990 unsigned int i
, symcount
;
3991 bfd_vma toaddr
= sec
->size
;
3992 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (abfd
);
3993 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
3994 unsigned int sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
3995 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
3996 bfd_byte
*contents
= data
->this_hdr
.contents
;
3998 /* Actually delete the bytes. */
4000 memmove (contents
+ addr
, contents
+ addr
+ count
, toaddr
- addr
- count
);
4002 /* Adjust the location of all of the relocs. Note that we need not
4003 adjust the addends, since all PC-relative references must be against
4004 symbols, which we will adjust below. */
4005 for (i
= 0; i
< sec
->reloc_count
; i
++)
4006 if (data
->relocs
[i
].r_offset
> addr
&& data
->relocs
[i
].r_offset
< toaddr
)
4007 data
->relocs
[i
].r_offset
-= count
;
4009 /* Adjust the local symbols defined in this section. */
4010 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
4012 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
+ i
;
4013 if (sym
->st_shndx
== sec_shndx
)
4015 /* If the symbol is in the range of memory we just moved, we
4016 have to adjust its value. */
4017 if (sym
->st_value
> addr
&& sym
->st_value
<= toaddr
)
4018 sym
->st_value
-= count
;
4020 /* If the symbol *spans* the bytes we just deleted (i.e. its
4021 *end* is in the moved bytes but its *start* isn't), then we
4022 must adjust its size.
4024 This test needs to use the original value of st_value, otherwise
4025 we might accidentally decrease size when deleting bytes right
4026 before the symbol. But since deleted relocs can't span across
4027 symbols, we can't have both a st_value and a st_size decrease,
4028 so it is simpler to just use an else. */
4029 else if (sym
->st_value
<= addr
4030 && sym
->st_value
+ sym
->st_size
> addr
4031 && sym
->st_value
+ sym
->st_size
<= toaddr
)
4032 sym
->st_size
-= count
;
4036 /* Now adjust the global symbols defined in this section. */
4037 symcount
= ((symtab_hdr
->sh_size
/ sizeof (ElfNN_External_Sym
))
4038 - symtab_hdr
->sh_info
);
4040 for (i
= 0; i
< symcount
; i
++)
4042 struct elf_link_hash_entry
*sym_hash
= sym_hashes
[i
];
4044 /* The '--wrap SYMBOL' option is causing a pain when the object file,
4045 containing the definition of __wrap_SYMBOL, includes a direct
4046 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4047 the same symbol (which is __wrap_SYMBOL), but still exist as two
4048 different symbols in 'sym_hashes', we don't want to adjust
4049 the global symbol __wrap_SYMBOL twice.
4051 The same problem occurs with symbols that are versioned_hidden, as
4052 foo becomes an alias for foo@BAR, and hence they need the same
4054 if (link_info
->wrap_hash
!= NULL
4055 || sym_hash
->versioned
!= unversioned
)
4057 struct elf_link_hash_entry
**cur_sym_hashes
;
4059 /* Loop only over the symbols which have already been checked. */
4060 for (cur_sym_hashes
= sym_hashes
; cur_sym_hashes
< &sym_hashes
[i
];
4063 /* If the current symbol is identical to 'sym_hash', that means
4064 the symbol was already adjusted (or at least checked). */
4065 if (*cur_sym_hashes
== sym_hash
)
4068 /* Don't adjust the symbol again. */
4069 if (cur_sym_hashes
< &sym_hashes
[i
])
4073 if ((sym_hash
->root
.type
== bfd_link_hash_defined
4074 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
4075 && sym_hash
->root
.u
.def
.section
== sec
)
4077 /* As above, adjust the value if needed. */
4078 if (sym_hash
->root
.u
.def
.value
> addr
4079 && sym_hash
->root
.u
.def
.value
<= toaddr
)
4080 sym_hash
->root
.u
.def
.value
-= count
;
4082 /* As above, adjust the size if needed. */
4083 else if (sym_hash
->root
.u
.def
.value
<= addr
4084 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
4085 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
<= toaddr
)
4086 sym_hash
->size
-= count
;
4093 /* Relax pcalau12i,addi.d => pcaddi. */
4095 loongarch_relax_pcala_addi (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4096 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4097 struct bfd_link_info
*info
, bool *again
)
4099 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4100 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4101 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4102 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4103 uint32_t rd
= pca
& 0x1f;
4105 /* This section's output_offset need to subtract the bytes of instructions
4106 relaxed by the previous sections, so it needs to be updated beforehand.
4107 size_input_section already took care of updating it after relaxation,
4108 so we additionally update once here. */
4109 sec
->output_offset
= sec
->output_section
->size
;
4110 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
4112 /* If pc and symbol not in the same segment, add/sub segment alignment.
4113 FIXME: if there are multiple readonly segments? */
4114 if (!(sym_sec
->flags
& SEC_READONLY
))
4117 pc
-= info
->maxpagesize
;
4118 else if (symval
< pc
)
4119 pc
+= info
->maxpagesize
;
4122 const uint32_t addi_d
= 0x02c00000;
4123 const uint32_t pcaddi
= 0x18000000;
4125 /* Is pcalau12i + addi.d insns? */
4126 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_PCALA_LO12
)
4127 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4128 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4129 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4130 || ((add
& addi_d
) != addi_d
)
4131 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4132 || ((add
& 0x1f) != rd
)
4133 || (((add
>> 5) & 0x1f) != rd
)
4134 /* Can be relaxed to pcaddi? */
4135 || (symval
& 0x3) /* 4 bytes align. */
4136 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
4137 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
4140 /* Continue next relax trip. */
4144 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
4146 /* Adjust relocations. */
4147 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4148 R_LARCH_PCREL20_S2
);
4149 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4151 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
4156 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
4158 loongarch_relax_pcala_ld (bfd
*abfd
, asection
*sec
,
4159 Elf_Internal_Rela
*rel_hi
)
4161 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4162 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4163 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4164 uint32_t ld
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4165 uint32_t rd
= pca
& 0x1f;
4166 const uint32_t ld_d
= 0x28c00000;
4167 uint32_t addi_d
= 0x02c00000;
4169 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
)
4170 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4171 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4172 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4173 || ((ld
& 0x1f) != rd
)
4174 || (((ld
>> 5) & 0x1f) != rd
)
4175 || ((ld
& ld_d
) != ld_d
))
4178 addi_d
= addi_d
| (rd
<< 5) | rd
;
4179 bfd_put (32, abfd
, addi_d
, contents
+ rel_lo
->r_offset
);
4181 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4182 R_LARCH_PCALA_HI20
);
4183 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_lo
->r_info
),
4184 R_LARCH_PCALA_LO12
);
4188 /* Called by after_allocation to set the information of data segment
4192 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info
*info
,
4193 int *data_segment_phase
)
4195 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4196 htab
->data_segment_phase
= data_segment_phase
;
4199 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4200 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
4202 loongarch_relax_align (bfd
*abfd
, asection
*sec
,
4204 struct bfd_link_info
*link_info
,
4205 Elf_Internal_Rela
*rel
,
4208 bfd_vma addend
, max
= 0, alignment
= 1;
4210 int index
= ELFNN_R_SYM (rel
->r_info
);
4213 alignment
= 1 << (rel
->r_addend
& 0xff);
4214 max
= rel
->r_addend
>> 8;
4217 alignment
= rel
->r_addend
+ 4;
4219 addend
= alignment
- 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
4220 symval
-= addend
; /* The address of first NOP added by R_LARCH_ALIGN. */
4221 bfd_vma aligned_addr
= ((symval
- 1) & ~(alignment
- 1)) + alignment
;
4222 bfd_vma need_nop_bytes
= aligned_addr
- symval
; /* */
4224 /* Make sure there are enough NOPs to actually achieve the alignment. */
4225 if (addend
< need_nop_bytes
)
4228 (_("%pB(%pA+%#" PRIx64
"): %" PRId64
" bytes required for alignment "
4229 "to %" PRId64
"-byte boundary, but only %" PRId64
" present"),
4230 abfd
, sym_sec
, (uint64_t) rel
->r_offset
,
4231 (int64_t) need_nop_bytes
, (int64_t) alignment
, (int64_t) addend
);
4232 bfd_set_error (bfd_error_bad_value
);
4236 /* Once we've handled an R_LARCH_ALIGN in a section,
4237 we can't relax anything else in this section. */
4238 sec
->sec_flg0
= true;
4239 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4241 /* If skipping more bytes than the specified maximum,
4242 then the alignment is not done at all and delete all NOPs. */
4243 if (max
> 0 && need_nop_bytes
> max
)
4244 return loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
,
4247 /* If the number of NOPs is already correct, there's nothing to do. */
4248 if (need_nop_bytes
== addend
)
4251 /* Delete the excess NOPs. */
4252 return loongarch_relax_delete_bytes (abfd
, sec
,
4253 rel
->r_offset
+ need_nop_bytes
,
4254 addend
- need_nop_bytes
, link_info
);
4257 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
4259 loongarch_relax_tls_ld_gd_desc (bfd
*abfd
, asection
*sec
, asection
*sym_sec
,
4260 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
,
4261 struct bfd_link_info
*info
, bool *again
)
4263 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
4264 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
4265 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
4266 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
4267 uint32_t rd
= pca
& 0x1f;
4269 /* This section's output_offset need to subtract the bytes of instructions
4270 relaxed by the previous sections, so it needs to be updated beforehand.
4271 size_input_section already took care of updating it after relaxation,
4272 so we additionally update once here. */
4273 sec
->output_offset
= sec
->output_section
->size
;
4274 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
4276 /* If pc and symbol not in the same segment, add/sub segment alignment.
4277 FIXME: if there are multiple readonly segments? */
4278 if (!(sym_sec
->flags
& SEC_READONLY
))
4281 pc
-= info
->maxpagesize
;
4282 else if (symval
< pc
)
4283 pc
+= info
->maxpagesize
;
4286 const uint32_t addi_d
= 0x02c00000;
4287 const uint32_t pcaddi
= 0x18000000;
4289 /* Is pcalau12i + addi.d insns? */
4290 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
4291 && ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_TLS_DESC_PC_LO12
)
4292 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
4293 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
4294 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
4295 || ((add
& addi_d
) != addi_d
)
4296 /* Is pcalau12i $rd + addi.d $rd,$rd? */
4297 || ((add
& 0x1f) != rd
)
4298 || (((add
>> 5) & 0x1f) != rd
)
4299 /* Can be relaxed to pcaddi? */
4300 || (symval
& 0x3) /* 4 bytes align. */
4301 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
4302 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
4305 /* Continue next relax trip. */
4309 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
4311 /* Adjust relocations. */
4312 switch (ELFNN_R_TYPE (rel_hi
->r_info
))
4314 case R_LARCH_TLS_LD_PC_HI20
:
4315 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4316 R_LARCH_TLS_LD_PCREL20_S2
);
4318 case R_LARCH_TLS_GD_PC_HI20
:
4319 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4320 R_LARCH_TLS_GD_PCREL20_S2
);
4322 case R_LARCH_TLS_DESC_PC_HI20
:
4323 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
4324 R_LARCH_TLS_DESC_PCREL20_S2
);
4329 rel_lo
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4331 loongarch_relax_delete_bytes (abfd
, sec
, rel_lo
->r_offset
, 4, info
);
4337 loongarch_elf_relax_section (bfd
*abfd
, asection
*sec
,
4338 struct bfd_link_info
*info
,
4341 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4342 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
4343 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (abfd
);
4344 Elf_Internal_Rela
*relocs
;
4347 if (bfd_link_relocatable (info
)
4349 || (sec
->flags
& SEC_RELOC
) == 0
4350 || sec
->reloc_count
== 0
4351 || (info
->disable_target_specific_optimizations
4352 && info
->relax_pass
== 0)
4353 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4354 and defined in ld/ldexp.h. */
4355 || *(htab
->data_segment_phase
) == 4)
4359 relocs
= data
->relocs
;
4360 else if (!(relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
4361 info
->keep_memory
)))
4364 if (!data
->this_hdr
.contents
4365 && !bfd_malloc_and_get_section (abfd
, sec
, &data
->this_hdr
.contents
))
4368 if (symtab_hdr
->sh_info
!= 0
4369 && !symtab_hdr
->contents
4370 && !(symtab_hdr
->contents
=
4371 (unsigned char *) bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
4372 symtab_hdr
->sh_info
,
4373 0, NULL
, NULL
, NULL
)))
4376 data
->relocs
= relocs
;
4378 for (unsigned int i
= 0; i
< sec
->reloc_count
; i
++)
4383 bool local_got
= false;
4384 Elf_Internal_Rela
*rel
= relocs
+ i
;
4385 struct elf_link_hash_entry
*h
= NULL
;
4386 unsigned long r_type
= ELFNN_R_TYPE (rel
->r_info
);
4387 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4389 /* Four kind of relocations:
4390 Normal: symval is the symbol address.
4391 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4392 added by this relocation, and then adds 4 more.
4393 R_LARCH_CALL36: symval is the symbol address for local symbols,
4394 or the PLT entry address of the symbol. (Todo)
4395 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4397 if (r_symndx
< symtab_hdr
->sh_info
)
4399 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)symtab_hdr
->contents
4401 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
4404 if (R_LARCH_TLS_LD_PC_HI20
== r_type
4405 || R_LARCH_TLS_GD_PC_HI20
== r_type
4406 || R_LARCH_TLS_DESC_PC_HI20
== r_type
)
4408 if (loongarch_can_relax_tls (info
, r_type
, h
, abfd
, r_symndx
))
4412 sym_sec
= htab
->elf
.sgot
;
4413 symval
= elf_local_got_offsets (abfd
)[r_symndx
];
4414 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
4416 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
4417 && GOT_TLS_GD_BOTH_P (tls_type
))
4418 symval
+= 2 * GOT_ENTRY_SIZE
;
4421 else if (sym
->st_shndx
== SHN_UNDEF
|| R_LARCH_ALIGN
== r_type
)
4424 symval
= rel
->r_offset
;
4428 sym_sec
= elf_elfsections (abfd
)[sym
->st_shndx
]->bfd_section
;
4429 symval
= sym
->st_value
;
4431 symtype
= ELF_ST_TYPE (sym
->st_info
);
4435 r_symndx
= ELFNN_R_SYM (rel
->r_info
) - symtab_hdr
->sh_info
;
4436 h
= elf_sym_hashes (abfd
)[r_symndx
];
4438 while (h
->root
.type
== bfd_link_hash_indirect
4439 || h
->root
.type
== bfd_link_hash_warning
)
4440 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
4442 /* Disable the relaxation for ifunc. */
4443 if (h
!= NULL
&& h
->type
== STT_GNU_IFUNC
)
4446 /* The GOT entry of tls symbols must in current execute file or
4448 if (R_LARCH_TLS_LD_PC_HI20
== r_type
4449 || R_LARCH_TLS_GD_PC_HI20
== r_type
4450 || R_LARCH_TLS_DESC_PC_HI20
== r_type
)
4452 if (loongarch_can_relax_tls (info
, r_type
, h
, abfd
, r_symndx
))
4456 sym_sec
= htab
->elf
.sgot
;
4457 symval
= h
->got
.offset
;
4458 char tls_type
= _bfd_loongarch_elf_tls_type (abfd
, h
,
4460 if (R_LARCH_TLS_DESC_PC_HI20
== r_type
4461 && GOT_TLS_GD_BOTH_P (tls_type
))
4462 symval
+= 2 * GOT_ENTRY_SIZE
;
4465 else if ((h
->root
.type
== bfd_link_hash_defined
4466 || h
->root
.type
== bfd_link_hash_defweak
)
4467 && h
->root
.u
.def
.section
!= NULL
4468 && h
->root
.u
.def
.section
->output_section
!= NULL
)
4470 symval
= h
->root
.u
.def
.value
;
4471 sym_sec
= h
->root
.u
.def
.section
;
4476 if (h
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
4481 if (sym_sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
4482 && (sym_sec
->flags
& SEC_MERGE
))
4484 if (symtype
== STT_SECTION
)
4485 symval
+= rel
->r_addend
;
4487 symval
= _bfd_merged_section_offset (abfd
, &sym_sec
,
4488 elf_section_data (sym_sec
)->sec_info
,
4491 if (symtype
!= STT_SECTION
)
4492 symval
+= rel
->r_addend
;
4494 /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
4496 If r_symndx is 0, alignmeng-4 is r_addend.
4497 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
4498 else if (R_LARCH_ALIGN
== r_type
)
4500 symval
+= ((1 << (rel
->r_addend
& 0xff)) - 4);
4502 symval
+= rel
->r_addend
;
4504 symval
+= rel
->r_addend
;
4506 symval
+= sec_addr (sym_sec
);
4511 if (1 == info
->relax_pass
)
4512 loongarch_relax_align (abfd
, sec
, sym_sec
, info
, rel
, symval
);
4514 case R_LARCH_DELETE
:
4515 if (1 == info
->relax_pass
)
4517 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4518 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4521 case R_LARCH_PCALA_HI20
:
4522 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4523 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
4526 case R_LARCH_GOT_PC_HI20
:
4527 if (local_got
&& 0 == info
->relax_pass
4528 && (i
+ 4) <= sec
->reloc_count
)
4530 if (loongarch_relax_pcala_ld (abfd
, sec
, rel
))
4531 loongarch_relax_pcala_addi (abfd
, sec
, sym_sec
, rel
, symval
,
4536 case R_LARCH_TLS_LD_PC_HI20
:
4537 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4538 loongarch_relax_tls_ld_gd_desc (abfd
, sec
, sym_sec
, rel
, symval
,
4542 case R_LARCH_TLS_GD_PC_HI20
:
4543 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4544 loongarch_relax_tls_ld_gd_desc (abfd
, sec
, sym_sec
, rel
, symval
,
4548 case R_LARCH_TLS_DESC_PC_HI20
:
4549 if (0 == info
->relax_pass
&& (i
+ 4) <= sec
->reloc_count
)
4550 loongarch_relax_tls_ld_gd_desc (abfd
, sec
, sym_sec
, rel
, symval
,
4562 /* Finish up dynamic symbol handling. We set the contents of various
4563 dynamic sections here. */
4566 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
4567 struct bfd_link_info
*info
,
4568 struct elf_link_hash_entry
*h
,
4569 Elf_Internal_Sym
*sym
)
4571 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4572 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
4574 if (h
->plt
.offset
!= MINUS_ONE
)
4577 asection
*plt
, *gotplt
, *relplt
;
4578 bfd_vma got_address
;
4579 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
4581 Elf_Internal_Rela rela
;
4585 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
4586 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4587 || h
->dynindx
!= -1);
4589 plt
= htab
->elf
.splt
;
4590 gotplt
= htab
->elf
.sgotplt
;
4591 if (h
->type
== STT_GNU_IFUNC
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
4592 relplt
= htab
->elf
.srelgot
;
4594 relplt
= htab
->elf
.srelplt
;
4595 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4597 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
4599 else /* if (htab->elf.iplt) */
4601 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
4602 && SYMBOL_REFERENCES_LOCAL (info
, h
));
4604 plt
= htab
->elf
.iplt
;
4605 gotplt
= htab
->elf
.igotplt
;
4606 relplt
= htab
->elf
.irelplt
;
4607 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4608 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
4611 /* Find out where the .plt entry should go. */
4612 loc
= plt
->contents
+ h
->plt
.offset
;
4614 /* Fill in the PLT entry itself. */
4615 if (!loongarch_make_plt_entry (got_address
,
4616 sec_addr (plt
) + h
->plt
.offset
,
4620 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
4621 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
4623 /* Fill in the initial value of the got.plt entry. */
4624 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
4625 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
4627 rela
.r_offset
= got_address
;
4629 /* TRUE if this is a PLT reference to a local IFUNC. */
4630 if (PLT_LOCAL_IFUNC_P (info
, h
)
4631 && (relplt
== htab
->elf
.srelgot
4632 || relplt
== htab
->elf
.irelplt
))
4634 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
4635 rela
.r_addend
= (h
->root
.u
.def
.value
4636 + h
->root
.u
.def
.section
->output_section
->vma
4637 + h
->root
.u
.def
.section
->output_offset
);
4639 loongarch_elf_append_rela (output_bfd
, relplt
, &rela
);
4643 /* Fill in the entry in the rela.plt section. */
4644 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
4646 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
4647 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
4650 if (!h
->def_regular
)
4652 /* Mark the symbol as undefined, rather than as defined in
4653 the .plt section. Leave the value alone. */
4654 sym
->st_shndx
= SHN_UNDEF
;
4655 /* If the symbol is weak, we do need to clear the value.
4656 Otherwise, the PLT entry would provide a definition for
4657 the symbol even if the symbol wasn't defined anywhere,
4658 and so the symbol would never be NULL. */
4659 if (!h
->ref_regular_nonweak
)
4664 if (h
->got
.offset
!= MINUS_ONE
4665 /* TLS got entry have been handled in elf_relocate_section. */
4666 && !(loongarch_elf_hash_entry (h
)->tls_type
4667 & (GOT_TLS_GD
| GOT_TLS_IE
| GOT_TLS_GDESC
))
4668 /* Have allocated got entry but not allocated rela before. */
4669 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
4671 asection
*sgot
, *srela
;
4672 Elf_Internal_Rela rela
;
4673 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
)1;
4675 /* This symbol has an entry in the GOT. Set it up. */
4676 sgot
= htab
->elf
.sgot
;
4677 srela
= htab
->elf
.srelgot
;
4678 BFD_ASSERT (sgot
&& srela
);
4680 rela
.r_offset
= sec_addr (sgot
) + off
;
4683 && h
->type
== STT_GNU_IFUNC
)
4685 if(h
->plt
.offset
== MINUS_ONE
)
4687 if (htab
->elf
.splt
== NULL
)
4688 srela
= htab
->elf
.irelplt
;
4690 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
4692 asection
*sec
= h
->root
.u
.def
.section
;
4693 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
4694 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
4695 + sec
->output_offset
;
4696 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
4700 BFD_ASSERT (h
->dynindx
!= -1);
4701 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4703 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
4706 else if(bfd_link_pic (info
))
4708 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4710 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
4715 /* For non-shared object, we can't use .got.plt, which
4716 contains the real function address if we need pointer
4717 equality. We load the GOT entry with the PLT entry. */
4718 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
4719 bfd_put_NN (output_bfd
,
4720 (plt
->output_section
->vma
4721 + plt
->output_offset
4723 sgot
->contents
+ off
);
4727 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
4729 asection
*sec
= h
->root
.u
.def
.section
;
4730 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4731 rela
.r_addend
= (h
->root
.u
.def
.value
+ sec
->output_section
->vma
4732 + sec
->output_offset
);
4736 BFD_ASSERT (h
->dynindx
!= -1);
4737 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4741 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
4744 /* Mark some specially defined symbols as absolute. */
4745 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
4746 sym
->st_shndx
= SHN_ABS
;
4751 /* Finish up the dynamic sections. */
4754 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
4757 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4758 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
4759 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
4760 bfd_byte
*dyncon
, *dynconend
;
4762 dynconend
= sdyn
->contents
+ sdyn
->size
;
4763 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
4765 Elf_Internal_Dyn dyn
;
4769 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
4774 s
= htab
->elf
.sgotplt
;
4775 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
4778 s
= htab
->elf
.srelplt
;
4779 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
4782 s
= htab
->elf
.srelplt
;
4783 dyn
.d_un
.d_val
= s
->size
;
4786 if ((info
->flags
& DF_TEXTREL
) == 0)
4790 if ((info
->flags
& DF_TEXTREL
) == 0)
4791 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
4795 skipped_size
+= dynsize
;
4797 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
4799 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
4800 memset (dyncon
- skipped_size
, 0, skipped_size
);
4804 /* Finish up local dynamic symbol handling. We set the contents of
4805 various dynamic sections here. */
4808 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
4810 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
4811 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
4813 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
4816 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4817 this function is called before elf_link_sort_relocs.
4818 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4819 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
4822 elf_loongarch_output_arch_local_syms
4823 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4824 struct bfd_link_info
*info
,
4825 void *flaginfo ATTRIBUTE_UNUSED
,
4826 int (*func
) (void *, const char *,
4829 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
4831 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4835 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4836 htab_traverse (htab
->loc_hash_table
,
4837 elfNN_loongarch_finish_local_dynamic_symbol
,
4844 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
4845 struct bfd_link_info
*info
)
4848 asection
*sdyn
, *plt
, *gotplt
= NULL
;
4849 struct loongarch_elf_link_hash_table
*htab
;
4851 htab
= loongarch_elf_hash_table (info
);
4853 dynobj
= htab
->elf
.dynobj
;
4854 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
4856 if (elf_hash_table (info
)->dynamic_sections_created
)
4858 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
4860 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
4864 plt
= htab
->elf
.splt
;
4865 gotplt
= htab
->elf
.sgotplt
;
4867 if (plt
&& 0 < plt
->size
)
4870 uint32_t plt_header
[PLT_HEADER_INSNS
];
4871 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
4875 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
4876 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
4878 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
4882 if (htab
->elf
.sgotplt
)
4884 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
4886 if (bfd_is_abs_section (output_section
))
4888 _bfd_error_handler (_("discarded output section: `%pA'"),
4893 if (0 < htab
->elf
.sgotplt
->size
)
4895 /* Write the first two entries in .got.plt, needed for the dynamic
4897 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
4899 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
4900 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
4903 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
4908 asection
*output_section
= htab
->elf
.sgot
->output_section
;
4910 if (0 < htab
->elf
.sgot
->size
)
4912 /* Set the first entry in the global offset table to the address of
4913 the dynamic section. */
4914 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
4915 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
4918 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
4924 /* Return address for Ith PLT stub in section PLT, for relocation REL
4925 or (bfd_vma) -1 if it should not be included. */
4928 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
4929 const arelent
*rel ATTRIBUTE_UNUSED
)
4931 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
4934 static enum elf_reloc_type_class
4935 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
4936 const asection
*rel_sec ATTRIBUTE_UNUSED
,
4937 const Elf_Internal_Rela
*rela
)
4939 struct loongarch_elf_link_hash_table
*htab
;
4940 htab
= loongarch_elf_hash_table (info
);
4942 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
4944 /* Check relocation against STT_GNU_IFUNC symbol if there are
4946 bfd
*abfd
= info
->output_bfd
;
4947 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
4948 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
4949 if (r_symndx
!= STN_UNDEF
)
4951 Elf_Internal_Sym sym
;
4952 if (!bed
->s
->swap_symbol_in (abfd
,
4953 htab
->elf
.dynsym
->contents
4954 + r_symndx
* bed
->s
->sizeof_sym
,
4957 /* xgettext:c-format */
4958 _bfd_error_handler (_("%pB symbol number %lu references"
4959 " nonexistent SHT_SYMTAB_SHNDX section"),
4961 /* Ideally an error class should be returned here. */
4963 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
4964 return reloc_class_ifunc
;
4968 switch (ELFNN_R_TYPE (rela
->r_info
))
4970 case R_LARCH_IRELATIVE
:
4971 return reloc_class_ifunc
;
4972 case R_LARCH_RELATIVE
:
4973 return reloc_class_relative
;
4974 case R_LARCH_JUMP_SLOT
:
4975 return reloc_class_plt
;
4977 return reloc_class_copy
;
4979 return reloc_class_normal
;
4983 /* Copy the extra info we tack onto an elf_link_hash_entry. */
4986 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
4987 struct elf_link_hash_entry
*dir
,
4988 struct elf_link_hash_entry
*ind
)
4990 struct elf_link_hash_entry
*edir
, *eind
;
4995 if (eind
->dyn_relocs
!= NULL
)
4997 if (edir
->dyn_relocs
!= NULL
)
4999 struct elf_dyn_relocs
**pp
;
5000 struct elf_dyn_relocs
*p
;
5002 /* Add reloc counts against the indirect sym to the direct sym
5003 list. Merge any entries against the same section. */
5004 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
5006 struct elf_dyn_relocs
*q
;
5008 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
5009 if (q
->sec
== p
->sec
)
5011 q
->pc_count
+= p
->pc_count
;
5012 q
->count
+= p
->count
;
5019 *pp
= edir
->dyn_relocs
;
5022 edir
->dyn_relocs
= eind
->dyn_relocs
;
5023 eind
->dyn_relocs
= NULL
;
5026 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
5028 loongarch_elf_hash_entry(edir
)->tls_type
5029 = loongarch_elf_hash_entry(eind
)->tls_type
;
5030 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
5032 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
5035 #define PRSTATUS_SIZE 0x1d8
5036 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
5037 #define PRSTATUS_OFFSET_PR_PID 0x20
5038 #define ELF_GREGSET_T_SIZE 0x168
5039 #define PRSTATUS_OFFSET_PR_REG 0x70
5041 /* Support for core dump NOTE sections. */
5044 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
5046 switch (note
->descsz
)
5051 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
5054 elf_tdata (abfd
)->core
->signal
=
5055 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
5058 elf_tdata (abfd
)->core
->lwpid
=
5059 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
5063 /* Make a ".reg/999" section. */
5064 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
5066 + PRSTATUS_OFFSET_PR_REG
);
5069 #define PRPSINFO_SIZE 0x88
5070 #define PRPSINFO_OFFSET_PR_PID 0x18
5071 #define PRPSINFO_OFFSET_PR_FNAME 0x28
5072 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
5073 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
5074 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
5077 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
5079 switch (note
->descsz
)
5084 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
5087 elf_tdata (abfd
)->core
->pid
=
5088 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
5091 elf_tdata (abfd
)->core
->program
=
5092 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
5093 PRPSINFO_SIZEOF_PR_FNAME
);
5096 elf_tdata (abfd
)->core
->command
=
5097 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
5098 PRPSINFO_SIZEOF_PR_PS_ARGS
);
5102 /* Note that for some reason, a spurious space is tacked
5103 onto the end of the args in some (at least one anyway)
5104 implementations, so strip it off if it exists. */
5107 char *command
= elf_tdata (abfd
)->core
->command
;
5108 int n
= strlen (command
);
5110 if (0 < n
&& command
[n
- 1] == ' ')
5111 command
[n
- 1] = '\0';
5117 /* Set the right mach type. */
5119 loongarch_elf_object_p (bfd
*abfd
)
5121 /* There are only two mach types in LoongArch currently. */
5122 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
5123 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
5125 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
5130 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
5131 Elf_Internal_Rela
*rel
,
5132 struct elf_link_hash_entry
*h
,
5133 Elf_Internal_Sym
*sym
)
5136 switch (ELFNN_R_TYPE (rel
->r_info
))
5138 case R_LARCH_GNU_VTINHERIT
:
5139 case R_LARCH_GNU_VTENTRY
:
5143 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
5146 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
5147 executable PLT slots where the executable never takes the address of those
5148 functions, the function symbols are not added to the hash table. */
5151 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
5153 if (h
->plt
.offset
!= (bfd_vma
) -1
5155 && !h
->pointer_equality_needed
)
5158 return _bfd_elf_hash_symbol (h
);
5161 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
5162 #define TARGET_LITTLE_NAME "elfNN-loongarch"
5163 #define ELF_ARCH bfd_arch_loongarch
5164 #define ELF_TARGET_ID LARCH_ELF_DATA
5165 #define ELF_MACHINE_CODE EM_LOONGARCH
5166 #define ELF_MAXPAGESIZE 0x4000
5167 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5168 #define bfd_elfNN_bfd_link_hash_table_create \
5169 loongarch_elf_link_hash_table_create
5170 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5171 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
5172 #define elf_info_to_howto loongarch_info_to_howto_rela
5173 #define bfd_elfNN_bfd_merge_private_bfd_data \
5174 elfNN_loongarch_merge_private_bfd_data
5176 #define elf_backend_reloc_type_class loongarch_reloc_type_class
5177 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5178 #define elf_backend_create_dynamic_sections \
5179 loongarch_elf_create_dynamic_sections
5180 #define elf_backend_check_relocs loongarch_elf_check_relocs
5181 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5182 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
5183 #define elf_backend_relocate_section loongarch_elf_relocate_section
5184 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
5185 #define elf_backend_output_arch_local_syms \
5186 elf_loongarch_output_arch_local_syms
5187 #define elf_backend_finish_dynamic_sections \
5188 loongarch_elf_finish_dynamic_sections
5189 #define elf_backend_object_p loongarch_elf_object_p
5190 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5191 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5192 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5193 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
5194 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
5195 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
5197 #define elf_backend_dtrel_excludes_plt 1
5199 #include "elfNN-target.h"