Closed Quuxplusone closed 4 years ago
Attached 43350.tar.xz
(833636 bytes, application/x-xz): Reproduce tar
Attached 43350-artifacts.tar.xz
(41772 bytes, application/x-xz): source, binaries and core
Reading symbols from except32.lld...done.
[New LWP 100600]
Core was generated by `./except32.lld'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x39600000 in ?? ()
(gdb) bt
#0 0x39600000 in ?? ()
#1 0x100100b4 in _start (argc=1, argv=<optimized out>, env=<optimized out>,
obj=<optimized out>, cleanup=0x5003d254 <rtld_nop_exit>, ps_strings=0x0)
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
(In reply to Alfredo Dal'Ava Júnior from comment #3)
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.
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).
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
}
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?
Fixed by https://reviews.llvm.org/D73399 . Will be included in lld 10.
Tested by Bdragon.
43350.tar.xz
(833636 bytes, application/x-xz)43350-artifacts.tar.xz
(41772 bytes, application/x-xz)