Skip to content

Commit

Permalink
[ELF] Ensure output section is not discarded in addStartEndSymbols()
Browse files Browse the repository at this point in the history
  • Loading branch information
nga888 committed Nov 19, 2021
1 parent 812e64e commit 47eb3f1
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
7 changes: 6 additions & 1 deletion lld/ELF/LinkerScript.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -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()) {
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/LinkerScript.h
Expand Up @@ -318,6 +318,8 @@ class LinkerScript final {
void processSymbolAssignments();
void declareSymbols();

bool isDiscarded(const OutputSection *sec) const;

// Used to handle INSERT AFTER statements.
void processInsertCommands();

Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Writer.cpp
Expand Up @@ -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 {
Expand Down
39 changes: 39 additions & 0 deletions 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); }
}

0 comments on commit 47eb3f1

Please sign in to comment.