[ELF] Linkerscript: define symbols outside SECTIONS

Symbol assignments outside of SECTIONS command need to be created
even when SECTIONS command is not used.

Differential Revision: https://reviews.llvm.org/D23751

llvm-svn: 280252
This commit is contained in:
Petr Hosek 2016-08-31 15:31:17 +00:00
parent b2e620a23b
commit e5d3ca5031
4 changed files with 32 additions and 4 deletions

View File

@ -258,6 +258,16 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
return Ret; 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> template <class ELFT>
void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) { for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) {
@ -714,12 +724,16 @@ void ScriptParser::readVersionScript() {
void ScriptParser::readLinkerScript() { void ScriptParser::readLinkerScript() {
while (!atEOF()) { while (!atEOF()) {
StringRef Tok = next(); StringRef Tok = next();
if (Handler Fn = Cmd.lookup(Tok)) if (Handler Fn = Cmd.lookup(Tok)) {
(this->*Fn)(); (this->*Fn)();
else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
Opt.Commands.emplace_back(Cmd); if (Opt.HasContents)
else Opt.Commands.emplace_back(Cmd);
else
Opt.Assignments.emplace_back(Cmd);
} else {
setError("unknown directive: " + Tok); setError("unknown directive: " + Tok);
}
} }
} }

View File

@ -118,6 +118,8 @@ struct PhdrsCommand {
// ScriptConfiguration holds linker script parse results. // ScriptConfiguration holds linker script parse results.
struct ScriptConfiguration { struct ScriptConfiguration {
// Used to create symbol assignments outside SECTIONS command.
std::vector<std::unique_ptr<SymbolAssignment>> Assignments;
// Used to assign addresses to sections. // Used to assign addresses to sections.
std::vector<std::unique_ptr<BaseCommand>> Commands; std::vector<std::unique_ptr<BaseCommand>> Commands;
@ -142,6 +144,7 @@ template <class ELFT> class LinkerScript {
public: public:
LinkerScript(); LinkerScript();
~LinkerScript(); ~LinkerScript();
void createAssignments();
void createSections(OutputSectionFactory<ELFT> &Factory); void createSections(OutputSectionFactory<ELFT> &Factory);
std::vector<PhdrEntry<ELFT>> createPhdrs(); std::vector<PhdrEntry<ELFT>> createPhdrs();

View File

@ -249,6 +249,8 @@ template <class ELFT> void Writer<ELFT>::run() {
CommonInputSection<ELFT> Common(getCommonSymbols<ELFT>()); CommonInputSection<ELFT> Common(getCommonSymbols<ELFT>());
CommonInputSection<ELFT>::X = &Common; CommonInputSection<ELFT>::X = &Common;
Script<ELFT>::X->createAssignments();
Script<ELFT>::X->OutputSections = &OutputSections; Script<ELFT>::X->OutputSections = &OutputSections;
if (ScriptConfig->HasContents) if (ScriptConfig->HasContents)
Script<ELFT>::X->createSections(Factory); Script<ELFT>::X->createSections(Factory);

View File

@ -67,6 +67,15 @@
# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN5 %s # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN5 %s
# HIDDEN5: 0000000000000000 *ABS* 00000000 somesym # HIDDEN5: 0000000000000000 *ABS* 00000000 somesym
# Simple symbol assignment. All three symbols should have the
# same value.
# RUN: echo "foo = 0x100; SECTIONS { bar = foo; } baz = bar;" > %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE2 %s
# SIMPLE2: 0000000000000100 *ABS* 00000000 foo
# SIMPLE2: 0000000000000100 *ABS* 00000000 bar
# SIMPLE2: 0000000000000100 *ABS* 00000000 baz
.global _start .global _start
_start: _start:
nop nop