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

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 31 12:45:20 PST 2017


LGTM

George Rimar via Phabricator <reviews at reviews.llvm.org> writes:

> grimar created this revision.
>
> This is alternative to https://reviews.llvm.org/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).
>
>
> https://reviews.llvm.org/D29332
>
> Files:
>   ELF/LinkerScript.cpp
>   test/ELF/linkerscript/non-absolute.s
>
>
> Index: test/ELF/linkerscript/non-absolute.s
> ===================================================================
> --- test/ELF/linkerscript/non-absolute.s
> +++ test/ELF/linkerscript/non-absolute.s
> @@ -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
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -1612,6 +1612,12 @@
>  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 @@
>      };
>    }
>    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 == ">>")
>
>
> Index: test/ELF/linkerscript/non-absolute.s
> ===================================================================
> --- test/ELF/linkerscript/non-absolute.s
> +++ test/ELF/linkerscript/non-absolute.s
> @@ -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
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -1612,6 +1612,12 @@
>  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 @@
>      };
>    }
>    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 == ">>")


More information about the llvm-commits mailing list