@@ -56,6 +56,12 @@ template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
56
56
Cmd->Sym = Sym->body ();
57
57
}
58
58
59
+ template <class ELFT > static void addSymbol (SymbolAssignment *Cmd) {
60
+ if (Cmd->IsAbsolute )
61
+ addRegular<ELFT>(Cmd);
62
+ else
63
+ addSynthetic<ELFT>(Cmd);
64
+ }
59
65
// If a symbol was in PROVIDE(), we need to define it only when
60
66
// it is an undefined symbol.
61
67
template <class ELFT > static bool shouldDefine (SymbolAssignment *Cmd) {
@@ -184,7 +190,7 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
184
190
for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands ) {
185
191
if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get ())) {
186
192
if (shouldDefine<ELFT>(OutCmd))
187
- addSynthetic <ELFT>(OutCmd);
193
+ addSymbol <ELFT>(OutCmd);
188
194
OutCmd->GoesAfter = Ret.empty () ? nullptr : Ret.back ();
189
195
continue ;
190
196
}
@@ -267,6 +273,26 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
267
273
}
268
274
}
269
275
276
+ // Sets value of a section-defined symbol. Two kinds of
277
+ // symbols are processed: synthetic symbols, whose value
278
+ // is an offset from beginning of section and regular
279
+ // symbols whose value is absolute.
280
+ template <class ELFT >
281
+ static void assignSectionSymbol (SymbolAssignment *Cmd,
282
+ OutputSectionBase<ELFT> *Sec,
283
+ typename ELFT::uint Off) {
284
+ if (!Cmd->Sym )
285
+ return ;
286
+
287
+ if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym )) {
288
+ Body->Section = Sec;
289
+ Body->Value = Cmd->Expression (Sec->getVA () + Off) - Sec->getVA ();
290
+ return ;
291
+ }
292
+ auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym );
293
+ Body->Value = Cmd->Expression (Sec->getVA () + Off);
294
+ }
295
+
270
296
// Linker script may define start and end symbols for special section types,
271
297
// like .got, .eh_frame_hdr, .eh_frame and others. Those sections are not a list
272
298
// of regular input input sections, therefore our way of defining symbols for
@@ -280,12 +306,7 @@ void addStartEndSymbols(OutputSectionCommand *Cmd,
280
306
281
307
for (std::unique_ptr<BaseCommand> &Base : Cmd->Commands ) {
282
308
if (auto *AssignCmd = dyn_cast<SymbolAssignment>(Base.get ())) {
283
- if (auto *Sym = cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym )) {
284
- Sym->Section = Sec;
285
- Sym->Value =
286
- AssignCmd->Expression (Sec->getVA () + (Start ? 0 : Sec->getSize ())) -
287
- Sec->getVA ();
288
- }
309
+ assignSectionSymbol<ELFT>(AssignCmd, Sec, Start ? 0 : Sec->getSize ());
289
310
} else {
290
311
if (!Start && isa<SymbolAssignment>(PrevCmd))
291
312
error (" section '" + Sec->getName () +
@@ -322,19 +343,13 @@ void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) {
322
343
if (D != AssignCmd->GoesAfter )
323
344
break ;
324
345
325
- uintX_t Value = AssignCmd->Expression (Sec->getVA () + Off) - Sec->getVA ();
326
346
if (AssignCmd->Name == " ." ) {
327
347
// Update to location counter means update to section size.
328
- Off = Value ;
348
+ Off = AssignCmd-> Expression (Sec-> getVA () + Off) - Sec-> getVA () ;
329
349
Sec->setSize (Off);
330
350
continue ;
331
351
}
332
-
333
- if (DefinedSynthetic<ELFT> *Sym =
334
- cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym )) {
335
- Sym->Section = OutSec;
336
- Sym->Value = Value;
337
- }
352
+ assignSectionSymbol<ELFT>(AssignCmd, Sec, Off);
338
353
}
339
354
};
340
355
@@ -631,7 +646,7 @@ class elf::ScriptParser : public ScriptParserBase {
631
646
unsigned readPhdrType ();
632
647
SortKind readSortKind ();
633
648
SymbolAssignment *readProvideHidden (bool Provide, bool Hidden);
634
- SymbolAssignment *readProvideOrAssignment (StringRef Tok);
649
+ SymbolAssignment *readProvideOrAssignment (StringRef Tok, bool MakeAbsolute );
635
650
void readSort ();
636
651
Expr readAssert ();
637
652
@@ -710,7 +725,7 @@ void ScriptParser::readLinkerScript() {
710
725
readSections ();
711
726
} else if (Tok == " VERSION" ) {
712
727
readVersion ();
713
- } else if (SymbolAssignment *Cmd = readProvideOrAssignment (Tok)) {
728
+ } else if (SymbolAssignment *Cmd = readProvideOrAssignment (Tok, true )) {
714
729
if (Opt.HasContents )
715
730
Opt.Commands .emplace_back (Cmd);
716
731
else
@@ -872,7 +887,7 @@ void ScriptParser::readSections() {
872
887
expect (" {" );
873
888
while (!Error && !skip (" }" )) {
874
889
StringRef Tok = next ();
875
- BaseCommand *Cmd = readProvideOrAssignment (Tok);
890
+ BaseCommand *Cmd = readProvideOrAssignment (Tok, true );
876
891
if (!Cmd) {
877
892
if (Tok == " ASSERT" )
878
893
Cmd = new AssertCommand (readAssert ());
@@ -1020,7 +1035,7 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) {
1020
1035
1021
1036
while (!Error && !skip (" }" )) {
1022
1037
StringRef Tok = next ();
1023
- if (SymbolAssignment *Assignment = readProvideOrAssignment (Tok))
1038
+ if (SymbolAssignment *Assignment = readProvideOrAssignment (Tok, false ))
1024
1039
Cmd->Commands .emplace_back (Assignment);
1025
1040
else if (Tok == " FILL" )
1026
1041
Cmd->Filler = readFill ();
@@ -1063,7 +1078,8 @@ SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1063
1078
return Cmd;
1064
1079
}
1065
1080
1066
- SymbolAssignment *ScriptParser::readProvideOrAssignment (StringRef Tok) {
1081
+ SymbolAssignment *ScriptParser::readProvideOrAssignment (StringRef Tok,
1082
+ bool MakeAbsolute) {
1067
1083
SymbolAssignment *Cmd = nullptr ;
1068
1084
if (peek () == " =" || peek () == " +=" ) {
1069
1085
Cmd = readAssignment (Tok);
@@ -1075,6 +1091,8 @@ SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
1075
1091
} else if (Tok == " PROVIDE_HIDDEN" ) {
1076
1092
Cmd = readProvideHidden (true , true );
1077
1093
}
1094
+ if (Cmd && MakeAbsolute)
1095
+ Cmd->IsAbsolute = true ;
1078
1096
return Cmd;
1079
1097
}
1080
1098
@@ -1153,11 +1171,18 @@ static uint64_t getHeaderSize() {
1153
1171
1154
1172
SymbolAssignment *ScriptParser::readAssignment (StringRef Name) {
1155
1173
StringRef Op = next ();
1174
+ bool IsAbsolute = false ;
1175
+ Expr E;
1156
1176
assert (Op == " =" || Op == " +=" );
1157
- Expr E = readExpr ();
1177
+ if (skip (" ABSOLUTE" )) {
1178
+ E = readParenExpr ();
1179
+ IsAbsolute = true ;
1180
+ } else {
1181
+ E = readExpr ();
1182
+ }
1158
1183
if (Op == " +=" )
1159
1184
E = [=](uint64_t Dot) { return getSymbolValue (Name, Dot) + E (Dot); };
1160
- return new SymbolAssignment (Name, E);
1185
+ return new SymbolAssignment (Name, E, IsAbsolute );
1161
1186
}
1162
1187
1163
1188
// This is an operator-precedence parser to parse a linker
0 commit comments