-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LLD -Wl,-z,notext on AArch64 breaks exception handling unwind #60392
Comments
@llvm/issue-subscribers-backend-aarch64 |
@llvm/issue-subscribers-lld-elf |
I cannot reproduce the failure on a Ubuntu 22.04.1 LTS AArch64 machine. g++ 11.2.0-19ubuntu1 % ~/llvm/out/release/bin/clang++ -fuse-ld=lld a.cc -o a -Wl,-z,notext
% ./a
all fine.
% ~/llvm/out/release/bin/clang++ -fuse-ld=lld a.cc -o a -Wl,-z,notext -stdlib=libc++ -Wl,-rpath=~/llvm/out/release/lib/aarch64-unknown-linux-gnu
% ./a
all fine. Any chance your company ships some local patches that are related? |
I think I was only using the stock fedora server toolchain and LLVM github/main. But I'll double check and provide more details later. |
Thanks for looking at this. I reduced system specifics by going for LLVM libcxx/libcxxabi. It still reproduces for me (based on LLVM github/main 0534791):
Diffing
I've uploaded delta.diff: https://gist.github.com/MatzeB/4f99823153411d4a9a3067e05f2727df |
|
Can you link with the environment variable |
FWIW: I noticed that Clang uses this assembly:
while GCC uses this pattern:
If I change clang generated assembly to the GCC pattern then things start working too... |
Hmm we build LLVM with |
The issue is a combination of:
The comment in D122459 is wrong ("Two code paths may reach here."). There are three code paths. The third is about a dynamic relocation (use of However, we can avoid the issue with the CodeGen change: https://reviews.llvm.org/D143039 ( On x86-64, With |
Thanks for investigating! Going for the same indirect codegen as GCC sounds reasonable. Though I hope we can at least detect the problematic relocations (non-relative relocations into eh_frame?) and have lld stop and produce an error message? (as I fear people will mix&match object files from older compiler versions with newer lld...) |
/cherry-pick 08c915f |
/branch llvm/llvm-project-release-prs/issue60392 |
Fix llvm/llvm-project#60392 ``` // a.cc void raise() { throw 42; } bool foo() { try { raise(); } catch (int) { return true; } return false; } int main() { foo(); } ``` ``` clang++ --target=x86_64-linux-gnu -fno-pic -mcmodel=large -no-pie -fuse-ld=lld -z notext a.cc -o a && ./a clang++ --target=aarch64-linux-gnu -fno-pic -no-pie -fuse-ld=lld -Wl,--dynamic-linker=/usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 -Wl,-rpath=/usr/aarch64-linux-gnu/lib -z notext a.cc -o a && ./a ``` Both commands fail because we produce a dynamic relocation for R_X86_64_64/R_AARCH64_ABS64 in .eh_frame which will be adjusted to a wrong offset by `SectionBase::getOffset` after D122459. Since GNU ld uses a canonical PLT entry instead of a dynamic relocation for .eh_frame, we follow suit as well to avoid the issue. Mips has an ABI issue (llvm/llvm-project#5837) and we don't implement GNU ld's DW_EH_PE_absptr conversion. mips64-eh-abs-reloc.s wants a dynamic relocation, so keep the original behavior for EM_MIPS. Differential Revision: https://reviews.llvm.org/D143136 (cherry picked from commit 08c915f)
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: #60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is necessary for small code model since "Max text segment size < 2GiB" but it is unnecessary to make `-fno-pic -mcmodel={tiny,small}` different: The scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
/pull-request llvm/llvm-project-release-prs#267 |
SNSystems/llvm-debuginfo-analyzer@1643997
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: llvm/llvm-project#60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is necessary for small code model since "Max text segment size < 2GiB" but it is unnecessary to make `-fno-pic -mcmodel={tiny,small}` different: The scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: #60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is unneeded for small code model since "Max text segment size < 2GiB" but making `-fno-pic -mcmodel={tiny,small}` different seems unnecessary: the scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) --- Two clang/test/Interpreter tests would fail without 6747fc0 ([ORC] Use JITLink as the default linker for LLJIT on Linux/arm64.) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: llvm/llvm-project#60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is unneeded for small code model since "Max text segment size < 2GiB" but making `-fno-pic -mcmodel={tiny,small}` different seems unnecessary: the scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) --- Two clang/test/Interpreter tests would fail without 6747fc07d1aa94e22622e278e5a02ba70675ac9b ([ORC] Use JITLink as the default linker for LLJIT on Linux/arm64.) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
Fix llvm/llvm-project#60392 ``` // a.cc void raise() { throw 42; } bool foo() { try { raise(); } catch (int) { return true; } return false; } int main() { foo(); } ``` ``` clang++ --target=x86_64-linux-gnu -fno-pic -mcmodel=large -no-pie -fuse-ld=lld -z notext a.cc -o a && ./a clang++ --target=aarch64-linux-gnu -fno-pic -no-pie -fuse-ld=lld -Wl,--dynamic-linker=/usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 -Wl,-rpath=/usr/aarch64-linux-gnu/lib -z notext a.cc -o a && ./a ``` Both commands fail because we produce a dynamic relocation for R_X86_64_64/R_AARCH64_ABS64 in .eh_frame which will be adjusted to a wrong offset by `SectionBase::getOffset` after D122459. Since GNU ld uses a canonical PLT entry instead of a dynamic relocation for .eh_frame, we follow suit as well to avoid the issue. Mips has an ABI issue (llvm/llvm-project#5837) and we don't implement GNU ld's DW_EH_PE_absptr conversion. mips64-eh-abs-reloc.s wants a dynamic relocation, so keep the original behavior for EM_MIPS. Differential Revision: https://reviews.llvm.org/D143136 (cherry picked from commit 08c915f)
@llvm/issue-subscribers-lld-elf |
Fix llvm/llvm-project#60392 ``` // a.cc void raise() { throw 42; } bool foo() { try { raise(); } catch (int) { return true; } return false; } int main() { foo(); } ``` ``` clang++ --target=x86_64-linux-gnu -fno-pic -mcmodel=large -no-pie -fuse-ld=lld -z notext a.cc -o a && ./a clang++ --target=aarch64-linux-gnu -fno-pic -no-pie -fuse-ld=lld -Wl,--dynamic-linker=/usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 -Wl,-rpath=/usr/aarch64-linux-gnu/lib -z notext a.cc -o a && ./a ``` Both commands fail because we produce a dynamic relocation for R_X86_64_64/R_AARCH64_ABS64 in .eh_frame which will be adjusted to a wrong offset by `SectionBase::getOffset` after D122459. Since GNU ld uses a canonical PLT entry instead of a dynamic relocation for .eh_frame, we follow suit as well to avoid the issue. Mips has an ABI issue (llvm/llvm-project#5837) and we don't implement GNU ld's DW_EH_PE_absptr conversion. mips64-eh-abs-reloc.s wants a dynamic relocation, so keep the original behavior for EM_MIPS. Differential Revision: https://reviews.llvm.org/D143136
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: llvm/llvm-project#60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is necessary for small code model since "Max text segment size < 2GiB" but it is unnecessary to make `-fno-pic -mcmodel={tiny,small}` different: The scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
…ality/lsda/ttype encodings For -fno-pic, without DW_EH_PE_indirect, the personality routine pointer in a CIE needs an R_AARCH64_ABS64 relocation. In common configurations that `__gcc_personality_v0` is defined in a shared object, this will lead to a discouraged canonical PLT entry, or, if `ld.lld -z notext` (betwen D122459 and D143136), a dynamic R_AARCH64_ABS64 relocation with an incorrect offset: llvm/llvm-project#60392 Since GCC uses DW_EH_PE_indirect for -fno-pic code (the behavior hasn't changed since the initial port in 2012), let's follow suit by simplifying the code. ( For tiny and small code models, we use DW_EH_PE_sdata8 instead of GCC's DW_EH_PE_sdata4. This is a deliberate choice to support personality-.eh_frame offset > 2GiB. This is unneeded for small code model since "Max text segment size < 2GiB" but making `-fno-pic -mcmodel={tiny,small}` different seems unnecessary: the scenarios that uses both -fno-pic and C++ exceptions have been increasingly rare now, so there is little advantage optimizing for the little size saving with code complexity. ) --- Two clang/test/Interpreter tests would fail without 6747fc0 ([ORC] Use JITLink as the default linker for LLJIT on Linux/arm64.) Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D143039
We see exception handling unwind failing on AArch64/Linux when using
clang -fuse-ld=lld -Wl,-z,notext
.Reproducer:
trying this on llvm-15 or a recent git version (9470de6). Gives me:
(it should just print "all fine.")
This worked with older toolchains based on llvm-12. I bisected the problem to 4645311
/ https://reviews.llvm.org/D122459 reverting this change does fix things for me...
The text was updated successfully, but these errors were encountered: