X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCWin64EH.cpp;h=c5b637c92443cffb18e3060cf9afd66e8fd4455e;hb=318b7cc7f10d41370929ff93274de29c11f87b81;hp=b8b07d3a180875f6bfd101c0bf576fedb353ffc2;hpb=59c5c6c2b24b77371e53e6dbdf035edb50eafe1a;p=oota-llvm.git diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp index b8b07d3a180..c5b637c9244 100644 --- a/lib/MC/MCWin64EH.cpp +++ b/lib/MC/MCWin64EH.cpp @@ -64,7 +64,7 @@ static void EmitAbsDifference(MCStreamer &streamer, MCSymbol *lhs, static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, MCWin64EHInstruction &inst) { - uint8_t b2; + uint8_t b1, b2; uint16_t w; b2 = (inst.getOperation() & 0x0F); switch (inst.getOperation()) { @@ -93,7 +93,8 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_SetFPReg: - EmitAbsDifference(streamer, inst.getLabel(), begin); + b1 = inst.getOffset() & 0xF0; + streamer.EmitIntValue(b1, 1); streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_SaveNonVol: @@ -128,29 +129,14 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, } } -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, - MCSymbolRefExpr::VK_COFF_IMGREL32, - Context); - streamer.EmitValue(MCBinaryExpr::CreateAdd(BaseRefRel, Ofs, Context), 4); -} - static void EmitRuntimeFunction(MCStreamer &streamer, const MCWin64EHUnwindInfo *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, - MCSymbolRefExpr::VK_COFF_IMGREL32, - context), 4); + streamer.EmitValue(MCSymbolRefExpr::Create(info->Begin, context), 4); + streamer.EmitValue(MCSymbolRefExpr::Create(info->End, context), 4); + streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol, context), 4); } static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) { @@ -159,11 +145,11 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) { MCContext &context = streamer.getContext(); streamer.EmitValueToAlignment(4); + // Upper 3 bits are the version number (currently 1). + uint8_t flags = 0x01; info->Symbol = context.CreateTempSymbol(); streamer.EmitLabel(info->Symbol); - // Upper 3 bits are the version number (currently 1). - uint8_t flags = 0x01; if (info->ChainedParent) flags |= Win64EH::UNW_ChainInfo << 3; else { @@ -199,26 +185,20 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) { EmitUnwindCode(streamer, info->Begin, inst); } - // For alignment purposes, the instruction array will always have an even - // number of entries, with the final entry potentially unused (in which case - // the array will be one longer than indicated by the count of unwind codes - // field). - if (numCodes & 1) { - streamer.EmitIntValue(0, 2); - } - if (flags & (Win64EH::UNW_ChainInfo << 3)) EmitRuntimeFunction(streamer, info->ChainedParent); else if (flags & ((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3)) - streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, - MCSymbolRefExpr::VK_COFF_IMGREL32, - context), 4); - else if (numCodes == 0) { + streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, context), + 4); + else if (numCodes < 2) { // The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not // a chained unwind info, if there is no handler, and if there are fewer // than 2 slots used in the unwind code array, we have to pad to 8 bytes. - streamer.EmitIntValue(0, 4); + if (numCodes == 1) + streamer.EmitIntValue(0, 2); + else + streamer.EmitIntValue(0, 4); } }