67 X86ELFObjectWriter(
bool is64Bit, uint8_t OSABI, uint16_t EMachine,
68 bool HasRelocationAddend,
bool foobar)
75 const uint64_t MaxNopLength;
79 MaxNopLength((CPU ==
"slm") ? 7 : 15) {
80 HasNopl = CPU !=
"generic" && CPU !=
"i386" && CPU !=
"i486" &&
81 CPU !=
"i586" && CPU !=
"pentium" && CPU !=
"pentium-mmx" &&
82 CPU !=
"i686" && CPU !=
"k6" && CPU !=
"k6-2" && CPU !=
"k6-3" &&
83 CPU !=
"geode" && CPU !=
"winchip-c6" && CPU !=
"winchip2" &&
84 CPU !=
"c3" && CPU !=
"c3-2" && CPU !=
"lakemont";
87 unsigned getNumFixupKinds()
const override {
97 {
"reloc_signed_4byte", 0, 32, 0},
98 {
"reloc_signed_4byte_relax", 0, 32, 0},
99 {
"reloc_global_offset_table", 0, 32, 0},
100 {
"reloc_global_offset_table8", 0, 64, 0},
111 void applyFixup(
const MCFixup &Fixup,
char *Data,
unsigned DataSize,
112 uint64_t
Value,
bool IsPCRel)
const override {
116 "Invalid fixup offset!");
123 "Value does not fit in the Fixup field");
125 for (
unsigned i = 0;
i != Size; ++
i)
126 Data[Fixup.
getOffset() +
i] = uint8_t(Value >> (
i * 8));
129 bool mayNeedRelaxation(
const MCInst &Inst)
const override;
131 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t Value,
136 MCInst &Res)
const override;
138 bool writeNopData(uint64_t Count,
MCObjectWriter *OW)
const override;
148 return (is16BitMode) ? X86::JAE_2 : X86::JAE_4;
150 return (is16BitMode) ? X86::JA_2 : X86::JA_4;
152 return (is16BitMode) ? X86::JBE_2 : X86::JBE_4;
154 return (is16BitMode) ? X86::JB_2 : X86::JB_4;
156 return (is16BitMode) ? X86::JE_2 : X86::JE_4;
158 return (is16BitMode) ? X86::JGE_2 : X86::JGE_4;
160 return (is16BitMode) ? X86::JG_2 : X86::JG_4;
162 return (is16BitMode) ? X86::JLE_2 : X86::JLE_4;
164 return (is16BitMode) ? X86::JL_2 : X86::JL_4;
166 return (is16BitMode) ? X86::JMP_2 : X86::JMP_4;
168 return (is16BitMode) ? X86::JNE_2 : X86::JNE_4;
170 return (is16BitMode) ? X86::JNO_2 : X86::JNO_4;
172 return (is16BitMode) ? X86::JNP_2 : X86::JNP_4;
174 return (is16BitMode) ? X86::JNS_2 : X86::JNS_4;
176 return (is16BitMode) ? X86::JO_2 : X86::JO_4;
178 return (is16BitMode) ? X86::JP_2 : X86::JP_4;
180 return (is16BitMode) ? X86::JS_2 : X86::JS_4;
191 case X86::IMUL16rri8:
return X86::IMUL16rri;
192 case X86::IMUL16rmi8:
return X86::IMUL16rmi;
193 case X86::IMUL32rri8:
return X86::IMUL32rri;
194 case X86::IMUL32rmi8:
return X86::IMUL32rmi;
195 case X86::IMUL64rri8:
return X86::IMUL64rri32;
196 case X86::IMUL64rmi8:
return X86::IMUL64rmi32;
199 case X86::AND16ri8:
return X86::AND16ri;
200 case X86::AND16mi8:
return X86::AND16mi;
201 case X86::AND32ri8:
return X86::AND32ri;
202 case X86::AND32mi8:
return X86::AND32mi;
203 case X86::AND64ri8:
return X86::AND64ri32;
204 case X86::AND64mi8:
return X86::AND64mi32;
207 case X86::OR16ri8:
return X86::OR16ri;
208 case X86::OR16mi8:
return X86::OR16mi;
209 case X86::OR32ri8:
return X86::OR32ri;
210 case X86::OR32mi8:
return X86::OR32mi;
211 case X86::OR64ri8:
return X86::OR64ri32;
212 case X86::OR64mi8:
return X86::OR64mi32;
215 case X86::XOR16ri8:
return X86::XOR16ri;
216 case X86::XOR16mi8:
return X86::XOR16mi;
217 case X86::XOR32ri8:
return X86::XOR32ri;
218 case X86::XOR32mi8:
return X86::XOR32mi;
219 case X86::XOR64ri8:
return X86::XOR64ri32;
220 case X86::XOR64mi8:
return X86::XOR64mi32;
223 case X86::ADD16ri8:
return X86::ADD16ri;
224 case X86::ADD16mi8:
return X86::ADD16mi;
225 case X86::ADD32ri8:
return X86::ADD32ri;
226 case X86::ADD32mi8:
return X86::ADD32mi;
227 case X86::ADD64ri8:
return X86::ADD64ri32;
228 case X86::ADD64mi8:
return X86::ADD64mi32;
231 case X86::ADC16ri8:
return X86::ADC16ri;
232 case X86::ADC16mi8:
return X86::ADC16mi;
233 case X86::ADC32ri8:
return X86::ADC32ri;
234 case X86::ADC32mi8:
return X86::ADC32mi;
235 case X86::ADC64ri8:
return X86::ADC64ri32;
236 case X86::ADC64mi8:
return X86::ADC64mi32;
239 case X86::SUB16ri8:
return X86::SUB16ri;
240 case X86::SUB16mi8:
return X86::SUB16mi;
241 case X86::SUB32ri8:
return X86::SUB32ri;
242 case X86::SUB32mi8:
return X86::SUB32mi;
243 case X86::SUB64ri8:
return X86::SUB64ri32;
244 case X86::SUB64mi8:
return X86::SUB64mi32;
247 case X86::SBB16ri8:
return X86::SBB16ri;
248 case X86::SBB16mi8:
return X86::SBB16mi;
249 case X86::SBB32ri8:
return X86::SBB32ri;
250 case X86::SBB32mi8:
return X86::SBB32mi;
251 case X86::SBB64ri8:
return X86::SBB64ri32;
252 case X86::SBB64mi8:
return X86::SBB64mi32;
255 case X86::CMP16ri8:
return X86::CMP16ri;
256 case X86::CMP16mi8:
return X86::CMP16mi;
257 case X86::CMP32ri8:
return X86::CMP32ri;
258 case X86::CMP32mi8:
return X86::CMP32mi;
259 case X86::CMP64ri8:
return X86::CMP64ri32;
260 case X86::CMP64mi8:
return X86::CMP64mi32;
263 case X86::PUSH32i8:
return X86::PUSHi32;
264 case X86::PUSH16i8:
return X86::PUSHi16;
265 case X86::PUSH64i8:
return X86::PUSH64i32;
276 bool X86AsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
295 bool X86AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
300 return int64_t(Value) != int64_t(int8_t(Value));
305 void X86AsmBackend::relaxInstruction(
const MCInst &Inst,
327 bool X86AsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
328 static const uint8_t Nops[10][10] = {
336 {0x0f, 0x1f, 0x40, 0x00},
338 {0x0f, 0x1f, 0x44, 0x00, 0x00},
340 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
342 {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
344 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
346 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
348 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
355 for (uint64_t
i = 0;
i < Count; ++
i)
363 const uint8_t ThisNopLength = (uint8_t)
std::min(Count, MaxNopLength);
364 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
365 for (uint8_t
i = 0;
i < Prefixes;
i++)
367 const uint8_t Rest = ThisNopLength - Prefixes;
368 for (uint8_t
i = 0;
i < Rest;
i++)
370 Count -= ThisNopLength;
371 }
while (Count != 0);
380 class ELFX86AsmBackend :
public X86AsmBackend {
384 : X86AsmBackend(T, CPU), OSABI(OSABI) {}
387 class ELFX86_32AsmBackend :
public ELFX86AsmBackend {
390 : ELFX86AsmBackend(T, OSABI, CPU) {}
397 class ELFX86_X32AsmBackend :
public ELFX86AsmBackend {
400 : ELFX86AsmBackend(T, OSABI, CPU) {}
408 class ELFX86_IAMCUAsmBackend :
public ELFX86AsmBackend {
411 : ELFX86AsmBackend(T, OSABI, CPU) {}
419 class ELFX86_64AsmBackend :
public ELFX86AsmBackend {
422 : ELFX86AsmBackend(T, OSABI, CPU) {}
429 class WindowsX86AsmBackend :
public X86AsmBackend {
434 : X86AsmBackend(T, CPU)
457 UNWIND_MODE_BP_FRAME = 0x01000000,
460 UNWIND_MODE_STACK_IMMD = 0x02000000,
463 UNWIND_MODE_STACK_IND = 0x03000000,
466 UNWIND_MODE_DWARF = 0x04000000,
469 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
472 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
477 class DarwinX86AsmBackend :
public X86AsmBackend {
481 enum { CU_NUM_SAVED_REGS = 6 };
483 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
487 unsigned MoveInstrSize;
488 unsigned StackDivide;
491 unsigned PushInstrSize(
unsigned Reg)
const {
515 if (Instrs.
empty())
return 0;
518 unsigned SavedRegIdx = 0;
519 memset(SavedRegs, 0,
sizeof(SavedRegs));
526 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
527 unsigned InstrOffset = 0;
528 unsigned StackAdjust = 0;
529 unsigned StackSize = 0;
530 unsigned PrevStackSize = 0;
531 unsigned NumDefCFAOffsets = 0;
533 for (
unsigned i = 0, e = Instrs.
size();
i != e; ++
i) {
553 (Is64Bit ? X86::RBP : X86::EBP))
557 memset(SavedRegs, 0,
sizeof(SavedRegs));
560 InstrOffset += MoveInstrSize;
578 PrevStackSize = StackSize;
596 if (SavedRegIdx == CU_NUM_SAVED_REGS)
599 return CU::UNWIND_MODE_DWARF;
602 SavedRegs[SavedRegIdx++] =
Reg;
603 StackAdjust += OffsetSize;
604 InstrOffset += PushInstrSize(Reg);
610 StackAdjust /= StackDivide;
613 if ((StackAdjust & 0xFF) != StackAdjust)
615 return CU::UNWIND_MODE_DWARF;
618 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
619 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
621 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
622 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
623 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
630 if ((NumDefCFAOffsets == SavedRegIdx + 1 &&
631 StackSize - PrevStackSize == 1) ||
632 (Instrs.
size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2))
633 return CU::UNWIND_MODE_DWARF;
635 SubtractInstrIdx += InstrOffset;
638 if ((StackSize & 0xFF) == StackSize) {
640 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
643 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
645 if ((StackAdjust & 0x7) != StackAdjust)
647 return CU::UNWIND_MODE_DWARF;
650 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
654 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
658 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
663 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
667 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
668 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
671 CompactUnwindEncoding |=
672 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
675 return CompactUnwindEncoding;
681 int getCompactUnwindRegNum(
unsigned Reg)
const {
682 static const MCPhysReg CU32BitRegs[7] = {
683 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
686 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
688 const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
689 for (
int Idx = 1; *CURegs; ++CURegs, ++Idx)
698 uint32_t encodeCompactUnwindRegistersWithFrame()
const {
703 for (
int i = 0, Idx = 0;
i != CU_NUM_SAVED_REGS; ++
i) {
704 unsigned Reg = SavedRegs[
i];
707 int CURegNum = getCompactUnwindRegNum(Reg);
708 if (CURegNum == -1)
return ~0U;
712 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
715 assert((RegEnc & 0x3FFFF) == RegEnc &&
716 "Invalid compact register encoding!");
723 uint32_t encodeCompactUnwindRegistersWithoutFrame(
unsigned RegCount)
const {
737 for (
unsigned i = 0;
i < RegCount; ++
i) {
738 int CUReg = getCompactUnwindRegNum(SavedRegs[
i]);
739 if (CUReg == -1)
return ~0U;
740 SavedRegs[
i] = CUReg;
744 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
746 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
747 for (
unsigned i = CU_NUM_SAVED_REGS - RegCount;
i < CU_NUM_SAVED_REGS; ++
i){
748 unsigned Countless = 0;
749 for (
unsigned j = CU_NUM_SAVED_REGS - RegCount; j <
i; ++j)
750 if (SavedRegs[j] < SavedRegs[i])
753 RenumRegs[
i] = SavedRegs[
i] - Countless - 1;
760 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
761 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
765 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
766 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
770 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
771 + 3 * RenumRegs[4] + RenumRegs[5];
774 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
778 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
781 permutationEncoding |= RenumRegs[5];
785 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
786 "Invalid compact register encoding!");
787 return permutationEncoding;
793 : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) {
794 memset(SavedRegs, 0,
sizeof(SavedRegs));
795 OffsetSize = Is64Bit ? 8 : 4;
796 MoveInstrSize = Is64Bit ? 3 : 2;
797 StackDivide = Is64Bit ? 8 : 4;
801 class DarwinX86_32AsmBackend :
public DarwinX86AsmBackend {
805 : DarwinX86AsmBackend(T, MRI, CPU,
false) {}
814 uint32_t generateCompactUnwindEncoding(
816 return generateCompactUnwindEncodingImpl(Instrs);
820 class DarwinX86_64AsmBackend :
public DarwinX86AsmBackend {
825 : DarwinX86AsmBackend(T, MRI, CPU,
true), Subtype(st) {}
833 uint32_t generateCompactUnwindEncoding(
835 return generateCompactUnwindEncodingImpl(Instrs);
847 return new DarwinX86_32AsmBackend(T, MRI, CPU);
850 return new WindowsX86AsmBackend(T,
false, CPU);
855 return new ELFX86_IAMCUAsmBackend(T, OSABI, CPU);
857 return new ELFX86_32AsmBackend(T, OSABI, CPU);
870 return new DarwinX86_64AsmBackend(T, MRI, CPU, CS);
874 return new WindowsX86AsmBackend(T,
true, CPU);
879 return new ELFX86_X32AsmBackend(T, OSABI, CPU);
880 return new ELFX86_64AsmBackend(T, OSABI, CPU);
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
A eight-byte pc relative fixup.
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
A raw_ostream that writes to an SmallVector or SmallString.
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
unsigned getRegister() const
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
bool isOSWindows() const
Tests whether the OS is Windows.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
A one-byte pc relative fixup.
MCObjectWriter * createX86WinCOFFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit)
Construct an X86 Win COFF object writer.
Encapsulates the layout of an assembly file at a particular point in time.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
A four-byte section relative fixup.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
const MCSubtargetInfo * STI
A two-byte section relative fixup.
Function Alias Analysis false
CompactUnwindEncodings
Compact unwind encoding values.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
uint32_t getOffset() const
size_t size() const
size - Get the array size.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Instances of this class represent a single low-level machine instruction.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
A switch()-like statement whose cases are string literals.
unsigned const MachineRegisterInfo * MRI
MCObjectWriter * createX86MachObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct an X86 Mach-O object writer.
static bool is64Bit(const char *name)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
virtual Optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
bool empty() const
empty - Check if the array is empty.
static unsigned getFixupKindLog2Size(unsigned Kind)
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
static unsigned getRelaxedOpcodeArith(const MCInst &Inst)
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
MCFixupKind getKind() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
OpType getOperation() const
MCAsmBackend * createX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
void setOpcode(unsigned Op)
A two-byte pc relative fixup.
A four-byte pc relative fixup.
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
static unsigned getRelaxedOpcodeBranch(const MCInst &Inst, bool is16BitMode)
MCObjectWriter * createX86ELFObjectWriter(raw_pwrite_stream &OS, bool IsELF64, uint8_t OSABI, uint16_t EMachine)
Construct an X86 ELF object writer.
unsigned getOpcode() const
Target - Wrapper for Target specific information.
A one-byte section relative fixup.
static unsigned getRelaxedOpcode(const MCInst &Inst, bool is16BitMode)
A eight-byte section relative fixup.
unsigned getNumOperands() const
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
MCSubtargetInfo - Generic base class for all target subtargets.
MCAsmBackend * createX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
Target independent information on a fixup kind.
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
An abstract base class for streams implementations that also support a pwrite operation.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Generic interface to target specific assembler backends.
StringRef - Represent a constant reference to a string, i.e.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
const MCOperand & getOperand(unsigned i) const