X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCWin64EH.cpp;h=1b73b7afb6a00ef28248b7792fad2759dfba2e68;hb=HEAD;hp=198c775110e9fe76da85e7ceddb2fdd0fb2a9791;hpb=117ff62354f5a827723ca5a481ca22bea49485ba;p=oota-llvm.git diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp index 198c775110e..1b73b7afb6a 100644 --- a/lib/MC/MCWin64EH.cpp +++ b/lib/MC/MCWin64EH.cpp @@ -15,15 +15,16 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Win64EH.h" namespace llvm { // NOTE: All relocations generated here are 4-byte image-relative. -static uint8_t CountOfUnwindCodes(std::vector &Insns) { +static uint8_t CountOfUnwindCodes(std::vector &Insns) { uint8_t Count = 0; for (const auto &I : Insns) { - switch (I.getOperation()) { + switch (static_cast(I.Operation)) { case Win64EH::UOP_PushNonVol: case Win64EH::UOP_AllocSmall: case Win64EH::UOP_SetFPReg: @@ -39,7 +40,7 @@ static uint8_t CountOfUnwindCodes(std::vector &Insns) { Count += 3; break; case Win64EH::UOP_AllocLarge: - Count += (I.getSize() > 512 * 1024 - 8) ? 3 : 2; + Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2; break; } } @@ -50,72 +51,72 @@ static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, const MCSymbol *RHS) { MCContext &Context = Streamer.getContext(); const MCExpr *Diff = - MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LHS, Context), - MCSymbolRefExpr::Create(RHS, Context), Context); - Streamer.EmitAbsValue(Diff, 1); + MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context), + MCSymbolRefExpr::create(RHS, Context), Context); + Streamer.EmitValue(Diff, 1); } -static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, - MCWin64EHInstruction &inst) { +static void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, + WinEH::Instruction &inst) { uint8_t b2; uint16_t w; - b2 = (inst.getOperation() & 0x0F); - switch (inst.getOperation()) { + b2 = (inst.Operation & 0x0F); + switch (static_cast(inst.Operation)) { case Win64EH::UOP_PushNonVol: - EmitAbsDifference(streamer, inst.getLabel(), begin); - b2 |= (inst.getRegister() & 0x0F) << 4; + EmitAbsDifference(streamer, inst.Label, begin); + b2 |= (inst.Register & 0x0F) << 4; streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_AllocLarge: - EmitAbsDifference(streamer, inst.getLabel(), begin); - if (inst.getSize() > 512*1024-8) { + EmitAbsDifference(streamer, inst.Label, begin); + if (inst.Offset > 512 * 1024 - 8) { b2 |= 0x10; streamer.EmitIntValue(b2, 1); - w = inst.getSize() & 0xFFF8; + w = inst.Offset & 0xFFF8; streamer.EmitIntValue(w, 2); - w = inst.getSize() >> 16; + w = inst.Offset >> 16; } else { streamer.EmitIntValue(b2, 1); - w = inst.getSize() >> 3; + w = inst.Offset >> 3; } streamer.EmitIntValue(w, 2); break; case Win64EH::UOP_AllocSmall: - b2 |= (((inst.getSize()-8) >> 3) & 0x0F) << 4; - EmitAbsDifference(streamer, inst.getLabel(), begin); + b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4; + EmitAbsDifference(streamer, inst.Label, begin); streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_SetFPReg: - EmitAbsDifference(streamer, inst.getLabel(), begin); + EmitAbsDifference(streamer, inst.Label, begin); streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_SaveNonVol: case Win64EH::UOP_SaveXMM128: - b2 |= (inst.getRegister() & 0x0F) << 4; - EmitAbsDifference(streamer, inst.getLabel(), begin); + b2 |= (inst.Register & 0x0F) << 4; + EmitAbsDifference(streamer, inst.Label, begin); streamer.EmitIntValue(b2, 1); - w = inst.getOffset() >> 3; - if (inst.getOperation() == Win64EH::UOP_SaveXMM128) + w = inst.Offset >> 3; + if (inst.Operation == Win64EH::UOP_SaveXMM128) w >>= 1; streamer.EmitIntValue(w, 2); break; case Win64EH::UOP_SaveNonVolBig: case Win64EH::UOP_SaveXMM128Big: - b2 |= (inst.getRegister() & 0x0F) << 4; - EmitAbsDifference(streamer, inst.getLabel(), begin); + b2 |= (inst.Register & 0x0F) << 4; + EmitAbsDifference(streamer, inst.Label, begin); streamer.EmitIntValue(b2, 1); - if (inst.getOperation() == Win64EH::UOP_SaveXMM128Big) - w = inst.getOffset() & 0xFFF0; + if (inst.Operation == Win64EH::UOP_SaveXMM128Big) + w = inst.Offset & 0xFFF0; else - w = inst.getOffset() & 0xFFF8; + w = inst.Offset & 0xFFF8; streamer.EmitIntValue(w, 2); - w = inst.getOffset() >> 16; + w = inst.Offset >> 16; streamer.EmitIntValue(w, 2); break; case Win64EH::UOP_PushMachFrame: - if (inst.isPushCodeFrame()) + if (inst.Offset == 1) b2 |= 0x10; - EmitAbsDifference(streamer, inst.getLabel(), begin); + EmitAbsDifference(streamer, inst.Label, begin); streamer.EmitIntValue(b2, 1); break; } @@ -125,35 +126,38 @@ static void EmitSymbolRefWithOfs(MCStreamer &streamer, const MCSymbol *Base, const MCSymbol *Other) { MCContext &Context = streamer.getContext(); - const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::Create(Base, Context); - const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::Create(Other, Context); - const MCExpr *Ofs = MCBinaryExpr::CreateSub(OtherRef, BaseRef, Context); - const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::Create(Base, + const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::create(Base, Context); + const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::create(Other, Context); + const MCExpr *Ofs = MCBinaryExpr::createSub(OtherRef, BaseRef, Context); + const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::create(Base, MCSymbolRefExpr::VK_COFF_IMGREL32, Context); - streamer.EmitValue(MCBinaryExpr::CreateAdd(BaseRefRel, Ofs, Context), 4); + streamer.EmitValue(MCBinaryExpr::createAdd(BaseRefRel, Ofs, Context), 4); } static void EmitRuntimeFunction(MCStreamer &streamer, - const MCWinFrameInfo *info) { + const WinEH::FrameInfo *info) { MCContext &context = streamer.getContext(); streamer.EmitValueToAlignment(4); EmitSymbolRefWithOfs(streamer, info->Function, info->Begin); EmitSymbolRefWithOfs(streamer, info->Function, info->End); - streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol, + streamer.EmitValue(MCSymbolRefExpr::create(info->Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, context), 4); } -static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) { +static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { // If this UNWIND_INFO already has a symbol, it's already been emitted. - if (info->Symbol) return; + if (info->Symbol) + return; MCContext &context = streamer.getContext(); + MCSymbol *Label = context.createTempSymbol(); + streamer.EmitValueToAlignment(4); - info->Symbol = context.CreateTempSymbol(); - streamer.EmitLabel(info->Symbol); + streamer.EmitLabel(Label); + info->Symbol = Label; // Upper 3 bits are the version number (currently 1). uint8_t flags = 0x01; @@ -177,17 +181,16 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) { uint8_t frame = 0; if (info->LastFrameInst >= 0) { - MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst]; - assert(frameInst.getOperation() == Win64EH::UOP_SetFPReg); - frame = (frameInst.getRegister() & 0x0F) | - (frameInst.getOffset() & 0xF0); + WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst]; + assert(frameInst.Operation == Win64EH::UOP_SetFPReg); + frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0); } streamer.EmitIntValue(frame, 1); // Emit unwind instructions (in reverse order). uint8_t numInst = info->Instructions.size(); for (uint8_t c = 0; c < numInst; ++c) { - MCWin64EHInstruction inst = info->Instructions.back(); + WinEH::Instruction inst = info->Instructions.back(); info->Instructions.pop_back(); EmitUnwindCode(streamer, info->Begin, inst); } @@ -204,7 +207,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) { EmitRuntimeFunction(streamer, info->ChainedParent); else if (flags & ((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3)) - streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, + streamer.EmitValue(MCSymbolRefExpr::create(info->ExceptionHandler, MCSymbolRefExpr::VK_COFF_IMGREL32, context), 4); else if (numCodes == 0) { @@ -215,77 +218,35 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) { } } -StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) { - if (!func || !func->isInSection()) return ""; - const MCSection *section = &func->getSection(); - const MCSectionCOFF *COFFSection; - if ((COFFSection = dyn_cast(section))) { - StringRef name = COFFSection->getSectionName(); - size_t dollar = name.find('$'); - size_t dot = name.find('.', 1); - if (dollar == StringRef::npos && dot == StringRef::npos) - return ""; - if (dot == StringRef::npos) - return name.substr(dollar); - if (dollar == StringRef::npos || dot < dollar) - return name.substr(dot); - return name.substr(dollar); - } - return ""; -} - -static const MCSection *getWin64EHTableSection(StringRef suffix, - MCContext &context) { - if (suffix == "") - return context.getObjectFileInfo()->getXDataSection(); - - return context.getCOFFSection((".xdata"+suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); -} - -static const MCSection *getWin64EHFuncTableSection(StringRef suffix, - MCContext &context) { - if (suffix == "") - return context.getObjectFileInfo()->getPDataSection(); - return context.getCOFFSection((".pdata"+suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); -} - -void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer, - MCWinFrameInfo *info) { - // Switch sections (the static function above is meant to be called from - // here and from Emit(). - MCContext &context = streamer.getContext(); - const MCSection *xdataSect = - getWin64EHTableSection(GetSectionSuffix(info->Function), context); - streamer.SwitchSection(xdataSect); - - llvm::EmitUnwindInfo(streamer, info); -} - -void MCWin64EHUnwindEmitter::Emit(MCStreamer &Streamer) { +namespace Win64EH { +void UnwindEmitter::Emit(MCStreamer &Streamer) const { MCContext &Context = Streamer.getContext(); // Emit the unwind info structs first. for (const auto &CFI : Streamer.getWinFrameInfos()) { - const MCSection *XData = - getWin64EHTableSection(GetSectionSuffix(CFI->Function), Context); + MCSection *XData = getXDataSection(CFI->Function, Context); Streamer.SwitchSection(XData); EmitUnwindInfo(Streamer, CFI); } // Now emit RUNTIME_FUNCTION entries. for (const auto &CFI : Streamer.getWinFrameInfos()) { - const MCSection *PData = - getWin64EHFuncTableSection(GetSectionSuffix(CFI->Function), Context); + MCSection *PData = getPDataSection(CFI->Function, Context); Streamer.SwitchSection(PData); EmitRuntimeFunction(Streamer, CFI); } } +void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer, + WinEH::FrameInfo *info) const { + // Switch sections (the static function above is meant to be called from + // here and from Emit(). + MCContext &context = Streamer.getContext(); + MCSection *xdataSect = getXDataSection(info->Function, context); + Streamer.SwitchSection(xdataSect); + + llvm::EmitUnwindInfo(Streamer, info); +} +} } // End of namespace llvm