summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-05-09 18:24:38 +0000
committerRui Ueyama <ruiu@google.com>2017-05-09 18:24:38 +0000
commit91b95b61f8b815e45ad6c3cdb1d35c70bb9e7bff (patch)
treeef2a8bc1ddef7132e9e58c04df4ecee47a31cd48
parent41ffc70484532c3cb2bb8110fe585aa7200ebee6 (diff)
downloadbcm5719-llvm-91b95b61f8b815e45ad6c3cdb1d35c70bb9e7bff.tar.gz
bcm5719-llvm-91b95b61f8b815e45ad6c3cdb1d35c70bb9e7bff.zip
Add memory ORIGIN and LENGTH expression support
Adds support for the ORIGIN and LENGTH linker script built in functions. ORIGIN(memory) Return the origin of the memory region LENGTH(memory) Return the length of the memory region Redo of D29775 for refactored linker script parsing. Patch by Robert Clarke Differential Revision: https://reviews.llvm.org/D32934 llvm-svn: 302564
-rw-r--r--lld/ELF/ScriptParser.cpp12
-rw-r--r--lld/test/ELF/linkerscript/symbol-memoryexpr.s33
2 files changed, 45 insertions, 0 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 032ecd50f3e..ca4f4cd2773 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -900,10 +900,22 @@ Expr ScriptParser::readPrimary() {
StringRef Name = readParenLiteral();
return [=] { return Script->isDefined(Name) ? 1 : 0; };
}
+ if (Tok == "LENGTH") {
+ StringRef Name = readParenLiteral();
+ if (Script->Opt.MemoryRegions.count(Name) == 0)
+ setError("memory region not defined: " + Name);
+ return [=] { return Script->Opt.MemoryRegions[Name].Length; };
+ }
if (Tok == "LOADADDR") {
StringRef Name = readParenLiteral();
return [=] { return Script->getOutputSection(Location, Name)->getLMA(); };
}
+ if (Tok == "ORIGIN") {
+ StringRef Name = readParenLiteral();
+ if (Script->Opt.MemoryRegions.count(Name) == 0)
+ setError("memory region not defined: " + Name);
+ return [=] { return Script->Opt.MemoryRegions[Name].Origin; };
+ }
if (Tok == "SEGMENT_START") {
expect("(");
skip();
diff --git a/lld/test/ELF/linkerscript/symbol-memoryexpr.s b/lld/test/ELF/linkerscript/symbol-memoryexpr.s
new file mode 100644
index 00000000000..9c75274e164
--- /dev/null
+++ b/lld/test/ELF/linkerscript/symbol-memoryexpr.s
@@ -0,0 +1,33 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "MEMORY { \
+# RUN: ram (rwx) : ORIGIN = 0x8000, LENGTH = 256K \
+# RUN: } \
+# RUN: SECTIONS { \
+# RUN: origin = ORIGIN(ram); \
+# RUN: length = LENGTH(ram); \
+# RUN: end = ORIGIN(ram) + LENGTH(ram); \
+# RUN: }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-objdump -t %t1 | FileCheck %s
+
+# CHECK: SYMBOL TABLE:
+# CHECK-NEXT: 0000000000000000 *UND* 00000000
+# CHECK-NEXT: 0000000000008000 .text 00000000 _start
+# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
+# CHECK-NEXT: 0000000000040000 *ABS* 00000000 length
+# CHECK-NEXT: 0000000000048000 *ABS* 00000000 end
+
+# RUN: echo "SECTIONS { \
+# RUN: no_exist_origin = ORIGIN(ram); \
+# RUN: no_exist_length = LENGTH(ram); \
+# RUN: }" > %t2.script
+# RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR %s
+# ERR: {{.*}}.script:1: memory region not defined: ram
+
+
+.global _start
+_start:
+ nop
OpenPOWER on IntegriCloud