[lld] r312777 - [ELF] - Linkerscript: implement REGION_ALIAS.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 8 01:23:15 PDT 2017
Author: grimar
Date: Fri Sep 8 01:23:15 2017
New Revision: 312777
URL: http://llvm.org/viewvc/llvm-project?rev=312777&view=rev
Log:
[ELF] - Linkerscript: implement REGION_ALIAS.
REGION_ALIAS(alias, region)
Alias names can be added to existing memory regions created with
the MEMORY command. Each name corresponds to at most one
memory region.
Differential revision: https://reviews.llvm.org/D37477
Added:
lld/trunk/test/ELF/linkerscript/region-alias.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/ScriptParser.cpp
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=312777&r1=312776&r2=312777&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep 8 01:23:15 2017
@@ -584,7 +584,7 @@ MemoryRegion *LinkerScript::findMemoryRe
if (!Sec->MemoryRegionName.empty()) {
auto It = Opt.MemoryRegions.find(Sec->MemoryRegionName);
if (It != Opt.MemoryRegions.end())
- return &It->second;
+ return It->second;
error("memory region '" + Sec->MemoryRegionName + "' not declared");
return nullptr;
}
@@ -597,9 +597,9 @@ MemoryRegion *LinkerScript::findMemoryRe
// See if a region can be found by matching section flags.
for (auto &Pair : Opt.MemoryRegions) {
- MemoryRegion &M = Pair.second;
- if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
- return &M;
+ MemoryRegion *M = Pair.second;
+ if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0)
+ return M;
}
// Otherwise, no suitable region was found.
@@ -778,7 +778,7 @@ void LinkerScript::allocateHeaders(std::
LinkerScript::AddressState::AddressState(const ScriptConfiguration &Opt) {
for (auto &MRI : Opt.MemoryRegions) {
- const MemoryRegion *MR = &MRI.second;
+ const MemoryRegion *MR = MRI.second;
MemRegionOffset[MR] = MR->Origin;
}
}
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=312777&r1=312776&r2=312777&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Sep 8 01:23:15 2017
@@ -187,7 +187,7 @@ struct ScriptConfiguration {
std::vector<InputSectionDescription *> KeptSections;
// A map from memory region name to a memory region descriptor.
- llvm::DenseMap<llvm::StringRef, MemoryRegion> MemoryRegions;
+ llvm::DenseMap<llvm::StringRef, MemoryRegion *> MemoryRegions;
// A list of symbols referenced by the script.
std::vector<llvm::StringRef> ReferencedSymbols;
Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=312777&r1=312776&r2=312777&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Fri Sep 8 01:23:15 2017
@@ -68,6 +68,7 @@ private:
void readOutputArch();
void readOutputFormat();
void readPhdrs();
+ void readRegionAlias();
void readSearchDir();
void readSections();
void readVersion();
@@ -241,6 +242,8 @@ void ScriptParser::readLinkerScript() {
readOutputFormat();
} else if (Tok == "PHDRS") {
readPhdrs();
+ } else if (Tok == "REGION_ALIAS") {
+ readRegionAlias();
} else if (Tok == "SEARCH_DIR") {
readSearchDir();
} else if (Tok == "SECTIONS") {
@@ -396,6 +399,20 @@ void ScriptParser::readPhdrs() {
}
}
+void ScriptParser::readRegionAlias() {
+ expect("(");
+ StringRef Alias = unquote(next());
+ expect(",");
+ StringRef Name = next();
+ expect(")");
+
+ if (Script->Opt.MemoryRegions.count(Alias))
+ setError("redefinition of memory region '" + Alias + "'");
+ if (!Script->Opt.MemoryRegions.count(Name))
+ setError("memory region '" + Name + "' is not defined");
+ Script->Opt.MemoryRegions[Alias] = Script->Opt.MemoryRegions[Name];
+}
+
void ScriptParser::readSearchDir() {
expect("(");
StringRef Tok = next();
@@ -984,7 +1001,7 @@ Expr ScriptParser::readPrimary() {
StringRef Name = readParenLiteral();
if (Script->Opt.MemoryRegions.count(Name) == 0)
setError("memory region not defined: " + Name);
- return [=] { return Script->Opt.MemoryRegions[Name].Length; };
+ return [=] { return Script->Opt.MemoryRegions[Name]->Length; };
}
if (Tok == "LOADADDR") {
StringRef Name = readParenLiteral();
@@ -995,7 +1012,7 @@ Expr ScriptParser::readPrimary() {
StringRef Name = readParenLiteral();
if (Script->Opt.MemoryRegions.count(Name) == 0)
setError("memory region not defined: " + Name);
- return [=] { return Script->Opt.MemoryRegions[Name].Origin; };
+ return [=] { return Script->Opt.MemoryRegions[Name]->Origin; };
}
if (Tok == "SEGMENT_START") {
expect("(");
@@ -1226,12 +1243,12 @@ void ScriptParser::readMemory() {
expect(",");
uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
- // Add the memory region to the region map (if it doesn't already exist).
- auto It = Script->Opt.MemoryRegions.find(Name);
- if (It != Script->Opt.MemoryRegions.end())
+ // Add the memory region to the region map.
+ if (Script->Opt.MemoryRegions.count(Name))
setError("region '" + Name + "' already defined");
- else
- Script->Opt.MemoryRegions[Name] = {Name, Origin, Length, Flags, NegFlags};
+ MemoryRegion *MR = make<MemoryRegion>();
+ *MR = {Name, Origin, Length, Flags, NegFlags};
+ Script->Opt.MemoryRegions[Name] = MR;
}
}
Added: lld/trunk/test/ELF/linkerscript/region-alias.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/region-alias.s?rev=312777&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/region-alias.s (added)
+++ lld/trunk/test/ELF/linkerscript/region-alias.s Fri Sep 8 01:23:15 2017
@@ -0,0 +1,54 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "MEMORY { \
+# RUN: ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100 \
+# RUN: RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100 \
+# RUN: } \
+# RUN: INCLUDE \"%t.script.inc\" \
+# RUN: SECTIONS { \
+# RUN: .text : { *(.text*) } > ALIAS_TEXT \
+# RUN: .data : { *(.data*) } > ALIAS_DATA \
+# RUN: }" > %t.script
+
+## .text to ROM, .data to RAM.
+# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc
+# RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
+# CHECK: .text 00000001 0000000000001000 TEXT DATA
+# CHECK: .data 00000008 0000000000002000 DATA
+
+## All to ROM.
+# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc
+# RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", ROM);" >> %t.script.inc
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM
+# RAM: .text 00000001 0000000000001000 TEXT DATA
+# RAM: .data 00000008 0000000000001001 DATA
+
+## Redefinition of region.
+# RUN: echo "REGION_ALIAS (\"ROM\", ROM);" > %t.script.inc
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERR1
+# ERR1: {{.*}}script.inc:1: redefinition of memory region 'ROM'
+
+## Redefinition of alias.
+# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc
+# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" >> %t.script.inc
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERR2
+# ERR2: {{.*}}script.inc:2: redefinition of memory region 'ALIAS_TEXT'
+
+## Attemp to create an alias for undefined region.
+# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", FOO);" > %t.script.inc
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERR3
+# ERR3: {{.*}}script.inc:1: memory region 'FOO' is not defined
+
+.text
+.global _start
+_start:
+ nop
+
+.section .data,"aw"
+.quad 0
More information about the llvm-commits
mailing list