From patchwork Sat Jun 22 10:03:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92709 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A2058382EF10 for ; Sat, 22 Jun 2024 10:04:26 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 92109382FAF9 for ; Sat, 22 Jun 2024 10:03:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 92109382FAF9 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 92109382FAF9 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050626; cv=none; b=oektkO6CL/f2uS7Z+EjLydpwhQ+RaNDFszZaAzkMn8EF++VGLvjLAVhEsL3myrKbhIVXqIwat4imwqIdROHZkWQ0hR9lrEYQt7D2/24EDRsLAKSS16jKQa0V4BvD0e5g7WSKwfkCm9vG5BF5yBteOenSvSdwf6YE5c6/dmlVmHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050626; c=relaxed/simple; bh=BuBPMGyn/01LKrf2wdIf2Oh0ajMjr9qUdA5GmCARdks=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=so+iB4417kT8J1IKUFS8M4h5+4fUmSxZkg3SwtuyAI8TQkd3WnlpdO+dgtcvJbypRu0eUPGoj89Q9xkorrcPRhS5SUwUAnU9LqmntWs4XpcT7d337FpaXDKYtm6RVtBx/dgu8YkAcVfmD0ptEdBmz3wxBQcTQoqYalG2XRhtgYg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719050623; bh=BuBPMGyn/01LKrf2wdIf2Oh0ajMjr9qUdA5GmCARdks=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B1xV/DYj0nQsadhUNealbXh3rWeN90EtRuL+2Tswomm2z8gJhZikqcYHVs5ZtOkZm 9sdSx9og3vygr07Yu30ImImN0wsIVb67YF1hqjhhyxjc5o/S5JQvkHw4mfqfdjoYEH d76DPJQJlPnEVhx2Ew/cQ5YutuH05CQxz50r8D1s= Received: from stargazer.. (unknown [113.200.174.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 195F3670EE; Sat, 22 Jun 2024 06:03:41 -0400 (EDT) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Zhensong Liu , i.swmail@xen0n.name, maskray@google.com, Szabolcs Nagy , Xi Ruoyao Subject: [PATCH 1/5] LoongArch: Reject R_LARCH_32 from becoming a runtime reloc in ELFCLASS64 Date: Sat, 22 Jun 2024 18:03:03 +0800 Message-ID: <20240622100307.9498-2-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240622100307.9498-1-xry111@xry111.site> References: <20240622100307.9498-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org We were converting R_LARCH_32 to R_LARCH_RELATIVE for ELFCLASS64: $ cat t.s .data x: .4byte x $ as/as-new t.s -o t.o $ ld/ld-new -shared t.s $ objdump -R a.out: file format elf64-loongarch DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00000000000001a8 R_LARCH_RELATIVE *ABS*+0x00000000000001a8 But this is just wrong: at runtime the dynamic linker will run *(uintptr *)&x += load_address, causing an OOB write. It does not make too much sense to support R_LARCH_32 in ELFCLASS64 or R_LARCH_64 in ELFCLASS32 when creating a DLL or PIE. And, if we keep it as-is in the linked object, it'll be rejected by Glibc dynamic linker anyway. So we can just reject it like x86_64 and RISC-V. Signed-off-by: Xi Ruoyao --- bfd/elfnn-loongarch.c | 23 ++++++++++++++++++- .../ld-loongarch-elf/ld-loongarch-elf.exp | 1 + .../ld-loongarch-elf/r_larch_32_elf64.d | 4 ++++ .../ld-loongarch-elf/r_larch_32_elf64.s | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index b1720760475..3a55ac93e20 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -2861,7 +2861,28 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, /* No alloc space of func allocate_dynrelocs. */ if (unresolved_reloc && !(h && (h->is_weakalias || !h->dyn_relocs))) - loongarch_elf_append_rela (output_bfd, sreloc, &outrel); + { + if (is_pic && r_type != R_LARCH_NN) + { + /* Not to use ELFCLASSNN in string literal or it'll + puzzle gettext. */ + + /* xgettext:c-format */ + char *msg = bfd_asprintf ( + _("reloc is unresolved and cannot be turned to " + "a runtime reloc in ELFCLASS%d"), + NN); + + /* loongarch_reloc_is_fatal will output + "R_LARCH_32" or "R_LARCH_64" for us. */ + fatal = loongarch_reloc_is_fatal ( + info, input_bfd, input_section, rel, howto, + bfd_reloc_notsupported, is_undefweak, name, msg); + } + else + loongarch_elf_append_rela (output_bfd, sreloc, + &outrel); + } } relocation += rel->r_addend; diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index d833a89246e..70625fa8dfe 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -139,6 +139,7 @@ if [istarget "loongarch64-*-*"] { run_dump_test "reloc_le_with_shared" run_dump_test "reloc_ler_with_shared" run_dump_test "reloc_abs_with_shared" + run_dump_test "r_larch_32_elf64" } if [check_pie_support] { diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d new file mode 100644 index 00000000000..df61f3a36c5 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d @@ -0,0 +1,4 @@ +#name: R_LARCH_32 in ELFCLASS64 +#source: r_larch_32_elf64.s +#ld: -shared -melf64loongarch +#error: R_LARCH_32 against `x':\nreloc is unresolved and cannot be turned to a runtime reloc in ELFCLASS64 diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s new file mode 100644 index 00000000000..6649f2bce01 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s @@ -0,0 +1,3 @@ +.data +x: + .4byte x From patchwork Sat Jun 22 10:03:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92710 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 28AD9382BC31 for ; Sat, 22 Jun 2024 10:04:33 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id A94443830B56 for ; Sat, 22 Jun 2024 10:03:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A94443830B56 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A94443830B56 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050628; cv=none; b=dEdPGAzSF3IxSh/QYenMI/s+bpcoxfPk2s966Tc//QjwalkZiaQqx3BVQLm2Marl4dSNx7b84tYpDSsFrwgQ9jg6vS0TE+g/mOa+G2qPr3vRLTEE2GUWM8ZlhZcBBuu8JCjpUZ5Mj6VnzTNe3gfWcWJtK8tGVB3VXwQKLd923B0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050628; c=relaxed/simple; bh=lqZfxL3ku2erDXK95joT4NDbmK9VMaxI2aQO8Hn/ZQg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=U4wt4Gyqng9n8KPWch9WS7sb4YOwcpJW+g/13GXjlhkUImYiPNmPfDRAuvNZcDGzv3JlMrXtZ6tgDVqUMBNM5v0W0ocJh/e4byJk3djlAPqZ8ZNdkNBtTLcPNR+3WOCTCTY5HgLYjUQfUy/j4b4uSQtYmHUZjXqqfm7RvAKI/+0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719050626; bh=lqZfxL3ku2erDXK95joT4NDbmK9VMaxI2aQO8Hn/ZQg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a7/EYSo5mmBp8qoK7hNTINN5AsY/hqPivFrX94W+E04R63gNYqecJUqldrTkf8XRK jabNC+NiAbyT2nKul2B2i1FFc7Ba5OGXDaYT2Cx1JU0zFL53QgSTZgF8i4M6HQOb+9 h6D91s4eBvTD0HxpX39I3RJgZm1pKqtp4CYoDmOo= Received: from stargazer.. (unknown [113.200.174.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 568B1670EF; Sat, 22 Jun 2024 06:03:44 -0400 (EDT) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Zhensong Liu , i.swmail@xen0n.name, maskray@google.com, Szabolcs Nagy , Xi Ruoyao Subject: [PATCH 2/5] LoongArch: Fix bad reloc with mixed visibility ifunc symbols in shared libraries Date: Sat, 22 Jun 2024 18:03:04 +0800 Message-ID: <20240622100307.9498-3-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240622100307.9498-1-xry111@xry111.site> References: <20240622100307.9498-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org With a simple test case: .globl ifunc .globl ifunc_hidden .hidden ifunc_hidden .type ifunc, %gnu_indirect_function .type ifunc_hidden, %gnu_indirect_function .text .align 2 ifunc: ret ifunc_hidden: ret test: bl ifunc bl ifunc_hidden "ld -shared" produces a shared object with one R_LARCH_NONE (instead of R_LARCH_JUMP_SLOT as we expect) to relocate the GOT entry of "ifunc". It's because the indices in .plt and .rela.plt mismatches for STV_DEFAULT STT_IFUNC symbols when another PLT entry exists for a STV_HIDDEN STT_IFUNC symbol, and such a mismatch breaks the logic of loongarch_elf_finish_dynamic_symbol. Fix the issue by reordering .plt so the indices no longer mismatch. Signed-off-by: Xi Ruoyao --- bfd/elfnn-loongarch.c | 77 ++++++++++++++++--- ld/testsuite/ld-loongarch-elf/ifunc-reloc.d | 19 +++++ ld/testsuite/ld-loongarch-elf/ifunc-reloc.s | 55 +++++++++++++ .../ld-loongarch-elf/ld-loongarch-elf.exp | 1 + 4 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 ld/testsuite/ld-loongarch-elf/ifunc-reloc.d create mode 100644 ld/testsuite/ld-loongarch-elf/ifunc-reloc.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 3a55ac93e20..e0b3e9f5ee6 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -1691,9 +1691,10 @@ local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, ifunc dynamic relocs. */ static bool -elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) +elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, + struct bfd_link_info *info, + bool ref_local) { - struct bfd_link_info *info; /* An example of a bfd_link_hash_indirect symbol is versioned symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect) -> __gxx_personality_v0(bfd_link_hash_defined) @@ -1709,20 +1710,18 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - info = (struct bfd_link_info *) inf; - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it here if it is defined and referenced in a non-shared object. */ if (h->type == STT_GNU_IFUNC && h->def_regular) { - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (ref_local && SYMBOL_REFERENCES_LOCAL (info, h)) return local_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, PLT_ENTRY_SIZE, PLT_HEADER_SIZE, GOT_ENTRY_SIZE, false); - else + else if (!ref_local && !SYMBOL_REFERENCES_LOCAL (info, h)) return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, PLT_ENTRY_SIZE, @@ -1734,6 +1733,23 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) return true; } +static bool +elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry *h, + void *info) +{ + return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info, + true); +} + +static bool +elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h, + void *info) +{ + return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info, + false); +} + + /* Allocate space in .plt, .got and associated reloc sections for ifunc dynamic relocs. */ @@ -1749,7 +1765,7 @@ elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf) || h->root.type != bfd_link_hash_defined) abort (); - return elfNN_allocate_ifunc_dynrelocs (h, inf); + return elfNN_allocate_ifunc_dynrelocs_ref_local (h, inf); } /* Set DF_TEXTREL if we find any dynamic relocs that apply to @@ -1909,11 +1925,48 @@ loongarch_elf_late_size_sections (bfd *output_bfd, sym dynamic relocs. */ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); - /* Allocate global ifunc sym .plt and .got entries, and space for global - ifunc sym dynamic relocs. */ - elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info); - - /* Allocate .plt and .got entries, and space for local ifunc symbols. */ + /* Allocate global ifunc sym .plt and .got entries, and space for + *preemptable* ifunc sym dynamic relocs. Note that we must do it + for *all* preemptable ifunc (including local ifuncs and STV_HIDDEN + ifuncs) before doing it for any unpreemptable ifunc symbol: + assuming we are not so careful, when we link a shared library the + correlation of .plt and .rela.plt might look like: + + idx in .plt idx in .rela.plt + ext_func1@plt 0 0 + ext_func2@plt 1 1 + ext_func3@plt 2 2 + hidden_ifunc1@plt 3 None: it's in .rela.got + hidden_ifunc2@plt 4 None: it's in .rela.got + normal_ifunc1@plt 5 != 3 + normal_ifunc2@plt 6 != 4 + local_ifunc@plt 7 None: it's in .rela.got + + Now oops the indices for normal_ifunc{1,2} in .rela.plt were different + from the indices in .plt :(. This would break finish_dynamic_symbol + which assumes the index in .rela.plt matches the index in .plt. + + So let's be careful and make it correct: + + idx in .plt idx in .rela.plt + ext_func1@plt 0 0 + ext_func2@plt 1 1 + ext_func3@plt 2 2 + normal_ifunc1@plt 3 3 + normal_ifunc2@plt 4 4 + hidden_ifunc1@plt 5 None: it's in .rela.got + hidden_ifunc2@plt 6 None: it's in .rela.got + local_ifunc@plt 7 None: it's in .rela.got + + Now normal_ifuncs first. */ + elf_link_hash_traverse (&htab->elf, + elfNN_allocate_ifunc_dynrelocs_ref_global, info); + + /* Now hidden_ifuncs ifuncs. */ + elf_link_hash_traverse (&htab->elf, + elfNN_allocate_ifunc_dynrelocs_ref_local, info); + + /* Finally local ifuncs. */ htab_traverse (htab->loc_hash_table, elfNN_allocate_local_ifunc_dynrelocs, info); diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d new file mode 100644 index 00000000000..cb592874b1e --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d @@ -0,0 +1,19 @@ +#ld: -shared +#readelf: -Wr + +#... +.*'\.rela\.dyn'.* +#... +.* R_LARCH_RELATIVE .* +.* R_LARCH_IRELATIVE .* +.* R_LARCH_IRELATIVE .* +.* R_LARCH_IRELATIVE .* +#... +.*'\.rela\.plt'.* +#... +.* R_LARCH_JUMP_SLOT .* +.* R_LARCH_JUMP_SLOT .* +.* R_LARCH_JUMP_SLOT .* +.* R_LARCH_JUMP_SLOT .* +.* R_LARCH_JUMP_SLOT .* +.* R_LARCH_JUMP_SLOT .* diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s new file mode 100644 index 00000000000..e59f2b20e36 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s @@ -0,0 +1,55 @@ +.globl foo +.globl foo_hidden1 +.globl foo_hidden2 +.globl foo_protected + +.type foo, %gnu_indirect_function +.type foo_hidden1, %gnu_indirect_function +.type foo_hidden2, %gnu_indirect_function +.type foo_protected, %gnu_indirect_function +.type foo_internal, %gnu_indirect_function + +.hidden foo_hidden1 +.hidden foo_hidden2 + +.protected foo_protected + +.globl ext_ifunc1 +.globl ext_ifunc2 +.type ext_ifunc1, %gnu_indirect_function +.type ext_ifunc2, %gnu_indirect_function + +.text +.align 2 +foo: + ret + +foo_hidden1: + ret + +foo_hidden2: + ret + +foo_protected: + ret + +foo_internal: + ret + +test: + la.got $a0, num + # The order is deliberately shuffled. + bl ext_ifunc1 + bl foo + bl foo_hidden1 + bl ext_func1 + bl foo_protected + bl foo_internal + bl foo_hidden2 + bl ext_func2 + bl ext_ifunc2 + +.data +.align 3 +num: + .quad 114514 diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 70625fa8dfe..b8721f0eaff 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -140,6 +140,7 @@ if [istarget "loongarch64-*-*"] { run_dump_test "reloc_ler_with_shared" run_dump_test "reloc_abs_with_shared" run_dump_test "r_larch_32_elf64" + run_dump_test "ifunc-reloc" } if [check_pie_support] { From patchwork Sat Jun 22 10:03:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92712 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 92E1C3826DCD for ; Sat, 22 Jun 2024 10:05:41 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 18EC6382EF16 for ; Sat, 22 Jun 2024 10:03:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 18EC6382EF16 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 18EC6382EF16 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050631; cv=none; b=m/zqPIdx/MSWC5aFo9bvAEg0/yXc/OtJHYI8atG8sbYkH0aewzast5lozheXg7jIfl+gaxLCBi7dh4vkYOqxbiw4jTYpOjbaOZhePNQvGWKyCj+rZ6+7Z1ptf3hqfLL23rx4TQ7CnZeofDmYpuFjgSz5im0/s7YoK55PY8ANIi4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050631; c=relaxed/simple; bh=NhsvYCxGO5vjkH4YJAbDJ0Y3cgKwAlaa/8ssZw6PqQs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=vg8FbwIfqPSPqQuBg65eiEwxrYh6ODv/UqUtR96OaCeNWaGzZQaf4rE26vwbS976smqsZzgRz5r4Bam0DKbaYczoPxZVmeJuMG/JdMyx9tkpbxHTGMmq2J4KVcQFNeJcVbvAX6ER7f+FIF2BwTTGJA8KvMh/DWuqJKYtheSE6og= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719050628; bh=NhsvYCxGO5vjkH4YJAbDJ0Y3cgKwAlaa/8ssZw6PqQs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MuH3n6QINk9J2otIQgfBnYOv4/qVODYEWum4TzXDY896H9DRHPaYrQRThSfvKC9X+ tGxI91he+HMovy0BrLi9QGtbaxzoAbIzlvkmjh1XW0IVbf3Ev6ZQ404AV2oPsPTrIK ZRe1ApJIQ/PYNc8/c4ia5AOa7CSpZ2gIs/XvdsZA= Received: from stargazer.. (unknown [113.200.174.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 6D1CB670F1; Sat, 22 Jun 2024 06:03:46 -0400 (EDT) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Zhensong Liu , i.swmail@xen0n.name, maskray@google.com, Szabolcs Nagy , Xi Ruoyao Subject: [PATCH 3/5] LoongArch: Make protected function symbols local for -shared Date: Sat, 22 Jun 2024 18:03:05 +0800 Message-ID: <20240622100307.9498-4-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240622100307.9498-1-xry111@xry111.site> References: <20240622100307.9498-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org On LoongArch there is no reason to treat STV_PROTECTED STT_FUNC symbols as preemptable. See the comment above LARCH_REF_LOCAL for detailed explanation. Signed-off-by: Xi Ruoyao --- bfd/elfnn-loongarch.c | 78 ++++++++++++++----- ld/testsuite/ld-loongarch-elf/ifunc-reloc.d | 2 +- .../ld-loongarch-elf/ld-loongarch-elf.exp | 1 + .../ld-loongarch-elf/protected-func.d | 6 ++ .../ld-loongarch-elf/protected-func.s | 17 ++++ 5 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 ld/testsuite/ld-loongarch-elf/protected-func.d create mode 100644 ld/testsuite/ld-loongarch-elf/protected-func.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index e0b3e9f5ee6..2acb5c7fa95 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -181,6 +181,46 @@ struct loongarch_elf_link_hash_table } \ while (0) +/* TL;DR always use it in this file instead when you want to type + SYMBOL_REFERENCES_LOCAL. + + It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local + protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but + let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people. + + We do generate the so-called "canonical PLT entry" when someone attempts + to la.pcrel an external function. But this is only an unwanted side- + effect from using R_LARCH_PCALA_{HI20,LO12} for medium and extreme + code model function call: we have the same problem as i386 where + R_386_PC32 is used for both call and lea (for medium code model new code + should use R_LARCH_CALL36 instead), but unlike i386 we never really + implemented "R_LARCH_COPY" thus attempting to la.pcrel an external + symbol is always considered a programming error unless it's a part of + a extreme code model function call, and pointer equality will be broken + even with a STV_DEFAULT function: + + $ cat t.c + #include + void check(void *p) {assert(p == check);} + $ cat main.c + extern void check(void *); + int main(void) { check(check); } + $ cc t.c -fPIC -shared -o t.so + $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. + $ ./a.out + a.out: t.c:2: check: Assertion `p == check' failed. + Aborted + + Thus handling STV_PROTECTED function specially just fixes nothing: + adding -fvisibility=protected compiling t.c will not magically fix + the inequality. The only possible and correct fix is not to use + -mdirect-extern-access. + + So we should remove this special handling, because it's only an + unsuccessful workaround for invalid code and it's penalizing valid + code. */ +#define LARCH_REF_LOCAL(info, h) \ + (_bfd_elf_symbol_refs_local_p ((h), (info), true)) /* Generate a PLT header. */ @@ -712,7 +752,7 @@ loongarch_tls_transition_without_check (struct bfd_link_info *info, struct elf_link_hash_entry *h) { bool local_exec = bfd_link_executable (info) - && SYMBOL_REFERENCES_LOCAL (info, h); + && LARCH_REF_LOCAL (info, h); switch (r_type) { @@ -1196,7 +1236,7 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info, { if (h->plt.refcount <= 0 || (h->type != STT_GNU_IFUNC - && (SYMBOL_REFERENCES_LOCAL (info, h) + && (LARCH_REF_LOCAL (info, h) || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT && h->root.type == bfd_link_hash_undefweak)))) { @@ -1714,14 +1754,14 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, here if it is defined and referenced in a non-shared object. */ if (h->type == STT_GNU_IFUNC && h->def_regular) { - if (ref_local && SYMBOL_REFERENCES_LOCAL (info, h)) + if (ref_local && LARCH_REF_LOCAL (info, h)) return local_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, PLT_ENTRY_SIZE, PLT_HEADER_SIZE, GOT_ENTRY_SIZE, false); - else if (!ref_local && !SYMBOL_REFERENCES_LOCAL (info, h)) + else if (!ref_local && !LARCH_REF_LOCAL (info, h)) return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, PLT_ENTRY_SIZE, @@ -1749,7 +1789,6 @@ elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h, false); } - /* Allocate space in .plt, .got and associated reloc sections for ifunc dynamic relocs. */ @@ -2662,7 +2701,6 @@ tlsoff (struct bfd_link_info *info, bfd_vma addr) return addr - elf_hash_table (info)->tls_sec->vma; } - static int loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, @@ -2788,7 +2826,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { defined_local = !unresolved_reloc && !ignored; resolved_local = - defined_local && SYMBOL_REFERENCES_LOCAL (info, h); + defined_local && LARCH_REF_LOCAL (info, h); resolved_dynly = !resolved_local; resolved_to_const = !resolved_local && !resolved_dynly; } @@ -2877,7 +2915,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, outrel.r_addend = 0; } - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (LARCH_REF_LOCAL (info, h)) { if (htab->elf.splt != NULL) @@ -3246,7 +3284,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, bfd_link_pic (info), h) && ((bfd_link_pic (info) - && SYMBOL_REFERENCES_LOCAL (info, h)))) + && LARCH_REF_LOCAL (info, h)))) { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined @@ -3391,7 +3429,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, asection *srel = htab->elf.srelgot; bfd_vma tls_block_off = 0; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (LARCH_REF_LOCAL (info, h)) { BFD_ASSERT (elf_hash_table (info)->tls_sec); tls_block_off = relocation @@ -3402,7 +3440,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { rela.r_offset = sec_addr (got) + got_off; rela.r_addend = 0; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (LARCH_REF_LOCAL (info, h)) { /* Local sym, used in exec, set module id 1. */ if (bfd_link_executable (info)) @@ -3435,7 +3473,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (tls_type & GOT_TLS_IE) { rela.r_offset = sec_addr (got) + got_off + ie_off; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (LARCH_REF_LOCAL (info, h)) { /* Local sym, used in exec, set module id 1. */ if (!bfd_link_executable (info)) @@ -3637,7 +3675,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_link_pic (info), h) && bfd_link_pic (info) - && SYMBOL_REFERENCES_LOCAL (info, h)) + && LARCH_REF_LOCAL (info, h)) { Elf_Internal_Rela rela; rela.r_offset = sec_addr (got) + got_off; @@ -4178,7 +4216,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec, { unsigned long insn; bool local_exec = bfd_link_executable (info) - && SYMBOL_REFERENCES_LOCAL (info, h); + && LARCH_REF_LOCAL (info, h); bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; unsigned long r_type = ELFNN_R_TYPE (rel->r_info); unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); @@ -4890,7 +4928,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, else continue; - if (h && SYMBOL_REFERENCES_LOCAL (info, h)) + if (h && LARCH_REF_LOCAL (info, h)) local_got = true; symtype = h->type; } @@ -5027,12 +5065,12 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, if (htab->elf.splt) { BFD_ASSERT ((h->type == STT_GNU_IFUNC - && SYMBOL_REFERENCES_LOCAL (info, h)) + && LARCH_REF_LOCAL (info, h)) || h->dynindx != -1); plt = htab->elf.splt; gotplt = htab->elf.sgotplt; - if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h)) + if (h->type == STT_GNU_IFUNC && LARCH_REF_LOCAL (info, h)) relplt = htab->elf.srelgot; else relplt = htab->elf.srelplt; @@ -5043,7 +5081,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, else /* if (htab->elf.iplt) */ { BFD_ASSERT (h->type == STT_GNU_IFUNC - && SYMBOL_REFERENCES_LOCAL (info, h)); + && LARCH_REF_LOCAL (info, h)); plt = htab->elf.iplt; gotplt = htab->elf.igotplt; @@ -5131,7 +5169,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, if (htab->elf.splt == NULL) srela = htab->elf.irelplt; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (LARCH_REF_LOCAL (info, h)) { asection *sec = h->root.u.def.section; rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); @@ -5168,7 +5206,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, return true; } } - else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) + else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h)) { asection *sec = h->root.u.def.section; rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d index cb592874b1e..968e7564b49 100644 --- a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d +++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d @@ -8,6 +8,7 @@ .* R_LARCH_IRELATIVE .* .* R_LARCH_IRELATIVE .* .* R_LARCH_IRELATIVE .* +.* R_LARCH_IRELATIVE .* #... .*'\.rela\.plt'.* #... @@ -16,4 +17,3 @@ .* R_LARCH_JUMP_SLOT .* .* R_LARCH_JUMP_SLOT .* .* R_LARCH_JUMP_SLOT .* -.* R_LARCH_JUMP_SLOT .* diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index b8721f0eaff..3172a0ab4b5 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -141,6 +141,7 @@ if [istarget "loongarch64-*-*"] { run_dump_test "reloc_abs_with_shared" run_dump_test "r_larch_32_elf64" run_dump_test "ifunc-reloc" + run_dump_test "protected-func" } if [check_pie_support] { diff --git a/ld/testsuite/ld-loongarch-elf/protected-func.d b/ld/testsuite/ld-loongarch-elf/protected-func.d new file mode 100644 index 00000000000..501c7cb5f8c --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/protected-func.d @@ -0,0 +1,6 @@ +#ld: -shared +#readelf: -Wr + +#... +.* R_LARCH_RELATIVE .* +.* R_LARCH_RELATIVE .* diff --git a/ld/testsuite/ld-loongarch-elf/protected-func.s b/ld/testsuite/ld-loongarch-elf/protected-func.s new file mode 100644 index 00000000000..347e371a777 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/protected-func.s @@ -0,0 +1,17 @@ +# protected function should be unpreemptable and relocated with +# R_LARCH_RELATIVE in shared library, for both GOT and pointer data + +.globl x +.protected x +.type x, @function +x: + ret + +.globl _start +_start: + la.got $a0, x + ret + +.data +p: + .quad x From patchwork Sat Jun 22 10:03:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92711 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6DC203826DF0 for ; Sat, 22 Jun 2024 10:05:02 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 68E6C382EF0D for ; Sat, 22 Jun 2024 10:03:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 68E6C382EF0D Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 68E6C382EF0D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050635; cv=none; b=eGj2a/giGi9UYwu5exr1G724AIcpOw2Tb0oN2epRqKw3brCLxOSw2bQjT2sAiyCDCi8u6AxIJrmpePcItbBFAbUMPMmLes75+gjCJ182DvxHqdHoVnGCp5ETZc43UtY9mkH0gLXSnOO5urfGdAbQ4f1oinjXCDE6NMowJWlcVN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050635; c=relaxed/simple; bh=u0Otgrx6yxGiHkKoa4/R9qFZ0ZiCydofqHHJ/gcCQUU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ou1BLZQyx93z9M+BTdZMfXfEiY/WE/Q/7dgvvcp31prDV7Myi48+N70CMofQWWxUw1/zLD9ZGnDdc/qbRte54/gtT0oDCQoljx0uccdhEPOGNWPrfV1K3PJ7LSZyPDJ3cASIQLUx0S9MKQw7puPAvjjLpGSnfOKWzdRgKCtbUMo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719050630; bh=u0Otgrx6yxGiHkKoa4/R9qFZ0ZiCydofqHHJ/gcCQUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g4PJpgxtSXFXbwaRqzBUVFix1WPPDeCoxSmv+bNnaGk5pJkvA0qZ1+cmNgQqATDX4 X8lqcOaJ82cpMH41j84L9ghbWAMM73z3hk7rcQG+h5LX6ZaDXDHperVTpYYp/0b//5 CyH7wJ4MyrgU9fyMYiPiL4OGg00w4GQlX3L39IEQ= Received: from stargazer.. (unknown [113.200.174.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id E46F9670ED; Sat, 22 Jun 2024 06:03:48 -0400 (EDT) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Zhensong Liu , i.swmail@xen0n.name, maskray@google.com, Szabolcs Nagy , Xi Ruoyao Subject: [PATCH 4/5] LoongArch: Add DT_RELR support Date: Sat, 22 Jun 2024 18:03:06 +0800 Message-ID: <20240622100307.9498-5-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240622100307.9498-1-xry111@xry111.site> References: <20240622100307.9498-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org The logic is same as a71d87680110 ("aarch64: Add DT_RELR support"). As LoongArch does not have -z dynamic-undefined-weak, we don't need to consider UNDEFWEAK_NO_DYNAMIC_RELOC. The linker relaxation adds another layer of complexity. When we delete bytes in a section during relaxation, we need to fix up the offset in the to-be-packed relative relocations against this section. Signed-off-by: Xi Ruoyao --- bfd/elfnn-loongarch.c | 482 ++++++++++++++++++++- binutils/testsuite/lib/binutils-common.exp | 1 + ld/emulparams/elf64loongarch.sh | 1 + 3 files changed, 481 insertions(+), 3 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 2acb5c7fa95..d63dfa81e91 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -84,6 +84,12 @@ struct _bfd_loongarch_elf_obj_tdata && elf_tdata (bfd) != NULL \ && elf_object_id (bfd) == LARCH_ELF_DATA) +struct relr_entry +{ + asection *sec; + bfd_vma off; +}; + struct loongarch_elf_link_hash_table { struct elf_link_hash_table elf; @@ -104,8 +110,50 @@ struct loongarch_elf_link_hash_table /* The data segment phase, don't relax the section when it is exp_seg_relro_adjust. */ int *data_segment_phase; + + /* Array of relative relocs to be emitted in DT_RELR format. */ + bfd_size_type relr_alloc; + bfd_size_type relr_count; + struct relr_entry *relr; + + /* Sorted output addresses of above relative relocs. */ + bfd_vma *relr_sorted; + + /* Layout recomputation count. */ + bfd_size_type relr_layout_iter; }; +struct loongarch_elf_section_data +{ + struct bfd_elf_section_data elf; + + /* &htab->relr[i] where i is the smallest number s.t. + htab->relr[i].sec == &elf. NULL if there exists no such i. */ + struct relr_entry *relr; +}; + +/* We need an additional field in elf_section_data to handle complex + interactions between DT_RELR and relaxation. */ +static bool +loongarch_elf_new_section_hook (bfd *abfd, asection *sec) +{ + if (!sec->used_by_bfd) + { + struct loongarch_elf_section_data *sdata; + size_t amt = sizeof (*sdata); + + sdata = bfd_zalloc (abfd, amt); + if (!sdata) + return false; + sec->used_by_bfd = sdata; + } + + return _bfd_elf_new_section_hook (abfd, sec); +} + +#define loongarch_elf_section_data(x) \ + ((struct loongarch_elf_section_data *) elf_section_data (x)) + /* Get the LoongArch ELF linker hash table from a link_info structure. */ #define loongarch_elf_hash_table(p) \ (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \ @@ -929,6 +977,20 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (rel + 1 != relocs + sec->reloc_count && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX) r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type); + + /* I don't want to spend time supporting DT_RELR with old object + files doing stack-based relocs. */ + if (info->enable_dt_relr + && r_type >= R_LARCH_SOP_PUSH_PCREL + && r_type <= R_LARCH_SOP_POP_32_U) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: stack based reloc type (%u) is not " + "supported with -z pack-relative-relocs"), + abfd, r_type); + return false; + } + switch (r_type) { case R_LARCH_GOT_PC_HI20: @@ -1120,6 +1182,20 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, return false; break; + case R_LARCH_ALIGN: + /* Check against irrational R_LARCH_ALIGN relocs which may cause + removing an odd number of bytes and disrupt DT_RELR. */ + if (rel->r_offset % 4 != 0) + { + /* xgettext:c-format */ + _bfd_error_handler ( + _("%pB: R_LARCH_ALIGN with offset %" PRId64 " not aligned " + "to instruction boundary"), + abfd, (uint64_t) rel->r_offset); + return false; + } + break; + default: break; } @@ -1834,6 +1910,342 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) return true; } +static bool +record_relr (struct loongarch_elf_link_hash_table *htab, asection *sec, + bfd_vma off, asection *sreloc) +{ + struct relr_entry **sec_relr = &loongarch_elf_section_data (sec)->relr; + + /* Undo the relocation section size accounting. */ + BFD_ASSERT (sreloc->size >= sizeof (ElfNN_External_Rela)); + sreloc->size -= sizeof (ElfNN_External_Rela); + + BFD_ASSERT (off % 2 == 0 && sec->alignment_power > 0); + if (htab->relr_count >= htab->relr_alloc) + { + if (htab->relr_alloc == 0) + htab->relr_alloc = 4096; + else + htab->relr_alloc *= 2; + + htab->relr = bfd_realloc (htab->relr, + htab->relr_alloc * sizeof (*htab->relr)); + if (!htab->relr) + return false; + } + htab->relr[htab->relr_count].sec = sec; + htab->relr[htab->relr_count].off = off; + if (*sec_relr == NULL) + *sec_relr = &htab->relr[htab->relr_count]; + htab->relr_count++; + return true; +} + +static bool +record_relr_local_got_relocs (bfd *input_bfd, struct bfd_link_info *info) +{ + bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd); + char *local_tls_type = _bfd_loongarch_elf_local_got_tls_type (input_bfd); + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd); + struct loongarch_elf_link_hash_table *htab = + loongarch_elf_hash_table (info); + + if (!local_got_offsets || !local_tls_type || !bfd_link_pic (info)) + return true; + + for (unsigned i = 0; i < symtab_hdr->sh_info; i++) + { + bfd_vma off = local_got_offsets[i]; + + /* FIXME: If the local symbol is in SHN_ABS then emitting + a relative relocation is not correct, but it seems to be wrong + in loongarch_elf_relocate_section too. */ + if (local_tls_type[i] == GOT_NORMAL + && !record_relr (htab, htab->elf.sgot, off, htab->elf.srelgot)) + return false; + } + + return true; +} + +static bool +record_relr_dyn_got_relocs (struct elf_link_hash_entry *h, void *inf) +{ + struct bfd_link_info *info = (struct bfd_link_info *) inf; + struct loongarch_elf_link_hash_table *htab = + loongarch_elf_hash_table (info); + + if (h->root.type == bfd_link_hash_indirect) + return true; + if (h->type == STT_GNU_IFUNC && h->def_regular) + return true; + if (h->got.refcount <= 0) + return true; + if (loongarch_elf_hash_entry (h)->tls_type + & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) + return true; + if (!bfd_link_pic (info)) + return true; + + /* On LoongArch a GOT entry for undefined weak symbol is never relocated + with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus + the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or + relocated with R_LARCH_NN (otherwise). */ + if (h->root.type == bfd_link_hash_undefweak) + return true; + + if (!LARCH_REF_LOCAL (info, h)) + return true; + if (bfd_is_abs_symbol (&h->root)) + return true; + + if (!record_relr (htab, htab->elf.sgot, h->got.offset, + htab->elf.srelgot)) + return false; + + return true; +} + +static bool +record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info, + asection *sec) +{ + asection *sreloc; + struct loongarch_elf_link_hash_table *htab; + Elf_Internal_Rela *relocs, *rel, *rel_end; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + + if (!bfd_link_pic (info)) + return true; + if (sec->reloc_count == 0) + return true; + if ((sec->flags & (SEC_RELOC | SEC_ALLOC | SEC_DEBUGGING)) + != (SEC_RELOC | SEC_ALLOC)) + return true; + if (sec->alignment_power == 0) + return true; + if (discarded_section (sec)) + return true; + + sreloc = elf_section_data (sec)->sreloc; + if (sreloc == NULL) + return true; + + htab = loongarch_elf_hash_table (info); + symtab_hdr = &elf_symtab_hdr (input_bfd); + sym_hashes = elf_sym_hashes (input_bfd); + relocs = _bfd_elf_link_info_read_relocs (input_bfd, info, sec, NULL, + NULL, info->keep_memory); + BFD_ASSERT (relocs != NULL); + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + unsigned r_symndx = ELFNN_R_SYM (rel->r_info); + struct elf_link_hash_entry *h = NULL; + asection *def_sec = NULL; + + if (ELFNN_R_TYPE (rel->r_info) != R_LARCH_NN + || rel->r_offset % 2 != 0) + continue; + + /* The logical below must match loongarch_elf_relocate_section. */ + if (r_symndx < symtab_hdr->sh_info) + { + /* A local symbol. */ + Elf_Internal_Sym *isym; + isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, input_bfd, + r_symndx); + BFD_ASSERT(isym != NULL); + + /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for + R_LARCH_NN, not R_LARCH_RELATIVE. */ + if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) + continue; + def_sec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); + } + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* Filter out symbols that cannot have a relative reloc. */ + if (h->dyn_relocs == NULL) + continue; + if (bfd_is_abs_symbol (&h->root)) + continue; + if (h->type == STT_GNU_IFUNC) + continue; + + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + def_sec = h->root.u.def.section; + + /* On LoongArch an R_LARCH_NN against undefined weak symbol + is never converted to R_LARCH_RELATIVE: we don't have + -z dynamic-undefined-weak, thus the reloc is either removed + (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */ + if (h->root.type == bfd_link_hash_undefweak) + continue; + + if (!LARCH_REF_LOCAL (info, h)) + continue; + } + + if (!def_sec || discarded_section (def_sec)) + continue; + + if (!record_relr (htab, sec, rel->r_offset, sreloc)) + return false; + } + + return true; +} + +static int +cmp_relr_addr (const void *p, const void *q) +{ + const bfd_vma *a = p, *b = q; + return (*a > *b) - (*a < *b); +} + +static bool +sort_relr (struct bfd_link_info *info, + struct loongarch_elf_link_hash_table *htab) +{ + if (htab->relr_count == 0) + return true; + + bfd_vma *addr = htab->relr_sorted; + if (!addr) + { + addr = bfd_malloc (htab->relr_count * sizeof (*addr)); + if (!addr) + return false; + htab->relr_sorted = addr; + } + + for (bfd_size_type i = 0; i < htab->relr_count; i++) + { + bfd_vma off = _bfd_elf_section_offset (info->output_bfd, info, + htab->relr[i].sec, + htab->relr[i].off); + addr[i] = htab->relr[i].sec->output_section->vma + + htab->relr[i].sec->output_offset + off; + } + qsort(addr, htab->relr_count, sizeof (*addr), cmp_relr_addr); + return true; +} + +static bool +loongarch_elf_size_relative_relocs (struct bfd_link_info *info, + bool *need_layout) +{ + struct loongarch_elf_link_hash_table *htab = + loongarch_elf_hash_table (info); + asection *srelrdyn = htab->elf.srelrdyn; + + *need_layout = false; + + if (!sort_relr (info, htab)) + return false; + bfd_vma *addr = htab->relr_sorted; + + BFD_ASSERT (srelrdyn != NULL); + bfd_size_type oldsize = srelrdyn->size; + srelrdyn->size = 0; + for (bfd_size_type i = 0; i < htab->relr_count; ) + { + bfd_vma base = addr[i]; + i++; + srelrdyn->size += NN / 8; + base += NN / 8; + while (1) + { + bfd_size_type start_i = i; + while (i < htab->relr_count + && addr[i] - base < (NN - 1) * (NN / 8) + && (addr[i] - base) % (NN / 8) == 0) + i++; + if (i == start_i) + break; + srelrdyn->size += NN / 8; + base += (NN - 1) * (NN / 8); + } + } + if (srelrdyn->size != oldsize) + { + *need_layout = true; + /* Stop after a few iterations in case the layout does not converge, + but we can only stop when the size would shrink (and pad the + spare space with 1. */ + if (htab->relr_layout_iter++ > 5 && srelrdyn->size < oldsize) + { + srelrdyn->size = oldsize; + *need_layout = false; + } + } + return true; +} + +static bool +loongarch_elf_finish_relative_relocs (struct bfd_link_info *info) +{ + struct loongarch_elf_link_hash_table *htab = + loongarch_elf_hash_table (info); + asection *srelrdyn = htab->elf.srelrdyn; + bfd *dynobj = htab->elf.dynobj; + + if (!srelrdyn || srelrdyn->size == 0) + return true; + + srelrdyn->contents = bfd_alloc (dynobj, srelrdyn->size); + if (!srelrdyn->contents) + return false; + + bfd_vma *addr = htab->relr_sorted; + bfd_byte *loc = srelrdyn->contents; + for (bfd_size_type i = 0; i < htab->relr_count; ) + { + bfd_vma base = addr[i]; + i++; + bfd_put_NN (dynobj, base, loc); + loc += NN / 8; + base += NN / 8; + while (1) + { + uintNN_t bits = 0; + while (i < htab->relr_count) + { + bfd_vma delta = addr[i] - base; + if (delta >= (NN - 1) * (NN / 8) || delta % (NN / 8) != 0) + break; + bits |= (uintNN_t) 1 << (delta / (NN / 8)); + i++; + } + if (bits == 0) + break; + bfd_put_NN (dynobj, (bits << 1) | 1, loc); + loc += NN / 8; + base += (NN - 1) * (NN / 8); + } + } + + free (addr); + htab->relr_sorted = NULL; + + /* Pad any excess with 1's, a do-nothing encoding. */ + while (loc < srelrdyn->contents + srelrdyn->size) + { + bfd_put_NN (dynobj, 1, loc); + loc += NN / 8; + } + + return true; +} + static bool loongarch_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info) @@ -2014,6 +2426,24 @@ loongarch_elf_late_size_sections (bfd *output_bfd, && (htab->elf.splt == NULL || htab->elf.splt->size == 0)) htab->elf.sgotplt->size = 0; + if (info->enable_dt_relr && !bfd_link_relocatable (info)) + { + elf_link_hash_traverse (&htab->elf, record_relr_dyn_got_relocs, info); + + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) + { + if (!is_loongarch_elf (ibfd)) + continue; + + for (s = ibfd->sections; s != NULL; s = s->next) + if (!record_relr_non_got_relocs (ibfd, info, s)) + return false; + + if (!record_relr_local_got_relocs (ibfd, info)) + return false; + } + } + /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ @@ -2038,6 +2468,14 @@ loongarch_elf_late_size_sections (bfd *output_bfd, s->reloc_count = 0; } } + else if (s == htab->elf.srelrdyn && htab->relr_count == 0) + { + /* Remove .relr.dyn based on relr_count, not size, since + it is not sized yet. */ + s->flags |= SEC_EXCLUDE; + /* Allocate contents later. */ + continue; + } else { /* It's not one of our sections. */ @@ -2970,6 +3408,17 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, info, input_bfd, input_section, rel, howto, bfd_reloc_notsupported, is_undefweak, name, msg); } + else if (info->enable_dt_relr + && (ELFNN_R_TYPE (outrel.r_info) + == R_LARCH_RELATIVE) + && input_section->alignment_power != 0 + && rel->r_offset % 2 == 0) + /* Don't emit a relative relocation that is packed, + only apply the addend (as if we are applying the + original R_LARCH_NN reloc in a PDE). */ + r = perform_relocation (rel, input_section, howto, + relocation, input_bfd, + contents); else loongarch_elf_append_rela (output_bfd, sreloc, &outrel); @@ -3697,7 +4146,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1); if ((local_got_offsets[r_symndx] & 1) == 0) { - if (bfd_link_pic (info)) + if (bfd_link_pic (info) && !info->enable_dt_relr) { Elf_Internal_Rela rela; rela.r_offset = sec_addr (got) + got_off; @@ -4109,6 +4558,14 @@ loongarch_relax_delete_bytes (bfd *abfd, unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); struct bfd_elf_section_data *data = elf_section_data (sec); bfd_byte *contents = data->this_hdr.contents; + struct relr_entry *relr = + ((struct loongarch_elf_section_data *)elf_section_data (sec))->relr; + struct loongarch_elf_link_hash_table *htab = + loongarch_elf_hash_table (link_info); + struct relr_entry *relr_end = NULL; + + if (htab->relr_count) + relr_end = htab->relr + htab->relr_count; /* Actually delete the bytes. */ sec->size -= count; @@ -4121,6 +4578,11 @@ loongarch_relax_delete_bytes (bfd *abfd, if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr) data->relocs[i].r_offset -= count; + /* Likewise for relative relocs to be packed into .relr. */ + for (; relr && relr < relr_end && relr->sec == sec; relr++) + if (relr->off > addr && relr->off < toaddr) + relr->off -= count; + /* Adjust the local symbols defined in this section. */ for (i = 0; i < symtab_hdr->sh_info; i++) { @@ -5209,9 +5671,18 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h)) { asection *sec = h->root.u.def.section; + bfd_vma linkaddr = h->root.u.def.value + sec->output_section->vma + + sec->output_offset; + + /* Don't emit relative relocs if they are packed, but we need + to write the addend (link-time addr) into the GOT then. */ + if (info->enable_dt_relr) + { + bfd_put_NN (output_bfd, linkaddr, sgot->contents + off); + goto skip_got_reloc; + } rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); - rela.r_addend = (h->root.u.def.value + sec->output_section->vma - + sec->output_offset); + rela.r_addend = linkaddr; } else { @@ -5222,6 +5693,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, loongarch_elf_append_rela (output_bfd, srela, &rela); } +skip_got_reloc: /* Mark some specially defined symbols as absolute. */ if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt) @@ -5675,6 +6147,10 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h) #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo #define elf_backend_hash_symbol elf_loongarch64_hash_symbol #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section +#define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs +#define elf_backend_finish_relative_relocs \ + loongarch_elf_finish_relative_relocs +#define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook #define elf_backend_dtrel_excludes_plt 1 diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index 5bfcde51531..262ad30e039 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -474,6 +474,7 @@ proc supports_dt_relr {} { || [istarget i?86-*-*] || [istarget powerpc64*-*-*] || ([istarget aarch64*-*-*] && ![istarget *-*-*ilp32])) + || [istarget loongarch64*-*-*] && ([istarget *-*-linux*] || [istarget *-*-gnu*]) } { return 1 diff --git a/ld/emulparams/elf64loongarch.sh b/ld/emulparams/elf64loongarch.sh index d7b2229e213..8c805da987e 100644 --- a/ld/emulparams/elf64loongarch.sh +++ b/ld/emulparams/elf64loongarch.sh @@ -1,4 +1,5 @@ source_sh ${srcdir}/emulparams/elf64loongarch-defs.sh +source_sh ${srcdir}/emulparams/dt-relr.sh OUTPUT_FORMAT="elf64-loongarch" case "$target" in From patchwork Sat Jun 22 10:03:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92713 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8E39D3828934 for ; Sat, 22 Jun 2024 10:05:46 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 27F15382EF3A for ; Sat, 22 Jun 2024 10:03:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 27F15382EF3A Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 27F15382EF3A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050638; cv=none; b=MlAmw09J13VwCaV/uJXyByM5BwFVztKd4TJaNNEKM6EeqanhvHdfo+ukQpdfCQVzdhgIIc/FfFdp+GD8MNzOYPbQzG8F1D2R/mLiWahYTTM+lO8BYstdAlCMG5dUuEZqEC8CN4XRu7iLuyEwXNNU6fhK8870JwQkqnReVVYhDQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719050638; c=relaxed/simple; bh=XLwEgI+LzwhB66YDWwaSrISftepDvCbnJTaJrwIhmO0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=wmtnG8t3zOg2Vb1pLZRdPckFDVez5d7StSYgU/QL58UesrGhkWT6JW9pRljrC+9ogNBGw5pBecsOqKHmWiTlM6Ba7aydZ5ao/4BQIwqgFMxSnFiw/B9S3Jiu+E0V4MPMxhjabOii/jmg+OwcW4H10DaU/V6HvQrFE7+McxLqPok= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719050632; bh=XLwEgI+LzwhB66YDWwaSrISftepDvCbnJTaJrwIhmO0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bXsHspzWnrpxq/YlVkuRMJk05Ug+G5GAU/CIQhn1oNTcmmAGtDGgtqcY6rWWfw/sV bm1yU/cjuN3FmqLnFATRYjnYR1rezhzZ24VdHZsVzIgEJoupKUEiOM6GMzI23oBb1+ tK13ZEY3w/o+yyJ2CU3MuQNCvIAtrl5b6GgWcgH0= Received: from stargazer.. (unknown [113.200.174.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 1D279670EE; Sat, 22 Jun 2024 06:03:50 -0400 (EDT) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Zhensong Liu , i.swmail@xen0n.name, maskray@google.com, Szabolcs Nagy , Xi Ruoyao Subject: [PATCH 5/5] LoongArch: Add DT_RELR tests Date: Sat, 22 Jun 2024 18:03:07 +0800 Message-ID: <20240622100307.9498-6-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240622100307.9498-1-xry111@xry111.site> References: <20240622100307.9498-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+patchwork=sourceware.org@sourceware.org Signed-off-by: Xi Ruoyao --- .../ld-loongarch-elf/ld-loongarch-elf.exp | 10 ++ ld/testsuite/ld-loongarch-elf/relr-addend.d | 11 ++ ld/testsuite/ld-loongarch-elf/relr-addend.s | 17 +++ ld/testsuite/ld-loongarch-elf/relr-align.d | 22 ++++ ld/testsuite/ld-loongarch-elf/relr-align.s | 106 ++++++++++++++++++ ld/testsuite/ld-loongarch-elf/relr-data-pie.d | 18 +++ .../ld-loongarch-elf/relr-data-shared.d | 18 +++ ld/testsuite/ld-loongarch-elf/relr-data.s | 71 ++++++++++++ .../ld-loongarch-elf/relr-discard-pie.d | 8 ++ .../ld-loongarch-elf/relr-discard-shared.d | 11 ++ ld/testsuite/ld-loongarch-elf/relr-discard.ld | 13 +++ ld/testsuite/ld-loongarch-elf/relr-discard.s | 61 ++++++++++ ld/testsuite/ld-loongarch-elf/relr-got-pie.d | 15 +++ .../ld-loongarch-elf/relr-got-shared.d | 15 +++ ld/testsuite/ld-loongarch-elf/relr-got.s | 27 +++++ ld/testsuite/ld-loongarch-elf/relr-relocs.ld | 24 ++++ ld/testsuite/ld-loongarch-elf/relr-text-pie.d | 14 +++ .../ld-loongarch-elf/relr-text-shared.d | 14 +++ ld/testsuite/ld-loongarch-elf/relr-text.s | 10 ++ 19 files changed, 485 insertions(+) create mode 100644 ld/testsuite/ld-loongarch-elf/relr-addend.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-addend.s create mode 100644 ld/testsuite/ld-loongarch-elf/relr-align.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-align.s create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data-pie.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data-shared.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data.s create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard-pie.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard-shared.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard.ld create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard.s create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-pie.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-shared.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got.s create mode 100644 ld/testsuite/ld-loongarch-elf/relr-relocs.ld create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text-pie.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text-shared.d create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text.s diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 3172a0ab4b5..4791d272115 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -142,10 +142,20 @@ if [istarget "loongarch64-*-*"] { run_dump_test "r_larch_32_elf64" run_dump_test "ifunc-reloc" run_dump_test "protected-func" + run_dump_test "relr-addend" + run_dump_test "relr-align" + run_dump_test "relr-data-shared" + run_dump_test "relr-discard-shared" + run_dump_test "relr-got-shared" + run_dump_test "relr-text-shared" } if [check_pie_support] { run_dump_test "pie_discard" + run_dump_test "relr-data-pie" + run_dump_test "relr-discard-pie" + run_dump_test "relr-got-pie" + run_dump_test "relr-text-pie" } run_dump_test "max_imm_b16" diff --git a/ld/testsuite/ld-loongarch-elf/relr-addend.d b/ld/testsuite/ld-loongarch-elf/relr-addend.d new file mode 100644 index 00000000000..da13c2cf823 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-addend.d @@ -0,0 +1,11 @@ +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#objdump: -s -j.got -j.data + +.*: file format elf64-loongarch + +Contents of section \.got: + 20000 [0-9a-f]+ [0-9a-f]+ 00003412 00000000 .* + 20010 08003412 00000000 .* +Contents of section \.data: + 12340000 14451100 00000000 10989101 00000000 .* + 12340010 00003412 00000000 08003412 00000000 .* diff --git a/ld/testsuite/ld-loongarch-elf/relr-addend.s b/ld/testsuite/ld-loongarch-elf/relr-addend.s new file mode 100644 index 00000000000..3d08f6ca0ae --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-addend.s @@ -0,0 +1,17 @@ +.data +.align 8 +x: + .quad 0x114514 +y: + .quad 0x1919810 +px: + .quad x +py: + .quad y + +.text +.align 2 +_start: + la.got $a0, x + la.got $a1, y + ret diff --git a/ld/testsuite/ld-loongarch-elf/relr-align.d b/ld/testsuite/ld-loongarch-elf/relr-align.d new file mode 100644 index 00000000000..d534243b2a5 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-align.d @@ -0,0 +1,22 @@ +#source: relr-align.s +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '\.rela.dyn' at offset 0x[0-9a-f]+ contains 3 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000012340011 0000000000000003 R_LARCH_RELATIVE 10000 +0000000012340019 0000000000000003 R_LARCH_RELATIVE 10000 +0000000012340041 0000000000000003 R_LARCH_RELATIVE 10000 + +Relocation section '\.relr.dyn' at offset 0x[0-9a-f]+ contains 9 entries which relocate 10 locations: +Index: Entry Address Symbolic Address +0000: 0000000012340000 0000000012340000 double_0 +0001: 0000000000000003 0000000012340008 double_0 \+ 0x8 +0002: 0000000012340022 0000000012340022 double_2 +0003: 0000000000000003 000000001234002a double_2 \+ 0x8 +0004: 0000000012340038 0000000012340038 single_0 +0005: 000000001234004a 000000001234004a single_2 +0006: 0000000012340058 0000000012340058 big +0007: 8000000100000001 0000000012340158 big \+ 0x100 + 0000000012340250 big \+ 0x1f8 +0008: 0000000000000003 0000000012340258 big \+ 0x200 diff --git a/ld/testsuite/ld-loongarch-elf/relr-align.s b/ld/testsuite/ld-loongarch-elf/relr-align.s new file mode 100644 index 00000000000..ddd055ab74e --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-align.s @@ -0,0 +1,106 @@ +# Test DT_RELR with differently aligned relative relocs. + +.text +.global _start +_start: +foo: + +.data +.p2align 3 +double_0: +.quad foo +.quad foo +.byte 0 +double_1: +.quad foo +.quad foo +.byte 0 +double_2: +.quad foo +.quad foo +.byte 0 +.byte 0 +.byte 0 +.byte 0 +.byte 0 +.byte 0 +single_0: +.quad foo +.byte 0 +single_1: +.quad foo +.byte 0 +single_2: +.quad foo +.byte 0 +.byte 0 +.byte 0 +.byte 0 +.byte 0 +.byte 0 +big: +.quad foo +.quad 1 +.quad 2 +.quad 3 +.quad 4 +.quad 5 +.quad 6 +.quad 7 +.quad 8 +.quad 9 +.quad 10 +.quad 11 +.quad 12 +.quad 13 +.quad 14 +.quad 15 +.quad 16 +.quad 17 +.quad 18 +.quad 19 +.quad 20 +.quad 21 +.quad 22 +.quad 23 +.quad 24 +.quad 25 +.quad 26 +.quad 27 +.quad 28 +.quad 29 +.quad 30 +.quad 31 +.quad foo + 32 +.quad 33 +.quad 34 +.quad 35 +.quad 36 +.quad 37 +.quad 38 +.quad 39 +.quad 40 +.quad 41 +.quad 42 +.quad 43 +.quad 44 +.quad 45 +.quad 46 +.quad 47 +.quad 48 +.quad 49 +.quad 50 +.quad 51 +.quad 52 +.quad 53 +.quad 54 +.quad 55 +.quad 56 +.quad 57 +.quad 58 +.quad 59 +.quad 60 +.quad 61 +.quad 62 +.quad foo + 63 +.quad foo + 64 diff --git a/ld/testsuite/ld-loongarch-elf/relr-data-pie.d b/ld/testsuite/ld-loongarch-elf/relr-data-pie.d new file mode 100644 index 00000000000..20ef9ac1c84 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-data-pie.d @@ -0,0 +1,18 @@ +#source: relr-data.s +#ld: -pie -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 5 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000012340000 0000000000000003 R_LARCH_RELATIVE 10004 +0000000012340008 0000000000000003 R_LARCH_RELATIVE 10008 +0000000012340010 0000000000000003 R_LARCH_RELATIVE 1000c +0000000012340018 0000000000000003 R_LARCH_RELATIVE 12340050 +0000000012340040 0000000c00000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0 + +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 4 locations: +Index: Entry Address Symbolic Address +0000: 0000000012340020 0000000012340020 aligned_local +0001: 0000000000000027 0000000012340028 aligned_hidden + 0000000012340030 aligned_global + 0000000012340048 aligned_DYNAMIC diff --git a/ld/testsuite/ld-loongarch-elf/relr-data-shared.d b/ld/testsuite/ld-loongarch-elf/relr-data-shared.d new file mode 100644 index 00000000000..37e4c0da83e --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-data-shared.d @@ -0,0 +1,18 @@ +#source: relr-data.s +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 6 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000012340000 0000000000000003 R_LARCH_RELATIVE 10004 +0000000012340008 0000000000000003 R_LARCH_RELATIVE 10008 +0000000012340018 0000000000000003 R_LARCH_RELATIVE 12340050 +0000000012340010 0000000d00000002 R_LARCH_64 000000000001000c sym_global \+ 0 +0000000012340030 0000000d00000002 R_LARCH_64 000000000001000c sym_global \+ 0 +0000000012340040 0000000c00000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0 + +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 3 locations: +Index: Entry Address Symbolic Address +0000: 0000000012340020 0000000012340020 aligned_local +0001: 0000000000000023 0000000012340028 aligned_hidden + 0000000012340048 aligned_DYNAMIC diff --git a/ld/testsuite/ld-loongarch-elf/relr-data.s b/ld/testsuite/ld-loongarch-elf/relr-data.s new file mode 100644 index 00000000000..03673e0fbd2 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-data.s @@ -0,0 +1,71 @@ +# Test symbol references in .data when used with DT_RELR. +# Relocations for unaligned sections are currently not packed. + +.text +.global _start +_start: + nop + +sym_local: + nop + +.global sym_hidden +.hidden sym_hidden +sym_hidden: + nop + +.global sym_global +sym_global: + nop + +.global sym_global_abs +.set sym_global_abs, 42 + +.global sym_weak_undef +.weak sym_weak_undef + +.section .data.unaligned_local +unaligned_local: +.quad sym_local + +.section .data.unaligned_hidden +unaligned_hidden: +.quad sym_hidden + +.section .data.unaligned_global +unaligned_global: +.quad sym_global + +.section .data.unaligned_DYNAMIC +unaligned_DYNAMIC: +.quad _DYNAMIC + +.section .data.aligned_local +.p2align 1 +aligned_local: +.quad sym_local + +.section .data.aligned_hidden +.p2align 1 +aligned_hidden: +.quad sym_hidden + +.section .data.aligned_global +.p2align 1 +aligned_global: +.quad sym_global + +.section .data.aligned_global_abs +.p2align 1 +aligned_global_abs: +.quad sym_global_abs + +.section .data.aligned_weak_undef +.p2align 1 +aligned_weak_undef: +.quad sym_weak_undef + +.section .data.aligned_DYNAMIC +.p2align 1 +aligned_DYNAMIC: +.quad _DYNAMIC diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d b/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d new file mode 100644 index 00000000000..4ea8ae5e7b4 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d @@ -0,0 +1,8 @@ +#source: relr-discard.s +#ld: -pie -z pack-relative-relocs -T relr-discard.ld +#readelf: -rW + +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 2 locations: +Index: Entry Address Symbolic Address +0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8 +0001: 0000000000000003 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10 diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d b/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d new file mode 100644 index 00000000000..8bfd8ba5add --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d @@ -0,0 +1,11 @@ +#source: relr-discard.s +#ld: -shared -z pack-relative-relocs -T relr-discard.ld +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 1 entry: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000000020010 0000000300000002 R_LARCH_64 000000000001000c sym_global \+ 0 + +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 1 entry which relocates 1 location: +Index: Entry Address Symbolic Address +0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8 diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard.ld b/ld/testsuite/ld-loongarch-elf/relr-discard.ld new file mode 100644 index 00000000000..165f1ed2f11 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-discard.ld @@ -0,0 +1,13 @@ +OUTPUT_ARCH(loongarch64) +ENTRY(_start) +SECTIONS +{ + /DISCARD/ : { *(.discard.*) } + + . = 0x10000; + .text : { *(.text) } + . = 0x20000; + .got : { *(.got) *(.got.plt)} + . = 0x30000; + .data : { *(.data) *(.data.*) } +} diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard.s b/ld/testsuite/ld-loongarch-elf/relr-discard.s new file mode 100644 index 00000000000..b52374a5498 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-discard.s @@ -0,0 +1,61 @@ +# Test DT_RELR with references in discarded sections. + +.text +.p2align 3 +.global _start +_start: + nop + +sym_local: + nop + +.global sym_hidden +.hidden sym_hidden +sym_hidden: + nop + +.global sym_global +sym_global: + nop + +.global sym_global_abs +.set sym_global_abs, 42 + +.global sym_weak_undef +.weak sym_weak_undef + +.section .discard.got_local,"ax" + la.got $a0, sym_local + +.section .discard.got_global,"ax" + la.got $a0, sym_global + +.section .discard.local,"a" +.p2align 1 +discard_local: +.quad sym_local + +.section .discard.hidden,"a" +.p2align 1 +discard_hidden: +.quad sym_hidden + +.section .discard.global,"a" +.p2align 1 +discard_global: +.quad sym_global + +.section .discard.global_abs,"a" +.p2align 1 +discard_global_abs: +.quad sym_global_abs + +.section .discard.weak_undef,"a" +.p2align 1 +discard_weak_undef: +.quad sym_weak_undef + +.section .discard._DYNAMIC,"a" +.p2align 1 +discard_DYNAMIC: +.quad _DYNAMIC diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-pie.d b/ld/testsuite/ld-loongarch-elf/relr-got-pie.d new file mode 100644 index 00000000000..e994f2bfe01 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-got-pie.d @@ -0,0 +1,15 @@ +#source: relr-got.s +#ld: -pie -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000000000000 0000000000000000 R_LARCH_NONE 0 +0000000000020030 0000000200000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0 + +Relocation section '.relr.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 4 locations: +Index: Entry Address Symbolic Address +0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8 +0001: 000000000000000f 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10 + 0000000000020018 _GLOBAL_OFFSET_TABLE_ \+ 0x18 + 0000000000020020 _GLOBAL_OFFSET_TABLE_ \+ 0x20 diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-shared.d b/ld/testsuite/ld-loongarch-elf/relr-got-shared.d new file mode 100644 index 00000000000..169e0e5d69d --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-got-shared.d @@ -0,0 +1,15 @@ +#source: relr-got.s +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 3 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +0000000000020020 0000000300000002 R_LARCH_64 0000000000010034 sym_global \+ 0 +0000000000020028 0000000500000002 R_LARCH_64 000000000000002a sym_global_abs \+ 0 +0000000000020030 0000000200000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0 + +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 3 locations: +Index: Entry Address Symbolic Address +0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8 +0001: 0000000000000007 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10 + 0000000000020018 _GLOBAL_OFFSET_TABLE_ \+ 0x18 diff --git a/ld/testsuite/ld-loongarch-elf/relr-got.s b/ld/testsuite/ld-loongarch-elf/relr-got.s new file mode 100644 index 00000000000..162528bc7e6 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-got.s @@ -0,0 +1,27 @@ +.text +.global _start +_start: + la.got $a0, sym_local + la.got $a1, sym_hidden + la.got $a2, sym_global + la.got $a3, sym_global_abs + la.got $a4, sym_weak_undef + la.got $a5, _DYNAMIC + +sym_local: + nop + +.global sym_hidden +.hidden sym_hidden +sym_hidden: + nop + +.global sym_global +sym_global: + nop + +.global sym_global_abs +.set sym_global_abs, 42 + +.global sym_weak_undef +.weak sym_weak_undef diff --git a/ld/testsuite/ld-loongarch-elf/relr-relocs.ld b/ld/testsuite/ld-loongarch-elf/relr-relocs.ld new file mode 100644 index 00000000000..ed83275b629 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-relocs.ld @@ -0,0 +1,24 @@ +/* Script for DT_RELR tests */ +OUTPUT_ARCH(loongarch64) +ENTRY(_start) +SECTIONS +{ + PROVIDE (__executable_start = 0x8000); . = 0x10000; + .text : + { + *(.before) + *(.text) + *(.after) + } =0 + . = 0x20000; + .got : + { + *(.got) + *(.got.plt) + } + . = 0x12340000; + .data : + { + *(.data) + } +} diff --git a/ld/testsuite/ld-loongarch-elf/relr-text-pie.d b/ld/testsuite/ld-loongarch-elf/relr-text-pie.d new file mode 100644 index 00000000000..8e34500fbd2 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-text-pie.d @@ -0,0 +1,14 @@ +#source: relr-text.s +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#readelf: -drW + +#... + 0x0000000000000016 \(TEXTREL\) 0x0 +#... + 0x0000000000000024 \(RELR\) .* + 0x0000000000000023 \(RELRSZ\) 8 \(bytes\) + 0x0000000000000025 \(RELRENT\) 8 \(bytes\) +#... +Relocation section '\.relr\.dyn' .* contains 1 entry which relocates 1 location: +Index: Entry Address Symbolic Address +0000: 0000000000010000 0000000000010000 _start diff --git a/ld/testsuite/ld-loongarch-elf/relr-text-shared.d b/ld/testsuite/ld-loongarch-elf/relr-text-shared.d new file mode 100644 index 00000000000..8e34500fbd2 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-text-shared.d @@ -0,0 +1,14 @@ +#source: relr-text.s +#ld: -shared -z pack-relative-relocs -T relr-relocs.ld +#readelf: -drW + +#... + 0x0000000000000016 \(TEXTREL\) 0x0 +#... + 0x0000000000000024 \(RELR\) .* + 0x0000000000000023 \(RELRSZ\) 8 \(bytes\) + 0x0000000000000025 \(RELRENT\) 8 \(bytes\) +#... +Relocation section '\.relr\.dyn' .* contains 1 entry which relocates 1 location: +Index: Entry Address Symbolic Address +0000: 0000000000010000 0000000000010000 _start diff --git a/ld/testsuite/ld-loongarch-elf/relr-text.s b/ld/testsuite/ld-loongarch-elf/relr-text.s new file mode 100644 index 00000000000..47465f2d8c4 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-text.s @@ -0,0 +1,10 @@ +# Test DT_RELR with DT_TEXTREL and R_LARCH_ALIGN. + +.text +.p2align 5 +.global _start +_start: +.global foo +.hidden foo +foo: +.quad foo