forked from OSchip/llvm-project
[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
This commit is contained in:
parent
812e64ef0c
commit
47eb3f155f
|
@ -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<StringRef> &phdrs) {
|
||||
if (sec.phdrs.empty()) {
|
||||
|
|
|
@ -318,6 +318,8 @@ public:
|
|||
void processSymbolAssignments();
|
||||
void declareSymbols();
|
||||
|
||||
bool isDiscarded(const OutputSection *sec) const;
|
||||
|
||||
// Used to handle INSERT AFTER statements.
|
||||
void processInsertCommands();
|
||||
|
||||
|
|
|
@ -2276,7 +2276,7 @@ template <class ELFT> void Writer<ELFT>::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 {
|
||||
|
|
|
@ -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); }
|
||||
}
|
Loading…
Reference in New Issue