From patchwork Wed Jun 26 10:04:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92876 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 224E33861828 for ; Wed, 26 Jun 2024 10:06:00 +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 3CE36384DEE3 for ; Wed, 26 Jun 2024 10:05:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3CE36384DEE3 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 3CE36384DEE3 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=1719396322; cv=none; b=c6prBtegG1rmfJNAkT8MShoOC7kMP1E08HHzt/o3kZldxZ0ALbl3sF6maDBgdIIoNF+/NPb5PYrsl5ToRUAYs1wXMET+Emh/NBGiv0TF1J+++7VNTqwg3UFS9d+IsjKq1rdLJOnZ7F0EpfCXDLPAzah+OTN/j+j3ZpcaX38ifnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719396322; c=relaxed/simple; bh=AC+e8pqGRa+WjwZsOeWmgpI8ed5DN4cakZQi0Dh/rm0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Qkcp4pIdV1hq8G82unQz9B4fIndaA7EJmAKTXxHTuD/Ogam7oRIUrldpGLlkXiljB6QvASYvyRQ9R1nuROYIfqdz2tFOstpP5E+OnQW1zXwk/BnlzjC38QljiRNdrZ0KsdoPLKaMOiFC40rWG7apDAjXvQs8M3Uf3NcWnn7KeLE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719396312; bh=AC+e8pqGRa+WjwZsOeWmgpI8ed5DN4cakZQi0Dh/rm0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ivaXYhu85fD2M9kg1yJ+GN6DkIeGeZeAaBS6C+vvXLgkYwHRjHqhRu18W0qGuvFhV 3iov5dmG4ODU1Pl9grX07atf6D8nCz/41jh/T/zUxhM1AXDhQmpNPuTltwuc8qd/sz NF2yEWsQmDTYDIyrnwxiiijGKU7DpOCt8OvtKB1I= Received: from stargazer.. (unknown [113.200.174.20]) (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 462AE66D68; Wed, 26 Jun 2024 06:05:10 -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 v2 1/5] LoongArch: Reject R_LARCH_32 from becoming a runtime reloc in ELFCLASS64 Date: Wed, 26 Jun 2024 18:04:50 +0800 Message-ID: <20240626100453.98946-3-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626100453.98946-2-xry111@xry111.site> References: <20240626100453.98946-2-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.9 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 .4byte 0xdeadbeef $ as/as-new t.s -o t.o $ ld/ld-new -shared t.o $ 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, clobbering the next 4 bytes of data ("0xdeadbeef" in the example). If we keep the R_LARCH_32 reloc as-is in ELFCLASS64, it'll be rejected by the Glibc dynamic linker anyway. And it does not make too much sense to modify Glibc to support it. So we can just reject it like x86_64: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC or RISC-V: relocation R_RISCV_32 against non-absolute symbol `a local symbol' can not be used in RV64 when making a shared object" 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 2d67c4f2668..4d9f4aebaff 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -132,6 +132,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 Wed Jun 26 10:04:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92877 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 C4D1A387089C for ; Wed, 26 Jun 2024 10:06:14 +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 2E746384AB57 for ; Wed, 26 Jun 2024 10:05:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2E746384AB57 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 2E746384AB57 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=1719396322; cv=none; b=U6b2hm+d3M6k7nKwo42nrv+Ga9AtIYL+dSte2CN2JMYpDcMoVJ3AWOQFpf76SyAiXZtXxG1WizpJ/c2Rzc/OWidAF0r+T7PNChLtEnxWlgNGPSjCTLb31BNFM+QusbHjDW0peHR/srucLBeSfOBaP2Mym1Z6QB8BWx5BI4MKUpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719396322; c=relaxed/simple; bh=UvRej48J6Y+aGWapzfSL1KBUY9UOaw8n1znEm0mpN1s=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=mVHc1kra9PlWkKdg711JfDVBT3jYvKap5XGJVDmolk+/+VzJXN+4MSQ3SlVSjDWfEdoEbp6XOqOsn5Dw3ayoO7kusxcrpZsL22scs5GdV0KeHulNw1Yw0KqEwM43SoKwYmtaQ1HHMQEkzpcjj23wmxyoURGQXKTtWa6WNpP5O9M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719396314; bh=UvRej48J6Y+aGWapzfSL1KBUY9UOaw8n1znEm0mpN1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lv4QQJyEapocpHuGSZ93EaYGRooQ7ob5gYNvHNF3s048g5CJ4IsTNLS9og8iCiHQq ktYrVpP0SabHydUhuHZ6krrHyPe6ajJgBlmq+eUoAjTKD0ZI+shzu+gFYVxzMB1d8E WDxFOxZ9umUt9zGDZzgXPLL5LYmO7ELrOa7xouqM= Received: from stargazer.. (unknown [113.200.174.20]) (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 8598B66D69; Wed, 26 Jun 2024 06:05:12 -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 v2 2/5] LoongArch: Fix bad reloc with mixed visibility ifunc symbols in shared libraries Date: Wed, 26 Jun 2024 18:04:51 +0800 Message-ID: <20240626100453.98946-4-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626100453.98946-2-xry111@xry111.site> References: <20240626100453.98946-2-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.3 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..c02e3f4bd9c 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 + *preemptible* ifunc sym dynamic relocs. Note that we must do it + for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN + ifuncs) before doing it for any non-preemptible 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 4d9f4aebaff..6cff117e29b 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -133,6 +133,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 Wed Jun 26 10:04:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92880 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 13DE03870F2D for ; Wed, 26 Jun 2024 10:07:32 +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 2AB55384AB77 for ; Wed, 26 Jun 2024 10:05:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2AB55384AB77 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 2AB55384AB77 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=1719396324; cv=none; b=ND9RxYg42vFiCa2ME6bFcLZz8Ub+Gty4wKVatqSQ5ZwvuhLAXN0zTapQoopC55c+PcaOcrIZCaxvf7H+5nWIE/t8s88YDL41UFu/xta3We1W19+Vyqf79KF8Fu14l0y4TcvbPy1cRgxlue2tzAWpDdlevOdtLFpBmQxDzC0RAJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719396324; c=relaxed/simple; bh=/RWTV0tpWHoCxxX+yZe9PXSPWUjvaI3wyKpuml2hWyI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=gb+4+AOUba7n5aHN4mai8TCgbWV5BtLjE/23yCi8/pX6mHju4+5BYeoIpf/LOwJdOZ9+p8uy+PTyaTH3MygXuNUWJ24ZeA4pmhApDtPMIm4l0hKSXDKB9Lgtjn10OhXQH8KO9wD9MHimdUI3flxrdTWh8mcCjTIqYFm4JO2BMy8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719396316; bh=/RWTV0tpWHoCxxX+yZe9PXSPWUjvaI3wyKpuml2hWyI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eGsHC+8BqwunHFoDFQG+IOkx96kPdPnEOxyAX/u0zojCFAuFj138bBPL0faUPCQjo 411VLCFOlCAKz7TKmnZJ6NXVXe/Tw+hFroTsml1398BoKYyVIXxZZyY+O0RsibEycq /0e/98as/SmlKFZ3r8udWx98wpkWwCLAP29rE5gw= Received: from stargazer.. (unknown [113.200.174.20]) (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 C135E66D6A; Wed, 26 Jun 2024 06:05:14 -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 v2 3/5] LoongArch: Make protected function symbols local for -shared Date: Wed, 26 Jun 2024 18:04:52 +0800 Message-ID: <20240626100453.98946-5-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626100453.98946-2-xry111@xry111.site> References: <20240626100453.98946-2-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.0 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 preemptible. See the comment above LARCH_REF_LOCAL for detailed explanation. Signed-off-by: Xi Ruoyao --- bfd/elfnn-loongarch.c | 76 ++++++++++++++----- 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, 81 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 c02e3f4bd9c..1a84b88320b 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -181,6 +181,44 @@ 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 a PLT entry when someone attempts to la.pcrel an external + function. But we never really implemented "R_LARCH_COPY", thus we've + never supported la.pcrel an external symbol unless the loaded address is + only used for locating a function to be called. Thus the PLT entry is + a normal PLT entry, not intended to be a so-called "canonical PLT entry" + on the ports supporting copy relocation. So attempting to la.pcrel an + external function will just break pointer equality, even it's 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=. -fpie -pie + $ ./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 +750,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 +1234,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 +1752,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 +1787,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 +2699,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 +2824,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 +2913,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 +3282,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 +3427,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 +3438,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 +3471,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 +3673,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 +4214,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 +4926,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 +5063,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 +5079,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 +5167,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 +5204,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 6cff117e29b..9a668fb7164 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -134,6 +134,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..8f28f9254a4 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/protected-func.s @@ -0,0 +1,17 @@ +# protected function should be non-preemptible 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 Wed Jun 26 10:04:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92878 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 7473E3870C15 for ; Wed, 26 Jun 2024 10:06: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 27D04384AB6E for ; Wed, 26 Jun 2024 10:05:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 27D04384AB6E 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 27D04384AB6E 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=1719396325; cv=none; b=YU3t+x/AJkvp3IGs3jbLpx+V8hpMxkYbqI+XFVYtghh/2gh3Xhj+i/eaT8wWAf7XKpZnvSC5y0ZPU3DZBt5w9A7TCUJ9eWEHAr1+BFecw8lZjiKVYMfDkIqxofk7Am9dx5X2PNP1HnHsrWcC/6zLn7xmICnbsYqlnEHE+MtCDqI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719396325; c=relaxed/simple; bh=xRw8DkS6r+hklxZSSd6gf2G1230VENW/gXbVkvFEId0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=QeECaIdprkwc9+crqszgzpjI5M1csXmo3SVqDHUFTDqxA6egNOrorAFo26EHWmziCSNVhURGcOeiix+2AppMllO5cE6LpwJHq/C9l/Nj+rJref9qivFwkHnaQWLcs4hqJGQH/Tr7fgzyKz26FtuihlQ93PbpoWK6jmXWkv57B8Y= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719396318; bh=xRw8DkS6r+hklxZSSd6gf2G1230VENW/gXbVkvFEId0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SqhU/lmHFDo3nanTUeh8pU4DvQOZMgKioBoqM++gUcgWHE2J/CWCOJSDGJ8+Sshpb VcZ8d1Miav8wtwUGoTR+Svx7F5heZqyWtFz6j6V3zpfFp9GWU05Z7/EbWwg4ICrLK8 6VjMTICcp374UPUSAh7xIj5huhFu+Gem3wXrXkT0= Received: from stargazer.. (unknown [113.200.174.20]) (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 23A7D66D6B; Wed, 26 Jun 2024 06:05:16 -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 v2 4/5] LoongArch: Add DT_RELR support Date: Wed, 26 Jun 2024 18:04:53 +0800 Message-ID: <20240626100453.98946-6-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626100453.98946-2-xry111@xry111.site> References: <20240626100453.98946-2-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.8 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 1a84b88320b..f501589bc70 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 \ @@ -927,6 +975,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: @@ -1118,6 +1180,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; } @@ -1832,6 +1908,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) @@ -2012,6 +2424,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. */ @@ -2036,6 +2466,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. */ @@ -2968,6 +3406,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); @@ -3695,7 +4144,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; @@ -4107,6 +4556,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; @@ -4119,6 +4576,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++) { @@ -5207,9 +5669,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 { @@ -5220,6 +5691,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) @@ -5673,6 +6145,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 f0136577b6c..ce7413a77e5 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 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 Wed Jun 26 10:04:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 92879 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 B596A3870C3C for ; Wed, 26 Jun 2024 10:07:19 +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 B8A7B387085A for ; Wed, 26 Jun 2024 10:05:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B8A7B387085A 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 B8A7B387085A 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=1719396326; cv=none; b=wXq6FEHLcO4NhQokxSM82F45Og7dMYRBmUH49GW4x3GXI8vyL50aJLU/qqp13Oxq8rgOIHSN6RauVaCSXuc1ajCPER9QaAPeFaw9iX0H1DeUUdeh9jDMYAvcYxgU8/4kn7cdFhNBnC0TAQEvVUcH/0r+B57pHNxWnoKSi6VEa7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719396326; c=relaxed/simple; bh=mYZOIdRCSP4qlsyHSoy0rkr1HqW2zzp6m9QY6gPGUd8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=w0jFelU7LZeHD383a16Ji3wOlvdUFwYMnnheAtnzsIn2c5suYM5VAbfOvKpn4yApeCYrR1ZMqvZ0JgSYG1gUii4DQVl4xIG5i3mUNExGBRMYAeGW/C58DRAUo+Jh/NRLvfs8Wfspb2Br5kLUyIFzLrw+ZkLdj8vaoObFpCGT+Zc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719396321; bh=mYZOIdRCSP4qlsyHSoy0rkr1HqW2zzp6m9QY6gPGUd8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e4/Vo26rPC/hPgtF5LOoZ6uiYfvypzZz4BYBd/9x/VG1w9sUauRD+km+q9Kv4yK6/ a/Ik4PBSRWOKNbL0+O9BJILzoCufAjntq/BdDZSMWPOMkb3sPRm4YI41UrpfgelW64 sr5gEnKTmpRKJQZbhVyMkxAZecsMxV6GHGJxI9+0= Received: from stargazer.. (unknown [113.200.174.20]) (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 617E066D6C; Wed, 26 Jun 2024 06:05:19 -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 v2 5/5] LoongArch: Add DT_RELR tests Date: Wed, 26 Jun 2024 18:04:54 +0800 Message-ID: <20240626100453.98946-7-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626100453.98946-2-xry111@xry111.site> References: <20240626100453.98946-2-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.9 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 Most tests are ported from AArch64. The relr-addend test is added to make sure the addend (link-time address) is correctly written into the relocated section. Doing so is not strictly needed for RELA, but strictly needed for RELR). 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 9a668fb7164..4606ede9fc0 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -135,10 +135,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