Make elf::ScriptConfig a LinkerScript class member variable.

LinkerScript used to be a template class, so we couldn't instantiate
that class in elf::link. We instantiated ScriptConfig class earlier
instead so that the linker script parser can store configurations to
the object.

Now that LinkerScript is not a template, it doesn't make sense to
separate ScriptConfig from LinkerScript. This patch merges them.

llvm-svn: 298457
This commit is contained in:
Rui Ueyama 2017-03-21 23:03:09 +00:00
parent b8dd23f56e
commit a34da93847
4 changed files with 23 additions and 27 deletions

View File

@ -78,7 +78,7 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
Config = make<Configuration>();
Driver = make<LinkerDriver>();
ScriptConfig = make<ScriptConfiguration>();
Script = make<LinkerScript>();
Driver->main(Args, CanExitEarly);
freeArena();
@ -855,7 +855,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
SymbolTable<ELFT> Symtab;
elf::Symtab<ELFT>::X = &Symtab;
Target = createTarget();
Script = make<LinkerScript>();
Config->MaxPageSize = getMaxPageSize(Args);
Config->ImageBase = getImageBase(Args);

View File

@ -53,6 +53,8 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
LinkerScript *elf::Script;
uint64_t ExprValue::getValue() const {
if (Sec)
return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
@ -109,9 +111,6 @@ static ExprValue bitOr(ExprValue A, ExprValue B) {
static ExprValue bitNot(ExprValue A) { return ~A.getValue(); }
static ExprValue minus(ExprValue A) { return -A.getValue(); }
LinkerScript *elf::Script;
ScriptConfiguration *elf::ScriptConfig;
template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
Symbol *Sym;
uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
@ -1102,7 +1101,6 @@ private:
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
readSymbols();
ScriptConfiguration &Opt = *ScriptConfig;
bool IsUnderSysroot;
};
@ -1150,7 +1148,7 @@ void ScriptParser::readLinkerScript() {
continue;
if (Tok == "ASSERT") {
Opt.Commands.emplace_back(new AssertCommand(readAssert()));
Script->Opt.Commands.emplace_back(new AssertCommand(readAssert()));
} else if (Tok == "ENTRY") {
readEntry();
} else if (Tok == "EXTERN") {
@ -1176,7 +1174,7 @@ void ScriptParser::readLinkerScript() {
} else if (Tok == "VERSION") {
readVersion();
} else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
Opt.Commands.emplace_back(Cmd);
Script->Opt.Commands.emplace_back(Cmd);
} else {
setError("unknown directive: " + Tok);
}
@ -1303,9 +1301,9 @@ void ScriptParser::readPhdrs() {
expect("{");
while (!Error && !consume("}")) {
StringRef Tok = next();
Opt.PhdrsCommands.push_back(
Script->Opt.PhdrsCommands.push_back(
{Tok, PT_NULL, false, false, UINT_MAX, nullptr});
PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back();
PhdrCmd.Type = readPhdrType();
do {
@ -1339,7 +1337,7 @@ void ScriptParser::readSearchDir() {
}
void ScriptParser::readSections() {
Opt.HasSections = true;
Script->Opt.HasSections = true;
// -no-rosegment is used to avoid placing read only non-executable sections in
// their own segment. We do the same if SECTIONS command is present in linker
// script. See comment for computeFlags().
@ -1355,7 +1353,7 @@ void ScriptParser::readSections() {
else
Cmd = readOutputSectionDescription(Tok);
}
Opt.Commands.emplace_back(Cmd);
Script->Opt.Commands.emplace_back(Cmd);
}
}
@ -1469,7 +1467,7 @@ ScriptParser::readInputSectionDescription(StringRef Tok) {
StringRef FilePattern = next();
InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
expect(")");
Opt.KeptSections.push_back(Cmd);
Script->Opt.KeptSections.push_back(Cmd);
return Cmd;
}
return readInputSectionRules(Tok);
@ -2072,11 +2070,12 @@ void ScriptParser::readMemory() {
uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
// Add the memory region to the region map (if it doesn't already exist).
auto It = Opt.MemoryRegions.find(Name);
if (It != Opt.MemoryRegions.end())
auto It = Script->Opt.MemoryRegions.find(Name);
if (It != Script->Opt.MemoryRegions.end())
setError("region '" + Name + "' already defined");
else
Opt.MemoryRegions[Name] = {Name, Origin, Length, Origin, Flags, NegFlags};
Script->Opt.MemoryRegions[Name] = {Name, Origin, Length,
Origin, Flags, NegFlags};
}
}

View File

@ -219,8 +219,6 @@ struct ScriptConfiguration {
llvm::DenseMap<llvm::StringRef, MemoryRegion> MemoryRegions;
};
extern ScriptConfiguration *ScriptConfig;
class LinkerScript {
protected:
void assignSymbol(SymbolAssignment *Cmd, bool InSec = false);
@ -243,9 +241,6 @@ protected:
OutputSection *Aether;
bool ErrorOnMissingSection = false;
// "ScriptConfig" is a bit too long, so define a short name for it.
ScriptConfiguration &Opt = *ScriptConfig;
uint64_t Dot;
uint64_t ThreadBssOffset = 0;
@ -287,6 +282,9 @@ public:
void writeDataBytes(StringRef Name, uint8_t *Buf);
void addSymbol(SymbolAssignment *Cmd);
void processCommands(OutputSectionFactory &Factory);
// Parsed linker script configurations are set to this struct.
ScriptConfiguration Opt;
};
extern LinkerScript *Script;

View File

@ -228,7 +228,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// Create output sections.
Script->OutputSections = &OutputSections;
if (ScriptConfig->HasSections) {
if (Script->Opt.HasSections) {
// If linker script contains SECTIONS commands, let it create sections.
Script->processCommands(Factory);
@ -261,7 +261,7 @@ template <class ELFT> void Writer<ELFT>::run() {
if (Config->Relocatable) {
assignFileOffsets();
} else {
if (ScriptConfig->HasSections) {
if (Script->Opt.HasSections) {
Script->assignAddresses(Phdrs);
} else {
fixSectionAlignments();
@ -841,7 +841,7 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
Symtab<ELFT>::X->addIgnored("__tls_get_addr");
// If linker script do layout we do not need to create any standart symbols.
if (ScriptConfig->HasSections)
if (Script->Opt.HasSections)
return;
// __ehdr_start is the location of ELF file headers.
@ -960,7 +960,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
// relative order for SHF_LINK_ORDER sections.
if (Config->Relocatable)
return;
if (!ScriptConfig->HasSections) {
if (!Script->Opt.HasSections) {
std::stable_sort(OutputSections.begin(), OutputSections.end(),
compareSectionsNonScript<ELFT>);
return;
@ -1437,7 +1437,7 @@ bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
}
Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
if (!ScriptConfig->HasSections)
if (!Script->Opt.HasSections)
Config->ImageBase = Min = std::min(Min, Config->ImageBase);
Out::ElfHeader->Addr = Min;
@ -1462,7 +1462,7 @@ bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
template <class ELFT> void Writer<ELFT>::fixHeaders() {
Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
// If the script has SECTIONS, assignAddresses will compute the values.
if (ScriptConfig->HasSections)
if (Script->Opt.HasSections)
return;
// When -T<section> option is specified, lower the base to make room for those