Closed 688cc089-1a96-4cb4-bd77-eaf433fc1da2 closed 4 years ago
Fixed by https://reviews.llvm.org/D73399 . Will be included in lld 10.
Tested by Bdragon.
Fangrui,
Now my test environment has LLVM9 fully integrated to FreeBSD base (clang900-import experimental branch) and found that passing arguments -fpic or -fPIC for clang will make it work. Without this application crashes with signal 5 (Trace/BPT trap)"
Should pic/PIC be implicit in this case or does it point to another bug?
The problem is similar to a previous bug report. There is no GOT-generating elocation (R_PPC_GOT16 R_PPC_GOT_TLSGD16 R_PPC_GOT_TLSLD16 R_PPC_GOT_TPREL16 ...).
% readelf -d except32.lld | grep PPC_GOT 0x70000000 (PPC_GOT) 0x0
// lld/ELF/SyntheticSections.cpp bool GotSection::isNeeded() const { // We need to emit a GOT even if it's empty if there's a relocation that is // relative to GOT(such as GOTOFFREL). return numEntries || hasGotOffRel; // In our case, numEntries == 0 && !hasGotOffRel }
The problem is that LLD sets the DT_PPC_GOT to 0, where it should never be a NULL pointer on a ET_EXEC. Glibc, NetBSD ld-elf.so, and FreeBSD's ld-elf.so all key off this being non-NULL to get the real pointer to the GOT. Even on a ET_DYN object, it should never be NULL, because the GOT cannot be at the very beginning of the file (obviously, the very beginning is the header).
Following the code, segmentation fault actually happens on bctr call at 0x1001086.
0x10010858 <00000000.plt_call32.atexit> lis r11,4099 (r11 is 0x5004ae62) 0x1001085c <00000000.plt_call32.atexit+4> lwz r11,4(r11) (r11 is 0x10030000) 0x10010860 <00000000.plt_call32.atexit+8> mtctr r11 (r11 is 0x39600000) 0x10010864 <00000000.plt_call32.atexit+12> bctr (r11 is 0x39600000)
So, it ends up with r11 = 0x39600000, that's is wrong.
Reading symbols from except32.lld...done. [New LWP 100600] Core was generated by `./except32.lld'. Program terminated with signal SIGSEGV, Segmentation fault.
(gdb) bt
at /root/freebsd/lib/csu/powerpc/crt1.c:87
I set a breakpoint at offset 0x100100ac, as it crashes on next instruction:
0x100100b0 <_start+176> bl 0x10010858 <00000000.plt_call32.atexit>
Context is:
│ │0x10010088 <_start+136> b 0x10010068 <_start+104> │ │0x1001008c <_start+140> cmplwi r8,0 │ │0x10010090 <_start+144> beq 0x1001009c <_start+156> │ │0x10010094 <_start+148> lis r3,4099 │ │0x10010098 <_start+152> stw r8,100(r3) │ │0x1001009c <_start+156> lis r3,4098 │ │0x100100a0 <_start+160> addi r3,r3,20 │ │0x100100a4 <_start+164> cmplwi r3,0 │ │0x100100a8 <_start+168> beq 0x100100b8 <_start+184> │ B+ │0x100100ac <_start+172> mr r3,r7 │
│0x100100b0 <_start+176> bl 0x10010858 <00000000.plt_call32.atexit> │ │0x100100b4 <_start+180> b 0x100100bc <_start+188> │ │0x100100b8 <_start+184> bl 0x10010868 <00000000.plt_call32._init_tls> │ │0x100100bc <_start+188> mr r3,r28 │ │0x100100c0 <_start+192> mr r4,r29 │ │0x100100c4 <_start+196> mr r5,r30
assigned to @MaskRay
Extended Description
On FreeBSD powerpc64 using 32 bit compatibility libraries (LIB32), C++ exception handling is broken when application is compiled with CLANG9 and linked with LLD9. Same application linked with BFD 2.17 works properly:
include
using namespace std;
int main () { try { throw 20; } catch (int e) { cout << "An exception occurred. Exception Nr. " << e << '\n'; } return 0; }
root@alfredo-2:~/test/except # ./except32.bfd An exception occurred. Exception Nr. 20
root@alfredo-2:~/test/except # ./except32.lld Segmentation fault (core dumped)