1/* LoongArch-specific support for NN-bit ELF. 2 Copyright (C) 2021-2022 Free Software Foundation, Inc. 3 Contributed by Loongson Ltd. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 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. 11 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. 16 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/>. */ 20 21#include "ansidecl.h" 22#include "sysdep.h" 23#include "bfd.h" 24#include "libbfd.h" 25#define ARCH_SIZE NN 26#include "elf-bfd.h" 27#include "objalloc.h" 28#include "elf/loongarch.h" 29#include "elfxx-loongarch.h" 30 31static bool 32loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, 33 Elf_Internal_Rela *dst) 34{ 35 cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd, 36 ELFNN_R_TYPE (dst->r_info)); 37 return cache_ptr->howto != NULL; 38} 39 40/* LoongArch ELF linker hash entry. */ 41struct loongarch_elf_link_hash_entry 42{ 43 struct elf_link_hash_entry elf; 44 45#define GOT_UNKNOWN 0 46#define GOT_NORMAL 1 47#define GOT_TLS_GD 2 48#define GOT_TLS_IE 4 49#define GOT_TLS_LE 8 50 char tls_type; 51}; 52 53#define loongarch_elf_hash_entry(ent) \ 54 ((struct loongarch_elf_link_hash_entry *) (ent)) 55 56struct _bfd_loongarch_elf_obj_tdata 57{ 58 struct elf_obj_tdata root; 59 60 /* The tls_type for each local got entry. */ 61 char *local_got_tls_type; 62}; 63 64#define _bfd_loongarch_elf_tdata(abfd) \ 65 ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any) 66 67#define _bfd_loongarch_elf_local_got_tls_type(abfd) \ 68 (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type) 69 70#define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \ 71 (*((h) != NULL \ 72 ? &loongarch_elf_hash_entry (h)->tls_type \ 73 : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx])) 74 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) 79 80struct loongarch_elf_link_hash_table 81{ 82 struct elf_link_hash_table elf; 83 84 /* Short-cuts to get to dynamic linker sections. */ 85 asection *sdyntdata; 86 87 /* Small local sym to section mapping cache. */ 88 struct sym_cache sym_cache; 89 90 /* Used by local STT_GNU_IFUNC symbols. */ 91 htab_t loc_hash_table; 92 void *loc_hash_memory; 93 94 /* The max alignment of output sections. */ 95 bfd_vma max_alignment; 96}; 97 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)) \ 102 : NULL) 103 104#define MINUS_ONE ((bfd_vma) 0 - 1) 105 106#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset) 107 108#define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3) 109#define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES) 110 111#define PLT_HEADER_INSNS 8 112#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4) 113 114#define PLT_ENTRY_INSNS 4 115#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4) 116 117#define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES) 118 119#define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2) 120 121#define elf_backend_want_got_plt 1 122 123#define elf_backend_plt_readonly 1 124 125#define elf_backend_want_plt_sym 1 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 130 131#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1) 132 133#define elf_backend_want_dynrelro 1 134#define elf_backend_rela_normal 1 135#define elf_backend_default_execstack 0 136 137/* Generate a PLT header. */ 138 139static bool 140loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr, 141 uint32_t *entry) 142{ 143 bfd_vma pcrel = got_plt_addr - plt_header_addr; 144 bfd_vma hi, lo; 145 146 if (pcrel + 0x80000800 > 0xffffffff) 147 { 148 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel); 149 bfd_set_error (bfd_error_bad_value); 150 return false; 151 } 152 hi = ((pcrel + 0x800) >> 12) & 0xfffff; 153 lo = pcrel & 0xfff; 154 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 162 jirl $r0, $t3, 0 */ 163 164 if (GOT_ENTRY_SIZE == 8) 165 { 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; 174 } 175 else 176 { 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; 185 } 186 return true; 187} 188 189/* Generate a PLT entry. */ 190 191static bool 192loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr, 193 uint32_t *entry) 194{ 195 bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr; 196 bfd_vma hi, lo; 197 198 if (pcrel + 0x80000800 > 0xffffffff) 199 { 200 _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel); 201 bfd_set_error (bfd_error_bad_value); 202 return false; 203 } 204 hi = ((pcrel + 0x800) >> 12) & 0xfffff; 205 lo = pcrel & 0xfff; 206 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 */ 212 213 return true; 214} 215 216/* Create an entry in an LoongArch ELF linker hash table. */ 217 218static struct bfd_hash_entry * 219link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, 220 const char *string) 221{ 222 struct loongarch_elf_link_hash_entry *eh; 223 224 /* Allocate the structure if it has not already been allocated by a 225 subclass. */ 226 if (entry == NULL) 227 { 228 entry = bfd_hash_allocate (table, sizeof (*eh)); 229 if (entry == NULL) 230 return entry; 231 } 232 233 /* Call the allocation method of the superclass. */ 234 entry = _bfd_elf_link_hash_newfunc (entry, table, string); 235 if (entry != NULL) 236 { 237 eh = (struct loongarch_elf_link_hash_entry *) entry; 238 eh->tls_type = GOT_UNKNOWN; 239 } 240 241 return entry; 242} 243 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. */ 248 249static hashval_t 250elfNN_loongarch_local_htab_hash (const void *ptr) 251{ 252 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr; 253 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index); 254} 255 256/* Compare local hash entries. */ 257 258static int 259elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2) 260{ 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; 263 264 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index; 265} 266 267/* Find and/or create a hash entry for local symbol. */ 268static struct elf_link_hash_entry * 269elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab, 270 bfd *abfd, const Elf_Internal_Rela *rel, 271 bool create) 272{ 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)); 276 void **slot; 277 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); 282 283 if (!slot) 284 return NULL; 285 286 if (*slot) 287 { 288 ret = (struct loongarch_elf_link_hash_entry *) *slot; 289 return &ret->elf; 290 } 291 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))); 295 if (ret) 296 { 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; 311 *slot = ret; 312 } 313 return &ret->elf; 314} 315 316/* Destroy an LoongArch elf linker hash table. */ 317 318static void 319elfNN_loongarch_link_hash_table_free (bfd *obfd) 320{ 321 struct loongarch_elf_link_hash_table *ret; 322 ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash; 323 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); 328 329 _bfd_elf_link_hash_table_free (obfd); 330} 331 332/* Create a LoongArch ELF linker hash table. */ 333 334static struct bfd_link_hash_table * 335loongarch_elf_link_hash_table_create (bfd *abfd) 336{ 337 struct loongarch_elf_link_hash_table *ret; 338 bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table); 339 340 ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt); 341 if (ret == NULL) 342 return NULL; 343 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)) 347 { 348 free (ret); 349 return NULL; 350 } 351 352 ret->max_alignment = MINUS_ONE; 353 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) 358 { 359 elfNN_loongarch_link_hash_table_free (abfd); 360 return NULL; 361 } 362 ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free; 363 364 return &ret->elf.root; 365} 366 367/* Merge backend specific data from an object file to the output 368 object file when linking. */ 369 370static bool 371elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 372{ 373 bfd *obfd = info->output_bfd; 374 flagword in_flags = elf_elfheader (ibfd)->e_flags; 375 flagword out_flags = elf_elfheader (obfd)->e_flags; 376 377 if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd)) 378 return true; 379 380 if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0) 381 { 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)); 386 return false; 387 } 388 389 if (!_bfd_elf_merge_object_attributes (ibfd, info)) 390 return false; 391 392 /* If the input BFD is not a dynamic object and it does not contain any 393 non-data sections, do not account its ABI. For example, various 394 packages produces such data-only relocatable objects with 395 `ld -r -b binary` or `objcopy`, and these objects have zero e_flags. 396 But they are compatible with all ABIs. */ 397 if (!(ibfd->flags & DYNAMIC)) 398 { 399 asection *sec; 400 bool have_code_sections = false; 401 for (sec = ibfd->sections; sec != NULL; sec = sec->next) 402 if ((bfd_section_flags (sec) 403 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) 404 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) 405 { 406 have_code_sections = true; 407 break; 408 } 409 if (!have_code_sections) 410 return true; 411 } 412 413 if (!elf_flags_init (obfd)) 414 { 415 elf_flags_init (obfd) = true; 416 elf_elfheader (obfd)->e_flags = in_flags; 417 return true; 418 } 419 else if (out_flags != in_flags) 420 { 421 if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags) 422 && EF_LOONGARCH_IS_OBJ_V1 (in_flags)) 423 || (EF_LOONGARCH_IS_OBJ_V0 (in_flags) 424 && EF_LOONGARCH_IS_OBJ_V1 (out_flags))) 425 { 426 elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1; 427 out_flags = elf_elfheader (obfd)->e_flags; 428 in_flags = out_flags; 429 } 430 } 431 432 /* Disallow linking different ABIs. */ 433 /* Only check relocation version. 434 The obj_v0 is compatible with obj_v1. */ 435 if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK) 436 { 437 _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd); 438 goto fail; 439 } 440 441 return true; 442 443 fail: 444 bfd_set_error (bfd_error_bad_value); 445 return false; 446} 447 448/* Create the .got section. */ 449 450static bool 451loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) 452{ 453 flagword flags; 454 char *name; 455 asection *s, *s_got; 456 struct elf_link_hash_entry *h; 457 const struct elf_backend_data *bed = get_elf_backend_data (abfd); 458 struct elf_link_hash_table *htab = elf_hash_table (info); 459 460 /* This function may be called more than once. */ 461 if (htab->sgot != NULL) 462 return true; 463 464 flags = bed->dynamic_sec_flags; 465 name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got"; 466 s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY); 467 468 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 469 return false; 470 htab->srelgot = s; 471 472 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags); 473 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 474 return false; 475 htab->sgot = s; 476 477 /* The first bit of the global offset table is the header. */ 478 s->size += bed->got_header_size; 479 480 if (bed->want_got_plt) 481 { 482 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); 483 if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 484 return false; 485 htab->sgotplt = s; 486 487 /* Reserve room for the header. */ 488 s->size = GOTPLT_HEADER_SIZE; 489 } 490 491 if (bed->want_got_sym) 492 { 493 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got 494 section. We don't do this in the linker script because we don't want 495 to define the symbol if we are not creating a global offset table. */ 496 h = _bfd_elf_define_linkage_sym (abfd, info, s_got, 497 "_GLOBAL_OFFSET_TABLE_"); 498 elf_hash_table (info)->hgot = h; 499 if (h == NULL) 500 return false; 501 } 502 return true; 503} 504 505/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and 506 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our 507 hash table. */ 508 509static bool 510loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) 511{ 512 struct loongarch_elf_link_hash_table *htab; 513 514 htab = loongarch_elf_hash_table (info); 515 BFD_ASSERT (htab != NULL); 516 517 if (!loongarch_elf_create_got_section (dynobj, info)) 518 return false; 519 520 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) 521 return false; 522 523 if (!bfd_link_pic (info)) 524 htab->sdyntdata 525 = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn", 526 SEC_ALLOC | SEC_THREAD_LOCAL); 527 528 if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss 529 || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata))) 530 abort (); 531 532 return true; 533} 534 535static bool 536loongarch_elf_record_tls_and_got_reference (bfd *abfd, 537 struct bfd_link_info *info, 538 struct elf_link_hash_entry *h, 539 unsigned long symndx, 540 char tls_type) 541{ 542 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 543 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 544 545 /* This is a global offset table entry for a local symbol. */ 546 if (elf_local_got_refcounts (abfd) == NULL) 547 { 548 bfd_size_type size = 549 symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type)); 550 if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size))) 551 return false; 552 _bfd_loongarch_elf_local_got_tls_type (abfd) = 553 (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info); 554 } 555 556 switch (tls_type) 557 { 558 case GOT_NORMAL: 559 case GOT_TLS_GD: 560 case GOT_TLS_IE: 561 /* Need GOT. */ 562 if (htab->elf.sgot == NULL 563 && !loongarch_elf_create_got_section (htab->elf.dynobj, info)) 564 return false; 565 if (h) 566 { 567 if (h->got.refcount < 0) 568 h->got.refcount = 0; 569 h->got.refcount++; 570 } 571 else 572 elf_local_got_refcounts (abfd)[symndx]++; 573 break; 574 case GOT_TLS_LE: 575 /* No need for GOT. */ 576 break; 577 default: 578 _bfd_error_handler (_("Internal error: unreachable.")); 579 return false; 580 } 581 582 char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx); 583 *new_tls_type |= tls_type; 584 if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL)) 585 { 586 _bfd_error_handler (_("%pB: `%s' accessed both as normal and " 587 "thread local symbol"), 588 abfd, 589 h ? h->root.root.string : "<local>"); 590 return false; 591 } 592 593 return true; 594} 595 596/* Look through the relocs for a section during the first phase, and 597 allocate space in the global offset table or procedure linkage 598 table. */ 599 600static bool 601loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, 602 asection *sec, const Elf_Internal_Rela *relocs) 603{ 604 struct loongarch_elf_link_hash_table *htab; 605 Elf_Internal_Shdr *symtab_hdr; 606 struct elf_link_hash_entry **sym_hashes; 607 const Elf_Internal_Rela *rel; 608 asection *sreloc = NULL; 609 610 if (bfd_link_relocatable (info)) 611 return true; 612 613 htab = loongarch_elf_hash_table (info); 614 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 615 sym_hashes = elf_sym_hashes (abfd); 616 617 if (htab->elf.dynobj == NULL) 618 htab->elf.dynobj = abfd; 619 620 for (rel = relocs; rel < relocs + sec->reloc_count; rel++) 621 { 622 unsigned int r_type; 623 unsigned int r_symndx; 624 struct elf_link_hash_entry *h; 625 Elf_Internal_Sym *isym = NULL; 626 627 r_symndx = ELFNN_R_SYM (rel->r_info); 628 r_type = ELFNN_R_TYPE (rel->r_info); 629 630 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) 631 { 632 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx); 633 return false; 634 } 635 636 if (r_symndx < symtab_hdr->sh_info) 637 { 638 /* A local symbol. */ 639 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx); 640 if (isym == NULL) 641 return false; 642 643 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) 644 { 645 h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true); 646 if (h == NULL) 647 return false; 648 649 h->type = STT_GNU_IFUNC; 650 h->ref_regular = 1; 651 } 652 else 653 h = NULL; 654 } 655 else 656 { 657 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 658 while (h->root.type == bfd_link_hash_indirect 659 || h->root.type == bfd_link_hash_warning) 660 h = (struct elf_link_hash_entry *) h->root.u.i.link; 661 } 662 663 /* It is referenced by a non-shared object. */ 664 if (h != NULL) 665 h->ref_regular = 1; 666 667 if (h && h->type == STT_GNU_IFUNC) 668 { 669 if (htab->elf.dynobj == NULL) 670 htab->elf.dynobj = abfd; 671 672 /* Create 'irelifunc' in PIC object. */ 673 if (bfd_link_pic (info) 674 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 675 return false; 676 /* If '.plt' not represent, create '.iplt' to deal with ifunc. */ 677 else if (!htab->elf.splt 678 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 679 return false; 680 /* Create the ifunc sections, iplt and ipltgot, for static 681 executables. */ 682 if ((r_type == R_LARCH_64 || r_type == R_LARCH_32) 683 && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 684 return false; 685 686 if (h->plt.refcount < 0) 687 h->plt.refcount = 0; 688 h->plt.refcount++; 689 h->needs_plt = 1; 690 691 elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc; 692 } 693 694 int need_dynreloc = 0; 695 int only_need_pcrel = 0; 696 697 switch (r_type) 698 { 699 case R_LARCH_GOT_PC_HI20: 700 case R_LARCH_GOT_HI20: 701 case R_LARCH_SOP_PUSH_GPREL: 702 /* For la.global. */ 703 if (h) 704 h->pointer_equality_needed = 1; 705 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 706 r_symndx, 707 GOT_NORMAL)) 708 return false; 709 break; 710 711 case R_LARCH_TLS_LD_PC_HI20: 712 case R_LARCH_TLS_LD_HI20: 713 case R_LARCH_TLS_GD_PC_HI20: 714 case R_LARCH_TLS_GD_HI20: 715 case R_LARCH_SOP_PUSH_TLS_GD: 716 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 717 r_symndx, 718 GOT_TLS_GD)) 719 return false; 720 break; 721 722 case R_LARCH_TLS_IE_PC_HI20: 723 case R_LARCH_TLS_IE_HI20: 724 case R_LARCH_SOP_PUSH_TLS_GOT: 725 if (bfd_link_pic (info)) 726 /* May fail for lazy-bind. */ 727 info->flags |= DF_STATIC_TLS; 728 729 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 730 r_symndx, 731 GOT_TLS_IE)) 732 return false; 733 break; 734 735 case R_LARCH_TLS_LE_HI20: 736 case R_LARCH_SOP_PUSH_TLS_TPREL: 737 if (!bfd_link_executable (info)) 738 return false; 739 740 info->flags |= DF_STATIC_TLS; 741 742 if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 743 r_symndx, 744 GOT_TLS_LE)) 745 return false; 746 break; 747 748 case R_LARCH_ABS_HI20: 749 case R_LARCH_SOP_PUSH_ABSOLUTE: 750 if (h != NULL) 751 /* If this reloc is in a read-only section, we might 752 need a copy reloc. We can't check reliably at this 753 stage whether the section is read-only, as input 754 sections have not yet been mapped to output sections. 755 Tentatively set the flag for now, and correct in 756 adjust_dynamic_symbol. */ 757 h->non_got_ref = 1; 758 break; 759 760 case R_LARCH_PCALA_HI20: 761 if (h != NULL) 762 { 763 /* For pcalau12i + jirl. */ 764 h->needs_plt = 1; 765 if (h->plt.refcount < 0) 766 h->plt.refcount = 0; 767 h->plt.refcount++; 768 769 h->non_got_ref = 1; 770 h->pointer_equality_needed = 1; 771 } 772 773 break; 774 775 case R_LARCH_B21: 776 case R_LARCH_B16: 777 case R_LARCH_B26: 778 if (h != NULL) 779 { 780 h->needs_plt = 1; 781 if (!bfd_link_pic (info)) 782 h->non_got_ref = 1; 783 784 /* We try to create PLT stub for all non-local function. */ 785 if (h->plt.refcount < 0) 786 h->plt.refcount = 0; 787 h->plt.refcount++; 788 } 789 790 break; 791 792 case R_LARCH_SOP_PUSH_PCREL: 793 if (h != NULL) 794 { 795 if (!bfd_link_pic (info)) 796 h->non_got_ref = 1; 797 798 /* We try to create PLT stub for all non-local function. */ 799 if (h->plt.refcount < 0) 800 h->plt.refcount = 0; 801 h->plt.refcount++; 802 h->pointer_equality_needed = 1; 803 } 804 805 break; 806 807 case R_LARCH_SOP_PUSH_PLT_PCREL: 808 /* This symbol requires a procedure linkage table entry. We 809 actually build the entry in adjust_dynamic_symbol, 810 because this might be a case of linking PIC code without 811 linking in any dynamic objects, in which case we don't 812 need to generate a procedure linkage table after all. */ 813 if (h != NULL) 814 { 815 h->needs_plt = 1; 816 if (h->plt.refcount < 0) 817 h->plt.refcount = 0; 818 h->plt.refcount++; 819 } 820 break; 821 822 case R_LARCH_TLS_DTPREL32: 823 case R_LARCH_TLS_DTPREL64: 824 need_dynreloc = 1; 825 only_need_pcrel = 1; 826 break; 827 828 case R_LARCH_JUMP_SLOT: 829 case R_LARCH_32: 830 case R_LARCH_64: 831 832 need_dynreloc = 1; 833 834 /* If resolved symbol is defined in this object, 835 1. Under pie, the symbol is known. We convert it 836 into R_LARCH_RELATIVE and need load-addr still. 837 2. Under pde, the symbol is known and we can discard R_LARCH_NN. 838 3. Under dll, R_LARCH_NN can't be changed normally, since 839 its defination could be covered by the one in executable. 840 For symbolic, we convert it into R_LARCH_RELATIVE. 841 Thus, only under pde, it needs pcrel only. We discard it. */ 842 only_need_pcrel = bfd_link_pde (info); 843 844 if (h != NULL 845 && (!bfd_link_pic (info) 846 || h->type == STT_GNU_IFUNC)) 847 { 848 /* This reloc might not bind locally. */ 849 h->non_got_ref = 1; 850 h->pointer_equality_needed = 1; 851 852 if (!h->def_regular 853 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) 854 { 855 /* We may need a .plt entry if the symbol is a function 856 defined in a shared lib or is a function referenced 857 from the code or read-only section. */ 858 h->plt.refcount += 1; 859 } 860 } 861 break; 862 863 case R_LARCH_GNU_VTINHERIT: 864 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 865 return false; 866 break; 867 868 case R_LARCH_GNU_VTENTRY: 869 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 870 return false; 871 break; 872 873 default: 874 break; 875 } 876 877 /* Record some info for sizing and allocating dynamic entry. */ 878 if (need_dynreloc && (sec->flags & SEC_ALLOC)) 879 { 880 /* When creating a shared object, we must copy these 881 relocs into the output file. We create a reloc 882 section in dynobj and make room for the reloc. */ 883 struct elf_dyn_relocs *p; 884 struct elf_dyn_relocs **head; 885 886 if (sreloc == NULL) 887 { 888 sreloc 889 = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj, 890 LARCH_ELF_LOG_WORD_BYTES, 891 abfd, /*rela?*/ true); 892 if (sreloc == NULL) 893 return false; 894 } 895 896 /* If this is a global symbol, we count the number of 897 relocations we need for this symbol. */ 898 if (h != NULL) 899 head = &h->dyn_relocs; 900 else 901 { 902 /* Track dynamic relocs needed for local syms too. 903 We really need local syms available to do this 904 easily. Oh well. */ 905 906 asection *s; 907 void *vpp; 908 909 s = bfd_section_from_elf_index (abfd, isym->st_shndx); 910 if (s == NULL) 911 s = sec; 912 913 vpp = &elf_section_data (s)->local_dynrel; 914 head = (struct elf_dyn_relocs **) vpp; 915 } 916 917 p = *head; 918 if (p == NULL || p->sec != sec) 919 { 920 bfd_size_type amt = sizeof *p; 921 p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt); 922 if (p == NULL) 923 return false; 924 p->next = *head; 925 *head = p; 926 p->sec = sec; 927 p->count = 0; 928 p->pc_count = 0; 929 } 930 931 p->count++; 932 p->pc_count += only_need_pcrel; 933 } 934 } 935 936 return true; 937} 938 939/* Find dynamic relocs for H that apply to read-only sections. */ 940 941static asection * 942readonly_dynrelocs (struct elf_link_hash_entry *h) 943{ 944 struct elf_dyn_relocs *p; 945 946 for (p = h->dyn_relocs; p != NULL; p = p->next) 947 { 948 asection *s = p->sec->output_section; 949 950 if (s != NULL && (s->flags & SEC_READONLY) != 0) 951 return p->sec; 952 } 953 return NULL; 954} 955 956/* Adjust a symbol defined by a dynamic object and referenced by a 957 regular object. The current definition is in some section of the 958 dynamic object, but we're not including those sections. We have to 959 change the definition to something the rest of the link can 960 understand. */ 961static bool 962loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info, 963 struct elf_link_hash_entry *h) 964{ 965 struct loongarch_elf_link_hash_table *htab; 966 bfd *dynobj; 967 968 htab = loongarch_elf_hash_table (info); 969 BFD_ASSERT (htab != NULL); 970 971 dynobj = htab->elf.dynobj; 972 973 /* Make sure we know what is going on here. */ 974 BFD_ASSERT (dynobj != NULL 975 && (h->needs_plt || h->type == STT_GNU_IFUNC || h->is_weakalias 976 || (h->def_dynamic && h->ref_regular && !h->def_regular))); 977 978 /* If this is a function, put it in the procedure linkage table. We 979 will fill in the contents of the procedure linkage table later 980 (although we could actually do it here). */ 981 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt) 982 { 983 if (h->plt.refcount < 0 984 || (h->type != STT_GNU_IFUNC 985 && (SYMBOL_REFERENCES_LOCAL (info, h) 986 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 987 && h->root.type == bfd_link_hash_undefweak)))) 988 { 989 /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc 990 in an input file, but the symbol was never referred to by a 991 dynamic object, or if all references were garbage collected. 992 In such a case, we don't actually need to build a PLT entry. */ 993 h->plt.offset = MINUS_ONE; 994 h->needs_plt = 0; 995 } 996 else 997 h->needs_plt = 1; 998 999 return true; 1000 } 1001 else 1002 h->plt.offset = MINUS_ONE; 1003 1004 /* If this is a weak symbol, and there is a real definition, the 1005 processor independent code will have arranged for us to see the 1006 real definition first, and we can just use the same value. */ 1007 if (h->is_weakalias) 1008 { 1009 struct elf_link_hash_entry *def = weakdef (h); 1010 BFD_ASSERT (def->root.type == bfd_link_hash_defined); 1011 h->root.u.def.section = def->root.u.def.section; 1012 h->root.u.def.value = def->root.u.def.value; 1013 return true; 1014 } 1015 1016 /* R_LARCH_COPY is not adept glibc, not to generate. */ 1017 /* Can not print anything, because make check ld. */ 1018 return true; 1019} 1020 1021/* Allocate space in .plt, .got and associated reloc sections for 1022 dynamic relocs. */ 1023 1024static bool 1025allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) 1026{ 1027 struct bfd_link_info *info; 1028 struct loongarch_elf_link_hash_table *htab; 1029 struct elf_dyn_relocs *p; 1030 1031 if (h->root.type == bfd_link_hash_indirect) 1032 return true; 1033 1034 if (h->type == STT_GNU_IFUNC 1035 && h->def_regular) 1036 return true; 1037 1038 info = (struct bfd_link_info *) inf; 1039 htab = loongarch_elf_hash_table (info); 1040 bool dyn = htab->elf.dynamic_sections_created; 1041 BFD_ASSERT (htab != NULL); 1042 1043 do 1044 { 1045 asection *plt, *gotplt, *relplt; 1046 1047 if (!h->needs_plt) 1048 break; 1049 1050 h->needs_plt = 0; 1051 1052 if (htab->elf.splt) 1053 { 1054 if (h->dynindx == -1 && !h->forced_local && dyn 1055 && h->root.type == bfd_link_hash_undefweak) 1056 { 1057 if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1058 return false; 1059 } 1060 1061 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h) 1062 && h->type != STT_GNU_IFUNC) 1063 break; 1064 1065 plt = htab->elf.splt; 1066 gotplt = htab->elf.sgotplt; 1067 relplt = htab->elf.srelplt; 1068 } 1069 else if (htab->elf.iplt) 1070 { 1071 /* .iplt only for IFUNC. */ 1072 if (h->type != STT_GNU_IFUNC) 1073 break; 1074 1075 plt = htab->elf.iplt; 1076 gotplt = htab->elf.igotplt; 1077 relplt = htab->elf.irelplt; 1078 } 1079 else 1080 break; 1081 1082 if (plt->size == 0) 1083 plt->size = PLT_HEADER_SIZE; 1084 1085 h->plt.offset = plt->size; 1086 plt->size += PLT_ENTRY_SIZE; 1087 gotplt->size += GOT_ENTRY_SIZE; 1088 relplt->size += sizeof (ElfNN_External_Rela); 1089 1090 /* If this symbol is not defined in a regular file, and we are 1091 not generating a shared library, then set the symbol to this 1092 location in the .plt. This is required to make function 1093 pointers compare as equal between the normal executable and 1094 the shared library. */ 1095 if (!bfd_link_pic (info) 1096 && !h->def_regular) 1097 { 1098 h->root.u.def.section = plt; 1099 h->root.u.def.value = h->plt.offset; 1100 } 1101 1102 h->needs_plt = 1; 1103 } 1104 while (0); 1105 1106 if (!h->needs_plt) 1107 h->plt.offset = MINUS_ONE; 1108 1109 if (0 < h->got.refcount) 1110 { 1111 asection *s; 1112 int tls_type = loongarch_elf_hash_entry (h)->tls_type; 1113 1114 /* Make sure this symbol is output as a dynamic symbol. 1115 Undefined weak syms won't yet be marked as dynamic. */ 1116 if (h->dynindx == -1 && !h->forced_local && dyn 1117 && h->root.type == bfd_link_hash_undefweak) 1118 { 1119 if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1120 return false; 1121 } 1122 1123 s = htab->elf.sgot; 1124 h->got.offset = s->size; 1125 if (tls_type & (GOT_TLS_GD | GOT_TLS_IE)) 1126 { 1127 /* TLS_GD needs two dynamic relocs and two GOT slots. */ 1128 if (tls_type & GOT_TLS_GD) 1129 { 1130 s->size += 2 * GOT_ENTRY_SIZE; 1131 if (bfd_link_executable (info)) 1132 { 1133 /* Link exe and not defined local. */ 1134 if (!SYMBOL_REFERENCES_LOCAL (info, h)) 1135 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); 1136 } 1137 else 1138 { 1139 if (SYMBOL_REFERENCES_LOCAL (info, h)) 1140 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1141 else 1142 htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); 1143 } 1144 } 1145 1146 /* TLS_IE needs one dynamic reloc and one GOT slot. */ 1147 if (tls_type & GOT_TLS_IE) 1148 { 1149 s->size += GOT_ENTRY_SIZE; 1150 1151 if (bfd_link_executable (info)) 1152 { 1153 /* Link exe and not defined local. */ 1154 if (!SYMBOL_REFERENCES_LOCAL (info, h)) 1155 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1156 } 1157 else 1158 { 1159 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1160 } 1161 } 1162 } 1163 else 1164 { 1165 s->size += GOT_ENTRY_SIZE; 1166 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 1167 || h->root.type != bfd_link_hash_undefweak) 1168 && (bfd_link_pic (info) 1169 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), 1170 h)) 1171 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) 1172 /* Undefined weak symbol in static PIE resolves to 0 without 1173 any dynamic relocations. */ 1174 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1175 } 1176 } 1177 else 1178 h->got.offset = MINUS_ONE; 1179 1180 if (h->dyn_relocs == NULL) 1181 return true; 1182 1183 /* Extra dynamic relocate, 1184 * R_LARCH_64 1185 * R_LARCH_TLS_DTPRELNN 1186 * R_LARCH_JUMP_SLOT 1187 * R_LARCH_NN. */ 1188 1189 if (SYMBOL_CALLS_LOCAL (info, h)) 1190 { 1191 struct elf_dyn_relocs **pp; 1192 1193 for (pp = &h->dyn_relocs; (p = *pp) != NULL;) 1194 { 1195 p->count -= p->pc_count; 1196 p->pc_count = 0; 1197 if (p->count == 0) 1198 *pp = p->next; 1199 else 1200 pp = &p->next; 1201 } 1202 } 1203 1204 if (h->root.type == bfd_link_hash_undefweak) 1205 { 1206 if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h) 1207 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 1208 || (!bfd_link_pic (info) && h->non_got_ref)) 1209 h->dyn_relocs = NULL; 1210 else if (h->dynindx == -1 && !h->forced_local) 1211 { 1212 /* Make sure this symbol is output as a dynamic symbol. 1213 Undefined weak syms won't yet be marked as dynamic. */ 1214 if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1215 return false; 1216 1217 if (h->dynindx == -1) 1218 h->dyn_relocs = NULL; 1219 } 1220 } 1221 1222 for (p = h->dyn_relocs; p != NULL; p = p->next) 1223 { 1224 asection *sreloc = elf_section_data (p->sec)->sreloc; 1225 sreloc->size += p->count * sizeof (ElfNN_External_Rela); 1226 } 1227 1228 return true; 1229} 1230 1231/* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs. 1232 For local def and ref ifunc, 1233 dynamic relocations are stored in 1234 1. rela.srelgot section in dynamic object (dll or exec). 1235 2. rela.irelplt section in static executable. 1236 Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used 1237 instead of rela.srelplt. Glibc ELF loader will not support 1238 R_LARCH_IRELATIVE relocation in rela.plt. */ 1239 1240static bool 1241local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, 1242 struct elf_link_hash_entry *h, 1243 struct elf_dyn_relocs **head, 1244 unsigned int plt_entry_size, 1245 unsigned int plt_header_size, 1246 unsigned int got_entry_size, 1247 bool avoid_plt) 1248{ 1249 asection *plt, *gotplt, *relplt; 1250 struct elf_dyn_relocs *p; 1251 unsigned int sizeof_reloc; 1252 const struct elf_backend_data *bed; 1253 struct elf_link_hash_table *htab; 1254 /* If AVOID_PLT is TRUE, don't use PLT if possible. */ 1255 bool use_plt = !avoid_plt || h->plt.refcount > 0; 1256 bool need_dynreloc = !use_plt || bfd_link_pic (info); 1257 1258 /* When a PIC object references a STT_GNU_IFUNC symbol defined 1259 in executable or it isn't referenced via PLT, the address of 1260 the resolved function may be used. But in non-PIC executable, 1261 the address of its plt slot may be used. Pointer equality may 1262 not work correctly. PIE or non-PLT reference should be used if 1263 pointer equality is required here. 1264 1265 If STT_GNU_IFUNC symbol is defined in position-dependent executable, 1266 backend should change it to the normal function and set its address 1267 to its PLT entry which should be resolved by R_*_IRELATIVE at 1268 run-time. All external references should be resolved to its PLT in 1269 executable. */ 1270 if (!need_dynreloc 1271 && !(bfd_link_pde (info) && h->def_regular) 1272 && (h->dynindx != -1 1273 || info->export_dynamic) 1274 && h->pointer_equality_needed) 1275 { 1276 info->callbacks->einfo 1277 /* xgettext:c-format. */ 1278 (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer " 1279 "equality in `%pB' can not be used when making an " 1280 "executable; recompile with -fPIE and relink with -pie\n"), 1281 h->root.root.string, 1282 h->root.u.def.section->owner); 1283 bfd_set_error (bfd_error_bad_value); 1284 return false; 1285 } 1286 1287 htab = elf_hash_table (info); 1288 1289 /* When the symbol is marked with regular reference, if PLT isn't used 1290 or we are building a PIC object, we must keep dynamic relocation 1291 if there is non-GOT reference and use PLT if there is PC-relative 1292 reference. */ 1293 if (need_dynreloc && h->ref_regular) 1294 { 1295 bool keep = false; 1296 for (p = *head; p != NULL; p = p->next) 1297 if (p->count) 1298 { 1299 h->non_got_ref = 1; 1300 /* Need dynamic relocations for non-GOT reference. */ 1301 keep = true; 1302 if (p->pc_count) 1303 { 1304 /* Must use PLT for PC-relative reference. */ 1305 use_plt = true; 1306 need_dynreloc = bfd_link_pic (info); 1307 break; 1308 } 1309 } 1310 if (keep) 1311 goto keep; 1312 } 1313 1314 /* Support garbage collection against STT_GNU_IFUNC symbols. */ 1315 if (h->plt.refcount <= 0 && h->got.refcount <= 0) 1316 { 1317 h->got = htab->init_got_offset; 1318 h->plt = htab->init_plt_offset; 1319 *head = NULL; 1320 return true; 1321 } 1322 1323 /* Return and discard space for dynamic relocations against it if 1324 it is never referenced. */ 1325 if (!h->ref_regular) 1326 { 1327 if (h->plt.refcount > 0 1328 || h->got.refcount > 0) 1329 abort (); 1330 h->got = htab->init_got_offset; 1331 h->plt = htab->init_plt_offset; 1332 *head = NULL; 1333 return true; 1334 } 1335 1336 keep: 1337 bed = get_elf_backend_data (info->output_bfd); 1338 if (bed->rela_plts_and_copies_p) 1339 sizeof_reloc = bed->s->sizeof_rela; 1340 else 1341 sizeof_reloc = bed->s->sizeof_rel; 1342 1343 /* When building a static executable, use iplt, igot.plt and 1344 rela.iplt sections for STT_GNU_IFUNC symbols. */ 1345 if (htab->splt != NULL) 1346 { 1347 plt = htab->splt; 1348 gotplt = htab->sgotplt; 1349 /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */ 1350 relplt = htab->srelgot; 1351 1352 /* If this is the first plt entry and PLT is used, make room for 1353 the special first entry. */ 1354 if (plt->size == 0 && use_plt) 1355 plt->size += plt_header_size; 1356 } 1357 else 1358 { 1359 plt = htab->iplt; 1360 gotplt = htab->igotplt; 1361 relplt = htab->irelplt; 1362 } 1363 1364 if (use_plt) 1365 { 1366 /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need 1367 the original value for R_*_IRELATIVE. */ 1368 h->plt.offset = plt->size; 1369 1370 /* Make room for this entry in the plt/iplt section. */ 1371 plt->size += plt_entry_size; 1372 1373 /* We also need to make an entry in the got.plt/got.iplt section, 1374 which will be placed in the got section by the linker script. */ 1375 gotplt->size += got_entry_size; 1376 } 1377 1378 /* We also need to make an entry in the rela.plt/.rela.iplt 1379 section for GOTPLT relocation if PLT is used. */ 1380 if (use_plt) 1381 { 1382 relplt->size += sizeof_reloc; 1383 relplt->reloc_count++; 1384 } 1385 1386 /* We need dynamic relocation for STT_GNU_IFUNC symbol only when 1387 there is a non-GOT reference in a PIC object or PLT isn't used. */ 1388 if (!need_dynreloc || !h->non_got_ref) 1389 *head = NULL; 1390 1391 /* Finally, allocate space. */ 1392 p = *head; 1393 if (p != NULL) 1394 { 1395 bfd_size_type count = 0; 1396 do 1397 { 1398 count += p->count; 1399 p = p->next; 1400 } 1401 while (p != NULL); 1402 1403 htab->ifunc_resolvers = count != 0; 1404 1405 /* Dynamic relocations are stored in 1406 1. rela.srelgot section in PIC object. 1407 2. rela.srelgot section in dynamic executable. 1408 3. rela.irelplt section in static executable. */ 1409 if (htab->splt != NULL) 1410 htab->srelgot->size += count * sizeof_reloc; 1411 else 1412 { 1413 relplt->size += count * sizeof_reloc; 1414 relplt->reloc_count += count; 1415 } 1416 } 1417 1418 /* For STT_GNU_IFUNC symbol, got.plt has the real function address 1419 and got has the PLT entry adddress. We will load the GOT entry 1420 with the PLT entry in finish_dynamic_symbol if it is used. For 1421 branch, it uses got.plt. For symbol value, if PLT is used, 1422 1. Use got.plt in a PIC object if it is forced local or not 1423 dynamic. 1424 2. Use got.plt in a non-PIC object if pointer equality isn't 1425 needed. 1426 3. Use got.plt in PIE. 1427 4. Use got.plt if got isn't used. 1428 5. Otherwise use got so that it can be shared among different 1429 objects at run-time. 1430 If PLT isn't used, always use got for symbol value. 1431 We only need to relocate got entry in PIC object or in dynamic 1432 executable without PLT. */ 1433 if (use_plt 1434 && (h->got.refcount <= 0 1435 || (bfd_link_pic (info) 1436 && (h->dynindx == -1 1437 || h->forced_local)) 1438 || ( 1439 !h->pointer_equality_needed) 1440 || htab->sgot == NULL)) 1441 { 1442 /* Use got.plt. */ 1443 h->got.offset = (bfd_vma) -1; 1444 } 1445 else 1446 { 1447 if (!use_plt) 1448 { 1449 /* PLT isn't used. */ 1450 h->plt.offset = (bfd_vma) -1; 1451 } 1452 if (h->got.refcount <= 0) 1453 { 1454 /* GOT isn't need when there are only relocations for static 1455 pointers. */ 1456 h->got.offset = (bfd_vma) -1; 1457 } 1458 else 1459 { 1460 h->got.offset = htab->sgot->size; 1461 htab->sgot->size += got_entry_size; 1462 /* Need to relocate the GOT entry in a PIC object or PLT isn't 1463 used. Otherwise, the GOT entry will be filled with the PLT 1464 entry and dynamic GOT relocation isn't needed. */ 1465 if (need_dynreloc) 1466 { 1467 /* For non-static executable, dynamic GOT relocation is in 1468 rela.got section, but for static executable, it is 1469 in rela.iplt section. */ 1470 if (htab->splt != NULL) 1471 htab->srelgot->size += sizeof_reloc; 1472 else 1473 { 1474 relplt->size += sizeof_reloc; 1475 relplt->reloc_count++; 1476 } 1477 } 1478 } 1479 } 1480 1481 return true; 1482} 1483 1484/* Allocate space in .plt, .got and associated reloc sections for 1485 ifunc dynamic relocs. */ 1486 1487static bool 1488elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) 1489{ 1490 struct bfd_link_info *info; 1491 /* An example of a bfd_link_hash_indirect symbol is versioned 1492 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect) 1493 -> __gxx_personality_v0(bfd_link_hash_defined) 1494 1495 There is no need to process bfd_link_hash_indirect symbols here 1496 because we will also be presented with the concrete instance of 1497 the symbol and loongarch_elf_copy_indirect_symbol () will have been 1498 called to copy all relevant data from the generic to the concrete 1499 symbol instance. */ 1500 if (h->root.type == bfd_link_hash_indirect) 1501 return true; 1502 1503 if (h->root.type == bfd_link_hash_warning) 1504 h = (struct elf_link_hash_entry *) h->root.u.i.link; 1505 1506 info = (struct bfd_link_info *) inf; 1507 1508 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it 1509 here if it is defined and referenced in a non-shared object. */ 1510 if (h->type == STT_GNU_IFUNC && h->def_regular) 1511 { 1512 if (SYMBOL_REFERENCES_LOCAL (info, h)) 1513 return local_allocate_ifunc_dyn_relocs (info, h, 1514 &h->dyn_relocs, 1515 PLT_ENTRY_SIZE, 1516 PLT_HEADER_SIZE, 1517 GOT_ENTRY_SIZE, 1518 false); 1519 else 1520 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, 1521 &h->dyn_relocs, 1522 PLT_ENTRY_SIZE, 1523 PLT_HEADER_SIZE, 1524 GOT_ENTRY_SIZE, 1525 false); 1526 } 1527 1528 return true; 1529} 1530 1531/* Allocate space in .plt, .got and associated reloc sections for 1532 ifunc dynamic relocs. */ 1533 1534static bool 1535elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf) 1536{ 1537 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; 1538 1539 if (h->type != STT_GNU_IFUNC 1540 || !h->def_regular 1541 || !h->ref_regular 1542 || !h->forced_local 1543 || h->root.type != bfd_link_hash_defined) 1544 abort (); 1545 1546 return elfNN_allocate_ifunc_dynrelocs (h, inf); 1547} 1548 1549/* Set DF_TEXTREL if we find any dynamic relocs that apply to 1550 read-only sections. */ 1551 1552static bool 1553maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) 1554{ 1555 asection *sec; 1556 1557 if (h->root.type == bfd_link_hash_indirect) 1558 return true; 1559 1560 sec = readonly_dynrelocs (h); 1561 if (sec != NULL) 1562 { 1563 struct bfd_link_info *info = (struct bfd_link_info *) info_p; 1564 1565 info->flags |= DF_TEXTREL; 1566 info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in " 1567 "read-only section `%pA'\n"), 1568 sec->owner, h->root.root.string, sec); 1569 1570 /* Not an error, just cut short the traversal. */ 1571 return false; 1572 } 1573 return true; 1574} 1575 1576static bool 1577loongarch_elf_size_dynamic_sections (bfd *output_bfd, 1578 struct bfd_link_info *info) 1579{ 1580 struct loongarch_elf_link_hash_table *htab; 1581 bfd *dynobj; 1582 asection *s; 1583 bfd *ibfd; 1584 1585 htab = loongarch_elf_hash_table (info); 1586 BFD_ASSERT (htab != NULL); 1587 dynobj = htab->elf.dynobj; 1588 BFD_ASSERT (dynobj != NULL); 1589 1590 if (htab->elf.dynamic_sections_created) 1591 { 1592 /* Set the contents of the .interp section to the interpreter. */ 1593 if (bfd_link_executable (info) && !info->nointerp) 1594 { 1595 const char *interpreter; 1596 s = bfd_get_linker_section (dynobj, ".interp"); 1597 BFD_ASSERT (s != NULL); 1598 1599 if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32) 1600 interpreter = "/lib32/ld.so.1"; 1601 else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64) 1602 interpreter = "/lib64/ld.so.1"; 1603 else 1604 interpreter = "/lib/ld.so.1"; 1605 1606 s->contents = (unsigned char *) interpreter; 1607 s->size = strlen (interpreter) + 1; 1608 } 1609 } 1610 1611 /* Set up .got offsets for local syms, and space for local dynamic 1612 relocs. */ 1613 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) 1614 { 1615 bfd_signed_vma *local_got; 1616 bfd_signed_vma *end_local_got; 1617 char *local_tls_type; 1618 bfd_size_type locsymcount; 1619 Elf_Internal_Shdr *symtab_hdr; 1620 asection *srel; 1621 1622 if (!is_loongarch_elf (ibfd)) 1623 continue; 1624 1625 for (s = ibfd->sections; s != NULL; s = s->next) 1626 { 1627 struct elf_dyn_relocs *p; 1628 1629 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) 1630 { 1631 p->count -= p->pc_count; 1632 if (!bfd_is_abs_section (p->sec) 1633 && bfd_is_abs_section (p->sec->output_section)) 1634 { 1635 /* Input section has been discarded, either because 1636 it is a copy of a linkonce section or due to 1637 linker script /DISCARD/, so we'll be discarding 1638 the relocs too. */ 1639 } 1640 else if (0 < p->count) 1641 { 1642 srel = elf_section_data (p->sec)->sreloc; 1643 srel->size += p->count * sizeof (ElfNN_External_Rela); 1644 if ((p->sec->output_section->flags & SEC_READONLY) != 0) 1645 info->flags |= DF_TEXTREL; 1646 } 1647 } 1648 } 1649 1650 local_got = elf_local_got_refcounts (ibfd); 1651 if (!local_got) 1652 continue; 1653 1654 symtab_hdr = &elf_symtab_hdr (ibfd); 1655 locsymcount = symtab_hdr->sh_info; 1656 end_local_got = local_got + locsymcount; 1657 local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd); 1658 s = htab->elf.sgot; 1659 srel = htab->elf.srelgot; 1660 for (; local_got < end_local_got; ++local_got, ++local_tls_type) 1661 { 1662 if (0 < *local_got) 1663 { 1664 *local_got = s->size; 1665 1666 /* TLS gd use two got. */ 1667 if (*local_tls_type & GOT_TLS_GD) 1668 s->size += GOT_ENTRY_SIZE * 2; 1669 else 1670 /* Normal got, tls ie/ld use one got. */ 1671 s->size += GOT_ENTRY_SIZE; 1672 1673 if (bfd_link_executable (info) 1674 && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE))) 1675 ;/* Do nothing. */ 1676 else 1677 { 1678 srel->size += sizeof (ElfNN_External_Rela); 1679 } 1680 } 1681 else 1682 *local_got = MINUS_ONE; 1683 } 1684 } 1685 1686 /* Allocate global sym .plt and .got entries, and space for global 1687 sym dynamic relocs. */ 1688 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); 1689 1690 /* Allocate global ifunc sym .plt and .got entries, and space for global 1691 ifunc sym dynamic relocs. */ 1692 elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info); 1693 1694 /* Allocate .plt and .got entries, and space for local ifunc symbols. */ 1695 htab_traverse (htab->loc_hash_table, 1696 (void *) elfNN_allocate_local_ifunc_dynrelocs, info); 1697 1698 /* Don't allocate .got.plt section if there are no PLT. */ 1699 if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE 1700 && (htab->elf.splt == NULL || htab->elf.splt->size == 0)) 1701 htab->elf.sgotplt->size = 0; 1702 1703 /* The check_relocs and adjust_dynamic_symbol entry points have 1704 determined the sizes of the various dynamic sections. Allocate 1705 memory for them. */ 1706 for (s = dynobj->sections; s != NULL; s = s->next) 1707 { 1708 if ((s->flags & SEC_LINKER_CREATED) == 0) 1709 continue; 1710 1711 if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot 1712 || s == htab->elf.sgotplt || s == htab->elf.igotplt 1713 || s == htab->elf.sdynbss || s == htab->elf.sdynrelro) 1714 { 1715 /* Strip this section if we don't need it; see the 1716 comment below. */ 1717 } 1718 else if (strncmp (s->name, ".rela", 5) == 0) 1719 { 1720 if (s->size != 0) 1721 { 1722 /* We use the reloc_count field as a counter if we need 1723 to copy relocs into the output file. */ 1724 s->reloc_count = 0; 1725 } 1726 } 1727 else 1728 { 1729 /* It's not one of our sections. */ 1730 continue; 1731 } 1732 1733 if (s->size == 0) 1734 { 1735 /* If we don't need this section, strip it from the 1736 output file. This is mostly to handle .rela.bss and 1737 .rela.plt. We must create both sections in 1738 create_dynamic_sections, because they must be created 1739 before the linker maps input sections to output 1740 sections. The linker does that before 1741 adjust_dynamic_symbol is called, and it is that 1742 function which decides whether anything needs to go 1743 into these sections. */ 1744 s->flags |= SEC_EXCLUDE; 1745 continue; 1746 } 1747 1748 if ((s->flags & SEC_HAS_CONTENTS) == 0) 1749 continue; 1750 1751 /* Allocate memory for the section contents. Zero the memory 1752 for the benefit of .rela.plt, which has 4 unused entries 1753 at the beginning, and we don't want garbage. */ 1754 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); 1755 if (s->contents == NULL) 1756 return false; 1757 } 1758 1759 if (elf_hash_table (info)->dynamic_sections_created) 1760 { 1761 /* Add some entries to the .dynamic section. We fill in the 1762 values later, in loongarch_elf_finish_dynamic_sections, but we 1763 must add the entries now so that we get the correct size for 1764 the .dynamic section. The DT_DEBUG entry is filled in by the 1765 dynamic linker and used by the debugger. */ 1766#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL) 1767 1768 if (bfd_link_executable (info)) 1769 { 1770 if (!add_dynamic_entry (DT_DEBUG, 0)) 1771 return false; 1772 } 1773 1774 if (htab->elf.srelplt->size != 0) 1775 { 1776 if (!add_dynamic_entry (DT_PLTGOT, 0) 1777 || !add_dynamic_entry (DT_PLTRELSZ, 0) 1778 || !add_dynamic_entry (DT_PLTREL, DT_RELA) 1779 || !add_dynamic_entry (DT_JMPREL, 0)) 1780 return false; 1781 } 1782 1783 if (!add_dynamic_entry (DT_RELA, 0) 1784 || !add_dynamic_entry (DT_RELASZ, 0) 1785 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela))) 1786 return false; 1787 1788 /* If any dynamic relocs apply to a read-only section, 1789 then we need a DT_TEXTREL entry. */ 1790 if ((info->flags & DF_TEXTREL) == 0) 1791 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); 1792 1793 if (info->flags & DF_TEXTREL) 1794 { 1795 if (!add_dynamic_entry (DT_TEXTREL, 0)) 1796 return false; 1797 /* Clear the DF_TEXTREL flag. It will be set again if we 1798 write out an actual text relocation; we may not, because 1799 at this point we do not know whether e.g. any .eh_frame 1800 absolute relocations have been converted to PC-relative. */ 1801 info->flags &= ~DF_TEXTREL; 1802 } 1803 } 1804#undef add_dynamic_entry 1805 1806 return true; 1807} 1808 1809#define LARCH_LD_STACK_DEPTH 16 1810static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH]; 1811static size_t larch_stack_top = 0; 1812 1813static bfd_reloc_status_type 1814loongarch_push (int64_t val) 1815{ 1816 if (LARCH_LD_STACK_DEPTH <= larch_stack_top) 1817 return bfd_reloc_outofrange; 1818 larch_opc_stack[larch_stack_top++] = val; 1819 return bfd_reloc_ok; 1820} 1821 1822static bfd_reloc_status_type 1823loongarch_pop (int64_t *val) 1824{ 1825 if (larch_stack_top == 0) 1826 return bfd_reloc_outofrange; 1827 BFD_ASSERT (val); 1828 *val = larch_opc_stack[--larch_stack_top]; 1829 return bfd_reloc_ok; 1830} 1831 1832static bfd_reloc_status_type 1833loongarch_top (int64_t *val) 1834{ 1835 if (larch_stack_top == 0) 1836 return bfd_reloc_outofrange; 1837 BFD_ASSERT (val); 1838 *val = larch_opc_stack[larch_stack_top - 1]; 1839 return bfd_reloc_ok; 1840} 1841 1842static void 1843loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel) 1844{ 1845 BFD_ASSERT (s && s->contents); 1846 const struct elf_backend_data *bed; 1847 bfd_byte *loc; 1848 1849 bed = get_elf_backend_data (abfd); 1850 if (!(s->size > s->reloc_count * bed->s->sizeof_rela)) 1851 BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela); 1852 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela); 1853 bed->s->swap_reloca_out (abfd, rel, loc); 1854} 1855 1856/* Check rel->r_offset in range of contents. */ 1857static bfd_reloc_status_type 1858loongarch_check_offset (const Elf_Internal_Rela *rel, 1859 const asection *input_section) 1860{ 1861 if (0 == strcmp(input_section->name, ".text") 1862 && rel->r_offset > input_section->size) 1863 return bfd_reloc_overflow; 1864 1865 return bfd_reloc_ok; 1866} 1867 1868#define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \ 1869 ({ \ 1870 bfd_reloc_status_type ret = loongarch_pop (&op2); \ 1871 if (ret == bfd_reloc_ok) \ 1872 { \ 1873 ret = loongarch_pop (&op1); \ 1874 if (ret == bfd_reloc_ok) \ 1875 ret = loongarch_push (op3); \ 1876 } \ 1877 ret; \ 1878 }) 1879 1880static bfd_reloc_status_type 1881loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel, 1882 const asection *input_section ATTRIBUTE_UNUSED, 1883 reloc_howto_type *howto, bfd *input_bfd, 1884 bfd_byte *contents, bfd_vma reloc_val) 1885{ 1886 int bits = bfd_get_reloc_size (howto) * 8; 1887 uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset); 1888 1889 if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val)) 1890 return bfd_reloc_overflow; 1891 1892 insn = (insn & (uint32_t)howto->src_mask) 1893 | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val); 1894 1895 bfd_put (bits, input_bfd, insn, contents + rel->r_offset); 1896 1897 return bfd_reloc_ok; 1898} 1899 1900static bfd_reloc_status_type 1901perform_relocation (const Elf_Internal_Rela *rel, asection *input_section, 1902 reloc_howto_type *howto, bfd_vma value, 1903 bfd *input_bfd, bfd_byte *contents) 1904{ 1905 int64_t opr1, opr2, opr3; 1906 bfd_reloc_status_type r = bfd_reloc_ok; 1907 int bits = bfd_get_reloc_size (howto) * 8; 1908 1909 switch (ELFNN_R_TYPE (rel->r_info)) 1910 { 1911 case R_LARCH_SOP_PUSH_PCREL: 1912 case R_LARCH_SOP_PUSH_ABSOLUTE: 1913 case R_LARCH_SOP_PUSH_GPREL: 1914 case R_LARCH_SOP_PUSH_TLS_TPREL: 1915 case R_LARCH_SOP_PUSH_TLS_GOT: 1916 case R_LARCH_SOP_PUSH_TLS_GD: 1917 case R_LARCH_SOP_PUSH_PLT_PCREL: 1918 r = loongarch_push (value); 1919 break; 1920 1921 case R_LARCH_SOP_PUSH_DUP: 1922 r = loongarch_pop (&opr1); 1923 if (r == bfd_reloc_ok) 1924 { 1925 r = loongarch_push (opr1); 1926 if (r == bfd_reloc_ok) 1927 r = loongarch_push (opr1); 1928 } 1929 break; 1930 1931 case R_LARCH_SOP_ASSERT: 1932 r = loongarch_pop (&opr1); 1933 if (r != bfd_reloc_ok || !opr1) 1934 r = bfd_reloc_notsupported; 1935 break; 1936 1937 case R_LARCH_SOP_NOT: 1938 r = loongarch_pop (&opr1); 1939 if (r == bfd_reloc_ok) 1940 r = loongarch_push (!opr1); 1941 break; 1942 1943 case R_LARCH_SOP_SUB: 1944 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2); 1945 break; 1946 1947 case R_LARCH_SOP_SL: 1948 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2); 1949 break; 1950 1951 case R_LARCH_SOP_SR: 1952 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2); 1953 break; 1954 1955 case R_LARCH_SOP_AND: 1956 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2); 1957 break; 1958 1959 case R_LARCH_SOP_ADD: 1960 r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2); 1961 break; 1962 1963 case R_LARCH_SOP_IF_ELSE: 1964 r = loongarch_pop (&opr3); 1965 if (r == bfd_reloc_ok) 1966 { 1967 r = loongarch_pop (&opr2); 1968 if (r == bfd_reloc_ok) 1969 { 1970 r = loongarch_pop (&opr1); 1971 if (r == bfd_reloc_ok) 1972 r = loongarch_push (opr1 ? opr2 : opr3); 1973 } 1974 } 1975 break; 1976 1977 case R_LARCH_SOP_POP_32_S_10_5: 1978 case R_LARCH_SOP_POP_32_S_10_12: 1979 case R_LARCH_SOP_POP_32_S_10_16: 1980 case R_LARCH_SOP_POP_32_S_10_16_S2: 1981 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: 1982 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: 1983 case R_LARCH_SOP_POP_32_S_5_20: 1984 case R_LARCH_SOP_POP_32_U_10_12: 1985 case R_LARCH_SOP_POP_32_U: 1986 r = loongarch_pop (&opr1); 1987 if (r != bfd_reloc_ok) 1988 break; 1989 r = loongarch_check_offset (rel, input_section); 1990 if (r != bfd_reloc_ok) 1991 break; 1992 1993 r = loongarch_reloc_rewrite_imm_insn (rel, input_section, 1994 howto, input_bfd, 1995 contents, (bfd_vma)opr1); 1996 break; 1997 1998 case R_LARCH_TLS_DTPREL32: 1999 case R_LARCH_32: 2000 case R_LARCH_TLS_DTPREL64: 2001 case R_LARCH_64: 2002 r = loongarch_check_offset (rel, input_section); 2003 if (r != bfd_reloc_ok) 2004 break; 2005 2006 bfd_put (bits, input_bfd, value, contents + rel->r_offset); 2007 break; 2008 2009 case R_LARCH_ADD8: 2010 case R_LARCH_ADD16: 2011 case R_LARCH_ADD24: 2012 case R_LARCH_ADD32: 2013 case R_LARCH_ADD64: 2014 r = loongarch_check_offset (rel, input_section); 2015 if (r != bfd_reloc_ok) 2016 break; 2017 2018 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset); 2019 bfd_put (bits, input_bfd, opr1 + value, contents + rel->r_offset); 2020 break; 2021 2022 case R_LARCH_SUB8: 2023 case R_LARCH_SUB16: 2024 case R_LARCH_SUB24: 2025 case R_LARCH_SUB32: 2026 case R_LARCH_SUB64: 2027 r = loongarch_check_offset (rel, input_section); 2028 if (r != bfd_reloc_ok) 2029 break; 2030 2031 opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset); 2032 bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset); 2033 break; 2034 2035 /* For eh_frame and debug info. */ 2036 case R_LARCH_32_PCREL: 2037 value -= sec_addr (input_section) + rel->r_offset; 2038 value += rel->r_addend; 2039 bfd_vma word = bfd_get (howto->bitsize, input_bfd, 2040 contents + rel->r_offset); 2041 word = (word & ~howto->dst_mask) | (value & howto->dst_mask); 2042 bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset); 2043 r = bfd_reloc_ok; 2044 break; 2045 2046 /* New reloc type. 2047 R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */ 2048 case R_LARCH_B16: 2049 case R_LARCH_B21: 2050 case R_LARCH_B26: 2051 case R_LARCH_ABS_HI20: 2052 case R_LARCH_ABS_LO12: 2053 case R_LARCH_ABS64_LO20: 2054 case R_LARCH_ABS64_HI12: 2055 case R_LARCH_PCALA_HI20: 2056 case R_LARCH_PCALA_LO12: 2057 case R_LARCH_PCALA64_LO20: 2058 case R_LARCH_PCALA64_HI12: 2059 case R_LARCH_GOT_PC_HI20: 2060 case R_LARCH_GOT_PC_LO12: 2061 case R_LARCH_GOT64_PC_LO20: 2062 case R_LARCH_GOT64_PC_HI12: 2063 case R_LARCH_GOT_HI20: 2064 case R_LARCH_GOT_LO12: 2065 case R_LARCH_GOT64_LO20: 2066 case R_LARCH_GOT64_HI12: 2067 case R_LARCH_TLS_LE_HI20: 2068 case R_LARCH_TLS_LE_LO12: 2069 case R_LARCH_TLS_LE64_LO20: 2070 case R_LARCH_TLS_LE64_HI12: 2071 case R_LARCH_TLS_IE_PC_HI20: 2072 case R_LARCH_TLS_IE_PC_LO12: 2073 case R_LARCH_TLS_IE64_PC_LO20: 2074 case R_LARCH_TLS_IE64_PC_HI12: 2075 case R_LARCH_TLS_IE_HI20: 2076 case R_LARCH_TLS_IE_LO12: 2077 case R_LARCH_TLS_IE64_LO20: 2078 case R_LARCH_TLS_IE64_HI12: 2079 case R_LARCH_TLS_LD_PC_HI20: 2080 case R_LARCH_TLS_LD_HI20: 2081 case R_LARCH_TLS_GD_PC_HI20: 2082 case R_LARCH_TLS_GD_HI20: 2083 r = loongarch_check_offset (rel, input_section); 2084 if (r != bfd_reloc_ok) 2085 break; 2086 2087 r = loongarch_reloc_rewrite_imm_insn (rel, input_section, 2088 howto, input_bfd, 2089 contents, value); 2090 break; 2091 2092 case R_LARCH_RELAX: 2093 break; 2094 2095 default: 2096 r = bfd_reloc_notsupported; 2097 } 2098 return r; 2099} 2100 2101#define LARCH_RECENT_RELOC_QUEUE_LENGTH 72 2102static struct 2103{ 2104 bfd *bfd; 2105 asection *section; 2106 bfd_vma r_offset; 2107 int r_type; 2108 bfd_vma relocation; 2109 Elf_Internal_Sym *sym; 2110 struct elf_link_hash_entry *h; 2111 bfd_vma addend; 2112 int64_t top_then; 2113} larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH]; 2114static size_t larch_reloc_queue_head = 0; 2115static size_t larch_reloc_queue_tail = 0; 2116 2117static const char * 2118loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h, 2119 Elf_Internal_Sym *sym) 2120{ 2121 const char *ret = NULL; 2122 if (sym) 2123 ret = bfd_elf_string_from_elf_section (input_bfd, 2124 elf_symtab_hdr (input_bfd).sh_link, 2125 sym->st_name); 2126 else if (h) 2127 ret = h->root.root.string; 2128 2129 if (ret == NULL || *ret == '\0') 2130 ret = "<nameless>"; 2131 return ret; 2132} 2133 2134static void 2135loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type, 2136 bfd_vma r_offset, Elf_Internal_Sym *sym, 2137 struct elf_link_hash_entry *h, bfd_vma addend) 2138{ 2139 if ((larch_reloc_queue_head == 0 2140 && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1) 2141 || larch_reloc_queue_head == larch_reloc_queue_tail + 1) 2142 larch_reloc_queue_head = 2143 (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 2144 larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd; 2145 larch_reloc_queue[larch_reloc_queue_tail].section = section; 2146 larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset; 2147 larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type; 2148 larch_reloc_queue[larch_reloc_queue_tail].sym = sym; 2149 larch_reloc_queue[larch_reloc_queue_tail].h = h; 2150 larch_reloc_queue[larch_reloc_queue_tail].addend = addend; 2151 loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then); 2152 larch_reloc_queue_tail = 2153 (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 2154} 2155 2156static void 2157loongarch_dump_reloc_record (void (*p) (const char *fmt, ...)) 2158{ 2159 size_t i = larch_reloc_queue_head; 2160 bfd *a_bfd = NULL; 2161 asection *section = NULL; 2162 bfd_vma r_offset = 0; 2163 int inited = 0; 2164 p ("Dump relocate record:\n"); 2165 p ("stack top\t\trelocation name\t\tsymbol"); 2166 while (i != larch_reloc_queue_tail) 2167 { 2168 if (a_bfd != larch_reloc_queue[i].bfd 2169 || section != larch_reloc_queue[i].section 2170 || r_offset != larch_reloc_queue[i].r_offset) 2171 { 2172 a_bfd = larch_reloc_queue[i].bfd; 2173 section = larch_reloc_queue[i].section; 2174 r_offset = larch_reloc_queue[i].r_offset; 2175 p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd, 2176 larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset); 2177 } 2178 2179 if (!inited) 2180 inited = 1, p ("...\n"); 2181 2182 reloc_howto_type *howto = 2183 loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd, 2184 larch_reloc_queue[i].r_type); 2185 p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then, 2186 howto ? howto->name : "<unknown reloc>", 2187 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h, 2188 larch_reloc_queue[i].sym)); 2189 2190 long addend = larch_reloc_queue[i].addend; 2191 if (addend < 0) 2192 p (" - %ld", -addend); 2193 else if (0 < addend) 2194 p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend); 2195 2196 p ("\n"); 2197 i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 2198 } 2199 p ("\n" 2200 "-- Record dump end --\n\n"); 2201} 2202 2203static bool 2204loongarch_reloc_is_fatal (struct bfd_link_info *info, 2205 bfd *input_bfd, 2206 asection *input_section, 2207 Elf_Internal_Rela *rel, 2208 reloc_howto_type *howto, 2209 bfd_reloc_status_type rtype, 2210 bool is_undefweak, 2211 const char *name, 2212 const char *msg) 2213{ 2214 bool fatal = true; 2215 switch (rtype) 2216 { 2217 /* 'dangerous' means we do it but can't promise it's ok 2218 'unsupport' means out of ability of relocation type 2219 'undefined' means we can't deal with the undefined symbol. */ 2220 case bfd_reloc_undefined: 2221 info->callbacks->undefined_symbol (info, name, input_bfd, input_section, 2222 rel->r_offset, true); 2223 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n", 2224 input_bfd, input_section, rel->r_offset, 2225 howto->name, 2226 is_undefweak ? "[undefweak] " : "", name, msg); 2227 break; 2228 case bfd_reloc_dangerous: 2229 info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n", 2230 input_bfd, input_section, rel->r_offset, 2231 howto->name, 2232 is_undefweak ? "[undefweak] " : "", name, msg); 2233 fatal = false; 2234 break; 2235 case bfd_reloc_notsupported: 2236 info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n", 2237 input_bfd, input_section, rel->r_offset, 2238 howto->name, 2239 is_undefweak ? "[undefweak] " : "", name, msg); 2240 break; 2241 default: 2242 break; 2243 } 2244 return fatal; 2245} 2246 2247#define RELOCATE_CALC_PC32_HI20(relocation, pc) \ 2248 ({ \ 2249 bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \ 2250 pc = pc & (~(bfd_vma)0xfff); \ 2251 if (lo > 0x7ff) \ 2252 { \ 2253 relocation += 0x1000; \ 2254 } \ 2255 relocation &= ~(bfd_vma)0xfff; \ 2256 relocation -= pc; \ 2257 }) 2258 2259#define RELOCATE_CALC_PC64_HI32(relocation, pc) \ 2260 ({ \ 2261 bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \ 2262 if (lo > 0x7ff) \ 2263 { \ 2264 relocation -= 0x100000000; \ 2265 } \ 2266 relocation -= (pc & ~(bfd_vma)0xffffffff); \ 2267 }) 2268 2269static int 2270loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 2271 bfd *input_bfd, asection *input_section, 2272 bfd_byte *contents, Elf_Internal_Rela *relocs, 2273 Elf_Internal_Sym *local_syms, 2274 asection **local_sections) 2275{ 2276 Elf_Internal_Rela *rel; 2277 Elf_Internal_Rela *relend; 2278 bool fatal = false; 2279 asection *sreloc = elf_section_data (input_section)->sreloc; 2280 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 2281 Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd); 2282 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); 2283 bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd); 2284 bool is_pic = bfd_link_pic (info); 2285 bool is_dyn = elf_hash_table (info)->dynamic_sections_created; 2286 asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 2287 asection *got = htab->elf.sgot; 2288 2289 relend = relocs + input_section->reloc_count; 2290 for (rel = relocs; rel < relend; rel++) 2291 { 2292 int r_type = ELFNN_R_TYPE (rel->r_info); 2293 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); 2294 bfd_vma pc = sec_addr (input_section) + rel->r_offset; 2295 reloc_howto_type *howto = NULL; 2296 asection *sec = NULL; 2297 Elf_Internal_Sym *sym = NULL; 2298 struct elf_link_hash_entry *h = NULL; 2299 const char *name; 2300 bfd_reloc_status_type r = bfd_reloc_ok; 2301 bool is_ie, is_undefweak, unresolved_reloc, defined_local; 2302 bool resolved_local, resolved_dynly, resolved_to_const; 2303 char tls_type; 2304 bfd_vma relocation, off, ie_off; 2305 int i, j; 2306 2307 howto = loongarch_elf_rtype_to_howto (input_bfd, r_type); 2308 if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT 2309 || r_type == R_LARCH_GNU_VTENTRY) 2310 continue; 2311 2312 /* This is a final link. */ 2313 if (r_symndx < symtab_hdr->sh_info) 2314 { 2315 is_undefweak = false; 2316 unresolved_reloc = false; 2317 sym = local_syms + r_symndx; 2318 sec = local_sections[r_symndx]; 2319 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 2320 2321 /* Relocate against local STT_GNU_IFUNC symbol. */ 2322 if (!bfd_link_relocatable (info) 2323 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) 2324 { 2325 h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel, 2326 false); 2327 if (h == NULL) 2328 abort (); 2329 2330 /* Set STT_GNU_IFUNC symbol value. */ 2331 h->root.u.def.value = sym->st_value; 2332 h->root.u.def.section = sec; 2333 } 2334 defined_local = true; 2335 resolved_local = true; 2336 resolved_dynly = false; 2337 resolved_to_const = false; 2338 2339 /* Calc in funtion elf_link_input_bfd, 2340 * if #define elf_backend_rela_normal to 1. */ 2341 if (bfd_link_relocatable (info) 2342 && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 2343 continue; 2344 } 2345 else 2346 { 2347 bool warned, ignored; 2348 2349 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 2350 r_symndx, symtab_hdr, sym_hashes, 2351 h, sec, relocation, 2352 unresolved_reloc, warned, ignored); 2353 /* Here means symbol isn't local symbol only and 'h != NULL'. */ 2354 2355 /* The 'unresolved_syms_in_objects' specify how to deal with undefined 2356 symbol. And 'dynamic_undefined_weak' specify what to do when 2357 meeting undefweak. */ 2358 2359 if ((is_undefweak = h->root.type == bfd_link_hash_undefweak)) 2360 { 2361 defined_local = false; 2362 resolved_local = false; 2363 resolved_to_const = (!is_dyn || h->dynindx == -1 2364 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); 2365 resolved_dynly = !resolved_local && !resolved_to_const; 2366 } 2367 else if (warned) 2368 { 2369 /* Symbol undefined offen means failed already. I don't know why 2370 'warned' here but I guess it want to continue relocating as if 2371 no error occures to find other errors as more as possible. */ 2372 2373 /* To avoid generating warning messages about truncated 2374 relocations, set the relocation's address to be the same as 2375 the start of this section. */ 2376 relocation = (input_section->output_section 2377 ? input_section->output_section->vma 2378 : 0); 2379 2380 defined_local = relocation != 0; 2381 resolved_local = defined_local; 2382 resolved_to_const = !resolved_local; 2383 resolved_dynly = false; 2384 } 2385 else 2386 { 2387 defined_local = !unresolved_reloc && !ignored; 2388 resolved_local = 2389 defined_local && SYMBOL_REFERENCES_LOCAL (info, h); 2390 resolved_dynly = !resolved_local; 2391 resolved_to_const = !resolved_local && !resolved_dynly; 2392 } 2393 } 2394 2395 name = loongarch_sym_name (input_bfd, h, sym); 2396 2397 if (sec != NULL && discarded_section (sec)) 2398 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, 2399 1, relend, howto, 0, contents); 2400 2401 if (bfd_link_relocatable (info)) 2402 continue; 2403 2404 /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols 2405 from removed linkonce sections, or sections discarded by a linker 2406 script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */ 2407 if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec)) 2408 { 2409 defined_local = false; 2410 resolved_local = false; 2411 resolved_dynly = false; 2412 resolved_to_const = true; 2413 } 2414 2415 /* The ifunc reference generate plt. */ 2416 if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE) 2417 { 2418 defined_local = true; 2419 resolved_local = true; 2420 resolved_dynly = false; 2421 resolved_to_const = false; 2422 relocation = sec_addr (plt) + h->plt.offset; 2423 } 2424 2425 unresolved_reloc = resolved_dynly; 2426 2427 BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1); 2428 2429 /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */ 2430 2431 BFD_ASSERT (!resolved_local || defined_local); 2432 2433 is_ie = false; 2434 switch (r_type) 2435 { 2436 case R_LARCH_MARK_PCREL: 2437 case R_LARCH_MARK_LA: 2438 case R_LARCH_NONE: 2439 r = bfd_reloc_continue; 2440 unresolved_reloc = false; 2441 break; 2442 2443 case R_LARCH_32: 2444 case R_LARCH_64: 2445 if (resolved_dynly || (is_pic && resolved_local)) 2446 { 2447 Elf_Internal_Rela outrel; 2448 2449 /* When generating a shared object, these relocations are copied 2450 into the output file to be resolved at run time. */ 2451 2452 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, 2453 input_section, 2454 rel->r_offset); 2455 2456 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset) 2457 && (input_section->flags & SEC_ALLOC)); 2458 2459 outrel.r_offset += sec_addr (input_section); 2460 2461 /* A pointer point to a ifunc symbol. */ 2462 if (h && h->type == STT_GNU_IFUNC) 2463 { 2464 if (h->dynindx == -1) 2465 { 2466 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 2467 outrel.r_addend = (h->root.u.def.value 2468 + h->root.u.def.section->output_section->vma 2469 + h->root.u.def.section->output_offset); 2470 } 2471 else 2472 { 2473 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 2474 outrel.r_addend = 0; 2475 } 2476 2477 if (SYMBOL_REFERENCES_LOCAL (info, h)) 2478 { 2479 2480 if (htab->elf.splt != NULL) 2481 sreloc = htab->elf.srelgot; 2482 else 2483 sreloc = htab->elf.irelplt; 2484 } 2485 else 2486 { 2487 2488 if (bfd_link_pic (info)) 2489 sreloc = htab->elf.irelifunc; 2490 else if (htab->elf.splt != NULL) 2491 sreloc = htab->elf.srelgot; 2492 else 2493 sreloc = htab->elf.irelplt; 2494 } 2495 } 2496 else if (resolved_dynly) 2497 { 2498 if (h->dynindx == -1) 2499 { 2500 if (h->root.type == bfd_link_hash_undefined) 2501 (*info->callbacks->undefined_symbol) 2502 (info, name, input_bfd, input_section, 2503 rel->r_offset, true); 2504 2505 outrel.r_info = ELFNN_R_INFO (0, r_type); 2506 } 2507 else 2508 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); 2509 2510 outrel.r_addend = rel->r_addend; 2511 } 2512 else 2513 { 2514 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 2515 outrel.r_addend = relocation + rel->r_addend; 2516 } 2517 2518 /* No alloc space of func allocate_dynrelocs. */ 2519 if (unresolved_reloc 2520 && !(h && (h->is_weakalias || !h->dyn_relocs))) 2521 loongarch_elf_append_rela (output_bfd, sreloc, &outrel); 2522 } 2523 2524 relocation += rel->r_addend; 2525 break; 2526 2527 case R_LARCH_ADD8: 2528 case R_LARCH_ADD16: 2529 case R_LARCH_ADD24: 2530 case R_LARCH_ADD32: 2531 case R_LARCH_ADD64: 2532 case R_LARCH_SUB8: 2533 case R_LARCH_SUB16: 2534 case R_LARCH_SUB24: 2535 case R_LARCH_SUB32: 2536 case R_LARCH_SUB64: 2537 if (resolved_dynly) 2538 fatal = (loongarch_reloc_is_fatal 2539 (info, input_bfd, input_section, rel, howto, 2540 bfd_reloc_undefined, is_undefweak, name, 2541 "Can't be resolved dynamically. " 2542 "If this procedure is hand-written assembly,\n" 2543 "there must be something like '.dword sym1 - sym2' " 2544 "to generate these relocs\n" 2545 "and we can't get known link-time address of " 2546 "these symbols.")); 2547 else 2548 relocation += rel->r_addend; 2549 break; 2550 2551 case R_LARCH_TLS_DTPREL32: 2552 case R_LARCH_TLS_DTPREL64: 2553 if (resolved_dynly) 2554 { 2555 Elf_Internal_Rela outrel; 2556 2557 outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, 2558 input_section, 2559 rel->r_offset); 2560 unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset) 2561 && (input_section->flags & SEC_ALLOC)); 2562 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); 2563 outrel.r_offset += sec_addr (input_section); 2564 outrel.r_addend = rel->r_addend; 2565 if (unresolved_reloc) 2566 loongarch_elf_append_rela (output_bfd, sreloc, &outrel); 2567 break; 2568 } 2569 2570 if (resolved_to_const) 2571 fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section, 2572 rel, howto, 2573 bfd_reloc_notsupported, 2574 is_undefweak, name, 2575 "Internal:"); 2576 if (resolved_local) 2577 { 2578 if (!elf_hash_table (info)->tls_sec) 2579 { 2580 fatal = loongarch_reloc_is_fatal (info, input_bfd, 2581 input_section, rel, howto, bfd_reloc_notsupported, 2582 is_undefweak, name, "TLS section not be created"); 2583 } 2584 else 2585 relocation -= elf_hash_table (info)->tls_sec->vma; 2586 } 2587 else 2588 { 2589 fatal = loongarch_reloc_is_fatal (info, input_bfd, 2590 input_section, rel, howto, bfd_reloc_undefined, 2591 is_undefweak, name, 2592 "TLS LE just can be resolved local only."); 2593 } 2594 2595 break; 2596 2597 case R_LARCH_SOP_PUSH_TLS_TPREL: 2598 if (resolved_local) 2599 { 2600 if (!elf_hash_table (info)->tls_sec) 2601 fatal = (loongarch_reloc_is_fatal 2602 (info, input_bfd, input_section, rel, howto, 2603 bfd_reloc_notsupported, is_undefweak, name, 2604 "TLS section not be created")); 2605 else 2606 relocation -= elf_hash_table (info)->tls_sec->vma; 2607 } 2608 else 2609 fatal = (loongarch_reloc_is_fatal 2610 (info, input_bfd, input_section, rel, howto, 2611 bfd_reloc_undefined, is_undefweak, name, 2612 "TLS LE just can be resolved local only.")); 2613 break; 2614 2615 case R_LARCH_SOP_PUSH_ABSOLUTE: 2616 if (is_undefweak) 2617 { 2618 if (resolved_dynly) 2619 fatal = (loongarch_reloc_is_fatal 2620 (info, input_bfd, input_section, rel, howto, 2621 bfd_reloc_dangerous, is_undefweak, name, 2622 "Someone require us to resolve undefweak " 2623 "symbol dynamically. \n" 2624 "But this reloc can't be done. " 2625 "I think I can't throw error " 2626 "for this\n" 2627 "so I resolved it to 0. " 2628 "I suggest to re-compile with '-fpic'.")); 2629 2630 relocation = 0; 2631 unresolved_reloc = false; 2632 break; 2633 } 2634 2635 if (resolved_to_const) 2636 { 2637 relocation += rel->r_addend; 2638 break; 2639 } 2640 2641 if (is_pic) 2642 { 2643 fatal = (loongarch_reloc_is_fatal 2644 (info, input_bfd, input_section, rel, howto, 2645 bfd_reloc_notsupported, is_undefweak, name, 2646 "Under PIC we don't know load address. Re-compile " 2647 "with '-fpic'?")); 2648 break; 2649 } 2650 2651 if (resolved_dynly) 2652 { 2653 if (!(plt && h && h->plt.offset != MINUS_ONE)) 2654 { 2655 fatal = (loongarch_reloc_is_fatal 2656 (info, input_bfd, input_section, rel, howto, 2657 bfd_reloc_undefined, is_undefweak, name, 2658 "Can't be resolved dynamically. Try to re-compile " 2659 "with '-fpic'?")); 2660 break; 2661 } 2662 2663 if (rel->r_addend != 0) 2664 { 2665 fatal = (loongarch_reloc_is_fatal 2666 (info, input_bfd, input_section, rel, howto, 2667 bfd_reloc_notsupported, is_undefweak, name, 2668 "Shouldn't be with r_addend.")); 2669 break; 2670 } 2671 2672 relocation = sec_addr (plt) + h->plt.offset; 2673 unresolved_reloc = false; 2674 break; 2675 } 2676 2677 if (resolved_local) 2678 { 2679 relocation += rel->r_addend; 2680 break; 2681 } 2682 2683 break; 2684 2685 case R_LARCH_SOP_PUSH_PCREL: 2686 case R_LARCH_SOP_PUSH_PLT_PCREL: 2687 unresolved_reloc = false; 2688 2689 if (is_undefweak) 2690 { 2691 i = 0, j = 0; 2692 relocation = 0; 2693 if (resolved_dynly) 2694 { 2695 if (h && h->plt.offset != MINUS_ONE) 2696 i = 1, j = 2; 2697 else 2698 fatal = (loongarch_reloc_is_fatal 2699 (info, input_bfd, input_section, rel, howto, 2700 bfd_reloc_dangerous, is_undefweak, name, 2701 "Undefweak need to be resolved dynamically, " 2702 "but PLT stub doesn't represent.")); 2703 } 2704 } 2705 else 2706 { 2707 if (!(defined_local || (h && h->plt.offset != MINUS_ONE))) 2708 { 2709 fatal = (loongarch_reloc_is_fatal 2710 (info, input_bfd, input_section, rel, howto, 2711 bfd_reloc_undefined, is_undefweak, name, 2712 "PLT stub does not represent and " 2713 "symbol not defined.")); 2714 break; 2715 } 2716 2717 if (resolved_local) 2718 i = 0, j = 2; 2719 else /* if (resolved_dynly) */ 2720 { 2721 if (!(h && h->plt.offset != MINUS_ONE)) 2722 fatal = (loongarch_reloc_is_fatal 2723 (info, input_bfd, input_section, rel, howto, 2724 bfd_reloc_dangerous, is_undefweak, name, 2725 "Internal: PLT stub doesn't represent. " 2726 "Resolve it with pcrel")); 2727 i = 1, j = 3; 2728 } 2729 } 2730 2731 for (; i < j; i++) 2732 { 2733 if ((i & 1) == 0 && defined_local) 2734 { 2735 relocation -= pc; 2736 relocation += rel->r_addend; 2737 break; 2738 } 2739 2740 if ((i & 1) && h && h->plt.offset != MINUS_ONE) 2741 { 2742 if (rel->r_addend != 0) 2743 { 2744 fatal = (loongarch_reloc_is_fatal 2745 (info, input_bfd, input_section, rel, howto, 2746 bfd_reloc_notsupported, is_undefweak, name, 2747 "PLT shouldn't be with r_addend.")); 2748 break; 2749 } 2750 relocation = sec_addr (plt) + h->plt.offset - pc; 2751 break; 2752 } 2753 } 2754 break; 2755 2756 case R_LARCH_SOP_PUSH_GPREL: 2757 unresolved_reloc = false; 2758 2759 if (rel->r_addend != 0) 2760 { 2761 fatal = (loongarch_reloc_is_fatal 2762 (info, input_bfd, input_section, rel, howto, 2763 bfd_reloc_notsupported, is_undefweak, name, 2764 "Shouldn't be with r_addend.")); 2765 break; 2766 } 2767 2768 if (h != NULL) 2769 { 2770 off = h->got.offset & (~1); 2771 2772 if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC) 2773 { 2774 fatal = (loongarch_reloc_is_fatal 2775 (info, input_bfd, input_section, rel, howto, 2776 bfd_reloc_notsupported, is_undefweak, name, 2777 "Internal: GOT entry doesn't represent.")); 2778 break; 2779 } 2780 2781 /* Hidden symbol not has .got entry, only .got.plt entry 2782 so gprel is (plt - got). */ 2783 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 2784 { 2785 if (h->plt.offset == (bfd_vma) -1) 2786 { 2787 abort(); 2788 } 2789 2790 bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE; 2791 off = plt_index * GOT_ENTRY_SIZE; 2792 2793 if (htab->elf.splt != NULL) 2794 { 2795 /* Section .plt header is 2 times of plt entry. */ 2796 off = sec_addr (htab->elf.sgotplt) + off 2797 - sec_addr (htab->elf.sgot); 2798 } 2799 else 2800 { 2801 /* Section iplt not has plt header. */ 2802 off = sec_addr (htab->elf.igotplt) + off 2803 - sec_addr (htab->elf.sgot); 2804 } 2805 } 2806 2807 if ((h->got.offset & 1) == 0) 2808 { 2809 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, 2810 bfd_link_pic (info), h) 2811 && ((bfd_link_pic (info) 2812 && SYMBOL_REFERENCES_LOCAL (info, h)))) 2813 { 2814 /* This is actually a static link, or it is a 2815 -Bsymbolic link and the symbol is defined 2816 locally, or the symbol was forced to be local 2817 because of a version file. We must initialize 2818 this entry in the global offset table. Since the 2819 offset must always be a multiple of the word size, 2820 we use the least significant bit to record whether 2821 we have initialized it already. 2822 2823 When doing a dynamic link, we create a rela.got 2824 relocation entry to initialize the value. This 2825 is done in the finish_dynamic_symbol routine. */ 2826 2827 if (resolved_dynly) 2828 { 2829 fatal = (loongarch_reloc_is_fatal 2830 (info, input_bfd, input_section, rel, howto, 2831 bfd_reloc_dangerous, is_undefweak, name, 2832 "Internal: here shouldn't dynamic.")); 2833 } 2834 2835 if (!(defined_local || resolved_to_const)) 2836 { 2837 fatal = (loongarch_reloc_is_fatal 2838 (info, input_bfd, input_section, rel, howto, 2839 bfd_reloc_undefined, is_undefweak, name, 2840 "Internal: ")); 2841 break; 2842 } 2843 2844 asection *s; 2845 Elf_Internal_Rela outrel; 2846 /* We need to generate a R_LARCH_RELATIVE reloc 2847 for the dynamic linker. */ 2848 s = htab->elf.srelgot; 2849 if (!s) 2850 { 2851 fatal = loongarch_reloc_is_fatal 2852 (info, input_bfd, 2853 input_section, rel, howto, 2854 bfd_reloc_notsupported, is_undefweak, name, 2855 "Internal: '.rel.got' not represent"); 2856 break; 2857 } 2858 2859 outrel.r_offset = sec_addr (got) + off; 2860 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 2861 outrel.r_addend = relocation; /* Link-time addr. */ 2862 loongarch_elf_append_rela (output_bfd, s, &outrel); 2863 } 2864 bfd_put_NN (output_bfd, relocation, got->contents + off); 2865 h->got.offset |= 1; 2866 } 2867 } 2868 else 2869 { 2870 if (!local_got_offsets) 2871 { 2872 fatal = (loongarch_reloc_is_fatal 2873 (info, input_bfd, input_section, rel, howto, 2874 bfd_reloc_notsupported, is_undefweak, name, 2875 "Internal: local got offsets not reporesent.")); 2876 break; 2877 } 2878 2879 off = local_got_offsets[r_symndx] & (~1); 2880 2881 if (local_got_offsets[r_symndx] == MINUS_ONE) 2882 { 2883 fatal = (loongarch_reloc_is_fatal 2884 (info, input_bfd, input_section, rel, howto, 2885 bfd_reloc_notsupported, is_undefweak, name, 2886 "Internal: GOT entry doesn't represent.")); 2887 break; 2888 } 2889 2890 /* The offset must always be a multiple of the word size. 2891 So, we can use the least significant bit to record 2892 whether we have already processed this entry. */ 2893 if ((local_got_offsets[r_symndx] & 1) == 0) 2894 { 2895 if (is_pic) 2896 { 2897 asection *s; 2898 Elf_Internal_Rela outrel; 2899 /* We need to generate a R_LARCH_RELATIVE reloc 2900 for the dynamic linker. */ 2901 s = htab->elf.srelgot; 2902 if (!s) 2903 { 2904 fatal = (loongarch_reloc_is_fatal 2905 (info, input_bfd, input_section, rel, howto, 2906 bfd_reloc_notsupported, is_undefweak, name, 2907 "Internal: '.rel.got' not represent")); 2908 break; 2909 } 2910 2911 outrel.r_offset = sec_addr (got) + off; 2912 outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 2913 outrel.r_addend = relocation; /* Link-time addr. */ 2914 loongarch_elf_append_rela (output_bfd, s, &outrel); 2915 } 2916 2917 bfd_put_NN (output_bfd, relocation, got->contents + off); 2918 local_got_offsets[r_symndx] |= 1; 2919 } 2920 } 2921 relocation = off; 2922 2923 break; 2924 2925 case R_LARCH_SOP_PUSH_TLS_GOT: 2926 case R_LARCH_SOP_PUSH_TLS_GD: 2927 { 2928 unresolved_reloc = false; 2929 if (r_type == R_LARCH_SOP_PUSH_TLS_GOT) 2930 is_ie = true; 2931 2932 bfd_vma got_off = 0; 2933 if (h != NULL) 2934 { 2935 got_off = h->got.offset; 2936 h->got.offset |= 1; 2937 } 2938 else 2939 { 2940 got_off = local_got_offsets[r_symndx]; 2941 local_got_offsets[r_symndx] |= 1; 2942 } 2943 2944 BFD_ASSERT (got_off != MINUS_ONE); 2945 2946 ie_off = 0; 2947 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 2948 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) 2949 ie_off = 2 * GOT_ENTRY_SIZE; 2950 2951 if ((got_off & 1) == 0) 2952 { 2953 Elf_Internal_Rela rela; 2954 asection *srel = htab->elf.srelgot; 2955 bfd_vma tls_block_off = 0; 2956 2957 if (SYMBOL_REFERENCES_LOCAL (info, h)) 2958 { 2959 BFD_ASSERT (elf_hash_table (info)->tls_sec); 2960 tls_block_off = relocation 2961 - elf_hash_table (info)->tls_sec->vma; 2962 } 2963 2964 if (tls_type & GOT_TLS_GD) 2965 { 2966 rela.r_offset = sec_addr (got) + got_off; 2967 rela.r_addend = 0; 2968 if (SYMBOL_REFERENCES_LOCAL (info, h)) 2969 { 2970 /* Local sym, used in exec, set module id 1. */ 2971 if (bfd_link_executable (info)) 2972 bfd_put_NN (output_bfd, 1, got->contents + got_off); 2973 else 2974 { 2975 rela.r_info = ELFNN_R_INFO (0, 2976 R_LARCH_TLS_DTPMODNN); 2977 loongarch_elf_append_rela (output_bfd, srel, &rela); 2978 } 2979 2980 bfd_put_NN (output_bfd, tls_block_off, 2981 got->contents + got_off + GOT_ENTRY_SIZE); 2982 } 2983 /* Dynamic resolved. */ 2984 else 2985 { 2986 /* Dynamic relocate module id. */ 2987 rela.r_info = ELFNN_R_INFO (h->dynindx, 2988 R_LARCH_TLS_DTPMODNN); 2989 loongarch_elf_append_rela (output_bfd, srel, &rela); 2990 2991 /* Dynamic relocate offset of block. */ 2992 rela.r_offset += GOT_ENTRY_SIZE; 2993 rela.r_info = ELFNN_R_INFO (h->dynindx, 2994 R_LARCH_TLS_DTPRELNN); 2995 loongarch_elf_append_rela (output_bfd, srel, &rela); 2996 } 2997 } 2998 if (tls_type & GOT_TLS_IE) 2999 { 3000 rela.r_offset = sec_addr (got) + got_off + ie_off; 3001 if (SYMBOL_REFERENCES_LOCAL (info, h)) 3002 { 3003 /* Local sym, used in exec, set module id 1. */ 3004 if (!bfd_link_executable (info)) 3005 { 3006 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN); 3007 rela.r_addend = tls_block_off; 3008 loongarch_elf_append_rela (output_bfd, srel, &rela); 3009 } 3010 3011 bfd_put_NN (output_bfd, tls_block_off, 3012 got->contents + got_off + ie_off); 3013 } 3014 /* Dynamic resolved. */ 3015 else 3016 { 3017 /* Dynamic relocate offset of block. */ 3018 rela.r_info = ELFNN_R_INFO (h->dynindx, 3019 R_LARCH_TLS_TPRELNN); 3020 rela.r_addend = 0; 3021 loongarch_elf_append_rela (output_bfd, srel, &rela); 3022 } 3023 } 3024 } 3025 3026 relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0); 3027 } 3028 break; 3029 3030 /* New reloc types. */ 3031 case R_LARCH_B21: 3032 case R_LARCH_B26: 3033 case R_LARCH_B16: 3034 unresolved_reloc = false; 3035 if (is_undefweak) 3036 { 3037 relocation = 0; 3038 } 3039 3040 if (resolved_local) 3041 { 3042 relocation -= pc; 3043 relocation += rel->r_addend; 3044 } 3045 else if (resolved_dynly) 3046 { 3047 BFD_ASSERT (h 3048 && (h->plt.offset != MINUS_ONE 3049 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) 3050 && rel->r_addend == 0); 3051 if (h && h->plt.offset == MINUS_ONE 3052 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) 3053 { 3054 relocation -= pc; 3055 relocation += rel->r_addend; 3056 } 3057 else 3058 relocation = sec_addr (plt) + h->plt.offset - pc; 3059 } 3060 3061 break; 3062 3063 case R_LARCH_ABS_HI20: 3064 case R_LARCH_ABS_LO12: 3065 case R_LARCH_ABS64_LO20: 3066 case R_LARCH_ABS64_HI12: 3067 BFD_ASSERT (!is_pic); 3068 3069 if (is_undefweak) 3070 { 3071 BFD_ASSERT (resolved_dynly); 3072 relocation = 0; 3073 break; 3074 } 3075 else if (resolved_to_const || resolved_local) 3076 { 3077 relocation += rel->r_addend; 3078 } 3079 else if (resolved_dynly) 3080 { 3081 unresolved_reloc = false; 3082 BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE) 3083 && rel->r_addend == 0); 3084 relocation = sec_addr (plt) + h->plt.offset; 3085 } 3086 3087 break; 3088 3089 case R_LARCH_PCALA_HI20: 3090 unresolved_reloc = false; 3091 if (h && h->plt.offset != MINUS_ONE) 3092 relocation = sec_addr (plt) + h->plt.offset; 3093 else 3094 relocation += rel->r_addend; 3095 3096 RELOCATE_CALC_PC32_HI20 (relocation, pc); 3097 3098 break; 3099 3100 case R_LARCH_PCALA_LO12: 3101 /* Not support if sym_addr in 2k page edge. 3102 pcalau12i pc_hi20 (sym_addr) 3103 ld.w/d pc_lo12 (sym_addr) 3104 ld.w/d pc_lo12 (sym_addr + x) 3105 ... 3106 can not calc correct address 3107 if sym_addr < 0x800 && sym_addr + x >= 0x800. */ 3108 3109 if (h && h->plt.offset != MINUS_ONE) 3110 relocation = sec_addr (plt) + h->plt.offset; 3111 else 3112 relocation += rel->r_addend; 3113 3114 relocation &= 0xfff; 3115 /* Signed extend. */ 3116 relocation = (relocation ^ 0x800) - 0x800; 3117 3118 /* For 2G jump, generate pcalau12i, jirl. */ 3119 /* If use jirl, turns to R_LARCH_B16. */ 3120 uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset); 3121 if ((insn & 0x4c000000) == 0x4c000000) 3122 { 3123 rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16); 3124 howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16); 3125 } 3126 break; 3127 3128 case R_LARCH_PCALA64_LO20: 3129 case R_LARCH_PCALA64_HI12: 3130 if (h && h->plt.offset != MINUS_ONE) 3131 relocation = sec_addr (plt) + h->plt.offset; 3132 else 3133 relocation += rel->r_addend; 3134 3135 RELOCATE_CALC_PC64_HI32 (relocation, pc); 3136 3137 break; 3138 3139 case R_LARCH_GOT_PC_HI20: 3140 case R_LARCH_GOT_HI20: 3141 /* Calc got offset. */ 3142 { 3143 unresolved_reloc = false; 3144 BFD_ASSERT (rel->r_addend == 0); 3145 3146 bfd_vma got_off = 0; 3147 if (h != NULL) 3148 { 3149 /* GOT ref or ifunc. */ 3150 BFD_ASSERT (h->got.offset != MINUS_ONE 3151 || h->type == STT_GNU_IFUNC); 3152 3153 got_off = h->got.offset & (~(bfd_vma)1); 3154 /* Hidden symbol not has got entry, 3155 * only got.plt entry so it is (plt - got). */ 3156 if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 3157 { 3158 bfd_vma idx; 3159 if (htab->elf.splt != NULL) 3160 { 3161 idx = (h->plt.offset - PLT_HEADER_SIZE) 3162 / PLT_ENTRY_SIZE; 3163 got_off = sec_addr (htab->elf.sgotplt) 3164 + GOTPLT_HEADER_SIZE 3165 + (idx * GOT_ENTRY_SIZE) 3166 - sec_addr (htab->elf.sgot); 3167 } 3168 else 3169 { 3170 idx = h->plt.offset / PLT_ENTRY_SIZE; 3171 got_off = sec_addr (htab->elf.sgotplt) 3172 + (idx * GOT_ENTRY_SIZE) 3173 - sec_addr (htab->elf.sgot); 3174 } 3175 } 3176 3177 if ((h->got.offset & 1) == 0) 3178 { 3179 /* We need to generate a R_LARCH_RELATIVE reloc once 3180 * in loongarch_elf_finish_dynamic_symbol or now, 3181 * call finish_dyn && nopic 3182 * or !call finish_dyn && pic. */ 3183 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, 3184 bfd_link_pic (info), 3185 h) 3186 && bfd_link_pic (info) 3187 && SYMBOL_REFERENCES_LOCAL (info, h)) 3188 { 3189 Elf_Internal_Rela rela; 3190 rela.r_offset = sec_addr (got) + got_off; 3191 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3192 rela.r_addend = relocation; 3193 loongarch_elf_append_rela (output_bfd, 3194 htab->elf.srelgot, &rela); 3195 } 3196 h->got.offset |= 1; 3197 bfd_put_NN (output_bfd, relocation, 3198 got->contents + got_off); 3199 } 3200 } 3201 else 3202 { 3203 BFD_ASSERT (local_got_offsets 3204 && local_got_offsets[r_symndx] != MINUS_ONE); 3205 3206 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1); 3207 if ((local_got_offsets[r_symndx] & 1) == 0) 3208 { 3209 if (bfd_link_pic (info)) 3210 { 3211 Elf_Internal_Rela rela; 3212 rela.r_offset = sec_addr (got) + got_off; 3213 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3214 rela.r_addend = relocation; 3215 loongarch_elf_append_rela (output_bfd, 3216 htab->elf.srelgot, &rela); 3217 } 3218 local_got_offsets[r_symndx] |= 1; 3219 } 3220 bfd_put_NN (output_bfd, relocation, got->contents + got_off); 3221 } 3222 3223 relocation = got_off + sec_addr (got); 3224 } 3225 3226 if (r_type == R_LARCH_GOT_PC_HI20) 3227 RELOCATE_CALC_PC32_HI20 (relocation, pc); 3228 3229 break; 3230 3231 case R_LARCH_GOT_PC_LO12: 3232 case R_LARCH_GOT64_PC_LO20: 3233 case R_LARCH_GOT64_PC_HI12: 3234 case R_LARCH_GOT_LO12: 3235 case R_LARCH_GOT64_LO20: 3236 case R_LARCH_GOT64_HI12: 3237 { 3238 unresolved_reloc = false; 3239 bfd_vma got_off; 3240 if (h) 3241 got_off = h->got.offset & (~(bfd_vma)1); 3242 else 3243 got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1); 3244 3245 if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 3246 { 3247 bfd_vma idx; 3248 if (htab->elf.splt != NULL) 3249 idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; 3250 else 3251 idx = h->plt.offset / PLT_ENTRY_SIZE; 3252 3253 got_off = sec_addr (htab->elf.sgotplt) 3254 + GOTPLT_HEADER_SIZE 3255 + (idx * GOT_ENTRY_SIZE) 3256 - sec_addr (htab->elf.sgot); 3257 } 3258 relocation = got_off + sec_addr (got); 3259 } 3260 3261 if (r_type == R_LARCH_GOT_PC_LO12) 3262 relocation &= (bfd_vma)0xfff; 3263 else if (r_type == R_LARCH_GOT64_PC_LO20 3264 || r_type == R_LARCH_GOT64_PC_HI12) 3265 RELOCATE_CALC_PC64_HI32 (relocation, pc); 3266 3267 break; 3268 3269 case R_LARCH_TLS_LE_HI20: 3270 case R_LARCH_TLS_LE_LO12: 3271 case R_LARCH_TLS_LE64_LO20: 3272 case R_LARCH_TLS_LE64_HI12: 3273 BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec); 3274 3275 relocation -= elf_hash_table (info)->tls_sec->vma; 3276 break; 3277 3278 /* TLS IE LD/GD process separately is troublesome. 3279 When a symbol is both ie and LD/GD, h->got.off |= 1 3280 make only one type be relocated. We must use 3281 h->got.offset |= 1 and h->got.offset |= 2 3282 diff IE and LD/GD. And all (got_off & (~(bfd_vma)1)) 3283 (IE LD/GD and reusable GOT reloc) must change to 3284 (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits 3285 as a tag. 3286 Now, LD and GD is both GOT_TLS_GD type, LD seems to 3287 can be omitted. */ 3288 case R_LARCH_TLS_IE_PC_HI20: 3289 case R_LARCH_TLS_IE_HI20: 3290 case R_LARCH_TLS_LD_PC_HI20: 3291 case R_LARCH_TLS_LD_HI20: 3292 case R_LARCH_TLS_GD_PC_HI20: 3293 case R_LARCH_TLS_GD_HI20: 3294 BFD_ASSERT (rel->r_addend == 0); 3295 unresolved_reloc = false; 3296 3297 if (r_type == R_LARCH_TLS_IE_PC_HI20 3298 || r_type == R_LARCH_TLS_IE_HI20) 3299 is_ie = true; 3300 3301 bfd_vma got_off = 0; 3302 if (h != NULL) 3303 { 3304 got_off = h->got.offset; 3305 h->got.offset |= 1; 3306 } 3307 else 3308 { 3309 got_off = local_got_offsets[r_symndx]; 3310 local_got_offsets[r_symndx] |= 1; 3311 } 3312 3313 BFD_ASSERT (got_off != MINUS_ONE); 3314 3315 ie_off = 0; 3316 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 3317 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) 3318 ie_off = 2 * GOT_ENTRY_SIZE; 3319 3320 if ((got_off & 1) == 0) 3321 { 3322 Elf_Internal_Rela rela; 3323 asection *relgot = htab->elf.srelgot; 3324 bfd_vma tls_block_off = 0; 3325 3326 if (SYMBOL_REFERENCES_LOCAL (info, h)) 3327 { 3328 BFD_ASSERT (elf_hash_table (info)->tls_sec); 3329 tls_block_off = relocation 3330 - elf_hash_table (info)->tls_sec->vma; 3331 } 3332 3333 if (tls_type & GOT_TLS_GD) 3334 { 3335 rela.r_offset = sec_addr (got) + got_off; 3336 rela.r_addend = 0; 3337 if (SYMBOL_REFERENCES_LOCAL (info, h)) 3338 { 3339 /* Local sym, used in exec, set module id 1. */ 3340 if (bfd_link_executable (info)) 3341 bfd_put_NN (output_bfd, 1, got->contents + got_off); 3342 else 3343 { 3344 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN); 3345 loongarch_elf_append_rela (output_bfd, relgot, &rela); 3346 } 3347 3348 bfd_put_NN (output_bfd, tls_block_off, 3349 got->contents + got_off + GOT_ENTRY_SIZE); 3350 } 3351 /* Dynamic resolved. */ 3352 else 3353 { 3354 /* Dynamic relocate module id. */ 3355 rela.r_info = ELFNN_R_INFO (h->dynindx, 3356 R_LARCH_TLS_DTPMODNN); 3357 loongarch_elf_append_rela (output_bfd, relgot, &rela); 3358 3359 /* Dynamic relocate offset of block. */ 3360 rela.r_offset += GOT_ENTRY_SIZE; 3361 rela.r_info = ELFNN_R_INFO (h->dynindx, 3362 R_LARCH_TLS_DTPRELNN); 3363 loongarch_elf_append_rela (output_bfd, relgot, &rela); 3364 } 3365 } 3366 if (tls_type & GOT_TLS_IE) 3367 { 3368 rela.r_offset = sec_addr (got) + got_off + ie_off; 3369 if (SYMBOL_REFERENCES_LOCAL (info, h)) 3370 { 3371 /* Local sym, used in exec, set module id 1. */ 3372 if (!bfd_link_executable (info)) 3373 { 3374 rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN); 3375 rela.r_addend = tls_block_off; 3376 loongarch_elf_append_rela (output_bfd, relgot, &rela); 3377 } 3378 3379 bfd_put_NN (output_bfd, tls_block_off, 3380 got->contents + got_off + ie_off); 3381 } 3382 /* Dynamic resolved. */ 3383 else 3384 { 3385 /* Dynamic relocate offset of block. */ 3386 rela.r_info = ELFNN_R_INFO (h->dynindx, 3387 R_LARCH_TLS_TPRELNN); 3388 rela.r_addend = 0; 3389 loongarch_elf_append_rela (output_bfd, relgot, &rela); 3390 } 3391 } 3392 } 3393 relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got) 3394 + (is_ie ? ie_off : 0); 3395 3396 if (r_type == R_LARCH_TLS_LD_PC_HI20 3397 || r_type == R_LARCH_TLS_GD_PC_HI20 3398 || r_type == R_LARCH_TLS_IE_PC_HI20) 3399 RELOCATE_CALC_PC32_HI20 (relocation, pc); 3400 3401 break; 3402 3403 case R_LARCH_TLS_IE_PC_LO12: 3404 case R_LARCH_TLS_IE64_PC_LO20: 3405 case R_LARCH_TLS_IE64_PC_HI12: 3406 case R_LARCH_TLS_IE_LO12: 3407 case R_LARCH_TLS_IE64_LO20: 3408 case R_LARCH_TLS_IE64_HI12: 3409 unresolved_reloc = false; 3410 3411 if (h) 3412 relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3)); 3413 else 3414 relocation = sec_addr (got) 3415 + (local_got_offsets[r_symndx] & (~(bfd_vma)3)); 3416 3417 tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 3418 /* Use both TLS_GD and TLS_IE. */ 3419 if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) 3420 relocation += 2 * GOT_ENTRY_SIZE; 3421 3422 if (r_type == R_LARCH_TLS_IE_PC_LO12) 3423 relocation &= (bfd_vma)0xfff; 3424 else if (r_type == R_LARCH_TLS_IE64_PC_LO20 3425 || r_type == R_LARCH_TLS_IE64_PC_HI12) 3426 RELOCATE_CALC_PC64_HI32 (relocation, pc); 3427 3428 break; 3429 3430 case R_LARCH_RELAX: 3431 break; 3432 3433 default: 3434 break; 3435 } 3436 3437 if (fatal) 3438 break; 3439 3440 do 3441 { 3442 /* 'unresolved_reloc' means we haven't done it yet. 3443 We need help of dynamic linker to fix this memory location up. */ 3444 if (!unresolved_reloc) 3445 break; 3446 3447 if (_bfd_elf_section_offset (output_bfd, info, input_section, 3448 rel->r_offset) == MINUS_ONE) 3449 /* WHY? May because it's invalid so skip checking. 3450 But why dynamic reloc a invalid section? */ 3451 break; 3452 3453 if (input_section->output_section->flags & SEC_DEBUGGING) 3454 { 3455 fatal = (loongarch_reloc_is_fatal 3456 (info, input_bfd, input_section, rel, howto, 3457 bfd_reloc_dangerous, is_undefweak, name, 3458 "Seems dynamic linker not process " 3459 "sections 'SEC_DEBUGGING'.")); 3460 } 3461 if (!is_dyn) 3462 break; 3463 3464 if ((info->flags & DF_TEXTREL) == 0) 3465 if (input_section->output_section->flags & SEC_READONLY) 3466 info->flags |= DF_TEXTREL; 3467 } 3468 while (0); 3469 3470 if (fatal) 3471 break; 3472 3473 loongarch_record_one_reloc (input_bfd, input_section, r_type, 3474 rel->r_offset, sym, h, rel->r_addend); 3475 3476 if (r != bfd_reloc_continue) 3477 r = perform_relocation (rel, input_section, howto, relocation, 3478 input_bfd, contents); 3479 3480 switch (r) 3481 { 3482 case bfd_reloc_dangerous: 3483 case bfd_reloc_continue: 3484 case bfd_reloc_ok: 3485 continue; 3486 3487 case bfd_reloc_overflow: 3488 /* Overflow value can't be filled in. */ 3489 loongarch_dump_reloc_record (info->callbacks->info); 3490 info->callbacks->reloc_overflow 3491 (info, h ? &h->root : NULL, name, howto->name, rel->r_addend, 3492 input_bfd, input_section, rel->r_offset); 3493 break; 3494 3495 case bfd_reloc_outofrange: 3496 /* Stack state incorrect. */ 3497 loongarch_dump_reloc_record (info->callbacks->info); 3498 info->callbacks->info 3499 ("%X%H: Internal stack state is incorrect.\n" 3500 "Want to push to full stack or pop from empty stack?\n", 3501 input_bfd, input_section, rel->r_offset); 3502 break; 3503 3504 case bfd_reloc_notsupported: 3505 info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd, 3506 input_section, rel->r_offset); 3507 break; 3508 3509 default: 3510 info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd, 3511 input_section, rel->r_offset); 3512 break; 3513 } 3514 3515 fatal = true; 3516 } 3517 3518 return !fatal; 3519} 3520 3521/* Finish up dynamic symbol handling. We set the contents of various 3522 dynamic sections here. */ 3523 3524static bool 3525loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, 3526 struct bfd_link_info *info, 3527 struct elf_link_hash_entry *h, 3528 Elf_Internal_Sym *sym) 3529{ 3530 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 3531 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 3532 asection *rela_dyn = bfd_get_section_by_name (output_bfd, ".rela.dyn"); 3533 struct bfd_link_order *lo = NULL; 3534 Elf_Internal_Rela *slot = NULL, *last_slot = NULL; 3535 3536 if (rela_dyn) 3537 lo = rela_dyn->map_head.link_order; 3538 3539 if (h->plt.offset != MINUS_ONE) 3540 { 3541 size_t i, plt_idx; 3542 asection *plt, *gotplt, *relplt; 3543 bfd_vma got_address; 3544 uint32_t plt_entry[PLT_ENTRY_INSNS]; 3545 bfd_byte *loc; 3546 Elf_Internal_Rela rela; 3547 asection *rela_sec = NULL; 3548 3549 if (htab->elf.splt) 3550 { 3551 BFD_ASSERT ((h->type == STT_GNU_IFUNC 3552 && SYMBOL_REFERENCES_LOCAL (info, h)) 3553 || h->dynindx != -1); 3554 3555 plt = htab->elf.splt; 3556 gotplt = htab->elf.sgotplt; 3557 if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h)) 3558 relplt = htab->elf.srelgot; 3559 else 3560 relplt = htab->elf.srelplt; 3561 plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; 3562 got_address = 3563 sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE; 3564 } 3565 else /* if (htab->elf.iplt) */ 3566 { 3567 BFD_ASSERT (h->type == STT_GNU_IFUNC 3568 && SYMBOL_REFERENCES_LOCAL (info, h)); 3569 3570 plt = htab->elf.iplt; 3571 gotplt = htab->elf.igotplt; 3572 relplt = htab->elf.irelplt; 3573 plt_idx = h->plt.offset / PLT_ENTRY_SIZE; 3574 got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE; 3575 } 3576 3577 /* Find out where the .plt entry should go. */ 3578 loc = plt->contents + h->plt.offset; 3579 3580 /* Fill in the PLT entry itself. */ 3581 if (!loongarch_make_plt_entry (got_address, 3582 sec_addr (plt) + h->plt.offset, 3583 plt_entry)) 3584 return false; 3585 3586 for (i = 0; i < PLT_ENTRY_INSNS; i++) 3587 bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i); 3588 3589 /* Fill in the initial value of the got.plt entry. */ 3590 loc = gotplt->contents + (got_address - sec_addr (gotplt)); 3591 bfd_put_NN (output_bfd, sec_addr (plt), loc); 3592 3593 rela.r_offset = got_address; 3594 3595 /* TRUE if this is a PLT reference to a local IFUNC. */ 3596 if (PLT_LOCAL_IFUNC_P (info, h) 3597 && (relplt == htab->elf.srelgot 3598 || relplt == htab->elf.irelplt)) 3599 { 3600 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 3601 rela.r_addend = (h->root.u.def.value 3602 + h->root.u.def.section->output_section->vma 3603 + h->root.u.def.section->output_offset); 3604 3605 /* Find the space after dyn sort. */ 3606 while (slot == last_slot || slot->r_offset != 0) 3607 { 3608 if (slot != last_slot) 3609 { 3610 slot++; 3611 continue; 3612 } 3613 3614 BFD_ASSERT (lo != NULL); 3615 rela_sec = lo->u.indirect.section; 3616 lo = lo->next; 3617 3618 slot = (Elf_Internal_Rela *)rela_sec->contents; 3619 last_slot = (Elf_Internal_Rela *)(rela_sec->contents + 3620 rela_sec->size); 3621 } 3622 3623 bed->s->swap_reloca_out (output_bfd, &rela, (bfd_byte *)slot); 3624 rela_sec->reloc_count++; 3625 } 3626 else 3627 { 3628 /* Fill in the entry in the rela.plt section. */ 3629 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT); 3630 rela.r_addend = 0; 3631 loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela); 3632 bed->s->swap_reloca_out (output_bfd, &rela, loc); 3633 } 3634 3635 if (!h->def_regular) 3636 { 3637 /* Mark the symbol as undefined, rather than as defined in 3638 the .plt section. Leave the value alone. */ 3639 sym->st_shndx = SHN_UNDEF; 3640 /* If the symbol is weak, we do need to clear the value. 3641 Otherwise, the PLT entry would provide a definition for 3642 the symbol even if the symbol wasn't defined anywhere, 3643 and so the symbol would never be NULL. */ 3644 if (!h->ref_regular_nonweak) 3645 sym->st_value = 0; 3646 } 3647 } 3648 3649 if (h->got.offset != MINUS_ONE 3650 /* TLS got entry have been handled in elf_relocate_section. */ 3651 && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) 3652 /* Have allocated got entry but not allocated rela before. */ 3653 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) 3654 { 3655 asection *sgot, *srela; 3656 Elf_Internal_Rela rela; 3657 bfd_vma off = h->got.offset & ~(bfd_vma)1; 3658 3659 /* This symbol has an entry in the GOT. Set it up. */ 3660 sgot = htab->elf.sgot; 3661 srela = htab->elf.srelgot; 3662 BFD_ASSERT (sgot && srela); 3663 3664 rela.r_offset = sec_addr (sgot) + off; 3665 3666 if (h->def_regular 3667 && h->type == STT_GNU_IFUNC) 3668 { 3669 if(h->plt.offset == MINUS_ONE) 3670 { 3671 if (htab->elf.splt == NULL) 3672 srela = htab->elf.irelplt; 3673 3674 if (SYMBOL_REFERENCES_LOCAL (info, h)) 3675 { 3676 asection *sec = h->root.u.def.section; 3677 rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 3678 rela.r_addend = h->root.u.def.value + sec->output_section->vma 3679 + sec->output_offset; 3680 bfd_put_NN (output_bfd, 0, sgot->contents + off); 3681 } 3682 else 3683 { 3684 BFD_ASSERT (h->dynindx != -1); 3685 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 3686 rela.r_addend = 0; 3687 bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off); 3688 } 3689 } 3690 else if(bfd_link_pic (info)) 3691 { 3692 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 3693 rela.r_addend = 0; 3694 bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off); 3695 } 3696 else 3697 { 3698 asection *plt; 3699 /* For non-shared object, we can't use .got.plt, which 3700 contains the real function address if we need pointer 3701 equality. We load the GOT entry with the PLT entry. */ 3702 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 3703 bfd_put_NN (output_bfd, 3704 (plt->output_section->vma 3705 + plt->output_offset 3706 + h->plt.offset), 3707 sgot->contents + off); 3708 return true; 3709 } 3710 } 3711 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) 3712 { 3713 asection *sec = h->root.u.def.section; 3714 rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3715 rela.r_addend = (h->root.u.def.value + sec->output_section->vma 3716 + sec->output_offset); 3717 } 3718 else 3719 { 3720 BFD_ASSERT (h->dynindx != -1); 3721 rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 3722 rela.r_addend = 0; 3723 } 3724 3725 loongarch_elf_append_rela (output_bfd, srela, &rela); 3726 } 3727 3728 /* Mark some specially defined symbols as absolute. */ 3729 if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt) 3730 sym->st_shndx = SHN_ABS; 3731 3732 return true; 3733} 3734 3735/* Finish up the dynamic sections. */ 3736 3737static bool 3738loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj, 3739 asection *sdyn) 3740{ 3741 struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 3742 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 3743 size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0; 3744 bfd_byte *dyncon, *dynconend; 3745 3746 dynconend = sdyn->contents + sdyn->size; 3747 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize) 3748 { 3749 Elf_Internal_Dyn dyn; 3750 asection *s; 3751 int skipped = 0; 3752 3753 bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 3754 3755 switch (dyn.d_tag) 3756 { 3757 case DT_PLTGOT: 3758 s = htab->elf.sgotplt; 3759 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; 3760 break; 3761 case DT_JMPREL: 3762 s = htab->elf.srelplt; 3763 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; 3764 break; 3765 case DT_PLTRELSZ: 3766 s = htab->elf.srelplt; 3767 dyn.d_un.d_val = s->size; 3768 break; 3769 case DT_TEXTREL: 3770 if ((info->flags & DF_TEXTREL) == 0) 3771 skipped = 1; 3772 break; 3773 case DT_FLAGS: 3774 if ((info->flags & DF_TEXTREL) == 0) 3775 dyn.d_un.d_val &= ~DF_TEXTREL; 3776 break; 3777 } 3778 if (skipped) 3779 skipped_size += dynsize; 3780 else 3781 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size); 3782 } 3783 /* Wipe out any trailing entries if we shifted down a dynamic tag. */ 3784 memset (dyncon - skipped_size, 0, skipped_size); 3785 return true; 3786} 3787 3788/* Finish up local dynamic symbol handling. We set the contents of 3789 various dynamic sections here. */ 3790 3791static bool 3792elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf) 3793{ 3794 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; 3795 struct bfd_link_info *info = (struct bfd_link_info *) inf; 3796 3797 return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL); 3798} 3799 3800static bool 3801loongarch_elf_finish_dynamic_sections (bfd *output_bfd, 3802 struct bfd_link_info *info) 3803{ 3804 bfd *dynobj; 3805 asection *sdyn, *plt, *gotplt = NULL; 3806 struct loongarch_elf_link_hash_table *htab; 3807 3808 htab = loongarch_elf_hash_table (info); 3809 BFD_ASSERT (htab); 3810 dynobj = htab->elf.dynobj; 3811 sdyn = bfd_get_linker_section (dynobj, ".dynamic"); 3812 3813 if (elf_hash_table (info)->dynamic_sections_created) 3814 { 3815 BFD_ASSERT (htab->elf.splt && sdyn); 3816 3817 if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn)) 3818 return false; 3819 } 3820 3821 plt = htab->elf.splt; 3822 gotplt = htab->elf.sgotplt; 3823 3824 if (plt && 0 < plt->size) 3825 { 3826 size_t i; 3827 uint32_t plt_header[PLT_HEADER_INSNS]; 3828 if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt), 3829 plt_header)) 3830 return false; 3831 3832 for (i = 0; i < PLT_HEADER_INSNS; i++) 3833 bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i); 3834 3835 elf_section_data (plt->output_section)->this_hdr.sh_entsize = 3836 PLT_ENTRY_SIZE; 3837 } 3838 3839 if (htab->elf.sgotplt) 3840 { 3841 asection *output_section = htab->elf.sgotplt->output_section; 3842 3843 if (bfd_is_abs_section (output_section)) 3844 { 3845 _bfd_error_handler (_("discarded output section: `%pA'"), 3846 htab->elf.sgotplt); 3847 return false; 3848 } 3849 3850 if (0 < htab->elf.sgotplt->size) 3851 { 3852 /* Write the first two entries in .got.plt, needed for the dynamic 3853 linker. */ 3854 bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents); 3855 3856 bfd_put_NN (output_bfd, (bfd_vma) 0, 3857 htab->elf.sgotplt->contents + GOT_ENTRY_SIZE); 3858 } 3859 3860 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; 3861 } 3862 3863 if (htab->elf.sgot) 3864 { 3865 asection *output_section = htab->elf.sgot->output_section; 3866 3867 if (0 < htab->elf.sgot->size) 3868 { 3869 /* Set the first entry in the global offset table to the address of 3870 the dynamic section. */ 3871 bfd_vma val = sdyn ? sec_addr (sdyn) : 0; 3872 bfd_put_NN (output_bfd, val, htab->elf.sgot->contents); 3873 } 3874 3875 elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; 3876 } 3877 3878 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ 3879 htab_traverse (htab->loc_hash_table, 3880 (void *) elfNN_loongarch_finish_local_dynamic_symbol, info); 3881 3882 return true; 3883} 3884 3885/* Return address for Ith PLT stub in section PLT, for relocation REL 3886 or (bfd_vma) -1 if it should not be included. */ 3887 3888static bfd_vma 3889loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt, 3890 const arelent *rel ATTRIBUTE_UNUSED) 3891{ 3892 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE; 3893} 3894 3895static enum elf_reloc_type_class 3896loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, 3897 const asection *rel_sec ATTRIBUTE_UNUSED, 3898 const Elf_Internal_Rela *rela) 3899{ 3900 struct loongarch_elf_link_hash_table *htab; 3901 htab = loongarch_elf_hash_table (info); 3902 3903 if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL) 3904 { 3905 /* Check relocation against STT_GNU_IFUNC symbol if there are 3906 dynamic symbols. */ 3907 bfd *abfd = info->output_bfd; 3908 const struct elf_backend_data *bed = get_elf_backend_data (abfd); 3909 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info); 3910 if (r_symndx != STN_UNDEF) 3911 { 3912 Elf_Internal_Sym sym; 3913 if (!bed->s->swap_symbol_in (abfd, 3914 htab->elf.dynsym->contents 3915 + r_symndx * bed->s->sizeof_sym, 3916 0, &sym)) 3917 { 3918 /* xgettext:c-format */ 3919 _bfd_error_handler (_("%pB symbol number %lu references" 3920 " nonexistent SHT_SYMTAB_SHNDX section"), 3921 abfd, r_symndx); 3922 /* Ideally an error class should be returned here. */ 3923 } 3924 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) 3925 return reloc_class_ifunc; 3926 } 3927 } 3928 3929 switch (ELFNN_R_TYPE (rela->r_info)) 3930 { 3931 case R_LARCH_IRELATIVE: 3932 return reloc_class_ifunc; 3933 case R_LARCH_RELATIVE: 3934 return reloc_class_relative; 3935 case R_LARCH_JUMP_SLOT: 3936 return reloc_class_plt; 3937 case R_LARCH_COPY: 3938 return reloc_class_copy; 3939 default: 3940 return reloc_class_normal; 3941 } 3942} 3943 3944/* Copy the extra info we tack onto an elf_link_hash_entry. */ 3945 3946static void 3947loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info, 3948 struct elf_link_hash_entry *dir, 3949 struct elf_link_hash_entry *ind) 3950{ 3951 struct elf_link_hash_entry *edir, *eind; 3952 3953 edir = dir; 3954 eind = ind; 3955 3956 if (eind->dyn_relocs != NULL) 3957 { 3958 if (edir->dyn_relocs != NULL) 3959 { 3960 struct elf_dyn_relocs **pp; 3961 struct elf_dyn_relocs *p; 3962 3963 /* Add reloc counts against the indirect sym to the direct sym 3964 list. Merge any entries against the same section. */ 3965 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) 3966 { 3967 struct elf_dyn_relocs *q; 3968 3969 for (q = edir->dyn_relocs; q != NULL; q = q->next) 3970 if (q->sec == p->sec) 3971 { 3972 q->pc_count += p->pc_count; 3973 q->count += p->count; 3974 *pp = p->next; 3975 break; 3976 } 3977 if (q == NULL) 3978 pp = &p->next; 3979 } 3980 *pp = edir->dyn_relocs; 3981 } 3982 3983 edir->dyn_relocs = eind->dyn_relocs; 3984 eind->dyn_relocs = NULL; 3985 } 3986 3987 if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0) 3988 { 3989 loongarch_elf_hash_entry(edir)->tls_type 3990 = loongarch_elf_hash_entry(eind)->tls_type; 3991 loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN; 3992 } 3993 _bfd_elf_link_hash_copy_indirect (info, dir, ind); 3994} 3995 3996#define PRSTATUS_SIZE 0x1d8 3997#define PRSTATUS_OFFSET_PR_CURSIG 0xc 3998#define PRSTATUS_OFFSET_PR_PID 0x20 3999#define ELF_GREGSET_T_SIZE 0x168 4000#define PRSTATUS_OFFSET_PR_REG 0x70 4001 4002/* Support for core dump NOTE sections. */ 4003 4004static bool 4005loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 4006{ 4007 switch (note->descsz) 4008 { 4009 default: 4010 return false; 4011 4012 /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */ 4013 case PRSTATUS_SIZE: 4014 /* pr_cursig */ 4015 elf_tdata (abfd)->core->signal = 4016 bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG); 4017 4018 /* pr_pid */ 4019 elf_tdata (abfd)->core->lwpid = 4020 bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID); 4021 break; 4022 } 4023 4024 /* Make a ".reg/999" section. */ 4025 return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE, 4026 note->descpos 4027 + PRSTATUS_OFFSET_PR_REG); 4028} 4029 4030#define PRPSINFO_SIZE 0x88 4031#define PRPSINFO_OFFSET_PR_PID 0x18 4032#define PRPSINFO_OFFSET_PR_FNAME 0x28 4033#define PRPSINFO_SIZEOF_PR_FNAME 0x10 4034#define PRPSINFO_OFFSET_PR_PS_ARGS 0x38 4035#define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50 4036 4037static bool 4038loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 4039{ 4040 switch (note->descsz) 4041 { 4042 default: 4043 return false; 4044 4045 /* The sizeof (prpsinfo_t) on Linux/LoongArch. */ 4046 case PRPSINFO_SIZE: 4047 /* pr_pid */ 4048 elf_tdata (abfd)->core->pid = 4049 bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID); 4050 4051 /* pr_fname */ 4052 elf_tdata (abfd)->core->program = 4053 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME, 4054 PRPSINFO_SIZEOF_PR_FNAME); 4055 4056 /* pr_psargs */ 4057 elf_tdata (abfd)->core->command = 4058 _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS, 4059 PRPSINFO_SIZEOF_PR_PS_ARGS); 4060 break; 4061 } 4062 4063 /* Note that for some reason, a spurious space is tacked 4064 onto the end of the args in some (at least one anyway) 4065 implementations, so strip it off if it exists. */ 4066 4067 { 4068 char *command = elf_tdata (abfd)->core->command; 4069 int n = strlen (command); 4070 4071 if (0 < n && command[n - 1] == ' ') 4072 command[n - 1] = '\0'; 4073 } 4074 4075 return true; 4076} 4077 4078/* Set the right mach type. */ 4079static bool 4080loongarch_elf_object_p (bfd *abfd) 4081{ 4082 /* There are only two mach types in LoongArch currently. */ 4083 if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0) 4084 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64); 4085 else 4086 bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32); 4087 return true; 4088} 4089 4090static asection * 4091loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info, 4092 Elf_Internal_Rela *rel, 4093 struct elf_link_hash_entry *h, 4094 Elf_Internal_Sym *sym) 4095{ 4096 if (h != NULL) 4097 switch (ELFNN_R_TYPE (rel->r_info)) 4098 { 4099 case R_LARCH_GNU_VTINHERIT: 4100 case R_LARCH_GNU_VTENTRY: 4101 return NULL; 4102 } 4103 4104 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); 4105} 4106 4107/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For 4108 executable PLT slots where the executable never takes the address of those 4109 functions, the function symbols are not added to the hash table. */ 4110 4111static bool 4112elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h) 4113{ 4114 if (h->plt.offset != (bfd_vma) -1 4115 && !h->def_regular 4116 && !h->pointer_equality_needed) 4117 return false; 4118 4119 return _bfd_elf_hash_symbol (h); 4120} 4121 4122#define TARGET_LITTLE_SYM loongarch_elfNN_vec 4123#define TARGET_LITTLE_NAME "elfNN-loongarch" 4124#define ELF_ARCH bfd_arch_loongarch 4125#define ELF_TARGET_ID LARCH_ELF_DATA 4126#define ELF_MACHINE_CODE EM_LOONGARCH 4127#define ELF_MAXPAGESIZE 0x4000 4128#define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup 4129#define bfd_elfNN_bfd_link_hash_table_create \ 4130 loongarch_elf_link_hash_table_create 4131#define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup 4132#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */ 4133#define elf_info_to_howto loongarch_info_to_howto_rela 4134#define bfd_elfNN_bfd_merge_private_bfd_data \ 4135 elfNN_loongarch_merge_private_bfd_data 4136 4137#define elf_backend_reloc_type_class loongarch_reloc_type_class 4138#define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol 4139#define elf_backend_create_dynamic_sections \ 4140 loongarch_elf_create_dynamic_sections 4141#define elf_backend_check_relocs loongarch_elf_check_relocs 4142#define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol 4143#define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections 4144#define elf_backend_relocate_section loongarch_elf_relocate_section 4145#define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol 4146#define elf_backend_finish_dynamic_sections \ 4147 loongarch_elf_finish_dynamic_sections 4148#define elf_backend_object_p loongarch_elf_object_p 4149#define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook 4150#define elf_backend_plt_sym_val loongarch_elf_plt_sym_val 4151#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus 4152#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo 4153#define elf_backend_hash_symbol elf_loongarch64_hash_symbol 4154 4155#include "elfNN-target.h" 4156