summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorPrakhar Bahuguna <prakhar.bahuguna@arm.com>2016-08-16 10:41:52 +0000
committerPrakhar Bahuguna <prakhar.bahuguna@arm.com>2016-08-16 10:41:52 +0000
commit15ed7ec5aab8de283b2cfc9b674b5382024c1da1 (patch)
tree48c40b51ab3f6bf481f75f0c99a6844dc58f80b1 /llvm/lib/Target
parentf16cd361d41135d7f261fd407d74fff38de9dfcb (diff)
downloadbcm5719-llvm-15ed7ec5aab8de283b2cfc9b674b5382024c1da1.tar.gz
bcm5719-llvm-15ed7ec5aab8de283b2cfc9b674b5382024c1da1.zip
[Thumb] Validate branch target for CBZ/CBNZ instructions.
Summary: The assembler currently does not check the branch target for CBZ/CBNZ instructions, which only permit branching forwards with a positive offset. This adds validation for the branch target to ensure negative PC-relative offsets are not encoded into the instruction, whether specified as a literal or as an assembler symbol. Reviewers: rengolin, t.p.northover Subscribers: llvm-commits, rengolin Differential Revision: https://reviews.llvm.org/D23312 llvm-svn: 278788
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp6
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp5
2 files changed, 11 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index b9b665fc1ea..c011c792bff 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6684,6 +6684,12 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
return Error(Operands[Op]->getStartLoc(), "branch target out of range");
break;
}
+ case ARM::tCBZ:
+ case ARM::tCBNZ: {
+ if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<6, 1>())
+ return Error(Operands[2]->getStartLoc(), "branch target out of range");
+ break;
+ }
case ARM::MOVi16:
case ARM::t2MOVi16:
case ARM::t2MOVTi16:
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 26f96ab77fe..5ac2d65a89e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -578,6 +578,11 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
// Offset by 4, and don't encode the low two bits.
return ((Value - 4) >> 2) & 0xff;
case ARM::fixup_arm_thumb_cb: {
+ // CB instructions can only branch to offsets in [0, 126] in multiples of 2
+ if (Ctx && ((int64_t)Value < 0 || Value > 0x3e || Value & 1)) {
+ Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
+ return 0;
+ }
// Offset by 4 and don't encode the lower bit, which is always 0.
// FIXME: diagnose if no Thumb2
uint32_t Binary = (Value - 4) >> 1;
OpenPOWER on IntegriCloud