[lld] [ELF] OVERLAY: support optional start address and LMA (PR #77272)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 7 21:37:28 PST 2024
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/77272
https://reviews.llvm.org/D44780 implemented rudimentary support for
OVERLAY. The start address and `AT(ldaddr)` in `OVERLAY [start] :
[NOCROSSREFS] [AT ( ldaddr )]` are not optional.
In addition, there are two issues:
* When the start address is `.`, subsequent sections don't share the
address of the first overlay section.
* When the first overlay section is empty and discardable, `p_paddr` is
incorrectly zero. This is because a discarded section has a zero
address, causing `prev->getLMA() + prev->size` where `prev` refers to
the first section to evaluate to zero.
This patch supports optional start address and LMA and fix the issues.
Close #77265
>From 54a4e2b2c1f65693c7e41abfb456bddfe65e12bd Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 7 Jan 2024 21:37:19 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
---
lld/ELF/ScriptParser.cpp | 25 ++++++++++++++++---------
lld/test/ELF/linkerscript/overlay.test | 19 +++++++++++--------
2 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 55b10f0c59b516..036aa16ad03e97 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -531,13 +531,15 @@ void ScriptParser::readSearchDir() {
// linker's sections sanity check failures.
// https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
- // VA and LMA expressions are optional, though for simplicity of
- // implementation we assume they are not. That is what OVERLAY was designed
- // for first of all: to allow sections with overlapping VAs at different LMAs.
- Expr addrExpr = readExpr();
- expect(":");
- expect("AT");
- Expr lmaExpr = readParenExpr();
+ Expr addrExpr;
+ if (consume(":")) {
+ addrExpr = [] { return script->getDot(); };
+ } else {
+ addrExpr = readExpr();
+ expect(":");
+ }
+ Expr lmaExpr =
+ consume("AT") ? readParenExpr() : [] { return script->getDot(); };
expect("{");
SmallVector<SectionCommand *, 0> v;
@@ -547,10 +549,15 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
// starting from the base load address specified.
OutputDesc *osd = readOverlaySectionDescription();
osd->osec.addrExpr = addrExpr;
- if (prev)
+ if (prev) {
osd->osec.lmaExpr = [=] { return prev->getLMA() + prev->size; };
- else
+ } else {
osd->osec.lmaExpr = lmaExpr;
+ // Ensure that the first section, even if empty, is not discarded.
+ // Subsequent sections share its address.
+ osd->osec.usedInExpression = true;
+ addrExpr = [=]() -> ExprValue { return {&osd->osec, false, 0, ""}; };
+ }
v.push_back(osd);
prev = &osd->osec;
}
diff --git a/lld/test/ELF/linkerscript/overlay.test b/lld/test/ELF/linkerscript/overlay.test
index 942e0a2971beca..a40ddb48cf5dba 100644
--- a/lld/test/ELF/linkerscript/overlay.test
+++ b/lld/test/ELF/linkerscript/overlay.test
@@ -16,9 +16,10 @@
# CHECK-NEXT: .small1 PROGBITS 0000000000001000 002000 000004
# CHECK-NEXT: .small2 PROGBITS 0000000000001008 002008 000004
# CHECK-NEXT: .big2 PROGBITS 0000000000001008 003008 000008
+# CHECK-NEXT: .empty3 PROGBITS 0000000000001010 003010 000000
# CHECK-NEXT: .small3 PROGBITS 0000000000001010 003010 000004
-# CHECK-NEXT: .big3 PROGBITS 0000000000001014 003014 000008
-# CHECK-NEXT: .text PROGBITS 0000000000001024 003024 000001
+# CHECK-NEXT: .big3 PROGBITS 0000000000001010 004010 000008
+# CHECK-NEXT: .text PROGBITS 0000000000001018 004018 000001
# CHECK: Program Headers:
# CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
@@ -26,10 +27,9 @@
# CHECK-NEXT: LOAD 0x002000 0x0000000000001000 0x0000000000001008 0x000004 0x000004 R 0x1000
# CHECK-NEXT: LOAD 0x002008 0x0000000000001008 0x0000000000002008 0x000004 0x000004 R 0x1000
# CHECK-NEXT: LOAD 0x003008 0x0000000000001008 0x000000000000200c 0x000008 0x000008 R 0x1000
-## FIXME Fix p_paddr when the first section in an overlay is empty and discarded.
-# CHECK-NEXT: LOAD 0x003010 0x0000000000001010 0x0000000000000000 0x000004 0x000004 R 0x1000
-# CHECK-NEXT: LOAD 0x003014 0x0000000000001014 0x0000000000000004 0x000008 0x000008 R 0x1000
-# CHECK-NEXT: LOAD 0x003024 0x0000000000001024 0x0000000000000014 0x000001 0x000001 R E 0x1000
+# CHECK-NEXT: LOAD 0x003010 0x0000000000001010 0x0000000000002014 0x000004 0x000004 R 0x1000
+# CHECK-NEXT: LOAD 0x004010 0x0000000000001010 0x0000000000002018 0x000008 0x000008 R 0x1000
+# CHECK-NEXT: LOAD 0x004018 0x0000000000001018 0x0000000000002020 0x000001 0x000001 R E 0x1000
# RUN: not ld.lld a.o -T err1.t 2>&1 | FileCheck %s --check-prefix=ERR1 --match-full-lines --strict-whitespace
# ERR1:{{.*}}error: err1.t:3: { expected, but got 0x3000
@@ -57,14 +57,17 @@ _start:
#--- a.t
SECTIONS {
- OVERLAY 0x1000 : AT( 0x1000 ) {
+## LMA defaults to VMA
+ OVERLAY 0x1000 : {
.big1 { *(.big1) }
.small1 { *(.small1) }
}
- OVERLAY 0x1008 : AT (0x2008) {
+## .big2 starts at ADDR(.small2)
+ OVERLAY : AT (0x2008) {
.small2 { *(.small2) }
.big2 { *(.big2) }
}
+## .big3 starts at .small3
OVERLAY . : AT (0x2014) {
.empty3 { *(.empty3) }
.small3 { *(.small3) }
More information about the llvm-commits
mailing list