[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