LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 33821 - After r307100, segfaults when linking FreeBSD aarch64 kernel
Summary: After r307100, segfaults when linking FreeBSD aarch64 kernel
Status: RESOLVED FIXED
Alias: None
Product: lld
Classification: Unclassified
Component: ELF (show other bugs)
Version: unspecified
Hardware: PC All
: P normal
Assignee: Rafael Ávila de Espíndola
URL:
Keywords:
Depends on:
Blocks: 23214
  Show dependency tree
 
Reported: 2017-07-17 11:42 PDT by Dimitry Andric
Modified: 2017-07-18 16:16 PDT (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitry Andric 2017-07-17 11:42:51 PDT
As reported on https://reviews.llvm.org/rL307100, after this change linking the FreeBSD aarch64 kernel results in lld segfaulting:

Thread 1 received signal SIGSEGV, Segmentation fault.
lld::elf::OutputSection::addSection (this=0x0, S=0x813b2d008)
    at /home/dim/src/llvm-trunk/tools/lld/ELF/OutputSections.cpp:84
84        Sections.push_back(S);
(gdb) bt
#0  lld::elf::OutputSection::addSection (this=0x0, S=0x813b2d008) at /home/dim/src/llvm-trunk/tools/lld/ELF/OutputSections.cpp:84
#1  0x00000000009506eb in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true> >::addPredefinedSections (this=0x7fffffff6e30) at /home/dim/src/llvm-trunk/tools/lld/ELF/Writer.cpp:1338
#2  0x0000000000949423 in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true> >::finalizeSections (this=0x7fffffff6e30) at /home/dim/src/llvm-trunk/tools/lld/ELF/Writer.cpp:1243
#3  0x0000000000914495 in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true> >::run (this=0x7fffffff6e30) at /home/dim/src/llvm-trunk/tools/lld/ELF/Writer.cpp:207
#4  0x0000000000973192 in lld::elf::writeResult<llvm::object::ELFType<(llvm::support::endianness)1, true> > () at /home/dim/src/llvm-trunk/tools/lld/ELF/Writer.cpp:126
#5  0x000000000066c7ff in lld::elf::LinkerDriver::link<llvm::object::ELFType<(llvm::support::endianness)1, true> > (this=0x805ce2000, Args=...) at /home/dim/src/llvm-trunk/tools/lld/ELF/Driver.cpp:1056
#6  0x0000000000655585 in lld::elf::LinkerDriver::main (this=0x805ce2000, ArgsArr=..., CanExitEarly=true) at /home/dim/src/llvm-trunk/tools/lld/ELF/Driver.cpp:386
#7  0x00000000006547a3 in lld::elf::link (Args=..., CanExitEarly=true, Error=...) at /home/dim/src/llvm-trunk/tools/lld/ELF/Driver.cpp:85
#8  0x0000000000457809 in main (Argc=1245, Argv=0x7fffffff8580) at /home/dim/src/llvm-trunk/tools/lld/tools/lld/lld.cpp:104
(gdb) up
#1  0x00000000009506eb in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true> >::addPredefinedSections (this=0x7fffffff6e30) at /home/dim/src/llvm-trunk/tools/lld/ELF/Writer.cpp:1338
1338      Cmd->Sec->addSection(Sentinel);
(gdb) print Cmd->Sec
$5 = (lld::elf::OutputSection *) 0x0

At this point findSectionCommand() was looping through Script->Opt.Commands, found a not-completely initialized .ARM.exidx section, which still had its null Sec member.

Reverting the findSectionCommand() implementation to its previous version prevents crashing, but it may not be the correct solution

The reproduction test case is unfortunately too large to be attached, find it here:
http://www.andric.com/freebsd/clang/lld-arm64-segfault.tar.xz  (18 MiB)
Comment 1 emaste 2017-07-18 08:57:51 PDT
Reproducible at r308300, and with --no-threads.

(gdb) frame
#2  0x00000000019ee7ab in (anonymous namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true> >::addPredefinedSections (this=0x7ffffffddae8) at ../tools/lld/ELF/Writer.cpp:1337
1337      Cmd->Sec->addSection(Sentinel);
(gdb) p Cmd->Sec
$4 = (lld::elf::OutputSection *) 0x0

With this change:
-  if (!Cmd || Cmd->Commands.empty() || Config->Relocatable)
+  if (!Cmd || !Cmd->Sec || Cmd->Commands.empty() || Config->Relocatable)
lld does not crash on the kernel link and passes the test suite.

(Using GDB because LLDB 5.0.0 is currently broken too.)
Comment 2 Rafael Ávila de Espíndola 2017-07-18 13:55:40 PDT
Sorry for the delay.  Looking at it now.
Comment 3 Rafael Ávila de Espíndola 2017-07-18 14:47:36 PDT
Fixed in r308382.
Comment 4 Rafael Ávila de Espíndola 2017-07-18 15:16:20 PDT
(In reply to emaste from comment #1)
> Reproducible at r308300, and with --no-threads.
> 
> (gdb) frame
> #2  0x00000000019ee7ab in (anonymous
> namespace)::Writer<llvm::object::ELFType<(llvm::support::endianness)1, true>
> >::addPredefinedSections (this=0x7ffffffddae8) at
> ../tools/lld/ELF/Writer.cpp:1337
> 1337      Cmd->Sec->addSection(Sentinel);
> (gdb) p Cmd->Sec
> $4 = (lld::elf::OutputSection *) 0x0
> 
> With this change:
> -  if (!Cmd || Cmd->Commands.empty() || Config->Relocatable)
> +  if (!Cmd || !Cmd->Sec || Cmd->Commands.empty() || Config->Relocatable)
> lld does not crash on the kernel link and passes the test suite.

Sorry, I just noticed this. Yes, that was the correct change. I had in mind only the synthetic linkerscirpt case when I first wrote it.
Comment 5 emaste 2017-07-18 16:16:11 PDT
No worries.

I can confirm that with my original change (https://github.com/emaste/freebsd/commit/1d3dfff8bc1e3023423d909d4b86e3b7aa43abc6) a lld-linked FreeBSD/arm64 kernel and world works (tested on a SoftIron OverDrive 1000).