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