diff options
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp')
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 95012a148d83..83f3614ded1a 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -680,12 +680,21 @@ Optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const { #define ELF_RELOC(X, Y) .Case(#X, Y) #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" #undef ELF_RELOC + .Case("BFD_RELOC_NONE", ELF::R_X86_64_NONE) + .Case("BFD_RELOC_8", ELF::R_X86_64_8) + .Case("BFD_RELOC_16", ELF::R_X86_64_16) + .Case("BFD_RELOC_32", ELF::R_X86_64_32) + .Case("BFD_RELOC_64", ELF::R_X86_64_64) .Default(-1u); } else { Type = llvm::StringSwitch<unsigned>(Name) #define ELF_RELOC(X, Y) .Case(#X, Y) #include "llvm/BinaryFormat/ELFRelocs/i386.def" #undef ELF_RELOC + .Case("BFD_RELOC_NONE", ELF::R_386_NONE) + .Case("BFD_RELOC_8", ELF::R_386_8) + .Case("BFD_RELOC_16", ELF::R_386_16) + .Case("BFD_RELOC_32", ELF::R_386_32) .Default(-1u); } if (Type == -1u) @@ -1073,6 +1082,8 @@ void X86AsmBackend::finishLayout(MCAssembler const &Asm, } unsigned X86AsmBackend::getMaximumNopSize() const { + if (STI.hasFeature(X86::Mode16Bit)) + return 4; if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Mode64Bit)) return 1; if (STI.getFeatureBits()[X86::FeatureFast7ByteNOP]) @@ -1091,29 +1102,44 @@ unsigned X86AsmBackend::getMaximumNopSize() const { /// bytes. /// \return - true on success, false on failure bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { - static const char Nops[10][11] = { - // nop - "\x90", - // xchg %ax,%ax - "\x66\x90", - // nopl (%[re]ax) - "\x0f\x1f\x00", - // nopl 0(%[re]ax) - "\x0f\x1f\x40\x00", - // nopl 0(%[re]ax,%[re]ax,1) - "\x0f\x1f\x44\x00\x00", - // nopw 0(%[re]ax,%[re]ax,1) - "\x66\x0f\x1f\x44\x00\x00", - // nopl 0L(%[re]ax) - "\x0f\x1f\x80\x00\x00\x00\x00", - // nopl 0L(%[re]ax,%[re]ax,1) - "\x0f\x1f\x84\x00\x00\x00\x00\x00", - // nopw 0L(%[re]ax,%[re]ax,1) - "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00", - // nopw %cs:0L(%[re]ax,%[re]ax,1) - "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00", + static const char Nops32Bit[10][11] = { + // nop + "\x90", + // xchg %ax,%ax + "\x66\x90", + // nopl (%[re]ax) + "\x0f\x1f\x00", + // nopl 0(%[re]ax) + "\x0f\x1f\x40\x00", + // nopl 0(%[re]ax,%[re]ax,1) + "\x0f\x1f\x44\x00\x00", + // nopw 0(%[re]ax,%[re]ax,1) + "\x66\x0f\x1f\x44\x00\x00", + // nopl 0L(%[re]ax) + "\x0f\x1f\x80\x00\x00\x00\x00", + // nopl 0L(%[re]ax,%[re]ax,1) + "\x0f\x1f\x84\x00\x00\x00\x00\x00", + // nopw 0L(%[re]ax,%[re]ax,1) + "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00", + // nopw %cs:0L(%[re]ax,%[re]ax,1) + "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00", + }; + + // 16-bit mode uses different nop patterns than 32-bit. + static const char Nops16Bit[4][11] = { + // nop + "\x90", + // xchg %eax,%eax + "\x66\x90", + // lea 0(%si),%si + "\x8d\x74\x00", + // lea 0w(%si),%si + "\x8d\xb4\x00\x00", }; + const char(*Nops)[11] = + STI.getFeatureBits()[X86::Mode16Bit] ? Nops16Bit : Nops32Bit; + uint64_t MaxNopLength = (uint64_t)getMaximumNopSize(); // Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining @@ -1428,6 +1454,7 @@ public: unsigned StackAdjust = 0; unsigned StackSize = 0; unsigned NumDefCFAOffsets = 0; + int MinAbsOffset = std::numeric_limits<int>::max(); for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { const MCCFIInstruction &Inst = Instrs[i]; @@ -1456,6 +1483,7 @@ public: memset(SavedRegs, 0, sizeof(SavedRegs)); StackAdjust = 0; SavedRegIdx = 0; + MinAbsOffset = std::numeric_limits<int>::max(); InstrOffset += MoveInstrSize; break; } @@ -1499,6 +1527,7 @@ public: unsigned Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true); SavedRegs[SavedRegIdx++] = Reg; StackAdjust += OffsetSize; + MinAbsOffset = std::min(MinAbsOffset, abs(Inst.getOffset())); InstrOffset += PushInstrSize(Reg); break; } @@ -1512,6 +1541,11 @@ public: // Offset was too big for a compact unwind encoding. return CU::UNWIND_MODE_DWARF; + // We don't attempt to track a real StackAdjust, so if the saved registers + // aren't adjacent to rbp we can't cope. + if (SavedRegIdx != 0 && MinAbsOffset != 3 * (int)OffsetSize) + return CU::UNWIND_MODE_DWARF; + // Get the encoding of the saved registers when we have a frame pointer. uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(); if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; @@ -1597,7 +1631,7 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); - if (TheTriple.getEnvironment() == Triple::GNUX32) + if (TheTriple.isX32()) return new ELFX86_X32AsmBackend(T, OSABI, STI); return new ELFX86_64AsmBackend(T, OSABI, STI); } |