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
This commit is contained in:
Rui Ueyama 2017-05-09 18:24:38 +00:00
parent 41ffc70484
commit 91b95b61f8
2 changed files with 45 additions and 0 deletions

View File

@ -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();

View File

@ -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