From patchwork Sun Jun 30 07:18:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 93084 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 8CBD53836E88 for ; Sun, 30 Jun 2024 07:19:28 +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 068793858429 for ; Sun, 30 Jun 2024 07:18:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 068793858429 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 068793858429 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=1719731929; cv=none; b=iflwi7wGD/XenvDKAoZjqYP90EA8TniyMs2QjbgLxXibMrYqBEjWNolFACKaqFy9VbKV/IM+QwUUojGj/MwJjk4N9ODRGMdomyUpNrlvK52C3lj3at2JXtTYZtaNf43K9BSBOEgC2SY1YJcJFF/ZwbbCl2/xIrL+h/oCwF29JrU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719731929; c=relaxed/simple; bh=kAp8BWcNuXLTpkambD90Dxmz1O9qWRLmoHclRlKERdE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=BICREQxeS1RnmQxhP38S6WrvP+NFa3Vyuz8g2Mlau8ZjVmtUKgZExKiXkRRaVXbhhwaAOraMxIlPDWx8itUGg94xh7pgbJKEzlzK6Cm7Kewj4AOnyj9219ppRMQgdnoCGs07Kyiq/nYYRjETQXBOrDNBZceMpgL0XSg+DnEP2Qc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719731918; bh=kAp8BWcNuXLTpkambD90Dxmz1O9qWRLmoHclRlKERdE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V6RzC26hiHt7JqtDjtZ3gwAtryR0Y8C/RUb6UXLvXIEiDH1M1kHFAwnPhyKbZU6/2 pOwfDgovJqnvMNs5+DlzgNyhK98lGWt4ZvXN/CASB4vuTtvIq5vZ11UdSlzBhaX4Tl H4IOESM9hyIXuQZ2JVEFk9i1ZuBCk6n+ggXtCSfo= Received: from stargazer.. (unknown [113.140.11.124]) (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 11D7D1A3EDF; Sun, 30 Jun 2024 03:18:36 -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 v3 1/5] LoongArch: Reject R_LARCH_32 from becoming a runtime reloc in ELFCLASS64 Date: Sun, 30 Jun 2024 15:18:21 +0800 Message-ID: <20240630071825.11172-2-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240630071825.11172-1-xry111@xry111.site> References: <20240630071825.11172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-9.5 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 | 30 +++++++++++++++++-- .../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, 36 insertions(+), 2 deletions(-) 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 da84aabc1ae..41463ea5c75 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -1036,8 +1036,32 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, only_need_pcrel = 1; break; - case R_LARCH_JUMP_SLOT: case R_LARCH_32: + if (ARCH_SIZE > 32 + && bfd_link_pic (info) + && (sec->flags & SEC_ALLOC) != 0) + { + bool is_abs_symbol = false; + + if (r_symndx < symtab_hdr->sh_info) + is_abs_symbol = isym->st_shndx == SHN_ABS; + else + is_abs_symbol = bfd_is_abs_symbol (&h->root); + + if (!is_abs_symbol) + { + _bfd_error_handler + (_("%pB: relocation R_LARCH_32 against non-absolute " + "symbol `%s' cannot be used in ELFCLASS64 when " + "making a shared object or PIE"), + abfd, h ? h->root.root.string : "a local symbol"); + bfd_set_error (bfd_error_bad_value); + return false; + } + } + + /* Fall through. */ + case R_LARCH_JUMP_SLOT: case R_LARCH_64: need_dynreloc = 1; @@ -2859,8 +2883,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, outrel.r_addend = relocation + rel->r_addend; } - /* No alloc space of func allocate_dynrelocs. */ + /* No alloc space of func allocate_dynrelocs. + No alloc space of invalid R_LARCH_32 in ELFCLASS64. */ if (unresolved_reloc + && (ARCH_SIZE == 32 || r_type != R_LARCH_32) && !(h && (h->is_weakalias || !h->dyn_relocs))) loongarch_elf_append_rela (output_bfd, sreloc, &outrel); } 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..3431329569c --- /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 .* cannot be used 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 Sun Jun 30 07:18:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 93085 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 839B238618FF for ; Sun, 30 Jun 2024 07:19: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 85D7A385E836 for ; Sun, 30 Jun 2024 07:18:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 85D7A385E836 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 85D7A385E836 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=1719731929; cv=none; b=GpKCCZvXyUb34RjugQZkuVDr6jyXhbVZErOe4Gv3RKfHIGlJDRU68SnkgxK3+65EgB4ZCN+ibSEfMSb3QixNcG4ycSHV4RUW5nA9gwsWoUbcyPDFOdjeGMMLVT/rx+sZ2ALAfr2ASmMHMUh99pzIjE4+s3o7zHCRHnvqWPeBnNM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719731929; c=relaxed/simple; bh=AYI9R6qUPyKOpLEpDrd4QxqtJ0aUfbnpiYB40DH7HII=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=tS5CMPeOgNS3KUTlXvIq3Gw4J6Lvq7UkF6gsI/uo9Gh/ELcxMjlC419WkAdy/qgpaqy9+dZ5JQpjNwSa6j/pVGDcGsNlWJVK+kjcZHsG5Hx2LEOpXxZrgeLAnIGUK9ULRfdf5mZ1cfzCGwUGgQZznqznUDki5UcCcD2Gs5QsN40= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719731920; bh=AYI9R6qUPyKOpLEpDrd4QxqtJ0aUfbnpiYB40DH7HII=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f0mQWUa+YO2Qu8quZZSYtvfPCrQqlZ4bS8sRVgNyWjw4myWkojj8JiEhoICJ71vsq c4pROIwH3kbJugFjuPDWwaP2gT3H9NZ8G2heTuAHFdLt+kuFRzUpYrq9/K0jUHnKxO KEfooelobPmlZbgxV2n6pUdmqcQ4SoJC8pCMqfWk= Received: from stargazer.. (unknown [113.140.11.124]) (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 3C12B1A3EE0; Sun, 30 Jun 2024 03:18:39 -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 v3 2/5] LoongArch: Fix bad reloc with mixed visibility ifunc symbols in shared libraries Date: Sun, 30 Jun 2024 15:18:22 +0800 Message-ID: <20240630071825.11172-3-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240630071825.11172-1-xry111@xry111.site> References: <20240630071825.11172-1-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, 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 41463ea5c75..bcb144357ff 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -1716,9 +1716,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) @@ -1734,20 +1735,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, @@ -1759,6 +1758,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. */ @@ -1774,7 +1790,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 @@ -1934,11 +1950,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); + + /* Next hidden_ifuncs follows. */ + 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 Sun Jun 30 07:18:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 93086 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 D13C53835406 for ; Sun, 30 Jun 2024 07:20:37 +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 A1C3A386075E for ; Sun, 30 Jun 2024 07:18:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A1C3A386075E 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 A1C3A386075E 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=1719731929; cv=none; b=md+XWwn8jd2jUXU7y0RN/hEydUUyALo25cLrRJy2DlQvntKO4O8KEv0ajzUImW9IH1HNIjoqboZDglm5zEUlYUvAQT3p5iMO+P7jJ8qTPtEkEldZF51bBpYuBvlTTANG8fpL2HCUlUXSWqJ0wLTexAjQEDGL9nTbBYz+QpWr/gc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719731929; c=relaxed/simple; bh=+E5UcJ8YmGzTxhZQaHjvyNrJPFWhkf93WHdAsz2BUhI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=BaUiFj/d+Z1K5Wb92RrheadQTemav372BYaCa6nMp0xdpILGkWMk4rRQy/cRyfJI1q1ReMIfKdUfP5/NqjNZZmStds1GQTckqq99iD/9GrevPIpakRzFkz0E6NRWui0NgAkExXsIHCq7fDMOTEpYtoO+WvrKu0krG2DAI65qeDE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719731922; bh=+E5UcJ8YmGzTxhZQaHjvyNrJPFWhkf93WHdAsz2BUhI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qet8cpC9zSI2oKWIznOg3PIRMyaOGqH5ZD86AAXjWx7ZZJkM9pDbufoTxdyKQl44M SaN8ndqvfjgpjRucMCpjVmDBq6Gol17Y4jrXmY7fV5CG78+ealW21itfzvuOEG42L8 YBXgablH6i9ssIhTh9eZ9VCnzeRNQCF6DRVp/r9s= Received: from stargazer.. (unknown [113.140.11.124]) (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 2F3761A3FF3; Sun, 30 Jun 2024 03:18: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 v3 3/5] LoongArch: Make protected function symbols local for -shared Date: Sun, 30 Jun 2024 15:18:23 +0800 Message-ID: <20240630071825.11172-4-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240630071825.11172-1-xry111@xry111.site> References: <20240630071825.11172-1-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, 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 bcb144357ff..fa8ed1feb29 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) { @@ -1221,7 +1259,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)))) { @@ -1739,14 +1777,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, @@ -1774,7 +1812,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. */ @@ -2687,7 +2724,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, @@ -2813,7 +2849,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; } @@ -2902,7 +2938,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) @@ -3252,7 +3288,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 @@ -3397,7 +3433,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 @@ -3408,7 +3444,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)) @@ -3441,7 +3477,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)) @@ -3643,7 +3679,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; @@ -4184,7 +4220,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); @@ -4896,7 +4932,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; } @@ -5033,12 +5069,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; @@ -5049,7 +5085,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; @@ -5137,7 +5173,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); @@ -5174,7 +5210,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 Sun Jun 30 07:18:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 93088 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 F1D4A3830B4B for ; Sun, 30 Jun 2024 07:20:50 +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 B230F3861806 for ; Sun, 30 Jun 2024 07:18:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B230F3861806 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 B230F3861806 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=1719731929; cv=none; b=fXqjMFw1t2OBogX2eJPKeneuud9FlA61+w6qZ7L4U/KYxZDkEVQIska5PcwaqnclLNiRKPbHgYxk7wCeNScP481qd6miKpfwnFza1PLVfJXWOqMY1OC4o5fWEUA1xAhvGFdMM8+dtKPmIMqTiF29/gVkikCYuDMlT7AQ5OXqDpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719731929; c=relaxed/simple; bh=/5C7XBNeUf3Xu4ZfAUKuwiNgK8zsw6Qv9aclmHulbiU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=xuu055/9n5PvXS5cG28lgRHPodgYJRTIhzp+670bJTqdTET5D+pJ3CXuxu0XwxEB2+yNxX77bCwAhSA3C+UgWdV0KlVIIDGKEf+cJinnLasoUQd8qwXr51hs83/uXhKE/BhCuylRUJw49Fxwhq6S0mrRGABoUGNmuNajD0TGglU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719731925; bh=/5C7XBNeUf3Xu4ZfAUKuwiNgK8zsw6Qv9aclmHulbiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WvFDwPDbK8Zd+1dAWRoSABeTdC0t2YXeQubNwwbl1b49bEQvGW2e8qX4cR9CsbEO9 YHfmqBGNBf8qbAW5915Hxo3Y+OS15qoDqOvtG7bclFHI+aWXlHJMGZwi3JoS1KBe2F S0ZmIpH2IX0RUphKnzHrhKMudVTQEzqx3/gBPuYo= Received: from stargazer.. (unknown [113.140.11.124]) (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 351321A3FF4; Sun, 30 Jun 2024 03:18:43 -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 v3 4/5] LoongArch: Add DT_RELR support Date: Sun, 30 Jun 2024 15:18:24 +0800 Message-ID: <20240630071825.11172-5-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240630071825.11172-1-xry111@xry111.site> References: <20240630071825.11172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-9.6 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 | 488 ++++++++++++++++++++- binutils/testsuite/lib/binutils-common.exp | 1 + ld/emulparams/elf64loongarch.sh | 1 + 3 files changed, 486 insertions(+), 4 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index fa8ed1feb29..06eec0ded6e 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,51 @@ 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. + elf_section_data (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 +976,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: @@ -1143,6 +1206,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; } @@ -1857,6 +1934,343 @@ 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); + unsigned int r_type = ELFNN_R_TYPE (rel->r_info); + struct elf_link_hash_entry *h = NULL; + asection *def_sec = NULL; + + if ((r_type != R_LARCH_64 && r_type != R_LARCH_32) + || 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) @@ -2037,6 +2451,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. */ @@ -2061,6 +2493,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. */ @@ -2977,7 +3417,21 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (unresolved_reloc && (ARCH_SIZE == 32 || r_type != R_LARCH_32) && !(h && (h->is_weakalias || !h->dyn_relocs))) - loongarch_elf_append_rela (output_bfd, sreloc, &outrel); + { + 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); + } } relocation += rel->r_addend; @@ -3701,7 +4155,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; @@ -4113,6 +4567,13 @@ 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 = loongarch_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; @@ -4125,6 +4586,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++) { @@ -5213,9 +5679,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 { @@ -5226,6 +5701,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) @@ -5679,6 +6155,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 Sun Jun 30 07:18:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 93087 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 2D13F382FAE5 for ; Sun, 30 Jun 2024 07:20:50 +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 121CF3861807 for ; Sun, 30 Jun 2024 07:18:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 121CF3861807 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 121CF3861807 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=1719731935; cv=none; b=wQds3deKC/3u4U5pctNrNqxiceJA1nCqG/MbhkHesEnqPJrtGOP5jBas7EUNEJzTBRRMCcFdAd7bw0BE5eVY53BRRRhxXabwzhGmSay8lbMWqJnumROhJ0JHaBq5+2Pam5hrWJ9nVh4Xwd/Wofq+4t6qic3I0E4/Q5HwC9IhSQw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719731935; c=relaxed/simple; bh=fgmw6YaWdOO4/tu1+voKJAMA3YjYeyFrWa8+AaHFsEs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Zjr0f+Kw9hkQyKxt/Rz4BDXMU3LIG3nfKwEEtsCdg+3aq/B8G6691JDrBGSg1uYmEDaMXH0I+dezc4k6sGNEdd1I8r1yq9Ye6dALSPxy295N3UXB28BplBPD3EK1n5188P9kYWmQMPCgO5tRzCV5mkSpPVam5DhO6fnFAMZXXvA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1719731927; bh=fgmw6YaWdOO4/tu1+voKJAMA3YjYeyFrWa8+AaHFsEs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZTfKuE9io/K73r2BAMTrpBuF3pGatdZPlm2Vb2pwAHbRCEDglkq34BwUiU/fda3xB IZsnMB+I6XuXG5xc9mvRsoA+YkaYLBsBiJpoi3n+T5mtEn0H+INi/B4mOJ5qeU+mEf 8HG0rhucERkJqFSPmKYe3JnM5KIgpnYS2siP641Y= Received: from stargazer.. (unknown [113.140.11.124]) (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 7283F1A3FF5; Sun, 30 Jun 2024 03:18:45 -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 v3 5/5] LoongArch: Add DT_RELR tests Date: Sun, 30 Jun 2024 15:18:25 +0800 Message-ID: <20240630071825.11172-6-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240630071825.11172-1-xry111@xry111.site> References: <20240630071825.11172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-8.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, LIKELY_SPAM_FROM, RCVD_IN_BARRACUDACENTRAL, 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..5121313e480 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-text-pie.d @@ -0,0 +1,14 @@ +#source: relr-text.s +#ld: -pie -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