From afbf90aef9e7878a2b139c3f7a5ef22b5d34caf7 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 13 Mar 2018 08:32:56 +0000 Subject: [PATCH] [ELF] - Drop special flags for empty output sections. This fixes PR36598. LLD currently crashes when we have empty output section with SHF_LINK_ORDER flag. This might happen if we place an empty synthetic section in the linker script, but keep output section alive with the use of additional symbol, for example. The patch fixes the issue by dropping all special flags for empty sections. Differential revision: https://reviews.llvm.org/D44376 llvm-svn: 327374 --- lld/ELF/LinkerScript.cpp | 18 +++++++++++------- lld/test/ELF/linkerscript/empty-link-order.test | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 lld/test/ELF/linkerscript/empty-link-order.test diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index e4b3bc9..fcfe078 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -813,7 +813,7 @@ static bool isDiscardable(OutputSection &Sec) { for (BaseCommand *Base : Sec.SectionCommands) if (!isa(*Base)) return false; - return getInputSections(&Sec).empty(); + return true; } void LinkerScript::adjustSectionsBeforeSorting() { @@ -845,14 +845,18 @@ void LinkerScript::adjustSectionsBeforeSorting() { continue; // A live output section means that some input section was added to it. It - // might have been removed (gc, or empty synthetic section), but we at least - // know the flags. + // might have been removed (if it was empty synthetic section), but we at + // least know the flags. if (Sec->Live) - Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); - else - Sec->Flags = Flags; + Flags = Sec->Flags; - if (isDiscardable(*Sec)) { + // We do not want to keep any special flags for output section + // in case it is empty. + bool IsEmpty = getInputSections(Sec).empty(); + if (IsEmpty) + Sec->Flags = Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); + + if (IsEmpty && isDiscardable(*Sec)) { Sec->Live = false; Cmd = nullptr; } diff --git a/lld/test/ELF/linkerscript/empty-link-order.test b/lld/test/ELF/linkerscript/empty-link-order.test new file mode 100644 index 0000000..eb9f1b3 --- /dev/null +++ b/lld/test/ELF/linkerscript/empty-link-order.test @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=arm-arm-none-eabi -o %t.o < /dev/null + +SECTIONS { + .foo : { + bar = .; + *(.ARM.exidx*) + } +} + +# RUN: ld.lld %t.o -o %t --script %s + +## Check we do not crash and do not set SHF_LINK_ORDER flag for .foo +# RUN: llvm-readobj -s %t | FileCheck %s +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_ARM_EXIDX +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] -- 2.7.4