MCWin64EH.cpp revision 07cbe231738d64d830b77303d664b531130722f7
13185f5c35322cbd10040ab20f265042d477efe62Charles Davis//===- lib/MC/MCWin64EH.cpp - MCWin64EH implementation --------------------===// 23185f5c35322cbd10040ab20f265042d477efe62Charles Davis// 33185f5c35322cbd10040ab20f265042d477efe62Charles Davis// The LLVM Compiler Infrastructure 43185f5c35322cbd10040ab20f265042d477efe62Charles Davis// 53185f5c35322cbd10040ab20f265042d477efe62Charles Davis// This file is distributed under the University of Illinois Open Source 63185f5c35322cbd10040ab20f265042d477efe62Charles Davis// License. See LICENSE.TXT for details. 73185f5c35322cbd10040ab20f265042d477efe62Charles Davis// 83185f5c35322cbd10040ab20f265042d477efe62Charles Davis//===----------------------------------------------------------------------===// 93185f5c35322cbd10040ab20f265042d477efe62Charles Davis 103185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/MC/MCWin64EH.h" 113185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/MC/MCStreamer.h" 123185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/MC/MCContext.h" 133185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/MC/MCExpr.h" 143185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/Target/TargetAsmInfo.h" 153185f5c35322cbd10040ab20f265042d477efe62Charles Davis 163185f5c35322cbd10040ab20f265042d477efe62Charles Davisnamespace llvm { 173185f5c35322cbd10040ab20f265042d477efe62Charles Davis 183185f5c35322cbd10040ab20f265042d477efe62Charles Davis// NOTE: All relocations generated here are 4-byte image-relative. 193185f5c35322cbd10040ab20f265042d477efe62Charles Davis 203185f5c35322cbd10040ab20f265042d477efe62Charles Davisstatic uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &instArray){ 213185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t count = 0; 223185f5c35322cbd10040ab20f265042d477efe62Charles Davis for (std::vector<MCWin64EHInstruction>::const_iterator I = instArray.begin(), 233185f5c35322cbd10040ab20f265042d477efe62Charles Davis E = instArray.end(); I != E; ++I) { 243185f5c35322cbd10040ab20f265042d477efe62Charles Davis switch (I->getOperation()) { 253185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushNonVol: 263185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocSmall: 273185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SetFPReg: 283185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushMachFrame: 293185f5c35322cbd10040ab20f265042d477efe62Charles Davis count += 1; 30ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 313185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVol: 323185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128: 333185f5c35322cbd10040ab20f265042d477efe62Charles Davis count += 2; 34ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 353185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVolBig: 363185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128Big: 373185f5c35322cbd10040ab20f265042d477efe62Charles Davis count += 3; 38ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 393185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocLarge: 403185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (I->getSize() > 512*1024-8) 413185f5c35322cbd10040ab20f265042d477efe62Charles Davis count += 3; 423185f5c35322cbd10040ab20f265042d477efe62Charles Davis else 433185f5c35322cbd10040ab20f265042d477efe62Charles Davis count += 2; 44ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 453185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 463185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 473185f5c35322cbd10040ab20f265042d477efe62Charles Davis return count; 483185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 493185f5c35322cbd10040ab20f265042d477efe62Charles Davis 50c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davisstatic void EmitAbsDifference(MCStreamer &streamer, MCSymbol *lhs, 51c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis MCSymbol *rhs) { 52c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis MCContext &context = streamer.getContext(); 53c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis const MCExpr *diff = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create( 54c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis lhs, context), 55c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis MCSymbolRefExpr::Create( 56c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis rhs, context), 57c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis context); 58c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis streamer.EmitAbsValue(diff, 1); 59c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis 60c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis} 61c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis 62c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davisstatic void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, 63c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis MCWin64EHInstruction &inst) { 643185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t b1, b2; 653185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint16_t w; 6607cbe231738d64d830b77303d664b531130722f7Charles Davis b2 = (inst.getOperation() & 0x0F); 673185f5c35322cbd10040ab20f265042d477efe62Charles Davis switch (inst.getOperation()) { 683185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushNonVol: 69c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 7007cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= (inst.getRegister() & 0x0F) << 4; 713185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 723185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 733185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocLarge: 74c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 753185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (inst.getSize() > 512*1024-8) { 7607cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= 0x10; 773185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 783185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getSize() & 0xFFF8; 793185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 803185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getSize() >> 16; 813185f5c35322cbd10040ab20f265042d477efe62Charles Davis } else { 823185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 833185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getSize() >> 3; 843185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 853185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 863185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 873185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocSmall: 8807cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= (((inst.getSize()-8) >> 3) & 0x0F) << 4; 89c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 903185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 913185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 923185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SetFPReg: 933185f5c35322cbd10040ab20f265042d477efe62Charles Davis b1 = inst.getOffset() & 0xF0; 943185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b1, 1); 953185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 963185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 973185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVol: 983185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128: 9907cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= (inst.getRegister() & 0x0F) << 4; 100c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 1013185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 1023185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getOffset() >> 3; 1033185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (inst.getOperation() == Win64EH::UOP_SaveXMM128) 1043185f5c35322cbd10040ab20f265042d477efe62Charles Davis w >>= 1; 1053185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 1063185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1073185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVolBig: 1083185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128Big: 10907cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= (inst.getRegister() & 0x0F) << 4; 110c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 1113185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 1123185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (inst.getOperation() == Win64EH::UOP_SaveXMM128Big) 1133185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getOffset() & 0xFFF0; 1143185f5c35322cbd10040ab20f265042d477efe62Charles Davis else 1153185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getOffset() & 0xFFF8; 1163185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 1173185f5c35322cbd10040ab20f265042d477efe62Charles Davis w = inst.getOffset() >> 16; 1183185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 1193185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1203185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushMachFrame: 1213185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (inst.isPushCodeFrame()) 12207cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= 0x10; 123c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitAbsDifference(streamer, inst.getLabel(), begin); 1243185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 1253185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1263185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1273185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 1283185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1293185f5c35322cbd10040ab20f265042d477efe62Charles Davisstatic void EmitRuntimeFunction(MCStreamer &streamer, 13038ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis const MCWin64EHUnwindInfo *info) { 1313185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCContext &context = streamer.getContext(); 1323185f5c35322cbd10040ab20f265042d477efe62Charles Davis 133ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis streamer.EmitValueToAlignment(4); 1343185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitValue(MCSymbolRefExpr::Create(info->Begin, context), 4); 1353185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitValue(MCSymbolRefExpr::Create(info->End, context), 4); 1363185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol, context), 4); 1373185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 1383185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1393185f5c35322cbd10040ab20f265042d477efe62Charles Davisstatic void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) { 1403185f5c35322cbd10040ab20f265042d477efe62Charles Davis // If this UNWIND_INFO already has a symbol, it's already been emitted. 1413185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->Symbol) return; 1423185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1433185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCContext &context = streamer.getContext(); 144ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis streamer.EmitValueToAlignment(4); 1453185f5c35322cbd10040ab20f265042d477efe62Charles Davis // Upper 3 bits are the version number (currently 1). 14607cbe231738d64d830b77303d664b531130722f7Charles Davis uint8_t flags = 0x01; 1473185f5c35322cbd10040ab20f265042d477efe62Charles Davis info->Symbol = context.CreateTempSymbol(); 1483185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitLabel(info->Symbol); 1493185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1503185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->ChainedParent) 15107cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_ChainInfo << 3; 1523185f5c35322cbd10040ab20f265042d477efe62Charles Davis else { 1533185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->HandlesUnwind) 15407cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_TerminateHandler << 3; 1553185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->HandlesExceptions) 15607cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_ExceptionHandler << 3; 1573185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1583185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(flags, 1); 1593185f5c35322cbd10040ab20f265042d477efe62Charles Davis 16007cbe231738d64d830b77303d664b531130722f7Charles Davis if (info->PrologEnd) 16107cbe231738d64d830b77303d664b531130722f7Charles Davis EmitAbsDifference(streamer, info->PrologEnd, info->Begin); 16207cbe231738d64d830b77303d664b531130722f7Charles Davis else 16307cbe231738d64d830b77303d664b531130722f7Charles Davis streamer.EmitIntValue(0, 1); 1643185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1653185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t numCodes = CountOfUnwindCodes(info->Instructions); 1663185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(numCodes, 1); 1673185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1683185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t frame = 0; 1693185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->LastFrameInst >= 0) { 1703185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst]; 1713185f5c35322cbd10040ab20f265042d477efe62Charles Davis assert(frameInst.getOperation() == Win64EH::UOP_SetFPReg); 17207cbe231738d64d830b77303d664b531130722f7Charles Davis frame = (frameInst.getRegister() & 0x0F) | 17307cbe231738d64d830b77303d664b531130722f7Charles Davis (frameInst.getOffset() & 0xF0); 1743185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1753185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(frame, 1); 1763185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1773185f5c35322cbd10040ab20f265042d477efe62Charles Davis // Emit unwind instructions (in reverse order). 1783185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t numInst = info->Instructions.size(); 1793185f5c35322cbd10040ab20f265042d477efe62Charles Davis for (uint8_t c = 0; c < numInst; ++c) { 1803185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCWin64EHInstruction inst = info->Instructions.back(); 1813185f5c35322cbd10040ab20f265042d477efe62Charles Davis info->Instructions.pop_back(); 182c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitUnwindCode(streamer, info->Begin, inst); 1833185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1843185f5c35322cbd10040ab20f265042d477efe62Charles Davis 18507cbe231738d64d830b77303d664b531130722f7Charles Davis if (flags & (Win64EH::UNW_ChainInfo << 3)) 1863185f5c35322cbd10040ab20f265042d477efe62Charles Davis EmitRuntimeFunction(streamer, info->ChainedParent); 18707cbe231738d64d830b77303d664b531130722f7Charles Davis else if (flags & 18807cbe231738d64d830b77303d664b531130722f7Charles Davis ((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3)) 1893185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, context), 1903185f5c35322cbd10040ab20f265042d477efe62Charles Davis 4); 19107cbe231738d64d830b77303d664b531130722f7Charles Davis else if (numCodes < 2) { 19207cbe231738d64d830b77303d664b531130722f7Charles Davis // The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not 19307cbe231738d64d830b77303d664b531130722f7Charles Davis // a chained unwind info, if there is no handler, and if there are fewer 19407cbe231738d64d830b77303d664b531130722f7Charles Davis // than 2 slots used in the unwind code array, we have to pad to 8 bytes. 19507cbe231738d64d830b77303d664b531130722f7Charles Davis if (numCodes == 1) 19607cbe231738d64d830b77303d664b531130722f7Charles Davis streamer.EmitIntValue(0, 2); 19707cbe231738d64d830b77303d664b531130722f7Charles Davis else 19807cbe231738d64d830b77303d664b531130722f7Charles Davis streamer.EmitIntValue(0, 4); 19907cbe231738d64d830b77303d664b531130722f7Charles Davis } 2003185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 2013185f5c35322cbd10040ab20f265042d477efe62Charles Davis 2023185f5c35322cbd10040ab20f265042d477efe62Charles Davisvoid MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer, 2033185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCWin64EHUnwindInfo *info) { 2043185f5c35322cbd10040ab20f265042d477efe62Charles Davis // Switch sections (the static function above is meant to be called from 2053185f5c35322cbd10040ab20f265042d477efe62Charles Davis // here and from Emit(). 2063185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCContext &context = streamer.getContext(); 2073185f5c35322cbd10040ab20f265042d477efe62Charles Davis const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); 2083185f5c35322cbd10040ab20f265042d477efe62Charles Davis const MCSection *xdataSect = asmInfo.getWin64EHTableSection(); 2093185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.SwitchSection(xdataSect); 2103185f5c35322cbd10040ab20f265042d477efe62Charles Davis 2113185f5c35322cbd10040ab20f265042d477efe62Charles Davis llvm::EmitUnwindInfo(streamer, info); 2123185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 2133185f5c35322cbd10040ab20f265042d477efe62Charles Davis 21438ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davisvoid MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) { 21538ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis MCContext &context = streamer.getContext(); 21638ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis // Emit the unwind info structs first. 21738ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); 21838ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis const MCSection *xdataSect = asmInfo.getWin64EHTableSection(); 21938ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis streamer.SwitchSection(xdataSect); 22038ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) 22138ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis llvm::EmitUnwindInfo(streamer, &streamer.getW64UnwindInfo(i)); 22238ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis // Now emit RUNTIME_FUNCTION entries. 22338ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis const MCSection *pdataSect = asmInfo.getWin64EHFuncTableSection(); 22438ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis streamer.SwitchSection(pdataSect); 22538ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) 22638ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis EmitRuntimeFunction(streamer, &streamer.getW64UnwindInfo(i)); 22738ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis} 22838ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis 2293185f5c35322cbd10040ab20f265042d477efe62Charles Davis} // End of namespace llvm 2303185f5c35322cbd10040ab20f265042d477efe62Charles Davis 231