Rename CurAddressState -> Ctx.

We used CurAddressState to capture a dynamic context just like
we use lambdas to capture static contexts. So, CurAddressState
is used everywhere in LinkerScript.cpp. It is worth a shorter
name.

llvm-svn: 315418
This commit is contained in:
Rui Ueyama 2017-10-11 02:45:54 +00:00
parent d9a283463a
commit 29b240c671
2 changed files with 40 additions and 45 deletions

View File

@ -106,12 +106,12 @@ void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
uint64_t Val = E().getValue(); uint64_t Val = E().getValue();
if (Val < Dot && InSec) if (Val < Dot && InSec)
error(Loc + ": unable to move location counter backward for: " + error(Loc + ": unable to move location counter backward for: " +
CurAddressState->OutSec->Name); Ctx->OutSec->Name);
Dot = Val; Dot = Val;
// Update to location counter means update to section size. // Update to location counter means update to section size.
if (InSec) if (InSec)
CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr; Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr;
} }
// This function is called from processSectionCommands, // This function is called from processSectionCommands,
@ -349,14 +349,13 @@ void LinkerScript::processSectionCommands(OutputSectionFactory &Factory) {
// which will map to whatever the first actual section is. // which will map to whatever the first actual section is.
Aether = make<OutputSection>("", 0, SHF_ALLOC); Aether = make<OutputSection>("", 0, SHF_ALLOC);
Aether->SectionIndex = 1; Aether->SectionIndex = 1;
auto State = make_unique<AddressState>();
// CurAddressState captures the local AddressState and makes it accessible // Ctx captures the local AddressState and makes it accessible deliberately.
// deliberately. This is needed as there are some cases where we cannot just // This is needed as there are some cases where we cannot just
// thread the current state through to a lambda function created by the // thread the current state through to a lambda function created by the
// script parser. // script parser.
CurAddressState = State.get(); Ctx = make_unique<AddressState>();
CurAddressState->OutSec = Aether; Ctx->OutSec = Aether;
for (size_t I = 0; I < SectionCommands.size(); ++I) { for (size_t I = 0; I < SectionCommands.size(); ++I) {
// Handle symbol assignments outside of any output section. // Handle symbol assignments outside of any output section.
@ -415,7 +414,7 @@ void LinkerScript::processSectionCommands(OutputSectionFactory &Factory) {
Sec->Type = SHT_NOBITS; Sec->Type = SHT_NOBITS;
} }
} }
CurAddressState = nullptr; Ctx = nullptr;
} }
void LinkerScript::fabricateDefaultCommands() { void LinkerScript::fabricateDefaultCommands() {
@ -468,14 +467,14 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
} }
uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) { uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
bool IsTbss = (CurAddressState->OutSec->Flags & SHF_TLS) && bool IsTbss =
CurAddressState->OutSec->Type == SHT_NOBITS; (Ctx->OutSec->Flags & SHF_TLS) && Ctx->OutSec->Type == SHT_NOBITS;
uint64_t Start = IsTbss ? Dot + CurAddressState->ThreadBssOffset : Dot; uint64_t Start = IsTbss ? Dot + Ctx->ThreadBssOffset : Dot;
Start = alignTo(Start, Align); Start = alignTo(Start, Align);
uint64_t End = Start + Size; uint64_t End = Start + Size;
if (IsTbss) if (IsTbss)
CurAddressState->ThreadBssOffset = End - Dot; Ctx->ThreadBssOffset = End - Dot;
else else
Dot = End; Dot = End;
return End; return End;
@ -484,43 +483,41 @@ uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
void LinkerScript::output(InputSection *S) { void LinkerScript::output(InputSection *S) {
uint64_t Before = advance(0, 1); uint64_t Before = advance(0, 1);
uint64_t Pos = advance(S->getSize(), S->Alignment); uint64_t Pos = advance(S->getSize(), S->Alignment);
S->OutSecOff = Pos - S->getSize() - CurAddressState->OutSec->Addr; S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
// Update output section size after adding each section. This is so that // Update output section size after adding each section. This is so that
// SIZEOF works correctly in the case below: // SIZEOF works correctly in the case below:
// .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
CurAddressState->OutSec->Size = Pos - CurAddressState->OutSec->Addr; Ctx->OutSec->Size = Pos - Ctx->OutSec->Addr;
// If there is a memory region associated with this input section, then // If there is a memory region associated with this input section, then
// place the section in that region and update the region index. // place the section in that region and update the region index.
if (CurAddressState->MemRegion) { if (Ctx->MemRegion) {
uint64_t &CurOffset = uint64_t &CurOffset = Ctx->MemRegionOffset[Ctx->MemRegion];
CurAddressState->MemRegionOffset[CurAddressState->MemRegion];
CurOffset += Pos - Before; CurOffset += Pos - Before;
uint64_t CurSize = CurOffset - CurAddressState->MemRegion->Origin; uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin;
if (CurSize > CurAddressState->MemRegion->Length) { if (CurSize > Ctx->MemRegion->Length) {
uint64_t OverflowAmt = CurSize - CurAddressState->MemRegion->Length; uint64_t OverflowAmt = CurSize - Ctx->MemRegion->Length;
error("section '" + CurAddressState->OutSec->Name + error("section '" + Ctx->OutSec->Name + "' will not fit in region '" +
"' will not fit in region '" + CurAddressState->MemRegion->Name + Ctx->MemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
"': overflowed by " + Twine(OverflowAmt) + " bytes"); " bytes");
} }
} }
} }
void LinkerScript::switchTo(OutputSection *Sec) { void LinkerScript::switchTo(OutputSection *Sec) {
if (CurAddressState->OutSec == Sec) if (Ctx->OutSec == Sec)
return; return;
CurAddressState->OutSec = Sec; Ctx->OutSec = Sec;
CurAddressState->OutSec->Addr = Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
advance(0, CurAddressState->OutSec->Alignment);
// If neither AT nor AT> is specified for an allocatable section, the linker // If neither AT nor AT> is specified for an allocatable section, the linker
// will set the LMA such that the difference between VMA and LMA for the // will set the LMA such that the difference between VMA and LMA for the
// section is the same as the preceding output section in the same region // section is the same as the preceding output section in the same region
// https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
if (CurAddressState->LMAOffset) if (Ctx->LMAOffset)
CurAddressState->OutSec->LMAOffset = CurAddressState->LMAOffset(); Ctx->OutSec->LMAOffset = Ctx->LMAOffset();
} }
void LinkerScript::process(BaseCommand &Base) { void LinkerScript::process(BaseCommand &Base) {
@ -532,9 +529,9 @@ void LinkerScript::process(BaseCommand &Base) {
// Handle BYTE(), SHORT(), LONG(), or QUAD(). // Handle BYTE(), SHORT(), LONG(), or QUAD().
if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) { if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
Cmd->Offset = Dot - CurAddressState->OutSec->Addr; Cmd->Offset = Dot - Ctx->OutSec->Addr;
Dot += Cmd->Size; Dot += Cmd->Size;
CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr; Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr;
return; return;
} }
@ -559,7 +556,7 @@ void LinkerScript::process(BaseCommand &Base) {
if (!Sec->Live) if (!Sec->Live)
continue; continue;
assert(CurAddressState->OutSec == Sec->getParent()); assert(Ctx->OutSec == Sec->getParent());
output(Sec); output(Sec);
} }
} }
@ -605,20 +602,20 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
else if (Sec->AddrExpr) else if (Sec->AddrExpr)
setDot(Sec->AddrExpr, Sec->Location, false); setDot(Sec->AddrExpr, Sec->Location, false);
CurAddressState->MemRegion = Sec->MemRegion; Ctx->MemRegion = Sec->MemRegion;
if (CurAddressState->MemRegion) if (Ctx->MemRegion)
Dot = CurAddressState->MemRegionOffset[CurAddressState->MemRegion]; Dot = Ctx->MemRegionOffset[Ctx->MemRegion];
if (Sec->LMAExpr) { if (Sec->LMAExpr) {
uint64_t D = Dot; uint64_t D = Dot;
CurAddressState->LMAOffset = [=] { return Sec->LMAExpr().getValue() - D; }; Ctx->LMAOffset = [=] { return Sec->LMAExpr().getValue() - D; };
} }
switchTo(Sec); switchTo(Sec);
// We do not support custom layout for compressed debug sectons. // We do not support custom layout for compressed debug sectons.
// At this point we already know their size and have compressed content. // At this point we already know their size and have compressed content.
if (CurAddressState->OutSec->Flags & SHF_COMPRESSED) if (Ctx->OutSec->Flags & SHF_COMPRESSED)
return; return;
for (BaseCommand *C : Sec->SectionCommands) for (BaseCommand *C : Sec->SectionCommands)
@ -776,13 +773,12 @@ void LinkerScript::assignAddresses() {
// By default linker scripts use an initial value of 0 for '.', but prefer // By default linker scripts use an initial value of 0 for '.', but prefer
// -image-base if set. // -image-base if set.
Dot = Config->ImageBase ? *Config->ImageBase : 0; Dot = Config->ImageBase ? *Config->ImageBase : 0;
auto State = make_unique<AddressState>();
// CurAddressState captures the local AddressState and makes it accessible // Ctx captures the local AddressState and makes it accessible
// deliberately. This is needed as there are some cases where we cannot just // deliberately. This is needed as there are some cases where we cannot just
// thread the current state through to a lambda function created by the // thread the current state through to a lambda function created by the
// script parser. // script parser.
CurAddressState = State.get(); Ctx = make_unique<AddressState>();
ErrorOnMissingSection = true; ErrorOnMissingSection = true;
switchTo(Aether); switchTo(Aether);
@ -799,7 +795,7 @@ void LinkerScript::assignAddresses() {
assignOffsets(cast<OutputSection>(Base)); assignOffsets(cast<OutputSection>(Base));
} }
CurAddressState = nullptr; Ctx = nullptr;
} }
// Creates program headers as instructed by PHDRS linker script command. // Creates program headers as instructed by PHDRS linker script command.
@ -851,9 +847,8 @@ bool LinkerScript::needsInterpSection() {
ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
if (S == ".") { if (S == ".") {
if (CurAddressState) if (Ctx)
return {CurAddressState->OutSec, false, return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc};
Dot - CurAddressState->OutSec->Addr, Loc};
error(Loc + ": unable to get location counter value"); error(Loc + ": unable to get location counter value");
return 0; return 0;
} }

View File

@ -218,7 +218,7 @@ class LinkerScript final {
void output(InputSection *Sec); void output(InputSection *Sec);
void process(BaseCommand &Base); void process(BaseCommand &Base);
AddressState *CurAddressState = nullptr; std::unique_ptr<AddressState> Ctx;
OutputSection *Aether; OutputSection *Aether;
uint64_t Dot; uint64_t Dot;