summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-03-17 14:55:36 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-03-17 14:55:36 +0000
commit7ba5f47eb8bdcf900ea39406e0ed22af6921d1f7 (patch)
treed91fc2f2a510f7115e2d9de36c5799a734ca35dc /lld/ELF/LinkerScript.cpp
parent3e4a7d38ab29fa3daf82727ce69cfe87618fd154 (diff)
downloadbcm5719-llvm-7ba5f47eb8bdcf900ea39406e0ed22af6921d1f7.tar.gz
bcm5719-llvm-7ba5f47eb8bdcf900ea39406e0ed22af6921d1f7.zip
Handle & and | of non abs values.
Handling & in particular is probably important because of its use in aligning addresses. llvm-svn: 298096
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 48e29111edb..e93f138324f 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -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, ExprValue B) {
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(); }
OpenPOWER on IntegriCloud