Index: llvm/include/llvm/MC/MCFixup.h =================================================================== --- llvm/include/llvm/MC/MCFixup.h +++ llvm/include/llvm/MC/MCFixup.h @@ -75,7 +75,7 @@ const MCExpr *Value = nullptr; /// The byte index of start of the relocation inside the MCFragment. - uint32_t Offset = 0; + uint64_t Offset = 0; /// The target dependent kind of fixup item this is. The kind is used to /// determine how the operand value should be encoded into the instruction. @@ -84,7 +84,7 @@ /// The source location which gave rise to the fixup, if any. SMLoc Loc; public: - static MCFixup create(uint32_t Offset, const MCExpr *Value, + static MCFixup create(uint64_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc = SMLoc()) { assert(Kind <= MaxFixupKind && "Kind out of range!"); MCFixup FI; @@ -99,8 +99,8 @@ unsigned getTargetKind() const { return Kind; } - uint32_t getOffset() const { return Offset; } - void setOffset(uint32_t Value) { Offset = Value; } + uint64_t getOffset() const { return Offset; } + void setOffset(uint64_t Value) { Offset = Value; } const MCExpr *getValue() const { return Value; } Index: llvm/lib/MC/MCAssembler.cpp =================================================================== --- llvm/lib/MC/MCAssembler.cpp +++ llvm/lib/MC/MCAssembler.cpp @@ -269,7 +269,7 @@ "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!"); if (IsPCRel) { - uint32_t Offset = Layout.getFragmentOffset(DF) + Fixup.getOffset(); + uint64_t Offset = Layout.getFragmentOffset(DF) + Fixup.getOffset(); // A number of ARM fixups in Thumb mode require that the effective PC // address be determined as the 32-bit aligned version of the actual offset. Index: llvm/lib/MC/MCObjectStreamer.cpp =================================================================== --- llvm/lib/MC/MCObjectStreamer.cpp +++ llvm/lib/MC/MCObjectStreamer.cpp @@ -682,7 +682,7 @@ } static Optional> -getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset, +getOffsetAndDataFragment(const MCSymbol &Symbol, uint64_t &RelocOffset, MCDataFragment *&DF) { if (Symbol.isVariable()) { const MCExpr *SymbolExpr = Symbol.getVariableValue(); @@ -778,7 +778,7 @@ const MCSymbolRefExpr &SRE = cast(*OffsetVal.getSymA()); const MCSymbol &Symbol = SRE.getSymbol(); if (Symbol.isDefined()) { - uint32_t SymbolOffset = 0; + uint64_t SymbolOffset = 0; Optional> Error; Error = getOffsetAndDataFragment(Symbol, SymbolOffset, DF); Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -28,12 +28,29 @@ if (Kind < FirstTargetFixupKind) return Value; + auto handlePCRelFixupValue = [&Value, &Ctx, &Fixup](unsigned W) -> uint64_t { + assert(Value % 2 == 0 && "Non-even PC relative offset."); + int64_t NumHalfWords = (int64_t)Value / 2; + int64_t Max = maxIntN(W); + int64_t Min = minIntN(W); + if (NumHalfWords < Min || NumHalfWords > Max) { + Ctx.reportError(Fixup.getLoc(), "operand out of range (" + + Twine((int64_t) Value) + " not between " + Twine(Min * 2) + + " and " + Twine(Max * 2) + ")"); + return 0; + } + return NumHalfWords; + }; + switch (unsigned(Kind)) { case SystemZ::FK_390_PC12DBL: + return handlePCRelFixupValue(12); case SystemZ::FK_390_PC16DBL: + return handlePCRelFixupValue(16); case SystemZ::FK_390_PC24DBL: + return handlePCRelFixupValue(24); case SystemZ::FK_390_PC32DBL: - return (int64_t)Value / 2; + return handlePCRelFixupValue(32); case SystemZ::FK_390_12: if (!isUInt<12>(Value)) { Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp @@ -311,7 +311,8 @@ Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx); } } - Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind)); + Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind, + MI.getLoc())); // Output the fixup for the TLS marker if present. if (AllowTLS && OpNum + 1 < MI.getNumOperands()) { Index: llvm/test/MC/SystemZ/fixups-out-of-range-02.s =================================================================== --- /dev/null +++ llvm/test/MC/SystemZ/fixups-out-of-range-02.s @@ -0,0 +1,72 @@ +# RUN: not llvm-mc -triple s390x-unknown-unknown -filetype=obj -mcpu=zEC12 \ +# RUN: -o /dev/null %s 2>&1 | FileCheck %s + + .text + +# Test fixup ranges, which are encoded as half-words. + +# 12-bit +# CHECK: 15:9: error: operand out of range (4096 not between -4096 and 4094) +# CHECK-NEXT: bprp 0, .Lab1, 0 +# CHECK-NEXT: ^ +# CHECK-NEXT: 22:9: error: operand out of range (-4098 not between -4096 and 4094) +# CHECK-NEXT: bprp 0, .Lab0, 0 +# CHECK-NEXT: ^ + bprp 0, .Lab1, 0 +.Lab0: + bprp 0, .Lab1, 0 + .rept 1021 ; nop ; .endr +.Lab1: + nopr + bprp 0, .Lab0, 0 + bprp 0, .Lab0, 0 + +# 24-bit +# CHECK-NEXT: 31:9: error: operand out of range (16777220 not between -16777216 and 16777214) +# CHECK-NEXT: bprp 0, 0, .Lab3 +# CHECK-NEXT: ^ +# CHECK-NEXT: 38:9: error: operand out of range (-16777222 not between -16777216 and 16777214) +# CHECK-NEXT: bprp 0, 0, .Lab2 +# CHECK-NEXT: ^ + bprp 0, 0, .Lab3 +.Lab2: + bprp 0, 0, .Lab3 + .rept 4194302 ; nop ; .endr +.Lab3: + nopr + bprp 0, 0, .Lab2 + bprp 0, 0, .Lab2 + +# 16-bit +# CHECK-NEXT: 47:9: error: operand out of range (65540 not between -65536 and 65534) +# CHECK-NEXT: cij %r1, 0, 0, .Lab5 +# CHECK-NEXT: ^ +# CHECK-NEXT: 54:9: error: operand out of range (-65542 not between -65536 and 65534) +# CHECK-NEXT: cij %r1, 0, 0, .Lab4 +# CHECK-NEXT: ^ + cij %r1, 0, 0, .Lab5 +.Lab4: + cij %r1, 0, 0, .Lab5 + .rept 16382 ; nop ; .endr +.Lab5: + nopr + cij %r1, 0, 0, .Lab4 + cij %r1, 0, 0, .Lab4 + +# 32-bit +# CHECK-NEXT: 63:2: error: operand out of range (4294967300 not between -4294967296 and 4294967294) +# CHECK-NEXT: larl %r1, .Lab7 +# CHECK-NEXT: ^ +# CHECK-NEXT: 70:2: error: operand out of range (-4294967302 not between -4294967296 and 4294967294) +# CHECK-NEXT: larl %r1, .Lab6 +# CHECK-NEXT: ^ + larl %r1, .Lab7 +.Lab6: + larl %r1, .Lab7 + .rept 1073741822 ; nop ; .endr +.Lab7: + nopr + larl %r1, .Lab6 + larl %r1, .Lab6 + +# CHECK-NOT: error