64 X86ELFObjectWriter(
bool is64Bit, uint8_t OSABI, uint16_t EMachine,
65 bool HasRelocationAddend,
bool foobar)
72 const uint64_t MaxNopLength;
75 :
MCAsmBackend(), CPU(CPU), MaxNopLength(CPU ==
"slm" ? 7 : 15) {
76 HasNopl = CPU !=
"generic" && CPU !=
"i386" && CPU !=
"i486" &&
77 CPU !=
"i586" && CPU !=
"pentium" && CPU !=
"pentium-mmx" &&
78 CPU !=
"i686" && CPU !=
"k6" && CPU !=
"k6-2" && CPU !=
"k6-3" &&
79 CPU !=
"geode" && CPU !=
"winchip-c6" && CPU !=
"winchip2" &&
80 CPU !=
"c3" && CPU !=
"c3-2";
83 unsigned getNumFixupKinds()
const override {
91 {
"reloc_signed_4byte", 0, 4 * 8, 0},
92 {
"reloc_global_offset_table", 0, 4 * 8, 0}
104 uint64_t
Value,
bool IsPCRel)
const override {
107 assert(Fixup.
getOffset() + Size <= DataSize &&
108 "Invalid fixup offset!");
114 assert(
isIntN(Size * 8 + 1, Value) &&
115 "Value does not fit in the Fixup field");
117 for (
unsigned i = 0; i != Size; ++i)
118 Data[Fixup.
getOffset() + i] = uint8_t(Value >> (i * 8));
121 bool mayNeedRelaxation(
const MCInst &Inst)
const override;
123 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t Value,
127 void relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const override;
129 bool writeNopData(uint64_t Count,
MCObjectWriter *OW)
const override;
138 case X86::JAE_1:
return X86::JAE_4;
139 case X86::JA_1:
return X86::JA_4;
140 case X86::JBE_1:
return X86::JBE_4;
141 case X86::JB_1:
return X86::JB_4;
142 case X86::JE_1:
return X86::JE_4;
143 case X86::JGE_1:
return X86::JGE_4;
144 case X86::JG_1:
return X86::JG_4;
145 case X86::JLE_1:
return X86::JLE_4;
146 case X86::JL_1:
return X86::JL_4;
147 case X86::JMP_1:
return X86::JMP_4;
148 case X86::JNE_1:
return X86::JNE_4;
149 case X86::JNO_1:
return X86::JNO_4;
150 case X86::JNP_1:
return X86::JNP_4;
151 case X86::JNS_1:
return X86::JNS_4;
152 case X86::JO_1:
return X86::JO_4;
153 case X86::JP_1:
return X86::JP_4;
154 case X86::JS_1:
return X86::JS_4;
164 case X86::IMUL16rri8:
return X86::IMUL16rri;
165 case X86::IMUL16rmi8:
return X86::IMUL16rmi;
166 case X86::IMUL32rri8:
return X86::IMUL32rri;
167 case X86::IMUL32rmi8:
return X86::IMUL32rmi;
168 case X86::IMUL64rri8:
return X86::IMUL64rri32;
169 case X86::IMUL64rmi8:
return X86::IMUL64rmi32;
172 case X86::AND16ri8:
return X86::AND16ri;
173 case X86::AND16mi8:
return X86::AND16mi;
174 case X86::AND32ri8:
return X86::AND32ri;
175 case X86::AND32mi8:
return X86::AND32mi;
176 case X86::AND64ri8:
return X86::AND64ri32;
177 case X86::AND64mi8:
return X86::AND64mi32;
180 case X86::OR16ri8:
return X86::OR16ri;
181 case X86::OR16mi8:
return X86::OR16mi;
182 case X86::OR32ri8:
return X86::OR32ri;
183 case X86::OR32mi8:
return X86::OR32mi;
184 case X86::OR64ri8:
return X86::OR64ri32;
185 case X86::OR64mi8:
return X86::OR64mi32;
188 case X86::XOR16ri8:
return X86::XOR16ri;
189 case X86::XOR16mi8:
return X86::XOR16mi;
190 case X86::XOR32ri8:
return X86::XOR32ri;
191 case X86::XOR32mi8:
return X86::XOR32mi;
192 case X86::XOR64ri8:
return X86::XOR64ri32;
193 case X86::XOR64mi8:
return X86::XOR64mi32;
196 case X86::ADD16ri8:
return X86::ADD16ri;
197 case X86::ADD16mi8:
return X86::ADD16mi;
198 case X86::ADD32ri8:
return X86::ADD32ri;
199 case X86::ADD32mi8:
return X86::ADD32mi;
200 case X86::ADD64ri8:
return X86::ADD64ri32;
201 case X86::ADD64mi8:
return X86::ADD64mi32;
204 case X86::SUB16ri8:
return X86::SUB16ri;
205 case X86::SUB16mi8:
return X86::SUB16mi;
206 case X86::SUB32ri8:
return X86::SUB32ri;
207 case X86::SUB32mi8:
return X86::SUB32mi;
208 case X86::SUB64ri8:
return X86::SUB64ri32;
209 case X86::SUB64mi8:
return X86::SUB64mi32;
212 case X86::CMP16ri8:
return X86::CMP16ri;
213 case X86::CMP16mi8:
return X86::CMP16mi;
214 case X86::CMP32ri8:
return X86::CMP32ri;
215 case X86::CMP32mi8:
return X86::CMP32mi;
216 case X86::CMP64ri8:
return X86::CMP64ri32;
217 case X86::CMP64mi8:
return X86::CMP64mi32;
220 case X86::PUSH32i8:
return X86::PUSHi32;
221 case X86::PUSH16i8:
return X86::PUSHi16;
222 case X86::PUSH64i8:
return X86::PUSH64i32;
233 bool X86AsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
252 bool X86AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
257 return int64_t(Value) != int64_t(int8_t(Value));
262 void X86AsmBackend::relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const {
281 bool X86AsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
282 static const uint8_t Nops[10][10] = {
290 {0x0f, 0x1f, 0x40, 0x00},
292 {0x0f, 0x1f, 0x44, 0x00, 0x00},
294 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
296 {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
298 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
300 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
302 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
309 for (uint64_t i = 0; i < Count; ++i)
317 const uint8_t ThisNopLength = (uint8_t)
std::min(Count, MaxNopLength);
318 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
319 for (uint8_t i = 0; i < Prefixes; i++)
321 const uint8_t Rest = ThisNopLength - Prefixes;
322 for (uint8_t i = 0; i < Rest; i++)
323 OW->
write8(Nops[Rest - 1][i]);
324 Count -= ThisNopLength;
325 }
while (Count != 0);
334 class ELFX86AsmBackend :
public X86AsmBackend {
338 : X86AsmBackend(T, CPU), OSABI(OSABI) {}
341 class ELFX86_32AsmBackend :
public ELFX86AsmBackend {
344 : ELFX86AsmBackend(T, OSABI, CPU) {}
351 class ELFX86_X32AsmBackend :
public ELFX86AsmBackend {
354 : ELFX86AsmBackend(T, OSABI, CPU) {}
362 class ELFX86_64AsmBackend :
public ELFX86AsmBackend {
365 : ELFX86AsmBackend(T, OSABI, CPU) {}
372 class WindowsX86AsmBackend :
public X86AsmBackend {
377 : X86AsmBackend(T, CPU)
392 UNWIND_MODE_BP_FRAME = 0x01000000,
395 UNWIND_MODE_STACK_IMMD = 0x02000000,
398 UNWIND_MODE_STACK_IND = 0x03000000,
401 UNWIND_MODE_DWARF = 0x04000000,
404 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
407 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
412 class DarwinX86AsmBackend :
public X86AsmBackend {
416 enum { CU_NUM_SAVED_REGS = 6 };
418 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
422 unsigned MoveInstrSize;
423 unsigned StackDivide;
426 unsigned PushInstrSize(
unsigned Reg)
const {
450 if (Instrs.
empty())
return 0;
453 unsigned SavedRegIdx = 0;
454 memset(SavedRegs, 0,
sizeof(SavedRegs));
459 uint32_t CompactUnwindEncoding = 0;
461 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
462 unsigned InstrOffset = 0;
463 unsigned StackAdjust = 0;
464 unsigned StackSize = 0;
465 unsigned PrevStackSize = 0;
466 unsigned NumDefCFAOffsets = 0;
468 for (
unsigned i = 0, e = Instrs.
size(); i != e; ++i) {
484 assert(MRI.getLLVMRegNum(Inst.
getRegister(),
true) ==
485 (Is64Bit ? X86::RBP : X86::EBP) &&
"Invalid frame pointer!");
488 memset(SavedRegs, 0,
sizeof(SavedRegs));
491 InstrOffset += MoveInstrSize;
509 PrevStackSize = StackSize;
527 if (SavedRegIdx == CU_NUM_SAVED_REGS)
530 return CU::UNWIND_MODE_DWARF;
532 unsigned Reg = MRI.getLLVMRegNum(Inst.
getRegister(),
true);
533 SavedRegs[SavedRegIdx++] =
Reg;
534 StackAdjust += OffsetSize;
535 InstrOffset += PushInstrSize(Reg);
541 StackAdjust /= StackDivide;
544 if ((StackAdjust & 0xFF) != StackAdjust)
546 return CU::UNWIND_MODE_DWARF;
549 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
550 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
552 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
553 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
554 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
561 if ((NumDefCFAOffsets == SavedRegIdx + 1 &&
562 StackSize - PrevStackSize == 1) ||
563 (Instrs.
size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2))
564 return CU::UNWIND_MODE_DWARF;
566 SubtractInstrIdx += InstrOffset;
569 if ((StackSize & 0xFF) == StackSize) {
571 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
574 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
576 if ((StackAdjust & 0x7) != StackAdjust)
578 return CU::UNWIND_MODE_DWARF;
581 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
585 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
589 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
593 std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
594 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
598 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
599 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
602 CompactUnwindEncoding |=
603 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
606 return CompactUnwindEncoding;
612 int getCompactUnwindRegNum(
unsigned Reg)
const {
613 static const uint16_t CU32BitRegs[7] = {
614 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
616 static const uint16_t CU64BitRegs[] = {
617 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
619 const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
620 for (
int Idx = 1; *CURegs; ++CURegs, ++Idx)
629 uint32_t encodeCompactUnwindRegistersWithFrame()
const {
634 for (
int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
635 unsigned Reg = SavedRegs[i];
638 int CURegNum = getCompactUnwindRegNum(Reg);
639 if (CURegNum == -1)
return ~0U;
643 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
646 assert((RegEnc & 0x3FFFF) == RegEnc &&
647 "Invalid compact register encoding!");
654 uint32_t encodeCompactUnwindRegistersWithoutFrame(
unsigned RegCount)
const {
668 for (
unsigned i = 0; i < RegCount; ++i) {
669 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
670 if (CUReg == -1)
return ~0U;
671 SavedRegs[i] = CUReg;
675 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
677 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
678 for (
unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
679 unsigned Countless = 0;
680 for (
unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
681 if (SavedRegs[j] < SavedRegs[i])
684 RenumRegs[i] = SavedRegs[i] - Countless - 1;
688 uint32_t permutationEncoding = 0;
691 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
692 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
696 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
697 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
701 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
702 + 3 * RenumRegs[4] + RenumRegs[5];
705 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
709 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
712 permutationEncoding |= RenumRegs[5];
716 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
717 "Invalid compact register encoding!");
718 return permutationEncoding;
724 : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) {
725 memset(SavedRegs, 0,
sizeof(SavedRegs));
726 OffsetSize = Is64Bit ? 8 : 4;
727 MoveInstrSize = Is64Bit ? 3 : 2;
728 StackDivide = Is64Bit ? 8 : 4;
732 class DarwinX86_32AsmBackend :
public DarwinX86AsmBackend {
736 : DarwinX86AsmBackend(T, MRI, CPU,
false) {}
745 uint32_t generateCompactUnwindEncoding(
747 return generateCompactUnwindEncodingImpl(Instrs);
751 class DarwinX86_64AsmBackend :
public DarwinX86AsmBackend {
756 : DarwinX86AsmBackend(T, MRI, CPU,
true), Subtype(st) {}
764 uint32_t generateCompactUnwindEncoding(
766 return generateCompactUnwindEncodingImpl(Instrs);
777 return new DarwinX86_32AsmBackend(T, MRI, CPU);
780 return new WindowsX86AsmBackend(T,
false, CPU);
783 return new ELFX86_32AsmBackend(T, OSABI, CPU);
795 return new DarwinX86_64AsmBackend(T, MRI, CPU, CS);
799 return new WindowsX86AsmBackend(T,
true, CPU);
804 return new ELFX86_X32AsmBackend(T, OSABI, CPU);
805 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.
MCAsmBackend * createX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
MCAsmBackend * createX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
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.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
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.
static unsigned getRelaxedOpcode(unsigned Op)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Reg
All possible values of the reg field in the ModR/M byte.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
A four-byte section relative fixup.
A two-byte section relative fixup.
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.
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.
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.
static unsigned getRelaxedOpcodeArith(unsigned Op)
bool empty() const
empty - Check if the array is empty.
static unsigned getFixupKindLog2Size(unsigned Kind)
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
MCFixupKind getKind() const
Triple - Helper class for working with autoconf configuration names.
PowerPC TLS Dynamic Call Fixup
OpType getOperation() const
void setOpcode(unsigned Op)
A two-byte pc relative fixup.
A four-byte pc relative fixup.
static unsigned getRelaxedOpcodeBranch(unsigned Op)
R Default(const T &Value) const
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.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
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.
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.
const ARM::ArchExtKind Kind
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