[lld] daba24e - [ELF] << >>: make RHS less than 64
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 15 10:34:38 PDT 2023
Author: Fangrui Song
Date: 2023-06-15T10:34:33-07:00
New Revision: daba24ee7bd3d80f085e2e5f057af6b873a78a24
URL: https://github.com/llvm/llvm-project/commit/daba24ee7bd3d80f085e2e5f057af6b873a78a24
DIFF: https://github.com/llvm/llvm-project/commit/daba24ee7bd3d80f085e2e5f057af6b873a78a24.diff
LOG: [ELF] << >>: make RHS less than 64
The left/right shift linker script operators may trigger UB.
E.g. in linkerscript/end-overflow-check.test, the initial REGION1__PADDED_SR_SHIFT is
uint64_t(-3), cause the following expression to trigger an out-of-range shift in
a ubsan build of lld.
REGION1__PADDED_SR_SIZE = MAX(1 << REGION1__PADDED_SR_SHIFT, 32);
Protect such UBs by making RHS less than 64.
Added:
Modified:
lld/ELF/ScriptParser.cpp
lld/test/ELF/linkerscript/operators.test
Removed:
################################################################################
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index a4fb0f7c6e17c..85cee08999cd3 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1094,9 +1094,9 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
case '-':
return sub(lhs, e());
case '<':
- return lhs.getValue() << e().getValue();
+ return lhs.getValue() << e().getValue() % 64;
case '>':
- return lhs.getValue() >> e().getValue();
+ return lhs.getValue() >> e().getValue() % 64;
case '&':
return lhs.getValue() & e().getValue();
case '|':
@@ -1147,9 +1147,9 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
};
}
if (op == "<<")
- return [=] { return l().getValue() << r().getValue(); };
+ return [=] { return l().getValue() << r().getValue() % 64; };
if (op == ">>")
- return [=] { return l().getValue() >> r().getValue(); };
+ return [=] { return l().getValue() >> r().getValue() % 64; };
if (op == "<")
return [=] { return l().getValue() < r().getValue(); };
if (op == ">")
diff --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index 3958b956a8eb5..0b6fdc2fe63f8 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -12,6 +12,7 @@ SECTIONS {
multiplicative = 20 / 2 % 7;
additive = 1 - 2 + -3 * -2;
shift = 2 << 5 >> 1 << 2;
+ shift2 = 2 << 69 >> 65;
less = 1 < 0 ? 1 : 2;
lesseq = 1<<0 <= 1>>0 ? 1 : 2;
greater = 0 > 1 ? 1 : 2;
@@ -36,9 +37,11 @@ SECTIONS {
minusassign = 3;
minusassign -= 1;
lshiftassign = 1;
- lshiftassign <<= 2;
- rshiftassign = 5;
+ lshiftassign <<= 1;
+ lshiftassign <<= 65; # arbitrarily reduced to 1
+ rshiftassign = 24;
rshiftassign >>= 1;
+ rshiftassign >>= 130; # arbitrarily reduced to 2
andassign = 6;
andassign &= 4;
orassign = 4;
@@ -73,6 +76,7 @@ SECTIONS {
# CHECK-NEXT: 0000000000000003 A multiplicative
# CHECK-NEXT: 0000000000000005 A additive
# CHECK-NEXT: 0000000000000080 A shift
+# CHECK-NEXT: 0000000000000020 A shift
# CHECK-NEXT: 0000000000000002 A less
# CHECK-NEXT: 0000000000000001 A lesseq
# CHECK-NEXT: 0000000000000002 A greater
@@ -92,7 +96,7 @@ SECTIONS {
# CHECK-NEXT: 0000000000000003 A plusassign
# CHECK-NEXT: 0000000000000002 A minusassign
# CHECK-NEXT: 0000000000000004 A lshiftassign
-# CHECK-NEXT: 0000000000000002 A rshiftassign
+# CHECK-NEXT: 0000000000000003 A rshiftassign
# CHECK-NEXT: 0000000000000004 A andassign
# CHECK-NEXT: 0000000000000005 A orassign
# CHECK-NEXT: 0000000000000015 A braces
More information about the llvm-commits
mailing list