Index: lld/trunk/ELF/Arch/AArch64.cpp =================================================================== --- lld/trunk/ELF/Arch/AArch64.cpp +++ lld/trunk/ELF/Arch/AArch64.cpp @@ -240,12 +240,12 @@ switch (Type) { case R_AARCH64_ABS16: case R_AARCH64_PREL16: - checkIntUInt<16>(Loc, Val, Type); + checkIntUInt(Loc, Val, 16, Type); write16le(Loc, Val); break; case R_AARCH64_ABS32: case R_AARCH64_PREL32: - checkIntUInt<32>(Loc, Val, Type); + checkIntUInt(Loc, Val, 32, Type); write32le(Loc, Val); break; case R_AARCH64_ABS64: @@ -260,11 +260,11 @@ case R_AARCH64_ADR_PREL_PG_HI21: case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSDESC_ADR_PAGE21: - checkInt<33>(Loc, Val, Type); + checkInt(Loc, Val, 33, Type); write32AArch64Addr(Loc, Val >> 12); break; case R_AARCH64_ADR_PREL_LO21: - checkInt<21>(Loc, Val, Type); + checkInt(Loc, Val, 21, Type); write32AArch64Addr(Loc, Val); break; case R_AARCH64_JUMP26: @@ -278,38 +278,38 @@ write32le(Loc, 0x14000000); LLVM_FALLTHROUGH; case R_AARCH64_CALL26: - checkInt<28>(Loc, Val, Type); + checkInt(Loc, Val, 28, Type); or32le(Loc, (Val & 0x0FFFFFFC) >> 2); break; case R_AARCH64_CONDBR19: case R_AARCH64_LD_PREL_LO19: - checkAlignment<4>(Loc, Val, Type); - checkInt<21>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); + checkInt(Loc, Val, 21, Type); or32le(Loc, (Val & 0x1FFFFC) << 3); break; case R_AARCH64_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case R_AARCH64_TLSDESC_LD64_LO12: - checkAlignment<8>(Loc, Val, Type); + checkAlignment(Loc, Val, 8, Type); or32le(Loc, (Val & 0xFF8) << 7); break; case R_AARCH64_LDST8_ABS_LO12_NC: or32AArch64Imm(Loc, getBits(Val, 0, 11)); break; case R_AARCH64_LDST16_ABS_LO12_NC: - checkAlignment<2>(Loc, Val, Type); + checkAlignment(Loc, Val, 2, Type); or32AArch64Imm(Loc, getBits(Val, 1, 11)); break; case R_AARCH64_LDST32_ABS_LO12_NC: - checkAlignment<4>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); or32AArch64Imm(Loc, getBits(Val, 2, 11)); break; case R_AARCH64_LDST64_ABS_LO12_NC: - checkAlignment<8>(Loc, Val, Type); + checkAlignment(Loc, Val, 8, Type); or32AArch64Imm(Loc, getBits(Val, 3, 11)); break; case R_AARCH64_LDST128_ABS_LO12_NC: - checkAlignment<16>(Loc, Val, Type); + checkAlignment(Loc, Val, 16, Type); or32AArch64Imm(Loc, getBits(Val, 4, 11)); break; case R_AARCH64_MOVW_UABS_G0_NC: @@ -325,11 +325,11 @@ or32le(Loc, (Val & 0xFFFF000000000000) >> 43); break; case R_AARCH64_TSTBR14: - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); or32le(Loc, (Val & 0xFFFC) << 3); break; case R_AARCH64_TLSLE_ADD_TPREL_HI12: - checkInt<24>(Loc, Val, Type); + checkInt(Loc, Val, 24, Type); or32AArch64Imm(Loc, Val >> 12); break; case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: @@ -353,7 +353,7 @@ // movk x0, #0x10 // nop // nop - checkUInt<32>(Loc, Val, Type); + checkUInt(Loc, Val, 32, Type); switch (Type) { case R_AARCH64_TLSDESC_ADD_LO12: @@ -403,7 +403,7 @@ } void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { - checkUInt<32>(Loc, Val, Type); + checkUInt(Loc, Val, 32, Type); if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) { // Generate MOVZ. Index: lld/trunk/ELF/Arch/ARM.cpp =================================================================== --- lld/trunk/ELF/Arch/ARM.cpp +++ lld/trunk/ELF/Arch/ARM.cpp @@ -393,7 +393,7 @@ write32le(Loc, 1); break; case R_ARM_PREL31: - checkInt<31>(Loc, Val, Type); + checkInt(Loc, Val, 31, Type); write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); break; case R_ARM_CALL: @@ -402,7 +402,7 @@ if (Val & 1) { // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' - checkInt<26>(Loc, Val, Type); + checkInt(Loc, Val, 26, Type); write32le(Loc, 0xfa000000 | // opcode ((Val & 2) << 23) | // H ((Val >> 2) & 0x00ffffff)); // imm24 @@ -417,16 +417,16 @@ case R_ARM_JUMP24: case R_ARM_PC24: case R_ARM_PLT32: - checkInt<26>(Loc, Val, Type); + checkInt(Loc, Val, 26, Type); write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); break; case R_ARM_THM_JUMP11: - checkInt<12>(Loc, Val, Type); + checkInt(Loc, Val, 12, Type); write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); break; case R_ARM_THM_JUMP19: // Encoding T3: Val = S:J2:J1:imm6:imm11:0 - checkInt<21>(Loc, Val, Type); + checkInt(Loc, Val, 21, Type); write16le(Loc, (read16le(Loc) & 0xfbc0) | // opcode cond ((Val >> 10) & 0x0400) | // S @@ -452,7 +452,7 @@ case R_ARM_THM_JUMP24: // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 // FIXME: Use of I1 and I2 require v6T2ops - checkInt<25>(Loc, Val, Type); + checkInt(Loc, Val, 25, Type); write16le(Loc, 0xf000 | // opcode ((Val >> 14) & 0x0400) | // S @@ -470,14 +470,14 @@ break; case R_ARM_MOVT_ABS: case R_ARM_MOVT_PREL: - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32le(Loc, (read32le(Loc) & ~0x000f0fff) | (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); break; case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVT_PREL: // Encoding T1: A = imm4:i:imm3:imm8 - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write16le(Loc, 0xf2c0 | // opcode ((Val >> 17) & 0x0400) | // i Index: lld/trunk/ELF/Arch/Mips.cpp =================================================================== --- lld/trunk/ELF/Arch/Mips.cpp +++ lld/trunk/ELF/Arch/Mips.cpp @@ -511,7 +511,7 @@ if (Config->Relocatable) { writeValue(Loc, Val + 0x8000, 16, 16); } else { - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); writeValue(Loc, Val, 16, 0); } break; @@ -519,7 +519,7 @@ if (Config->Relocatable) { writeShuffleValue(Loc, Val + 0x8000, 16, 16); } else { - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); writeShuffleValue(Loc, Val, 16, 0); } break; @@ -530,7 +530,7 @@ case R_MIPS_TLS_GD: case R_MIPS_TLS_GOTTPREL: case R_MIPS_TLS_LDM: - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); LLVM_FALLTHROUGH; case R_MIPS_CALL_LO16: case R_MIPS_GOT_LO16: @@ -546,7 +546,7 @@ case R_MICROMIPS_GPREL16: case R_MICROMIPS_TLS_GD: case R_MICROMIPS_TLS_LDM: - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); writeShuffleValue(Loc, Val, 16, 0); break; case R_MICROMIPS_CALL16: @@ -559,7 +559,7 @@ writeShuffleValue(Loc, Val, 16, 0); break; case R_MICROMIPS_GPREL7_S2: - checkInt<7>(Loc, Val, Type); + checkInt(Loc, Val, 7, Type); writeShuffleValue(Loc, Val, 7, 2); break; case R_MIPS_CALL_HI16: @@ -594,23 +594,23 @@ // Ignore this optimization relocation for now break; case R_MIPS_PC16: - checkAlignment<4>(Loc, Val, Type); - checkInt<18>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); + checkInt(Loc, Val, 18, Type); writeValue(Loc, Val, 16, 2); break; case R_MIPS_PC19_S2: - checkAlignment<4>(Loc, Val, Type); - checkInt<21>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); + checkInt(Loc, Val, 21, Type); writeValue(Loc, Val, 19, 2); break; case R_MIPS_PC21_S2: - checkAlignment<4>(Loc, Val, Type); - checkInt<23>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); + checkInt(Loc, Val, 23, Type); writeValue(Loc, Val, 21, 2); break; case R_MIPS_PC26_S2: - checkAlignment<4>(Loc, Val, Type); - checkInt<28>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); + checkInt(Loc, Val, 28, Type); writeValue(Loc, Val, 26, 2); break; case R_MIPS_PC32: @@ -618,35 +618,35 @@ break; case R_MICROMIPS_26_S1: case R_MICROMIPS_PC26_S1: - checkInt<27>(Loc, Val, Type); + checkInt(Loc, Val, 27, Type); writeShuffleValue(Loc, Val, 26, 1); break; case R_MICROMIPS_PC7_S1: - checkInt<8>(Loc, Val, Type); + checkInt(Loc, Val, 8, Type); writeMicroRelocation16(Loc, Val, 7, 1); break; case R_MICROMIPS_PC10_S1: - checkInt<11>(Loc, Val, Type); + checkInt(Loc, Val, 11, Type); writeMicroRelocation16(Loc, Val, 10, 1); break; case R_MICROMIPS_PC16_S1: - checkInt<17>(Loc, Val, Type); + checkInt(Loc, Val, 17, Type); writeShuffleValue(Loc, Val, 16, 1); break; case R_MICROMIPS_PC18_S3: - checkInt<21>(Loc, Val, Type); + checkInt(Loc, Val, 21, Type); writeShuffleValue(Loc, Val, 18, 3); break; case R_MICROMIPS_PC19_S2: - checkInt<21>(Loc, Val, Type); + checkInt(Loc, Val, 21, Type); writeShuffleValue(Loc, Val, 19, 2); break; case R_MICROMIPS_PC21_S1: - checkInt<22>(Loc, Val, Type); + checkInt(Loc, Val, 22, Type); writeShuffleValue(Loc, Val, 21, 1); break; case R_MICROMIPS_PC23_S2: - checkInt<25>(Loc, Val, Type); + checkInt(Loc, Val, 25, Type); writeShuffleValue(Loc, Val, 23, 2); break; default: Index: lld/trunk/ELF/Arch/PPC64.cpp =================================================================== --- lld/trunk/ELF/Arch/PPC64.cpp +++ lld/trunk/ELF/Arch/PPC64.cpp @@ -200,18 +200,18 @@ switch (Type) { case R_PPC64_ADDR14: { - checkAlignment<4>(Loc, Val, Type); + checkAlignment(Loc, Val, 4, Type); // Preserve the AA/LK bits in the branch instruction uint8_t AALK = Loc[3]; write16(Loc + 2, (AALK & 3) | (Val & 0xfffc)); break; } case R_PPC64_ADDR16: - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); write16(Loc, Val); break; case R_PPC64_ADDR16_DS: - checkInt<16>(Loc, Val, Type); + checkInt(Loc, Val, 16, Type); write16(Loc, (read16(Loc) & 3) | (Val & ~3)); break; case R_PPC64_ADDR16_HA: @@ -243,7 +243,7 @@ break; case R_PPC64_ADDR32: case R_PPC64_REL32: - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32(Loc, Val); break; case R_PPC64_ADDR64: @@ -253,7 +253,7 @@ break; case R_PPC64_REL24: { uint32_t Mask = 0x03FFFFFC; - checkInt<24>(Loc, Val, Type); + checkInt(Loc, Val, 24, Type); write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask)); break; } Index: lld/trunk/ELF/Arch/SPARCV9.cpp =================================================================== --- lld/trunk/ELF/Arch/SPARCV9.cpp +++ lld/trunk/ELF/Arch/SPARCV9.cpp @@ -77,23 +77,23 @@ case R_SPARC_32: case R_SPARC_UA32: // V-word32 - checkUInt<32>(Loc, Val, Type); + checkUInt(Loc, Val, 32, Type); write32be(Loc, Val); break; case R_SPARC_DISP32: // V-disp32 - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32be(Loc, Val); break; case R_SPARC_WDISP30: case R_SPARC_WPLT30: // V-disp30 - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff)); break; case R_SPARC_22: // V-imm22 - checkUInt<22>(Loc, Val, Type); + checkUInt(Loc, Val, 22, Type); write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff)); break; case R_SPARC_GOT22: @@ -103,7 +103,7 @@ break; case R_SPARC_WDISP19: // V-disp19 - checkInt<21>(Loc, Val, Type); + checkInt(Loc, Val, 21, Type); write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff)); break; case R_SPARC_GOT10: Index: lld/trunk/ELF/Arch/X86.cpp =================================================================== --- lld/trunk/ELF/Arch/X86.cpp +++ lld/trunk/ELF/Arch/X86.cpp @@ -255,15 +255,15 @@ // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are // being used for some 16-bit programs such as boot loaders, so // we want to support them. - checkUInt<8>(Loc, Val, Type); + checkUInt(Loc, Val, 8, Type); *Loc = Val; break; case R_386_PC8: - checkInt<8>(Loc, Val, Type); + checkInt(Loc, Val, 8, Type); *Loc = Val; break; case R_386_16: - checkUInt<16>(Loc, Val, Type); + checkUInt(Loc, Val, 16, Type); write16le(Loc, Val); break; case R_386_PC16: @@ -277,7 +277,7 @@ // current location subtracted from it. // We just check that Val fits in 17 bits. This misses some cases, but // should have no false positives. - checkInt<17>(Loc, Val, Type); + checkInt(Loc, Val, 17, Type); write16le(Loc, Val); break; case R_386_32: @@ -300,7 +300,7 @@ case R_386_TLS_LE_32: case R_386_TLS_TPOFF: case R_386_TLS_TPOFF32: - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32le(Loc, Val); break; default: Index: lld/trunk/ELF/Arch/X86_64.cpp =================================================================== --- lld/trunk/ELF/Arch/X86_64.cpp +++ lld/trunk/ELF/Arch/X86_64.cpp @@ -284,15 +284,15 @@ void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { switch (Type) { case R_X86_64_8: - checkUInt<8>(Loc, Val, Type); + checkUInt(Loc, Val, 8, Type); *Loc = Val; break; case R_X86_64_16: - checkUInt<16>(Loc, Val, Type); + checkUInt(Loc, Val, 16, Type); write16le(Loc, Val); break; case R_X86_64_32: - checkUInt<32>(Loc, Val, Type); + checkUInt(Loc, Val, 32, Type); write32le(Loc, Val); break; case R_X86_64_32S: @@ -308,7 +308,7 @@ case R_X86_64_TLSLD: case R_X86_64_DTPOFF32: case R_X86_64_SIZE32: - checkInt<32>(Loc, Val, Type); + checkInt(Loc, Val, 32, Type); write32le(Loc, Val); break; case R_X86_64_64: Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -176,29 +176,33 @@ Twine(Max).str() + "]" + Hint); } -template -static void checkInt(uint8_t *Loc, int64_t V, RelType Type) { - if (!llvm::isInt(V)) +// Sign-extend Nth bit all the way to MSB. +inline int64_t signExtend(uint64_t V, int N) { + return int64_t(V << (64 - N)) >> (64 - N); +} + +// Make sure that V can be represented as an N bit signed integer. +inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) { + if (V != signExtend(V, N)) reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N)); } -template -static void checkUInt(uint8_t *Loc, uint64_t V, RelType Type) { - if (!llvm::isUInt(V)) +// Make sure that V can be represented as an N bit unsigned integer. +inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) { + if ((V >> N) != 0) reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N)); } -template -static void checkIntUInt(uint8_t *Loc, uint64_t V, RelType Type) { - if (!llvm::isInt(V) && !llvm::isUInt(V)) - // For the error message we should cast V to a signed integer so that error - // messages show a small negative value rather than an extremely large one +// Make sure that V can be represented as an N bit signed or unsigned integer. +inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) { + // For the error message we should cast V to a signed integer so that error + // messages show a small negative value rather than an extremely large one + if (V != (uint64_t)signExtend(V, N) && (V >> N) != 0) reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N), - llvm::maxUIntN(N)); + llvm::maxIntN(N)); } -template -static void checkAlignment(uint8_t *Loc, uint64_t V, RelType Type) { +inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) { if ((V & (N - 1)) != 0) error(getErrorLocation(Loc) + "improper alignment for relocation " + lld::toString(Type) + ": 0x" + llvm::utohexstr(V) +