[lld] r368041 - [ELF][ARM] Fix /DISCARD/ of section with .ARM.exidx section

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 8 01:56:30 PDT 2019


Merged to release_90 in r368270.

On Tue, Aug 6, 2019 at 4:13 PM Peter Smith via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: psmith
> Date: Tue Aug  6 07:13:38 2019
> New Revision: 368041
>
> URL: http://llvm.org/viewvc/llvm-project?rev=368041&view=rev
> Log:
> [ELF][ARM] Fix /DISCARD/ of section with .ARM.exidx section
>
> The combineEhSections runs, by design, before processSectionCommands so
> that input exception sections like .ARM.exidx and .eh_frame are not assigned
> to OutputSections. Unfortunately if /DISCARD/ removes InputSections that
> have associated .ARM.exidx sections without discarding the .ARM.exidx
> synthetic section then we will end up crashing when trying to sort the
> InputSections in ascending address order.
>
> We fix this by filtering out the sections that have been discarded prior
> to processing the InputSections in finalizeContents().
>
> fixes pr42890
>
> Differential Revision: https://reviews.llvm.org/D65759
>
> Added:
>     lld/trunk/test/ELF/arm-exidx-partial-discard.s
> Modified:
>     lld/trunk/ELF/SyntheticSections.cpp
>
> Modified: lld/trunk/ELF/SyntheticSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=368041&r1=368040&r2=368041&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SyntheticSections.cpp (original)
> +++ lld/trunk/ELF/SyntheticSections.cpp Tue Aug  6 07:13:38 2019
> @@ -3200,11 +3200,23 @@ static bool isDuplicateArmExidxSec(Input
>
>  // The .ARM.exidx table must be sorted in ascending order of the address of the
>  // functions the table describes. Optionally duplicate adjacent table entries
> -// can be removed. At the end of the function the ExecutableSections must be
> +// can be removed. At the end of the function the executableSections must be
>  // sorted in ascending order of address, Sentinel is set to the InputSection
>  // with the highest address and any InputSections that have mergeable
>  // .ARM.exidx table entries are removed from it.
>  void ARMExidxSyntheticSection::finalizeContents() {
> +  if (script->hasSectionsCommand) {
> +    // The executableSections and exidxSections that we use to derive the
> +    // final contents of this SyntheticSection are populated before the
> +    // linker script assigns InputSections to OutputSections. The linker script
> +    // SECTIONS command may have a /DISCARD/ entry that removes executable
> +    // InputSections and their dependent .ARM.exidx section that we recorded
> +    // earlier.
> +    auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); };
> +    llvm::erase_if(executableSections, isDiscarded);
> +    llvm::erase_if(exidxSections, isDiscarded);
> +  }
> +
>    // 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.
>
> Added: lld/trunk/test/ELF/arm-exidx-partial-discard.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-exidx-partial-discard.s?rev=368041&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/arm-exidx-partial-discard.s (added)
> +++ lld/trunk/test/ELF/arm-exidx-partial-discard.s Tue Aug  6 07:13:38 2019
> @@ -0,0 +1,37 @@
> +// 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 -x .ARM.exidx --sections %t.elf | FileCheck %s
> +
> +// CHECK-NOT: .exit.text
> +/// Expect 2 entries both CANTUNWIND as the .ARM.exidx.exit.text
> +// should have been removed.
> +// CHECK: Hex dump of section '.ARM.exidx':
> +// CHECK-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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list