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
;
54 #define loongarch_elf_hash_entry(ent) \
55 ((struct loongarch_elf_link_hash_entry *) (ent))
57 struct _bfd_loongarch_elf_obj_tdata
59 struct elf_obj_tdata root
;
61 /* The tls_type for each local got entry. */
62 char *local_got_tls_type
;
65 #define _bfd_loongarch_elf_tdata(abfd) \
66 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
68 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
69 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
71 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
73 ? &loongarch_elf_hash_entry (h)->tls_type \
74 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
76 #define is_loongarch_elf(bfd) \
77 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
78 && elf_tdata (bfd) != NULL \
79 && elf_object_id (bfd) == LARCH_ELF_DATA)
81 struct loongarch_elf_link_hash_table
83 struct elf_link_hash_table elf
;
85 /* Short-cuts to get to dynamic linker sections. */
88 /* Small local sym to section mapping cache. */
89 struct sym_cache sym_cache
;
91 /* Used by local STT_GNU_IFUNC symbols. */
92 htab_t loc_hash_table
;
93 void *loc_hash_memory
;
95 /* The max alignment of output sections. */
96 bfd_vma max_alignment
;
98 /* The data segment phase, don't relax the section
99 when it is exp_seg_relro_adjust. */
100 int *data_segment_phase
;
103 /* Get the LoongArch ELF linker hash table from a link_info structure. */
104 #define loongarch_elf_hash_table(p) \
105 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
106 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
109 #define MINUS_ONE ((bfd_vma) 0 - 1)
111 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
113 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
114 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
116 #define PLT_HEADER_INSNS 8
117 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
119 #define PLT_ENTRY_INSNS 4
120 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
122 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
124 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
126 #define elf_backend_want_got_plt 1
128 #define elf_backend_plt_readonly 1
130 #define elf_backend_want_plt_sym 1
131 #define elf_backend_plt_alignment 4
132 #define elf_backend_can_gc_sections 1
133 #define elf_backend_can_refcount 1
134 #define elf_backend_want_got_sym 1
136 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
138 #define elf_backend_want_dynrelro 1
139 #define elf_backend_rela_normal 1
140 #define elf_backend_default_execstack 0
142 /* Generate a PLT header. */
145 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
148 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
151 if (pcrel
+ 0x80000800 > 0xffffffff)
153 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
154 bfd_set_error (bfd_error_bad_value
);
157 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
160 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
161 sub.[wd] $t1, $t1, $t3
162 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
163 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
164 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
165 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
166 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
169 if (GOT_ENTRY_SIZE
== 8)
171 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
172 entry
[1] = 0x0011bdad;
173 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
174 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
175 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
176 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
177 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
178 entry
[7] = 0x4c0001e0;
182 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
183 entry
[1] = 0x00113dad;
184 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
185 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
186 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
187 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
188 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
189 entry
[7] = 0x4c0001e0;
194 /* Generate a PLT entry. */
197 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
200 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
203 if (pcrel
+ 0x80000800 > 0xffffffff)
205 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
206 bfd_set_error (bfd_error_bad_value
);
209 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
212 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
213 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
214 | (lo
& 0xfff) << 10);
215 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
216 entry
[3] = 0x03400000; /* nop */
221 /* Create an entry in an LoongArch ELF linker hash table. */
223 static struct bfd_hash_entry
*
224 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
227 struct loongarch_elf_link_hash_entry
*eh
;
229 /* Allocate the structure if it has not already been allocated by a
233 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
238 /* Call the allocation method of the superclass. */
239 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
242 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
243 eh
->tls_type
= GOT_UNKNOWN
;
249 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
250 for local symbol so that we can handle local STT_GNU_IFUNC symbols
251 as global symbol. We reuse indx and dynstr_index for local symbol
252 hash since they aren't used by global symbols in this backend. */
255 elfNN_loongarch_local_htab_hash (const void *ptr
)
257 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
258 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
261 /* Compare local hash entries. */
264 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
266 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
267 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
269 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
272 /* Find and/or create a hash entry for local symbol. */
273 static struct elf_link_hash_entry
*
274 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
275 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
278 struct loongarch_elf_link_hash_entry e
, *ret
;
279 asection
*sec
= abfd
->sections
;
280 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
283 e
.elf
.indx
= sec
->id
;
284 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
285 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
286 create
? INSERT
: NO_INSERT
);
293 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
297 ret
= ((struct loongarch_elf_link_hash_entry
*)
298 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
299 sizeof (struct loongarch_elf_link_hash_entry
)));
302 memset (ret
, 0, sizeof (*ret
));
303 ret
->elf
.indx
= sec
->id
;
304 ret
->elf
.pointer_equality_needed
= 0;
305 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
306 ret
->elf
.dynindx
= -1;
307 ret
->elf
.needs_plt
= 0;
308 ret
->elf
.plt
.refcount
= -1;
309 ret
->elf
.got
.refcount
= -1;
310 ret
->elf
.def_dynamic
= 0;
311 ret
->elf
.def_regular
= 1;
312 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
313 ret
->elf
.ref_regular
= 0;
314 ret
->elf
.forced_local
= 1;
315 ret
->elf
.root
.type
= bfd_link_hash_defined
;
321 /* Destroy an LoongArch elf linker hash table. */
324 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
326 struct loongarch_elf_link_hash_table
*ret
;
327 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
329 if (ret
->loc_hash_table
)
330 htab_delete (ret
->loc_hash_table
);
331 if (ret
->loc_hash_memory
)
332 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
334 _bfd_elf_link_hash_table_free (obfd
);
337 /* Create a LoongArch ELF linker hash table. */
339 static struct bfd_link_hash_table
*
340 loongarch_elf_link_hash_table_create (bfd
*abfd
)
342 struct loongarch_elf_link_hash_table
*ret
;
343 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
345 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
349 if (!_bfd_elf_link_hash_table_init
350 (&ret
->elf
, abfd
, link_hash_newfunc
,
351 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
357 ret
->max_alignment
= MINUS_ONE
;
359 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
360 elfNN_loongarch_local_htab_eq
, NULL
);
361 ret
->loc_hash_memory
= objalloc_create ();
362 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
364 elfNN_loongarch_link_hash_table_free (abfd
);
367 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
369 return &ret
->elf
.root
;
372 /* Merge backend specific data from an object file to the output
373 object file when linking. */
376 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
378 bfd
*obfd
= info
->output_bfd
;
379 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
380 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
382 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
385 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
387 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
388 "the selected emulation:\n"
389 " target emulation `%s' does not match `%s'"),
390 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
394 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
397 /* If the input BFD is not a dynamic object and it does not contain any
398 non-data sections, do not account its ABI. For example, various
399 packages produces such data-only relocatable objects with
400 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
401 But they are compatible with all ABIs. */
402 if (!(ibfd
->flags
& DYNAMIC
))
405 bool have_code_sections
= false;
406 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
407 if ((bfd_section_flags (sec
)
408 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
409 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
411 have_code_sections
= true;
414 if (!have_code_sections
)
418 if (!elf_flags_init (obfd
))
420 elf_flags_init (obfd
) = true;
421 elf_elfheader (obfd
)->e_flags
= in_flags
;
424 else if (out_flags
!= in_flags
)
426 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags
)
427 && EF_LOONGARCH_IS_OBJ_V1 (in_flags
))
428 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags
)
429 && EF_LOONGARCH_IS_OBJ_V1 (out_flags
)))
431 elf_elfheader (obfd
)->e_flags
|= EF_LOONGARCH_OBJABI_V1
;
432 out_flags
= elf_elfheader (obfd
)->e_flags
;
433 in_flags
= out_flags
;
437 /* Disallow linking different ABIs. */
438 /* Only check relocation version.
439 The obj_v0 is compatible with obj_v1. */
440 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
442 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
449 bfd_set_error (bfd_error_bad_value
);
453 /* Create the .got section. */
456 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
461 struct elf_link_hash_entry
*h
;
462 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
463 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
465 /* This function may be called more than once. */
466 if (htab
->sgot
!= NULL
)
469 flags
= bed
->dynamic_sec_flags
;
470 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
471 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
473 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
477 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
478 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
482 /* The first bit of the global offset table is the header. */
483 s
->size
+= bed
->got_header_size
;
485 if (bed
->want_got_plt
)
487 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
488 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
492 /* Reserve room for the header. */
493 s
->size
= GOTPLT_HEADER_SIZE
;
496 if (bed
->want_got_sym
)
498 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
499 section. We don't do this in the linker script because we don't want
500 to define the symbol if we are not creating a global offset table. */
501 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
502 "_GLOBAL_OFFSET_TABLE_");
503 elf_hash_table (info
)->hgot
= h
;
510 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
511 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
515 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
517 struct loongarch_elf_link_hash_table
*htab
;
519 htab
= loongarch_elf_hash_table (info
);
520 BFD_ASSERT (htab
!= NULL
);
522 if (!loongarch_elf_create_got_section (dynobj
, info
))
525 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
528 if (!bfd_link_pic (info
))
530 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
531 SEC_ALLOC
| SEC_THREAD_LOCAL
);
533 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
534 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
541 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
542 struct bfd_link_info
*info
,
543 struct elf_link_hash_entry
*h
,
544 unsigned long symndx
,
547 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
548 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
550 /* This is a global offset table entry for a local symbol. */
551 if (elf_local_got_refcounts (abfd
) == NULL
)
554 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
555 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
557 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
558 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
567 if (htab
->elf
.sgot
== NULL
568 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
572 if (h
->got
.refcount
< 0)
577 elf_local_got_refcounts (abfd
)[symndx
]++;
580 /* No need for GOT. */
583 _bfd_error_handler (_("Internal error: unreachable."));
587 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
588 *new_tls_type
|= tls_type
;
589 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
591 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
592 "thread local symbol"),
594 h
? h
->root
.root
.string
: "<local>");
601 /* Look through the relocs for a section during the first phase, and
602 allocate space in the global offset table or procedure linkage
606 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
607 asection
*sec
, const Elf_Internal_Rela
*relocs
)
609 struct loongarch_elf_link_hash_table
*htab
;
610 Elf_Internal_Shdr
*symtab_hdr
;
611 struct elf_link_hash_entry
**sym_hashes
;
612 const Elf_Internal_Rela
*rel
;
613 asection
*sreloc
= NULL
;
615 if (bfd_link_relocatable (info
))
618 htab
= loongarch_elf_hash_table (info
);
619 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
620 sym_hashes
= elf_sym_hashes (abfd
);
622 if (htab
->elf
.dynobj
== NULL
)
623 htab
->elf
.dynobj
= abfd
;
625 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
628 unsigned int r_symndx
;
629 struct elf_link_hash_entry
*h
;
630 Elf_Internal_Sym
*isym
= NULL
;
632 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
633 r_type
= ELFNN_R_TYPE (rel
->r_info
);
635 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
637 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
641 if (r_symndx
< symtab_hdr
->sh_info
)
643 /* A local symbol. */
644 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
648 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
650 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
654 h
->type
= STT_GNU_IFUNC
;
662 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
663 while (h
->root
.type
== bfd_link_hash_indirect
664 || h
->root
.type
== bfd_link_hash_warning
)
665 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
668 /* It is referenced by a non-shared object. */
672 if (h
&& h
->type
== STT_GNU_IFUNC
)
674 if (htab
->elf
.dynobj
== NULL
)
675 htab
->elf
.dynobj
= abfd
;
677 /* Create 'irelifunc' in PIC object. */
678 if (bfd_link_pic (info
)
679 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
681 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
682 else if (!htab
->elf
.splt
683 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
685 /* Create the ifunc sections, iplt and ipltgot, for static
687 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
688 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
691 if (h
->plt
.refcount
< 0)
696 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
699 int need_dynreloc
= 0;
700 int only_need_pcrel
= 0;
704 case R_LARCH_GOT_PC_HI20
:
705 case R_LARCH_GOT_HI20
:
706 case R_LARCH_SOP_PUSH_GPREL
:
709 h
->pointer_equality_needed
= 1;
710 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
716 case R_LARCH_TLS_LD_PC_HI20
:
717 case R_LARCH_TLS_LD_HI20
:
718 case R_LARCH_TLS_GD_PC_HI20
:
719 case R_LARCH_TLS_GD_HI20
:
720 case R_LARCH_SOP_PUSH_TLS_GD
:
721 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
727 case R_LARCH_TLS_IE_PC_HI20
:
728 case R_LARCH_TLS_IE_HI20
:
729 case R_LARCH_SOP_PUSH_TLS_GOT
:
730 if (bfd_link_pic (info
))
731 /* May fail for lazy-bind. */
732 info
->flags
|= DF_STATIC_TLS
;
734 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
740 case R_LARCH_TLS_LE_HI20
:
741 case R_LARCH_SOP_PUSH_TLS_TPREL
:
742 if (!bfd_link_executable (info
))
745 info
->flags
|= DF_STATIC_TLS
;
747 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
753 case R_LARCH_ABS_HI20
:
754 case R_LARCH_SOP_PUSH_ABSOLUTE
:
756 /* If this reloc is in a read-only section, we might
757 need a copy reloc. We can't check reliably at this
758 stage whether the section is read-only, as input
759 sections have not yet been mapped to output sections.
760 Tentatively set the flag for now, and correct in
761 adjust_dynamic_symbol. */
765 case R_LARCH_PCALA_HI20
:
768 /* For pcalau12i + jirl. */
770 if (h
->plt
.refcount
< 0)
775 h
->pointer_equality_needed
= 1;
786 if (!bfd_link_pic (info
))
789 /* We try to create PLT stub for all non-local function. */
790 if (h
->plt
.refcount
< 0)
797 case R_LARCH_SOP_PUSH_PCREL
:
800 if (!bfd_link_pic (info
))
803 /* We try to create PLT stub for all non-local function. */
804 if (h
->plt
.refcount
< 0)
807 h
->pointer_equality_needed
= 1;
812 case R_LARCH_SOP_PUSH_PLT_PCREL
:
813 /* This symbol requires a procedure linkage table entry. We
814 actually build the entry in adjust_dynamic_symbol,
815 because this might be a case of linking PIC code without
816 linking in any dynamic objects, in which case we don't
817 need to generate a procedure linkage table after all. */
821 if (h
->plt
.refcount
< 0)
827 case R_LARCH_TLS_DTPREL32
:
828 case R_LARCH_TLS_DTPREL64
:
833 case R_LARCH_JUMP_SLOT
:
839 /* If resolved symbol is defined in this object,
840 1. Under pie, the symbol is known. We convert it
841 into R_LARCH_RELATIVE and need load-addr still.
842 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
843 3. Under dll, R_LARCH_NN can't be changed normally, since
844 its defination could be covered by the one in executable.
845 For symbolic, we convert it into R_LARCH_RELATIVE.
846 Thus, only under pde, it needs pcrel only. We discard it. */
847 only_need_pcrel
= bfd_link_pde (info
);
850 && (!bfd_link_pic (info
)
851 || h
->type
== STT_GNU_IFUNC
))
853 /* This reloc might not bind locally. */
855 h
->pointer_equality_needed
= 1;
858 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
860 /* We may need a .plt entry if the symbol is a function
861 defined in a shared lib or is a function referenced
862 from the code or read-only section. */
863 h
->plt
.refcount
+= 1;
868 case R_LARCH_GNU_VTINHERIT
:
869 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
873 case R_LARCH_GNU_VTENTRY
:
874 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
882 /* Record some info for sizing and allocating dynamic entry. */
883 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
885 /* When creating a shared object, we must copy these
886 relocs into the output file. We create a reloc
887 section in dynobj and make room for the reloc. */
888 struct elf_dyn_relocs
*p
;
889 struct elf_dyn_relocs
**head
;
894 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
895 LARCH_ELF_LOG_WORD_BYTES
,
896 abfd
, /*rela?*/ true);
901 /* If this is a global symbol, we count the number of
902 relocations we need for this symbol. */
904 head
= &h
->dyn_relocs
;
907 /* Track dynamic relocs needed for local syms too.
908 We really need local syms available to do this
914 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
918 vpp
= &elf_section_data (s
)->local_dynrel
;
919 head
= (struct elf_dyn_relocs
**) vpp
;
923 if (p
== NULL
|| p
->sec
!= sec
)
925 bfd_size_type amt
= sizeof *p
;
926 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
937 p
->pc_count
+= only_need_pcrel
;
944 /* Find dynamic relocs for H that apply to read-only sections. */
947 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
949 struct elf_dyn_relocs
*p
;
951 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
953 asection
*s
= p
->sec
->output_section
;
955 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
961 /* Adjust a symbol defined by a dynamic object and referenced by a
962 regular object. The current definition is in some section of the
963 dynamic object, but we're not including those sections. We have to
964 change the definition to something the rest of the link can
967 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
968 struct elf_link_hash_entry
*h
)
970 struct loongarch_elf_link_hash_table
*htab
;
973 htab
= loongarch_elf_hash_table (info
);
974 BFD_ASSERT (htab
!= NULL
);
976 dynobj
= htab
->elf
.dynobj
;
978 /* Make sure we know what is going on here. */
979 BFD_ASSERT (dynobj
!= NULL
981 || h
->type
== STT_GNU_IFUNC
985 && !h
->def_regular
)));
987 /* If this is a function, put it in the procedure linkage table. We
988 will fill in the contents of the procedure linkage table later
989 (although we could actually do it here). */
990 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
992 if (h
->plt
.refcount
<= 0
993 || (h
->type
!= STT_GNU_IFUNC
994 && (SYMBOL_REFERENCES_LOCAL (info
, h
)
995 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
996 && h
->root
.type
== bfd_link_hash_undefweak
))))
998 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
999 in an input file, but the symbol was never referred to by a
1000 dynamic object, or if all references were garbage collected.
1001 In such a case, we don't actually need to build a PLT entry. */
1002 h
->plt
.offset
= MINUS_ONE
;
1009 h
->plt
.offset
= MINUS_ONE
;
1011 /* If this is a weak symbol, and there is a real definition, the
1012 processor independent code will have arranged for us to see the
1013 real definition first, and we can just use the same value. */
1014 if (h
->is_weakalias
)
1016 struct elf_link_hash_entry
*def
= weakdef (h
);
1017 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
1018 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
1019 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
1023 /* R_LARCH_COPY is not adept glibc, not to generate. */
1024 /* Can not print anything, because make check ld. */
1028 /* Allocate space in .plt, .got and associated reloc sections for
1032 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1034 struct bfd_link_info
*info
;
1035 struct loongarch_elf_link_hash_table
*htab
;
1036 struct elf_dyn_relocs
*p
;
1038 if (h
->root
.type
== bfd_link_hash_indirect
)
1041 if (h
->type
== STT_GNU_IFUNC
1045 info
= (struct bfd_link_info
*) inf
;
1046 htab
= loongarch_elf_hash_table (info
);
1047 bool dyn
= htab
->elf
.dynamic_sections_created
;
1048 BFD_ASSERT (htab
!= NULL
);
1052 asection
*plt
, *gotplt
, *relplt
;
1061 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1062 && h
->root
.type
== bfd_link_hash_undefweak
)
1064 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1068 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1069 && h
->type
!= STT_GNU_IFUNC
)
1072 plt
= htab
->elf
.splt
;
1073 gotplt
= htab
->elf
.sgotplt
;
1074 relplt
= htab
->elf
.srelplt
;
1076 else if (htab
->elf
.iplt
)
1078 /* .iplt only for IFUNC. */
1079 if (h
->type
!= STT_GNU_IFUNC
)
1082 plt
= htab
->elf
.iplt
;
1083 gotplt
= htab
->elf
.igotplt
;
1084 relplt
= htab
->elf
.irelplt
;
1090 plt
->size
= PLT_HEADER_SIZE
;
1092 h
->plt
.offset
= plt
->size
;
1093 plt
->size
+= PLT_ENTRY_SIZE
;
1094 gotplt
->size
+= GOT_ENTRY_SIZE
;
1095 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1097 /* If this symbol is not defined in a regular file, and we are
1098 not generating a shared library, then set the symbol to this
1099 location in the .plt. This is required to make function
1100 pointers compare as equal between the normal executable and
1101 the shared library. */
1102 if (!bfd_link_pic (info
)
1105 h
->root
.u
.def
.section
= plt
;
1106 h
->root
.u
.def
.value
= h
->plt
.offset
;
1114 h
->plt
.offset
= MINUS_ONE
;
1116 if (0 < h
->got
.refcount
)
1119 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1121 /* Make sure this symbol is output as a dynamic symbol.
1122 Undefined weak syms won't yet be marked as dynamic. */
1123 if (h
->dynindx
== -1 && !h
->forced_local
&& dyn
1124 && h
->root
.type
== bfd_link_hash_undefweak
)
1126 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1131 h
->got
.offset
= s
->size
;
1132 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
1134 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1135 if (tls_type
& GOT_TLS_GD
)
1137 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1138 if (bfd_link_executable (info
))
1140 /* Link exe and not defined local. */
1141 if (!SYMBOL_REFERENCES_LOCAL (info
, h
))
1142 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1146 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1147 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1149 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1153 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1154 if (tls_type
& GOT_TLS_IE
)
1156 s
->size
+= GOT_ENTRY_SIZE
;
1158 if (bfd_link_executable (info
))
1160 /* Link exe and not defined local. */
1161 if (!SYMBOL_REFERENCES_LOCAL (info
, h
))
1162 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1166 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1172 s
->size
+= GOT_ENTRY_SIZE
;
1173 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1174 || h
->root
.type
!= bfd_link_hash_undefweak
)
1175 && (bfd_link_pic (info
)
1176 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
),
1178 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1179 /* Undefined weak symbol in static PIE resolves to 0 without
1180 any dynamic relocations. */
1181 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1185 h
->got
.offset
= MINUS_ONE
;
1187 if (h
->dyn_relocs
== NULL
)
1190 /* Extra dynamic relocate,
1192 * R_LARCH_TLS_DTPRELNN
1196 if (SYMBOL_CALLS_LOCAL (info
, h
))
1198 struct elf_dyn_relocs
**pp
;
1200 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1202 p
->count
-= p
->pc_count
;
1211 if (h
->root
.type
== bfd_link_hash_undefweak
)
1213 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
)
1214 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
1215 || (!bfd_link_pic (info
) && h
->non_got_ref
))
1216 h
->dyn_relocs
= NULL
;
1217 else if (h
->dynindx
== -1 && !h
->forced_local
)
1219 /* Make sure this symbol is output as a dynamic symbol.
1220 Undefined weak syms won't yet be marked as dynamic. */
1221 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
1224 if (h
->dynindx
== -1)
1225 h
->dyn_relocs
= NULL
;
1229 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1231 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1232 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1238 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1239 For local def and ref ifunc,
1240 dynamic relocations are stored in
1241 1. rela.srelgot section in dynamic object (dll or exec).
1242 2. rela.irelplt section in static executable.
1243 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1244 instead of rela.srelplt. Glibc ELF loader will not support
1245 R_LARCH_IRELATIVE relocation in rela.plt. */
1248 local_allocate_ifunc_dyn_relocs (struct bfd_link_info
*info
,
1249 struct elf_link_hash_entry
*h
,
1250 struct elf_dyn_relocs
**head
,
1251 unsigned int plt_entry_size
,
1252 unsigned int plt_header_size
,
1253 unsigned int got_entry_size
,
1256 asection
*plt
, *gotplt
, *relplt
;
1257 struct elf_dyn_relocs
*p
;
1258 unsigned int sizeof_reloc
;
1259 const struct elf_backend_data
*bed
;
1260 struct elf_link_hash_table
*htab
;
1261 /* If AVOID_PLT is TRUE, don't use PLT if possible. */
1262 bool use_plt
= !avoid_plt
|| h
->plt
.refcount
> 0;
1263 bool need_dynreloc
= !use_plt
|| bfd_link_pic (info
);
1265 /* When a PIC object references a STT_GNU_IFUNC symbol defined
1266 in executable or it isn't referenced via PLT, the address of
1267 the resolved function may be used. But in non-PIC executable,
1268 the address of its plt slot may be used. Pointer equality may
1269 not work correctly. PIE or non-PLT reference should be used if
1270 pointer equality is required here.
1272 If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1273 backend should change it to the normal function and set its address
1274 to its PLT entry which should be resolved by R_*_IRELATIVE at
1275 run-time. All external references should be resolved to its PLT in
1278 && !(bfd_link_pde (info
) && h
->def_regular
)
1279 && (h
->dynindx
!= -1
1280 || info
->export_dynamic
)
1281 && h
->pointer_equality_needed
)
1283 info
->callbacks
->einfo
1284 /* xgettext:c-format. */
1285 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1286 "equality in `%pB' can not be used when making an "
1287 "executable; recompile with -fPIE and relink with -pie\n"),
1288 h
->root
.root
.string
,
1289 h
->root
.u
.def
.section
->owner
);
1290 bfd_set_error (bfd_error_bad_value
);
1294 htab
= elf_hash_table (info
);
1296 /* When the symbol is marked with regular reference, if PLT isn't used
1297 or we are building a PIC object, we must keep dynamic relocation
1298 if there is non-GOT reference and use PLT if there is PC-relative
1300 if (need_dynreloc
&& h
->ref_regular
)
1303 for (p
= *head
; p
!= NULL
; p
= p
->next
)
1307 /* Need dynamic relocations for non-GOT reference. */
1311 /* Must use PLT for PC-relative reference. */
1313 need_dynreloc
= bfd_link_pic (info
);
1321 /* Support garbage collection against STT_GNU_IFUNC symbols. */
1322 if (h
->plt
.refcount
<= 0 && h
->got
.refcount
<= 0)
1324 h
->got
= htab
->init_got_offset
;
1325 h
->plt
= htab
->init_plt_offset
;
1330 /* Return and discard space for dynamic relocations against it if
1331 it is never referenced. */
1332 if (!h
->ref_regular
)
1334 if (h
->plt
.refcount
> 0
1335 || h
->got
.refcount
> 0)
1337 h
->got
= htab
->init_got_offset
;
1338 h
->plt
= htab
->init_plt_offset
;
1344 bed
= get_elf_backend_data (info
->output_bfd
);
1345 if (bed
->rela_plts_and_copies_p
)
1346 sizeof_reloc
= bed
->s
->sizeof_rela
;
1348 sizeof_reloc
= bed
->s
->sizeof_rel
;
1350 /* When building a static executable, use iplt, igot.plt and
1351 rela.iplt sections for STT_GNU_IFUNC symbols. */
1352 if (htab
->splt
!= NULL
)
1355 gotplt
= htab
->sgotplt
;
1356 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
1357 relplt
= htab
->srelgot
;
1359 /* If this is the first plt entry and PLT is used, make room for
1360 the special first entry. */
1361 if (plt
->size
== 0 && use_plt
)
1362 plt
->size
+= plt_header_size
;
1367 gotplt
= htab
->igotplt
;
1368 relplt
= htab
->irelplt
;
1373 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
1374 the original value for R_*_IRELATIVE. */
1375 h
->plt
.offset
= plt
->size
;
1377 /* Make room for this entry in the plt/iplt section. */
1378 plt
->size
+= plt_entry_size
;
1380 /* We also need to make an entry in the got.plt/got.iplt section,
1381 which will be placed in the got section by the linker script. */
1382 gotplt
->size
+= got_entry_size
;
1385 /* We also need to make an entry in the rela.plt/.rela.iplt
1386 section for GOTPLT relocation if PLT is used. */
1389 relplt
->size
+= sizeof_reloc
;
1390 relplt
->reloc_count
++;
1393 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1394 there is a non-GOT reference in a PIC object or PLT isn't used. */
1395 if (!need_dynreloc
|| !h
->non_got_ref
)
1398 /* Finally, allocate space. */
1402 bfd_size_type count
= 0;
1410 htab
->ifunc_resolvers
= count
!= 0;
1412 /* Dynamic relocations are stored in
1413 1. rela.srelgot section in PIC object.
1414 2. rela.srelgot section in dynamic executable.
1415 3. rela.irelplt section in static executable. */
1416 if (htab
->splt
!= NULL
)
1417 htab
->srelgot
->size
+= count
* sizeof_reloc
;
1420 relplt
->size
+= count
* sizeof_reloc
;
1421 relplt
->reloc_count
+= count
;
1425 /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1426 and got has the PLT entry adddress. We will load the GOT entry
1427 with the PLT entry in finish_dynamic_symbol if it is used. For
1428 branch, it uses got.plt. For symbol value, if PLT is used,
1429 1. Use got.plt in a PIC object if it is forced local or not
1431 2. Use got.plt in a non-PIC object if pointer equality isn't
1433 3. Use got.plt in PIE.
1434 4. Use got.plt if got isn't used.
1435 5. Otherwise use got so that it can be shared among different
1436 objects at run-time.
1437 If PLT isn't used, always use got for symbol value.
1438 We only need to relocate got entry in PIC object or in dynamic
1439 executable without PLT. */
1441 && (h
->got
.refcount
<= 0
1442 || (bfd_link_pic (info
)
1443 && (h
->dynindx
== -1
1444 || h
->forced_local
))
1446 !h
->pointer_equality_needed
)
1447 || htab
->sgot
== NULL
))
1450 h
->got
.offset
= (bfd_vma
) -1;
1456 /* PLT isn't used. */
1457 h
->plt
.offset
= (bfd_vma
) -1;
1459 if (h
->got
.refcount
<= 0)
1461 /* GOT isn't need when there are only relocations for static
1463 h
->got
.offset
= (bfd_vma
) -1;
1467 h
->got
.offset
= htab
->sgot
->size
;
1468 htab
->sgot
->size
+= got_entry_size
;
1469 /* Need to relocate the GOT entry in a PIC object or PLT isn't
1470 used. Otherwise, the GOT entry will be filled with the PLT
1471 entry and dynamic GOT relocation isn't needed. */
1474 /* For non-static executable, dynamic GOT relocation is in
1475 rela.got section, but for static executable, it is
1476 in rela.iplt section. */
1477 if (htab
->splt
!= NULL
)
1478 htab
->srelgot
->size
+= sizeof_reloc
;
1481 relplt
->size
+= sizeof_reloc
;
1482 relplt
->reloc_count
++;
1491 /* Allocate space in .plt, .got and associated reloc sections for
1492 ifunc dynamic relocs. */
1495 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1497 struct bfd_link_info
*info
;
1498 /* An example of a bfd_link_hash_indirect symbol is versioned
1499 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1500 -> __gxx_personality_v0(bfd_link_hash_defined)
1502 There is no need to process bfd_link_hash_indirect symbols here
1503 because we will also be presented with the concrete instance of
1504 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1505 called to copy all relevant data from the generic to the concrete
1507 if (h
->root
.type
== bfd_link_hash_indirect
)
1510 if (h
->root
.type
== bfd_link_hash_warning
)
1511 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1513 info
= (struct bfd_link_info
*) inf
;
1515 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1516 here if it is defined and referenced in a non-shared object. */
1517 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
1519 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1520 return local_allocate_ifunc_dyn_relocs (info
, h
,
1527 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1538 /* Allocate space in .plt, .got and associated reloc sections for
1539 ifunc dynamic relocs. */
1542 elfNN_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
1544 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1546 if (h
->type
!= STT_GNU_IFUNC
1550 || h
->root
.type
!= bfd_link_hash_defined
)
1553 return elfNN_allocate_ifunc_dynrelocs (h
, inf
);
1556 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1557 read-only sections. */
1560 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1564 if (h
->root
.type
== bfd_link_hash_indirect
)
1567 sec
= readonly_dynrelocs (h
);
1570 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1572 info
->flags
|= DF_TEXTREL
;
1573 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1574 "read-only section `%pA'\n"),
1575 sec
->owner
, h
->root
.root
.string
, sec
);
1577 /* Not an error, just cut short the traversal. */
1584 loongarch_elf_size_dynamic_sections (bfd
*output_bfd
,
1585 struct bfd_link_info
*info
)
1587 struct loongarch_elf_link_hash_table
*htab
;
1592 htab
= loongarch_elf_hash_table (info
);
1593 BFD_ASSERT (htab
!= NULL
);
1594 dynobj
= htab
->elf
.dynobj
;
1595 BFD_ASSERT (dynobj
!= NULL
);
1597 if (htab
->elf
.dynamic_sections_created
)
1599 /* Set the contents of the .interp section to the interpreter. */
1600 if (bfd_link_executable (info
) && !info
->nointerp
)
1602 const char *interpreter
;
1603 s
= bfd_get_linker_section (dynobj
, ".interp");
1604 BFD_ASSERT (s
!= NULL
);
1606 if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS32
)
1607 interpreter
= "/lib32/ld.so.1";
1608 else if (elf_elfheader (output_bfd
)->e_ident
[EI_CLASS
] == ELFCLASS64
)
1609 interpreter
= "/lib64/ld.so.1";
1611 interpreter
= "/lib/ld.so.1";
1613 s
->contents
= (unsigned char *) interpreter
;
1614 s
->size
= strlen (interpreter
) + 1;
1618 /* Set up .got offsets for local syms, and space for local dynamic
1620 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
1622 bfd_signed_vma
*local_got
;
1623 bfd_signed_vma
*end_local_got
;
1624 char *local_tls_type
;
1625 bfd_size_type locsymcount
;
1626 Elf_Internal_Shdr
*symtab_hdr
;
1629 if (!is_loongarch_elf (ibfd
))
1632 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
1634 struct elf_dyn_relocs
*p
;
1636 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
1638 p
->count
-= p
->pc_count
;
1639 if (!bfd_is_abs_section (p
->sec
)
1640 && bfd_is_abs_section (p
->sec
->output_section
))
1642 /* Input section has been discarded, either because
1643 it is a copy of a linkonce section or due to
1644 linker script /DISCARD/, so we'll be discarding
1647 else if (0 < p
->count
)
1649 srel
= elf_section_data (p
->sec
)->sreloc
;
1650 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1651 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
1652 info
->flags
|= DF_TEXTREL
;
1657 local_got
= elf_local_got_refcounts (ibfd
);
1661 symtab_hdr
= &elf_symtab_hdr (ibfd
);
1662 locsymcount
= symtab_hdr
->sh_info
;
1663 end_local_got
= local_got
+ locsymcount
;
1664 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
1666 srel
= htab
->elf
.srelgot
;
1667 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
1671 *local_got
= s
->size
;
1673 /* TLS gd use two got. */
1674 if (*local_tls_type
& GOT_TLS_GD
)
1675 s
->size
+= GOT_ENTRY_SIZE
* 2;
1677 /* Normal got, tls ie/ld use one got. */
1678 s
->size
+= GOT_ENTRY_SIZE
;
1680 if (bfd_link_executable (info
)
1681 && (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
)))
1685 srel
->size
+= sizeof (ElfNN_External_Rela
);
1689 *local_got
= MINUS_ONE
;
1693 /* Allocate global sym .plt and .got entries, and space for global
1694 sym dynamic relocs. */
1695 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
1697 /* Allocate global ifunc sym .plt and .got entries, and space for global
1698 ifunc sym dynamic relocs. */
1699 elf_link_hash_traverse (&htab
->elf
, elfNN_allocate_ifunc_dynrelocs
, info
);
1701 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1702 htab_traverse (htab
->loc_hash_table
,
1703 elfNN_allocate_local_ifunc_dynrelocs
, info
);
1705 /* Don't allocate .got.plt section if there are no PLT. */
1706 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
1707 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
1708 htab
->elf
.sgotplt
->size
= 0;
1710 /* The check_relocs and adjust_dynamic_symbol entry points have
1711 determined the sizes of the various dynamic sections. Allocate
1713 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
1715 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
1718 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
1719 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
1720 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
1722 /* Strip this section if we don't need it; see the
1725 else if (strncmp (s
->name
, ".rela", 5) == 0)
1729 /* We use the reloc_count field as a counter if we need
1730 to copy relocs into the output file. */
1736 /* It's not one of our sections. */
1742 /* If we don't need this section, strip it from the
1743 output file. This is mostly to handle .rela.bss and
1744 .rela.plt. We must create both sections in
1745 create_dynamic_sections, because they must be created
1746 before the linker maps input sections to output
1747 sections. The linker does that before
1748 adjust_dynamic_symbol is called, and it is that
1749 function which decides whether anything needs to go
1750 into these sections. */
1751 s
->flags
|= SEC_EXCLUDE
;
1755 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
1758 /* Allocate memory for the section contents. Zero the memory
1759 for the benefit of .rela.plt, which has 4 unused entries
1760 at the beginning, and we don't want garbage. */
1761 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
1762 if (s
->contents
== NULL
)
1766 if (elf_hash_table (info
)->dynamic_sections_created
)
1768 /* Add some entries to the .dynamic section. We fill in the
1769 values later, in loongarch_elf_finish_dynamic_sections, but we
1770 must add the entries now so that we get the correct size for
1771 the .dynamic section. The DT_DEBUG entry is filled in by the
1772 dynamic linker and used by the debugger. */
1773 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1775 if (bfd_link_executable (info
))
1777 if (!add_dynamic_entry (DT_DEBUG
, 0))
1781 if (htab
->elf
.srelplt
->size
!= 0)
1783 if (!add_dynamic_entry (DT_PLTGOT
, 0)
1784 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
1785 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
1786 || !add_dynamic_entry (DT_JMPREL
, 0))
1790 if (!add_dynamic_entry (DT_RELA
, 0)
1791 || !add_dynamic_entry (DT_RELASZ
, 0)
1792 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
1795 /* If any dynamic relocs apply to a read-only section,
1796 then we need a DT_TEXTREL entry. */
1797 if ((info
->flags
& DF_TEXTREL
) == 0)
1798 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
1800 if (info
->flags
& DF_TEXTREL
)
1802 if (!add_dynamic_entry (DT_TEXTREL
, 0))
1804 /* Clear the DF_TEXTREL flag. It will be set again if we
1805 write out an actual text relocation; we may not, because
1806 at this point we do not know whether e.g. any .eh_frame
1807 absolute relocations have been converted to PC-relative. */
1808 info
->flags
&= ~DF_TEXTREL
;
1811 #undef add_dynamic_entry
1816 #define LARCH_LD_STACK_DEPTH 16
1817 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
1818 static size_t larch_stack_top
= 0;
1820 static bfd_reloc_status_type
1821 loongarch_push (int64_t val
)
1823 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
1824 return bfd_reloc_outofrange
;
1825 larch_opc_stack
[larch_stack_top
++] = val
;
1826 return bfd_reloc_ok
;
1829 static bfd_reloc_status_type
1830 loongarch_pop (int64_t *val
)
1832 if (larch_stack_top
== 0)
1833 return bfd_reloc_outofrange
;
1835 *val
= larch_opc_stack
[--larch_stack_top
];
1836 return bfd_reloc_ok
;
1839 static bfd_reloc_status_type
1840 loongarch_top (int64_t *val
)
1842 if (larch_stack_top
== 0)
1843 return bfd_reloc_outofrange
;
1845 *val
= larch_opc_stack
[larch_stack_top
- 1];
1846 return bfd_reloc_ok
;
1850 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
1852 BFD_ASSERT (s
&& s
->contents
);
1853 const struct elf_backend_data
*bed
;
1856 bed
= get_elf_backend_data (abfd
);
1857 if (!(s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
))
1858 BFD_ASSERT (s
->size
> s
->reloc_count
* bed
->s
->sizeof_rela
);
1859 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
1860 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
1863 /* Check rel->r_offset in range of contents. */
1864 static bfd_reloc_status_type
1865 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
1866 const asection
*input_section
)
1868 if (0 == strcmp(input_section
->name
, ".text")
1869 && rel
->r_offset
> input_section
->size
)
1870 return bfd_reloc_overflow
;
1872 return bfd_reloc_ok
;
1875 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
1877 bfd_reloc_status_type ret = loongarch_pop (&op2); \
1878 if (ret == bfd_reloc_ok) \
1880 ret = loongarch_pop (&op1); \
1881 if (ret == bfd_reloc_ok) \
1882 ret = loongarch_push (op3); \
1887 static bfd_reloc_status_type
1888 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
1889 const asection
*input_section ATTRIBUTE_UNUSED
,
1890 reloc_howto_type
*howto
, bfd
*input_bfd
,
1891 bfd_byte
*contents
, bfd_vma reloc_val
)
1893 int bits
= bfd_get_reloc_size (howto
) * 8;
1894 uint32_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1896 if (!loongarch_adjust_reloc_bitsfield (input_bfd
, howto
, &reloc_val
))
1897 return bfd_reloc_overflow
;
1899 insn
= (insn
& (uint32_t)howto
->src_mask
)
1900 | ((insn
& (~(uint32_t)howto
->dst_mask
)) | reloc_val
);
1902 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
1904 return bfd_reloc_ok
;
1907 static bfd_reloc_status_type
1908 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
1909 reloc_howto_type
*howto
, bfd_vma value
,
1910 bfd
*input_bfd
, bfd_byte
*contents
)
1912 int64_t opr1
, opr2
, opr3
;
1913 bfd_reloc_status_type r
= bfd_reloc_ok
;
1914 int bits
= bfd_get_reloc_size (howto
) * 8;
1916 switch (ELFNN_R_TYPE (rel
->r_info
))
1918 case R_LARCH_SOP_PUSH_PCREL
:
1919 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1920 case R_LARCH_SOP_PUSH_GPREL
:
1921 case R_LARCH_SOP_PUSH_TLS_TPREL
:
1922 case R_LARCH_SOP_PUSH_TLS_GOT
:
1923 case R_LARCH_SOP_PUSH_TLS_GD
:
1924 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1925 r
= loongarch_push (value
);
1928 case R_LARCH_SOP_PUSH_DUP
:
1929 r
= loongarch_pop (&opr1
);
1930 if (r
== bfd_reloc_ok
)
1932 r
= loongarch_push (opr1
);
1933 if (r
== bfd_reloc_ok
)
1934 r
= loongarch_push (opr1
);
1938 case R_LARCH_SOP_ASSERT
:
1939 r
= loongarch_pop (&opr1
);
1940 if (r
!= bfd_reloc_ok
|| !opr1
)
1941 r
= bfd_reloc_notsupported
;
1944 case R_LARCH_SOP_NOT
:
1945 r
= loongarch_pop (&opr1
);
1946 if (r
== bfd_reloc_ok
)
1947 r
= loongarch_push (!opr1
);
1950 case R_LARCH_SOP_SUB
:
1951 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
1954 case R_LARCH_SOP_SL
:
1955 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
1958 case R_LARCH_SOP_SR
:
1959 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
1962 case R_LARCH_SOP_AND
:
1963 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
1966 case R_LARCH_SOP_ADD
:
1967 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
1970 case R_LARCH_SOP_IF_ELSE
:
1971 r
= loongarch_pop (&opr3
);
1972 if (r
== bfd_reloc_ok
)
1974 r
= loongarch_pop (&opr2
);
1975 if (r
== bfd_reloc_ok
)
1977 r
= loongarch_pop (&opr1
);
1978 if (r
== bfd_reloc_ok
)
1979 r
= loongarch_push (opr1
? opr2
: opr3
);
1984 case R_LARCH_SOP_POP_32_S_10_5
:
1985 case R_LARCH_SOP_POP_32_S_10_12
:
1986 case R_LARCH_SOP_POP_32_S_10_16
:
1987 case R_LARCH_SOP_POP_32_S_10_16_S2
:
1988 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
1989 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
1990 case R_LARCH_SOP_POP_32_S_5_20
:
1991 case R_LARCH_SOP_POP_32_U_10_12
:
1992 case R_LARCH_SOP_POP_32_U
:
1993 r
= loongarch_pop (&opr1
);
1994 if (r
!= bfd_reloc_ok
)
1996 r
= loongarch_check_offset (rel
, input_section
);
1997 if (r
!= bfd_reloc_ok
)
2000 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2002 contents
, (bfd_vma
)opr1
);
2005 case R_LARCH_TLS_DTPREL32
:
2007 case R_LARCH_TLS_DTPREL64
:
2009 r
= loongarch_check_offset (rel
, input_section
);
2010 if (r
!= bfd_reloc_ok
)
2013 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
2016 /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2017 Because set/sub reloc pair not support multi-thread. While add/sub
2018 reloc pair process order not affect the final result.
2020 For add/sub reloc, the original value will be involved in the
2021 calculation. In order not to add/sub extra value, we write 0 to symbol
2022 address at assembly time.
2024 add/sub reloc bits determined by the value after symbol subtraction,
2027 add/sub reloc save part of the symbol value, so we only need to
2028 save howto->dst_mask bits. */
2032 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2033 contents
+ rel
->r_offset
);
2034 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2035 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2040 /* Not need to read the original value, just write the new value. */
2052 /* Because add/sub reloc is processed separately,
2053 so the high bits is invalid. */
2054 bfd_vma word
= value
& howto
->dst_mask
;
2055 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2060 case R_LARCH_ADD_ULEB128
:
2061 case R_LARCH_SUB_ULEB128
:
2063 unsigned int len
= 0;
2064 /* Before write uleb128, first read it to get it's length. */
2065 _bfd_read_unsigned_leb128 (input_bfd
, contents
+ rel
->r_offset
, &len
);
2066 loongarch_write_unsigned_leb128 (contents
+ rel
->r_offset
, len
, value
);
2071 /* For eh_frame and debug info. */
2072 case R_LARCH_32_PCREL
:
2073 case R_LARCH_64_PCREL
:
2075 value
-= sec_addr (input_section
) + rel
->r_offset
;
2076 value
+= rel
->r_addend
;
2077 bfd_vma word
= bfd_get (howto
->bitsize
, input_bfd
,
2078 contents
+ rel
->r_offset
);
2079 word
= (word
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2080 bfd_put (howto
->bitsize
, input_bfd
, word
, contents
+ rel
->r_offset
);
2086 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
2090 case R_LARCH_ABS_HI20
:
2091 case R_LARCH_ABS_LO12
:
2092 case R_LARCH_ABS64_LO20
:
2093 case R_LARCH_ABS64_HI12
:
2094 case R_LARCH_PCALA_HI20
:
2095 case R_LARCH_PCALA_LO12
:
2096 case R_LARCH_PCALA64_LO20
:
2097 case R_LARCH_PCALA64_HI12
:
2098 case R_LARCH_GOT_PC_HI20
:
2099 case R_LARCH_GOT_PC_LO12
:
2100 case R_LARCH_GOT64_PC_LO20
:
2101 case R_LARCH_GOT64_PC_HI12
:
2102 case R_LARCH_GOT_HI20
:
2103 case R_LARCH_GOT_LO12
:
2104 case R_LARCH_GOT64_LO20
:
2105 case R_LARCH_GOT64_HI12
:
2106 case R_LARCH_TLS_LE_HI20
:
2107 case R_LARCH_TLS_LE_LO12
:
2108 case R_LARCH_TLS_LE64_LO20
:
2109 case R_LARCH_TLS_LE64_HI12
:
2110 case R_LARCH_TLS_IE_PC_HI20
:
2111 case R_LARCH_TLS_IE_PC_LO12
:
2112 case R_LARCH_TLS_IE64_PC_LO20
:
2113 case R_LARCH_TLS_IE64_PC_HI12
:
2114 case R_LARCH_TLS_IE_HI20
:
2115 case R_LARCH_TLS_IE_LO12
:
2116 case R_LARCH_TLS_IE64_LO20
:
2117 case R_LARCH_TLS_IE64_HI12
:
2118 case R_LARCH_TLS_LD_PC_HI20
:
2119 case R_LARCH_TLS_LD_HI20
:
2120 case R_LARCH_TLS_GD_PC_HI20
:
2121 case R_LARCH_TLS_GD_HI20
:
2122 case R_LARCH_PCREL20_S2
:
2123 r
= loongarch_check_offset (rel
, input_section
);
2124 if (r
!= bfd_reloc_ok
)
2127 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
2136 r
= bfd_reloc_notsupported
;
2141 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2149 Elf_Internal_Sym
*sym
;
2150 struct elf_link_hash_entry
*h
;
2153 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
2154 static size_t larch_reloc_queue_head
= 0;
2155 static size_t larch_reloc_queue_tail
= 0;
2158 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
2159 Elf_Internal_Sym
*sym
)
2161 const char *ret
= NULL
;
2163 ret
= bfd_elf_string_from_elf_section (input_bfd
,
2164 elf_symtab_hdr (input_bfd
).sh_link
,
2167 ret
= h
->root
.root
.string
;
2169 if (ret
== NULL
|| *ret
== '\0')
2175 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
2176 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
2177 struct elf_link_hash_entry
*h
, bfd_vma addend
)
2179 if ((larch_reloc_queue_head
== 0
2180 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
2181 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
2182 larch_reloc_queue_head
=
2183 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2184 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
2185 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
2186 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
2187 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
2188 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
2189 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
2190 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
2191 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
2192 larch_reloc_queue_tail
=
2193 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2197 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
2199 size_t i
= larch_reloc_queue_head
;
2201 asection
*section
= NULL
;
2202 bfd_vma r_offset
= 0;
2204 p ("Dump relocate record:\n");
2205 p ("stack top\t\trelocation name\t\tsymbol");
2206 while (i
!= larch_reloc_queue_tail
)
2208 if (a_bfd
!= larch_reloc_queue
[i
].bfd
2209 || section
!= larch_reloc_queue
[i
].section
2210 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
2212 a_bfd
= larch_reloc_queue
[i
].bfd
;
2213 section
= larch_reloc_queue
[i
].section
;
2214 r_offset
= larch_reloc_queue
[i
].r_offset
;
2215 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
2216 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
2220 inited
= 1, p ("...\n");
2222 reloc_howto_type
*howto
=
2223 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
2224 larch_reloc_queue
[i
].r_type
);
2225 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
2226 howto
? howto
->name
: "<unknown reloc>",
2227 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
2228 larch_reloc_queue
[i
].sym
));
2230 long addend
= larch_reloc_queue
[i
].addend
;
2232 p (" - %ld", -addend
);
2233 else if (0 < addend
)
2234 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
2237 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
2240 "-- Record dump end --\n\n");
2244 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
2246 asection
*input_section
,
2247 Elf_Internal_Rela
*rel
,
2248 reloc_howto_type
*howto
,
2249 bfd_reloc_status_type rtype
,
2257 /* 'dangerous' means we do it but can't promise it's ok
2258 'unsupport' means out of ability of relocation type
2259 'undefined' means we can't deal with the undefined symbol. */
2260 case bfd_reloc_undefined
:
2261 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
2262 rel
->r_offset
, true);
2263 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2264 input_bfd
, input_section
, rel
->r_offset
,
2266 is_undefweak
? "[undefweak] " : "", name
, msg
);
2268 case bfd_reloc_dangerous
:
2269 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2270 input_bfd
, input_section
, rel
->r_offset
,
2272 is_undefweak
? "[undefweak] " : "", name
, msg
);
2275 case bfd_reloc_notsupported
:
2276 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2277 input_bfd
, input_section
, rel
->r_offset
,
2279 is_undefweak
? "[undefweak] " : "", name
, msg
);
2287 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2288 hi20 immediate need to add 0x1.
2289 For example: pc 0x120000000, symbol 0x120000812
2290 lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2291 hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2292 (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2295 pcalau12i $t0, hi20 (0x1)
2296 $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2297 addi.d $t0, $t0, lo12 (0x812)
2298 $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2299 = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2301 Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2303 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */
2304 #define RELOCATE_CALC_PC32_HI20(relocation, pc) \
2306 bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2307 relocation = (relocation & ~(bfd_vma)0xfff) \
2308 - (pc & ~(bfd_vma)0xfff); \
2310 relocation += 0x1000; \
2313 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2314 offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2316 lo12: 0x1812348ffff812 & 0xfff = 0x812
2317 hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2318 lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2321 pcalau12i $t1, hi20 (0x80000)
2322 $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2323 = 0x11000010000100 + 0xffffffff80000000
2325 addi.d $t0, $zero, lo12 (0x812)
2326 $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2327 lo20 need to sub 0x1)
2328 lu32i.d $t0, lo20 (0x71234)
2329 $t0 = {0x71234, 0xfffff812}
2331 lu52i.d $t0, hi12 (0x0)
2332 $t0 = {0x0, 0x71234fffff812}
2335 $t1 = 0x10ffff90000000 + 0x71234fffff812
2336 = 0x1812348ffff812. */
2337 #define RELOCATE_CALC_PC64_HI32(relocation, pc) \
2339 bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2340 relocation = (relocation & ~(bfd_vma)0xfff) \
2341 - (pc & ~(bfd_vma)0xfff); \
2343 relocation += (0x1000 - 0x100000000); \
2344 if (relocation & 0x80000000) \
2345 relocation += 0x100000000; \
2349 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
2350 bfd
*input_bfd
, asection
*input_section
,
2351 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
2352 Elf_Internal_Sym
*local_syms
,
2353 asection
**local_sections
)
2355 Elf_Internal_Rela
*rel
;
2356 Elf_Internal_Rela
*relend
;
2358 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
2359 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
2360 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2361 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
2362 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
2363 bool is_pic
= bfd_link_pic (info
);
2364 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
2365 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
2366 asection
*got
= htab
->elf
.sgot
;
2368 relend
= relocs
+ input_section
->reloc_count
;
2369 for (rel
= relocs
; rel
< relend
; rel
++)
2371 int r_type
= ELFNN_R_TYPE (rel
->r_info
);
2372 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2373 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
2374 reloc_howto_type
*howto
= NULL
;
2375 asection
*sec
= NULL
;
2376 Elf_Internal_Sym
*sym
= NULL
;
2377 struct elf_link_hash_entry
*h
= NULL
;
2379 bfd_reloc_status_type r
= bfd_reloc_ok
;
2380 bool is_ie
, is_undefweak
, unresolved_reloc
, defined_local
;
2381 bool resolved_local
, resolved_dynly
, resolved_to_const
;
2383 bfd_vma relocation
, off
, ie_off
;
2386 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
2387 if (howto
== NULL
|| r_type
== R_LARCH_GNU_VTINHERIT
2388 || r_type
== R_LARCH_GNU_VTENTRY
)
2391 /* This is a final link. */
2392 if (r_symndx
< symtab_hdr
->sh_info
)
2394 is_undefweak
= false;
2395 unresolved_reloc
= false;
2396 sym
= local_syms
+ r_symndx
;
2397 sec
= local_sections
[r_symndx
];
2398 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
2400 /* Relocate against local STT_GNU_IFUNC symbol. */
2401 if (!bfd_link_relocatable (info
)
2402 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2404 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
2409 /* Set STT_GNU_IFUNC symbol value. */
2410 h
->root
.u
.def
.value
= sym
->st_value
;
2411 h
->root
.u
.def
.section
= sec
;
2413 defined_local
= true;
2414 resolved_local
= true;
2415 resolved_dynly
= false;
2416 resolved_to_const
= false;
2418 /* Calc in funtion elf_link_input_bfd,
2419 * if #define elf_backend_rela_normal to 1. */
2420 if (bfd_link_relocatable (info
)
2421 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2426 bool warned
, ignored
;
2428 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2429 r_symndx
, symtab_hdr
, sym_hashes
,
2431 unresolved_reloc
, warned
, ignored
);
2432 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2434 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2435 symbol. And 'dynamic_undefined_weak' specify what to do when
2436 meeting undefweak. */
2438 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
2440 defined_local
= false;
2441 resolved_local
= false;
2442 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
2443 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
2444 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
2448 /* Symbol undefined offen means failed already. I don't know why
2449 'warned' here but I guess it want to continue relocating as if
2450 no error occures to find other errors as more as possible. */
2452 /* To avoid generating warning messages about truncated
2453 relocations, set the relocation's address to be the same as
2454 the start of this section. */
2455 relocation
= (input_section
->output_section
2456 ? input_section
->output_section
->vma
2459 defined_local
= relocation
!= 0;
2460 resolved_local
= defined_local
;
2461 resolved_to_const
= !resolved_local
;
2462 resolved_dynly
= false;
2466 defined_local
= !unresolved_reloc
&& !ignored
;
2468 defined_local
&& SYMBOL_REFERENCES_LOCAL (info
, h
);
2469 resolved_dynly
= !resolved_local
;
2470 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
2474 name
= loongarch_sym_name (input_bfd
, h
, sym
);
2476 if (sec
!= NULL
&& discarded_section (sec
))
2477 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
2478 1, relend
, howto
, 0, contents
);
2480 if (bfd_link_relocatable (info
))
2483 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2484 from removed linkonce sections, or sections discarded by a linker
2485 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2486 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
2488 defined_local
= false;
2489 resolved_local
= false;
2490 resolved_dynly
= false;
2491 resolved_to_const
= true;
2494 /* The ifunc reference generate plt. */
2495 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
2497 defined_local
= true;
2498 resolved_local
= true;
2499 resolved_dynly
= false;
2500 resolved_to_const
= false;
2501 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2504 unresolved_reloc
= resolved_dynly
;
2506 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
2508 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2510 BFD_ASSERT (!resolved_local
|| defined_local
);
2515 case R_LARCH_MARK_PCREL
:
2516 case R_LARCH_MARK_LA
:
2518 r
= bfd_reloc_continue
;
2519 unresolved_reloc
= false;
2524 if (resolved_dynly
|| (is_pic
&& resolved_local
))
2526 Elf_Internal_Rela outrel
;
2528 /* When generating a shared object, these relocations are copied
2529 into the output file to be resolved at run time. */
2531 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2535 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2536 && (input_section
->flags
& SEC_ALLOC
));
2538 outrel
.r_offset
+= sec_addr (input_section
);
2540 /* A pointer point to a ifunc symbol. */
2541 if (h
&& h
->type
== STT_GNU_IFUNC
)
2543 if (h
->dynindx
== -1)
2545 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2546 outrel
.r_addend
= (h
->root
.u
.def
.value
2547 + h
->root
.u
.def
.section
->output_section
->vma
2548 + h
->root
.u
.def
.section
->output_offset
);
2552 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2553 outrel
.r_addend
= 0;
2556 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
2559 if (htab
->elf
.splt
!= NULL
)
2560 sreloc
= htab
->elf
.srelgot
;
2562 sreloc
= htab
->elf
.irelplt
;
2567 if (bfd_link_pic (info
))
2568 sreloc
= htab
->elf
.irelifunc
;
2569 else if (htab
->elf
.splt
!= NULL
)
2570 sreloc
= htab
->elf
.srelgot
;
2572 sreloc
= htab
->elf
.irelplt
;
2575 else if (resolved_dynly
)
2577 if (h
->dynindx
== -1)
2579 if (h
->root
.type
== bfd_link_hash_undefined
)
2580 (*info
->callbacks
->undefined_symbol
)
2581 (info
, name
, input_bfd
, input_section
,
2582 rel
->r_offset
, true);
2584 outrel
.r_info
= ELFNN_R_INFO (0, r_type
);
2587 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2589 outrel
.r_addend
= rel
->r_addend
;
2593 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2594 outrel
.r_addend
= relocation
+ rel
->r_addend
;
2597 /* No alloc space of func allocate_dynrelocs. */
2598 if (unresolved_reloc
2599 && !(h
&& (h
->is_weakalias
|| !h
->dyn_relocs
)))
2600 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2603 relocation
+= rel
->r_addend
;
2613 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2614 contents
+ rel
->r_offset
);
2615 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2626 bfd_vma old_value
= bfd_get (howto
->bitsize
, input_bfd
,
2627 contents
+ rel
->r_offset
);
2628 relocation
= old_value
- relocation
- rel
->r_addend
;
2632 case R_LARCH_ADD_ULEB128
:
2633 case R_LARCH_SUB_ULEB128
:
2635 /* Get the value and length of the uleb128 data. */
2636 unsigned int len
= 0;
2637 bfd_vma old_value
= _bfd_read_unsigned_leb128 (input_bfd
,
2638 contents
+ rel
->r_offset
, &len
);
2640 if (R_LARCH_ADD_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2641 relocation
= old_value
+ relocation
+ rel
->r_addend
;
2642 else if (R_LARCH_SUB_ULEB128
== ELFNN_R_TYPE (rel
->r_info
))
2643 relocation
= old_value
- relocation
- rel
->r_addend
;
2645 bfd_vma mask
= (1 << (7 * len
)) - 1;
2650 case R_LARCH_TLS_DTPREL32
:
2651 case R_LARCH_TLS_DTPREL64
:
2654 Elf_Internal_Rela outrel
;
2656 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2659 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2660 && (input_section
->flags
& SEC_ALLOC
));
2661 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2662 outrel
.r_offset
+= sec_addr (input_section
);
2663 outrel
.r_addend
= rel
->r_addend
;
2664 if (unresolved_reloc
)
2665 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2669 if (resolved_to_const
)
2670 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
2672 bfd_reloc_notsupported
,
2677 if (!elf_hash_table (info
)->tls_sec
)
2679 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2680 input_section
, rel
, howto
, bfd_reloc_notsupported
,
2681 is_undefweak
, name
, "TLS section not be created");
2684 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2688 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2689 input_section
, rel
, howto
, bfd_reloc_undefined
,
2691 "TLS LE just can be resolved local only.");
2696 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2699 if (!elf_hash_table (info
)->tls_sec
)
2700 fatal
= (loongarch_reloc_is_fatal
2701 (info
, input_bfd
, input_section
, rel
, howto
,
2702 bfd_reloc_notsupported
, is_undefweak
, name
,
2703 "TLS section not be created"));
2705 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2708 fatal
= (loongarch_reloc_is_fatal
2709 (info
, input_bfd
, input_section
, rel
, howto
,
2710 bfd_reloc_undefined
, is_undefweak
, name
,
2711 "TLS LE just can be resolved local only."));
2714 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2718 fatal
= (loongarch_reloc_is_fatal
2719 (info
, input_bfd
, input_section
, rel
, howto
,
2720 bfd_reloc_dangerous
, is_undefweak
, name
,
2721 "Someone require us to resolve undefweak "
2722 "symbol dynamically. \n"
2723 "But this reloc can't be done. "
2724 "I think I can't throw error "
2726 "so I resolved it to 0. "
2727 "I suggest to re-compile with '-fpic'."));
2730 unresolved_reloc
= false;
2734 if (resolved_to_const
)
2736 relocation
+= rel
->r_addend
;
2742 fatal
= (loongarch_reloc_is_fatal
2743 (info
, input_bfd
, input_section
, rel
, howto
,
2744 bfd_reloc_notsupported
, is_undefweak
, name
,
2745 "Under PIC we don't know load address. Re-compile "
2752 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
2754 fatal
= (loongarch_reloc_is_fatal
2755 (info
, input_bfd
, input_section
, rel
, howto
,
2756 bfd_reloc_undefined
, is_undefweak
, name
,
2757 "Can't be resolved dynamically. Try to re-compile "
2762 if (rel
->r_addend
!= 0)
2764 fatal
= (loongarch_reloc_is_fatal
2765 (info
, input_bfd
, input_section
, rel
, howto
,
2766 bfd_reloc_notsupported
, is_undefweak
, name
,
2767 "Shouldn't be with r_addend."));
2771 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2772 unresolved_reloc
= false;
2778 relocation
+= rel
->r_addend
;
2784 case R_LARCH_SOP_PUSH_PCREL
:
2785 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2786 unresolved_reloc
= false;
2794 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
2797 fatal
= (loongarch_reloc_is_fatal
2798 (info
, input_bfd
, input_section
, rel
, howto
,
2799 bfd_reloc_dangerous
, is_undefweak
, name
,
2800 "Undefweak need to be resolved dynamically, "
2801 "but PLT stub doesn't represent."));
2806 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
2808 fatal
= (loongarch_reloc_is_fatal
2809 (info
, input_bfd
, input_section
, rel
, howto
,
2810 bfd_reloc_undefined
, is_undefweak
, name
,
2811 "PLT stub does not represent and "
2812 "symbol not defined."));
2818 else /* if (resolved_dynly) */
2820 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
2821 fatal
= (loongarch_reloc_is_fatal
2822 (info
, input_bfd
, input_section
, rel
, howto
,
2823 bfd_reloc_dangerous
, is_undefweak
, name
,
2824 "Internal: PLT stub doesn't represent. "
2825 "Resolve it with pcrel"));
2832 if ((i
& 1) == 0 && defined_local
)
2835 relocation
+= rel
->r_addend
;
2839 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
2841 if (rel
->r_addend
!= 0)
2843 fatal
= (loongarch_reloc_is_fatal
2844 (info
, input_bfd
, input_section
, rel
, howto
,
2845 bfd_reloc_notsupported
, is_undefweak
, name
,
2846 "PLT shouldn't be with r_addend."));
2849 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
2855 case R_LARCH_SOP_PUSH_GPREL
:
2856 unresolved_reloc
= false;
2858 if (rel
->r_addend
!= 0)
2860 fatal
= (loongarch_reloc_is_fatal
2861 (info
, input_bfd
, input_section
, rel
, howto
,
2862 bfd_reloc_notsupported
, is_undefweak
, name
,
2863 "Shouldn't be with r_addend."));
2869 off
= h
->got
.offset
& (~1);
2871 if (h
->got
.offset
== MINUS_ONE
&& h
->type
!= STT_GNU_IFUNC
)
2873 fatal
= (loongarch_reloc_is_fatal
2874 (info
, input_bfd
, input_section
, rel
, howto
,
2875 bfd_reloc_notsupported
, is_undefweak
, name
,
2876 "Internal: GOT entry doesn't represent."));
2880 /* Hidden symbol not has .got entry, only .got.plt entry
2881 so gprel is (plt - got). */
2882 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
2884 if (h
->plt
.offset
== (bfd_vma
) -1)
2889 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
2890 off
= plt_index
* GOT_ENTRY_SIZE
;
2892 if (htab
->elf
.splt
!= NULL
)
2894 /* Section .plt header is 2 times of plt entry. */
2895 off
= sec_addr (htab
->elf
.sgotplt
) + off
2896 - sec_addr (htab
->elf
.sgot
);
2900 /* Section iplt not has plt header. */
2901 off
= sec_addr (htab
->elf
.igotplt
) + off
2902 - sec_addr (htab
->elf
.sgot
);
2906 if ((h
->got
.offset
& 1) == 0)
2908 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
2909 bfd_link_pic (info
), h
)
2910 && ((bfd_link_pic (info
)
2911 && SYMBOL_REFERENCES_LOCAL (info
, h
))))
2913 /* This is actually a static link, or it is a
2914 -Bsymbolic link and the symbol is defined
2915 locally, or the symbol was forced to be local
2916 because of a version file. We must initialize
2917 this entry in the global offset table. Since the
2918 offset must always be a multiple of the word size,
2919 we use the least significant bit to record whether
2920 we have initialized it already.
2922 When doing a dynamic link, we create a rela.got
2923 relocation entry to initialize the value. This
2924 is done in the finish_dynamic_symbol routine. */
2928 fatal
= (loongarch_reloc_is_fatal
2929 (info
, input_bfd
, input_section
, rel
, howto
,
2930 bfd_reloc_dangerous
, is_undefweak
, name
,
2931 "Internal: here shouldn't dynamic."));
2934 if (!(defined_local
|| resolved_to_const
))
2936 fatal
= (loongarch_reloc_is_fatal
2937 (info
, input_bfd
, input_section
, rel
, howto
,
2938 bfd_reloc_undefined
, is_undefweak
, name
,
2944 Elf_Internal_Rela outrel
;
2945 /* We need to generate a R_LARCH_RELATIVE reloc
2946 for the dynamic linker. */
2947 s
= htab
->elf
.srelgot
;
2950 fatal
= loongarch_reloc_is_fatal
2952 input_section
, rel
, howto
,
2953 bfd_reloc_notsupported
, is_undefweak
, name
,
2954 "Internal: '.rel.got' not represent");
2958 outrel
.r_offset
= sec_addr (got
) + off
;
2959 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2960 outrel
.r_addend
= relocation
; /* Link-time addr. */
2961 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
2963 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
2969 if (!local_got_offsets
)
2971 fatal
= (loongarch_reloc_is_fatal
2972 (info
, input_bfd
, input_section
, rel
, howto
,
2973 bfd_reloc_notsupported
, is_undefweak
, name
,
2974 "Internal: local got offsets not reporesent."));
2978 off
= local_got_offsets
[r_symndx
] & (~1);
2980 if (local_got_offsets
[r_symndx
] == MINUS_ONE
)
2982 fatal
= (loongarch_reloc_is_fatal
2983 (info
, input_bfd
, input_section
, rel
, howto
,
2984 bfd_reloc_notsupported
, is_undefweak
, name
,
2985 "Internal: GOT entry doesn't represent."));
2989 /* The offset must always be a multiple of the word size.
2990 So, we can use the least significant bit to record
2991 whether we have already processed this entry. */
2992 if ((local_got_offsets
[r_symndx
] & 1) == 0)
2997 Elf_Internal_Rela outrel
;
2998 /* We need to generate a R_LARCH_RELATIVE reloc
2999 for the dynamic linker. */
3000 s
= htab
->elf
.srelgot
;
3003 fatal
= (loongarch_reloc_is_fatal
3004 (info
, input_bfd
, input_section
, rel
, howto
,
3005 bfd_reloc_notsupported
, is_undefweak
, name
,
3006 "Internal: '.rel.got' not represent"));
3010 outrel
.r_offset
= sec_addr (got
) + off
;
3011 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3012 outrel
.r_addend
= relocation
; /* Link-time addr. */
3013 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
3016 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
3017 local_got_offsets
[r_symndx
] |= 1;
3024 case R_LARCH_SOP_PUSH_TLS_GOT
:
3025 case R_LARCH_SOP_PUSH_TLS_GD
:
3027 unresolved_reloc
= false;
3028 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
3031 bfd_vma got_off
= 0;
3034 got_off
= h
->got
.offset
;
3039 got_off
= local_got_offsets
[r_symndx
];
3040 local_got_offsets
[r_symndx
] |= 1;
3043 BFD_ASSERT (got_off
!= MINUS_ONE
);
3046 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3047 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3048 ie_off
= 2 * GOT_ENTRY_SIZE
;
3050 if ((got_off
& 1) == 0)
3052 Elf_Internal_Rela rela
;
3053 asection
*srel
= htab
->elf
.srelgot
;
3054 bfd_vma tls_block_off
= 0;
3056 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3058 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3059 tls_block_off
= relocation
3060 - elf_hash_table (info
)->tls_sec
->vma
;
3063 if (tls_type
& GOT_TLS_GD
)
3065 rela
.r_offset
= sec_addr (got
) + got_off
;
3067 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3069 /* Local sym, used in exec, set module id 1. */
3070 if (bfd_link_executable (info
))
3071 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3074 rela
.r_info
= ELFNN_R_INFO (0,
3075 R_LARCH_TLS_DTPMODNN
);
3076 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3079 bfd_put_NN (output_bfd
, tls_block_off
,
3080 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3082 /* Dynamic resolved. */
3085 /* Dynamic relocate module id. */
3086 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3087 R_LARCH_TLS_DTPMODNN
);
3088 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3090 /* Dynamic relocate offset of block. */
3091 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3092 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3093 R_LARCH_TLS_DTPRELNN
);
3094 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3097 if (tls_type
& GOT_TLS_IE
)
3099 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3100 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3102 /* Local sym, used in exec, set module id 1. */
3103 if (!bfd_link_executable (info
))
3105 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3106 rela
.r_addend
= tls_block_off
;
3107 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3110 bfd_put_NN (output_bfd
, tls_block_off
,
3111 got
->contents
+ got_off
+ ie_off
);
3113 /* Dynamic resolved. */
3116 /* Dynamic relocate offset of block. */
3117 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3118 R_LARCH_TLS_TPRELNN
);
3120 loongarch_elf_append_rela (output_bfd
, srel
, &rela
);
3125 relocation
= (got_off
& (~(bfd_vma
)1)) + (is_ie
? ie_off
: 0);
3129 /* New reloc types. */
3133 unresolved_reloc
= false;
3142 relocation
+= rel
->r_addend
;
3144 else if (resolved_dynly
)
3147 && (h
->plt
.offset
!= MINUS_ONE
3148 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3149 && rel
->r_addend
== 0);
3150 if (h
&& h
->plt
.offset
== MINUS_ONE
3151 && ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
3154 relocation
+= rel
->r_addend
;
3157 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
3162 case R_LARCH_ABS_HI20
:
3163 case R_LARCH_ABS_LO12
:
3164 case R_LARCH_ABS64_LO20
:
3165 case R_LARCH_ABS64_HI12
:
3166 BFD_ASSERT (!is_pic
);
3170 BFD_ASSERT (resolved_dynly
);
3174 else if (resolved_to_const
|| resolved_local
)
3176 relocation
+= rel
->r_addend
;
3178 else if (resolved_dynly
)
3180 unresolved_reloc
= false;
3181 BFD_ASSERT ((plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
)
3182 && rel
->r_addend
== 0);
3183 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3188 case R_LARCH_PCREL20_S2
:
3189 unresolved_reloc
= false;
3190 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3191 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3193 relocation
+= rel
->r_addend
;
3197 case R_LARCH_PCALA_HI20
:
3198 unresolved_reloc
= false;
3199 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3200 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3202 relocation
+= rel
->r_addend
;
3204 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3208 case R_LARCH_PCALA_LO12
:
3209 /* Not support if sym_addr in 2k page edge.
3210 pcalau12i pc_hi20 (sym_addr)
3211 ld.w/d pc_lo12 (sym_addr)
3212 ld.w/d pc_lo12 (sym_addr + x)
3214 can not calc correct address
3215 if sym_addr < 0x800 && sym_addr + x >= 0x800. */
3217 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3218 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3220 relocation
+= rel
->r_addend
;
3222 /* For 2G jump, generate pcalau12i, jirl. */
3223 /* If use jirl, turns to R_LARCH_B16. */
3224 uint32_t insn
= bfd_get (32, input_bfd
, contents
+ rel
->r_offset
);
3225 if ((insn
& 0x4c000000) == 0x4c000000)
3227 relocation
&= 0xfff;
3228 /* Signed extend. */
3229 relocation
= (relocation
^ 0x800) - 0x800;
3231 rel
->r_info
= ELFNN_R_INFO (r_symndx
, R_LARCH_B16
);
3232 howto
= loongarch_elf_rtype_to_howto (input_bfd
, R_LARCH_B16
);
3236 case R_LARCH_PCALA64_LO20
:
3237 case R_LARCH_PCALA64_HI12
:
3238 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
3239 relocation
= sec_addr (plt
) + h
->plt
.offset
;
3241 relocation
+= rel
->r_addend
;
3243 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3247 case R_LARCH_GOT_PC_HI20
:
3248 case R_LARCH_GOT_HI20
:
3249 /* Calc got offset. */
3251 unresolved_reloc
= false;
3252 BFD_ASSERT (rel
->r_addend
== 0);
3254 bfd_vma got_off
= 0;
3257 /* GOT ref or ifunc. */
3258 BFD_ASSERT (h
->got
.offset
!= MINUS_ONE
3259 || h
->type
== STT_GNU_IFUNC
);
3261 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3262 /* Hidden symbol not has got entry,
3263 * only got.plt entry so it is (plt - got). */
3264 if (h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3267 if (htab
->elf
.splt
!= NULL
)
3269 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
)
3271 got_off
= sec_addr (htab
->elf
.sgotplt
)
3272 + GOTPLT_HEADER_SIZE
3273 + (idx
* GOT_ENTRY_SIZE
)
3274 - sec_addr (htab
->elf
.sgot
);
3278 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3279 got_off
= sec_addr (htab
->elf
.sgotplt
)
3280 + (idx
* GOT_ENTRY_SIZE
)
3281 - sec_addr (htab
->elf
.sgot
);
3285 if ((h
->got
.offset
& 1) == 0)
3287 /* We need to generate a R_LARCH_RELATIVE reloc once
3288 * in loongarch_elf_finish_dynamic_symbol or now,
3289 * call finish_dyn && nopic
3290 * or !call finish_dyn && pic. */
3291 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
,
3292 bfd_link_pic (info
),
3294 && bfd_link_pic (info
)
3295 && SYMBOL_REFERENCES_LOCAL (info
, h
))
3297 Elf_Internal_Rela rela
;
3298 rela
.r_offset
= sec_addr (got
) + got_off
;
3299 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3300 rela
.r_addend
= relocation
;
3301 loongarch_elf_append_rela (output_bfd
,
3302 htab
->elf
.srelgot
, &rela
);
3305 bfd_put_NN (output_bfd
, relocation
,
3306 got
->contents
+ got_off
);
3311 BFD_ASSERT (local_got_offsets
3312 && local_got_offsets
[r_symndx
] != MINUS_ONE
);
3314 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3315 if ((local_got_offsets
[r_symndx
] & 1) == 0)
3317 if (bfd_link_pic (info
))
3319 Elf_Internal_Rela rela
;
3320 rela
.r_offset
= sec_addr (got
) + got_off
;
3321 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
3322 rela
.r_addend
= relocation
;
3323 loongarch_elf_append_rela (output_bfd
,
3324 htab
->elf
.srelgot
, &rela
);
3326 local_got_offsets
[r_symndx
] |= 1;
3328 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ got_off
);
3331 relocation
= got_off
+ sec_addr (got
);
3334 if (r_type
== R_LARCH_GOT_PC_HI20
)
3335 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3339 case R_LARCH_GOT_PC_LO12
:
3340 case R_LARCH_GOT64_PC_LO20
:
3341 case R_LARCH_GOT64_PC_HI12
:
3342 case R_LARCH_GOT_LO12
:
3343 case R_LARCH_GOT64_LO20
:
3344 case R_LARCH_GOT64_HI12
:
3346 unresolved_reloc
= false;
3349 got_off
= h
->got
.offset
& (~(bfd_vma
)1);
3351 got_off
= local_got_offsets
[r_symndx
] & (~(bfd_vma
)1);
3353 if (h
&& h
->got
.offset
== MINUS_ONE
&& h
->type
== STT_GNU_IFUNC
)
3356 if (htab
->elf
.splt
!= NULL
)
3357 idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
3359 idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
3361 got_off
= sec_addr (htab
->elf
.sgotplt
)
3362 + GOTPLT_HEADER_SIZE
3363 + (idx
* GOT_ENTRY_SIZE
)
3364 - sec_addr (htab
->elf
.sgot
);
3367 relocation
= got_off
+ sec_addr (got
);
3370 if (r_type
== R_LARCH_GOT64_PC_HI12
3371 || r_type
== R_LARCH_GOT64_PC_LO20
)
3372 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3376 case R_LARCH_TLS_LE_HI20
:
3377 case R_LARCH_TLS_LE_LO12
:
3378 case R_LARCH_TLS_LE64_LO20
:
3379 case R_LARCH_TLS_LE64_HI12
:
3380 BFD_ASSERT (resolved_local
&& elf_hash_table (info
)->tls_sec
);
3382 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
3385 /* TLS IE LD/GD process separately is troublesome.
3386 When a symbol is both ie and LD/GD, h->got.off |= 1
3387 make only one type be relocated. We must use
3388 h->got.offset |= 1 and h->got.offset |= 2
3389 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
3390 (IE LD/GD and reusable GOT reloc) must change to
3391 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3393 Now, LD and GD is both GOT_TLS_GD type, LD seems to
3395 case R_LARCH_TLS_IE_PC_HI20
:
3396 case R_LARCH_TLS_IE_HI20
:
3397 case R_LARCH_TLS_LD_PC_HI20
:
3398 case R_LARCH_TLS_LD_HI20
:
3399 case R_LARCH_TLS_GD_PC_HI20
:
3400 case R_LARCH_TLS_GD_HI20
:
3401 BFD_ASSERT (rel
->r_addend
== 0);
3402 unresolved_reloc
= false;
3404 if (r_type
== R_LARCH_TLS_IE_PC_HI20
3405 || r_type
== R_LARCH_TLS_IE_HI20
)
3408 bfd_vma got_off
= 0;
3411 got_off
= h
->got
.offset
;
3416 got_off
= local_got_offsets
[r_symndx
];
3417 local_got_offsets
[r_symndx
] |= 1;
3420 BFD_ASSERT (got_off
!= MINUS_ONE
);
3423 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3424 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3425 ie_off
= 2 * GOT_ENTRY_SIZE
;
3427 if ((got_off
& 1) == 0)
3429 Elf_Internal_Rela rela
;
3430 asection
*relgot
= htab
->elf
.srelgot
;
3431 bfd_vma tls_block_off
= 0;
3433 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3435 BFD_ASSERT (elf_hash_table (info
)->tls_sec
);
3436 tls_block_off
= relocation
3437 - elf_hash_table (info
)->tls_sec
->vma
;
3440 if (tls_type
& GOT_TLS_GD
)
3442 rela
.r_offset
= sec_addr (got
) + got_off
;
3444 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3446 /* Local sym, used in exec, set module id 1. */
3447 if (bfd_link_executable (info
))
3448 bfd_put_NN (output_bfd
, 1, got
->contents
+ got_off
);
3451 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN
);
3452 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3455 bfd_put_NN (output_bfd
, tls_block_off
,
3456 got
->contents
+ got_off
+ GOT_ENTRY_SIZE
);
3458 /* Dynamic resolved. */
3461 /* Dynamic relocate module id. */
3462 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3463 R_LARCH_TLS_DTPMODNN
);
3464 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3466 /* Dynamic relocate offset of block. */
3467 rela
.r_offset
+= GOT_ENTRY_SIZE
;
3468 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3469 R_LARCH_TLS_DTPRELNN
);
3470 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3473 if (tls_type
& GOT_TLS_IE
)
3475 rela
.r_offset
= sec_addr (got
) + got_off
+ ie_off
;
3476 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3478 /* Local sym, used in exec, set module id 1. */
3479 if (!bfd_link_executable (info
))
3481 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
3482 rela
.r_addend
= tls_block_off
;
3483 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3486 bfd_put_NN (output_bfd
, tls_block_off
,
3487 got
->contents
+ got_off
+ ie_off
);
3489 /* Dynamic resolved. */
3492 /* Dynamic relocate offset of block. */
3493 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
3494 R_LARCH_TLS_TPRELNN
);
3496 loongarch_elf_append_rela (output_bfd
, relgot
, &rela
);
3500 relocation
= (got_off
& (~(bfd_vma
)1)) + sec_addr (got
)
3501 + (is_ie
? ie_off
: 0);
3503 if (r_type
== R_LARCH_TLS_LD_PC_HI20
3504 || r_type
== R_LARCH_TLS_GD_PC_HI20
3505 || r_type
== R_LARCH_TLS_IE_PC_HI20
)
3506 RELOCATE_CALC_PC32_HI20 (relocation
, pc
);
3510 case R_LARCH_TLS_IE_PC_LO12
:
3511 case R_LARCH_TLS_IE64_PC_LO20
:
3512 case R_LARCH_TLS_IE64_PC_HI12
:
3513 case R_LARCH_TLS_IE_LO12
:
3514 case R_LARCH_TLS_IE64_LO20
:
3515 case R_LARCH_TLS_IE64_HI12
:
3516 unresolved_reloc
= false;
3519 relocation
= sec_addr (got
) + (h
->got
.offset
& (~(bfd_vma
)3));
3521 relocation
= sec_addr (got
)
3522 + (local_got_offsets
[r_symndx
] & (~(bfd_vma
)3));
3524 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
3525 /* Use both TLS_GD and TLS_IE. */
3526 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
3527 relocation
+= 2 * GOT_ENTRY_SIZE
;
3529 if (r_type
== R_LARCH_TLS_IE64_PC_LO20
3530 || r_type
== R_LARCH_TLS_IE64_PC_HI12
)
3531 RELOCATE_CALC_PC64_HI32 (relocation
, pc
);
3537 r
= bfd_reloc_continue
;
3538 unresolved_reloc
= false;
3550 /* 'unresolved_reloc' means we haven't done it yet.
3551 We need help of dynamic linker to fix this memory location up. */
3552 if (!unresolved_reloc
)
3555 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
3556 rel
->r_offset
) == MINUS_ONE
)
3557 /* WHY? May because it's invalid so skip checking.
3558 But why dynamic reloc a invalid section? */
3561 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
3563 fatal
= (loongarch_reloc_is_fatal
3564 (info
, input_bfd
, input_section
, rel
, howto
,
3565 bfd_reloc_dangerous
, is_undefweak
, name
,
3566 "Seems dynamic linker not process "
3567 "sections 'SEC_DEBUGGING'."));
3572 if ((info
->flags
& DF_TEXTREL
) == 0)
3573 if (input_section
->output_section
->flags
& SEC_READONLY
)
3574 info
->flags
|= DF_TEXTREL
;
3581 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
3582 rel
->r_offset
, sym
, h
, rel
->r_addend
);
3584 if (r
!= bfd_reloc_continue
)
3585 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
3586 input_bfd
, contents
);
3590 case bfd_reloc_dangerous
:
3591 case bfd_reloc_continue
:
3595 case bfd_reloc_overflow
:
3596 /* Overflow value can't be filled in. */
3597 loongarch_dump_reloc_record (info
->callbacks
->info
);
3598 info
->callbacks
->reloc_overflow
3599 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
3600 input_bfd
, input_section
, rel
->r_offset
);
3603 case bfd_reloc_outofrange
:
3604 /* Stack state incorrect. */
3605 loongarch_dump_reloc_record (info
->callbacks
->info
);
3606 info
->callbacks
->info
3607 ("%X%H: Internal stack state is incorrect.\n"
3608 "Want to push to full stack or pop from empty stack?\n",
3609 input_bfd
, input_section
, rel
->r_offset
);
3612 case bfd_reloc_notsupported
:
3613 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
3614 input_section
, rel
->r_offset
);
3618 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
3619 input_section
, rel
->r_offset
);
3630 loongarch_relax_delete_bytes (bfd
*abfd
,
3634 struct bfd_link_info
*link_info
)
3636 unsigned int i
, symcount
;
3637 bfd_vma toaddr
= sec
->size
;
3638 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (abfd
);
3639 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
3640 unsigned int sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
3641 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
3642 bfd_byte
*contents
= data
->this_hdr
.contents
;
3644 /* Actually delete the bytes. */
3646 memmove (contents
+ addr
, contents
+ addr
+ count
, toaddr
- addr
- count
);
3648 /* Adjust the location of all of the relocs. Note that we need not
3649 adjust the addends, since all PC-relative references must be against
3650 symbols, which we will adjust below. */
3651 for (i
= 0; i
< sec
->reloc_count
; i
++)
3652 if (data
->relocs
[i
].r_offset
> addr
&& data
->relocs
[i
].r_offset
< toaddr
)
3653 data
->relocs
[i
].r_offset
-= count
;
3655 /* Adjust the local symbols defined in this section. */
3656 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
3658 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
+ i
;
3659 if (sym
->st_shndx
== sec_shndx
)
3661 /* If the symbol is in the range of memory we just moved, we
3662 have to adjust its value. */
3663 if (sym
->st_value
> addr
&& sym
->st_value
<= toaddr
)
3664 sym
->st_value
-= count
;
3666 /* If the symbol *spans* the bytes we just deleted (i.e. its
3667 *end* is in the moved bytes but its *start* isn't), then we
3668 must adjust its size.
3670 This test needs to use the original value of st_value, otherwise
3671 we might accidentally decrease size when deleting bytes right
3672 before the symbol. But since deleted relocs can't span across
3673 symbols, we can't have both a st_value and a st_size decrease,
3674 so it is simpler to just use an else. */
3675 else if (sym
->st_value
<= addr
3676 && sym
->st_value
+ sym
->st_size
> addr
3677 && sym
->st_value
+ sym
->st_size
<= toaddr
)
3678 sym
->st_size
-= count
;
3682 /* Now adjust the global symbols defined in this section. */
3683 symcount
= ((symtab_hdr
->sh_size
/ sizeof (ElfNN_External_Sym
))
3684 - symtab_hdr
->sh_info
);
3686 for (i
= 0; i
< symcount
; i
++)
3688 struct elf_link_hash_entry
*sym_hash
= sym_hashes
[i
];
3690 /* The '--wrap SYMBOL' option is causing a pain when the object file,
3691 containing the definition of __wrap_SYMBOL, includes a direct
3692 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
3693 the same symbol (which is __wrap_SYMBOL), but still exist as two
3694 different symbols in 'sym_hashes', we don't want to adjust
3695 the global symbol __wrap_SYMBOL twice.
3697 The same problem occurs with symbols that are versioned_hidden, as
3698 foo becomes an alias for foo@BAR, and hence they need the same
3700 if (link_info
->wrap_hash
!= NULL
3701 || sym_hash
->versioned
!= unversioned
)
3703 struct elf_link_hash_entry
**cur_sym_hashes
;
3705 /* Loop only over the symbols which have already been checked. */
3706 for (cur_sym_hashes
= sym_hashes
; cur_sym_hashes
< &sym_hashes
[i
];
3709 /* If the current symbol is identical to 'sym_hash', that means
3710 the symbol was already adjusted (or at least checked). */
3711 if (*cur_sym_hashes
== sym_hash
)
3714 /* Don't adjust the symbol again. */
3715 if (cur_sym_hashes
< &sym_hashes
[i
])
3719 if ((sym_hash
->root
.type
== bfd_link_hash_defined
3720 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
3721 && sym_hash
->root
.u
.def
.section
== sec
)
3723 /* As above, adjust the value if needed. */
3724 if (sym_hash
->root
.u
.def
.value
> addr
3725 && sym_hash
->root
.u
.def
.value
<= toaddr
)
3726 sym_hash
->root
.u
.def
.value
-= count
;
3728 /* As above, adjust the size if needed. */
3729 else if (sym_hash
->root
.u
.def
.value
<= addr
3730 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
3731 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
<= toaddr
)
3732 sym_hash
->size
-= count
;
3739 /* Relax pcalau12i,addi.d => pcaddi. */
3741 loongarch_relax_pcala_addi (bfd
*abfd
, asection
*sec
,
3742 Elf_Internal_Rela
*rel_hi
, bfd_vma symval
)
3744 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
3745 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
3746 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
3747 uint32_t add
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
3748 uint32_t rd
= pca
& 0x1f;
3749 bfd_vma pc
= sec_addr (sec
) + rel_hi
->r_offset
;
3750 const uint32_t addi_d
= 0x02c00000;
3751 const uint32_t pcaddi
= 0x18000000;
3753 /* Is pcalau12i + addi.d insns? */
3754 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_PCALA_LO12
)
3755 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
3756 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
3757 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
3758 || ((add
& addi_d
) != addi_d
)
3759 /* Is pcalau12i $rd + addi.d $rd,$rd? */
3760 || ((add
& 0x1f) != rd
)
3761 || (((add
>> 5) & 0x1f) != rd
)
3762 /* Can be relaxed to pcaddi? */
3763 || (symval
& 0x3) /* 4 bytes align. */
3764 || ((bfd_signed_vma
)(symval
- pc
) < (bfd_signed_vma
)(int32_t)0xffe00000)
3765 || ((bfd_signed_vma
)(symval
- pc
) > (bfd_signed_vma
)(int32_t)0x1ffffc))
3769 bfd_put (32, abfd
, pca
, contents
+ rel_hi
->r_offset
);
3771 /* Adjust relocations. */
3772 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
3773 R_LARCH_PCREL20_S2
);
3774 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
3780 /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
3782 loongarch_relax_pcala_ld (bfd
*abfd
, asection
*sec
,
3783 Elf_Internal_Rela
*rel_hi
)
3785 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
3786 Elf_Internal_Rela
*rel_lo
= rel_hi
+ 2;
3787 uint32_t pca
= bfd_get (32, abfd
, contents
+ rel_hi
->r_offset
);
3788 uint32_t ld
= bfd_get (32, abfd
, contents
+ rel_lo
->r_offset
);
3789 uint32_t rd
= pca
& 0x1f;
3790 const uint32_t ld_d
= 0x28c00000;
3791 uint32_t addi_d
= 0x02c00000;
3793 if ((ELFNN_R_TYPE (rel_lo
->r_info
) != R_LARCH_GOT_PC_LO12
)
3794 || (ELFNN_R_TYPE ((rel_lo
+ 1)->r_info
) != R_LARCH_RELAX
)
3795 || (ELFNN_R_TYPE ((rel_hi
+ 1)->r_info
) != R_LARCH_RELAX
)
3796 || (rel_hi
->r_offset
+ 4 != rel_lo
->r_offset
)
3797 || ((ld
& 0x1f) != rd
)
3798 || (((ld
>> 5) & 0x1f) != rd
)
3799 || ((ld
& ld_d
) != ld_d
))
3802 addi_d
= addi_d
| (rd
<< 5) | rd
;
3803 bfd_put (32, abfd
, addi_d
, contents
+ rel_lo
->r_offset
);
3805 rel_hi
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_hi
->r_info
),
3806 R_LARCH_PCALA_HI20
);
3807 rel_lo
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel_lo
->r_info
),
3808 R_LARCH_PCALA_LO12
);
3812 /* Called by after_allocation to set the information of data segment
3816 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info
*info
,
3817 int *data_segment_phase
)
3819 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3820 htab
->data_segment_phase
= data_segment_phase
;
3823 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
3824 Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
3826 loongarch_relax_align (bfd
*abfd
, asection
*sec
,
3828 struct bfd_link_info
*link_info
,
3829 Elf_Internal_Rela
*rel
,
3832 bfd_byte
*contents
= elf_section_data (sec
)->this_hdr
.contents
;
3833 bfd_vma alignment
= 1, pos
;
3834 while (alignment
<= rel
->r_addend
)
3837 symval
-= rel
->r_addend
;
3838 bfd_vma aligned_addr
= ((symval
- 1) & ~(alignment
- 1)) + alignment
;
3839 bfd_vma nop_bytes
= aligned_addr
- symval
;
3841 /* Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
3842 sec
->sec_flg0
= true;
3844 /* Make sure there are enough NOPs to actually achieve the alignment. */
3845 if (rel
->r_addend
< nop_bytes
)
3848 (_("%pB(%pA+%#" PRIx64
"): %" PRId64
" bytes required for alignment "
3849 "to %" PRId64
"-byte boundary, but only %" PRId64
" present"),
3850 abfd
, sym_sec
, (uint64_t) rel
->r_offset
,
3851 (int64_t) nop_bytes
, (int64_t) alignment
, (int64_t) rel
->r_addend
);
3852 bfd_set_error (bfd_error_bad_value
);
3856 /* Delete the reloc. */
3857 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
3859 /* If the number of NOPs is already correct, there's nothing to do. */
3860 if (nop_bytes
== rel
->r_addend
)
3863 /* Write as many LOONGARCH NOPs as we need. */
3864 for (pos
= 0; pos
< (nop_bytes
& -4); pos
+= 4)
3865 bfd_putl32 (LARCH_NOP
, contents
+ rel
->r_offset
+ pos
);
3867 /* Delete the excess NOPs. */
3868 return loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
+ nop_bytes
,
3869 rel
->r_addend
- nop_bytes
, link_info
);
3873 loongarch_elf_relax_section (bfd
*abfd
, asection
*sec
,
3874 struct bfd_link_info
*info
,
3877 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3878 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (abfd
);
3879 struct bfd_elf_section_data
*data
= elf_section_data (sec
);
3880 Elf_Internal_Rela
*relocs
;
3883 if (bfd_link_relocatable (info
)
3885 || (sec
->flags
& SEC_RELOC
) == 0
3886 || sec
->reloc_count
== 0
3887 || elf_seg_map (info
->output_bfd
) == NULL
3888 || (info
->disable_target_specific_optimizations
3889 && info
->relax_pass
== 0)
3890 /* The exp_seg_relro_adjust is enum phase_enum (0x4),
3891 and defined in ld/ldexp.h. */
3892 || *(htab
->data_segment_phase
) == 4)
3896 relocs
= data
->relocs
;
3897 else if (!(relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
3898 info
->keep_memory
)))
3901 if (!data
->this_hdr
.contents
3902 && !bfd_malloc_and_get_section (abfd
, sec
, &data
->this_hdr
.contents
))
3905 if (symtab_hdr
->sh_info
!= 0
3906 && !symtab_hdr
->contents
3907 && !(symtab_hdr
->contents
=
3908 (unsigned char *) bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
3909 symtab_hdr
->sh_info
,
3910 0, NULL
, NULL
, NULL
)))
3913 data
->relocs
= relocs
;
3915 for (unsigned int i
= 0; i
< sec
->reloc_count
; i
++)
3917 Elf_Internal_Rela
*rel
= relocs
+ i
;
3920 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3921 bool local_got
= false;
3923 struct elf_link_hash_entry
*h
= NULL
;
3925 if (r_symndx
< symtab_hdr
->sh_info
)
3927 Elf_Internal_Sym
*sym
= (Elf_Internal_Sym
*)symtab_hdr
->contents
3929 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
3932 if (sym
->st_shndx
== SHN_UNDEF
)
3935 symval
= rel
->r_offset
;
3939 sym_sec
= elf_elfsections (abfd
)[sym
->st_shndx
]->bfd_section
;
3940 symval
= sym
->st_value
;
3942 symtype
= ELF_ST_TYPE (sym
->st_info
);
3946 r_symndx
= ELFNN_R_SYM (rel
->r_info
) - symtab_hdr
->sh_info
;
3947 h
= elf_sym_hashes (abfd
)[r_symndx
];
3949 while (h
->root
.type
== bfd_link_hash_indirect
3950 || h
->root
.type
== bfd_link_hash_warning
)
3951 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3953 /* Disable the relaxation for ifunc. */
3954 if (h
!= NULL
&& h
->type
== STT_GNU_IFUNC
)
3957 if ((h
->root
.type
== bfd_link_hash_defined
3958 || h
->root
.type
== bfd_link_hash_defweak
)
3959 && h
->root
.u
.def
.section
!= NULL
3960 && h
->root
.u
.def
.section
->output_section
!= NULL
)
3962 symval
= h
->root
.u
.def
.value
;
3963 sym_sec
= h
->root
.u
.def
.section
;
3968 if (h
&& bfd_link_executable (info
)
3969 && SYMBOL_REFERENCES_LOCAL (info
, h
))
3974 if (sym_sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
3975 && (sym_sec
->flags
& SEC_MERGE
))
3977 if (symtype
== STT_SECTION
)
3978 symval
+= rel
->r_addend
;
3980 symval
= _bfd_merged_section_offset (abfd
, &sym_sec
,
3981 elf_section_data (sym_sec
)->sec_info
,
3984 if (symtype
!= STT_SECTION
)
3985 symval
+= rel
->r_addend
;
3988 symval
+= rel
->r_addend
;
3990 symval
+= sec_addr (sym_sec
);
3992 switch (ELFNN_R_TYPE (rel
->r_info
))
3995 if (2 == info
->relax_pass
)
3996 loongarch_relax_align (abfd
, sec
, sym_sec
, info
, rel
, symval
);
3998 case R_LARCH_DELETE
:
3999 if (info
->relax_pass
== 1)
4001 loongarch_relax_delete_bytes (abfd
, sec
, rel
->r_offset
, 4, info
);
4002 rel
->r_info
= ELFNN_R_INFO (0, R_LARCH_NONE
);
4005 case R_LARCH_PCALA_HI20
:
4006 if (info
->relax_pass
== 0)
4008 if (i
+ 4 > sec
->reloc_count
)
4010 loongarch_relax_pcala_addi (abfd
, sec
, rel
, symval
);
4013 case R_LARCH_GOT_PC_HI20
:
4016 if (i
+ 4 > sec
->reloc_count
)
4018 if (loongarch_relax_pcala_ld (abfd
, sec
, rel
))
4020 loongarch_relax_pcala_addi (abfd
, sec
, rel
, symval
);
4032 /* Finish up dynamic symbol handling. We set the contents of various
4033 dynamic sections here. */
4036 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
4037 struct bfd_link_info
*info
,
4038 struct elf_link_hash_entry
*h
,
4039 Elf_Internal_Sym
*sym
)
4041 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4042 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
4044 if (h
->plt
.offset
!= MINUS_ONE
)
4047 asection
*plt
, *gotplt
, *relplt
;
4048 bfd_vma got_address
;
4049 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
4051 Elf_Internal_Rela rela
;
4055 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
4056 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4057 || h
->dynindx
!= -1);
4059 plt
= htab
->elf
.splt
;
4060 gotplt
= htab
->elf
.sgotplt
;
4061 if (h
->type
== STT_GNU_IFUNC
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
4062 relplt
= htab
->elf
.srelgot
;
4064 relplt
= htab
->elf
.srelplt
;
4065 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4067 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
4069 else /* if (htab->elf.iplt) */
4071 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
4072 && SYMBOL_REFERENCES_LOCAL (info
, h
));
4074 plt
= htab
->elf
.iplt
;
4075 gotplt
= htab
->elf
.igotplt
;
4076 relplt
= htab
->elf
.irelplt
;
4077 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
4078 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
4081 /* Find out where the .plt entry should go. */
4082 loc
= plt
->contents
+ h
->plt
.offset
;
4084 /* Fill in the PLT entry itself. */
4085 if (!loongarch_make_plt_entry (got_address
,
4086 sec_addr (plt
) + h
->plt
.offset
,
4090 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
4091 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
4093 /* Fill in the initial value of the got.plt entry. */
4094 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
4095 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
4097 rela
.r_offset
= got_address
;
4099 /* TRUE if this is a PLT reference to a local IFUNC. */
4100 if (PLT_LOCAL_IFUNC_P (info
, h
)
4101 && (relplt
== htab
->elf
.srelgot
4102 || relplt
== htab
->elf
.irelplt
))
4104 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
4105 rela
.r_addend
= (h
->root
.u
.def
.value
4106 + h
->root
.u
.def
.section
->output_section
->vma
4107 + h
->root
.u
.def
.section
->output_offset
);
4109 loongarch_elf_append_rela (output_bfd
, relplt
, &rela
);
4113 /* Fill in the entry in the rela.plt section. */
4114 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
4116 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
4117 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
4120 if (!h
->def_regular
)
4122 /* Mark the symbol as undefined, rather than as defined in
4123 the .plt section. Leave the value alone. */
4124 sym
->st_shndx
= SHN_UNDEF
;
4125 /* If the symbol is weak, we do need to clear the value.
4126 Otherwise, the PLT entry would provide a definition for
4127 the symbol even if the symbol wasn't defined anywhere,
4128 and so the symbol would never be NULL. */
4129 if (!h
->ref_regular_nonweak
)
4134 if (h
->got
.offset
!= MINUS_ONE
4135 /* TLS got entry have been handled in elf_relocate_section. */
4136 && !(loongarch_elf_hash_entry (h
)->tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
4137 /* Have allocated got entry but not allocated rela before. */
4138 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
4140 asection
*sgot
, *srela
;
4141 Elf_Internal_Rela rela
;
4142 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
)1;
4144 /* This symbol has an entry in the GOT. Set it up. */
4145 sgot
= htab
->elf
.sgot
;
4146 srela
= htab
->elf
.srelgot
;
4147 BFD_ASSERT (sgot
&& srela
);
4149 rela
.r_offset
= sec_addr (sgot
) + off
;
4152 && h
->type
== STT_GNU_IFUNC
)
4154 if(h
->plt
.offset
== MINUS_ONE
)
4156 if (htab
->elf
.splt
== NULL
)
4157 srela
= htab
->elf
.irelplt
;
4159 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
4161 asection
*sec
= h
->root
.u
.def
.section
;
4162 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
4163 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
4164 + sec
->output_offset
;
4165 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
4169 BFD_ASSERT (h
->dynindx
!= -1);
4170 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4172 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
4175 else if(bfd_link_pic (info
))
4177 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4179 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
4184 /* For non-shared object, we can't use .got.plt, which
4185 contains the real function address if we need pointer
4186 equality. We load the GOT entry with the PLT entry. */
4187 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
4188 bfd_put_NN (output_bfd
,
4189 (plt
->output_section
->vma
4190 + plt
->output_offset
4192 sgot
->contents
+ off
);
4196 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
4198 asection
*sec
= h
->root
.u
.def
.section
;
4199 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
4200 rela
.r_addend
= (h
->root
.u
.def
.value
+ sec
->output_section
->vma
4201 + sec
->output_offset
);
4205 BFD_ASSERT (h
->dynindx
!= -1);
4206 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
4210 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
4213 /* Mark some specially defined symbols as absolute. */
4214 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
4215 sym
->st_shndx
= SHN_ABS
;
4220 /* Finish up the dynamic sections. */
4223 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
4226 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4227 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
4228 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
4229 bfd_byte
*dyncon
, *dynconend
;
4231 dynconend
= sdyn
->contents
+ sdyn
->size
;
4232 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
4234 Elf_Internal_Dyn dyn
;
4238 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
4243 s
= htab
->elf
.sgotplt
;
4244 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
4247 s
= htab
->elf
.srelplt
;
4248 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
4251 s
= htab
->elf
.srelplt
;
4252 dyn
.d_un
.d_val
= s
->size
;
4255 if ((info
->flags
& DF_TEXTREL
) == 0)
4259 if ((info
->flags
& DF_TEXTREL
) == 0)
4260 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
4264 skipped_size
+= dynsize
;
4266 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
4268 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
4269 memset (dyncon
- skipped_size
, 0, skipped_size
);
4273 /* Finish up local dynamic symbol handling. We set the contents of
4274 various dynamic sections here. */
4277 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
4279 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
4280 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
4282 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
4285 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4286 this function is called before elf_link_sort_relocs.
4287 So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4288 .rela.dyn (.rela.got) by loongarch_elf_append_rela. */
4291 elf_loongarch_output_arch_local_syms
4292 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4293 struct bfd_link_info
*info
,
4294 void *flaginfo ATTRIBUTE_UNUSED
,
4295 int (*func
) (void *, const char *,
4298 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
4300 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
4304 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4305 htab_traverse (htab
->loc_hash_table
,
4306 elfNN_loongarch_finish_local_dynamic_symbol
,
4313 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
4314 struct bfd_link_info
*info
)
4317 asection
*sdyn
, *plt
, *gotplt
= NULL
;
4318 struct loongarch_elf_link_hash_table
*htab
;
4320 htab
= loongarch_elf_hash_table (info
);
4322 dynobj
= htab
->elf
.dynobj
;
4323 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
4325 if (elf_hash_table (info
)->dynamic_sections_created
)
4327 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
4329 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
4333 plt
= htab
->elf
.splt
;
4334 gotplt
= htab
->elf
.sgotplt
;
4336 if (plt
&& 0 < plt
->size
)
4339 uint32_t plt_header
[PLT_HEADER_INSNS
];
4340 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
4344 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
4345 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
4347 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
4351 if (htab
->elf
.sgotplt
)
4353 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
4355 if (bfd_is_abs_section (output_section
))
4357 _bfd_error_handler (_("discarded output section: `%pA'"),
4362 if (0 < htab
->elf
.sgotplt
->size
)
4364 /* Write the first two entries in .got.plt, needed for the dynamic
4366 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
4368 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
4369 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
4372 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
4377 asection
*output_section
= htab
->elf
.sgot
->output_section
;
4379 if (0 < htab
->elf
.sgot
->size
)
4381 /* Set the first entry in the global offset table to the address of
4382 the dynamic section. */
4383 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
4384 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
4387 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
4393 /* Return address for Ith PLT stub in section PLT, for relocation REL
4394 or (bfd_vma) -1 if it should not be included. */
4397 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
4398 const arelent
*rel ATTRIBUTE_UNUSED
)
4400 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
4403 static enum elf_reloc_type_class
4404 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
4405 const asection
*rel_sec ATTRIBUTE_UNUSED
,
4406 const Elf_Internal_Rela
*rela
)
4408 struct loongarch_elf_link_hash_table
*htab
;
4409 htab
= loongarch_elf_hash_table (info
);
4411 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
4413 /* Check relocation against STT_GNU_IFUNC symbol if there are
4415 bfd
*abfd
= info
->output_bfd
;
4416 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
4417 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
4418 if (r_symndx
!= STN_UNDEF
)
4420 Elf_Internal_Sym sym
;
4421 if (!bed
->s
->swap_symbol_in (abfd
,
4422 htab
->elf
.dynsym
->contents
4423 + r_symndx
* bed
->s
->sizeof_sym
,
4426 /* xgettext:c-format */
4427 _bfd_error_handler (_("%pB symbol number %lu references"
4428 " nonexistent SHT_SYMTAB_SHNDX section"),
4430 /* Ideally an error class should be returned here. */
4432 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
4433 return reloc_class_ifunc
;
4437 switch (ELFNN_R_TYPE (rela
->r_info
))
4439 case R_LARCH_IRELATIVE
:
4440 return reloc_class_ifunc
;
4441 case R_LARCH_RELATIVE
:
4442 return reloc_class_relative
;
4443 case R_LARCH_JUMP_SLOT
:
4444 return reloc_class_plt
;
4446 return reloc_class_copy
;
4448 return reloc_class_normal
;
4452 /* Copy the extra info we tack onto an elf_link_hash_entry. */
4455 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
4456 struct elf_link_hash_entry
*dir
,
4457 struct elf_link_hash_entry
*ind
)
4459 struct elf_link_hash_entry
*edir
, *eind
;
4464 if (eind
->dyn_relocs
!= NULL
)
4466 if (edir
->dyn_relocs
!= NULL
)
4468 struct elf_dyn_relocs
**pp
;
4469 struct elf_dyn_relocs
*p
;
4471 /* Add reloc counts against the indirect sym to the direct sym
4472 list. Merge any entries against the same section. */
4473 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
4475 struct elf_dyn_relocs
*q
;
4477 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
4478 if (q
->sec
== p
->sec
)
4480 q
->pc_count
+= p
->pc_count
;
4481 q
->count
+= p
->count
;
4488 *pp
= edir
->dyn_relocs
;
4491 edir
->dyn_relocs
= eind
->dyn_relocs
;
4492 eind
->dyn_relocs
= NULL
;
4495 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
4497 loongarch_elf_hash_entry(edir
)->tls_type
4498 = loongarch_elf_hash_entry(eind
)->tls_type
;
4499 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
4501 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
4504 #define PRSTATUS_SIZE 0x1d8
4505 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
4506 #define PRSTATUS_OFFSET_PR_PID 0x20
4507 #define ELF_GREGSET_T_SIZE 0x168
4508 #define PRSTATUS_OFFSET_PR_REG 0x70
4510 /* Support for core dump NOTE sections. */
4513 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
4515 switch (note
->descsz
)
4520 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
4523 elf_tdata (abfd
)->core
->signal
=
4524 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
4527 elf_tdata (abfd
)->core
->lwpid
=
4528 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
4532 /* Make a ".reg/999" section. */
4533 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
4535 + PRSTATUS_OFFSET_PR_REG
);
4538 #define PRPSINFO_SIZE 0x88
4539 #define PRPSINFO_OFFSET_PR_PID 0x18
4540 #define PRPSINFO_OFFSET_PR_FNAME 0x28
4541 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
4542 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
4543 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
4546 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
4548 switch (note
->descsz
)
4553 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
4556 elf_tdata (abfd
)->core
->pid
=
4557 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
4560 elf_tdata (abfd
)->core
->program
=
4561 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
4562 PRPSINFO_SIZEOF_PR_FNAME
);
4565 elf_tdata (abfd
)->core
->command
=
4566 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
4567 PRPSINFO_SIZEOF_PR_PS_ARGS
);
4571 /* Note that for some reason, a spurious space is tacked
4572 onto the end of the args in some (at least one anyway)
4573 implementations, so strip it off if it exists. */
4576 char *command
= elf_tdata (abfd
)->core
->command
;
4577 int n
= strlen (command
);
4579 if (0 < n
&& command
[n
- 1] == ' ')
4580 command
[n
- 1] = '\0';
4586 /* Set the right mach type. */
4588 loongarch_elf_object_p (bfd
*abfd
)
4590 /* There are only two mach types in LoongArch currently. */
4591 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
4592 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
4594 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
4599 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
4600 Elf_Internal_Rela
*rel
,
4601 struct elf_link_hash_entry
*h
,
4602 Elf_Internal_Sym
*sym
)
4605 switch (ELFNN_R_TYPE (rel
->r_info
))
4607 case R_LARCH_GNU_VTINHERIT
:
4608 case R_LARCH_GNU_VTENTRY
:
4612 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
4615 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
4616 executable PLT slots where the executable never takes the address of those
4617 functions, the function symbols are not added to the hash table. */
4620 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
4622 if (h
->plt
.offset
!= (bfd_vma
) -1
4624 && !h
->pointer_equality_needed
)
4627 return _bfd_elf_hash_symbol (h
);
4630 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
4631 #define TARGET_LITTLE_NAME "elfNN-loongarch"
4632 #define ELF_ARCH bfd_arch_loongarch
4633 #define ELF_TARGET_ID LARCH_ELF_DATA
4634 #define ELF_MACHINE_CODE EM_LOONGARCH
4635 #define ELF_MAXPAGESIZE 0x4000
4636 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
4637 #define bfd_elfNN_bfd_link_hash_table_create \
4638 loongarch_elf_link_hash_table_create
4639 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
4640 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
4641 #define elf_info_to_howto loongarch_info_to_howto_rela
4642 #define bfd_elfNN_bfd_merge_private_bfd_data \
4643 elfNN_loongarch_merge_private_bfd_data
4645 #define elf_backend_reloc_type_class loongarch_reloc_type_class
4646 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
4647 #define elf_backend_create_dynamic_sections \
4648 loongarch_elf_create_dynamic_sections
4649 #define elf_backend_check_relocs loongarch_elf_check_relocs
4650 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
4651 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
4652 #define elf_backend_relocate_section loongarch_elf_relocate_section
4653 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
4654 #define elf_backend_output_arch_local_syms \
4655 elf_loongarch_output_arch_local_syms
4656 #define elf_backend_finish_dynamic_sections \
4657 loongarch_elf_finish_dynamic_sections
4658 #define elf_backend_object_p loongarch_elf_object_p
4659 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
4660 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
4661 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
4662 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
4663 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
4664 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
4666 #define elf_backend_dtrel_excludes_plt 1
4668 #include "elfNN-target.h"