1 /* LoongArch-specific support for NN-bit ELF.
2 Copyright (C) 2021-2022 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"
32 loongarch_info_to_howto_rela (bfd
*abfd
, arelent
*cache_ptr
,
33 Elf_Internal_Rela
*dst
)
35 cache_ptr
->howto
= loongarch_elf_rtype_to_howto (abfd
,
36 ELFNN_R_TYPE (dst
->r_info
));
37 return cache_ptr
->howto
!= NULL
;
40 /* LoongArch ELF linker hash entry. */
41 struct loongarch_elf_link_hash_entry
43 struct elf_link_hash_entry elf
;
53 #define loongarch_elf_hash_entry(ent) \
54 ((struct loongarch_elf_link_hash_entry *) (ent))
56 struct _bfd_loongarch_elf_obj_tdata
58 struct elf_obj_tdata root
;
60 /* The tls_type for each local got entry. */
61 char *local_got_tls_type
;
64 #define _bfd_loongarch_elf_tdata(abfd) \
65 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
67 #define _bfd_loongarch_elf_local_got_tls_type(abfd) \
68 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
70 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \
72 ? &loongarch_elf_hash_entry (h)->tls_type \
73 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
75 #define is_loongarch_elf(bfd) \
76 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
77 && elf_tdata (bfd) != NULL \
78 && elf_object_id (bfd) == LARCH_ELF_DATA)
80 struct loongarch_elf_link_hash_table
82 struct elf_link_hash_table elf
;
84 /* Short-cuts to get to dynamic linker sections. */
87 /* Small local sym to section mapping cache. */
88 struct sym_cache sym_cache
;
90 /* Used by local STT_GNU_IFUNC symbols. */
91 htab_t loc_hash_table
;
92 void *loc_hash_memory
;
94 /* The max alignment of output sections. */
95 bfd_vma max_alignment
;
98 /* Get the LoongArch ELF linker hash table from a link_info structure. */
99 #define loongarch_elf_hash_table(p) \
100 (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
101 ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
104 #define MINUS_ONE ((bfd_vma) 0 - 1)
106 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
108 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
109 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
111 #define PLT_HEADER_INSNS 8
112 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
114 #define PLT_ENTRY_INSNS 4
115 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
117 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
119 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
121 #define elf_backend_want_got_plt 1
123 #define elf_backend_plt_readonly 1
125 #define elf_backend_want_plt_sym 0
126 #define elf_backend_plt_alignment 4
127 #define elf_backend_can_gc_sections 1
128 #define elf_backend_want_got_sym 1
130 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
132 #define elf_backend_want_dynrelro 1
134 /* Generate a PLT header. */
137 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
140 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
143 if (pcrel
+ 0x80000800 > 0xffffffff)
145 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
146 bfd_set_error (bfd_error_bad_value
);
149 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
152 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
153 sub.[wd] $t1, $t1, $t3
154 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
155 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
156 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
157 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
158 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
161 if (GOT_ENTRY_SIZE
== 8)
163 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
164 entry
[1] = 0x0011bdad;
165 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
166 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
167 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
168 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
169 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
170 entry
[7] = 0x4c0001e0;
174 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
175 entry
[1] = 0x00113dad;
176 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
177 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
178 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
179 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
180 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
181 entry
[7] = 0x4c0001e0;
186 /* Generate a PLT entry. */
189 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
192 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
195 if (pcrel
+ 0x80000800 > 0xffffffff)
197 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
198 bfd_set_error (bfd_error_bad_value
);
201 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
204 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
205 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
206 | (lo
& 0xfff) << 10);
207 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
208 entry
[3] = 0x03400000; /* nop */
213 /* Create an entry in an LoongArch ELF linker hash table. */
215 static struct bfd_hash_entry
*
216 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
219 struct loongarch_elf_link_hash_entry
*eh
;
221 /* Allocate the structure if it has not already been allocated by a
225 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
230 /* Call the allocation method of the superclass. */
231 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
234 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
235 eh
->tls_type
= GOT_UNKNOWN
;
241 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
242 for local symbol so that we can handle local STT_GNU_IFUNC symbols
243 as global symbol. We reuse indx and dynstr_index for local symbol
244 hash since they aren't used by global symbols in this backend. */
247 elfNN_loongarch_local_htab_hash (const void *ptr
)
249 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
250 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
253 /* Compare local hash entries. */
256 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
258 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
259 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
261 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
264 /* Find and/or create a hash entry for local symbol. */
265 static struct elf_link_hash_entry
*
266 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
267 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
270 struct loongarch_elf_link_hash_entry e
, *ret
;
271 asection
*sec
= abfd
->sections
;
272 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
275 e
.elf
.indx
= sec
->id
;
276 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
277 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
278 create
? INSERT
: NO_INSERT
);
285 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
289 ret
= ((struct loongarch_elf_link_hash_entry
*)
290 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
291 sizeof (struct loongarch_elf_link_hash_entry
)));
294 memset (ret
, 0, sizeof (*ret
));
295 ret
->elf
.indx
= sec
->id
;
296 ret
->elf
.pointer_equality_needed
= 0;
297 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
298 ret
->elf
.dynindx
= -1;
299 ret
->elf
.needs_plt
= 0;
300 ret
->elf
.plt
.refcount
= -1;
301 ret
->elf
.got
.refcount
= -1;
302 ret
->elf
.def_dynamic
= 0;
303 ret
->elf
.def_regular
= 1;
304 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
305 ret
->elf
.ref_regular
= 0;
306 ret
->elf
.forced_local
= 1;
307 ret
->elf
.root
.type
= bfd_link_hash_defined
;
313 /* Destroy an LoongArch elf linker hash table. */
316 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
318 struct loongarch_elf_link_hash_table
*ret
;
319 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
321 if (ret
->loc_hash_table
)
322 htab_delete (ret
->loc_hash_table
);
323 if (ret
->loc_hash_memory
)
324 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
326 _bfd_elf_link_hash_table_free (obfd
);
329 /* Create a LoongArch ELF linker hash table. */
331 static struct bfd_link_hash_table
*
332 loongarch_elf_link_hash_table_create (bfd
*abfd
)
334 struct loongarch_elf_link_hash_table
*ret
;
335 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
337 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
341 if (!_bfd_elf_link_hash_table_init
342 (&ret
->elf
, abfd
, link_hash_newfunc
,
343 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
349 ret
->max_alignment
= MINUS_ONE
;
351 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
352 elfNN_loongarch_local_htab_eq
, NULL
);
353 ret
->loc_hash_memory
= objalloc_create ();
354 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
356 elfNN_loongarch_link_hash_table_free (abfd
);
359 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
361 return &ret
->elf
.root
;
364 /* Merge backend specific data from an object file to the output
365 object file when linking. */
368 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
370 bfd
*obfd
= info
->output_bfd
;
371 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
372 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
374 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
377 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
379 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
380 "the selected emulation:\n"
381 " target emulation `%s' does not match `%s'"),
382 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
386 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
389 /* If the input BFD is not a dynamic object and it does not contain any
390 non-data sections, do not account its ABI. For example, various
391 packages produces such data-only relocatable objects with
392 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
393 But they are compatible with all ABIs. */
394 if (!(ibfd
->flags
& DYNAMIC
))
397 bool have_code_sections
= false;
398 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
399 if ((bfd_section_flags (sec
)
400 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
401 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
403 have_code_sections
= true;
406 if (!have_code_sections
)
410 if (!elf_flags_init (obfd
))
412 elf_flags_init (obfd
) = true;
413 elf_elfheader (obfd
)->e_flags
= in_flags
;
417 /* Disallow linking different ABIs. */
418 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
420 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
427 bfd_set_error (bfd_error_bad_value
);
431 /* Create the .got section. */
434 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
439 struct elf_link_hash_entry
*h
;
440 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
441 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
443 /* This function may be called more than once. */
444 if (htab
->sgot
!= NULL
)
447 flags
= bed
->dynamic_sec_flags
;
448 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
449 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
451 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
455 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
456 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
460 /* The first bit of the global offset table is the header. */
461 s
->size
+= bed
->got_header_size
;
463 if (bed
->want_got_plt
)
465 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
466 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
470 /* Reserve room for the header. */
471 s
->size
= GOTPLT_HEADER_SIZE
;
474 if (bed
->want_got_sym
)
476 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
477 section. We don't do this in the linker script because we don't want
478 to define the symbol if we are not creating a global offset table. */
479 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
480 "_GLOBAL_OFFSET_TABLE_");
481 elf_hash_table (info
)->hgot
= h
;
488 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
489 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
493 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
495 struct loongarch_elf_link_hash_table
*htab
;
497 htab
= loongarch_elf_hash_table (info
);
498 BFD_ASSERT (htab
!= NULL
);
500 if (!loongarch_elf_create_got_section (dynobj
, info
))
503 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
506 if (!bfd_link_pic (info
))
508 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
509 SEC_ALLOC
| SEC_THREAD_LOCAL
);
511 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
512 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
519 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
520 struct bfd_link_info
*info
,
521 struct elf_link_hash_entry
*h
,
522 unsigned long symndx
,
525 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
526 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
528 /* This is a global offset table entry for a local symbol. */
529 if (elf_local_got_refcounts (abfd
) == NULL
)
532 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
533 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
535 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
536 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
545 if (htab
->elf
.sgot
== NULL
546 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
550 if (h
->got
.refcount
< 0)
555 elf_local_got_refcounts (abfd
)[symndx
]++;
558 /* No need for GOT. */
561 _bfd_error_handler (_("Internal error: unreachable."));
565 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
566 *new_tls_type
|= tls_type
;
567 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
569 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
570 "thread local symbol"),
572 h
? h
->root
.root
.string
: "<local>");
579 /* Look through the relocs for a section during the first phase, and
580 allocate space in the global offset table or procedure linkage
584 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
585 asection
*sec
, const Elf_Internal_Rela
*relocs
)
587 struct loongarch_elf_link_hash_table
*htab
;
588 Elf_Internal_Shdr
*symtab_hdr
;
589 struct elf_link_hash_entry
**sym_hashes
;
590 const Elf_Internal_Rela
*rel
;
591 asection
*sreloc
= NULL
;
593 if (bfd_link_relocatable (info
))
596 htab
= loongarch_elf_hash_table (info
);
597 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
598 sym_hashes
= elf_sym_hashes (abfd
);
600 if (htab
->elf
.dynobj
== NULL
)
601 htab
->elf
.dynobj
= abfd
;
603 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
606 unsigned int r_symndx
;
607 struct elf_link_hash_entry
*h
;
608 Elf_Internal_Sym
*isym
= NULL
;
613 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
614 r_type
= ELFNN_R_TYPE (rel
->r_info
);
616 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
618 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
622 if (r_symndx
< symtab_hdr
->sh_info
)
624 /* A local symbol. */
625 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
, abfd
, r_symndx
);
629 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
631 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
635 h
->type
= STT_GNU_IFUNC
;
643 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
644 while (h
->root
.type
== bfd_link_hash_indirect
645 || h
->root
.type
== bfd_link_hash_warning
)
646 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
649 /* It is referenced by a non-shared object. */
653 if (h
&& h
->type
== STT_GNU_IFUNC
)
655 if (htab
->elf
.dynobj
== NULL
)
656 htab
->elf
.dynobj
= abfd
;
658 /* Create the ifunc sections, iplt and ipltgot, for static
660 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
661 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
665 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
666 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
669 if (h
->plt
.refcount
< 0)
674 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
681 case R_LARCH_SOP_PUSH_GPREL
:
682 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
688 case R_LARCH_SOP_PUSH_TLS_GD
:
689 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
695 case R_LARCH_SOP_PUSH_TLS_GOT
:
696 if (bfd_link_pic (info
))
697 /* May fail for lazy-bind. */
698 info
->flags
|= DF_STATIC_TLS
;
700 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
706 case R_LARCH_SOP_PUSH_TLS_TPREL
:
707 if (!bfd_link_executable (info
))
710 info
->flags
|= DF_STATIC_TLS
;
712 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
718 case R_LARCH_SOP_PUSH_ABSOLUTE
:
720 /* If this reloc is in a read-only section, we might
721 need a copy reloc. We can't check reliably at this
722 stage whether the section is read-only, as input
723 sections have not yet been mapped to output sections.
724 Tentatively set the flag for now, and correct in
725 adjust_dynamic_symbol. */
729 case R_LARCH_SOP_PUSH_PCREL
:
734 /* We try to create PLT stub for all non-local function. */
735 if (h
->plt
.refcount
< 0)
741 case R_LARCH_SOP_PUSH_PLT_PCREL
:
742 /* This symbol requires a procedure linkage table entry. We
743 actually build the entry in adjust_dynamic_symbol,
744 because this might be a case of linking PIC code without
745 linking in any dynamic objects, in which case we don't
746 need to generate a procedure linkage table after all. */
750 if (h
->plt
.refcount
< 0)
756 case R_LARCH_TLS_DTPREL32
:
757 case R_LARCH_TLS_DTPREL64
:
762 case R_LARCH_JUMP_SLOT
:
767 /* If resolved symbol is defined in this object,
768 1. Under pie, the symbol is known. We convert it
769 into R_LARCH_RELATIVE and need load-addr still.
770 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
771 3. Under dll, R_LARCH_NN can't be changed normally, since
772 its defination could be covered by the one in executable.
773 For symbolic, we convert it into R_LARCH_RELATIVE.
774 Thus, only under pde, it needs pcrel only. We discard it. */
775 only_need_pcrel
= bfd_link_pde (info
);
781 && (!bfd_link_pic (info
)
782 || h
->type
== STT_GNU_IFUNC
))
784 /* This reloc might not bind locally. */
786 h
->pointer_equality_needed
= 1;
789 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
791 /* We may need a .plt entry if the symbol is a function
792 defined in a shared lib or is a function referenced
793 from the code or read-only section. */
794 h
->plt
.refcount
+= 1;
799 case R_LARCH_GNU_VTINHERIT
:
800 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
804 case R_LARCH_GNU_VTENTRY
:
805 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
813 /* Record some info for sizing and allocating dynamic entry. */
814 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
816 /* When creating a shared object, we must copy these
817 relocs into the output file. We create a reloc
818 section in dynobj and make room for the reloc. */
819 struct elf_dyn_relocs
*p
;
820 struct elf_dyn_relocs
**head
;
825 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
826 LARCH_ELF_LOG_WORD_BYTES
,
827 abfd
, /*rela?*/ true);
832 /* If this is a global symbol, we count the number of
833 relocations we need for this symbol. */
835 head
= &h
->dyn_relocs
;
838 /* Track dynamic relocs needed for local syms too.
839 We really need local syms available to do this
845 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
849 vpp
= &elf_section_data (s
)->local_dynrel
;
850 head
= (struct elf_dyn_relocs
**) vpp
;
854 if (p
== NULL
|| p
->sec
!= sec
)
856 bfd_size_type amt
= sizeof *p
;
857 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
868 p
->pc_count
+= only_need_pcrel
;
875 /* Find dynamic relocs for H that apply to read-only sections. */
878 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
880 struct elf_dyn_relocs
*p
;
882 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
884 asection
*s
= p
->sec
->output_section
;
886 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
892 /* Adjust a symbol defined by a dynamic object and referenced by a
893 regular object. The current definition is in some section of the
894 dynamic object, but we're not including those sections. We have to
895 change the definition to something the rest of the link can
898 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
899 struct elf_link_hash_entry
*h
)
901 struct loongarch_elf_link_hash_table
*htab
;
902 struct loongarch_elf_link_hash_entry
*eh
;
906 htab
= loongarch_elf_hash_table (info
);
907 BFD_ASSERT (htab
!= NULL
);
909 dynobj
= htab
->elf
.dynobj
;
911 /* Make sure we know what is going on here. */
912 BFD_ASSERT (dynobj
!= NULL
913 && (h
->needs_plt
|| h
->type
== STT_GNU_IFUNC
|| h
->is_weakalias
914 || (h
->def_dynamic
&& h
->ref_regular
&& !h
->def_regular
)));
916 /* If this is a function, put it in the procedure linkage table. We
917 will fill in the contents of the procedure linkage table later
918 (although we could actually do it here). */
919 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
921 if (h
->plt
.refcount
< 0
922 || (h
->type
!= STT_GNU_IFUNC
923 && (SYMBOL_REFERENCES_LOCAL (info
, h
)
924 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
925 && h
->root
.type
== bfd_link_hash_undefweak
))))
927 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
928 in an input file, but the symbol was never referred to by a
929 dynamic object, or if all references were garbage collected.
930 In such a case, we don't actually need to build a PLT entry. */
931 h
->plt
.offset
= MINUS_ONE
;
940 h
->plt
.offset
= MINUS_ONE
;
942 /* If this is a weak symbol, and there is a real definition, the
943 processor independent code will have arranged for us to see the
944 real definition first, and we can just use the same value. */
947 struct elf_link_hash_entry
*def
= weakdef (h
);
948 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
949 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
950 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
954 /* This is a reference to a symbol defined by a dynamic object which
955 is not a function. */
957 /* If we are creating a shared library, we must presume that the
958 only references to the symbol are via the global offset table.
959 For such cases we need not do anything here; the relocations will
960 be handled correctly by relocate_section. */
961 if (bfd_link_dll (info
))
964 /* If there are no references to this symbol that do not use the
965 GOT, we don't need to generate a copy reloc. */
969 /* If -z nocopyreloc was given, we won't generate them either. */
970 if (info
->nocopyreloc
)
976 /* If we don't find any dynamic relocs in read-only sections, then
977 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
978 if (!readonly_dynrelocs (h
))
984 /* We must allocate the symbol in our .dynbss section, which will
985 become part of the .bss section of the executable. There will be
986 an entry for this symbol in the .dynsym section. The dynamic
987 object will contain position independent code, so all references
988 from the dynamic object to this symbol will go through the global
989 offset table. The dynamic linker will use the .dynsym entry to
990 determine the address it must put in the global offset table, so
991 both the dynamic object and the regular object will refer to the
992 same memory location for the variable. */
994 /* We must generate a R_LARCH_COPY reloc to tell the dynamic linker
995 to copy the initial value out of the dynamic object and into the
996 runtime process image. We need to remember the offset into the
997 .rel.bss section we are going to use. */
998 eh
= (struct loongarch_elf_link_hash_entry
*) h
;
999 if (eh
->tls_type
& ~GOT_NORMAL
)
1001 s
= htab
->sdyntdata
;
1002 srel
= htab
->elf
.srelbss
;
1004 else if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
1006 s
= htab
->elf
.sdynrelro
;
1007 srel
= htab
->elf
.sreldynrelro
;
1011 s
= htab
->elf
.sdynbss
;
1012 srel
= htab
->elf
.srelbss
;
1014 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
1016 srel
->size
+= sizeof (ElfNN_External_Rela
);
1020 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
1023 /* Allocate space in .plt, .got and associated reloc sections for
1027 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1029 struct bfd_link_info
*info
;
1030 struct loongarch_elf_link_hash_table
*htab
;
1031 struct elf_dyn_relocs
*p
;
1033 if (h
->root
.type
== bfd_link_hash_indirect
)
1036 if (h
->type
== STT_GNU_IFUNC
1040 info
= (struct bfd_link_info
*) inf
;
1041 htab
= loongarch_elf_hash_table (info
);
1042 BFD_ASSERT (htab
!= NULL
);
1046 asection
*plt
, *gotplt
, *relplt
;
1055 if (h
->dynindx
== -1 && !h
->forced_local
1056 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
1059 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1060 && h
->type
!= STT_GNU_IFUNC
)
1063 plt
= htab
->elf
.splt
;
1064 gotplt
= htab
->elf
.sgotplt
;
1065 relplt
= htab
->elf
.srelplt
;
1067 else if (htab
->elf
.iplt
)
1069 /* .iplt only for IFUNC. */
1070 if (h
->type
!= STT_GNU_IFUNC
)
1073 plt
= htab
->elf
.iplt
;
1074 gotplt
= htab
->elf
.igotplt
;
1075 relplt
= htab
->elf
.irelplt
;
1081 plt
->size
= PLT_HEADER_SIZE
;
1083 h
->plt
.offset
= plt
->size
;
1084 plt
->size
+= PLT_ENTRY_SIZE
;
1085 gotplt
->size
+= GOT_ENTRY_SIZE
;
1086 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1088 /* If this symbol is not defined in a regular file, and we are
1089 not generating a shared library, then set the symbol to this
1090 location in the .plt. This is required to make function
1091 pointers compare as equal between the normal executable and
1092 the shared library. */
1093 if (!bfd_link_pic(info
)
1096 h
->root
.u
.def
.section
= plt
;
1097 h
->root
.u
.def
.value
= h
->plt
.offset
;
1105 h
->plt
.offset
= MINUS_ONE
;
1107 if (0 < h
->got
.refcount
)
1111 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1113 /* Make sure this symbol is output as a dynamic symbol.
1114 Undefined weak syms won't yet be marked as dynamic. */
1115 if (h
->dynindx
== -1 && !h
->forced_local
)
1117 if (SYMBOL_REFERENCES_LOCAL (info
, h
)
1118 && (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
1121 /* The pr21964-4. do nothing. */
1125 if( !bfd_elf_link_record_dynamic_symbol (info
, h
))
1131 h
->got
.offset
= s
->size
;
1132 dyn
= htab
->elf
.dynamic_sections_created
;
1133 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
1135 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1136 if (tls_type
& GOT_TLS_GD
)
1138 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1139 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1142 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1143 if (tls_type
& GOT_TLS_IE
)
1145 s
->size
+= GOT_ENTRY_SIZE
;
1146 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1151 s
->size
+= GOT_ENTRY_SIZE
;
1152 if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
1153 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1154 || h
->type
== STT_GNU_IFUNC
)
1155 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1159 h
->got
.offset
= MINUS_ONE
;
1161 if (h
->dyn_relocs
== NULL
)
1164 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1166 struct elf_dyn_relocs
**pp
;
1168 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1170 p
->count
-= p
->pc_count
;
1179 if (h
->root
.type
== bfd_link_hash_undefweak
)
1181 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1182 h
->dyn_relocs
= NULL
;
1183 else if (h
->dynindx
== -1 && !h
->forced_local
1184 /* Make sure this symbol is output as a dynamic symbol.
1185 Undefined weak syms won't yet be marked as dynamic. */
1186 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
1190 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1192 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1193 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1199 /* Allocate space in .plt, .got and associated reloc sections for
1200 ifunc dynamic relocs. */
1203 elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
1206 struct bfd_link_info
*info
;
1207 /* An example of a bfd_link_hash_indirect symbol is versioned
1208 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1209 -> __gxx_personality_v0(bfd_link_hash_defined)
1211 There is no need to process bfd_link_hash_indirect symbols here
1212 because we will also be presented with the concrete instance of
1213 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1214 called to copy all relevant data from the generic to the concrete
1216 if (h
->root
.type
== bfd_link_hash_indirect
)
1219 if (h
->root
.type
== bfd_link_hash_warning
)
1220 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1222 info
= (struct bfd_link_info
*) inf
;
1224 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1225 here if it is defined and referenced in a non-shared object. */
1226 if (h
->type
== STT_GNU_IFUNC
1228 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1237 /* Allocate space in .plt, .got and associated reloc sections for
1238 ifunc dynamic relocs. */
1241 elfNN_loongarch_allocate_local_dynrelocs (void **slot
, void *inf
)
1243 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1245 if (h
->type
!= STT_GNU_IFUNC
1249 || h
->root
.type
!= bfd_link_hash_defined
)
1252 return elfNN_loongarch_allocate_ifunc_dynrelocs (h
, inf
);
1255 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1256 read-only sections. */
1259 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1263 if (h
->root
.type
== bfd_link_hash_indirect
)
1266 sec
= readonly_dynrelocs (h
);
1269 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1271 info
->flags
|= DF_TEXTREL
;
1272 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1273 "read-only section `%pA'\n"),
1274 sec
->owner
, h
->root
.root
.string
, sec
);
1276 /* Not an error, just cut short the traversal. */
1283 loongarch_elf_size_dynamic_sections (bfd
*output_bfd
,
1284 struct bfd_link_info
*info
)
1286 struct loongarch_elf_link_hash_table
*htab
;
1291 htab
= loongarch_elf_hash_table (info
);
1292 BFD_ASSERT (htab
!= NULL
);
1293 dynobj
= htab
->elf
.dynobj
;
1294 BFD_ASSERT (dynobj
!= NULL
);
1296 if (htab
->elf
.dynamic_sections_created
)
1298 /* Set the contents of the .interp section to the interpreter. */
1299 if (bfd_link_executable (info
) && !info
->nointerp
)
1301 const char *interpreter
;
1302 flagword flags
= elf_elfheader (output_bfd
)->e_flags
;
1303 s
= bfd_get_linker_section (dynobj
, ".interp");
1304 BFD_ASSERT (s
!= NULL
);
1305 if (EF_LOONGARCH_IS_ILP32 (flags
))
1306 interpreter
= "/lib32/ld.so.1";
1307 else if (EF_LOONGARCH_IS_LP64 (flags
))
1308 interpreter
= "/lib64/ld.so.1";
1310 interpreter
= "/lib/ld.so.1";
1311 s
->contents
= (unsigned char *) interpreter
;
1312 s
->size
= strlen (interpreter
) + 1;
1316 /* Set up .got offsets for local syms, and space for local dynamic
1318 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
1320 bfd_signed_vma
*local_got
;
1321 bfd_signed_vma
*end_local_got
;
1322 char *local_tls_type
;
1323 bfd_size_type locsymcount
;
1324 Elf_Internal_Shdr
*symtab_hdr
;
1327 if (!is_loongarch_elf (ibfd
))
1330 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
1332 struct elf_dyn_relocs
*p
;
1334 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
1336 p
->count
-= p
->pc_count
;
1337 if (!bfd_is_abs_section (p
->sec
)
1338 && bfd_is_abs_section (p
->sec
->output_section
))
1340 /* Input section has been discarded, either because
1341 it is a copy of a linkonce section or due to
1342 linker script /DISCARD/, so we'll be discarding
1345 else if (0 < p
->count
)
1347 srel
= elf_section_data (p
->sec
)->sreloc
;
1348 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1349 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
1350 info
->flags
|= DF_TEXTREL
;
1355 local_got
= elf_local_got_refcounts (ibfd
);
1359 symtab_hdr
= &elf_symtab_hdr (ibfd
);
1360 locsymcount
= symtab_hdr
->sh_info
;
1361 end_local_got
= local_got
+ locsymcount
;
1362 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
1364 srel
= htab
->elf
.srelgot
;
1365 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
1369 *local_got
= s
->size
;
1370 s
->size
+= GOT_ENTRY_SIZE
;
1372 if (*local_tls_type
& GOT_TLS_GD
)
1373 s
->size
+= GOT_ENTRY_SIZE
;
1375 /* If R_LARCH_RELATIVE. */
1376 if (bfd_link_pic (info
)
1377 /* Or R_LARCH_TLS_DTPRELNN or R_LARCH_TLS_TPRELNN. */
1378 || (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
)))
1379 srel
->size
+= sizeof (ElfNN_External_Rela
);
1382 *local_got
= MINUS_ONE
;
1386 /* Allocate global sym .plt and .got entries, and space for global
1387 sym dynamic relocs. */
1388 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
1390 /* Allocate global ifunc sym .plt and .got entries, and space for global
1391 ifunc sym dynamic relocs. */
1392 elf_link_hash_traverse (&htab
->elf
, elfNN_loongarch_allocate_ifunc_dynrelocs
, info
);
1394 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1395 htab_traverse (htab
->loc_hash_table
,
1396 (void *) elfNN_loongarch_allocate_local_dynrelocs
, info
);
1398 /* Don't allocate .got.plt section if there are no PLT. */
1399 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
1400 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
1401 htab
->elf
.sgotplt
->size
= 0;
1403 /* The check_relocs and adjust_dynamic_symbol entry points have
1404 determined the sizes of the various dynamic sections. Allocate
1406 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
1408 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
1411 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
1412 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
1413 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
1415 /* Strip this section if we don't need it; see the
1418 else if (strncmp (s
->name
, ".rela", 5) == 0)
1422 /* We use the reloc_count field as a counter if we need
1423 to copy relocs into the output file. */
1429 /* It's not one of our sections. */
1435 /* If we don't need this section, strip it from the
1436 output file. This is mostly to handle .rela.bss and
1437 .rela.plt. We must create both sections in
1438 create_dynamic_sections, because they must be created
1439 before the linker maps input sections to output
1440 sections. The linker does that before
1441 adjust_dynamic_symbol is called, and it is that
1442 function which decides whether anything needs to go
1443 into these sections. */
1444 s
->flags
|= SEC_EXCLUDE
;
1448 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
1451 /* Allocate memory for the section contents. Zero the memory
1452 for the benefit of .rela.plt, which has 4 unused entries
1453 at the beginning, and we don't want garbage. */
1454 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
1455 if (s
->contents
== NULL
)
1459 if (elf_hash_table (info
)->dynamic_sections_created
)
1461 /* Add some entries to the .dynamic section. We fill in the
1462 values later, in loongarch_elf_finish_dynamic_sections, but we
1463 must add the entries now so that we get the correct size for
1464 the .dynamic section. The DT_DEBUG entry is filled in by the
1465 dynamic linker and used by the debugger. */
1466 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1468 if (bfd_link_executable (info
))
1470 if (!add_dynamic_entry (DT_DEBUG
, 0))
1474 if (htab
->elf
.srelplt
->size
!= 0)
1476 if (!add_dynamic_entry (DT_PLTGOT
, 0)
1477 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
1478 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
1479 || !add_dynamic_entry (DT_JMPREL
, 0))
1483 if (!add_dynamic_entry (DT_RELA
, 0)
1484 || !add_dynamic_entry (DT_RELASZ
, 0)
1485 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
1488 /* If any dynamic relocs apply to a read-only section,
1489 then we need a DT_TEXTREL entry. */
1490 if ((info
->flags
& DF_TEXTREL
) == 0)
1491 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
1493 if (info
->flags
& DF_TEXTREL
)
1495 if (!add_dynamic_entry (DT_TEXTREL
, 0))
1497 /* Clear the DF_TEXTREL flag. It will be set again if we
1498 write out an actual text relocation; we may not, because
1499 at this point we do not know whether e.g. any .eh_frame
1500 absolute relocations have been converted to PC-relative. */
1501 info
->flags
&= ~DF_TEXTREL
;
1504 #undef add_dynamic_entry
1509 #define LARCH_LD_STACK_DEPTH 16
1510 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
1511 static size_t larch_stack_top
= 0;
1513 static bfd_reloc_status_type
1514 loongarch_push (int64_t val
)
1516 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
1517 return bfd_reloc_outofrange
;
1518 larch_opc_stack
[larch_stack_top
++] = val
;
1519 return bfd_reloc_ok
;
1522 static bfd_reloc_status_type
1523 loongarch_pop (int64_t *val
)
1525 if (larch_stack_top
== 0)
1526 return bfd_reloc_outofrange
;
1528 *val
= larch_opc_stack
[--larch_stack_top
];
1529 return bfd_reloc_ok
;
1532 static bfd_reloc_status_type
1533 loongarch_top (int64_t *val
)
1535 if (larch_stack_top
== 0)
1536 return bfd_reloc_outofrange
;
1538 *val
= larch_opc_stack
[larch_stack_top
- 1];
1539 return bfd_reloc_ok
;
1543 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
1545 const struct elf_backend_data
*bed
;
1548 bed
= get_elf_backend_data (abfd
);
1549 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
1550 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
1553 /* Check rel->r_offset in range of contents. */
1554 static bfd_reloc_status_type
1555 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
1556 const asection
*input_section
)
1558 if (0 == strcmp(input_section
->name
, ".text")
1559 && rel
->r_offset
> input_section
->size
)
1560 return bfd_reloc_overflow
;
1562 return bfd_reloc_ok
;
1565 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
1567 bfd_reloc_status_type ret = loongarch_pop (&op2); \
1568 if (ret == bfd_reloc_ok) \
1570 ret = loongarch_pop (&op1); \
1571 if (ret == bfd_reloc_ok) \
1572 ret = loongarch_push (op3); \
1577 static bfd_reloc_status_type
1578 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
1579 const asection
*input_section ATTRIBUTE_UNUSED
,
1580 reloc_howto_type
*howto
, bfd
*input_bfd
,
1581 bfd_byte
*contents
, bfd_vma reloc_val
)
1583 int bits
= bfd_get_reloc_size (howto
) * 8;
1584 uint32_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1586 if (!loongarch_adjust_reloc_bitsfield(howto
, &reloc_val
))
1587 return bfd_reloc_overflow
;
1589 insn
= (insn
& (uint32_t)howto
->src_mask
)
1590 | ((insn
& (~(uint32_t)howto
->dst_mask
)) | reloc_val
);
1592 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
1594 return bfd_reloc_ok
;
1597 /* Emplace a static relocation. */
1599 static bfd_reloc_status_type
1600 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
1601 reloc_howto_type
*howto
, bfd_vma value
,
1602 bfd
*input_bfd
, bfd_byte
*contents
)
1605 int64_t opr1
, opr2
, opr3
;
1606 bfd_reloc_status_type r
= bfd_reloc_ok
;
1607 int bits
= bfd_get_reloc_size (howto
) * 8;
1610 switch (ELFNN_R_TYPE (rel
->r_info
))
1612 case R_LARCH_SOP_PUSH_PCREL
:
1613 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1614 case R_LARCH_SOP_PUSH_GPREL
:
1615 case R_LARCH_SOP_PUSH_TLS_TPREL
:
1616 case R_LARCH_SOP_PUSH_TLS_GOT
:
1617 case R_LARCH_SOP_PUSH_TLS_GD
:
1618 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1619 r
= loongarch_push (value
);
1622 case R_LARCH_SOP_PUSH_DUP
:
1623 r
= loongarch_pop (&opr1
);
1624 if (r
== bfd_reloc_ok
)
1626 r
= loongarch_push (opr1
);
1627 if (r
== bfd_reloc_ok
)
1628 r
= loongarch_push (opr1
);
1632 case R_LARCH_SOP_ASSERT
:
1633 r
= loongarch_pop (&opr1
);
1634 if (r
!= bfd_reloc_ok
|| !opr1
)
1635 r
= bfd_reloc_notsupported
;
1638 case R_LARCH_SOP_NOT
:
1639 r
= loongarch_pop (&opr1
);
1640 if (r
== bfd_reloc_ok
)
1641 r
= loongarch_push (!opr1
);
1644 case R_LARCH_SOP_SUB
:
1645 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
1648 case R_LARCH_SOP_SL
:
1649 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
1652 case R_LARCH_SOP_SR
:
1653 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
1656 case R_LARCH_SOP_AND
:
1657 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
1660 case R_LARCH_SOP_ADD
:
1661 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
1664 case R_LARCH_SOP_IF_ELSE
:
1665 r
= loongarch_pop (&opr3
);
1666 if (r
== bfd_reloc_ok
)
1668 r
= loongarch_pop (&opr2
);
1669 if (r
== bfd_reloc_ok
)
1671 r
= loongarch_pop (&opr1
);
1672 if (r
== bfd_reloc_ok
)
1673 r
= loongarch_push (opr1
? opr2
: opr3
);
1678 case R_LARCH_SOP_POP_32_S_10_5
:
1679 case R_LARCH_SOP_POP_32_S_10_12
:
1680 case R_LARCH_SOP_POP_32_S_10_16
:
1681 case R_LARCH_SOP_POP_32_S_10_16_S2
:
1682 case R_LARCH_SOP_POP_32_S_5_20
:
1683 case R_LARCH_SOP_POP_32_U_10_12
:
1684 case R_LARCH_SOP_POP_32_U
:
1685 r
= loongarch_pop (&opr1
);
1686 if (r
!= bfd_reloc_ok
)
1688 r
= loongarch_check_offset (rel
, input_section
);
1689 if (r
!= bfd_reloc_ok
)
1692 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
1694 contents
, (bfd_vma
)opr1
);
1697 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
1699 r
= loongarch_pop (&opr1
);
1700 if (r
!= bfd_reloc_ok
)
1703 if ((opr1
& 0x3) != 0)
1705 r
= bfd_reloc_overflow
;
1709 uint32_t imm
= opr1
>> howto
->rightshift
;
1710 if ((imm
& (~0xfffffU
)) && ((imm
& (~0xfffffU
)) != (~0xfffffU
)))
1712 r
= bfd_reloc_overflow
;
1715 r
= loongarch_check_offset (rel
, input_section
);
1716 if (r
!= bfd_reloc_ok
)
1719 insn1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1720 insn1
= (insn1
& howto
->src_mask
)
1721 | ((imm
& 0xffffU
) << 10)
1722 | ((imm
& 0x1f0000U
) >> 16);
1723 bfd_put (bits
, input_bfd
, insn1
, contents
+ rel
->r_offset
);
1727 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
1729 r
= loongarch_pop (&opr1
);
1730 if (r
!= bfd_reloc_ok
)
1733 if ((opr1
& 0x3) != 0)
1735 r
= bfd_reloc_overflow
;
1739 uint32_t imm
= opr1
>> howto
->rightshift
;
1740 if ((imm
& (~0x1ffffffU
)) && (imm
& (~0x1ffffffU
)) != (~0x1ffffffU
))
1742 r
= bfd_reloc_overflow
;
1746 r
= loongarch_check_offset (rel
, input_section
);
1747 if (r
!= bfd_reloc_ok
)
1750 insn1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1751 insn1
= ((insn1
& howto
->src_mask
)
1752 | ((imm
& 0xffffU
) << 10)
1753 | ((imm
& 0x3ff0000U
) >> 16));
1754 bfd_put (bits
, input_bfd
, insn1
, contents
+ rel
->r_offset
);
1758 case R_LARCH_TLS_DTPREL32
:
1760 case R_LARCH_TLS_DTPREL64
:
1762 r
= loongarch_check_offset (rel
, input_section
);
1763 if (r
!= bfd_reloc_ok
)
1766 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
1774 r
= loongarch_check_offset (rel
, input_section
);
1775 if (r
!= bfd_reloc_ok
)
1778 opr1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1779 bfd_put (bits
, input_bfd
, opr1
+ value
, contents
+ rel
->r_offset
);
1787 r
= loongarch_check_offset (rel
, input_section
);
1788 if (r
!= bfd_reloc_ok
)
1791 opr1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1792 bfd_put (bits
, input_bfd
, opr1
- value
, contents
+ rel
->r_offset
);
1796 r
= bfd_reloc_notsupported
;
1801 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
1809 Elf_Internal_Sym
*sym
;
1810 struct elf_link_hash_entry
*h
;
1813 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
1814 static size_t larch_reloc_queue_head
= 0;
1815 static size_t larch_reloc_queue_tail
= 0;
1818 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
1819 Elf_Internal_Sym
*sym
)
1821 const char *ret
= NULL
;
1823 ret
= bfd_elf_string_from_elf_section (input_bfd
,
1824 elf_symtab_hdr (input_bfd
).sh_link
,
1827 ret
= h
->root
.root
.string
;
1829 if (ret
== NULL
|| *ret
== '\0')
1835 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
1836 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
1837 struct elf_link_hash_entry
*h
, bfd_vma addend
)
1839 if ((larch_reloc_queue_head
== 0
1840 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
1841 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
1842 larch_reloc_queue_head
=
1843 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1844 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
1845 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
1846 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
1847 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
1848 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
1849 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
1850 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
1851 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
1852 larch_reloc_queue_tail
=
1853 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1857 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
1859 size_t i
= larch_reloc_queue_head
;
1861 asection
*section
= NULL
;
1862 bfd_vma r_offset
= 0;
1864 p ("Dump relocate record:\n");
1865 p ("stack top\t\trelocation name\t\tsymbol");
1866 while (i
!= larch_reloc_queue_tail
)
1868 if (a_bfd
!= larch_reloc_queue
[i
].bfd
1869 || section
!= larch_reloc_queue
[i
].section
1870 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
1872 a_bfd
= larch_reloc_queue
[i
].bfd
;
1873 section
= larch_reloc_queue
[i
].section
;
1874 r_offset
= larch_reloc_queue
[i
].r_offset
;
1875 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
1876 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
1880 inited
= 1, p ("...\n");
1882 reloc_howto_type
*howto
=
1883 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
1884 larch_reloc_queue
[i
].r_type
);
1885 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
1886 howto
? howto
->name
: "<unknown reloc>",
1887 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
1888 larch_reloc_queue
[i
].sym
));
1890 long addend
= larch_reloc_queue
[i
].addend
;
1892 p (" - %ld", -addend
);
1893 else if (0 < addend
)
1894 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
1897 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1900 "-- Record dump end --\n\n");
1905 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
1907 asection
*input_section
,
1908 Elf_Internal_Rela
*rel
,
1909 reloc_howto_type
*howto
,
1910 bfd_reloc_status_type rtype
,
1918 /* 'dangerous' means we do it but can't promise it's ok
1919 'unsupport' means out of ability of relocation type
1920 'undefined' means we can't deal with the undefined symbol. */
1921 case bfd_reloc_undefined
:
1922 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
1923 rel
->r_offset
, true);
1924 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1925 input_bfd
, input_section
, rel
->r_offset
,
1927 is_undefweak
? "[undefweak] " : "", name
, msg
);
1929 case bfd_reloc_dangerous
:
1930 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
1931 input_bfd
, input_section
, rel
->r_offset
,
1933 is_undefweak
? "[undefweak] " : "", name
, msg
);
1936 case bfd_reloc_notsupported
:
1937 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1938 input_bfd
, input_section
, rel
->r_offset
,
1940 is_undefweak
? "[undefweak] " : "", name
, msg
);
1952 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
1953 bfd
*input_bfd
, asection
*input_section
,
1954 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
1955 Elf_Internal_Sym
*local_syms
,
1956 asection
**local_sections
)
1958 Elf_Internal_Rela
*rel
;
1959 Elf_Internal_Rela
*relend
;
1961 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
1962 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
1963 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
1964 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
1965 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
1966 bool is_pic
= bfd_link_pic (info
);
1967 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
1968 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
1969 asection
*got
= htab
->elf
.sgot
;
1971 relend
= relocs
+ input_section
->reloc_count
;
1972 for (rel
= relocs
; rel
< relend
; rel
++)
1974 int r_type
= ELFNN_R_TYPE (rel
->r_info
);
1975 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1976 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
1977 reloc_howto_type
*howto
= NULL
;
1978 asection
*sec
= NULL
;
1979 Elf_Internal_Sym
*sym
= NULL
;
1980 struct elf_link_hash_entry
*h
= NULL
;
1982 bfd_reloc_status_type r
= bfd_reloc_ok
;
1983 bool is_ie
, is_undefweak
, unresolved_reloc
, defined_local
;
1984 bool resolved_local
, resolved_dynly
, resolved_to_const
;
1987 bfd_vma off
, ie_off
;
1990 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
1991 if (howto
== NULL
|| r_type
== R_LARCH_GNU_VTINHERIT
1992 || r_type
== R_LARCH_GNU_VTENTRY
)
1995 /* This is a final link. */
1996 if (r_symndx
< symtab_hdr
->sh_info
)
1998 is_undefweak
= false;
1999 unresolved_reloc
= false;
2000 sym
= local_syms
+ r_symndx
;
2001 sec
= local_sections
[r_symndx
];
2002 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
2004 /* Relocate against local STT_GNU_IFUNC symbol. */
2005 if (!bfd_link_relocatable (info
)
2006 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2008 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
2013 /* Set STT_GNU_IFUNC symbol value. */
2014 h
->root
.u
.def
.value
= sym
->st_value
;
2015 h
->root
.u
.def
.section
= sec
;
2017 defined_local
= true;
2018 resolved_local
= true;
2019 resolved_dynly
= false;
2020 resolved_to_const
= false;
2021 if (bfd_link_relocatable (info
)
2022 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2023 rel
->r_addend
+= sec
->output_offset
;
2027 bool warned
, ignored
;
2029 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2030 r_symndx
, symtab_hdr
, sym_hashes
,
2032 unresolved_reloc
, warned
, ignored
);
2033 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2035 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2036 symbol. And 'dynamic_undefined_weak' specify what to do when
2037 meeting undefweak. */
2039 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
2041 defined_local
= false;
2042 resolved_local
= false;
2043 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
2044 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
2045 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
2049 /* Symbol undefined offen means failed already. I don't know why
2050 'warned' here but I guess it want to continue relocating as if
2051 no error occures to find other errors as more as possible. */
2053 /* To avoid generating warning messages about truncated
2054 relocations, set the relocation's address to be the same as
2055 the start of this section. */
2056 relocation
= (input_section
->output_section
2057 ? input_section
->output_section
->vma
2060 defined_local
= relocation
!= 0;
2061 resolved_local
= defined_local
;
2062 resolved_to_const
= !resolved_local
;
2063 resolved_dynly
= false;
2067 defined_local
= !unresolved_reloc
&& !ignored
;
2069 defined_local
&& SYMBOL_REFERENCES_LOCAL (info
, h
);
2070 resolved_dynly
= !resolved_local
;
2071 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
2075 name
= loongarch_sym_name (input_bfd
, h
, sym
);
2077 if (sec
!= NULL
&& discarded_section (sec
))
2078 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
2079 1, relend
, howto
, 0, contents
);
2081 if (bfd_link_relocatable (info
))
2084 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2085 from removed linkonce sections, or sections discarded by a linker
2086 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2087 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
2089 defined_local
= false;
2090 resolved_local
= false;
2091 resolved_dynly
= false;
2092 resolved_to_const
= true;
2095 /* The ifunc without reference does not generate plt. */
2096 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
2098 defined_local
= true;
2099 resolved_local
= true;
2100 resolved_dynly
= false;
2101 resolved_to_const
= false;
2102 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2105 unresolved_reloc
= resolved_dynly
;
2107 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
2109 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2111 BFD_ASSERT (!resolved_local
|| defined_local
);
2116 case R_LARCH_MARK_PCREL
:
2117 case R_LARCH_MARK_LA
:
2119 r
= bfd_reloc_continue
;
2120 unresolved_reloc
= false;
2125 if (resolved_dynly
|| (is_pic
&& resolved_local
))
2127 Elf_Internal_Rela outrel
;
2129 /* When generating a shared object, these relocations are copied
2130 into the output file to be resolved at run time. */
2132 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2136 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2137 && (input_section
->flags
& SEC_ALLOC
));
2139 outrel
.r_offset
+= sec_addr (input_section
);
2141 /* A pointer point to a local ifunc symbol. */
2143 && h
->type
== STT_GNU_IFUNC
2144 && (h
->dynindx
== -1
2146 || bfd_link_executable(info
)))
2148 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2149 outrel
.r_addend
= (h
->root
.u
.def
.value
2150 + h
->root
.u
.def
.section
->output_section
->vma
2151 + h
->root
.u
.def
.section
->output_offset
);
2153 /* Dynamic relocations are stored in
2154 1. .rela.ifunc section in PIC object.
2155 2. .rela.got section in dynamic executable.
2156 3. .rela.iplt section in static executable. */
2157 if (bfd_link_pic (info
))
2158 sreloc
= htab
->elf
.irelifunc
;
2159 else if (htab
->elf
.splt
!= NULL
)
2160 sreloc
= htab
->elf
.srelgot
;
2162 sreloc
= htab
->elf
.irelplt
;
2164 else if (resolved_dynly
)
2166 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2167 outrel
.r_addend
= rel
->r_addend
;
2171 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2172 outrel
.r_addend
= relocation
+ rel
->r_addend
;
2175 if (unresolved_reloc
)
2176 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2179 relocation
+= rel
->r_addend
;
2193 fatal
= (loongarch_reloc_is_fatal
2194 (info
, input_bfd
, input_section
, rel
, howto
,
2195 bfd_reloc_undefined
, is_undefweak
, name
,
2196 "Can't be resolved dynamically. "
2197 "If this procedure is hand-written assembly,\n"
2198 "there must be something like '.dword sym1 - sym2' "
2199 "to generate these relocs\n"
2200 "and we can't get known link-time address of "
2203 relocation
+= rel
->r_addend
;
2206 case R_LARCH_TLS_DTPREL32
:
2207 case R_LARCH_TLS_DTPREL64
:
2210 Elf_Internal_Rela outrel
;
2212 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2215 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2216 && (input_section
->flags
& SEC_ALLOC
));
2217 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2218 outrel
.r_offset
+= sec_addr (input_section
);
2219 outrel
.r_addend
= rel
->r_addend
;
2220 if (unresolved_reloc
)
2221 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2225 if (resolved_to_const
)
2226 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
2228 bfd_reloc_notsupported
,
2233 if (!elf_hash_table (info
)->tls_sec
)
2235 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2236 input_section
, rel
, howto
, bfd_reloc_notsupported
,
2237 is_undefweak
, name
, "TLS section not be created");
2240 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2244 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2245 input_section
, rel
, howto
, bfd_reloc_undefined
,
2247 "TLS LE just can be resolved local only.");
2252 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2255 if (!elf_hash_table (info
)->tls_sec
)
2256 fatal
= (loongarch_reloc_is_fatal
2257 (info
, input_bfd
, input_section
, rel
, howto
,
2258 bfd_reloc_notsupported
, is_undefweak
, name
,
2259 "TLS section not be created"));
2261 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2264 fatal
= (loongarch_reloc_is_fatal
2265 (info
, input_bfd
, input_section
, rel
, howto
,
2266 bfd_reloc_undefined
, is_undefweak
, name
,
2267 "TLS LE just can be resolved local only."));
2270 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2274 fatal
= (loongarch_reloc_is_fatal
2275 (info
, input_bfd
, input_section
, rel
, howto
,
2276 bfd_reloc_dangerous
, is_undefweak
, name
,
2277 "Someone require us to resolve undefweak "
2278 "symbol dynamically. \n"
2279 "But this reloc can't be done. "
2280 "I think I can't throw error "
2282 "so I resolved it to 0. "
2283 "I suggest to re-compile with '-fpic'."));
2286 unresolved_reloc
= false;
2290 if (resolved_to_const
)
2292 relocation
+= rel
->r_addend
;
2298 fatal
= (loongarch_reloc_is_fatal
2299 (info
, input_bfd
, input_section
, rel
, howto
,
2300 bfd_reloc_notsupported
, is_undefweak
, name
,
2301 "Under PIC we don't know load address. Re-compile "
2308 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
2310 fatal
= (loongarch_reloc_is_fatal
2311 (info
, input_bfd
, input_section
, rel
, howto
,
2312 bfd_reloc_undefined
, is_undefweak
, name
,
2313 "Can't be resolved dynamically. Try to re-compile "
2318 if (rel
->r_addend
!= 0)
2320 fatal
= (loongarch_reloc_is_fatal
2321 (info
, input_bfd
, input_section
, rel
, howto
,
2322 bfd_reloc_notsupported
, is_undefweak
, name
,
2323 "Shouldn't be with r_addend."));
2327 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2328 unresolved_reloc
= false;
2334 relocation
+= rel
->r_addend
;
2340 case R_LARCH_SOP_PUSH_PCREL
:
2341 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2342 unresolved_reloc
= false;
2344 if (resolved_to_const
)
2346 relocation
+= rel
->r_addend
;
2349 else if (is_undefweak
)
2355 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
2358 fatal
= (loongarch_reloc_is_fatal
2359 (info
, input_bfd
, input_section
, rel
, howto
,
2360 bfd_reloc_dangerous
, is_undefweak
, name
,
2361 "Undefweak need to be resolved dynamically, "
2362 "but PLT stub doesn't represent."));
2367 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
2369 fatal
= (loongarch_reloc_is_fatal
2370 (info
, input_bfd
, input_section
, rel
, howto
,
2371 bfd_reloc_undefined
, is_undefweak
, name
,
2372 "PLT stub does not represent and "
2373 "symbol not defined."));
2379 else /* if (resolved_dynly) */
2381 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
2382 fatal
= (loongarch_reloc_is_fatal
2383 (info
, input_bfd
, input_section
, rel
, howto
,
2384 bfd_reloc_dangerous
, is_undefweak
, name
,
2385 "Internal: PLT stub doesn't represent. "
2386 "Resolve it with pcrel"));
2393 if ((i
& 1) == 0 && defined_local
)
2396 relocation
+= rel
->r_addend
;
2400 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
2402 if (rel
->r_addend
!= 0)
2404 fatal
= (loongarch_reloc_is_fatal
2405 (info
, input_bfd
, input_section
, rel
, howto
,
2406 bfd_reloc_notsupported
, is_undefweak
, name
,
2407 "PLT shouldn't be with r_addend."));
2410 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
2416 case R_LARCH_SOP_PUSH_GPREL
:
2417 unresolved_reloc
= false;
2419 if (rel
->r_addend
!= 0)
2421 fatal
= (loongarch_reloc_is_fatal
2422 (info
, input_bfd
, input_section
, rel
, howto
,
2423 bfd_reloc_notsupported
, is_undefweak
, name
,
2424 "Shouldn't be with r_addend."));
2430 off
= h
->got
.offset
;
2432 if (off
== MINUS_ONE
2433 && h
->type
!= STT_GNU_IFUNC
)
2435 fatal
= (loongarch_reloc_is_fatal
2436 (info
, input_bfd
, input_section
, rel
, howto
,
2437 bfd_reloc_notsupported
, is_undefweak
, name
,
2438 "Internal: GOT entry doesn't represent."));
2442 /* Hidden symbol not has .got entry, only .got.plt entry
2443 so gprel is (plt - got). */
2444 if (off
== MINUS_ONE
2445 && h
->type
== STT_GNU_IFUNC
)
2447 if (h
->plt
.offset
== (bfd_vma
) -1)
2452 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
2453 off
= plt_index
* GOT_ENTRY_SIZE
;
2455 if (htab
->elf
.splt
!= NULL
)
2457 /* Section .plt header is 2 times of plt entry. */
2458 off
= sec_addr(htab
->elf
.sgotplt
) + off
2459 - sec_addr(htab
->elf
.sgot
);
2463 /* Section iplt not has plt header. */
2464 off
= sec_addr(htab
->elf
.igotplt
) + off
2465 - sec_addr(htab
->elf
.sgot
);
2469 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
, is_pic
, h
)
2470 || (is_pic
&& SYMBOL_REFERENCES_LOCAL (info
, h
)))
2472 /* This is actually a static link, or it is a
2473 -Bsymbolic link and the symbol is defined
2474 locally, or the symbol was forced to be local
2475 because of a version file. We must initialize
2476 this entry in the global offset table. Since the
2477 offset must always be a multiple of the word size,
2478 we use the least significant bit to record whether
2479 we have initialized it already.
2481 When doing a dynamic link, we create a .rela.got
2482 relocation entry to initialize the value. This
2483 is done in the finish_dynamic_symbol routine. */
2487 fatal
= (loongarch_reloc_is_fatal
2488 (info
, input_bfd
, input_section
, rel
, howto
,
2489 bfd_reloc_dangerous
, is_undefweak
, name
,
2490 "Internal: here shouldn't dynamic."));
2493 if (!(defined_local
|| resolved_to_const
))
2495 fatal
= (loongarch_reloc_is_fatal
2496 (info
, input_bfd
, input_section
, rel
, howto
,
2497 bfd_reloc_undefined
, is_undefweak
, name
,
2506 /* The pr21964-4. Create relocate entry. */
2507 if (is_pic
&& h
->start_stop
)
2510 Elf_Internal_Rela outrel
;
2511 /* We need to generate a R_LARCH_RELATIVE reloc
2512 for the dynamic linker. */
2513 s
= htab
->elf
.srelgot
;
2516 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2517 input_section
, rel
, howto
,
2518 bfd_reloc_notsupported
, is_undefweak
, name
,
2519 "Internal: '.rel.got' not represent");
2523 outrel
.r_offset
= sec_addr (got
) + off
;
2524 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2525 outrel
.r_addend
= relocation
; /* Link-time addr. */
2526 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
2528 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
2535 if (!local_got_offsets
)
2537 fatal
= (loongarch_reloc_is_fatal
2538 (info
, input_bfd
, input_section
, rel
, howto
,
2539 bfd_reloc_notsupported
, is_undefweak
, name
,
2540 "Internal: local got offsets not reporesent."));
2544 off
= local_got_offsets
[r_symndx
];
2546 if (off
== MINUS_ONE
)
2548 fatal
= (loongarch_reloc_is_fatal
2549 (info
, input_bfd
, input_section
, rel
, howto
,
2550 bfd_reloc_notsupported
, is_undefweak
, name
,
2551 "Internal: GOT entry doesn't represent."));
2555 /* The offset must always be a multiple of the word size.
2556 So, we can use the least significant bit to record
2557 whether we have already processed this entry. */
2565 Elf_Internal_Rela outrel
;
2566 /* We need to generate a R_LARCH_RELATIVE reloc
2567 for the dynamic linker. */
2568 s
= htab
->elf
.srelgot
;
2571 fatal
= (loongarch_reloc_is_fatal
2572 (info
, input_bfd
, input_section
, rel
, howto
,
2573 bfd_reloc_notsupported
, is_undefweak
, name
,
2574 "Internal: '.rel.got' not represent"));
2578 outrel
.r_offset
= sec_addr (got
) + off
;
2579 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2580 outrel
.r_addend
= relocation
; /* Link-time addr. */
2581 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
2584 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
2585 local_got_offsets
[r_symndx
] |= 1;
2591 case R_LARCH_SOP_PUSH_TLS_GOT
:
2592 case R_LARCH_SOP_PUSH_TLS_GD
:
2593 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
2595 unresolved_reloc
= false;
2597 if (rel
->r_addend
!= 0)
2599 fatal
= (loongarch_reloc_is_fatal
2600 (info
, input_bfd
, input_section
, rel
, howto
,
2601 bfd_reloc_notsupported
, is_undefweak
, name
,
2602 "Shouldn't be with r_addend."));
2607 if (resolved_to_const
&& is_undefweak
&& h
->dynindx
!= -1)
2609 /* What if undefweak? Let rtld make a decision. */
2610 resolved_to_const
= resolved_local
= false;
2611 resolved_dynly
= true;
2614 if (resolved_to_const
)
2616 fatal
= (loongarch_reloc_is_fatal
2617 (info
, input_bfd
, input_section
, rel
, howto
,
2618 bfd_reloc_notsupported
, is_undefweak
, name
,
2619 "Internal: Shouldn't be resolved to const."));
2625 off
= h
->got
.offset
;
2630 off
= local_got_offsets
[r_symndx
];
2631 local_got_offsets
[r_symndx
] |= 1;
2634 if (off
== MINUS_ONE
)
2636 fatal
= (loongarch_reloc_is_fatal
2637 (info
, input_bfd
, input_section
, rel
, howto
,
2638 bfd_reloc_notsupported
, is_undefweak
, name
,
2639 "Internal: TLS GOT entry doesn't represent."));
2643 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
2645 /* If this symbol is referenced by both GD and IE TLS, the IE
2646 reference's GOT slot follows the GD reference's slots. */
2648 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
2649 ie_off
= 2 * GOT_ENTRY_SIZE
;
2655 bfd_vma tls_block_off
= 0;
2656 Elf_Internal_Rela outrel
;
2660 if (!elf_hash_table (info
)->tls_sec
)
2662 fatal
= (loongarch_reloc_is_fatal
2663 (info
, input_bfd
, input_section
, rel
, howto
,
2664 bfd_reloc_notsupported
, is_undefweak
, name
,
2665 "Internal: TLS sec not represent."));
2669 relocation
- elf_hash_table (info
)->tls_sec
->vma
;
2672 if (tls_type
& GOT_TLS_GD
)
2674 outrel
.r_offset
= sec_addr (got
) + off
;
2675 outrel
.r_addend
= 0;
2676 bfd_put_NN (output_bfd
, 0, got
->contents
+ off
);
2677 if (resolved_local
&& bfd_link_executable (info
))
2678 bfd_put_NN (output_bfd
, 1, got
->contents
+ off
);
2679 else if (resolved_local
/* && !bfd_link_executable (info) */)
2681 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN
);
2682 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2685 else /* if (resolved_dynly) */
2688 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_DTPMODNN
);
2689 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2693 outrel
.r_offset
+= GOT_ENTRY_SIZE
;
2694 bfd_put_NN (output_bfd
, tls_block_off
,
2695 got
->contents
+ off
+ GOT_ENTRY_SIZE
);
2697 /* DTPREL known. */;
2698 else /* if (resolved_dynly) */
2701 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_DTPRELNN
);
2702 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2707 if (tls_type
& GOT_TLS_IE
)
2709 outrel
.r_offset
= sec_addr (got
) + off
+ ie_off
;
2710 bfd_put_NN (output_bfd
, tls_block_off
,
2711 got
->contents
+ off
+ ie_off
);
2712 if (resolved_local
&& bfd_link_executable (info
))
2714 else if (resolved_local
/* && !bfd_link_executable (info) */)
2716 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
2717 outrel
.r_addend
= tls_block_off
;
2718 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2721 else /* if (resolved_dynly) */
2723 /* Static linking has no .dynsym table. */
2724 if (!htab
->elf
.dynamic_sections_created
)
2727 ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
2728 outrel
.r_addend
= 0;
2733 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_TPRELNN
);
2734 outrel
.r_addend
= 0;
2736 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2742 relocation
= off
+ (is_ie
? ie_off
: 0);
2754 /* 'unresolved_reloc' means we haven't done it yet.
2755 We need help of dynamic linker to fix this memory location up. */
2756 if (!unresolved_reloc
)
2759 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
2760 rel
->r_offset
) == MINUS_ONE
)
2761 /* WHY? May because it's invalid so skip checking.
2762 But why dynamic reloc a invalid section? */
2765 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
2767 fatal
= (loongarch_reloc_is_fatal
2768 (info
, input_bfd
, input_section
, rel
, howto
,
2769 bfd_reloc_dangerous
, is_undefweak
, name
,
2770 "Seems dynamic linker not process "
2771 "sections 'SEC_DEBUGGING'."));
2776 if ((info
->flags
& DF_TEXTREL
) == 0)
2777 if (input_section
->output_section
->flags
& SEC_READONLY
)
2778 info
->flags
|= DF_TEXTREL
;
2785 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
2786 rel
->r_offset
, sym
, h
, rel
->r_addend
);
2788 if (r
!= bfd_reloc_continue
)
2789 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
2790 input_bfd
, contents
);
2794 case bfd_reloc_dangerous
:
2795 case bfd_reloc_continue
:
2799 case bfd_reloc_overflow
:
2800 /* Overflow value can't be filled in. */
2801 loongarch_dump_reloc_record (info
->callbacks
->info
);
2802 info
->callbacks
->reloc_overflow
2803 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
2804 input_bfd
, input_section
, rel
->r_offset
);
2807 case bfd_reloc_outofrange
:
2808 /* Stack state incorrect. */
2809 loongarch_dump_reloc_record (info
->callbacks
->info
);
2810 info
->callbacks
->info
2811 ("%X%H: Internal stack state is incorrect.\n"
2812 "Want to push to full stack or pop from empty stack?\n",
2813 input_bfd
, input_section
, rel
->r_offset
);
2816 case bfd_reloc_notsupported
:
2817 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
2818 input_section
, rel
->r_offset
);
2822 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
2823 input_section
, rel
->r_offset
);
2834 /* Finish up dynamic symbol handling. We set the contents of various
2835 dynamic sections here. */
2838 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
2839 struct bfd_link_info
*info
,
2840 struct elf_link_hash_entry
*h
,
2841 Elf_Internal_Sym
*sym
)
2843 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
2844 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
2846 if (h
->plt
.offset
!= MINUS_ONE
)
2849 asection
*plt
, *gotplt
, *relplt
;
2850 bfd_vma got_address
;
2851 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
2853 Elf_Internal_Rela rela
;
2857 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
2858 && SYMBOL_REFERENCES_LOCAL (info
, h
))
2859 || h
->dynindx
!= -1);
2861 plt
= htab
->elf
.splt
;
2862 gotplt
= htab
->elf
.sgotplt
;
2863 relplt
= htab
->elf
.srelplt
;
2864 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
2866 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
2868 else /* if (htab->elf.iplt) */
2870 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
2871 && SYMBOL_REFERENCES_LOCAL (info
, h
));
2873 plt
= htab
->elf
.iplt
;
2874 gotplt
= htab
->elf
.igotplt
;
2875 relplt
= htab
->elf
.irelplt
;
2876 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
2877 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
2880 /* Find out where the .plt entry should go. */
2881 loc
= plt
->contents
+ h
->plt
.offset
;
2883 /* Fill in the PLT entry itself. */
2884 if (!loongarch_make_plt_entry (got_address
,
2885 sec_addr (plt
) + h
->plt
.offset
,
2889 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
2890 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
2892 /* Fill in the initial value of the .got.plt entry. */
2893 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
2894 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
2896 rela
.r_offset
= got_address
;
2898 /* TRUE if this is a PLT reference to a local IFUNC. */
2899 if (PLT_LOCAL_IFUNC_P(info
, h
))
2901 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2902 rela
.r_addend
= (h
->root
.u
.def
.value
2903 + h
->root
.u
.def
.section
->output_section
->vma
2904 + h
->root
.u
.def
.section
->output_offset
);
2908 /* Fill in the entry in the .rela.plt section. */
2909 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
2913 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
2914 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
2916 if (!h
->def_regular
)
2918 /* Mark the symbol as undefined, rather than as defined in
2919 the .plt section. Leave the value alone. */
2920 sym
->st_shndx
= SHN_UNDEF
;
2921 /* If the symbol is weak, we do need to clear the value.
2922 Otherwise, the PLT entry would provide a definition for
2923 the symbol even if the symbol wasn't defined anywhere,
2924 and so the symbol would never be NULL. */
2925 if (!h
->ref_regular_nonweak
)
2930 if (h
->got
.offset
!= MINUS_ONE
2931 /* TLS got entry have been handled in elf_relocate_section. */
2932 && !(loongarch_elf_hash_entry (h
)->tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
2933 /* have allocated got entry but not allocated rela before. */
2934 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2936 asection
*sgot
, *srela
;
2937 Elf_Internal_Rela rela
;
2938 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
) 1;
2940 /* This symbol has an entry in the GOT. Set it up. */
2942 sgot
= htab
->elf
.sgot
;
2943 srela
= htab
->elf
.srelgot
;
2944 BFD_ASSERT (sgot
&& srela
);
2946 rela
.r_offset
= sec_addr (sgot
) + off
;
2949 && h
->type
== STT_GNU_IFUNC
)
2951 if(h
->plt
.offset
== MINUS_ONE
)
2953 if (htab
->elf
.splt
== NULL
)
2954 srela
= htab
->elf
.irelplt
;
2956 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
2958 asection
*sec
= h
->root
.u
.def
.section
;
2959 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2960 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
2961 + sec
->output_offset
;
2962 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
2966 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
2967 BFD_ASSERT (h
->dynindx
!= -1);
2968 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2970 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
2973 else if(bfd_link_pic (info
))
2975 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2977 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
2982 /* For non-shared object, we can't use .got.plt, which
2983 contains the real function address if we need pointer
2984 equality. We load the GOT entry with the PLT entry. */
2985 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
2986 bfd_put_NN (output_bfd
,
2987 (plt
->output_section
->vma
2988 + plt
->output_offset
2990 sgot
->contents
+ off
);
2994 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
2996 BFD_ASSERT (h
->got
.offset
& 1 /* Has been filled in addr. */);
2997 asection
*sec
= h
->root
.u
.def
.section
;
2998 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2999 rela
.r_addend
= (h
->root
.u
.def
.value
+ sec
->output_section
->vma
3000 + sec
->output_offset
);
3004 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
3005 BFD_ASSERT (h
->dynindx
!= -1);
3006 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
3010 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
3015 Elf_Internal_Rela rela
;
3018 /* This symbols needs a copy reloc. Set it up. */
3019 BFD_ASSERT (h
->dynindx
!= -1);
3021 rela
.r_offset
= sec_addr (h
->root
.u
.def
.section
) + h
->root
.u
.def
.value
;
3022 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_COPY
);
3024 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3025 s
= htab
->elf
.sreldynrelro
;
3027 s
= htab
->elf
.srelbss
;
3028 loongarch_elf_append_rela (output_bfd
, s
, &rela
);
3031 /* Mark some specially defined symbols as absolute. */
3032 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
3033 sym
->st_shndx
= SHN_ABS
;
3038 /* Finish up the dynamic sections. */
3041 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
3044 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3045 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
3046 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
3047 bfd_byte
*dyncon
, *dynconend
;
3049 dynconend
= sdyn
->contents
+ sdyn
->size
;
3050 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
3052 Elf_Internal_Dyn dyn
;
3056 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
3061 s
= htab
->elf
.sgotplt
;
3062 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3065 s
= htab
->elf
.srelplt
;
3066 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3069 s
= htab
->elf
.srelplt
;
3070 dyn
.d_un
.d_val
= s
->size
;
3073 if ((info
->flags
& DF_TEXTREL
) == 0)
3077 if ((info
->flags
& DF_TEXTREL
) == 0)
3078 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
3082 skipped_size
+= dynsize
;
3084 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
3086 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
3087 memset (dyncon
- skipped_size
, 0, skipped_size
);
3091 /* Finish up local dynamic symbol handling. We set the contents of
3092 various dynamic sections here. */
3095 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
3097 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
3098 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
3100 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
3104 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
3105 struct bfd_link_info
*info
)
3108 asection
*sdyn
, *plt
, *gotplt
= NULL
;
3109 struct loongarch_elf_link_hash_table
*htab
;
3111 htab
= loongarch_elf_hash_table (info
);
3113 dynobj
= htab
->elf
.dynobj
;
3114 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3116 if (elf_hash_table (info
)->dynamic_sections_created
)
3118 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
3120 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
3124 plt
= htab
->elf
.splt
;
3125 gotplt
= htab
->elf
.sgotplt
;
3127 if (plt
&& 0 < plt
->size
)
3130 uint32_t plt_header
[PLT_HEADER_INSNS
];
3131 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
3135 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
3136 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
3138 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
3142 if (htab
->elf
.sgotplt
)
3144 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
3146 if (bfd_is_abs_section (output_section
))
3148 _bfd_error_handler (_("discarded output section: `%pA'"),
3153 if (0 < htab
->elf
.sgotplt
->size
)
3155 /* Write the first two entries in .got.plt, needed for the dynamic
3157 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
3159 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
3160 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
3163 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
3168 asection
*output_section
= htab
->elf
.sgot
->output_section
;
3170 if (0 < htab
->elf
.sgot
->size
)
3172 /* Set the first entry in the global offset table to the address of
3173 the dynamic section. */
3174 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
3175 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
3178 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
3181 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
3182 htab_traverse (htab
->loc_hash_table
,
3183 (void *) elfNN_loongarch_finish_local_dynamic_symbol
, info
);
3188 /* Return address for Ith PLT stub in section PLT, for relocation REL
3189 or (bfd_vma) -1 if it should not be included. */
3192 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
3193 const arelent
*rel ATTRIBUTE_UNUSED
)
3195 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
3198 static enum elf_reloc_type_class
3199 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
3200 const asection
*rel_sec ATTRIBUTE_UNUSED
,
3201 const Elf_Internal_Rela
*rela
)
3203 struct loongarch_elf_link_hash_table
*htab
;
3204 htab
= loongarch_elf_hash_table (info
);
3206 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
3208 /* Check relocation against STT_GNU_IFUNC symbol if there are
3210 bfd
*abfd
= info
->output_bfd
;
3211 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
3212 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
3213 if (r_symndx
!= STN_UNDEF
)
3215 Elf_Internal_Sym sym
;
3216 if (!bed
->s
->swap_symbol_in (abfd
,
3217 htab
->elf
.dynsym
->contents
3218 + r_symndx
* bed
->s
->sizeof_sym
,
3221 /* xgettext:c-format */
3222 _bfd_error_handler (_("%pB symbol number %lu references"
3223 " nonexistent SHT_SYMTAB_SHNDX section"),
3225 /* Ideally an error class should be returned here. */
3227 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
3228 return reloc_class_ifunc
;
3232 switch (ELFNN_R_TYPE (rela
->r_info
))
3234 case R_LARCH_IRELATIVE
:
3235 return reloc_class_ifunc
;
3236 case R_LARCH_RELATIVE
:
3237 return reloc_class_relative
;
3238 case R_LARCH_JUMP_SLOT
:
3239 return reloc_class_plt
;
3241 return reloc_class_copy
;
3243 return reloc_class_normal
;
3247 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3250 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
3251 struct elf_link_hash_entry
*dir
,
3252 struct elf_link_hash_entry
*ind
)
3254 struct elf_link_hash_entry
*edir
, *eind
;
3259 if (eind
->dyn_relocs
!= NULL
)
3261 if (edir
->dyn_relocs
!= NULL
)
3263 struct elf_dyn_relocs
**pp
;
3264 struct elf_dyn_relocs
*p
;
3266 /* Add reloc counts against the indirect sym to the direct sym
3267 list. Merge any entries against the same section. */
3268 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
3270 struct elf_dyn_relocs
*q
;
3272 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
3273 if (q
->sec
== p
->sec
)
3275 q
->pc_count
+= p
->pc_count
;
3276 q
->count
+= p
->count
;
3283 *pp
= edir
->dyn_relocs
;
3286 edir
->dyn_relocs
= eind
->dyn_relocs
;
3287 eind
->dyn_relocs
= NULL
;
3290 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
3292 loongarch_elf_hash_entry(edir
)->tls_type
3293 = loongarch_elf_hash_entry(eind
)->tls_type
;
3294 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
3296 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
3299 #define PRSTATUS_SIZE 0x1d8
3300 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
3301 #define PRSTATUS_OFFSET_PR_PID 0x20
3302 #define ELF_GREGSET_T_SIZE 0x168
3303 #define PRSTATUS_OFFSET_PR_REG 0x70
3305 /* Support for core dump NOTE sections. */
3308 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
3310 switch (note
->descsz
)
3315 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
3318 elf_tdata (abfd
)->core
->signal
=
3319 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
3322 elf_tdata (abfd
)->core
->lwpid
=
3323 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
3327 /* Make a ".reg/999" section. */
3328 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
3330 + PRSTATUS_OFFSET_PR_REG
);
3333 #define PRPSINFO_SIZE 0x88
3334 #define PRPSINFO_OFFSET_PR_PID 0x18
3335 #define PRPSINFO_OFFSET_PR_FNAME 0x28
3336 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
3337 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
3338 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
3342 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
3344 switch (note
->descsz
)
3349 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
3352 elf_tdata (abfd
)->core
->pid
=
3353 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
3356 elf_tdata (abfd
)->core
->program
=
3357 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
3358 PRPSINFO_SIZEOF_PR_FNAME
);
3361 elf_tdata (abfd
)->core
->command
=
3362 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
3363 PRPSINFO_SIZEOF_PR_PS_ARGS
);
3367 /* Note that for some reason, a spurious space is tacked
3368 onto the end of the args in some (at least one anyway)
3369 implementations, so strip it off if it exists. */
3372 char *command
= elf_tdata (abfd
)->core
->command
;
3373 int n
= strlen (command
);
3375 if (0 < n
&& command
[n
- 1] == ' ')
3376 command
[n
- 1] = '\0';
3382 /* Set the right mach type. */
3384 loongarch_elf_object_p (bfd
*abfd
)
3386 /* There are only two mach types in LoongArch currently. */
3387 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
3388 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
3390 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
3395 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
3396 Elf_Internal_Rela
*rel
,
3397 struct elf_link_hash_entry
*h
,
3398 Elf_Internal_Sym
*sym
)
3401 switch (ELFNN_R_TYPE (rel
->r_info
))
3403 case R_LARCH_GNU_VTINHERIT
:
3404 case R_LARCH_GNU_VTENTRY
:
3408 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
3411 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3412 executable PLT slots where the executable never takes the address of those
3413 functions, the function symbols are not added to the hash table. */
3416 elf_loongarch64_hash_symbol (struct elf_link_hash_entry
*h
)
3418 if (h
->plt
.offset
!= (bfd_vma
) -1
3420 && !h
->pointer_equality_needed
)
3423 return _bfd_elf_hash_symbol (h
);
3426 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
3427 #define TARGET_LITTLE_NAME "elfNN-loongarch"
3428 #define ELF_ARCH bfd_arch_loongarch
3429 #define ELF_TARGET_ID LARCH_ELF_DATA
3430 #define ELF_MACHINE_CODE EM_LOONGARCH
3431 #define ELF_MAXPAGESIZE 0x4000
3432 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
3433 #define bfd_elfNN_bfd_link_hash_table_create \
3434 loongarch_elf_link_hash_table_create
3435 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
3436 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
3437 #define elf_info_to_howto loongarch_info_to_howto_rela
3438 #define bfd_elfNN_bfd_merge_private_bfd_data \
3439 elfNN_loongarch_merge_private_bfd_data
3441 #define elf_backend_reloc_type_class loongarch_reloc_type_class
3442 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
3443 #define elf_backend_create_dynamic_sections \
3444 loongarch_elf_create_dynamic_sections
3445 #define elf_backend_check_relocs loongarch_elf_check_relocs
3446 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
3447 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
3448 #define elf_backend_relocate_section loongarch_elf_relocate_section
3449 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
3450 #define elf_backend_finish_dynamic_sections \
3451 loongarch_elf_finish_dynamic_sections
3452 #define elf_backend_object_p loongarch_elf_object_p
3453 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
3454 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
3455 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
3456 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
3457 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
3459 #include "elfNN-target.h"