diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-03-17 14:55:36 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-03-17 14:55:36 +0000 |
| commit | 7ba5f47eb8bdcf900ea39406e0ed22af6921d1f7 (patch) | |
| tree | d91fc2f2a510f7115e2d9de36c5799a734ca35dc /lld/ELF/LinkerScript.cpp | |
| parent | 3e4a7d38ab29fa3daf82727ce69cfe87618fd154 (diff) | |
| download | bcm5719-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.cpp | 22 |
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(); } |

