forked from OSchip/llvm-project
[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:
parent
b2e620a23b
commit
e5d3ca5031
|
@ -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,14 +724,18 @@ 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)) {
|
||||||
|
if (Opt.HasContents)
|
||||||
Opt.Commands.emplace_back(Cmd);
|
Opt.Commands.emplace_back(Cmd);
|
||||||
else
|
else
|
||||||
|
Opt.Assignments.emplace_back(Cmd);
|
||||||
|
} else {
|
||||||
setError("unknown directive: " + Tok);
|
setError("unknown directive: " + Tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptParser::addFile(StringRef S) {
|
void ScriptParser::addFile(StringRef S) {
|
||||||
if (IsUnderSysroot && S.startswith("/")) {
|
if (IsUnderSysroot && S.startswith("/")) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue