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" 11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h" 123185f5c35322cbd10040ab20f265042d477efe62Charles Davis#include "llvm/MC/MCContext.h" 13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 14e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCObjectFileInfo.h" 157b06b7357aa5a7cbdd769edbf6edb10fa055ea09Charles Davis#include "llvm/MC/MCSectionCOFF.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCStreamer.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSymbol.h" 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Win64EH.h" 193185f5c35322cbd10040ab20f265042d477efe62Charles Davis 20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm; 213185f5c35322cbd10040ab20f265042d477efe62Charles Davis 223185f5c35322cbd10040ab20f265042d477efe62Charles Davis// NOTE: All relocations generated here are 4-byte image-relative. 233185f5c35322cbd10040ab20f265042d477efe62Charles Davis 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic uint8_t CountOfUnwindCodes(std::vector<WinEH::Instruction> &Insns) { 25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint8_t Count = 0; 26c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &I : Insns) { 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) { 283185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushNonVol: 293185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocSmall: 303185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SetFPReg: 313185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushMachFrame: 32c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Count += 1; 33ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 343185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVol: 353185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128: 36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Count += 2; 37ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 383185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVolBig: 393185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128Big: 40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Count += 3; 41ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 423185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocLarge: 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2; 44ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis break; 453185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 463185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Count; 483185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 493185f5c35322cbd10040ab20f265042d477efe62Charles Davis 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const MCSymbol *RHS) { 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MCContext &Context = Streamer.getContext(); 5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const MCExpr *Diff = 546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context), 556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbolRefExpr::create(RHS, Context), Context); 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Streamer.EmitValue(Diff, 1); 57c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis} 58c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines WinEH::Instruction &inst) { 61f0a0d578089572be37063bbe37063edb28148159Kai Nacke uint8_t b2; 623185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint16_t w; 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines b2 = (inst.Operation & 0x0F); 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) { 653185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushNonVol: 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines b2 |= (inst.Register & 0x0F) << 4; 683185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 693185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 703185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocLarge: 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (inst.Offset > 512 * 1024 - 8) { 7307cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= 0x10; 743185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset & 0xFFF8; 763185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset >> 16; 783185f5c35322cbd10040ab20f265042d477efe62Charles Davis } else { 793185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset >> 3; 813185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 823185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 833185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 843185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_AllocSmall: 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4; 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 873185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 883185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 893185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SetFPReg: 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 913185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 923185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 933185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVol: 943185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128: 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines b2 |= (inst.Register & 0x0F) << 4; 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 973185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset >> 3; 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (inst.Operation == Win64EH::UOP_SaveXMM128) 1003185f5c35322cbd10040ab20f265042d477efe62Charles Davis w >>= 1; 1013185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 1023185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1033185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveNonVolBig: 1043185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_SaveXMM128Big: 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines b2 |= (inst.Register & 0x0F) << 4; 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 1073185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (inst.Operation == Win64EH::UOP_SaveXMM128Big) 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset & 0xFFF0; 1103185f5c35322cbd10040ab20f265042d477efe62Charles Davis else 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset & 0xFFF8; 1123185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines w = inst.Offset >> 16; 1143185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(w, 2); 1153185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1163185f5c35322cbd10040ab20f265042d477efe62Charles Davis case Win64EH::UOP_PushMachFrame: 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (inst.Offset == 1) 11807cbe231738d64d830b77303d664b531130722f7Charles Davis b2 |= 0x10; 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EmitAbsDifference(streamer, inst.Label, begin); 1203185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(b2, 1); 1213185f5c35322cbd10040ab20f265042d477efe62Charles Davis break; 1223185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1233185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 1243185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1257185bdd88302a67618b2edf51c499d647e5ff492Kai Nackestatic void EmitSymbolRefWithOfs(MCStreamer &streamer, 1267185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke const MCSymbol *Base, 1277185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke const MCSymbol *Other) { 1287185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke MCContext &Context = streamer.getContext(); 1296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::create(Base, Context); 1306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::create(Other, Context); 1316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCExpr *Ofs = MCBinaryExpr::createSub(OtherRef, BaseRef, Context); 1326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::create(Base, 1337185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke MCSymbolRefExpr::VK_COFF_IMGREL32, 1347185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke Context); 1356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar streamer.EmitValue(MCBinaryExpr::createAdd(BaseRefRel, Ofs, Context), 4); 1367185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke} 1377185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke 1383185f5c35322cbd10040ab20f265042d477efe62Charles Davisstatic void EmitRuntimeFunction(MCStreamer &streamer, 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const WinEH::FrameInfo *info) { 1403185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCContext &context = streamer.getContext(); 1413185f5c35322cbd10040ab20f265042d477efe62Charles Davis 142ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis streamer.EmitValueToAlignment(4); 1437185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke EmitSymbolRefWithOfs(streamer, info->Function, info->Begin); 1447185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke EmitSymbolRefWithOfs(streamer, info->Function, info->End); 1456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar streamer.EmitValue(MCSymbolRefExpr::create(info->Symbol, 1467185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke MCSymbolRefExpr::VK_COFF_IMGREL32, 1477185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke context), 4); 1483185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 1493185f5c35322cbd10040ab20f265042d477efe62Charles Davis 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { 1513185f5c35322cbd10040ab20f265042d477efe62Charles Davis // If this UNWIND_INFO already has a symbol, it's already been emitted. 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (info->Symbol) 15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 1543185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1553185f5c35322cbd10040ab20f265042d477efe62Charles Davis MCContext &context = streamer.getContext(); 1566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbol *Label = context.createTempSymbol(); 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 158ef60724ddc7726da8044d711c2a126197f4a0965Charles Davis streamer.EmitValueToAlignment(4); 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines streamer.EmitLabel(Label); 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines info->Symbol = Label; 1613185f5c35322cbd10040ab20f265042d477efe62Charles Davis 162c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke // Upper 3 bits are the version number (currently 1). 163c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke uint8_t flags = 0x01; 1643185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->ChainedParent) 16507cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_ChainInfo << 3; 1663185f5c35322cbd10040ab20f265042d477efe62Charles Davis else { 1673185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->HandlesUnwind) 16807cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_TerminateHandler << 3; 1693185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->HandlesExceptions) 17007cbe231738d64d830b77303d664b531130722f7Charles Davis flags |= Win64EH::UNW_ExceptionHandler << 3; 1713185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1723185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(flags, 1); 1733185f5c35322cbd10040ab20f265042d477efe62Charles Davis 17407cbe231738d64d830b77303d664b531130722f7Charles Davis if (info->PrologEnd) 17507cbe231738d64d830b77303d664b531130722f7Charles Davis EmitAbsDifference(streamer, info->PrologEnd, info->Begin); 17607cbe231738d64d830b77303d664b531130722f7Charles Davis else 17707cbe231738d64d830b77303d664b531130722f7Charles Davis streamer.EmitIntValue(0, 1); 1783185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1793185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t numCodes = CountOfUnwindCodes(info->Instructions); 1803185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(numCodes, 1); 1813185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1823185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t frame = 0; 1833185f5c35322cbd10040ab20f265042d477efe62Charles Davis if (info->LastFrameInst >= 0) { 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst]; 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(frameInst.Operation == Win64EH::UOP_SetFPReg); 18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0); 1873185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1883185f5c35322cbd10040ab20f265042d477efe62Charles Davis streamer.EmitIntValue(frame, 1); 1893185f5c35322cbd10040ab20f265042d477efe62Charles Davis 1903185f5c35322cbd10040ab20f265042d477efe62Charles Davis // Emit unwind instructions (in reverse order). 1913185f5c35322cbd10040ab20f265042d477efe62Charles Davis uint8_t numInst = info->Instructions.size(); 1923185f5c35322cbd10040ab20f265042d477efe62Charles Davis for (uint8_t c = 0; c < numInst; ++c) { 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines WinEH::Instruction inst = info->Instructions.back(); 1943185f5c35322cbd10040ab20f265042d477efe62Charles Davis info->Instructions.pop_back(); 195c4cbf9b6aa95cf861a5a80bfccf615ff5c53e4efCharles Davis EmitUnwindCode(streamer, info->Begin, inst); 1963185f5c35322cbd10040ab20f265042d477efe62Charles Davis } 1973185f5c35322cbd10040ab20f265042d477efe62Charles Davis 198c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke // For alignment purposes, the instruction array will always have an even 199c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke // number of entries, with the final entry potentially unused (in which case 200c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke // the array will be one longer than indicated by the count of unwind codes 201c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke // field). 202c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke if (numCodes & 1) { 203c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke streamer.EmitIntValue(0, 2); 204c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke } 205c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke 20607cbe231738d64d830b77303d664b531130722f7Charles Davis if (flags & (Win64EH::UNW_ChainInfo << 3)) 2073185f5c35322cbd10040ab20f265042d477efe62Charles Davis EmitRuntimeFunction(streamer, info->ChainedParent); 20807cbe231738d64d830b77303d664b531130722f7Charles Davis else if (flags & 20907cbe231738d64d830b77303d664b531130722f7Charles Davis ((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3)) 2106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar streamer.EmitValue(MCSymbolRefExpr::create(info->ExceptionHandler, 2117185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke MCSymbolRefExpr::VK_COFF_IMGREL32, 2127185bdd88302a67618b2edf51c499d647e5ff492Kai Nacke context), 4); 213c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke else if (numCodes == 0) { 21407cbe231738d64d830b77303d664b531130722f7Charles Davis // The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not 21507cbe231738d64d830b77303d664b531130722f7Charles Davis // a chained unwind info, if there is no handler, and if there are fewer 21607cbe231738d64d830b77303d664b531130722f7Charles Davis // than 2 slots used in the unwind code array, we have to pad to 8 bytes. 217c29a720b362790746ca899a0b44fa35a1b399a42Kai Nacke streamer.EmitIntValue(0, 4); 21807cbe231738d64d830b77303d664b531130722f7Charles Davis } 2193185f5c35322cbd10040ab20f265042d477efe62Charles Davis} 2203185f5c35322cbd10040ab20f265042d477efe62Charles Davis 221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const { 22238ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis // Emit the unwind info structs first. 223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) { 224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection); 225c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Streamer.SwitchSection(XData); 226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ::EmitUnwindInfo(Streamer, CFI); 2277b06b7357aa5a7cbdd769edbf6edb10fa055ea09Charles Davis } 228c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 22938ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis // Now emit RUNTIME_FUNCTION entries. 230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) { 231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection); 232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Streamer.SwitchSection(PData); 233c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EmitRuntimeFunction(Streamer, CFI); 2347b06b7357aa5a7cbdd769edbf6edb10fa055ea09Charles Davis } 23538ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis} 23638ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis 237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid llvm::Win64EH::UnwindEmitter::EmitUnwindInfo( 238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCStreamer &Streamer, WinEH::FrameInfo *info) const { 23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Switch sections (the static function above is meant to be called from 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // here and from Emit(). 241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection); 242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Streamer.SwitchSection(XData); 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ::EmitUnwindInfo(Streamer, info); 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 2463185f5c35322cbd10040ab20f265042d477efe62Charles Davis 247