diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-07-28 18:16:24 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-07-28 18:16:24 +0000 |
| commit | 54c145ce0e2fd205036cd8e02275451bac7c3819 (patch) | |
| tree | a3503a12eee7a38c4fade03c26cef1cb1cef5409 | |
| parent | 6a742846525d89e8e53972919ab6ffdde6fedeec (diff) | |
| download | bcm5719-llvm-54c145ce0e2fd205036cd8e02275451bac7c3819.tar.gz bcm5719-llvm-54c145ce0e2fd205036cd8e02275451bac7c3819.zip | |
Add support for SEGMENT_START.
This is a bit of an odd feature. It is normally used in
. = SEGMENT_START(seg, val);
In bfd it evaluates to val or to the value of the corresponding
-T<seg>-segment. Note that the -T<seg>-segment in bfd doesn't actually
change the segment address, just the value this evaluates too,
including in the default linker script.
In gold the -T<seg>-segment options do change the segment address and
seeing this expressions in linker scripts disables the options.
For new this just always evaluates the expression to val.
llvm-svn: 277014
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 9 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/Inputs/segment-start.script | 7 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/segment-start.s | 22 |
3 files changed, 38 insertions, 0 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 50a7b7522cc..395f1268d58 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -872,6 +872,15 @@ Expr ScriptParser::readPrimary() { expect(")"); return [=](uint64_t Dot) { return getConstant(Tok); }; } + if (Tok == "SEGMENT_START") { + expect("("); + next(); + expect(","); + uint64_t Val; + next().getAsInteger(0, Val); + expect(")"); + return [=](uint64_t Dot) { return Val; }; + } if (Tok == "DATA_SEGMENT_ALIGN") { expect("("); Expr E = readExpr(); diff --git a/lld/test/ELF/linkerscript/Inputs/segment-start.script b/lld/test/ELF/linkerscript/Inputs/segment-start.script new file mode 100644 index 00000000000..95933a290d5 --- /dev/null +++ b/lld/test/ELF/linkerscript/Inputs/segment-start.script @@ -0,0 +1,7 @@ +SECTIONS +{ + PROVIDE (foobar1 = SEGMENT_START("text-segment", 0x8001)); + PROVIDE (foobar2 = SEGMENT_START("data-segment", 0x8002)); + PROVIDE (foobar3 = SEGMENT_START("bss-segment", 0x8003)); + PROVIDE (foobar4 = SEGMENT_START("abc-segment", 0x8004)); +} diff --git a/lld/test/ELF/linkerscript/segment-start.s b/lld/test/ELF/linkerscript/segment-start.s new file mode 100644 index 00000000000..2f3245fc21a --- /dev/null +++ b/lld/test/ELF/linkerscript/segment-start.s @@ -0,0 +1,22 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o %S/Inputs/segment-start.script -shared -o %t.so +// RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s + +// CHECK: Name: foobar1 +// CHECK-NEXT: Value: 0x8001 + +// CHECK: Name: foobar2 +// CHECK-NEXT: Value: 0x8002 + +// CHECK: Name: foobar3 +// CHECK-NEXT: Value: 0x8003 + +// CHECK: Name: foobar +// CHECK-NEXT: Value: 0x8004 + +.data +.quad foobar1 +.quad foobar2 +.quad foobar3 +.quad foobar4 |

