Index: lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -13,6 +13,8 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -60,6 +62,35 @@ } } +static bool isFixupRelative(unsigned Kind) { + switch (Kind) { + default: + llvm_unreachable("invalid fixup kind!"); + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + case FK_Data_8: + case X86::reloc_signed_4byte: + case X86::reloc_signed_4byte_relax: + case X86::reloc_global_offset_table8: + case X86::reloc_global_offset_table: + return false; + case FK_PCRel_1: + case FK_SecRel_1: + case FK_PCRel_2: + case FK_SecRel_2: + case FK_PCRel_4: + case FK_SecRel_4: + case X86::reloc_riprel_4byte: + case X86::reloc_riprel_4byte_relax: + case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_riprel_4byte_movq_load: + case FK_PCRel_8: + case FK_SecRel_8: + return true; + } +} + namespace { class X86ELFObjectWriter : public MCELFObjectTargetWriter { @@ -119,8 +150,19 @@ // Specifically ignore overflow/underflow as long as the leakage is // limited to the lower bits. This is to remain compatible with // other assemblers. - assert(isIntN(Size * 8 + 1, Value) && - "Value does not fit in the Fixup field"); + if (isFixupRelative(Fixup.getKind())) { + if (!isIntN(Size * 8, Value)) { + Asm.getContext().reportError(Fixup.getLoc(), + "Value " + Twine(int64_t(Value)) + + " does not fit in the Fixup field"); + } + } else { + if (!isIntN((Size * 8) + 1, Value)) { + Asm.getContext().reportError(Fixup.getLoc(), + "Value " + Twine(Value) + + " does not fit in the Fixup field"); + } + } for (unsigned i = 0; i != Size; ++i) Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); Index: test/MC/MachO/reloc.s =================================================================== --- test/MC/MachO/reloc.s +++ test/MC/MachO/reloc.s @@ -37,7 +37,7 @@ .text _f0: L1: - jmp 0xbabecafe + jmp 0x7abecafe jmp L0 jmp L1 ret Index: test/MC/X86/x86-jcxz-loop-fixup.s =================================================================== --- test/MC/X86/x86-jcxz-loop-fixup.s +++ test/MC/X86/x86-jcxz-loop-fixup.s @@ -0,0 +1,29 @@ +# RUN: not llvm-mc -filetype=obj -triple=x86_64-linux-gnu %s 2>&1 | FileCheck %s + + .balign 256 +label00: +// CHECK: Value 509 does not fit in the Fixup field + jecxz label01 +// CHECK: Value 507 does not fit in the Fixup field + jrcxz label01 +// CHECK: Value 505 does not fit in the Fixup field + loop label01 +// CHECK: Value 503 does not fit in the Fixup field + loope label01 +// CHECK: Value 501 does not fit in the Fixup field + loopne label01 + .balign 512 +label01: +// CHECK: Value -515 does not fit in the Fixup field + jecxz label00 +// CHECK: Value -517 does not fit in the Fixup field + jrcxz label00 +// CHECK: Value -519 does not fit in the Fixup field + loop label00 +// CHECK: Value -521 does not fit in the Fixup field + loope label00 +// CHECK: Value -523 does not fit in the Fixup field + loopne label00 + + +