Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2569,16 +2569,22 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { // The Sections are sorted in order of ascending PREL31 address with the // sentinel last. We need to find the InputSection that precedes the - // sentinel. By construction the Sentinel is in the last - // InputSectionDescription as the InputSection that precedes it. + // sentinel. OutputSection *C = getParent(); - auto ISD = - std::find_if(C->SectionCommands.rbegin(), C->SectionCommands.rend(), - [](const BaseCommand *Base) { - return isa(Base); - }); - auto L = cast(*ISD); - InputSection *Highest = L->Sections[L->Sections.size() - 2]; + InputSection *Highest = nullptr; + int Skip = 1; + for (const BaseCommand *Base : llvm::reverse(C->SectionCommands)) { + if (!isa(Base)) + continue; + auto L = cast(Base); + if (Skip >= L->Sections.size()) { + Skip -= L->Sections.size(); + continue; + } + Highest = L->Sections[L->Sections.size() - Skip - 1]; + break; + } + assert(Highest); InputSection *LS = Highest->getLinkOrderDep(); uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize()); uint64_t P = getVA(); Index: test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s =================================================================== --- test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s +++ test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s @@ -0,0 +1,24 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .ARM.exidx 0x1000 : { *(.ARM.exidx*) foo = .; } \ +# RUN: .text 0x2000 : { *(.text*) } \ +# RUN: }" > %t.script +## We used to crash if the last output section command for .ARM.exidx +## was anything but an input section description. +# RUN: ld.lld -T %t.script %t.o -shared -o %t.so +# RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s + + .syntax unified + .text + .global _start +_start: + .fnstart + .cantunwind + bx lr + .fnend + +// CHECK: Contents of section .ARM.exidx: +// 1000 + 1000 = 0x2000 = _start +// 1008 + 0ffc = 0x2004 = _start + sizeof(_start) +// CHECK-NEXT: 1000 00100000 01000000 fc0f0000 01000000