Skip to content

Commit dee900a

Browse files
author
George Rimar
committedApr 26, 2019
[LLD][ELF] - Do not remove empty sections referenced in LOADADDR/ADDR commands.
This is https://bugs.llvm.org//show_bug.cgi?id=38750. If script references empty sections in LOADADDR/ADDR commands .empty : { *(.empty ) } .text : AT(LOADADDR (.empty) + SIZEOF (.empty)) { *(.text) } then an empty section will be removed and LOADADDR/ADDR will evaluate to null. It is not that user may expect from using of the generic script, what is a common case. Differential revision: https://reviews.llvm.org/D54621 llvm-svn: 359279
1 parent 2aa0bde commit dee900a

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed
 

Diff for: ‎lld/ELF/LinkerScript.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -825,12 +825,18 @@ static bool isDiscardable(OutputSection &Sec) {
825825
if (!Sec.Phdrs.empty())
826826
return false;
827827

828-
// We do not want to remove sections that reference symbols in address and
829-
// other expressions. We add script symbols as undefined, and want to ensure
830-
// all of them are defined in the output, hence have to keep them.
828+
// We do not want to remove OutputSections with expressions that reference
829+
// symbols even if the OutputSection is empty. We want to ensure that the
830+
// expressions can be evaluated and report an error if they cannot.
831831
if (Sec.ExpressionsUseSymbols)
832832
return false;
833833

834+
// OutputSections may be referenced by name in ADDR and LOADADDR expressions,
835+
// as an empty Section can has a valid VMA and LMA we keep the OutputSection
836+
// to maintain the integrity of the other Expression.
837+
if (Sec.UsedInExpression)
838+
return false;
839+
834840
for (BaseCommand *Base : Sec.SectionCommands) {
835841
if (auto Cmd = dyn_cast<SymbolAssignment>(Base))
836842
// Don't create empty output sections just for unreferenced PROVIDE

Diff for: ‎lld/ELF/OutputSections.h

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class OutputSection final : public BaseCommand, public SectionBase {
9090
bool NonAlloc = false;
9191
bool Noload = false;
9292
bool ExpressionsUseSymbols = false;
93+
bool UsedInExpression = false;
9394
bool InOverlay = false;
9495

9596
void finalize();

Diff for: ‎lld/ELF/ScriptParser.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ Expr ScriptParser::readPrimary() {
11541154
if (Tok == "ADDR") {
11551155
StringRef Name = readParenLiteral();
11561156
OutputSection *Sec = Script->getOrCreateOutputSection(Name);
1157+
Sec->UsedInExpression = true;
11571158
return [=]() -> ExprValue {
11581159
checkIfExists(Sec, Location);
11591160
return {Sec, false, 0, Location};
@@ -1230,6 +1231,7 @@ Expr ScriptParser::readPrimary() {
12301231
if (Tok == "LOADADDR") {
12311232
StringRef Name = readParenLiteral();
12321233
OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1234+
Cmd->UsedInExpression = true;
12331235
return [=] {
12341236
checkIfExists(Cmd, Location);
12351237
return Cmd->getLMA();
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# REQUIRES: x86
2+
# RUN: echo ".text; nop; .data; .byte 0" \
3+
# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o
4+
# RUN: ld.lld -o %t --script %s %t.o
5+
# RUN: llvm-readelf -program-headers %t | FileCheck %s
6+
7+
## Check we do not remove the empty output sections used in LOADADDR/ADDR
8+
## expressions and hence can evaluate the correct addresses.
9+
10+
# CHECK: Program Headers:
11+
# CHECK-NEXT: Type Offset VirtAddr PhysAddr
12+
# CHECK-NEXT: LOAD 0x001000 0x0000000000080000 0x0000000000080000
13+
# CHECK-NEXT: LOAD 0x001001 0x0000000000080001 0x0000000000082000
14+
15+
# CHECK: Section to Segment mapping:
16+
# CHECK: 00 .empty .text
17+
# CHECK-NEXT: 01 .data
18+
19+
SECTIONS {
20+
. = 0x00080000;
21+
.empty : { *(.empty ) }
22+
.text : AT(LOADADDR(.empty) + SIZEOF(.empty)) { *(.text) }
23+
.data : AT(ADDR(.empty) + 0x2000) { *(.data) }
24+
}

0 commit comments

Comments
 (0)
Please sign in to comment.