Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -3205,6 +3205,19 @@ // with the highest address and any InputSections that have mergeable // .ARM.exidx table entries are removed from it. void ARMExidxSyntheticSection::finalizeContents() { + // The linker script may have a /DISCARD/ entry that removes either + // a .ARM.exidx section or a section with a .ARM.exidx section. + if (script->hasSectionsCommand) { + auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); }; + executableSections.erase(std::remove_if(executableSections.begin(), + executableSections.end(), + isDiscarded), + executableSections.end()); + exidxSections.erase( + std::remove_if(exidxSections.begin(), exidxSections.end(), isDiscarded), + exidxSections.end()); + } + // Sort the executable sections that may or may not have associated // .ARM.exidx sections by order of ascending address. This requires the // relative positions of InputSections to be known. Index: test/ELF/arm-exidx-partial-discard.s =================================================================== --- /dev/null +++ test/ELF/arm-exidx-partial-discard.s @@ -0,0 +1,38 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o +// RUN: echo "SECTIONS { . = 0x10000; .text : { *(.text) } /DISCARD/ : { *(.exit.text) } }" > %t.script +// RUN: ld.lld -T %t.script %t.o -o %t.elf +// RUN: llvm-readobj --sections %t.elf | FileCheck %s +// RUN: llvm-readobj -x .ARM.exidx %t.elf | FileCheck --check-prefix=CHECK-HEX %s + +// CHECK-NOT: .exit.text +/// Expect 2 entries both CANTUNWIND as the .ARM.exidx.exit.text +// should have been removed. +// CHECK-HEX: Hex dump of section '.ARM.exidx': +// CHECK-HEX-NEXT: 0x00010000 10000000 01000000 10000000 01000000 + +/// The /DISCARD/ is evaluated after sections have been assigned to the +/// .ARM.exidx synthetic section. We must account for the /DISCARD/ + .section .exit.text, "ax", %progbits + .globl foo + .type foo, %function +foo: + .fnstart + bx lr + .save {r7, lr} + .setfp r7, sp, #0 + .fnend + + .text + .globl _start + .type _start, %function +_start: + .fnstart + bx lr + .cantunwind + .fnend + + .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits + .global __aeabi_unwind_cpp_pr0 +__aeabi_unwind_cpp_pr0: + bx lr