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_can_refcount 1 */
129 #define elf_backend_want_got_sym 1
131 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
133 #define elf_backend_want_dynrelro 1
134 /* #define elf_backend_rela_normal 1
135 #define elf_backend_default_execstack 0 */
137 /* Generate a PLT header. */
140 loongarch_make_plt_header (bfd_vma got_plt_addr
, bfd_vma plt_header_addr
,
143 bfd_vma pcrel
= got_plt_addr
- plt_header_addr
;
146 if (pcrel
+ 0x80000800 > 0xffffffff)
148 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
149 bfd_set_error (bfd_error_bad_value
);
152 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
155 /* pcaddu12i $t2, %hi(%pcrel(.got.plt))
156 sub.[wd] $t1, $t1, $t3
157 ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
158 addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12)
159 addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt))
160 srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
161 ld.[wd] $t0, $t0, GOT_ENTRY_SIZE
164 if (GOT_ENTRY_SIZE
== 8)
166 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
167 entry
[1] = 0x0011bdad;
168 entry
[2] = 0x28c001cf | (lo
& 0xfff) << 10;
169 entry
[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
170 entry
[4] = 0x02c001cc | (lo
& 0xfff) << 10;
171 entry
[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
172 entry
[6] = 0x28c0018c | GOT_ENTRY_SIZE
<< 10;
173 entry
[7] = 0x4c0001e0;
177 entry
[0] = 0x1c00000e | (hi
& 0xfffff) << 5;
178 entry
[1] = 0x00113dad;
179 entry
[2] = 0x288001cf | (lo
& 0xfff) << 10;
180 entry
[3] = 0x028001ad | ((-(PLT_HEADER_SIZE
+ 12)) & 0xfff) << 10;
181 entry
[4] = 0x028001cc | (lo
& 0xfff) << 10;
182 entry
[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES
) << 10;
183 entry
[6] = 0x2880018c | GOT_ENTRY_SIZE
<< 10;
184 entry
[7] = 0x4c0001e0;
189 /* Generate a PLT entry. */
192 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr
, bfd_vma plt_entry_addr
,
195 bfd_vma pcrel
= got_plt_entry_addr
- plt_entry_addr
;
198 if (pcrel
+ 0x80000800 > 0xffffffff)
200 _bfd_error_handler (_("%#" PRIx64
" invaild imm"), (uint64_t) pcrel
);
201 bfd_set_error (bfd_error_bad_value
);
204 hi
= ((pcrel
+ 0x800) >> 12) & 0xfffff;
207 entry
[0] = 0x1c00000f | (hi
& 0xfffff) << 5;
208 entry
[1] = ((GOT_ENTRY_SIZE
== 8 ? 0x28c001ef : 0x288001ef)
209 | (lo
& 0xfff) << 10);
210 entry
[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */
211 entry
[3] = 0x03400000; /* nop */
216 /* Create an entry in an LoongArch ELF linker hash table. */
218 static struct bfd_hash_entry
*
219 link_hash_newfunc (struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
222 struct loongarch_elf_link_hash_entry
*eh
;
224 /* Allocate the structure if it has not already been allocated by a
228 entry
= bfd_hash_allocate (table
, sizeof (*eh
));
233 /* Call the allocation method of the superclass. */
234 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
237 eh
= (struct loongarch_elf_link_hash_entry
*) entry
;
238 eh
->tls_type
= GOT_UNKNOWN
;
244 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
245 for local symbol so that we can handle local STT_GNU_IFUNC symbols
246 as global symbol. We reuse indx and dynstr_index for local symbol
247 hash since they aren't used by global symbols in this backend. */
250 elfNN_loongarch_local_htab_hash (const void *ptr
)
252 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) ptr
;
253 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
256 /* Compare local hash entries. */
259 elfNN_loongarch_local_htab_eq (const void *ptr1
, const void *ptr2
)
261 struct elf_link_hash_entry
*h1
= (struct elf_link_hash_entry
*) ptr1
;
262 struct elf_link_hash_entry
*h2
= (struct elf_link_hash_entry
*) ptr2
;
264 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
267 /* Find and/or create a hash entry for local symbol. */
268 static struct elf_link_hash_entry
*
269 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table
*htab
,
270 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
273 struct loongarch_elf_link_hash_entry e
, *ret
;
274 asection
*sec
= abfd
->sections
;
275 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
, ELFNN_R_SYM (rel
->r_info
));
278 e
.elf
.indx
= sec
->id
;
279 e
.elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
280 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
281 create
? INSERT
: NO_INSERT
);
288 ret
= (struct loongarch_elf_link_hash_entry
*) *slot
;
292 ret
= ((struct loongarch_elf_link_hash_entry
*)
293 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
294 sizeof (struct loongarch_elf_link_hash_entry
)));
297 memset (ret
, 0, sizeof (*ret
));
298 ret
->elf
.indx
= sec
->id
;
299 ret
->elf
.pointer_equality_needed
= 0;
300 ret
->elf
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
301 ret
->elf
.dynindx
= -1;
302 ret
->elf
.needs_plt
= 0;
303 ret
->elf
.plt
.refcount
= -1;
304 ret
->elf
.got
.refcount
= -1;
305 ret
->elf
.def_dynamic
= 0;
306 ret
->elf
.def_regular
= 1;
307 ret
->elf
.ref_dynamic
= 0; /* This should be always 0 for local. */
308 ret
->elf
.ref_regular
= 0;
309 ret
->elf
.forced_local
= 1;
310 ret
->elf
.root
.type
= bfd_link_hash_defined
;
316 /* Destroy an LoongArch elf linker hash table. */
319 elfNN_loongarch_link_hash_table_free (bfd
*obfd
)
321 struct loongarch_elf_link_hash_table
*ret
;
322 ret
= (struct loongarch_elf_link_hash_table
*) obfd
->link
.hash
;
324 if (ret
->loc_hash_table
)
325 htab_delete (ret
->loc_hash_table
);
326 if (ret
->loc_hash_memory
)
327 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
329 _bfd_elf_link_hash_table_free (obfd
);
332 /* Create a LoongArch ELF linker hash table. */
334 static struct bfd_link_hash_table
*
335 loongarch_elf_link_hash_table_create (bfd
*abfd
)
337 struct loongarch_elf_link_hash_table
*ret
;
338 bfd_size_type amt
= sizeof (struct loongarch_elf_link_hash_table
);
340 ret
= (struct loongarch_elf_link_hash_table
*) bfd_zmalloc (amt
);
344 if (!_bfd_elf_link_hash_table_init
345 (&ret
->elf
, abfd
, link_hash_newfunc
,
346 sizeof (struct loongarch_elf_link_hash_entry
), LARCH_ELF_DATA
))
352 ret
->max_alignment
= MINUS_ONE
;
354 ret
->loc_hash_table
= htab_try_create (1024, elfNN_loongarch_local_htab_hash
,
355 elfNN_loongarch_local_htab_eq
, NULL
);
356 ret
->loc_hash_memory
= objalloc_create ();
357 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
359 elfNN_loongarch_link_hash_table_free (abfd
);
362 ret
->elf
.root
.hash_table_free
= elfNN_loongarch_link_hash_table_free
;
364 return &ret
->elf
.root
;
367 /* Merge backend specific data from an object file to the output
368 object file when linking. */
371 elfNN_loongarch_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
373 bfd
*obfd
= info
->output_bfd
;
374 flagword in_flags
= elf_elfheader (ibfd
)->e_flags
;
375 flagword out_flags
= elf_elfheader (obfd
)->e_flags
;
377 if (!is_loongarch_elf (ibfd
) || !is_loongarch_elf (obfd
))
380 if (strcmp (bfd_get_target (ibfd
), bfd_get_target (obfd
)) != 0)
382 _bfd_error_handler (_("%pB: ABI is incompatible with that of "
383 "the selected emulation:\n"
384 " target emulation `%s' does not match `%s'"),
385 ibfd
, bfd_get_target (ibfd
), bfd_get_target (obfd
));
389 if (!_bfd_elf_merge_object_attributes (ibfd
, info
))
392 if (!elf_flags_init (obfd
))
394 elf_flags_init (obfd
) = true;
395 elf_elfheader (obfd
)->e_flags
= in_flags
;
399 /* Disallow linking different ABIs. */
400 if (EF_LOONGARCH_ABI(out_flags
^ in_flags
) & EF_LOONGARCH_ABI_MASK
)
402 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd
);
409 bfd_set_error (bfd_error_bad_value
);
413 /* Create the .got section. */
416 loongarch_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
421 struct elf_link_hash_entry
*h
;
422 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
423 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
425 /* This function may be called more than once. */
426 if (htab
->sgot
!= NULL
)
429 flags
= bed
->dynamic_sec_flags
;
430 name
= bed
->rela_plts_and_copies_p
? ".rela.got" : ".rel.got";
431 s
= bfd_make_section_anyway_with_flags (abfd
, name
, flags
| SEC_READONLY
);
433 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
437 s
= s_got
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
438 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
442 /* The first bit of the global offset table is the header. */
443 s
->size
+= bed
->got_header_size
;
445 if (bed
->want_got_plt
)
447 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
448 if (s
== NULL
|| !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
452 /* Reserve room for the header. */
453 s
->size
= GOTPLT_HEADER_SIZE
;
456 if (bed
->want_got_sym
)
458 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
459 section. We don't do this in the linker script because we don't want
460 to define the symbol if we are not creating a global offset table. */
461 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s_got
,
462 "_GLOBAL_OFFSET_TABLE_");
463 elf_hash_table (info
)->hgot
= h
;
470 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
471 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
475 loongarch_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
477 struct loongarch_elf_link_hash_table
*htab
;
479 htab
= loongarch_elf_hash_table (info
);
480 BFD_ASSERT (htab
!= NULL
);
482 if (!loongarch_elf_create_got_section (dynobj
, info
))
485 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
488 if (!bfd_link_pic (info
))
490 = bfd_make_section_anyway_with_flags (dynobj
, ".tdata.dyn",
491 SEC_ALLOC
| SEC_THREAD_LOCAL
);
493 if (!htab
->elf
.splt
|| !htab
->elf
.srelplt
|| !htab
->elf
.sdynbss
494 || (!bfd_link_pic (info
) && (!htab
->elf
.srelbss
|| !htab
->sdyntdata
)))
501 loongarch_elf_record_tls_and_got_reference (bfd
*abfd
,
502 struct bfd_link_info
*info
,
503 struct elf_link_hash_entry
*h
,
504 unsigned long symndx
,
507 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
508 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
510 /* This is a global offset table entry for a local symbol. */
511 if (elf_local_got_refcounts (abfd
) == NULL
)
514 symtab_hdr
->sh_info
* (sizeof (bfd_vma
) + sizeof (tls_type
));
515 if (!(elf_local_got_refcounts (abfd
) = bfd_zalloc (abfd
, size
)))
517 _bfd_loongarch_elf_local_got_tls_type (abfd
) =
518 (char *) (elf_local_got_refcounts (abfd
) + symtab_hdr
->sh_info
);
527 if (htab
->elf
.sgot
== NULL
528 && !loongarch_elf_create_got_section (htab
->elf
.dynobj
, info
))
532 if (h
->got
.refcount
< 0)
537 elf_local_got_refcounts (abfd
)[symndx
]++;
540 /* No need for GOT. */
543 _bfd_error_handler (_("Internal error: unreachable."));
547 char *new_tls_type
= &_bfd_loongarch_elf_tls_type (abfd
, h
, symndx
);
548 *new_tls_type
|= tls_type
;
549 if ((*new_tls_type
& GOT_NORMAL
) && (*new_tls_type
& ~GOT_NORMAL
))
551 _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
552 "thread local symbol"),
554 h
? h
->root
.root
.string
: "<local>");
561 /* Look through the relocs for a section during the first phase, and
562 allocate space in the global offset table or procedure linkage
566 loongarch_elf_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
567 asection
*sec
, const Elf_Internal_Rela
*relocs
)
569 struct loongarch_elf_link_hash_table
*htab
;
570 Elf_Internal_Shdr
*symtab_hdr
;
571 struct elf_link_hash_entry
**sym_hashes
;
572 const Elf_Internal_Rela
*rel
;
573 asection
*sreloc
= NULL
;
575 if (bfd_link_relocatable (info
))
578 htab
= loongarch_elf_hash_table (info
);
579 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
580 sym_hashes
= elf_sym_hashes (abfd
);
582 if (htab
->elf
.dynobj
== NULL
)
583 htab
->elf
.dynobj
= abfd
;
585 for (rel
= relocs
; rel
< relocs
+ sec
->reloc_count
; rel
++)
588 unsigned int r_symndx
;
589 struct elf_link_hash_entry
*h
;
590 Elf_Internal_Sym
*isym
= NULL
;
595 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
596 r_type
= ELFNN_R_TYPE (rel
->r_info
);
598 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
600 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
604 if (r_symndx
< symtab_hdr
->sh_info
)
606 /* A local symbol. */
607 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
, abfd
, r_symndx
);
611 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
613 h
= elfNN_loongarch_get_local_sym_hash (htab
, abfd
, rel
, true);
617 h
->type
= STT_GNU_IFUNC
;
625 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
626 while (h
->root
.type
== bfd_link_hash_indirect
627 || h
->root
.type
== bfd_link_hash_warning
)
628 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
631 /* It is referenced by a non-shared object. */
635 if (h
&& h
->type
== STT_GNU_IFUNC
)
637 if (htab
->elf
.dynobj
== NULL
)
638 htab
->elf
.dynobj
= abfd
;
640 /* Create the ifunc sections, iplt and ipltgot, for static
642 if ((r_type
== R_LARCH_64
|| r_type
== R_LARCH_32
)
643 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
647 && !_bfd_elf_create_ifunc_sections (htab
->elf
.dynobj
, info
))
648 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
651 if (h
->plt
.refcount
< 0)
656 elf_tdata (info
->output_bfd
)->has_gnu_osabi
|= elf_gnu_osabi_ifunc
;
663 case R_LARCH_SOP_PUSH_GPREL
:
664 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
670 case R_LARCH_SOP_PUSH_TLS_GD
:
671 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
677 case R_LARCH_SOP_PUSH_TLS_GOT
:
678 if (bfd_link_pic (info
))
679 /* May fail for lazy-bind. */
680 info
->flags
|= DF_STATIC_TLS
;
682 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
688 case R_LARCH_SOP_PUSH_TLS_TPREL
:
689 if (!bfd_link_executable (info
))
692 info
->flags
|= DF_STATIC_TLS
;
694 if (!loongarch_elf_record_tls_and_got_reference (abfd
, info
, h
,
700 case R_LARCH_SOP_PUSH_ABSOLUTE
:
702 /* If this reloc is in a read-only section, we might
703 need a copy reloc. We can't check reliably at this
704 stage whether the section is read-only, as input
705 sections have not yet been mapped to output sections.
706 Tentatively set the flag for now, and correct in
707 adjust_dynamic_symbol. */
711 case R_LARCH_SOP_PUSH_PCREL
:
716 /* We try to create PLT stub for all non-local function. */
717 if (h
->plt
.refcount
< 0)
723 case R_LARCH_SOP_PUSH_PLT_PCREL
:
724 /* This symbol requires a procedure linkage table entry. We
725 actually build the entry in adjust_dynamic_symbol,
726 because this might be a case of linking PIC code without
727 linking in any dynamic objects, in which case we don't
728 need to generate a procedure linkage table after all. */
732 if (h
->plt
.refcount
< 0)
738 case R_LARCH_TLS_DTPREL32
:
739 case R_LARCH_TLS_DTPREL64
:
744 case R_LARCH_JUMP_SLOT
:
749 /* If resolved symbol is defined in this object,
750 1. Under pie, the symbol is known. We convert it
751 into R_LARCH_RELATIVE and need load-addr still.
752 2. Under pde, the symbol is known and we can discard R_LARCH_NN.
753 3. Under dll, R_LARCH_NN can't be changed normally, since
754 its defination could be covered by the one in executable.
755 For symbolic, we convert it into R_LARCH_RELATIVE.
756 Thus, only under pde, it needs pcrel only. We discard it. */
757 only_need_pcrel
= bfd_link_pde (info
);
763 && (!bfd_link_pic (info
)
764 || h
->type
== STT_GNU_IFUNC
))
766 /* This reloc might not bind locally. */
768 h
->pointer_equality_needed
= 1;
771 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
773 /* We may need a .plt entry if the symbol is a function
774 defined in a shared lib or is a function referenced
775 from the code or read-only section. */
776 h
->plt
.refcount
+= 1;
781 case R_LARCH_GNU_VTINHERIT
:
782 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
786 case R_LARCH_GNU_VTENTRY
:
787 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
795 /* Record some info for sizing and allocating dynamic entry. */
796 if (need_dynreloc
&& (sec
->flags
& SEC_ALLOC
))
798 /* When creating a shared object, we must copy these
799 relocs into the output file. We create a reloc
800 section in dynobj and make room for the reloc. */
801 struct elf_dyn_relocs
*p
;
802 struct elf_dyn_relocs
**head
;
807 = _bfd_elf_make_dynamic_reloc_section (sec
, htab
->elf
.dynobj
,
808 LARCH_ELF_LOG_WORD_BYTES
,
809 abfd
, /*rela?*/ true);
814 /* If this is a global symbol, we count the number of
815 relocations we need for this symbol. */
817 head
= &h
->dyn_relocs
;
820 /* Track dynamic relocs needed for local syms too.
821 We really need local syms available to do this
827 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
831 vpp
= &elf_section_data (s
)->local_dynrel
;
832 head
= (struct elf_dyn_relocs
**) vpp
;
836 if (p
== NULL
|| p
->sec
!= sec
)
838 bfd_size_type amt
= sizeof *p
;
839 p
= (struct elf_dyn_relocs
*) bfd_alloc (htab
->elf
.dynobj
, amt
);
850 p
->pc_count
+= only_need_pcrel
;
857 /* Find dynamic relocs for H that apply to read-only sections. */
860 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
862 struct elf_dyn_relocs
*p
;
864 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
866 asection
*s
= p
->sec
->output_section
;
868 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
874 /* Adjust a symbol defined by a dynamic object and referenced by a
875 regular object. The current definition is in some section of the
876 dynamic object, but we're not including those sections. We have to
877 change the definition to something the rest of the link can
880 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
881 struct elf_link_hash_entry
*h
)
883 struct loongarch_elf_link_hash_table
*htab
;
884 struct loongarch_elf_link_hash_entry
*eh
;
888 htab
= loongarch_elf_hash_table (info
);
889 BFD_ASSERT (htab
!= NULL
);
891 dynobj
= htab
->elf
.dynobj
;
893 /* Make sure we know what is going on here. */
894 BFD_ASSERT (dynobj
!= NULL
895 && (h
->needs_plt
|| h
->type
== STT_GNU_IFUNC
|| h
->is_weakalias
896 || (h
->def_dynamic
&& h
->ref_regular
&& !h
->def_regular
)));
898 /* If this is a function, put it in the procedure linkage table. We
899 will fill in the contents of the procedure linkage table later
900 (although we could actually do it here). */
901 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
903 if (h
->plt
.refcount
< 0
904 || (h
->type
!= STT_GNU_IFUNC
905 && (SYMBOL_REFERENCES_LOCAL (info
, h
)
906 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
907 && h
->root
.type
== bfd_link_hash_undefweak
))))
909 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
910 in an input file, but the symbol was never referred to by a
911 dynamic object, or if all references were garbage collected.
912 In such a case, we don't actually need to build a PLT entry. */
913 h
->plt
.offset
= MINUS_ONE
;
922 h
->plt
.offset
= MINUS_ONE
;
924 /* If this is a weak symbol, and there is a real definition, the
925 processor independent code will have arranged for us to see the
926 real definition first, and we can just use the same value. */
929 struct elf_link_hash_entry
*def
= weakdef (h
);
930 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
931 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
932 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
936 /* This is a reference to a symbol defined by a dynamic object which
937 is not a function. */
939 /* If we are creating a shared library, we must presume that the
940 only references to the symbol are via the global offset table.
941 For such cases we need not do anything here; the relocations will
942 be handled correctly by relocate_section. */
943 if (bfd_link_dll (info
))
946 /* If there are no references to this symbol that do not use the
947 GOT, we don't need to generate a copy reloc. */
951 /* If -z nocopyreloc was given, we won't generate them either. */
952 if (info
->nocopyreloc
)
958 /* If we don't find any dynamic relocs in read-only sections, then
959 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
960 if (!readonly_dynrelocs (h
))
966 /* We must allocate the symbol in our .dynbss section, which will
967 become part of the .bss section of the executable. There will be
968 an entry for this symbol in the .dynsym section. The dynamic
969 object will contain position independent code, so all references
970 from the dynamic object to this symbol will go through the global
971 offset table. The dynamic linker will use the .dynsym entry to
972 determine the address it must put in the global offset table, so
973 both the dynamic object and the regular object will refer to the
974 same memory location for the variable. */
976 /* We must generate a R_LARCH_COPY reloc to tell the dynamic linker
977 to copy the initial value out of the dynamic object and into the
978 runtime process image. We need to remember the offset into the
979 .rel.bss section we are going to use. */
980 eh
= (struct loongarch_elf_link_hash_entry
*) h
;
981 if (eh
->tls_type
& ~GOT_NORMAL
)
984 srel
= htab
->elf
.srelbss
;
986 else if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
988 s
= htab
->elf
.sdynrelro
;
989 srel
= htab
->elf
.sreldynrelro
;
993 s
= htab
->elf
.sdynbss
;
994 srel
= htab
->elf
.srelbss
;
996 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
998 srel
->size
+= sizeof (ElfNN_External_Rela
);
1002 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
1005 /* Allocate space in .plt, .got and associated reloc sections for
1009 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
1011 struct bfd_link_info
*info
;
1012 struct loongarch_elf_link_hash_table
*htab
;
1013 struct elf_dyn_relocs
*p
;
1015 if (h
->root
.type
== bfd_link_hash_indirect
)
1018 if (h
->type
== STT_GNU_IFUNC
1022 info
= (struct bfd_link_info
*) inf
;
1023 htab
= loongarch_elf_hash_table (info
);
1024 BFD_ASSERT (htab
!= NULL
);
1028 asection
*plt
, *gotplt
, *relplt
;
1037 if (h
->dynindx
== -1 && !h
->forced_local
1038 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
1041 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
)
1042 && h
->type
!= STT_GNU_IFUNC
)
1045 plt
= htab
->elf
.splt
;
1046 gotplt
= htab
->elf
.sgotplt
;
1047 relplt
= htab
->elf
.srelplt
;
1049 else if (htab
->elf
.iplt
)
1051 /* .iplt only for IFUNC. */
1052 if (h
->type
!= STT_GNU_IFUNC
)
1055 plt
= htab
->elf
.iplt
;
1056 gotplt
= htab
->elf
.igotplt
;
1057 relplt
= htab
->elf
.irelplt
;
1063 plt
->size
= PLT_HEADER_SIZE
;
1065 h
->plt
.offset
= plt
->size
;
1066 plt
->size
+= PLT_ENTRY_SIZE
;
1067 gotplt
->size
+= GOT_ENTRY_SIZE
;
1068 relplt
->size
+= sizeof (ElfNN_External_Rela
);
1070 /* If this symbol is not defined in a regular file, and we are
1071 not generating a shared library, then set the symbol to this
1072 location in the .plt. This is required to make function
1073 pointers compare as equal between the normal executable and
1074 the shared library. */
1075 if (!bfd_link_pic(info
)
1078 h
->root
.u
.def
.section
= plt
;
1079 h
->root
.u
.def
.value
= h
->plt
.offset
;
1087 h
->plt
.offset
= MINUS_ONE
;
1089 if (0 < h
->got
.refcount
)
1093 int tls_type
= loongarch_elf_hash_entry (h
)->tls_type
;
1095 /* Make sure this symbol is output as a dynamic symbol.
1096 Undefined weak syms won't yet be marked as dynamic. */
1097 if (h
->dynindx
== -1 && !h
->forced_local
)
1099 if (SYMBOL_REFERENCES_LOCAL (info
, h
)
1100 && (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
1103 /* The pr21964-4. do nothing. */
1107 if( !bfd_elf_link_record_dynamic_symbol (info
, h
))
1113 h
->got
.offset
= s
->size
;
1114 dyn
= htab
->elf
.dynamic_sections_created
;
1115 if (tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
1117 /* TLS_GD needs two dynamic relocs and two GOT slots. */
1118 if (tls_type
& GOT_TLS_GD
)
1120 s
->size
+= 2 * GOT_ENTRY_SIZE
;
1121 htab
->elf
.srelgot
->size
+= 2 * sizeof (ElfNN_External_Rela
);
1124 /* TLS_IE needs one dynamic reloc and one GOT slot. */
1125 if (tls_type
& GOT_TLS_IE
)
1127 s
->size
+= GOT_ENTRY_SIZE
;
1128 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1133 s
->size
+= GOT_ENTRY_SIZE
;
1134 if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
1135 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1136 || h
->type
== STT_GNU_IFUNC
)
1137 htab
->elf
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1141 h
->got
.offset
= MINUS_ONE
;
1143 if (h
->dyn_relocs
== NULL
)
1146 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
1148 struct elf_dyn_relocs
**pp
;
1150 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
1152 p
->count
-= p
->pc_count
;
1161 if (h
->root
.type
== bfd_link_hash_undefweak
)
1163 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
1164 h
->dyn_relocs
= NULL
;
1165 else if (h
->dynindx
== -1 && !h
->forced_local
1166 /* Make sure this symbol is output as a dynamic symbol.
1167 Undefined weak syms won't yet be marked as dynamic. */
1168 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
1172 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
1174 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
1175 sreloc
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1181 /* Allocate space in .plt, .got and associated reloc sections for
1182 ifunc dynamic relocs. */
1185 elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
1188 struct bfd_link_info
*info
;
1189 /* An example of a bfd_link_hash_indirect symbol is versioned
1190 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1191 -> __gxx_personality_v0(bfd_link_hash_defined)
1193 There is no need to process bfd_link_hash_indirect symbols here
1194 because we will also be presented with the concrete instance of
1195 the symbol and loongarch_elf_copy_indirect_symbol () will have been
1196 called to copy all relevant data from the generic to the concrete
1198 if (h
->root
.type
== bfd_link_hash_indirect
)
1201 if (h
->root
.type
== bfd_link_hash_warning
)
1202 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1204 info
= (struct bfd_link_info
*) inf
;
1206 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1207 here if it is defined and referenced in a non-shared object. */
1208 if (h
->type
== STT_GNU_IFUNC
1210 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
1219 /* Allocate space in .plt, .got and associated reloc sections for
1220 ifunc dynamic relocs. */
1223 elfNN_loongarch_allocate_local_dynrelocs (void **slot
, void *inf
)
1225 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
1227 if (h
->type
!= STT_GNU_IFUNC
1231 || h
->root
.type
!= bfd_link_hash_defined
)
1234 return elfNN_loongarch_allocate_ifunc_dynrelocs (h
, inf
);
1237 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1238 read-only sections. */
1241 maybe_set_textrel (struct elf_link_hash_entry
*h
, void *info_p
)
1245 if (h
->root
.type
== bfd_link_hash_indirect
)
1248 sec
= readonly_dynrelocs (h
);
1251 struct bfd_link_info
*info
= (struct bfd_link_info
*) info_p
;
1253 info
->flags
|= DF_TEXTREL
;
1254 info
->callbacks
->minfo (_("%pB: dynamic relocation against `%pT' in "
1255 "read-only section `%pA'\n"),
1256 sec
->owner
, h
->root
.root
.string
, sec
);
1258 /* Not an error, just cut short the traversal. */
1265 loongarch_elf_size_dynamic_sections (bfd
*output_bfd
,
1266 struct bfd_link_info
*info
)
1268 struct loongarch_elf_link_hash_table
*htab
;
1273 htab
= loongarch_elf_hash_table (info
);
1274 BFD_ASSERT (htab
!= NULL
);
1275 dynobj
= htab
->elf
.dynobj
;
1276 BFD_ASSERT (dynobj
!= NULL
);
1278 if (htab
->elf
.dynamic_sections_created
)
1280 /* Set the contents of the .interp section to the interpreter. */
1281 if (bfd_link_executable (info
) && !info
->nointerp
)
1283 const char *interpreter
;
1284 flagword flags
= elf_elfheader (output_bfd
)->e_flags
;
1285 s
= bfd_get_linker_section (dynobj
, ".interp");
1286 BFD_ASSERT (s
!= NULL
);
1287 if (EF_LOONGARCH_IS_ILP32 (flags
))
1288 interpreter
= "/lib32/ld.so.1";
1289 else if (EF_LOONGARCH_IS_LP64 (flags
))
1290 interpreter
= "/lib64/ld.so.1";
1292 interpreter
= "/lib/ld.so.1";
1293 s
->contents
= (unsigned char *) interpreter
;
1294 s
->size
= strlen (interpreter
) + 1;
1298 /* Set up .got offsets for local syms, and space for local dynamic
1300 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
1302 bfd_signed_vma
*local_got
;
1303 bfd_signed_vma
*end_local_got
;
1304 char *local_tls_type
;
1305 bfd_size_type locsymcount
;
1306 Elf_Internal_Shdr
*symtab_hdr
;
1309 if (!is_loongarch_elf (ibfd
))
1312 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
1314 struct elf_dyn_relocs
*p
;
1316 for (p
= elf_section_data (s
)->local_dynrel
; p
!= NULL
; p
= p
->next
)
1318 p
->count
-= p
->pc_count
;
1319 if (!bfd_is_abs_section (p
->sec
)
1320 && bfd_is_abs_section (p
->sec
->output_section
))
1322 /* Input section has been discarded, either because
1323 it is a copy of a linkonce section or due to
1324 linker script /DISCARD/, so we'll be discarding
1327 else if (0 < p
->count
)
1329 srel
= elf_section_data (p
->sec
)->sreloc
;
1330 srel
->size
+= p
->count
* sizeof (ElfNN_External_Rela
);
1331 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
1332 info
->flags
|= DF_TEXTREL
;
1337 local_got
= elf_local_got_refcounts (ibfd
);
1341 symtab_hdr
= &elf_symtab_hdr (ibfd
);
1342 locsymcount
= symtab_hdr
->sh_info
;
1343 end_local_got
= local_got
+ locsymcount
;
1344 local_tls_type
= _bfd_loongarch_elf_local_got_tls_type (ibfd
);
1346 srel
= htab
->elf
.srelgot
;
1347 for (; local_got
< end_local_got
; ++local_got
, ++local_tls_type
)
1351 *local_got
= s
->size
;
1352 s
->size
+= GOT_ENTRY_SIZE
;
1354 if (*local_tls_type
& GOT_TLS_GD
)
1355 s
->size
+= GOT_ENTRY_SIZE
;
1357 /* If R_LARCH_RELATIVE. */
1358 if (bfd_link_pic (info
)
1359 /* Or R_LARCH_TLS_DTPRELNN or R_LARCH_TLS_TPRELNN. */
1360 || (*local_tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
)))
1361 srel
->size
+= sizeof (ElfNN_External_Rela
);
1364 *local_got
= MINUS_ONE
;
1368 /* Allocate global sym .plt and .got entries, and space for global
1369 sym dynamic relocs. */
1370 elf_link_hash_traverse (&htab
->elf
, allocate_dynrelocs
, info
);
1372 /* Allocate global ifunc sym .plt and .got entries, and space for global
1373 ifunc sym dynamic relocs. */
1374 elf_link_hash_traverse (&htab
->elf
, elfNN_loongarch_allocate_ifunc_dynrelocs
, info
);
1376 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
1377 htab_traverse (htab
->loc_hash_table
,
1378 (void *) elfNN_loongarch_allocate_local_dynrelocs
, info
);
1380 /* Don't allocate .got.plt section if there are no PLT. */
1381 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
== GOTPLT_HEADER_SIZE
1382 && (htab
->elf
.splt
== NULL
|| htab
->elf
.splt
->size
== 0))
1383 htab
->elf
.sgotplt
->size
= 0;
1385 /* The check_relocs and adjust_dynamic_symbol entry points have
1386 determined the sizes of the various dynamic sections. Allocate
1388 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
1390 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
1393 if (s
== htab
->elf
.splt
|| s
== htab
->elf
.iplt
|| s
== htab
->elf
.sgot
1394 || s
== htab
->elf
.sgotplt
|| s
== htab
->elf
.igotplt
1395 || s
== htab
->elf
.sdynbss
|| s
== htab
->elf
.sdynrelro
)
1397 /* Strip this section if we don't need it; see the
1400 else if (strncmp (s
->name
, ".rela", 5) == 0)
1404 /* We use the reloc_count field as a counter if we need
1405 to copy relocs into the output file. */
1411 /* It's not one of our sections. */
1417 /* If we don't need this section, strip it from the
1418 output file. This is mostly to handle .rela.bss and
1419 .rela.plt. We must create both sections in
1420 create_dynamic_sections, because they must be created
1421 before the linker maps input sections to output
1422 sections. The linker does that before
1423 adjust_dynamic_symbol is called, and it is that
1424 function which decides whether anything needs to go
1425 into these sections. */
1426 s
->flags
|= SEC_EXCLUDE
;
1430 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
1433 /* Allocate memory for the section contents. Zero the memory
1434 for the benefit of .rela.plt, which has 4 unused entries
1435 at the beginning, and we don't want garbage. */
1436 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
1437 if (s
->contents
== NULL
)
1441 if (elf_hash_table (info
)->dynamic_sections_created
)
1443 /* Add some entries to the .dynamic section. We fill in the
1444 values later, in loongarch_elf_finish_dynamic_sections, but we
1445 must add the entries now so that we get the correct size for
1446 the .dynamic section. The DT_DEBUG entry is filled in by the
1447 dynamic linker and used by the debugger. */
1448 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1450 if (bfd_link_executable (info
))
1452 if (!add_dynamic_entry (DT_DEBUG
, 0))
1456 if (htab
->elf
.srelplt
->size
!= 0)
1458 if (!add_dynamic_entry (DT_PLTGOT
, 0)
1459 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
1460 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
1461 || !add_dynamic_entry (DT_JMPREL
, 0))
1465 if (!add_dynamic_entry (DT_RELA
, 0)
1466 || !add_dynamic_entry (DT_RELASZ
, 0)
1467 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
1470 /* If any dynamic relocs apply to a read-only section,
1471 then we need a DT_TEXTREL entry. */
1472 if ((info
->flags
& DF_TEXTREL
) == 0)
1473 elf_link_hash_traverse (&htab
->elf
, maybe_set_textrel
, info
);
1475 if (info
->flags
& DF_TEXTREL
)
1477 if (!add_dynamic_entry (DT_TEXTREL
, 0))
1479 /* Clear the DF_TEXTREL flag. It will be set again if we
1480 write out an actual text relocation; we may not, because
1481 at this point we do not know whether e.g. any .eh_frame
1482 absolute relocations have been converted to PC-relative. */
1483 info
->flags
&= ~DF_TEXTREL
;
1486 #undef add_dynamic_entry
1491 #define LARCH_LD_STACK_DEPTH 16
1492 static int64_t larch_opc_stack
[LARCH_LD_STACK_DEPTH
];
1493 static size_t larch_stack_top
= 0;
1495 static bfd_reloc_status_type
1496 loongarch_push (int64_t val
)
1498 if (LARCH_LD_STACK_DEPTH
<= larch_stack_top
)
1499 return bfd_reloc_outofrange
;
1500 larch_opc_stack
[larch_stack_top
++] = val
;
1501 return bfd_reloc_ok
;
1504 static bfd_reloc_status_type
1505 loongarch_pop (int64_t *val
)
1507 if (larch_stack_top
== 0)
1508 return bfd_reloc_outofrange
;
1510 *val
= larch_opc_stack
[--larch_stack_top
];
1511 return bfd_reloc_ok
;
1514 static bfd_reloc_status_type
1515 loongarch_top (int64_t *val
)
1517 if (larch_stack_top
== 0)
1518 return bfd_reloc_outofrange
;
1520 *val
= larch_opc_stack
[larch_stack_top
- 1];
1521 return bfd_reloc_ok
;
1525 loongarch_elf_append_rela (bfd
*abfd
, asection
*s
, Elf_Internal_Rela
*rel
)
1527 const struct elf_backend_data
*bed
;
1530 bed
= get_elf_backend_data (abfd
);
1531 loc
= s
->contents
+ (s
->reloc_count
++ * bed
->s
->sizeof_rela
);
1532 bed
->s
->swap_reloca_out (abfd
, rel
, loc
);
1535 /* Check rel->r_offset in range of contents. */
1536 static bfd_reloc_status_type
1537 loongarch_check_offset (const Elf_Internal_Rela
*rel
,
1538 const asection
*input_section
)
1540 if (0 == strcmp(input_section
->name
, ".text")
1541 && rel
->r_offset
> input_section
->size
)
1542 return bfd_reloc_overflow
;
1544 return bfd_reloc_ok
;
1547 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
1549 bfd_reloc_status_type ret = loongarch_pop (&op2); \
1550 if (ret == bfd_reloc_ok) \
1552 ret = loongarch_pop (&op1); \
1553 if (ret == bfd_reloc_ok) \
1554 ret = loongarch_push (op3); \
1559 static bfd_reloc_status_type
1560 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela
*rel
,
1561 const asection
*input_section ATTRIBUTE_UNUSED
,
1562 reloc_howto_type
*howto
, bfd
*input_bfd
,
1563 bfd_byte
*contents
, bfd_vma reloc_val
)
1565 int bits
= bfd_get_reloc_size (howto
) * 8;
1566 uint32_t insn
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1568 if (!loongarch_adjust_reloc_bitsfield(howto
, &reloc_val
))
1569 return bfd_reloc_overflow
;
1571 insn
= (insn
& (uint32_t)howto
->src_mask
)
1572 | ((insn
& (~(uint32_t)howto
->dst_mask
)) | reloc_val
);
1574 bfd_put (bits
, input_bfd
, insn
, contents
+ rel
->r_offset
);
1576 return bfd_reloc_ok
;
1579 /* Emplace a static relocation. */
1581 static bfd_reloc_status_type
1582 perform_relocation (const Elf_Internal_Rela
*rel
, asection
*input_section
,
1583 reloc_howto_type
*howto
, bfd_vma value
,
1584 bfd
*input_bfd
, bfd_byte
*contents
)
1587 int64_t opr1
, opr2
, opr3
;
1588 bfd_reloc_status_type r
= bfd_reloc_ok
;
1589 int bits
= bfd_get_reloc_size (howto
) * 8;
1592 switch (ELFNN_R_TYPE (rel
->r_info
))
1594 case R_LARCH_SOP_PUSH_PCREL
:
1595 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1596 case R_LARCH_SOP_PUSH_GPREL
:
1597 case R_LARCH_SOP_PUSH_TLS_TPREL
:
1598 case R_LARCH_SOP_PUSH_TLS_GOT
:
1599 case R_LARCH_SOP_PUSH_TLS_GD
:
1600 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1601 r
= loongarch_push (value
);
1604 case R_LARCH_SOP_PUSH_DUP
:
1605 r
= loongarch_pop (&opr1
);
1606 if (r
== bfd_reloc_ok
)
1608 r
= loongarch_push (opr1
);
1609 if (r
== bfd_reloc_ok
)
1610 r
= loongarch_push (opr1
);
1614 case R_LARCH_SOP_ASSERT
:
1615 r
= loongarch_pop (&opr1
);
1616 if (r
!= bfd_reloc_ok
|| !opr1
)
1617 r
= bfd_reloc_notsupported
;
1620 case R_LARCH_SOP_NOT
:
1621 r
= loongarch_pop (&opr1
);
1622 if (r
== bfd_reloc_ok
)
1623 r
= loongarch_push (!opr1
);
1626 case R_LARCH_SOP_SUB
:
1627 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
- opr2
);
1630 case R_LARCH_SOP_SL
:
1631 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
<< opr2
);
1634 case R_LARCH_SOP_SR
:
1635 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
>> opr2
);
1638 case R_LARCH_SOP_AND
:
1639 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
& opr2
);
1642 case R_LARCH_SOP_ADD
:
1643 r
= LARCH_RELOC_PERFORM_3OP (opr1
, opr2
, opr1
+ opr2
);
1646 case R_LARCH_SOP_IF_ELSE
:
1647 r
= loongarch_pop (&opr3
);
1648 if (r
== bfd_reloc_ok
)
1650 r
= loongarch_pop (&opr2
);
1651 if (r
== bfd_reloc_ok
)
1653 r
= loongarch_pop (&opr1
);
1654 if (r
== bfd_reloc_ok
)
1655 r
= loongarch_push (opr1
? opr2
: opr3
);
1660 case R_LARCH_SOP_POP_32_S_10_5
:
1661 case R_LARCH_SOP_POP_32_S_10_12
:
1662 case R_LARCH_SOP_POP_32_S_10_16
:
1663 case R_LARCH_SOP_POP_32_S_10_16_S2
:
1664 case R_LARCH_SOP_POP_32_S_5_20
:
1665 case R_LARCH_SOP_POP_32_U_10_12
:
1666 case R_LARCH_SOP_POP_32_U
:
1667 r
= loongarch_pop (&opr1
);
1668 if (r
!= bfd_reloc_ok
)
1670 r
= loongarch_check_offset (rel
, input_section
);
1671 if (r
!= bfd_reloc_ok
)
1674 r
= loongarch_reloc_rewrite_imm_insn (rel
, input_section
,
1676 contents
, (bfd_vma
)opr1
);
1679 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
1681 r
= loongarch_pop (&opr1
);
1682 if (r
!= bfd_reloc_ok
)
1685 if ((opr1
& 0x3) != 0)
1687 r
= bfd_reloc_overflow
;
1691 uint32_t imm
= opr1
>> howto
->rightshift
;
1692 if ((imm
& (~0xfffffU
)) && ((imm
& (~0xfffffU
)) != (~0xfffffU
)))
1694 r
= bfd_reloc_overflow
;
1697 r
= loongarch_check_offset (rel
, input_section
);
1698 if (r
!= bfd_reloc_ok
)
1701 insn1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1702 insn1
= (insn1
& howto
->src_mask
)
1703 | ((imm
& 0xffffU
) << 10)
1704 | ((imm
& 0x1f0000U
) >> 16);
1705 bfd_put (bits
, input_bfd
, insn1
, contents
+ rel
->r_offset
);
1709 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
1711 r
= loongarch_pop (&opr1
);
1712 if (r
!= bfd_reloc_ok
)
1715 if ((opr1
& 0x3) != 0)
1717 r
= bfd_reloc_overflow
;
1721 uint32_t imm
= opr1
>> howto
->rightshift
;
1722 if ((imm
& (~0x1ffffffU
)) && (imm
& (~0x1ffffffU
)) != (~0x1ffffffU
))
1724 r
= bfd_reloc_overflow
;
1728 r
= loongarch_check_offset (rel
, input_section
);
1729 if (r
!= bfd_reloc_ok
)
1732 insn1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1733 insn1
= ((insn1
& howto
->src_mask
)
1734 | ((imm
& 0xffffU
) << 10)
1735 | ((imm
& 0x3ff0000U
) >> 16));
1736 bfd_put (bits
, input_bfd
, insn1
, contents
+ rel
->r_offset
);
1740 case R_LARCH_TLS_DTPREL32
:
1742 case R_LARCH_TLS_DTPREL64
:
1744 r
= loongarch_check_offset (rel
, input_section
);
1745 if (r
!= bfd_reloc_ok
)
1748 bfd_put (bits
, input_bfd
, value
, contents
+ rel
->r_offset
);
1756 r
= loongarch_check_offset (rel
, input_section
);
1757 if (r
!= bfd_reloc_ok
)
1760 opr1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1761 bfd_put (bits
, input_bfd
, opr1
+ value
, contents
+ rel
->r_offset
);
1769 r
= loongarch_check_offset (rel
, input_section
);
1770 if (r
!= bfd_reloc_ok
)
1773 opr1
= bfd_get (bits
, input_bfd
, contents
+ rel
->r_offset
);
1774 bfd_put (bits
, input_bfd
, opr1
- value
, contents
+ rel
->r_offset
);
1778 r
= bfd_reloc_notsupported
;
1783 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
1791 Elf_Internal_Sym
*sym
;
1792 struct elf_link_hash_entry
*h
;
1795 } larch_reloc_queue
[LARCH_RECENT_RELOC_QUEUE_LENGTH
];
1796 static size_t larch_reloc_queue_head
= 0;
1797 static size_t larch_reloc_queue_tail
= 0;
1800 loongarch_sym_name (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
1801 Elf_Internal_Sym
*sym
)
1803 const char *ret
= NULL
;
1805 ret
= bfd_elf_string_from_elf_section (input_bfd
,
1806 elf_symtab_hdr (input_bfd
).sh_link
,
1809 ret
= h
->root
.root
.string
;
1811 if (ret
== NULL
|| *ret
== '\0')
1817 loongarch_record_one_reloc (bfd
*abfd
, asection
*section
, int r_type
,
1818 bfd_vma r_offset
, Elf_Internal_Sym
*sym
,
1819 struct elf_link_hash_entry
*h
, bfd_vma addend
)
1821 if ((larch_reloc_queue_head
== 0
1822 && larch_reloc_queue_tail
== LARCH_RECENT_RELOC_QUEUE_LENGTH
- 1)
1823 || larch_reloc_queue_head
== larch_reloc_queue_tail
+ 1)
1824 larch_reloc_queue_head
=
1825 (larch_reloc_queue_head
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1826 larch_reloc_queue
[larch_reloc_queue_tail
].bfd
= abfd
;
1827 larch_reloc_queue
[larch_reloc_queue_tail
].section
= section
;
1828 larch_reloc_queue
[larch_reloc_queue_tail
].r_offset
= r_offset
;
1829 larch_reloc_queue
[larch_reloc_queue_tail
].r_type
= r_type
;
1830 larch_reloc_queue
[larch_reloc_queue_tail
].sym
= sym
;
1831 larch_reloc_queue
[larch_reloc_queue_tail
].h
= h
;
1832 larch_reloc_queue
[larch_reloc_queue_tail
].addend
= addend
;
1833 loongarch_top (&larch_reloc_queue
[larch_reloc_queue_tail
].top_then
);
1834 larch_reloc_queue_tail
=
1835 (larch_reloc_queue_tail
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1839 loongarch_dump_reloc_record (void (*p
) (const char *fmt
, ...))
1841 size_t i
= larch_reloc_queue_head
;
1843 asection
*section
= NULL
;
1844 bfd_vma r_offset
= 0;
1846 p ("Dump relocate record:\n");
1847 p ("stack top\t\trelocation name\t\tsymbol");
1848 while (i
!= larch_reloc_queue_tail
)
1850 if (a_bfd
!= larch_reloc_queue
[i
].bfd
1851 || section
!= larch_reloc_queue
[i
].section
1852 || r_offset
!= larch_reloc_queue
[i
].r_offset
)
1854 a_bfd
= larch_reloc_queue
[i
].bfd
;
1855 section
= larch_reloc_queue
[i
].section
;
1856 r_offset
= larch_reloc_queue
[i
].r_offset
;
1857 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue
[i
].bfd
,
1858 larch_reloc_queue
[i
].section
, larch_reloc_queue
[i
].r_offset
);
1862 inited
= 1, p ("...\n");
1864 reloc_howto_type
*howto
=
1865 loongarch_elf_rtype_to_howto (larch_reloc_queue
[i
].bfd
,
1866 larch_reloc_queue
[i
].r_type
);
1867 p ("0x%V %s\t`%s'", (bfd_vma
) larch_reloc_queue
[i
].top_then
,
1868 howto
? howto
->name
: "<unknown reloc>",
1869 loongarch_sym_name (larch_reloc_queue
[i
].bfd
, larch_reloc_queue
[i
].h
,
1870 larch_reloc_queue
[i
].sym
));
1872 long addend
= larch_reloc_queue
[i
].addend
;
1874 p (" - %ld", -addend
);
1875 else if (0 < addend
)
1876 p (" + %ld(0x%v)", addend
, larch_reloc_queue
[i
].addend
);
1879 i
= (i
+ 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH
;
1882 "-- Record dump end --\n\n");
1887 loongarch_reloc_is_fatal (struct bfd_link_info
*info
,
1889 asection
*input_section
,
1890 Elf_Internal_Rela
*rel
,
1891 reloc_howto_type
*howto
,
1892 bfd_reloc_status_type rtype
,
1900 /* 'dangerous' means we do it but can't promise it's ok
1901 'unsupport' means out of ability of relocation type
1902 'undefined' means we can't deal with the undefined symbol. */
1903 case bfd_reloc_undefined
:
1904 info
->callbacks
->undefined_symbol (info
, name
, input_bfd
, input_section
,
1905 rel
->r_offset
, true);
1906 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1907 input_bfd
, input_section
, rel
->r_offset
,
1909 is_undefweak
? "[undefweak] " : "", name
, msg
);
1911 case bfd_reloc_dangerous
:
1912 info
->callbacks
->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
1913 input_bfd
, input_section
, rel
->r_offset
,
1915 is_undefweak
? "[undefweak] " : "", name
, msg
);
1918 case bfd_reloc_notsupported
:
1919 info
->callbacks
->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
1920 input_bfd
, input_section
, rel
->r_offset
,
1922 is_undefweak
? "[undefweak] " : "", name
, msg
);
1934 loongarch_elf_relocate_section (bfd
*output_bfd
, struct bfd_link_info
*info
,
1935 bfd
*input_bfd
, asection
*input_section
,
1936 bfd_byte
*contents
, Elf_Internal_Rela
*relocs
,
1937 Elf_Internal_Sym
*local_syms
,
1938 asection
**local_sections
)
1940 Elf_Internal_Rela
*rel
;
1941 Elf_Internal_Rela
*relend
;
1943 asection
*sreloc
= elf_section_data (input_section
)->sreloc
;
1944 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
1945 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
1946 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
1947 bfd_vma
*local_got_offsets
= elf_local_got_offsets (input_bfd
);
1948 bool is_pic
= bfd_link_pic (info
);
1949 bool is_dyn
= elf_hash_table (info
)->dynamic_sections_created
;
1950 asection
*plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
1951 asection
*got
= htab
->elf
.sgot
;
1953 relend
= relocs
+ input_section
->reloc_count
;
1954 for (rel
= relocs
; rel
< relend
; rel
++)
1956 int r_type
= ELFNN_R_TYPE (rel
->r_info
);
1957 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1958 bfd_vma pc
= sec_addr (input_section
) + rel
->r_offset
;
1959 reloc_howto_type
*howto
= NULL
;
1960 asection
*sec
= NULL
;
1961 Elf_Internal_Sym
*sym
= NULL
;
1962 struct elf_link_hash_entry
*h
= NULL
;
1964 bfd_reloc_status_type r
= bfd_reloc_ok
;
1965 bool is_ie
, is_undefweak
, unresolved_reloc
, defined_local
;
1966 bool resolved_local
, resolved_dynly
, resolved_to_const
;
1969 bfd_vma off
, ie_off
;
1972 howto
= loongarch_elf_rtype_to_howto (input_bfd
, r_type
);
1973 if (howto
== NULL
|| r_type
== R_LARCH_GNU_VTINHERIT
1974 || r_type
== R_LARCH_GNU_VTENTRY
)
1977 /* This is a final link. */
1978 if (r_symndx
< symtab_hdr
->sh_info
)
1980 is_undefweak
= false;
1981 unresolved_reloc
= false;
1982 sym
= local_syms
+ r_symndx
;
1983 sec
= local_sections
[r_symndx
];
1984 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1986 /* Relocate against local STT_GNU_IFUNC symbol. */
1987 if (!bfd_link_relocatable (info
)
1988 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
1990 h
= elfNN_loongarch_get_local_sym_hash (htab
, input_bfd
, rel
,
1995 /* Set STT_GNU_IFUNC symbol value. */
1996 h
->root
.u
.def
.value
= sym
->st_value
;
1997 h
->root
.u
.def
.section
= sec
;
1999 defined_local
= true;
2000 resolved_local
= true;
2001 resolved_dynly
= false;
2002 resolved_to_const
= false;
2003 if (bfd_link_relocatable (info
)
2004 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2005 rel
->r_addend
+= sec
->output_offset
;
2009 bool warned
, ignored
;
2011 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2012 r_symndx
, symtab_hdr
, sym_hashes
,
2014 unresolved_reloc
, warned
, ignored
);
2015 /* Here means symbol isn't local symbol only and 'h != NULL'. */
2017 /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2018 symbol. And 'dynamic_undefined_weak' specify what to do when
2019 meeting undefweak. */
2021 if ((is_undefweak
= h
->root
.type
== bfd_link_hash_undefweak
))
2023 defined_local
= false;
2024 resolved_local
= false;
2025 resolved_to_const
= (!is_dyn
|| h
->dynindx
== -1
2026 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
2027 resolved_dynly
= !resolved_local
&& !resolved_to_const
;
2031 /* Symbol undefined offen means failed already. I don't know why
2032 'warned' here but I guess it want to continue relocating as if
2033 no error occures to find other errors as more as possible. */
2035 /* To avoid generating warning messages about truncated
2036 relocations, set the relocation's address to be the same as
2037 the start of this section. */
2038 relocation
= (input_section
->output_section
2039 ? input_section
->output_section
->vma
2042 defined_local
= relocation
!= 0;
2043 resolved_local
= defined_local
;
2044 resolved_to_const
= !resolved_local
;
2045 resolved_dynly
= false;
2049 defined_local
= !unresolved_reloc
&& !ignored
;
2051 defined_local
&& SYMBOL_REFERENCES_LOCAL (info
, h
);
2052 resolved_dynly
= !resolved_local
;
2053 resolved_to_const
= !resolved_local
&& !resolved_dynly
;
2057 name
= loongarch_sym_name (input_bfd
, h
, sym
);
2059 if (sec
!= NULL
&& discarded_section (sec
))
2060 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
, rel
,
2061 1, relend
, howto
, 0, contents
);
2063 if (bfd_link_relocatable (info
))
2066 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2067 from removed linkonce sections, or sections discarded by a linker
2068 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
2069 if (r_symndx
== STN_UNDEF
|| bfd_is_abs_section (sec
))
2071 defined_local
= false;
2072 resolved_local
= false;
2073 resolved_dynly
= false;
2074 resolved_to_const
= true;
2077 /* The ifunc without reference does not generate plt. */
2078 if (h
&& h
->type
== STT_GNU_IFUNC
&& h
->plt
.offset
!= MINUS_ONE
)
2080 defined_local
= true;
2081 resolved_local
= true;
2082 resolved_dynly
= false;
2083 resolved_to_const
= false;
2084 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2087 unresolved_reloc
= resolved_dynly
;
2089 BFD_ASSERT (resolved_local
+ resolved_dynly
+ resolved_to_const
== 1);
2091 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */
2093 BFD_ASSERT (!resolved_local
|| defined_local
);
2098 case R_LARCH_MARK_PCREL
:
2099 case R_LARCH_MARK_LA
:
2101 r
= bfd_reloc_continue
;
2102 unresolved_reloc
= false;
2107 if (resolved_dynly
|| (is_pic
&& resolved_local
))
2109 Elf_Internal_Rela outrel
;
2111 /* When generating a shared object, these relocations are copied
2112 into the output file to be resolved at run time. */
2114 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2118 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2119 && (input_section
->flags
& SEC_ALLOC
));
2121 outrel
.r_offset
+= sec_addr (input_section
);
2123 /* A pointer point to a local ifunc symbol. */
2125 && h
->type
== STT_GNU_IFUNC
2126 && (h
->dynindx
== -1
2128 || bfd_link_executable(info
)))
2130 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2131 outrel
.r_addend
= (h
->root
.u
.def
.value
2132 + h
->root
.u
.def
.section
->output_section
->vma
2133 + h
->root
.u
.def
.section
->output_offset
);
2135 /* Dynamic relocations are stored in
2136 1. .rela.ifunc section in PIC object.
2137 2. .rela.got section in dynamic executable.
2138 3. .rela.iplt section in static executable. */
2139 if (bfd_link_pic (info
))
2140 sreloc
= htab
->elf
.irelifunc
;
2141 else if (htab
->elf
.splt
!= NULL
)
2142 sreloc
= htab
->elf
.srelgot
;
2144 sreloc
= htab
->elf
.irelplt
;
2146 else if (resolved_dynly
)
2148 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2149 outrel
.r_addend
= rel
->r_addend
;
2153 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2154 outrel
.r_addend
= relocation
+ rel
->r_addend
;
2157 if (unresolved_reloc
)
2158 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2161 relocation
+= rel
->r_addend
;
2175 fatal
= (loongarch_reloc_is_fatal
2176 (info
, input_bfd
, input_section
, rel
, howto
,
2177 bfd_reloc_undefined
, is_undefweak
, name
,
2178 "Can't be resolved dynamically. "
2179 "If this procedure is hand-written assembly,\n"
2180 "there must be something like '.dword sym1 - sym2' "
2181 "to generate these relocs\n"
2182 "and we can't get known link-time address of "
2185 relocation
+= rel
->r_addend
;
2188 case R_LARCH_TLS_DTPREL32
:
2189 case R_LARCH_TLS_DTPREL64
:
2192 Elf_Internal_Rela outrel
;
2194 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
2197 unresolved_reloc
= (!((bfd_vma
) -2 <= outrel
.r_offset
)
2198 && (input_section
->flags
& SEC_ALLOC
));
2199 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
2200 outrel
.r_offset
+= sec_addr (input_section
);
2201 outrel
.r_addend
= rel
->r_addend
;
2202 if (unresolved_reloc
)
2203 loongarch_elf_append_rela (output_bfd
, sreloc
, &outrel
);
2207 if (resolved_to_const
)
2208 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
, input_section
,
2210 bfd_reloc_notsupported
,
2215 if (!elf_hash_table (info
)->tls_sec
)
2217 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2218 input_section
, rel
, howto
, bfd_reloc_notsupported
,
2219 is_undefweak
, name
, "TLS section not be created");
2222 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2226 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2227 input_section
, rel
, howto
, bfd_reloc_undefined
,
2229 "TLS LE just can be resolved local only.");
2234 case R_LARCH_SOP_PUSH_TLS_TPREL
:
2237 if (!elf_hash_table (info
)->tls_sec
)
2238 fatal
= (loongarch_reloc_is_fatal
2239 (info
, input_bfd
, input_section
, rel
, howto
,
2240 bfd_reloc_notsupported
, is_undefweak
, name
,
2241 "TLS section not be created"));
2243 relocation
-= elf_hash_table (info
)->tls_sec
->vma
;
2246 fatal
= (loongarch_reloc_is_fatal
2247 (info
, input_bfd
, input_section
, rel
, howto
,
2248 bfd_reloc_undefined
, is_undefweak
, name
,
2249 "TLS LE just can be resolved local only."));
2252 case R_LARCH_SOP_PUSH_ABSOLUTE
:
2256 fatal
= (loongarch_reloc_is_fatal
2257 (info
, input_bfd
, input_section
, rel
, howto
,
2258 bfd_reloc_dangerous
, is_undefweak
, name
,
2259 "Someone require us to resolve undefweak "
2260 "symbol dynamically. \n"
2261 "But this reloc can't be done. "
2262 "I think I can't throw error "
2264 "so I resolved it to 0. "
2265 "I suggest to re-compile with '-fpic'."));
2268 unresolved_reloc
= false;
2272 if (resolved_to_const
)
2274 relocation
+= rel
->r_addend
;
2280 fatal
= (loongarch_reloc_is_fatal
2281 (info
, input_bfd
, input_section
, rel
, howto
,
2282 bfd_reloc_notsupported
, is_undefweak
, name
,
2283 "Under PIC we don't know load address. Re-compile "
2290 if (!(plt
&& h
&& h
->plt
.offset
!= MINUS_ONE
))
2292 fatal
= (loongarch_reloc_is_fatal
2293 (info
, input_bfd
, input_section
, rel
, howto
,
2294 bfd_reloc_undefined
, is_undefweak
, name
,
2295 "Can't be resolved dynamically. Try to re-compile "
2300 if (rel
->r_addend
!= 0)
2302 fatal
= (loongarch_reloc_is_fatal
2303 (info
, input_bfd
, input_section
, rel
, howto
,
2304 bfd_reloc_notsupported
, is_undefweak
, name
,
2305 "Shouldn't be with r_addend."));
2309 relocation
= sec_addr (plt
) + h
->plt
.offset
;
2310 unresolved_reloc
= false;
2316 relocation
+= rel
->r_addend
;
2322 case R_LARCH_SOP_PUSH_PCREL
:
2323 case R_LARCH_SOP_PUSH_PLT_PCREL
:
2324 unresolved_reloc
= false;
2326 if (resolved_to_const
)
2328 relocation
+= rel
->r_addend
;
2331 else if (is_undefweak
)
2337 if (h
&& h
->plt
.offset
!= MINUS_ONE
)
2340 fatal
= (loongarch_reloc_is_fatal
2341 (info
, input_bfd
, input_section
, rel
, howto
,
2342 bfd_reloc_dangerous
, is_undefweak
, name
,
2343 "Undefweak need to be resolved dynamically, "
2344 "but PLT stub doesn't represent."));
2349 if (!(defined_local
|| (h
&& h
->plt
.offset
!= MINUS_ONE
)))
2351 fatal
= (loongarch_reloc_is_fatal
2352 (info
, input_bfd
, input_section
, rel
, howto
,
2353 bfd_reloc_undefined
, is_undefweak
, name
,
2354 "PLT stub does not represent and "
2355 "symbol not defined."));
2361 else /* if (resolved_dynly) */
2363 if (!(h
&& h
->plt
.offset
!= MINUS_ONE
))
2364 fatal
= (loongarch_reloc_is_fatal
2365 (info
, input_bfd
, input_section
, rel
, howto
,
2366 bfd_reloc_dangerous
, is_undefweak
, name
,
2367 "Internal: PLT stub doesn't represent. "
2368 "Resolve it with pcrel"));
2375 if ((i
& 1) == 0 && defined_local
)
2378 relocation
+= rel
->r_addend
;
2382 if ((i
& 1) && h
&& h
->plt
.offset
!= MINUS_ONE
)
2384 if (rel
->r_addend
!= 0)
2386 fatal
= (loongarch_reloc_is_fatal
2387 (info
, input_bfd
, input_section
, rel
, howto
,
2388 bfd_reloc_notsupported
, is_undefweak
, name
,
2389 "PLT shouldn't be with r_addend."));
2392 relocation
= sec_addr (plt
) + h
->plt
.offset
- pc
;
2398 case R_LARCH_SOP_PUSH_GPREL
:
2399 unresolved_reloc
= false;
2401 if (rel
->r_addend
!= 0)
2403 fatal
= (loongarch_reloc_is_fatal
2404 (info
, input_bfd
, input_section
, rel
, howto
,
2405 bfd_reloc_notsupported
, is_undefweak
, name
,
2406 "Shouldn't be with r_addend."));
2412 off
= h
->got
.offset
;
2414 if (off
== MINUS_ONE
2415 && h
->type
!= STT_GNU_IFUNC
)
2417 fatal
= (loongarch_reloc_is_fatal
2418 (info
, input_bfd
, input_section
, rel
, howto
,
2419 bfd_reloc_notsupported
, is_undefweak
, name
,
2420 "Internal: GOT entry doesn't represent."));
2424 /* Hidden symbol not has .got entry, only .got.plt entry
2425 so gprel is (plt - got). */
2426 if (off
== MINUS_ONE
2427 && h
->type
== STT_GNU_IFUNC
)
2429 if (h
->plt
.offset
== (bfd_vma
) -1)
2434 bfd_vma plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
2435 off
= plt_index
* GOT_ENTRY_SIZE
;
2437 if (htab
->elf
.splt
!= NULL
)
2439 /* Section .plt header is 2 times of plt entry. */
2440 off
= sec_addr(htab
->elf
.sgotplt
) + off
2441 - sec_addr(htab
->elf
.sgot
);
2445 /* Section iplt not has plt header. */
2446 off
= sec_addr(htab
->elf
.igotplt
) + off
2447 - sec_addr(htab
->elf
.sgot
);
2451 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn
, is_pic
, h
)
2452 || (is_pic
&& SYMBOL_REFERENCES_LOCAL (info
, h
)))
2454 /* This is actually a static link, or it is a
2455 -Bsymbolic link and the symbol is defined
2456 locally, or the symbol was forced to be local
2457 because of a version file. We must initialize
2458 this entry in the global offset table. Since the
2459 offset must always be a multiple of the word size,
2460 we use the least significant bit to record whether
2461 we have initialized it already.
2463 When doing a dynamic link, we create a .rela.got
2464 relocation entry to initialize the value. This
2465 is done in the finish_dynamic_symbol routine. */
2469 fatal
= (loongarch_reloc_is_fatal
2470 (info
, input_bfd
, input_section
, rel
, howto
,
2471 bfd_reloc_dangerous
, is_undefweak
, name
,
2472 "Internal: here shouldn't dynamic."));
2475 if (!(defined_local
|| resolved_to_const
))
2477 fatal
= (loongarch_reloc_is_fatal
2478 (info
, input_bfd
, input_section
, rel
, howto
,
2479 bfd_reloc_undefined
, is_undefweak
, name
,
2488 /* The pr21964-4. Create relocate entry. */
2489 if (is_pic
&& h
->start_stop
)
2492 Elf_Internal_Rela outrel
;
2493 /* We need to generate a R_LARCH_RELATIVE reloc
2494 for the dynamic linker. */
2495 s
= htab
->elf
.srelgot
;
2498 fatal
= loongarch_reloc_is_fatal (info
, input_bfd
,
2499 input_section
, rel
, howto
,
2500 bfd_reloc_notsupported
, is_undefweak
, name
,
2501 "Internal: '.rel.got' not represent");
2505 outrel
.r_offset
= sec_addr (got
) + off
;
2506 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2507 outrel
.r_addend
= relocation
; /* Link-time addr. */
2508 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
2510 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
2517 if (!local_got_offsets
)
2519 fatal
= (loongarch_reloc_is_fatal
2520 (info
, input_bfd
, input_section
, rel
, howto
,
2521 bfd_reloc_notsupported
, is_undefweak
, name
,
2522 "Internal: local got offsets not reporesent."));
2526 off
= local_got_offsets
[r_symndx
];
2528 if (off
== MINUS_ONE
)
2530 fatal
= (loongarch_reloc_is_fatal
2531 (info
, input_bfd
, input_section
, rel
, howto
,
2532 bfd_reloc_notsupported
, is_undefweak
, name
,
2533 "Internal: GOT entry doesn't represent."));
2537 /* The offset must always be a multiple of the word size.
2538 So, we can use the least significant bit to record
2539 whether we have already processed this entry. */
2547 Elf_Internal_Rela outrel
;
2548 /* We need to generate a R_LARCH_RELATIVE reloc
2549 for the dynamic linker. */
2550 s
= htab
->elf
.srelgot
;
2553 fatal
= (loongarch_reloc_is_fatal
2554 (info
, input_bfd
, input_section
, rel
, howto
,
2555 bfd_reloc_notsupported
, is_undefweak
, name
,
2556 "Internal: '.rel.got' not represent"));
2560 outrel
.r_offset
= sec_addr (got
) + off
;
2561 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2562 outrel
.r_addend
= relocation
; /* Link-time addr. */
2563 loongarch_elf_append_rela (output_bfd
, s
, &outrel
);
2566 bfd_put_NN (output_bfd
, relocation
, got
->contents
+ off
);
2567 local_got_offsets
[r_symndx
] |= 1;
2573 case R_LARCH_SOP_PUSH_TLS_GOT
:
2574 case R_LARCH_SOP_PUSH_TLS_GD
:
2575 if (r_type
== R_LARCH_SOP_PUSH_TLS_GOT
)
2577 unresolved_reloc
= false;
2579 if (rel
->r_addend
!= 0)
2581 fatal
= (loongarch_reloc_is_fatal
2582 (info
, input_bfd
, input_section
, rel
, howto
,
2583 bfd_reloc_notsupported
, is_undefweak
, name
,
2584 "Shouldn't be with r_addend."));
2589 if (resolved_to_const
&& is_undefweak
&& h
->dynindx
!= -1)
2591 /* What if undefweak? Let rtld make a decision. */
2592 resolved_to_const
= resolved_local
= false;
2593 resolved_dynly
= true;
2596 if (resolved_to_const
)
2598 fatal
= (loongarch_reloc_is_fatal
2599 (info
, input_bfd
, input_section
, rel
, howto
,
2600 bfd_reloc_notsupported
, is_undefweak
, name
,
2601 "Internal: Shouldn't be resolved to const."));
2607 off
= h
->got
.offset
;
2612 off
= local_got_offsets
[r_symndx
];
2613 local_got_offsets
[r_symndx
] |= 1;
2616 if (off
== MINUS_ONE
)
2618 fatal
= (loongarch_reloc_is_fatal
2619 (info
, input_bfd
, input_section
, rel
, howto
,
2620 bfd_reloc_notsupported
, is_undefweak
, name
,
2621 "Internal: TLS GOT entry doesn't represent."));
2625 tls_type
= _bfd_loongarch_elf_tls_type (input_bfd
, h
, r_symndx
);
2627 /* If this symbol is referenced by both GD and IE TLS, the IE
2628 reference's GOT slot follows the GD reference's slots. */
2630 if ((tls_type
& GOT_TLS_GD
) && (tls_type
& GOT_TLS_IE
))
2631 ie_off
= 2 * GOT_ENTRY_SIZE
;
2637 bfd_vma tls_block_off
= 0;
2638 Elf_Internal_Rela outrel
;
2642 if (!elf_hash_table (info
)->tls_sec
)
2644 fatal
= (loongarch_reloc_is_fatal
2645 (info
, input_bfd
, input_section
, rel
, howto
,
2646 bfd_reloc_notsupported
, is_undefweak
, name
,
2647 "Internal: TLS sec not represent."));
2651 relocation
- elf_hash_table (info
)->tls_sec
->vma
;
2654 if (tls_type
& GOT_TLS_GD
)
2656 outrel
.r_offset
= sec_addr (got
) + off
;
2657 outrel
.r_addend
= 0;
2658 bfd_put_NN (output_bfd
, 0, got
->contents
+ off
);
2659 if (resolved_local
&& bfd_link_executable (info
))
2660 bfd_put_NN (output_bfd
, 1, got
->contents
+ off
);
2661 else if (resolved_local
/* && !bfd_link_executable (info) */)
2663 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN
);
2664 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2667 else /* if (resolved_dynly) */
2670 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_DTPMODNN
);
2671 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2675 outrel
.r_offset
+= GOT_ENTRY_SIZE
;
2676 bfd_put_NN (output_bfd
, tls_block_off
,
2677 got
->contents
+ off
+ GOT_ENTRY_SIZE
);
2679 /* DTPREL known. */;
2680 else /* if (resolved_dynly) */
2683 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_DTPRELNN
);
2684 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2689 if (tls_type
& GOT_TLS_IE
)
2691 outrel
.r_offset
= sec_addr (got
) + off
+ ie_off
;
2692 bfd_put_NN (output_bfd
, tls_block_off
,
2693 got
->contents
+ off
+ ie_off
);
2694 if (resolved_local
&& bfd_link_executable (info
))
2696 else if (resolved_local
/* && !bfd_link_executable (info) */)
2698 outrel
.r_info
= ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
2699 outrel
.r_addend
= tls_block_off
;
2700 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2703 else /* if (resolved_dynly) */
2705 /* Static linking has no .dynsym table. */
2706 if (!htab
->elf
.dynamic_sections_created
)
2709 ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN
);
2710 outrel
.r_addend
= 0;
2715 ELFNN_R_INFO (h
->dynindx
, R_LARCH_TLS_TPRELNN
);
2716 outrel
.r_addend
= 0;
2718 loongarch_elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
2724 relocation
= off
+ (is_ie
? ie_off
: 0);
2736 /* 'unresolved_reloc' means we haven't done it yet.
2737 We need help of dynamic linker to fix this memory location up. */
2738 if (!unresolved_reloc
)
2741 if (_bfd_elf_section_offset (output_bfd
, info
, input_section
,
2742 rel
->r_offset
) == MINUS_ONE
)
2743 /* WHY? May because it's invalid so skip checking.
2744 But why dynamic reloc a invalid section? */
2747 if (input_section
->output_section
->flags
& SEC_DEBUGGING
)
2749 fatal
= (loongarch_reloc_is_fatal
2750 (info
, input_bfd
, input_section
, rel
, howto
,
2751 bfd_reloc_dangerous
, is_undefweak
, name
,
2752 "Seems dynamic linker not process "
2753 "sections 'SEC_DEBUGGING'."));
2758 if ((info
->flags
& DF_TEXTREL
) == 0)
2759 if (input_section
->output_section
->flags
& SEC_READONLY
)
2760 info
->flags
|= DF_TEXTREL
;
2767 loongarch_record_one_reloc (input_bfd
, input_section
, r_type
,
2768 rel
->r_offset
, sym
, h
, rel
->r_addend
);
2770 if (r
!= bfd_reloc_continue
)
2771 r
= perform_relocation (rel
, input_section
, howto
, relocation
,
2772 input_bfd
, contents
);
2776 case bfd_reloc_dangerous
:
2777 case bfd_reloc_continue
:
2781 case bfd_reloc_overflow
:
2782 /* Overflow value can't be filled in. */
2783 loongarch_dump_reloc_record (info
->callbacks
->info
);
2784 info
->callbacks
->reloc_overflow
2785 (info
, h
? &h
->root
: NULL
, name
, howto
->name
, rel
->r_addend
,
2786 input_bfd
, input_section
, rel
->r_offset
);
2789 case bfd_reloc_outofrange
:
2790 /* Stack state incorrect. */
2791 loongarch_dump_reloc_record (info
->callbacks
->info
);
2792 info
->callbacks
->info
2793 ("%X%H: Internal stack state is incorrect.\n"
2794 "Want to push to full stack or pop from empty stack?\n",
2795 input_bfd
, input_section
, rel
->r_offset
);
2798 case bfd_reloc_notsupported
:
2799 info
->callbacks
->info ("%X%H: Unknown relocation type.\n", input_bfd
,
2800 input_section
, rel
->r_offset
);
2804 info
->callbacks
->info ("%X%H: Internal: unknown error.\n", input_bfd
,
2805 input_section
, rel
->r_offset
);
2816 /* Finish up dynamic symbol handling. We set the contents of various
2817 dynamic sections here. */
2820 loongarch_elf_finish_dynamic_symbol (bfd
*output_bfd
,
2821 struct bfd_link_info
*info
,
2822 struct elf_link_hash_entry
*h
,
2823 Elf_Internal_Sym
*sym
)
2825 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
2826 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
2828 if (h
->plt
.offset
!= MINUS_ONE
)
2831 asection
*plt
, *gotplt
, *relplt
;
2832 bfd_vma got_address
;
2833 uint32_t plt_entry
[PLT_ENTRY_INSNS
];
2835 Elf_Internal_Rela rela
;
2839 BFD_ASSERT ((h
->type
== STT_GNU_IFUNC
2840 && SYMBOL_REFERENCES_LOCAL (info
, h
))
2841 || h
->dynindx
!= -1);
2843 plt
= htab
->elf
.splt
;
2844 gotplt
= htab
->elf
.sgotplt
;
2845 relplt
= htab
->elf
.srelplt
;
2846 plt_idx
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
2848 sec_addr (gotplt
) + GOTPLT_HEADER_SIZE
+ plt_idx
* GOT_ENTRY_SIZE
;
2850 else /* if (htab->elf.iplt) */
2852 BFD_ASSERT (h
->type
== STT_GNU_IFUNC
2853 && SYMBOL_REFERENCES_LOCAL (info
, h
));
2855 plt
= htab
->elf
.iplt
;
2856 gotplt
= htab
->elf
.igotplt
;
2857 relplt
= htab
->elf
.irelplt
;
2858 plt_idx
= h
->plt
.offset
/ PLT_ENTRY_SIZE
;
2859 got_address
= sec_addr (gotplt
) + plt_idx
* GOT_ENTRY_SIZE
;
2862 /* Find out where the .plt entry should go. */
2863 loc
= plt
->contents
+ h
->plt
.offset
;
2865 /* Fill in the PLT entry itself. */
2866 if (!loongarch_make_plt_entry (got_address
,
2867 sec_addr (plt
) + h
->plt
.offset
,
2871 for (i
= 0; i
< PLT_ENTRY_INSNS
; i
++)
2872 bfd_put_32 (output_bfd
, plt_entry
[i
], loc
+ 4 * i
);
2874 /* Fill in the initial value of the .got.plt entry. */
2875 loc
= gotplt
->contents
+ (got_address
- sec_addr (gotplt
));
2876 bfd_put_NN (output_bfd
, sec_addr (plt
), loc
);
2878 rela
.r_offset
= got_address
;
2880 /* TRUE if this is a PLT reference to a local IFUNC. */
2881 if (PLT_LOCAL_IFUNC_P(info
, h
))
2883 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2884 rela
.r_addend
= (h
->root
.u
.def
.value
2885 + h
->root
.u
.def
.section
->output_section
->vma
2886 + h
->root
.u
.def
.section
->output_offset
);
2890 /* Fill in the entry in the .rela.plt section. */
2891 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_JUMP_SLOT
);
2895 loc
= relplt
->contents
+ plt_idx
* sizeof (ElfNN_External_Rela
);
2896 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
2898 if (!h
->def_regular
)
2900 /* Mark the symbol as undefined, rather than as defined in
2901 the .plt section. Leave the value alone. */
2902 sym
->st_shndx
= SHN_UNDEF
;
2903 /* If the symbol is weak, we do need to clear the value.
2904 Otherwise, the PLT entry would provide a definition for
2905 the symbol even if the symbol wasn't defined anywhere,
2906 and so the symbol would never be NULL. */
2907 if (!h
->ref_regular_nonweak
)
2912 if (h
->got
.offset
!= MINUS_ONE
2913 /* TLS got entry have been handled in elf_relocate_section. */
2914 && !(loongarch_elf_hash_entry (h
)->tls_type
& (GOT_TLS_GD
| GOT_TLS_IE
))
2915 /* have allocated got entry but not allocated rela before. */
2916 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2918 asection
*sgot
, *srela
;
2919 Elf_Internal_Rela rela
;
2920 bfd_vma off
= h
->got
.offset
& ~(bfd_vma
) 1;
2922 /* This symbol has an entry in the GOT. Set it up. */
2924 sgot
= htab
->elf
.sgot
;
2925 srela
= htab
->elf
.srelgot
;
2926 BFD_ASSERT (sgot
&& srela
);
2928 rela
.r_offset
= sec_addr (sgot
) + off
;
2931 && h
->type
== STT_GNU_IFUNC
)
2933 if(h
->plt
.offset
== MINUS_ONE
)
2935 if (htab
->elf
.splt
== NULL
)
2936 srela
= htab
->elf
.irelplt
;
2938 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
2940 asection
*sec
= h
->root
.u
.def
.section
;
2941 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_IRELATIVE
);
2942 rela
.r_addend
= h
->root
.u
.def
.value
+ sec
->output_section
->vma
2943 + sec
->output_offset
;
2944 bfd_put_NN (output_bfd
, 0, sgot
->contents
+ off
);
2948 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
2949 BFD_ASSERT (h
->dynindx
!= -1);
2950 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2952 bfd_put_NN (output_bfd
, (bfd_vma
) 0, sgot
->contents
+ off
);
2955 else if(bfd_link_pic (info
))
2957 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2959 bfd_put_NN (output_bfd
, rela
.r_addend
, sgot
->contents
+ off
);
2964 /* For non-shared object, we can't use .got.plt, which
2965 contains the real function address if we need pointer
2966 equality. We load the GOT entry with the PLT entry. */
2967 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
2968 bfd_put_NN (output_bfd
,
2969 (plt
->output_section
->vma
2970 + plt
->output_offset
2972 sgot
->contents
+ off
);
2976 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
2978 BFD_ASSERT (h
->got
.offset
& 1 /* Has been filled in addr. */);
2979 asection
*sec
= h
->root
.u
.def
.section
;
2980 rela
.r_info
= ELFNN_R_INFO (0, R_LARCH_RELATIVE
);
2981 rela
.r_addend
= (h
->root
.u
.def
.value
+ sec
->output_section
->vma
2982 + sec
->output_offset
);
2986 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
2987 BFD_ASSERT (h
->dynindx
!= -1);
2988 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_NN
);
2992 loongarch_elf_append_rela (output_bfd
, srela
, &rela
);
2997 Elf_Internal_Rela rela
;
3000 /* This symbols needs a copy reloc. Set it up. */
3001 BFD_ASSERT (h
->dynindx
!= -1);
3003 rela
.r_offset
= sec_addr (h
->root
.u
.def
.section
) + h
->root
.u
.def
.value
;
3004 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_LARCH_COPY
);
3006 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3007 s
= htab
->elf
.sreldynrelro
;
3009 s
= htab
->elf
.srelbss
;
3010 loongarch_elf_append_rela (output_bfd
, s
, &rela
);
3013 /* Mark some specially defined symbols as absolute. */
3014 if (h
== htab
->elf
.hdynamic
|| h
== htab
->elf
.hgot
|| h
== htab
->elf
.hplt
)
3015 sym
->st_shndx
= SHN_ABS
;
3020 /* Finish up the dynamic sections. */
3023 loongarch_finish_dyn (bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*dynobj
,
3026 struct loongarch_elf_link_hash_table
*htab
= loongarch_elf_hash_table (info
);
3027 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
3028 size_t dynsize
= bed
->s
->sizeof_dyn
, skipped_size
= 0;
3029 bfd_byte
*dyncon
, *dynconend
;
3031 dynconend
= sdyn
->contents
+ sdyn
->size
;
3032 for (dyncon
= sdyn
->contents
; dyncon
< dynconend
; dyncon
+= dynsize
)
3034 Elf_Internal_Dyn dyn
;
3038 bed
->s
->swap_dyn_in (dynobj
, dyncon
, &dyn
);
3043 s
= htab
->elf
.sgotplt
;
3044 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3047 s
= htab
->elf
.srelplt
;
3048 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3051 s
= htab
->elf
.srelplt
;
3052 dyn
.d_un
.d_val
= s
->size
;
3055 if ((info
->flags
& DF_TEXTREL
) == 0)
3059 if ((info
->flags
& DF_TEXTREL
) == 0)
3060 dyn
.d_un
.d_val
&= ~DF_TEXTREL
;
3064 skipped_size
+= dynsize
;
3066 bed
->s
->swap_dyn_out (output_bfd
, &dyn
, dyncon
- skipped_size
);
3068 /* Wipe out any trailing entries if we shifted down a dynamic tag. */
3069 memset (dyncon
- skipped_size
, 0, skipped_size
);
3073 /* Finish up local dynamic symbol handling. We set the contents of
3074 various dynamic sections here. */
3077 elfNN_loongarch_finish_local_dynamic_symbol (void **slot
, void *inf
)
3079 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) *slot
;
3080 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
3082 return loongarch_elf_finish_dynamic_symbol (info
->output_bfd
, info
, h
, NULL
);
3086 loongarch_elf_finish_dynamic_sections (bfd
*output_bfd
,
3087 struct bfd_link_info
*info
)
3090 asection
*sdyn
, *plt
, *gotplt
= NULL
;
3091 struct loongarch_elf_link_hash_table
*htab
;
3093 htab
= loongarch_elf_hash_table (info
);
3095 dynobj
= htab
->elf
.dynobj
;
3096 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3098 if (elf_hash_table (info
)->dynamic_sections_created
)
3100 BFD_ASSERT (htab
->elf
.splt
&& sdyn
);
3102 if (!loongarch_finish_dyn (output_bfd
, info
, dynobj
, sdyn
))
3106 plt
= htab
->elf
.splt
;
3107 gotplt
= htab
->elf
.sgotplt
;
3109 if (plt
&& 0 < plt
->size
)
3112 uint32_t plt_header
[PLT_HEADER_INSNS
];
3113 if (!loongarch_make_plt_header (sec_addr (gotplt
), sec_addr (plt
),
3117 for (i
= 0; i
< PLT_HEADER_INSNS
; i
++)
3118 bfd_put_32 (output_bfd
, plt_header
[i
], plt
->contents
+ 4 * i
);
3120 elf_section_data (plt
->output_section
)->this_hdr
.sh_entsize
=
3124 if (htab
->elf
.sgotplt
)
3126 asection
*output_section
= htab
->elf
.sgotplt
->output_section
;
3128 if (bfd_is_abs_section (output_section
))
3130 _bfd_error_handler (_("discarded output section: `%pA'"),
3135 if (0 < htab
->elf
.sgotplt
->size
)
3137 /* Write the first two entries in .got.plt, needed for the dynamic
3139 bfd_put_NN (output_bfd
, MINUS_ONE
, htab
->elf
.sgotplt
->contents
);
3141 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
3142 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
3145 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
3150 asection
*output_section
= htab
->elf
.sgot
->output_section
;
3152 if (0 < htab
->elf
.sgot
->size
)
3154 /* Set the first entry in the global offset table to the address of
3155 the dynamic section. */
3156 bfd_vma val
= sdyn
? sec_addr (sdyn
) : 0;
3157 bfd_put_NN (output_bfd
, val
, htab
->elf
.sgot
->contents
);
3160 elf_section_data (output_section
)->this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
3163 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
3164 htab_traverse (htab
->loc_hash_table
,
3165 (void *) elfNN_loongarch_finish_local_dynamic_symbol
, info
);
3170 /* Return address for Ith PLT stub in section PLT, for relocation REL
3171 or (bfd_vma) -1 if it should not be included. */
3174 loongarch_elf_plt_sym_val (bfd_vma i
, const asection
*plt
,
3175 const arelent
*rel ATTRIBUTE_UNUSED
)
3177 return plt
->vma
+ PLT_HEADER_SIZE
+ i
* PLT_ENTRY_SIZE
;
3180 static enum elf_reloc_type_class
3181 loongarch_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
3182 const asection
*rel_sec ATTRIBUTE_UNUSED
,
3183 const Elf_Internal_Rela
*rela
)
3185 struct loongarch_elf_link_hash_table
*htab
;
3186 htab
= loongarch_elf_hash_table (info
);
3188 if (htab
->elf
.dynsym
!= NULL
&& htab
->elf
.dynsym
->contents
!= NULL
)
3190 /* Check relocation against STT_GNU_IFUNC symbol if there are
3192 bfd
*abfd
= info
->output_bfd
;
3193 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
3194 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
3195 if (r_symndx
!= STN_UNDEF
)
3197 Elf_Internal_Sym sym
;
3198 if (!bed
->s
->swap_symbol_in (abfd
,
3199 htab
->elf
.dynsym
->contents
3200 + r_symndx
* bed
->s
->sizeof_sym
,
3203 /* xgettext:c-format */
3204 _bfd_error_handler (_("%pB symbol number %lu references"
3205 " nonexistent SHT_SYMTAB_SHNDX section"),
3207 /* Ideally an error class should be returned here. */
3209 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
3210 return reloc_class_ifunc
;
3214 switch (ELFNN_R_TYPE (rela
->r_info
))
3216 case R_LARCH_IRELATIVE
:
3217 return reloc_class_ifunc
;
3218 case R_LARCH_RELATIVE
:
3219 return reloc_class_relative
;
3220 case R_LARCH_JUMP_SLOT
:
3221 return reloc_class_plt
;
3223 return reloc_class_copy
;
3225 return reloc_class_normal
;
3229 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3232 loongarch_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
3233 struct elf_link_hash_entry
*dir
,
3234 struct elf_link_hash_entry
*ind
)
3236 struct elf_link_hash_entry
*edir
, *eind
;
3241 if (eind
->dyn_relocs
!= NULL
)
3243 if (edir
->dyn_relocs
!= NULL
)
3245 struct elf_dyn_relocs
**pp
;
3246 struct elf_dyn_relocs
*p
;
3248 /* Add reloc counts against the indirect sym to the direct sym
3249 list. Merge any entries against the same section. */
3250 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
3252 struct elf_dyn_relocs
*q
;
3254 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
3255 if (q
->sec
== p
->sec
)
3257 q
->pc_count
+= p
->pc_count
;
3258 q
->count
+= p
->count
;
3265 *pp
= edir
->dyn_relocs
;
3268 edir
->dyn_relocs
= eind
->dyn_relocs
;
3269 eind
->dyn_relocs
= NULL
;
3272 if (ind
->root
.type
== bfd_link_hash_indirect
&& dir
->got
.refcount
< 0)
3274 loongarch_elf_hash_entry(edir
)->tls_type
3275 = loongarch_elf_hash_entry(eind
)->tls_type
;
3276 loongarch_elf_hash_entry(eind
)->tls_type
= GOT_UNKNOWN
;
3278 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
3281 #define PRSTATUS_SIZE 0x1d8
3282 #define PRSTATUS_OFFSET_PR_CURSIG 0xc
3283 #define PRSTATUS_OFFSET_PR_PID 0x20
3284 #define ELF_GREGSET_T_SIZE 0x168
3285 #define PRSTATUS_OFFSET_PR_REG 0x70
3287 /* Support for core dump NOTE sections. */
3290 loongarch_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
3292 switch (note
->descsz
)
3297 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */
3300 elf_tdata (abfd
)->core
->signal
=
3301 bfd_get_16 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_CURSIG
);
3304 elf_tdata (abfd
)->core
->lwpid
=
3305 bfd_get_32 (abfd
, note
->descdata
+ PRSTATUS_OFFSET_PR_PID
);
3309 /* Make a ".reg/999" section. */
3310 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", ELF_GREGSET_T_SIZE
,
3312 + PRSTATUS_OFFSET_PR_REG
);
3315 #define PRPSINFO_SIZE 0x88
3316 #define PRPSINFO_OFFSET_PR_PID 0x18
3317 #define PRPSINFO_OFFSET_PR_FNAME 0x28
3318 #define PRPSINFO_SIZEOF_PR_FNAME 0x10
3319 #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
3320 #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
3324 loongarch_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
3326 switch (note
->descsz
)
3331 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */
3334 elf_tdata (abfd
)->core
->pid
=
3335 bfd_get_32 (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PID
);
3338 elf_tdata (abfd
)->core
->program
=
3339 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_FNAME
,
3340 PRPSINFO_SIZEOF_PR_FNAME
);
3343 elf_tdata (abfd
)->core
->command
=
3344 _bfd_elfcore_strndup (abfd
, note
->descdata
+ PRPSINFO_OFFSET_PR_PS_ARGS
,
3345 PRPSINFO_SIZEOF_PR_PS_ARGS
);
3349 /* Note that for some reason, a spurious space is tacked
3350 onto the end of the args in some (at least one anyway)
3351 implementations, so strip it off if it exists. */
3354 char *command
= elf_tdata (abfd
)->core
->command
;
3355 int n
= strlen (command
);
3357 if (0 < n
&& command
[n
- 1] == ' ')
3358 command
[n
- 1] = '\0';
3364 /* Set the right mach type. */
3366 loongarch_elf_object_p (bfd
*abfd
)
3368 /* There are only two mach types in LoongArch currently. */
3369 if (strcmp (abfd
->xvec
->name
, "elf64-loongarch") == 0)
3370 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch64
);
3372 bfd_default_set_arch_mach (abfd
, bfd_arch_loongarch
, bfd_mach_loongarch32
);
3377 loongarch_elf_gc_mark_hook (asection
*sec
, struct bfd_link_info
*info
,
3378 Elf_Internal_Rela
*rel
,
3379 struct elf_link_hash_entry
*h
,
3380 Elf_Internal_Sym
*sym
)
3383 switch (ELFNN_R_TYPE (rel
->r_info
))
3385 case R_LARCH_GNU_VTINHERIT
:
3386 case R_LARCH_GNU_VTENTRY
:
3390 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
3393 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
3394 #define TARGET_LITTLE_NAME "elfNN-loongarch"
3395 #define ELF_ARCH bfd_arch_loongarch
3396 #define ELF_TARGET_ID LARCH_ELF_DATA
3397 #define ELF_MACHINE_CODE EM_LOONGARCH
3398 #define ELF_MAXPAGESIZE 0x4000
3399 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
3400 #define bfd_elfNN_bfd_link_hash_table_create \
3401 loongarch_elf_link_hash_table_create
3402 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
3403 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
3404 #define elf_info_to_howto loongarch_info_to_howto_rela
3405 #define bfd_elfNN_bfd_merge_private_bfd_data \
3406 elfNN_loongarch_merge_private_bfd_data
3408 #define elf_backend_reloc_type_class loongarch_reloc_type_class
3409 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
3410 #define elf_backend_create_dynamic_sections \
3411 loongarch_elf_create_dynamic_sections
3412 #define elf_backend_check_relocs loongarch_elf_check_relocs
3413 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
3414 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
3415 #define elf_backend_relocate_section loongarch_elf_relocate_section
3416 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
3417 #define elf_backend_finish_dynamic_sections \
3418 loongarch_elf_finish_dynamic_sections
3419 #define elf_backend_object_p loongarch_elf_object_p
3420 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
3421 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
3422 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
3423 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
3425 #include "elfNN-target.h"