[lld] r298096 - Handle & and | of non abs values.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 17 07:55:36 PDT 2017


Author: rafael
Date: Fri Mar 17 09:55:36 2017
New Revision: 298096

URL: http://llvm.org/viewvc/llvm-project?rev=298096&view=rev
Log:
Handle & and | of non abs values.

Handling & in particular is probably important because of its use in
aligning addresses.

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/test/ELF/linkerscript/expr-sections.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=298096&r1=298095&r2=298096&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Mar 17 09:55:36 2017
@@ -59,11 +59,23 @@ uint64_t ExprValue::getValue() const {
   return Val;
 }
 
-static ExprValue add(ExprValue A, ExprValue B) {
+uint64_t ExprValue::getSecAddr() const {
+  if (Sec)
+    return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
+  return 0;
+}
+
+// Some operations only support one non absolute value. Move the
+// absolute one to the right hand side for convenience.
+static void moveAbsRight(ExprValue &A, ExprValue &B) {
   if (A.isAbsolute())
     std::swap(A, B);
   if (!B.isAbsolute())
     error("At least one side of the expression must be absolute");
+}
+
+static ExprValue add(ExprValue A, ExprValue B) {
+  moveAbsRight(A, B);
   return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()};
 }
 static ExprValue sub(ExprValue A, ExprValue B) {
@@ -103,10 +115,14 @@ static ExprValue notEqual(ExprValue A, E
   return A.getValue() != B.getValue();
 }
 static ExprValue bitAnd(ExprValue A, ExprValue B) {
-  return A.getValue() & B.getValue();
+  moveAbsRight(A, B);
+  return {A.Sec, A.ForceAbsolute,
+          (A.getValue() & B.getValue()) - A.getSecAddr()};
 }
 static ExprValue bitOr(ExprValue A, ExprValue B) {
-  return A.getValue() | B.getValue();
+  moveAbsRight(A, B);
+  return {A.Sec, A.ForceAbsolute,
+          (A.getValue() | B.getValue()) - A.getSecAddr()};
 }
 static ExprValue bitNot(ExprValue A) { return ~A.getValue(); }
 static ExprValue minus(ExprValue A) { return -A.getValue(); }

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=298096&r1=298095&r2=298096&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Mar 17 09:55:36 2017
@@ -49,6 +49,7 @@ struct ExprValue {
   ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
   bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
   uint64_t getValue() const;
+  uint64_t getSecAddr() const;
 };
 
 // This represents an expression in the linker script.

Modified: lld/trunk/test/ELF/linkerscript/expr-sections.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/expr-sections.s?rev=298096&r1=298095&r2=298096&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/expr-sections.s (original)
+++ lld/trunk/test/ELF/linkerscript/expr-sections.s Fri Mar 17 09:55:36 2017
@@ -1,35 +1,22 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
-# RUN: echo "SECTIONS { foo = ADDR(.text) + 1; bar = 1 + ADDR(.text); };" > %t.script
+# RUN: echo "SECTIONS { \
+# RUN:        . = . + 4; \
+# RUN:        .text : { \
+# RUN:          *(.text) \
+# RUN:          foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); \
+# RUN:          foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); \
+# RUN:          foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); \
+# RUN:        } \
+# RUN: };" > %t.script
 # RUN: ld.lld -o %t.so --script %t.script %t.o -shared
-# RUN: llvm-readobj -t -s %t.so | FileCheck %s
+# RUN: llvm-objdump -t -h %t.so | FileCheck %s
 
-# CHECK:      Section {
-# CHECK:        Index:
-# CHECK:        Name: .text
-# CHECK-NEXT:   Type:
-# CHECK-NEXT:   Flags [
-# CHECK-NEXT:     SHF_ALLOC
-# CHECK-NEXT:     SHF_EXECINSTR
-# CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0x0
+# CHECK:  1 .text         00000000 0000000000000004 TEXT DATA
 
-# CHECK:      Symbol {
-# CHECK:        Name: foo
-# CHECK-NEXT:   Value: 0x1
-# CHECK-NEXT:   Size: 0
-# CHECK-NEXT:   Binding: Global
-# CHECK-NEXT:   Type: None
-# CHECK-NEXT:   Other: 0
-# CHECK-NEXT:   Section: .text
-# CHECK-NEXT: }
-
-# CHECK:      Symbol {
-# CHECK:        Name: bar
-# CHECK-NEXT:   Value: 0x1
-# CHECK-NEXT:   Size: 0
-# CHECK-NEXT:   Binding: Global
-# CHECK-NEXT:   Type: None
-# CHECK-NEXT:   Other: 0
-# CHECK-NEXT:   Section: .text
-# CHECK-NEXT: }
+# CHECK: 0000000000000005         .text		 00000000 foo1
+# CHECK: 0000000000000005         .text		 00000000 bar1
+# CHECK: 0000000000000000         .text		 00000000 foo2
+# CHECK: 0000000000000000         .text		 00000000 bar2
+# CHECK: 0000000000000005         .text		 00000000 foo3
+# CHECK: 0000000000000005         .text		 00000000 bar3




More information about the llvm-commits mailing list