[ELF] - Linkerscript: properly mark minus expression with non-absolute flag

This is alternative to D28857 which was incorrect.

One of linux scripts contains:

vvar_start = . - 2 * (1 << 12);
vvar_page = vvar_start;
vvar_vsyscall_gtod_data = vvar_page + 128;
Previously we did not mark first expression as non-absolute,
though it contains location counter.

And LLD failed with error:
relocation R_X86_64_PC32 cannot refer to absolute symbol

This patch should fix the issue, and opens road for doing the same for other operators
(though not clear if that is needed).

Differential revision: https://reviews.llvm.org/D29332

llvm-svn: 293748
This commit is contained in:
George Rimar 2017-02-01 09:01:16 +00:00
parent efd412f8fe
commit cc4d3e5745
2 changed files with 38 additions and 7 deletions

View File

@ -1612,6 +1612,12 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
static Expr combine(StringRef Op, Expr L, Expr R) {
auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
auto GetOutSec = [=] {
const OutputSectionBase *S = L.Section();
return S ? S : R.Section();
};
if (Op == "*")
return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
if (Op == "/") {
@ -1625,14 +1631,9 @@ static Expr combine(StringRef Op, Expr L, Expr R) {
};
}
if (Op == "+")
return {[=](uint64_t Dot) { return L(Dot) + R(Dot); },
[=] { return L.IsAbsolute() && R.IsAbsolute(); },
[=] {
const OutputSectionBase *S = L.Section();
return S ? S : R.Section();
}};
return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, IsAbs, GetOutSec};
if (Op == "-")
return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
return {[=](uint64_t Dot) { return L(Dot) - R(Dot); }, IsAbs, GetOutSec};
if (Op == "<<")
return [=](uint64_t Dot) { return L(Dot) << R(Dot); };
if (Op == ">>")

View File

@ -0,0 +1,30 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
# RUN: echo "SECTIONS { A = . - 0x10; B = A + 0x1; }" > %t.script
# RUN: ld.lld -shared %t1.o --script %t.script -o %t
# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP
# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL
# DUMP: Disassembly of section .text:
# DUMP-NEXT: foo:
# DUMP-NEXT: 0: {{.*}} -21(%rip), %eax
# SYMBOL: Symbol {
# SYMBOL: Name: B
# SYMBOL-NEXT: Value: 0xFFFFFFFFFFFFFFF1
# SYMBOL-NEXT: Size: 0
# SYMBOL-NEXT: Binding: Local
# SYMBOL-NEXT: Type: None
# SYMBOL-NEXT: Other [
# SYMBOL-NEXT: STV_HIDDEN
# SYMBOL-NEXT: ]
# SYMBOL-NEXT: Section: .text
# SYMBOL-NEXT: }
.text
.globl foo
.type foo, @function
foo:
movl B(%rip), %eax
.hidden B