From: Andrew Ng Date: Wed, 17 Nov 2021 17:15:20 +0000 (+0000) Subject: [ELF] Ensure output section is not discarded in addStartEndSymbols() X-Git-Tag: upstream/15.0.7~25237 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47eb3f155f9e7b2670b8e0f8a85c64f31ea39fa4;p=platform%2Fupstream%2Fllvm.git [ELF] Ensure output section is not discarded in addStartEndSymbols() Fixes https://bugs.llvm.org/show_bug.cgi?id=52534. Differential Revision: https://reviews.llvm.org/D114179 --- diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index dcc7ebb..f332b03 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -1034,7 +1034,7 @@ void LinkerScript::assignOffsets(OutputSection *sec) { } } -static bool isDiscardable(OutputSection &sec) { +static bool isDiscardable(const OutputSection &sec) { if (sec.name == "/DISCARD/") return true; @@ -1063,6 +1063,11 @@ static bool isDiscardable(OutputSection &sec) { return true; } +bool LinkerScript::isDiscarded(const OutputSection *sec) const { + return hasSectionsCommand && (getFirstInputSection(sec) == nullptr) && + isDiscardable(*sec); +} + static void maybePropagatePhdrs(OutputSection &sec, std::vector &phdrs) { if (sec.phdrs.empty()) { diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index e6fec02..b366da4 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -318,6 +318,8 @@ public: void processSymbolAssignments(); void declareSymbols(); + bool isDiscarded(const OutputSection *sec) const; + // Used to handle INSERT AFTER statements. void processInsertCommands(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 19a71ad..6d97852 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2276,7 +2276,7 @@ template void Writer::addStartEndSymbols() { Default = Out::elfHeader; auto define = [=](StringRef start, StringRef end, OutputSection *os) { - if (os) { + if (os && !script->isDiscarded(os)) { addOptionalRegular(start, os, 0); addOptionalRegular(end, os, -1); } else { diff --git a/lld/test/ELF/linkerscript/preinit-array-empty.test b/lld/test/ELF/linkerscript/preinit-array-empty.test new file mode 100644 index 0000000..696c8dd --- /dev/null +++ b/lld/test/ELF/linkerscript/preinit-array-empty.test @@ -0,0 +1,39 @@ +# REQUIRES: x86 +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/t.s -o %t.o + +## PR52534: https://bugs.llvm.org/show_bug.cgi?id=52534 +## Check case where .preinit_array is discarded. +## Link should succeed without causing an out of range relocation error. +# RUN: ld.lld -T %t/discarded.script %t.o -o %t1 --image-base=0x80000000 +# RUN: llvm-readelf -s %t1 | FileCheck --check-prefixes=CHECK,DISCARDED %s + +## Check case where .preinit_array is emitted but empty. +# RUN: ld.lld -T %t/empty.script %t.o -o %t2 +# RUN: llvm-readelf -s %t2 | FileCheck --check-prefixes=CHECK,EMPTY %s + +# CHECK: [[#%x,ADDR:]] 0 NOTYPE LOCAL HIDDEN [[#]] __preinit_array_start +# CHECK-NEXT: [[#ADDR]] 0 NOTYPE LOCAL HIDDEN [[#]] __preinit_array_end + +# DISCARDED-NEXT: [[#ADDR]] 0 NOTYPE GLOBAL DEFAULT [[#]] _start + +# EMPTY-NOT: [[#ADDR]] 0 NOTYPE GLOBAL DEFAULT [[#]] _start +# EMPTY: [[#ADDR]] 0 NOTYPE GLOBAL DEFAULT [[#]] ADDR + +#--- t.s +.global _start +_start: + movq __preinit_array_start@GOTPCREL(%rip),%rax + movq __preinit_array_end@GOTPCREL(%rip),%rax + +#--- discarded.script +SECTIONS { + .text : { *(.text); } + .preinit_array : { *(.preinit_array); } +} + +#--- empty.script +SECTIONS { + .text : { *(.text); } + .preinit_array : { ADDR = .; *(.preinit_array); } +}