Skip to content
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 segfault in InputSection::writeTo linking FreeBSD/i386 gptboot loader (reproducer attached) #30643

Closed
emaste opened this issue Dec 6, 2016 · 5 comments
Labels
bugzilla Issues migrated from bugzilla lld:ELF

Comments

@emaste
Copy link
Member

emaste commented Dec 6, 2016

Bugzilla Link 31295
Resolution FIXED
Resolved on Dec 20, 2016 03:46
Version unspecified
OS FreeBSD
Blocks #23588
Attachments lld segfault reproducer

Extended Description

Linking the gpt bootloader, which is an i386 binary on FreeBSD/amd64.

Boot log excerpt:

--- gptboot.out ---
ld -static -N --gc-sections -m elf_i386_fbsd -Ttext 0x0 -o gptboot.out /tank/emaste/obj/tank/emaste/src/freebsd-xlld/sys/boot/i386/gptboot/../btx/lib/crt0.o gptboot.o sio.o crc32.o drv.o cons.o util.o xform_aes_xts.o /tank/emaste/obj/tank/emaste/src/freebsd-xlld/sys/boot/i386/gptboot/../../geli/libgeliboot.a /tank/emaste/obj/tank/emaste/src/freebsd-xlld/sys/boot/i386/gptboot/../../libstand32/libstand.a

Backtrace excerpt:

(lldb) bt

  • thread #​5: tid = 102169, 0x00000008065eaf46 libc.so.7`memcpy + 22 at bcopy.S:65, stop reason = invalid address (fault address: 0x9051b1090)
    • frame #​0: 0x00000008065eaf46 libc.so.7memcpy + 22 at bcopy.S:65 frame #&#8203;1: 0x000000000068d084 ld.lldlld::elf::InputSection<llvm::object::ELFType<(this=0x00000008074f3320, Buf=0x00000009051b1000)1, false> >::writeTo(unsigned char*) + 372 at InputSection.cpp:596
      frame #​2: 0x000000000081be40 ld.lldoperator(this=0x00007fffdf7f9bd8, IS=0x00000008074f3320) + 32 at OutputSections.cpp:256 frame #&#8203;3: 0x000000000081db6c ld.lldoperator() [inlined] lld::elf::OutputSection<llvm::object::ELFType<(__first=__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<1, false> > > at 0x00007fffdf7f9be8, __last=__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<1, false> > > at 0x00007fffdf7f9be0, __f=l
      ld::elf::OutputSection<llvm::object::ELFType<llvm::support::endianness, false> >:: at 0x00007fffdf7f9bd8)1, false> >::writeTo(unsigned char
      )::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*) std::__1::for_each<std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >
      >, lld::elf::Output
      Section<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*)>(std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >
      >, std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, fa
      lse> >
      >, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*)) + 93 at algorithm:853
      frame #​4: 0x000000000081db0f ld.lldoperator(this=0x0000000808810078) + 191 at Parallel.h:307 frame #&#8203;5: 0x000000000081da3c ld.lldstd::__1::__function::__func<void lld::parallel_for_each<std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >
      >, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*)>(std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*))::'lambda'(), std::__1::allocator<void lld::parallel_for_each<std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*)>(std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, std::__1::__wrap_iter<lld::elf:
      :InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >
      >, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*))::'lambda'()>, void ()>::operator()
      () [inlined] decltype(this=0x0000000808810078, __f=0x0000000808810078)1, false> >
      > >(fp)(std::__1::forward<>(fp0))) std::__1::__invoke<void lld::parallel_for_each<std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::spport::endianness)1, false> >>, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*)>(std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >>, lld::elf::OutputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeTo(unsigned char*)::'lambda'(lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*))::'lambda'()&>(std::__1::__wrap_iter<lld::elf::InputSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >*>&&) + 60
      at __functional_base:413
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 6, 2016

Problem is:
-Ttext 0x0

Our offset calculation does not support this yet:
return First->Offset + Sec->Addr - First->Addr;

First->Offset == 0x0
Sec->Addr == 0x0 (-Ttext)
First->Addr = 0x10000 (Header)

@emaste
Copy link
Member Author

emaste commented Dec 6, 2016

Also a segfault in:

--- zfsboot.out ---
ld -static -N --gc-sections -m elf_i386_fbsd -Ttext 0x2000 -o zfsboot.out /tank/
emaste/obj/tank/emaste/src/freebsd-xlld/sys/boot/i386/zfsboot/../btx/lib/crt0.o
zfsboot.o sio.o drv.o cons.o util.o skein.o skein_block.o /tank/emaste/obj/tank/
emaste/src/freebsd-xlld/sys/boot/i386/zfsboot/../../libstand32/libstand.a
Segmentation fault (core dumped)
*** [zfsboot.out] Error code 139

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 7, 2016

D27526 should fix that all.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 8, 2016

So looks -Ttext option does not set the address of .text at fact.
For bfd it do:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000080 00ba74 00 WAX 0 0 16
[ 2] .rodata PROGBITS 0000ba80 00bb00 0035f4 00 A 0 0 16
[ 3] .got.plt PROGBITS 0000f074 00f0f4 00000c 04 WA 0 0 4
...
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000080 0x00000000 0x00000000 0x0f1b0 0x18598 RWE 0x10
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10

Buf for gold - dont:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000080 000080 00ba74 00 AX 0 0 16
[ 2] .rodata PROGBITS 0000bb00 00bb00 0035fc 00 A 0 0 16
[ 3] .got PROGBITS 0000f0fc 00f0fc 000000 00 WA 0 0 4
[ 4] .got.plt PROGBITS 0000f0fc 00f0fc 00000c 00 WA 0 0 4
...

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x00000000 0x00000000 0x0f238 0x18628 RWE 0x10
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0

But it affects on PT_LOAD VA. Does it mean we just want to set ImageBase to address of -Ttext ?
that looks would have the same behavior as gold shows then. (PT_LOAD will have VA = 0x0, .text will have some address as VA, size_of_headers in the case of reproduce for this issue).

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 20, 2016

Should be fixed by Rafael in r290136

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla lld:ELF
Projects
None yet
Development

No branches or pull requests

2 participants