Improve handling ASSERT outside SECTIONS block

Differential revision: https://reviews.llvm.org/D24450

llvm-svn: 281740
This commit is contained in:
Eugene Leviant 2016-09-16 15:30:47 +00:00
parent 85ef4a1c47
commit 20d031948e
4 changed files with 62 additions and 43 deletions

View File

@ -48,6 +48,11 @@ template <class ELFT> static void addRegular(SymbolAssignment *Cmd) {
Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT);
Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
Cmd->Sym = Sym->body();
// If we have no SECTIONS then we don't have '.' and don't call
// assignAddresses(). We calculate symbol value immediately in this case.
if (!ScriptConfig->HasSections)
cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
}
template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
@ -215,15 +220,6 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
return Ret;
}
template <class ELFT> void LinkerScript<ELFT>::createAssignments() {
for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) {
if (shouldDefine<ELFT>(Cmd.get()))
addRegular<ELFT>(Cmd.get());
if (Cmd->Sym)
cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
}
}
template <class ELFT>
static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
@ -256,15 +252,19 @@ static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
}
template <class ELFT>
void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
auto AddSec = [&](InputSectionBase<ELFT> *Sec, StringRef Name) {
OutputSectionBase<ELFT> *OutSec;
bool IsNew;
std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
if (IsNew)
OutputSections->push_back(OutSec);
return OutSec;
};
void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
InputSectionBase<ELFT> *Sec,
StringRef Name) {
OutputSectionBase<ELFT> *OutSec;
bool IsNew;
std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
if (IsNew)
OutputSections->push_back(OutSec);
OutSec->addSection(Sec);
}
template <class ELFT>
void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) {
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
@ -272,6 +272,14 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
addRegular<ELFT>(Cmd);
continue;
}
if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
// If we don't have SECTIONS then output sections have already been
// created by Writer<EFLT>. The LinkerScript<ELFT>::assignAddresses
// will not be called, so ASSERT should be evaluated now.
if (!Opt.HasSections)
Cmd->Expression(0);
continue;
}
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
@ -285,25 +293,22 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
continue;
for (InputSectionBase<ELFT> *Sec : V) {
OutputSectionBase<ELFT> *OutSec = AddSec(Sec, Cmd->Name);
uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
if (Subalign)
addSection(Factory, Sec, Cmd->Name);
if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0)
Sec->Alignment = Subalign;
OutSec->addSection(Sec);
}
}
}
}
template <class ELFT>
void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
processCommands(Factory);
// Add orphan sections.
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
for (InputSectionBase<ELFT> *S : F->getSections()) {
if (isDiscarded(S) || S->OutSec)
continue;
OutputSectionBase<ELFT> *OutSec = AddSec(S, getOutputSectionName(S));
OutSec->addSection(S);
}
}
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec)
addSection(Factory, S, getOutputSectionName(S));
}
// Sets value of a section-defined symbol. Two kinds of
@ -754,7 +759,9 @@ void ScriptParser::readLinkerScript() {
if (Tok == ";")
continue;
if (Tok == "ENTRY") {
if (Tok == "ASSERT") {
Opt.Commands.emplace_back(new AssertCommand(readAssert()));
} else if (Tok == "ENTRY") {
readEntry();
} else if (Tok == "EXTERN") {
readExtern();
@ -777,10 +784,7 @@ void ScriptParser::readLinkerScript() {
} else if (Tok == "VERSION") {
readVersion();
} else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) {
if (Opt.HasSections)
Opt.Commands.emplace_back(Cmd);
else
Opt.Assignments.emplace_back(Cmd);
Opt.Commands.emplace_back(Cmd);
} else {
setError("unknown directive: " + Tok);
}

View File

@ -140,8 +140,6 @@ public:
// ScriptConfiguration holds linker script parse results.
struct ScriptConfiguration {
// Used to create symbol assignments outside SECTIONS command.
std::vector<std::unique_ptr<SymbolAssignment>> Assignments;
// Used to assign addresses to sections.
std::vector<std::unique_ptr<BaseCommand>> Commands;
@ -166,7 +164,7 @@ template <class ELFT> class LinkerScript final : public LinkerScriptBase {
public:
LinkerScript();
~LinkerScript();
void createAssignments();
void processCommands(OutputSectionFactory<ELFT> &Factory);
void createSections(OutputSectionFactory<ELFT> &Factory);
std::vector<PhdrEntry<ELFT>> createPhdrs();
@ -191,6 +189,8 @@ private:
void computeInputSections(InputSectionDescription *,
ConstraintKind Constraint);
void addSection(OutputSectionFactory<ELFT> &Factory,
InputSectionBase<ELFT> *Sec, StringRef Name);
void discard(ArrayRef<InputSectionBase<ELFT> *> V);
std::vector<InputSectionBase<ELFT> *>

View File

@ -249,13 +249,13 @@ template <class ELFT> void Writer<ELFT>::run() {
CommonInputSection<ELFT> Common(getCommonSymbols<ELFT>());
CommonInputSection<ELFT>::X = &Common;
Script<ELFT>::X->createAssignments();
Script<ELFT>::X->OutputSections = &OutputSections;
if (ScriptConfig->HasSections)
if (ScriptConfig->HasSections) {
Script<ELFT>::X->createSections(Factory);
else
} else {
createSections();
Script<ELFT>::X->processCommands(Factory);
}
finalizeSections();
if (HasError)

View File

@ -25,3 +25,18 @@
# RUN: }" > %t4.script
# RUN: ld.lld -shared -o %t4 --script %t4.script %t1.o
# RUN: llvm-readobj %t4 > /dev/null
# RUN: echo "SECTIONS { \
# RUN: .foo : { *(.foo) } \
# RUN: } \
# RUN: ASSERT(SIZEOF(.foo) == 8, \"true\");" > %t5.script
# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o
# RUN: llvm-readobj %t5 > /dev/null
## Even without SECTIONS block we still use section names
## in expressions
# RUN: echo "ASSERT(SIZEOF(.foo) == 8, \"true\");" > %t5.script
# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o
# RUN: llvm-readobj %t5 > /dev/null
.section .foo, "a"
.quad 0