[flang-commits] [flang] [LLD][AARCH64] lld incorrectly handles .eh_frame when it has a non-zero offset within its output section. (PR #65966)
Peter Smith via flang-commits
flang-commits at lists.llvm.org
Mon Sep 11 09:16:57 PDT 2023
================
@@ -770,6 +770,9 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
+ else if (auto *eh = dyn_cast<EhInputSection>(&sec))
----------------
smithp35 wrote:
I don't think this problem specific to AArch64? It would also affect the other targets that use .eh_frame such as x86_64.
As I understand it this was triggered by the Picolibc linker script (https://github.com/picolibc/picolibc/blob/main/picolibc.ld.in) with extract:
```
.except_ordered : {
*(.gcc_except_table *.gcc_except_table.*)
KEEP (*(.eh_frame .eh_frame.*))
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >flash AT>flash :text
```
Which has the .eh_frame sections after .gcc_except_table.
I made a failing test case for x86_64 by editing the output of GNU ld's --verbose and adding a dummy QUAD statement. I've not included the whole ld --verbose output as it is rather long.
```
/* Insert QUAD(0) to make .eh_frame start at non 0 offset within ouptut section */
.eh_frame : ONLY_IF_RO { QUAD(0); KEEP (*(.eh_frame)) *(.eh_frame.*) }
```
With the simple test program
```
#include <stdio.h>
int main(void) {
try {
throw 55;
}
catch (int i) { printf("Caught int %d\n", i); }
catch (...) { printf("Caught generic\n"); }
return 0;
}
```
With results:
```
clang++ -fuse-ld=bfd throw.cpp -o throw.exe -Wl,--script=ld.script
./throw.exe
Caught int 55
clang++ -fuse-ld=lld throw.cpp -o throw.exe -Wl,--script=ld.script
./throw.exe
[1] 444896 abort (core dumped) ./throw.exe
```
https://github.com/llvm/llvm-project/pull/65966
More information about the flang-commits
mailing list