Rename Commands -> SectionCommands.

"Commands" was ambiguous because in the linker script, everything is
a command. We used to handle only SECTIONS commands, and at the time,
it might make sense to call them the commands, but it is no longer
the case. We handle not only SECTIONS but also MEMORY, PHDRS, VERSION,
etc., and they are all commands.

llvm-svn: 315409
This commit is contained in:
Rui Ueyama 2017-10-11 01:50:56 +00:00
parent 197f68da76
commit 6b394caaf1
10 changed files with 70 additions and 64 deletions

View File

@ -130,7 +130,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
std::vector<lto::SymbolResolution> Resols(Syms.size());
DenseSet<StringRef> ScriptSymbols;
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
ScriptSymbols.insert(Cmd->Name);

View File

@ -341,7 +341,7 @@ std::vector<InputSectionBase *>
LinkerScript::createInputSectionList(OutputSection &OutCmd) {
std::vector<InputSectionBase *> Ret;
for (BaseCommand *Base : OutCmd.Commands) {
for (BaseCommand *Base : OutCmd.SectionCommands) {
auto *Cmd = dyn_cast<InputSectionDescription>(Base);
if (!Cmd)
continue;
@ -374,14 +374,14 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
CurAddressState = State.get();
CurAddressState->OutSec = Aether;
for (size_t I = 0; I < Commands.size(); ++I) {
for (size_t I = 0; I < SectionCommands.size(); ++I) {
// Handle symbol assignments outside of any output section.
if (auto *Cmd = dyn_cast<SymbolAssignment>(Commands[I])) {
if (auto *Cmd = dyn_cast<SymbolAssignment>(SectionCommands[I])) {
addSymbol(Cmd);
continue;
}
if (auto *Sec = dyn_cast<OutputSection>(Commands[I])) {
if (auto *Sec = dyn_cast<OutputSection>(SectionCommands[I])) {
std::vector<InputSectionBase *> V = createInputSectionList(*Sec);
// The output section name `/DISCARD/' is special.
@ -396,19 +396,19 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
// sections satisfy a given constraint. If not, a directive is handled
// as if it wasn't present from the beginning.
//
// Because we'll iterate over Commands many more times, the easiest
// Because we'll iterate over SectionCommands many more times, the easiest
// way to "make it as if it wasn't present" is to just remove it.
if (!matchConstraints(V, Sec->Constraint)) {
for (InputSectionBase *S : V)
S->Assigned = false;
Commands.erase(Commands.begin() + I);
SectionCommands.erase(SectionCommands.begin() + I);
--I;
continue;
}
// A directive may contain symbol definitions like this:
// ".foo : { ...; bar = .; }". Handle them.
for (BaseCommand *Base : Sec->Commands)
for (BaseCommand *Base : Sec->SectionCommands)
if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
addSymbol(OutCmd);
@ -447,7 +447,8 @@ void LinkerScript::fabricateDefaultCommands() {
auto Expr = [=] {
return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
};
Commands.insert(Commands.begin(), make<SymbolAssignment>(".", Expr, ""));
SectionCommands.insert(SectionCommands.begin(),
make<SymbolAssignment>(".", Expr, ""));
}
static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
@ -461,7 +462,7 @@ static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
unsigned End = Commands.size();
unsigned End = SectionCommands.size();
for (InputSectionBase *S : InputSections) {
if (!S->Live || S->Parent)
@ -471,13 +472,13 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
log(toString(S) + " is being placed in '" + Name + "'");
if (OutputSection *Sec =
findByName(makeArrayRef(Commands).slice(0, End), Name)) {
findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) {
Sec->addSection(cast<InputSection>(S));
continue;
}
if (OutputSection *OS = Factory.addInputSec(S, Name))
Script->Commands.push_back(OS);
SectionCommands.push_back(OS);
assert(S->getOutputSection()->SectionIndex == INT_MAX);
}
}
@ -636,7 +637,7 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
if (CurAddressState->OutSec->Flags & SHF_COMPRESSED)
return;
for (BaseCommand *C : Sec->Commands)
for (BaseCommand *C : Sec->SectionCommands)
process(*C);
}
@ -647,7 +648,7 @@ void LinkerScript::removeEmptyCommands() {
// clutter the output.
// We instead remove trivially empty sections. The bfd linker seems even
// more aggressive at removing them.
llvm::erase_if(Commands, [&](BaseCommand *Base) {
llvm::erase_if(SectionCommands, [&](BaseCommand *Base) {
if (auto *Sec = dyn_cast<OutputSection>(Base))
return !Sec->Live;
return false;
@ -655,7 +656,7 @@ void LinkerScript::removeEmptyCommands() {
}
static bool isAllSectionDescription(const OutputSection &Cmd) {
for (BaseCommand *Base : Cmd.Commands)
for (BaseCommand *Base : Cmd.SectionCommands)
if (!isa<InputSectionDescription>(*Base))
return false;
return true;
@ -668,7 +669,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// consequeces and gives us a section to put the symbol in.
uint64_t Flags = SHF_ALLOC;
for (BaseCommand *Cmd : Commands) {
for (BaseCommand *Cmd : SectionCommands) {
auto *Sec = dyn_cast<OutputSection>(Cmd);
if (!Sec)
continue;
@ -687,7 +688,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
void LinkerScript::adjustSectionsAfterSorting() {
// Try and find an appropriate memory region to assign offsets in.
for (BaseCommand *Base : Commands) {
for (BaseCommand *Base : SectionCommands) {
if (auto *Sec = dyn_cast<OutputSection>(Base)) {
if (!Sec->Live)
continue;
@ -714,7 +715,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
// Walk the commands and propagate the program headers to commands that don't
// explicitly specify them.
for (BaseCommand *Base : Commands) {
for (BaseCommand *Base : SectionCommands) {
auto *Sec = dyn_cast<OutputSection>(Base);
if (!Sec)
continue;
@ -801,7 +802,7 @@ void LinkerScript::assignAddresses() {
ErrorOnMissingSection = true;
switchTo(Aether);
for (BaseCommand *Base : Commands) {
for (BaseCommand *Base : SectionCommands) {
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
assignSymbol(Cmd, false);
continue;

View File

@ -246,7 +246,7 @@ public:
void processCommands(OutputSectionFactory &Factory);
// SECTIONS command list.
std::vector<BaseCommand *> Commands;
std::vector<BaseCommand *> SectionCommands;
// PHDRS command list.
std::vector<PhdrsCommand> PhdrsCommands;

View File

@ -133,7 +133,7 @@ template <class ELFT> void elf::writeMapFile() {
OS << OSec->Name << '\n';
// Dump symbols for each input section.
for (BaseCommand *Base : OSec->Commands) {
for (BaseCommand *Base : OSec->SectionCommands) {
auto *ISD = dyn_cast<InputSectionDescription>(Base);
if (!ISD)
continue;

View File

@ -139,9 +139,10 @@ void OutputSection::addSection(InputSection *IS) {
if (!IS->Assigned) {
IS->Assigned = true;
if (Commands.empty() || !isa<InputSectionDescription>(Commands.back()))
Commands.push_back(make<InputSectionDescription>(""));
auto *ISD = cast<InputSectionDescription>(Commands.back());
if (SectionCommands.empty() ||
!isa<InputSectionDescription>(SectionCommands.back()))
SectionCommands.push_back(make<InputSectionDescription>(""));
auto *ISD = cast<InputSectionDescription>(SectionCommands.back());
ISD->Sections.push_back(IS);
}
}
@ -311,8 +312,9 @@ bool OutputSection::classof(const BaseCommand *C) {
}
void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) {
assert(Commands.size() == 1);
sortByOrder(cast<InputSectionDescription>(Commands[0])->Sections, Order);
assert(SectionCommands.size() == 1);
sortByOrder(cast<InputSectionDescription>(SectionCommands[0])->Sections,
Order);
}
// Fill [Buf, Buf + Size) with Filler.
@ -382,7 +384,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
// Write leading padding.
std::vector<InputSection *> Sections;
for (BaseCommand *Cmd : Commands)
for (BaseCommand *Cmd : SectionCommands)
if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
for (InputSection *IS : ISD->Sections)
if (IS->Live)
@ -409,7 +411,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
// Linker scripts may have BYTE()-family commands with which you
// can write arbitrary bytes to the output. Process them if any.
for (BaseCommand *Base : Commands)
for (BaseCommand *Base : SectionCommands)
if (auto *Data = dyn_cast<BytesDataCommand>(Base))
writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
}
@ -449,7 +451,7 @@ template <class ELFT> void OutputSection::finalize() {
// but sort must consider them all at once.
std::vector<InputSection **> ScriptSections;
std::vector<InputSection *> Sections;
for (BaseCommand *Base : Commands) {
for (BaseCommand *Base : SectionCommands) {
if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
for (InputSection *&IS : ISD->Sections) {
ScriptSections.push_back(&IS);
@ -546,8 +548,8 @@ static bool compCtors(const InputSection *A, const InputSection *B) {
// Unfortunately, the rules are different from the one for .{init,fini}_array.
// Read the comment above.
void OutputSection::sortCtorsDtors() {
assert(Commands.size() == 1);
auto *ISD = cast<InputSectionDescription>(Commands[0]);
assert(SectionCommands.size() == 1);
auto *ISD = cast<InputSectionDescription>(SectionCommands[0]);
std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors);
}

View File

@ -88,7 +88,7 @@ public:
Expr AlignExpr;
Expr LMAExpr;
Expr SubalignExpr;
std::vector<BaseCommand *> Commands;
std::vector<BaseCommand *> SectionCommands;
std::vector<StringRef> Phdrs;
llvm::Optional<uint32_t> Filler;
ConstraintKind Constraint = ConstraintKind::NoConstraint;

View File

@ -1024,7 +1024,7 @@ void ThunkCreator::mergeThunks() {
}
static uint32_t findEndOfFirstNonExec(OutputSection &Cmd) {
for (BaseCommand *Base : Cmd.Commands)
for (BaseCommand *Base : Cmd.SectionCommands)
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
for (auto *IS : ISD->Sections)
if ((IS->Flags & SHF_EXECINSTR) == 0)
@ -1052,7 +1052,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
// InputSection (IS) that we need to precede is in.
OutputSection *TOS = IS->getParent();
std::vector<InputSection *> *Range = nullptr;
for (BaseCommand *BC : TOS->Commands)
for (BaseCommand *BC : TOS->SectionCommands)
if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
InputSection *first = ISD->Sections.front();
InputSection *last = ISD->Sections.back();
@ -1100,7 +1100,7 @@ void ThunkCreator::forEachExecInputSection(
for (OutputSection *OS : OutputSections) {
if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
continue;
for (BaseCommand *BC : OS->Commands)
for (BaseCommand *BC : OS->SectionCommands)
if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
CurTS = nullptr;
for (InputSection *IS : ISD->Sections)

View File

@ -234,7 +234,7 @@ void ScriptParser::readLinkerScript() {
continue;
if (Tok == "ASSERT") {
Script->Commands.push_back(readAssert());
Script->SectionCommands.push_back(readAssert());
} else if (Tok == "ENTRY") {
readEntry();
} else if (Tok == "EXTERN") {
@ -262,7 +262,7 @@ void ScriptParser::readLinkerScript() {
} else if (Tok == "VERSION") {
readVersion();
} else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
Script->Commands.push_back(Cmd);
Script->SectionCommands.push_back(Cmd);
} else {
setError("unknown directive: " + Tok);
}
@ -451,7 +451,7 @@ void ScriptParser::readSections() {
else
Cmd = readOutputSectionDescription(Tok);
}
Script->Commands.push_back(Cmd);
Script->SectionCommands.push_back(Cmd);
}
}
@ -669,11 +669,11 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
if (Tok == ";") {
// Empty commands are allowed. Do nothing here.
} else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) {
Cmd->Commands.push_back(Assign);
Cmd->SectionCommands.push_back(Assign);
} else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) {
Cmd->Commands.push_back(Data);
Cmd->SectionCommands.push_back(Data);
} else if (Tok == "ASSERT") {
Cmd->Commands.push_back(readAssert());
Cmd->SectionCommands.push_back(readAssert());
expect(";");
} else if (Tok == "CONSTRUCTORS") {
// CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
@ -684,7 +684,7 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
} else if (Tok == "SORT") {
readSort();
} else if (peek() == "(") {
Cmd->Commands.push_back(readInputSectionDescription(Tok));
Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
} else {
setError("unknown command " + Tok);
}

View File

@ -2378,10 +2378,11 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
// sentinel. By construction the Sentinel is in the last
// InputSectionDescription as the InputSection that precedes it.
OutputSection *C = getParent();
auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(),
[](const BaseCommand *Base) {
return isa<InputSectionDescription>(Base);
});
auto ISD =
std::find_if(C->SectionCommands.rbegin(), C->SectionCommands.rend(),
[](const BaseCommand *Base) {
return isa<InputSectionDescription>(Base);
});
auto L = cast<InputSectionDescription>(*ISD);
InputSection *Highest = L->Sections[L->Sections.size() - 2];
InputSection *LS = Highest->getLinkOrderDep();

View File

@ -466,16 +466,16 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
// Create one STT_SECTION symbol for each output section we might
// have a relocation with.
for (BaseCommand *Base : Script->Commands) {
for (BaseCommand *Base : Script->SectionCommands) {
auto *Sec = dyn_cast<OutputSection>(Base);
if (!Sec)
continue;
auto I = llvm::find_if(Sec->Commands, [](BaseCommand *Base) {
auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) {
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
return !ISD->Sections.empty();
return false;
});
if (I == Sec->Commands.end())
if (I == Sec->SectionCommands.end())
continue;
InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
if (isa<SyntheticSection>(IS) || IS->Type == SHT_REL ||
@ -849,7 +849,7 @@ static void sortBySymbolsOrder() {
// Sort sections by priority.
DenseMap<SectionBase *, int> SectionOrder = buildSectionOrder();
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
}
@ -876,7 +876,8 @@ template <class ELFT> void Writer<ELFT>::createSections() {
Factory.addInputSec(IS, getOutputSectionName(IS->Name)))
Vec.push_back(Sec);
Script->Commands.insert(Script->Commands.begin(), Vec.begin(), Vec.end());
Script->SectionCommands.insert(Script->SectionCommands.begin(), Vec.begin(),
Vec.end());
Script->fabricateDefaultCommands();
sortBySymbolsOrder();
@ -1051,15 +1052,15 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
if (Config->Relocatable)
return;
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
Sec->SortRank = getSectionRank(Sec);
if (!Script->HasSectionsCommand) {
// We know that all the OutputSections are contiguous in
// this case.
auto E = Script->Commands.end();
auto I = Script->Commands.begin();
auto E = Script->SectionCommands.end();
auto I = Script->SectionCommands.begin();
auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
I = std::find_if(I, E, IsSection);
E = std::find_if(llvm::make_reverse_iterator(E),
@ -1108,8 +1109,8 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
// after another commands. For the details, look at shouldSkip
// function.
auto I = Script->Commands.begin();
auto E = Script->Commands.end();
auto I = Script->SectionCommands.begin();
auto E = Script->SectionCommands.end();
auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
if (auto *Sec = dyn_cast<OutputSection>(Base))
return Sec->Live && Sec->SectionIndex == INT_MAX;
@ -1178,8 +1179,9 @@ static void removeUnusedSyntheticSections() {
if (!SS->empty() || !OS)
continue;
std::vector<BaseCommand *>::iterator Empty = OS->Commands.end();
for (auto I = OS->Commands.begin(), E = OS->Commands.end(); I != E; ++I) {
std::vector<BaseCommand *>::iterator Empty = OS->SectionCommands.end();
for (auto I = OS->SectionCommands.begin(), E = OS->SectionCommands.end();
I != E; ++I) {
BaseCommand *B = *I;
if (auto *ISD = dyn_cast<InputSectionDescription>(B)) {
llvm::erase_if(ISD->Sections,
@ -1188,12 +1190,12 @@ static void removeUnusedSyntheticSections() {
Empty = I;
}
}
if (Empty != OS->Commands.end())
OS->Commands.erase(Empty);
if (Empty != OS->SectionCommands.end())
OS->SectionCommands.erase(Empty);
// If there are no other sections in the output section, remove it from the
// output.
if (OS->Commands.empty())
if (OS->SectionCommands.empty())
OS->Live = false;
}
}
@ -1240,7 +1242,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// addresses of each section by section name. Add such symbols.
if (!Config->Relocatable) {
addStartEndSymbols();
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
addStartStopSymbols(Sec);
}
@ -1304,7 +1306,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Now that we have the final list, create a list of all the
// OutputSections for convenience.
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
OutputSections.push_back(Sec);
@ -1440,7 +1442,7 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
}
template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) {
for (BaseCommand *Base : Script->Commands)
for (BaseCommand *Base : Script->SectionCommands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
if (Sec->Name == Name)
return Sec;