@@ -47,7 +47,7 @@ using namespace lld::elf;
47
47
namespace {
48
48
class ScriptParser final : ScriptLexer {
49
49
public:
50
- ScriptParser (Ctx &ctx, MemoryBufferRef mb) : ScriptLexer(ctx, mb) {}
50
+ ScriptParser (Ctx &ctx, MemoryBufferRef mb) : ScriptLexer(ctx, mb), ctx(ctx) {}
51
51
52
52
void readLinkerScript ();
53
53
void readVersionScript ();
@@ -126,6 +126,8 @@ class ScriptParser final : ScriptLexer {
126
126
std::pair<SmallVector<SymbolVersion, 0 >, SmallVector<SymbolVersion, 0 >>
127
127
readSymbols ();
128
128
129
+ Ctx &ctx;
130
+
129
131
// If we are currently parsing a PROVIDE|PROVIDE_HIDDEN command,
130
132
// then this member is set to the PROVIDE symbol name.
131
133
std::optional<llvm::StringRef> activeProvideSym;
@@ -140,16 +142,16 @@ static StringRef unquote(StringRef s) {
140
142
141
143
// Some operations only support one non absolute value. Move the
142
144
// absolute one to the right hand side for convenience.
143
- static void moveAbsRight (ExprValue &a, ExprValue &b) {
145
+ static void moveAbsRight (LinkerScript &s, ExprValue &a, ExprValue &b) {
144
146
if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute ()))
145
147
std::swap (a, b);
146
148
if (!b.isAbsolute ())
147
- ctx. script -> recordError (
148
- a. loc + " : at least one side of the expression must be absolute" );
149
+ s. recordError (a. loc +
150
+ " : at least one side of the expression must be absolute" );
149
151
}
150
152
151
- static ExprValue add (ExprValue a, ExprValue b) {
152
- moveAbsRight (a, b);
153
+ static ExprValue add (LinkerScript &s, ExprValue a, ExprValue b) {
154
+ moveAbsRight (s, a, b);
153
155
return {a.sec , a.forceAbsolute , a.getSectionOffset () + b.getValue (), a.loc };
154
156
}
155
157
@@ -160,20 +162,20 @@ static ExprValue sub(ExprValue a, ExprValue b) {
160
162
return {a.sec , false , a.getSectionOffset () - b.getValue (), a.loc };
161
163
}
162
164
163
- static ExprValue bitAnd (ExprValue a, ExprValue b) {
164
- moveAbsRight (a, b);
165
+ static ExprValue bitAnd (LinkerScript &s, ExprValue a, ExprValue b) {
166
+ moveAbsRight (s, a, b);
165
167
return {a.sec , a.forceAbsolute ,
166
168
(a.getValue () & b.getValue ()) - a.getSecAddr (), a.loc };
167
169
}
168
170
169
- static ExprValue bitXor (ExprValue a, ExprValue b) {
170
- moveAbsRight (a, b);
171
+ static ExprValue bitXor (LinkerScript &s, ExprValue a, ExprValue b) {
172
+ moveAbsRight (s, a, b);
171
173
return {a.sec , a.forceAbsolute ,
172
174
(a.getValue () ^ b.getValue ()) - a.getSecAddr (), a.loc };
173
175
}
174
176
175
- static ExprValue bitOr (ExprValue a, ExprValue b) {
176
- moveAbsRight (a, b);
177
+ static ExprValue bitOr (LinkerScript &s, ExprValue a, ExprValue b) {
178
+ moveAbsRight (s, a, b);
177
179
return {a.sec , a.forceAbsolute ,
178
180
(a.getValue () | b.getValue ()) - a.getSecAddr (), a.loc };
179
181
}
@@ -561,15 +563,15 @@ void ScriptParser::readSearchDir() {
561
563
SmallVector<SectionCommand *, 0 > ScriptParser::readOverlay () {
562
564
Expr addrExpr;
563
565
if (consume (" :" )) {
564
- addrExpr = [& ] { return ctx. script ->getDot (); };
566
+ addrExpr = [s = ctx. script ] { return s ->getDot (); };
565
567
} else {
566
568
addrExpr = readExpr ();
567
569
expect (" :" );
568
570
}
569
571
// When AT is omitted, LMA should equal VMA. script->getDot() when evaluating
570
572
// lmaExpr will ensure this, even if the start address is specified.
571
- Expr lmaExpr =
572
- consume ( " AT " ) ? readParenExpr () : [& ] { return ctx. script ->getDot (); };
573
+ Expr lmaExpr = consume ( " AT " ) ? readParenExpr ()
574
+ : [s = ctx. script ] { return s ->getDot (); };
573
575
expect (" {" );
574
576
575
577
SmallVector<SectionCommand *, 0 > v;
@@ -891,10 +893,10 @@ Expr ScriptParser::readAssert() {
891
893
StringRef msg = readName ();
892
894
expect (" )" );
893
895
894
- return [=] {
896
+ return [=, s = ctx. script ]() -> ExprValue {
895
897
if (!e ().getValue ())
896
898
errorOrWarn (msg);
897
- return ctx. script ->getDot ();
899
+ return s ->getDot ();
898
900
};
899
901
}
900
902
@@ -1196,8 +1198,8 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
1196
1198
Expr e = readExpr ();
1197
1199
if (op != " =" ) {
1198
1200
std::string loc = getCurrentLocation ();
1199
- e = [=, c = op[0 ]]() -> ExprValue {
1200
- ExprValue lhs = ctx. script ->getSymbolValue (name, loc);
1201
+ e = [=, s = ctx. script , c = op[0 ]]() -> ExprValue {
1202
+ ExprValue lhs = s ->getSymbolValue (name, loc);
1201
1203
switch (c) {
1202
1204
case ' *' :
1203
1205
return lhs.getValue () * e ().getValue ();
@@ -1207,7 +1209,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
1207
1209
error (loc + " : division by zero" );
1208
1210
return 0 ;
1209
1211
case ' +' :
1210
- return add (lhs, e ());
1212
+ return add (*s, lhs, e ());
1211
1213
case ' -' :
1212
1214
return sub (lhs, e ());
1213
1215
case ' <' :
@@ -1241,7 +1243,7 @@ Expr ScriptParser::readExpr() {
1241
1243
1242
1244
Expr ScriptParser::combine (StringRef op, Expr l, Expr r) {
1243
1245
if (op == " +" )
1244
- return [=] { return add (l (), r ()); };
1246
+ return [=, s = ctx. script ] { return add (*s, l (), r ()); };
1245
1247
if (op == " -" )
1246
1248
return [=] { return sub (l (), r ()); };
1247
1249
if (op == " *" )
@@ -1285,11 +1287,11 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
1285
1287
if (op == " &&" )
1286
1288
return [=] { return l ().getValue () && r ().getValue (); };
1287
1289
if (op == " &" )
1288
- return [=] { return bitAnd (l (), r ()); };
1290
+ return [=, s = ctx. script ] { return bitAnd (*s, l (), r ()); };
1289
1291
if (op == " ^" )
1290
- return [=] { return bitXor (l (), r ()); };
1292
+ return [=, s = ctx. script ] { return bitXor (*s, l (), r ()); };
1291
1293
if (op == " |" )
1292
- return [=] { return bitOr (l (), r ()); };
1294
+ return [=, s = ctx. script ] { return bitOr (*s, l (), r ()); };
1293
1295
llvm_unreachable (" invalid operator" );
1294
1296
}
1295
1297
@@ -1324,7 +1326,7 @@ Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
1324
1326
1325
1327
Expr ScriptParser::getPageSize () {
1326
1328
std::string location = getCurrentLocation ();
1327
- return [=]() -> uint64_t {
1329
+ return [=, &ctx = this -> ctx ]() -> uint64_t {
1328
1330
if (ctx.target )
1329
1331
return ctx.arg .commonPageSize ;
1330
1332
error (location + " : unable to calculate page size" );
@@ -1337,7 +1339,7 @@ Expr ScriptParser::readConstant() {
1337
1339
if (s == " COMMONPAGESIZE" )
1338
1340
return getPageSize ();
1339
1341
if (s == " MAXPAGESIZE" )
1340
- return [&] { return ctx.arg .maxPageSize ; };
1342
+ return [&ctx = this -> ctx ] { return ctx.arg .maxPageSize ; };
1341
1343
setError (" unknown constant: " + s);
1342
1344
return [] { return 0 ; };
1343
1345
}
@@ -1459,9 +1461,10 @@ StringRef ScriptParser::readParenName() {
1459
1461
return tok;
1460
1462
}
1461
1463
1462
- static void checkIfExists (const OutputSection &osec, StringRef location) {
1463
- if (osec.location .empty () && ctx.script ->errorOnMissingSection )
1464
- ctx.script ->recordError (location + " : undefined section " + osec.name );
1464
+ static void checkIfExists (LinkerScript &script, const OutputSection &osec,
1465
+ StringRef location) {
1466
+ if (osec.location .empty () && script.errorOnMissingSection )
1467
+ script.recordError (location + " : undefined section " + osec.name );
1465
1468
}
1466
1469
1467
1470
static bool isValidSymbolName (StringRef s) {
@@ -1505,8 +1508,8 @@ Expr ScriptParser::readPrimary() {
1505
1508
StringRef name = readParenName ();
1506
1509
OutputSection *osec = &ctx.script ->getOrCreateOutputSection (name)->osec ;
1507
1510
osec->usedInExpression = true ;
1508
- return [=]() -> ExprValue {
1509
- checkIfExists (*osec, location);
1511
+ return [=, s = ctx. script ]() -> ExprValue {
1512
+ checkIfExists (*s, * osec, location);
1510
1513
return {osec, false , 0 , location};
1511
1514
};
1512
1515
}
@@ -1515,8 +1518,9 @@ Expr ScriptParser::readPrimary() {
1515
1518
Expr e = readExpr ();
1516
1519
if (consume (" )" )) {
1517
1520
e = checkAlignment (e, location);
1518
- return
1519
- [=] { return alignToPowerOf2 (ctx.script ->getDot (), e ().getValue ()); };
1521
+ return [=, s = ctx.script ] {
1522
+ return alignToPowerOf2 (s->getDot (), e ().getValue ());
1523
+ };
1520
1524
}
1521
1525
expect (" ," );
1522
1526
Expr e2 = checkAlignment (readExpr (), location);
@@ -1530,8 +1534,8 @@ Expr ScriptParser::readPrimary() {
1530
1534
if (tok == " ALIGNOF" ) {
1531
1535
StringRef name = readParenName ();
1532
1536
OutputSection *osec = &ctx.script ->getOrCreateOutputSection (name)->osec ;
1533
- return [=] {
1534
- checkIfExists (*osec, location);
1537
+ return [=, s = ctx. script ] {
1538
+ checkIfExists (*s, * osec, location);
1535
1539
return osec->addralign ;
1536
1540
};
1537
1541
}
@@ -1546,16 +1550,16 @@ Expr ScriptParser::readPrimary() {
1546
1550
readExpr ();
1547
1551
expect (" )" );
1548
1552
ctx.script ->seenDataAlign = true ;
1549
- return [=] {
1553
+ return [=, s = ctx. script ] {
1550
1554
uint64_t align = std::max (uint64_t (1 ), e ().getValue ());
1551
- return (ctx. script ->getDot () + align - 1 ) & -align;
1555
+ return (s ->getDot () + align - 1 ) & -align;
1552
1556
};
1553
1557
}
1554
1558
if (tok == " DATA_SEGMENT_END" ) {
1555
1559
expect (" (" );
1556
1560
expect (" ." );
1557
1561
expect (" )" );
1558
- return [& ] { return ctx. script ->getDot (); };
1562
+ return [s = ctx. script ] { return s ->getDot (); };
1559
1563
}
1560
1564
if (tok == " DATA_SEGMENT_RELRO_END" ) {
1561
1565
// GNU linkers implements more complicated logic to handle
@@ -1567,7 +1571,7 @@ Expr ScriptParser::readPrimary() {
1567
1571
readExpr ();
1568
1572
expect (" )" );
1569
1573
ctx.script ->seenRelroEnd = true ;
1570
- return [&] {
1574
+ return [&ctx = this -> ctx ] {
1571
1575
return alignToPowerOf2 (ctx.script ->getDot (), ctx.arg .maxPageSize );
1572
1576
};
1573
1577
}
@@ -1576,7 +1580,7 @@ Expr ScriptParser::readPrimary() {
1576
1580
// Return 1 if s is defined. If the definition is only found in a linker
1577
1581
// script, it must happen before this DEFINED.
1578
1582
auto order = ctx.scriptSymOrderCounter ++;
1579
- return [=] {
1583
+ return [=, &ctx = this -> ctx ] {
1580
1584
Symbol *s = symtab.find (name);
1581
1585
return s && s->isDefined () && ctx.scriptSymOrder .lookup (s) < order ? 1
1582
1586
: 0 ;
@@ -1594,8 +1598,8 @@ Expr ScriptParser::readPrimary() {
1594
1598
StringRef name = readParenName ();
1595
1599
OutputSection *osec = &ctx.script ->getOrCreateOutputSection (name)->osec ;
1596
1600
osec->usedInExpression = true ;
1597
- return [=] {
1598
- checkIfExists (*osec, location);
1601
+ return [=, s = ctx. script ] {
1602
+ checkIfExists (*s, * osec, location);
1599
1603
return osec->getLMA ();
1600
1604
};
1601
1605
}
@@ -1647,7 +1651,7 @@ Expr ScriptParser::readPrimary() {
1647
1651
1648
1652
// Tok is the dot.
1649
1653
if (tok == " ." )
1650
- return [=] { return ctx.script ->getSymbolValue (tok, location); };
1654
+ return [=, s = ctx.script ] { return s ->getSymbolValue (tok, location); };
1651
1655
1652
1656
// Tok is a literal number.
1653
1657
if (std::optional<uint64_t > val = parseInt (tok))
@@ -1662,7 +1666,7 @@ Expr ScriptParser::readPrimary() {
1662
1666
ctx.script ->provideMap [*activeProvideSym].push_back (tok);
1663
1667
else
1664
1668
ctx.script ->referencedSymbols .push_back (tok);
1665
- return [=] { return ctx.script ->getSymbolValue (tok, location); };
1669
+ return [=, s = ctx.script ] { return s ->getSymbolValue (tok, location); };
1666
1670
}
1667
1671
1668
1672
Expr ScriptParser::readTernary (Expr cond) {
0 commit comments