It is fixed in stable/12 but probably worth to merge to releng/12. run script: root@clinch1:~ # uname -a FreeBSD clinch1.musec.engr.mun.ca 12.0-RC1 FreeBSD 12.0-RC1 r340470 GENERIC amd64 root@clinch1:~ # cat a.c #include <stdio.h> int main(int argc, const char *argv[]) { printf("hello world!\n"); return 0; } root@clinch1:~ # clang -fuse-ld=lld -g -static a.c root@clinch1:~ # llvm-objdump -d a.out a.out: file format ELF64-x86-64 llvm-objdump: 'a.out': index past the end of the symbol table
Ed, any idea which revision in stable/12 fixed this? r339304 maybe? I'm unsure.
I'm locating the commit fixing this, with the artifacts available on hand: r340604 is bad, while r340608 is good. I'm building and checking r340605, r340606, r340607.
r340608 fixes this.
That's strange... r340608 is the MFC of r339898 "Convert amd64_get/set_fs/gsbase to ifunc". Which is an internal change in libc only, I don't see what it has to do with llvm-objdump. Unless this changes the format of libc.a somehow?
(In reply to Dimitry Andric from comment #4) It is indeed _somewhat_ strange. This merge introduced actual use of ifunc in libc, and in particular in the static binaries, which now have PLT. Before that, csu contained code to process PLT and referenced weak start/stop symbols for the PLT bounds, which should be zeroes.
I've tried to build r340607 and r340608 cleanly and confirmed this. Do we need to fix this in 12.0? Or maybe we can close this since it is fixed in 12-STABLE.
(In reply to Konstantin Belousov from comment #5) We had some issues with lld and ifuncs with statically linked binaries that we brought in a fix or two for -- I wonder if the fix somehow introduced a regression for output _without_ ifuncs? Does GNU objdump complain about a.out as well? One thing to try: set LLD_REPRODUCE=hello.tar environment var and build the hello world on 12.0, then extract the hello.tar on stable/12, link with lld [ld.lld $(cat response.txt)] and check that output.
root@clinch1:~/hello # uname -a FreeBSD clinch1.musec.engr.mun.ca 12.0-PRERELEASE FreeBSD 12.0-PRERELEASE r340752 GENERIC amd64 root@clinch1:~/hello # cat response.txt --chroot . --eh-frame-hdr -Bstatic -o a.out usr/lib/crt1.o usr/lib/crti.o usr/lib/crtbeginT.o --library-path usr/lib tmp/a-aa866f.o --library gcc --library gcc_eh --library c --library gcc --library gcc_eh usr/lib/crtend.o usr/lib/crtn.o root@clinch1:~/hello # ld.lld `cat response.txt ` root@clinch1:~/hello # llvm-objdump -d a.out a.out: file format ELF64-x86-64 llvm-objdump: 'a.out': index past the end of the symbol table
Reproducer: https://people.freebsd.org/~lwhsu/pr233397/hello.tar.xz
/usr/local/bin/objdump: a.out symbol number 1030 references nonexistent SHT_SYMTAB_SHNDX section /usr/local/bin/objdump: a.out: File in wrong format % readelf -s a.out | grep '^ *1030:' 1030: 0000000000000000 0 NOTYPE LOCAL HIDDEN 65535 __rela_iplt_end These symbols are added by: // The beginning and the ending of .rel[a].plt section are marked // with __rel[a]_iplt_{start,end} symbols if it is a statically linked // executable. The runtime needs these symbols in order to resolve // all IRELATIVE relocs on startup. For dynamic executables, we don't // need these symbols, since IRELATIVE relocs are resolved through GOT // and PLT. For details, see http://www.airs.com/blog/archives/403. template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { if (!Config->Static) return; StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; addOptionalRegular(S, InX::RelaIplt, -1, STV_HIDDEN, STB_WEAK); } So what I think happens is when we have ifuncs these special symbols are emitted with Ndx set to the appropriate iplt section (.rela.plt), but when we have no ifuncs we still emit the symbols but there is no section for them to refer to.
This is https://llvm.org/pr36634
Linking with gold 1.15 (binutils 2.30): nuc% readelf -s a.out | grep iplt 1033: 000000000048b068 0 NOTYPE LOCAL HIDDEN 8 __rela_iplt_start 1034: 000000000048b068 0 NOTYPE LOCAL HIDDEN 8 __rela_iplt_end [ 8] .tdata PROGBITS 000000000048b070 0008a070 0000000000001800 0000000000000000 WAT 0 0 16 with ld.bfd 2.30 nuc% readelf -s a.out | grep iplt 1032: 00000000004001c0 0 NOTYPE LOCAL DEFAULT 1 __rela_iplt_end 1034: 00000000004001c0 0 NOTYPE LOCAL DEFAULT 1 __rela_iplt_start [ 1] .note.tag NOTE 0000000000400190 00000190 0000000000000030 0000000000000000 A 0 0 4
Proposed patch in https://reviews.llvm.org/D54985. This is probably only a cosmetic issue (i.e., when running objdump/readelf/etc. on the binary) unless it also causes tools like objcopy or strip to malfunction.
This was fixed in base r344779 (clang 8.0.0 rc3 import), which was merged into stable/12 in base r346168.