Projects
openEuler:24.03:SP1:Everything
binutils
_service:tar_scm:LoongArch-Fixed-ABI-v1.00-TLS-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:LoongArch-Fixed-ABI-v1.00-TLS-dynamic-relocation-gen.patch of Package binutils
From aa37c01e929ddd41416ecdd6d8b57799cff4b001 Mon Sep 17 00:00:00 2001 From: Lulu Cai <cailulu@loongson.cn> Date: Thu, 5 Sep 2024 10:20:49 +0800 Subject: [PATCH 111/123] LoongArch: Fixed ABI v1.00 TLS dynamic relocation generation bug Commit "b67a17aa7c0c478a" modified the logic of allocating dynamic relocation space for TLS GD/IE, but only modified the logic of generation dynamic relocations for TLS GD/IE in ABI v2.00. When linking an object file of ABI v1.00 with bfd ld of ABI v2.00, it will cause an assertion failure. Modified the dynamic relocation generation logic of TLS GD/IE in ABI v1.00 to be consistent with ABI v2.00. --- bfd/elfnn-loongarch.c | 92 +++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 14ecd944..30ac5555 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -3541,7 +3541,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_reloc_notsupported, is_undefweak, name, "TLS section not be created")); else - relocation -= elf_hash_table (info)->tls_sec->vma; + relocation = tlsoff (info, relocation); } else fatal = (loongarch_reloc_is_fatal @@ -3890,73 +3890,71 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { Elf_Internal_Rela rela; asection *srel = htab->elf.srelgot; - bfd_vma tls_block_off = 0; - if (LARCH_REF_LOCAL (info, h)) - { - BFD_ASSERT (elf_hash_table (info)->tls_sec); - tls_block_off = relocation - - elf_hash_table (info)->tls_sec->vma; - } + int indx = 0; + bool need_reloc = false; + LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx, + need_reloc); if (tls_type & GOT_TLS_GD) { - rela.r_offset = sec_addr (got) + got_off; - rela.r_addend = 0; - if (LARCH_REF_LOCAL (info, h)) + if (need_reloc) { - /* Local sym, used in exec, set module id 1. */ - if (bfd_link_executable (info)) - bfd_put_NN (output_bfd, 1, got->contents + got_off); + /* Dynamic resolved Module ID. */ + rela.r_offset = sec_addr (got) + got_off; + rela.r_addend = 0; + rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DTPMODNN); + bfd_put_NN (output_bfd, 0, got->contents + got_off); + loongarch_elf_append_rela (output_bfd, srel, &rela); + + if (indx == 0) + { + /* Local symbol, tp offset has been known. */ + BFD_ASSERT (! unresolved_reloc); + bfd_put_NN (output_bfd, + tlsoff (info, relocation), + (got->contents + got_off + GOT_ENTRY_SIZE)); + } else { - rela.r_info = ELFNN_R_INFO (0, - R_LARCH_TLS_DTPMODNN); + /* Dynamic resolved block offset. */ + bfd_put_NN (output_bfd, 0, + got->contents + got_off + GOT_ENTRY_SIZE); + rela.r_info = ELFNN_R_INFO (indx, + R_LARCH_TLS_DTPRELNN); + rela.r_offset += GOT_ENTRY_SIZE; loongarch_elf_append_rela (output_bfd, srel, &rela); } - - bfd_put_NN (output_bfd, tls_block_off, - got->contents + got_off + GOT_ENTRY_SIZE); } - /* Dynamic resolved. */ else { - /* Dynamic relocate module id. */ - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_DTPMODNN); - loongarch_elf_append_rela (output_bfd, srel, &rela); - - /* Dynamic relocate offset of block. */ - rela.r_offset += GOT_ENTRY_SIZE; - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_DTPRELNN); - loongarch_elf_append_rela (output_bfd, srel, &rela); + /* In a static link or an executable link with the symbol + binding locally. Mark it as belonging to module 1. */ + bfd_put_NN (output_bfd, 1, got->contents + got_off); + bfd_put_NN (output_bfd, tlsoff (info, relocation), + got->contents + got_off + GOT_ENTRY_SIZE); } } if (tls_type & GOT_TLS_IE) { - rela.r_offset = sec_addr (got) + got_off + ie_off; - if (LARCH_REF_LOCAL (info, h)) + if (need_reloc) { - /* Local sym, used in exec, set module id 1. */ - if (!bfd_link_executable (info)) - { - rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN); - rela.r_addend = tls_block_off; - loongarch_elf_append_rela (output_bfd, srel, &rela); - } + bfd_put_NN (output_bfd, 0, + got->contents + got_off + ie_off); + rela.r_offset = sec_addr (got) + got_off + ie_off; + rela.r_addend = 0; - bfd_put_NN (output_bfd, tls_block_off, - got->contents + got_off + ie_off); + if (indx == 0) + rela.r_addend = tlsoff (info, relocation); + rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN); + loongarch_elf_append_rela (output_bfd, srel, &rela); } - /* Dynamic resolved. */ else { - /* Dynamic relocate offset of block. */ - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_TPRELNN); - rela.r_addend = 0; - loongarch_elf_append_rela (output_bfd, srel, &rela); + /* In a static link or an executable link with the symbol + binding locally, compute offset directly. */ + bfd_put_NN (output_bfd, tlsoff (info, relocation), + got->contents + got_off + ie_off); } } } -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2