summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp')
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index 21ce5785ea5e..9db746733aa3 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -150,6 +150,19 @@ static unsigned AdrImmBits(unsigned Value) {
return (hi19 << 5) | (lo2 << 29);
}
+static bool valueFitsIntoFixupKind(unsigned Kind, uint64_t Value) {
+ unsigned NumBits;
+ switch(Kind) {
+ case FK_Data_1: NumBits = 8; break;
+ case FK_Data_2: NumBits = 16; break;
+ case FK_Data_4: NumBits = 32; break;
+ case FK_Data_8: NumBits = 64; break;
+ default: return true;
+ }
+ return isUIntN(NumBits, Value) ||
+ isIntN(NumBits, static_cast<int64_t>(Value));
+}
+
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
uint64_t Value, MCContext &Ctx,
const Triple &TheTriple, bool IsResolved) {
@@ -309,11 +322,14 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
if (Value & 0x3)
Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
return (Value >> 2) & 0x3ffffff;
- case FK_NONE:
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
+ if (!valueFitsIntoFixupKind(Fixup.getTargetKind(), Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value too large for data type!");
+ LLVM_FALLTHROUGH;
+ case FK_NONE:
case FK_SecRel_2:
case FK_SecRel_4:
return Value;