1 //===-- ARMWinEHPrinter.cpp - Windows on ARM EH Data Printer ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // Windows on ARM uses a series of serialised data structures (RuntimeFunction)
10 // to create a table of information for unwinding.  In order to conserve space,
11 // there are two different ways that this data is represented.
12 //
13 // For functions with canonical forms for the prologue and epilogue, the data
14 // can be stored in a "packed" form.  In this case, the data is packed into the
15 // RuntimeFunction's remaining 30-bits and can fully describe the entire frame.
16 //
17 //        +---------------------------------------+
18 //        |         Function Entry Address        |
19 //        +---------------------------------------+
20 //        |           Packed Form Data            |
21 //        +---------------------------------------+
22 //
23 // This layout is parsed by Decoder::dumpPackedEntry.  No unwind bytecode is
24 // associated with such a frame as they can be derived from the provided data.
25 // The decoder does not synthesize this data as it is unnecessary for the
26 // purposes of validation, with the synthesis being required only by a proper
27 // unwinder.
28 //
29 // For functions that are large or do not match canonical forms, the data is
30 // split up into two portions, with the actual data residing in the "exception
31 // data" table (.xdata) with a reference to the entry from the "procedure data"
32 // (.pdata) entry.
33 //
34 // The exception data contains information about the frame setup, all of the
35 // epilogue scopes (for functions for which there are multiple exit points) and
36 // the associated exception handler.  Additionally, the entry contains byte-code
37 // describing how to unwind the function (c.f. Decoder::decodeOpcodes).
38 //
39 //        +---------------------------------------+
40 //        |         Function Entry Address        |
41 //        +---------------------------------------+
42 //        |      Exception Data Entry Address     |
43 //        +---------------------------------------+
44 //
45 // This layout is parsed by Decoder::dumpUnpackedEntry.  Such an entry must
46 // first resolve the exception data entry address.  This structure
47 // (ExceptionDataRecord) has a variable sized header
48 // (c.f. ARM::WinEH::HeaderWords) and encodes most of the same information as
49 // the packed form.  However, because this information is insufficient to
50 // synthesize the unwinding, there are associated unwinding bytecode which make
51 // up the bulk of the Decoder.
52 //
53 // The decoder itself is table-driven, using the first byte to determine the
54 // opcode and dispatching to the associated printing routine.  The bytecode
55 // itself is a variable length instruction encoding that can fully describe the
56 // state of the stack and the necessary operations for unwinding to the
57 // beginning of the frame.
58 //
59 // The byte-code maintains a 1-1 instruction mapping, indicating both the width
60 // of the instruction (Thumb2 instructions are variable length, 16 or 32 bits
61 // wide) allowing the program to unwind from any point in the prologue, body, or
62 // epilogue of the function.
63 
64 #include "ARMWinEHPrinter.h"
65 #include "llvm/ADT/STLExtras.h"
66 #include "llvm/ADT/StringExtras.h"
67 #include "llvm/Support/ARMWinEH.h"
68 #include "llvm/Support/Format.h"
69 
70 using namespace llvm;
71 using namespace llvm::object;
72 using namespace llvm::support;
73 
74 namespace llvm {
75 raw_ostream &operator<<(raw_ostream &OS, const ARM::WinEH::ReturnType &RT) {
76   switch (RT) {
77   case ARM::WinEH::ReturnType::RT_POP:
78     OS << "pop {pc}";
79     break;
80   case ARM::WinEH::ReturnType::RT_B:
81     OS << "b target";
82     break;
83   case ARM::WinEH::ReturnType::RT_BW:
84     OS << "b.w target";
85     break;
86   case ARM::WinEH::ReturnType::RT_NoEpilogue:
87     OS << "(no epilogue)";
88     break;
89   }
90   return OS;
91 }
92 }
93 
94 static std::string formatSymbol(StringRef Name, uint64_t Address,
95                                 uint64_t Offset = 0) {
96   std::string Buffer;
97   raw_string_ostream OS(Buffer);
98 
99   if (!Name.empty())
100     OS << Name << " ";
101 
102   if (Offset)
103     OS << format("+0x%" PRIX64 " (0x%" PRIX64 ")", Offset, Address);
104   else if (!Name.empty())
105     OS << format("(0x%" PRIX64 ")", Address);
106   else
107     OS << format("0x%" PRIX64, Address);
108 
109   return OS.str();
110 }
111 
112 namespace llvm {
113 namespace ARM {
114 namespace WinEH {
115 const size_t Decoder::PDataEntrySize = sizeof(RuntimeFunction);
116 
117 // TODO name the uops more appropriately
118 const Decoder::RingEntry Decoder::Ring[] = {
119   { 0x80, 0x00, 1, &Decoder::opcode_0xxxxxxx },  // UOP_STACK_FREE (16-bit)
120   { 0xc0, 0x80, 2, &Decoder::opcode_10Lxxxxx },  // UOP_POP (32-bit)
121   { 0xf0, 0xc0, 1, &Decoder::opcode_1100xxxx },  // UOP_STACK_SAVE (16-bit)
122   { 0xf8, 0xd0, 1, &Decoder::opcode_11010Lxx },  // UOP_POP (16-bit)
123   { 0xf8, 0xd8, 1, &Decoder::opcode_11011Lxx },  // UOP_POP (32-bit)
124   { 0xf8, 0xe0, 1, &Decoder::opcode_11100xxx },  // UOP_VPOP (32-bit)
125   { 0xfc, 0xe8, 2, &Decoder::opcode_111010xx },  // UOP_STACK_FREE (32-bit)
126   { 0xfe, 0xec, 2, &Decoder::opcode_1110110L },  // UOP_POP (16-bit)
127   { 0xff, 0xee, 2, &Decoder::opcode_11101110 },  // UOP_MICROSOFT_SPECIFIC (16-bit)
128                                               // UOP_PUSH_MACHINE_FRAME
129                                               // UOP_PUSH_CONTEXT
130                                               // UOP_PUSH_TRAP_FRAME
131                                               // UOP_REDZONE_RESTORE_LR
132   { 0xff, 0xef, 2, &Decoder::opcode_11101111 },  // UOP_LDRPC_POSTINC (32-bit)
133   { 0xff, 0xf5, 2, &Decoder::opcode_11110101 },  // UOP_VPOP (32-bit)
134   { 0xff, 0xf6, 2, &Decoder::opcode_11110110 },  // UOP_VPOP (32-bit)
135   { 0xff, 0xf7, 3, &Decoder::opcode_11110111 },  // UOP_STACK_RESTORE (16-bit)
136   { 0xff, 0xf8, 4, &Decoder::opcode_11111000 },  // UOP_STACK_RESTORE (16-bit)
137   { 0xff, 0xf9, 3, &Decoder::opcode_11111001 },  // UOP_STACK_RESTORE (32-bit)
138   { 0xff, 0xfa, 4, &Decoder::opcode_11111010 },  // UOP_STACK_RESTORE (32-bit)
139   { 0xff, 0xfb, 1, &Decoder::opcode_11111011 },  // UOP_NOP (16-bit)
140   { 0xff, 0xfc, 1, &Decoder::opcode_11111100 },  // UOP_NOP (32-bit)
141   { 0xff, 0xfd, 1, &Decoder::opcode_11111101 },  // UOP_NOP (16-bit) / END
142   { 0xff, 0xfe, 1, &Decoder::opcode_11111110 },  // UOP_NOP (32-bit) / END
143   { 0xff, 0xff, 1, &Decoder::opcode_11111111 },  // UOP_END
144 };
145 
146 
147 // Unwind opcodes for ARM64.
148 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
149 const Decoder::RingEntry Decoder::Ring64[] = {
150   { 0xe0, 0x00, 1, &Decoder::opcode_alloc_s },
151   { 0xe0, 0x20, 1, &Decoder::opcode_save_r19r20_x },
152   { 0xc0, 0x40, 1, &Decoder::opcode_save_fplr },
153   { 0xc0, 0x80, 1, &Decoder::opcode_save_fplr_x },
154   { 0xf8, 0xc0, 2, &Decoder::opcode_alloc_m },
155   { 0xfc, 0xc8, 2, &Decoder::opcode_save_regp },
156   { 0xfc, 0xcc, 2, &Decoder::opcode_save_regp_x },
157   { 0xfc, 0xd0, 2, &Decoder::opcode_save_reg },
158   { 0xfe, 0xd4, 2, &Decoder::opcode_save_reg_x },
159   { 0xfe, 0xd6, 2, &Decoder::opcode_save_lrpair },
160   { 0xfe, 0xd8, 2, &Decoder::opcode_save_fregp },
161   { 0xfe, 0xda, 2, &Decoder::opcode_save_fregp_x },
162   { 0xfe, 0xdc, 2, &Decoder::opcode_save_freg },
163   { 0xff, 0xde, 2, &Decoder::opcode_save_freg_x },
164   { 0xff, 0xe0, 4, &Decoder::opcode_alloc_l },
165   { 0xff, 0xe1, 1, &Decoder::opcode_setfp },
166   { 0xff, 0xe2, 2, &Decoder::opcode_addfp },
167   { 0xff, 0xe3, 1, &Decoder::opcode_nop },
168   { 0xff, 0xe4, 1, &Decoder::opcode_end },
169   { 0xff, 0xe5, 1, &Decoder::opcode_end_c },
170   { 0xff, 0xe6, 1, &Decoder::opcode_save_next },
171   { 0xff, 0xe8, 1, &Decoder::opcode_trap_frame },
172   { 0xff, 0xe9, 1, &Decoder::opcode_machine_frame },
173   { 0xff, 0xea, 1, &Decoder::opcode_context },
174   { 0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call },
175 };
176 
177 void Decoder::printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask) {
178   static const char * const GPRRegisterNames[16] = {
179     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
180     "r11", "ip", "sp", "lr", "pc",
181   };
182 
183   const uint16_t GPRMask = std::get<0>(RegisterMask);
184   const uint16_t VFPMask = std::get<1>(RegisterMask);
185 
186   OS << '{';
187   ListSeparator LS;
188   for (unsigned RI = 0, RE = 11; RI < RE; ++RI)
189     if (GPRMask & (1 << RI))
190       OS << LS << GPRRegisterNames[RI];
191   for (unsigned RI = 0, RE = 32; RI < RE; ++RI)
192     if (VFPMask & (1 << RI))
193       OS << LS << "d" << unsigned(RI);
194   for (unsigned RI = 11, RE = 16; RI < RE; ++RI)
195     if (GPRMask & (1 << RI))
196       OS << LS << GPRRegisterNames[RI];
197   OS << '}';
198 }
199 
200 ErrorOr<object::SectionRef>
201 Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) {
202   for (const auto &Section : COFF.sections()) {
203     uint64_t Address = Section.getAddress();
204     uint64_t Size = Section.getSize();
205 
206     if (VA >= Address && (VA - Address) <= Size)
207       return Section;
208   }
209   return inconvertibleErrorCode();
210 }
211 
212 ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF,
213                                               uint64_t VA, bool FunctionOnly) {
214   for (const auto &Symbol : COFF.symbols()) {
215     Expected<SymbolRef::Type> Type = Symbol.getType();
216     if (!Type)
217       return errorToErrorCode(Type.takeError());
218     if (FunctionOnly && *Type != SymbolRef::ST_Function)
219       continue;
220 
221     Expected<uint64_t> Address = Symbol.getAddress();
222     if (!Address)
223       return errorToErrorCode(Address.takeError());
224     if (*Address == VA)
225       return Symbol;
226   }
227   return inconvertibleErrorCode();
228 }
229 
230 ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
231                                                const SectionRef &Section,
232                                                uint64_t Offset) {
233   for (const auto &Relocation : Section.relocations()) {
234     uint64_t RelocationOffset = Relocation.getOffset();
235     if (RelocationOffset == Offset)
236       return *Relocation.getSymbol();
237   }
238   return inconvertibleErrorCode();
239 }
240 
241 SymbolRef Decoder::getPreferredSymbol(const COFFObjectFile &COFF, SymbolRef Sym,
242                                       uint64_t &SymbolOffset) {
243   // The symbol resolved by getRelocatedSymbol can be any internal
244   // nondescriptive symbol; try to resolve a more descriptive one.
245   COFFSymbolRef CoffSym = COFF.getCOFFSymbol(Sym);
246   if (CoffSym.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL &&
247       CoffSym.getSectionDefinition() == nullptr)
248     return Sym;
249   for (const auto &S : COFF.symbols()) {
250     COFFSymbolRef CS = COFF.getCOFFSymbol(S);
251     if (CS.getSectionNumber() == CoffSym.getSectionNumber() &&
252         CS.getValue() <= CoffSym.getValue() + SymbolOffset &&
253         CS.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL &&
254         CS.getSectionDefinition() == nullptr) {
255       uint32_t Offset = CoffSym.getValue() + SymbolOffset - CS.getValue();
256       if (Offset <= SymbolOffset) {
257         SymbolOffset = Offset;
258         Sym = S;
259         CoffSym = CS;
260         if (CS.isExternal() && SymbolOffset == 0)
261           return Sym;
262       }
263     }
264   }
265   return Sym;
266 }
267 
268 ErrorOr<SymbolRef> Decoder::getSymbolForLocation(
269     const COFFObjectFile &COFF, const SectionRef &Section,
270     uint64_t OffsetInSection, uint64_t ImmediateOffset, uint64_t &SymbolAddress,
271     uint64_t &SymbolOffset, bool FunctionOnly) {
272   // Try to locate a relocation that points at the offset in the section
273   ErrorOr<SymbolRef> SymOrErr =
274       getRelocatedSymbol(COFF, Section, OffsetInSection);
275   if (SymOrErr) {
276     // We found a relocation symbol; the immediate offset needs to be added
277     // to the symbol address.
278     SymbolOffset = ImmediateOffset;
279 
280     Expected<uint64_t> AddressOrErr = SymOrErr->getAddress();
281     if (!AddressOrErr) {
282       std::string Buf;
283       llvm::raw_string_ostream OS(Buf);
284       logAllUnhandledErrors(AddressOrErr.takeError(), OS);
285       OS.flush();
286       report_fatal_error(Buf);
287     }
288     // We apply SymbolOffset here directly. We return it separately to allow
289     // the caller to print it as an offset on the symbol name.
290     SymbolAddress = *AddressOrErr + SymbolOffset;
291 
292     if (FunctionOnly) // Resolve label/section symbols into function names.
293       SymOrErr = getPreferredSymbol(COFF, *SymOrErr, SymbolOffset);
294   } else {
295     // No matching relocation found; operating on a linked image. Try to
296     // find a descriptive symbol if possible. The immediate offset contains
297     // the image relative address, and we shouldn't add any offset to the
298     // symbol.
299     SymbolAddress = COFF.getImageBase() + ImmediateOffset;
300     SymbolOffset = 0;
301     SymOrErr = getSymbol(COFF, SymbolAddress, FunctionOnly);
302   }
303   return SymOrErr;
304 }
305 
306 bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
307                               unsigned Length, bool Prologue) {
308   uint8_t Imm = OC[Offset] & 0x7f;
309   SW.startLine() << format("0x%02x                ; %s sp, #(%u * 4)\n",
310                            OC[Offset],
311                            static_cast<const char *>(Prologue ? "sub" : "add"),
312                            Imm);
313   ++Offset;
314   return false;
315 }
316 
317 bool Decoder::opcode_10Lxxxxx(const uint8_t *OC, unsigned &Offset,
318                               unsigned Length, bool Prologue) {
319   unsigned Link = (OC[Offset] & 0x20) >> 5;
320   uint16_t RegisterMask = (Link << (Prologue ? 14 : 15))
321                         | ((OC[Offset + 0] & 0x1f) << 8)
322                         | ((OC[Offset + 1] & 0xff) << 0);
323   assert((~RegisterMask & (1 << 13)) && "sp must not be set");
324   assert((~RegisterMask & (1 << (Prologue ? 15 : 14))) && "pc must not be set");
325 
326   SW.startLine() << format("0x%02x 0x%02x           ; %s.w ",
327                            OC[Offset + 0], OC[Offset + 1],
328                            Prologue ? "push" : "pop");
329   printRegisters(std::make_pair(RegisterMask, 0));
330   OS << '\n';
331 
332   Offset += 2;
333   return false;
334 }
335 
336 bool Decoder::opcode_1100xxxx(const uint8_t *OC, unsigned &Offset,
337                               unsigned Length, bool Prologue) {
338   if (Prologue)
339     SW.startLine() << format("0x%02x                ; mov r%u, sp\n",
340                              OC[Offset], OC[Offset] & 0xf);
341   else
342     SW.startLine() << format("0x%02x                ; mov sp, r%u\n",
343                              OC[Offset], OC[Offset] & 0xf);
344   ++Offset;
345   return false;
346 }
347 
348 bool Decoder::opcode_11010Lxx(const uint8_t *OC, unsigned &Offset,
349                               unsigned Length, bool Prologue) {
350   unsigned Link = (OC[Offset] & 0x4) >> 3;
351   unsigned Count = (OC[Offset] & 0x3);
352 
353   uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
354                    | (((1 << (Count + 1)) - 1) << 4);
355 
356   SW.startLine() << format("0x%02x                ; %s ", OC[Offset],
357                            Prologue ? "push" : "pop");
358   printRegisters(std::make_pair(GPRMask, 0));
359   OS << '\n';
360 
361   ++Offset;
362   return false;
363 }
364 
365 bool Decoder::opcode_11011Lxx(const uint8_t *OC, unsigned &Offset,
366                               unsigned Length, bool Prologue) {
367   unsigned Link = (OC[Offset] & 0x4) >> 2;
368   unsigned Count = (OC[Offset] & 0x3) + 4;
369 
370   uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
371                    | (((1 << (Count + 1)) - 1) << 4);
372 
373   SW.startLine() << format("0x%02x                ; %s.w ", OC[Offset],
374                            Prologue ? "push" : "pop");
375   printRegisters(std::make_pair(GPRMask, 0));
376   OS << '\n';
377 
378   ++Offset;
379   return false;
380 }
381 
382 bool Decoder::opcode_11100xxx(const uint8_t *OC, unsigned &Offset,
383                               unsigned Length, bool Prologue) {
384   unsigned High = (OC[Offset] & 0x7);
385   uint32_t VFPMask = (((1 << (High + 1)) - 1) << 8);
386 
387   SW.startLine() << format("0x%02x                ; %s ", OC[Offset],
388                            Prologue ? "vpush" : "vpop");
389   printRegisters(std::make_pair(0, VFPMask));
390   OS << '\n';
391 
392   ++Offset;
393   return false;
394 }
395 
396 bool Decoder::opcode_111010xx(const uint8_t *OC, unsigned &Offset,
397                               unsigned Length, bool Prologue) {
398   uint16_t Imm = ((OC[Offset + 0] & 0x03) << 8) | ((OC[Offset + 1] & 0xff) << 0);
399 
400   SW.startLine() << format("0x%02x 0x%02x           ; %s.w sp, #(%u * 4)\n",
401                            OC[Offset + 0], OC[Offset + 1],
402                            static_cast<const char *>(Prologue ? "sub" : "add"),
403                            Imm);
404 
405   Offset += 2;
406   return false;
407 }
408 
409 bool Decoder::opcode_1110110L(const uint8_t *OC, unsigned &Offset,
410                               unsigned Length, bool Prologue) {
411   uint8_t GPRMask = ((OC[Offset + 0] & 0x01) << (Prologue ? 14 : 15))
412                   | ((OC[Offset + 1] & 0xff) << 0);
413 
414   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
415                            OC[Offset + 1], Prologue ? "push" : "pop");
416   printRegisters(std::make_pair(GPRMask, 0));
417   OS << '\n';
418 
419   Offset += 2;
420   return false;
421 }
422 
423 bool Decoder::opcode_11101110(const uint8_t *OC, unsigned &Offset,
424                               unsigned Length, bool Prologue) {
425   assert(!Prologue && "may not be used in prologue");
426 
427   if (OC[Offset + 1] & 0xf0)
428     SW.startLine() << format("0x%02x 0x%02x           ; reserved\n",
429                              OC[Offset + 0], OC[Offset +  1]);
430   else
431     SW.startLine()
432       << format("0x%02x 0x%02x           ; microsoft-specific (type: %u)\n",
433                 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] & 0x0f);
434 
435   Offset += 2;
436   return false;
437 }
438 
439 bool Decoder::opcode_11101111(const uint8_t *OC, unsigned &Offset,
440                               unsigned Length, bool Prologue) {
441   assert(!Prologue && "may not be used in prologue");
442 
443   if (OC[Offset + 1] & 0xf0)
444     SW.startLine() << format("0x%02x 0x%02x           ; reserved\n",
445                              OC[Offset + 0], OC[Offset +  1]);
446   else
447     SW.startLine()
448       << format("0x%02x 0x%02x           ; ldr.w lr, [sp], #%u\n",
449                 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] << 2);
450 
451   Offset += 2;
452   return false;
453 }
454 
455 bool Decoder::opcode_11110101(const uint8_t *OC, unsigned &Offset,
456                               unsigned Length, bool Prologue) {
457   unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
458   unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
459   uint32_t VFPMask = ((1 << (End - Start)) - 1) << Start;
460 
461   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
462                            OC[Offset + 1], Prologue ? "vpush" : "vpop");
463   printRegisters(std::make_pair(0, VFPMask));
464   OS << '\n';
465 
466   Offset += 2;
467   return false;
468 }
469 
470 bool Decoder::opcode_11110110(const uint8_t *OC, unsigned &Offset,
471                               unsigned Length, bool Prologue) {
472   unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
473   unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
474   uint32_t VFPMask = ((1 << (End - Start)) - 1) << 16;
475 
476   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
477                            OC[Offset + 1], Prologue ? "vpush" : "vpop");
478   printRegisters(std::make_pair(0, VFPMask));
479   OS << '\n';
480 
481   Offset += 2;
482   return false;
483 }
484 
485 bool Decoder::opcode_11110111(const uint8_t *OC, unsigned &Offset,
486                               unsigned Length, bool Prologue) {
487   uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
488 
489   SW.startLine() << format("0x%02x 0x%02x 0x%02x      ; %s sp, sp, #(%u * 4)\n",
490                            OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
491                            static_cast<const char *>(Prologue ? "sub" : "add"),
492                            Imm);
493 
494   Offset += 3;
495   return false;
496 }
497 
498 bool Decoder::opcode_11111000(const uint8_t *OC, unsigned &Offset,
499                               unsigned Length, bool Prologue) {
500   uint32_t Imm = (OC[Offset + 1] << 16)
501                | (OC[Offset + 2] << 8)
502                | (OC[Offset + 3] << 0);
503 
504   SW.startLine()
505     << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s sp, sp, #(%u * 4)\n",
506               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
507               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
508 
509   Offset += 4;
510   return false;
511 }
512 
513 bool Decoder::opcode_11111001(const uint8_t *OC, unsigned &Offset,
514                               unsigned Length, bool Prologue) {
515   uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
516 
517   SW.startLine()
518     << format("0x%02x 0x%02x 0x%02x      ; %s.w sp, sp, #(%u * 4)\n",
519               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
520               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
521 
522   Offset += 3;
523   return false;
524 }
525 
526 bool Decoder::opcode_11111010(const uint8_t *OC, unsigned &Offset,
527                               unsigned Length, bool Prologue) {
528   uint32_t Imm = (OC[Offset + 1] << 16)
529                | (OC[Offset + 2] << 8)
530                | (OC[Offset + 3] << 0);
531 
532   SW.startLine()
533     << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s.w sp, sp, #(%u * 4)\n",
534               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
535               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
536 
537   Offset += 4;
538   return false;
539 }
540 
541 bool Decoder::opcode_11111011(const uint8_t *OC, unsigned &Offset,
542                               unsigned Length, bool Prologue) {
543   SW.startLine() << format("0x%02x                ; nop\n", OC[Offset]);
544   ++Offset;
545   return false;
546 }
547 
548 bool Decoder::opcode_11111100(const uint8_t *OC, unsigned &Offset,
549                               unsigned Length, bool Prologue) {
550   SW.startLine() << format("0x%02x                ; nop.w\n", OC[Offset]);
551   ++Offset;
552   return false;
553 }
554 
555 bool Decoder::opcode_11111101(const uint8_t *OC, unsigned &Offset,
556                               unsigned Length, bool Prologue) {
557   SW.startLine() << format("0x%02x                ; b\n", OC[Offset]);
558   ++Offset;
559   return true;
560 }
561 
562 bool Decoder::opcode_11111110(const uint8_t *OC, unsigned &Offset,
563                               unsigned Length, bool Prologue) {
564   SW.startLine() << format("0x%02x                ; b.w\n", OC[Offset]);
565   ++Offset;
566   return true;
567 }
568 
569 bool Decoder::opcode_11111111(const uint8_t *OC, unsigned &Offset,
570                               unsigned Length, bool Prologue) {
571   ++Offset;
572   return true;
573 }
574 
575 // ARM64 unwind codes start here.
576 bool Decoder::opcode_alloc_s(const uint8_t *OC, unsigned &Offset,
577                              unsigned Length, bool Prologue) {
578   uint32_t NumBytes = (OC[Offset] & 0x1F) << 4;
579   SW.startLine() << format("0x%02x                ; %s sp, #%u\n", OC[Offset],
580                            static_cast<const char *>(Prologue ? "sub" : "add"),
581                            NumBytes);
582   ++Offset;
583   return false;
584 }
585 
586 bool Decoder::opcode_save_r19r20_x(const uint8_t *OC, unsigned &Offset,
587                                    unsigned Length, bool Prologue) {
588   uint32_t Off = (OC[Offset] & 0x1F) << 3;
589   if (Prologue)
590     SW.startLine() << format(
591         "0x%02x                ; stp x19, x20, [sp, #-%u]!\n", OC[Offset], Off);
592   else
593     SW.startLine() << format(
594         "0x%02x                ; ldp x19, x20, [sp], #%u\n", OC[Offset], Off);
595   ++Offset;
596   return false;
597 }
598 
599 bool Decoder::opcode_save_fplr(const uint8_t *OC, unsigned &Offset,
600                                unsigned Length, bool Prologue) {
601   uint32_t Off = (OC[Offset] & 0x3F) << 3;
602   SW.startLine() << format(
603       "0x%02x                ; %s x29, x30, [sp, #%u]\n", OC[Offset],
604       static_cast<const char *>(Prologue ? "stp" : "ldp"), Off);
605   ++Offset;
606   return false;
607 }
608 
609 bool Decoder::opcode_save_fplr_x(const uint8_t *OC, unsigned &Offset,
610                                  unsigned Length, bool Prologue) {
611   uint32_t Off = ((OC[Offset] & 0x3F) + 1) << 3;
612   if (Prologue)
613     SW.startLine() << format(
614         "0x%02x                ; stp x29, x30, [sp, #-%u]!\n", OC[Offset], Off);
615   else
616     SW.startLine() << format(
617         "0x%02x                ; ldp x29, x30, [sp], #%u\n", OC[Offset], Off);
618   ++Offset;
619   return false;
620 }
621 
622 bool Decoder::opcode_alloc_m(const uint8_t *OC, unsigned &Offset,
623                              unsigned Length, bool Prologue) {
624   uint32_t NumBytes = ((OC[Offset] & 0x07) << 8);
625   NumBytes |= (OC[Offset + 1] & 0xFF);
626   NumBytes <<= 4;
627   SW.startLine() << format("0x%02x%02x              ; %s sp, #%u\n",
628                            OC[Offset], OC[Offset + 1],
629                            static_cast<const char *>(Prologue ? "sub" : "add"),
630                            NumBytes);
631   Offset += 2;
632   return false;
633 }
634 
635 bool Decoder::opcode_save_regp(const uint8_t *OC, unsigned &Offset,
636                                unsigned Length, bool Prologue) {
637   uint32_t Reg = ((OC[Offset] & 0x03) << 8);
638   Reg |= (OC[Offset + 1] & 0xC0);
639   Reg >>= 6;
640   Reg += 19;
641   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
642   SW.startLine() << format(
643       "0x%02x%02x              ; %s x%u, x%u, [sp, #%u]\n",
644       OC[Offset], OC[Offset + 1],
645       static_cast<const char *>(Prologue ? "stp" : "ldp"), Reg, Reg + 1, Off);
646   Offset += 2;
647   return false;
648 }
649 
650 bool Decoder::opcode_save_regp_x(const uint8_t *OC, unsigned &Offset,
651                                  unsigned Length, bool Prologue) {
652   uint32_t Reg = ((OC[Offset] & 0x03) << 8);
653   Reg |= (OC[Offset + 1] & 0xC0);
654   Reg >>= 6;
655   Reg += 19;
656   uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
657   if (Prologue)
658     SW.startLine() << format(
659         "0x%02x%02x              ; stp x%u, x%u, [sp, #-%u]!\n",
660         OC[Offset], OC[Offset + 1], Reg,
661         Reg + 1, Off);
662   else
663     SW.startLine() << format(
664         "0x%02x%02x              ; ldp x%u, x%u, [sp], #%u\n",
665         OC[Offset], OC[Offset + 1], Reg,
666         Reg + 1, Off);
667   Offset += 2;
668   return false;
669 }
670 
671 bool Decoder::opcode_save_reg(const uint8_t *OC, unsigned &Offset,
672                               unsigned Length, bool Prologue) {
673   uint32_t Reg = (OC[Offset] & 0x03) << 8;
674   Reg |= (OC[Offset + 1] & 0xC0);
675   Reg >>= 6;
676   Reg += 19;
677   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
678   SW.startLine() << format("0x%02x%02x              ; %s x%u, [sp, #%u]\n",
679                            OC[Offset], OC[Offset + 1],
680                            static_cast<const char *>(Prologue ? "str" : "ldr"),
681                            Reg, Off);
682   Offset += 2;
683   return false;
684 }
685 
686 bool Decoder::opcode_save_reg_x(const uint8_t *OC, unsigned &Offset,
687                                 unsigned Length, bool Prologue) {
688   uint32_t Reg = (OC[Offset] & 0x01) << 8;
689   Reg |= (OC[Offset + 1] & 0xE0);
690   Reg >>= 5;
691   Reg += 19;
692   uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
693   if (Prologue)
694     SW.startLine() << format("0x%02x%02x              ; str x%u, [sp, #-%u]!\n",
695                              OC[Offset], OC[Offset + 1], Reg, Off);
696   else
697     SW.startLine() << format("0x%02x%02x              ; ldr x%u, [sp], #%u\n",
698                              OC[Offset], OC[Offset + 1], Reg, Off);
699   Offset += 2;
700   return false;
701 }
702 
703 bool Decoder::opcode_save_lrpair(const uint8_t *OC, unsigned &Offset,
704                                  unsigned Length, bool Prologue) {
705   uint32_t Reg = (OC[Offset] & 0x01) << 8;
706   Reg |= (OC[Offset + 1] & 0xC0);
707   Reg >>= 6;
708   Reg *= 2;
709   Reg += 19;
710   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
711   SW.startLine() << format("0x%02x%02x              ; %s x%u, lr, [sp, #%u]\n",
712                            OC[Offset], OC[Offset + 1],
713                            static_cast<const char *>(Prologue ? "stp" : "ldp"),
714                            Reg, Off);
715   Offset += 2;
716   return false;
717 }
718 
719 bool Decoder::opcode_save_fregp(const uint8_t *OC, unsigned &Offset,
720                                 unsigned Length, bool Prologue) {
721   uint32_t Reg = (OC[Offset] & 0x01) << 8;
722   Reg |= (OC[Offset + 1] & 0xC0);
723   Reg >>= 6;
724   Reg += 8;
725   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
726   SW.startLine() << format("0x%02x%02x              ; %s d%u, d%u, [sp, #%u]\n",
727                            OC[Offset], OC[Offset + 1],
728                            static_cast<const char *>(Prologue ? "stp" : "ldp"),
729                            Reg, Reg + 1, Off);
730   Offset += 2;
731   return false;
732 }
733 
734 bool Decoder::opcode_save_fregp_x(const uint8_t *OC, unsigned &Offset,
735                                   unsigned Length, bool Prologue) {
736   uint32_t Reg = (OC[Offset] & 0x01) << 8;
737   Reg |= (OC[Offset + 1] & 0xC0);
738   Reg >>= 6;
739   Reg += 8;
740   uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
741   if (Prologue)
742     SW.startLine() << format(
743         "0x%02x%02x              ; stp d%u, d%u, [sp, #-%u]!\n", OC[Offset],
744         OC[Offset + 1], Reg, Reg + 1, Off);
745   else
746     SW.startLine() << format(
747         "0x%02x%02x              ; ldp d%u, d%u, [sp], #%u\n", OC[Offset],
748         OC[Offset + 1], Reg, Reg + 1, Off);
749   Offset += 2;
750   return false;
751 }
752 
753 bool Decoder::opcode_save_freg(const uint8_t *OC, unsigned &Offset,
754                                unsigned Length, bool Prologue) {
755   uint32_t Reg = (OC[Offset] & 0x01) << 8;
756   Reg |= (OC[Offset + 1] & 0xC0);
757   Reg >>= 6;
758   Reg += 8;
759   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
760   SW.startLine() << format("0x%02x%02x              ; %s d%u, [sp, #%u]\n",
761                            OC[Offset], OC[Offset + 1],
762                            static_cast<const char *>(Prologue ? "str" : "ldr"),
763                            Reg, Off);
764   Offset += 2;
765   return false;
766 }
767 
768 bool Decoder::opcode_save_freg_x(const uint8_t *OC, unsigned &Offset,
769                                  unsigned Length, bool Prologue) {
770   uint32_t Reg = ((OC[Offset + 1] & 0xE0) >> 5) + 8;
771   uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
772   if (Prologue)
773     SW.startLine() << format(
774         "0x%02x%02x              ; str d%u, [sp, #-%u]!\n", OC[Offset],
775         OC[Offset + 1], Reg, Off);
776   else
777     SW.startLine() << format(
778         "0x%02x%02x              ; ldr d%u, [sp], #%u\n", OC[Offset],
779         OC[Offset + 1], Reg, Off);
780   Offset += 2;
781   return false;
782 }
783 
784 bool Decoder::opcode_alloc_l(const uint8_t *OC, unsigned &Offset,
785                              unsigned Length, bool Prologue) {
786   unsigned Off =
787       (OC[Offset + 1] << 16) | (OC[Offset + 2] << 8) | (OC[Offset + 3] << 0);
788   Off <<= 4;
789   SW.startLine() << format(
790       "0x%02x%02x%02x%02x          ; %s sp, #%u\n", OC[Offset], OC[Offset + 1],
791       OC[Offset + 2], OC[Offset + 3],
792       static_cast<const char *>(Prologue ? "sub" : "add"), Off);
793   Offset += 4;
794   return false;
795 }
796 
797 bool Decoder::opcode_setfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
798                            bool Prologue) {
799   SW.startLine() << format("0x%02x                ; mov %s, %s\n", OC[Offset],
800                            static_cast<const char *>(Prologue ? "fp" : "sp"),
801                            static_cast<const char *>(Prologue ? "sp" : "fp"));
802   ++Offset;
803   return false;
804 }
805 
806 bool Decoder::opcode_addfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
807                            bool Prologue) {
808   unsigned NumBytes = OC[Offset + 1] << 3;
809   SW.startLine() << format(
810       "0x%02x%02x              ; %s %s, %s, #%u\n", OC[Offset], OC[Offset + 1],
811       static_cast<const char *>(Prologue ? "add" : "sub"),
812       static_cast<const char *>(Prologue ? "fp" : "sp"),
813       static_cast<const char *>(Prologue ? "sp" : "fp"), NumBytes);
814   Offset += 2;
815   return false;
816 }
817 
818 bool Decoder::opcode_nop(const uint8_t *OC, unsigned &Offset, unsigned Length,
819                          bool Prologue) {
820   SW.startLine() << format("0x%02x                ; nop\n", OC[Offset]);
821   ++Offset;
822   return false;
823 }
824 
825 bool Decoder::opcode_end(const uint8_t *OC, unsigned &Offset, unsigned Length,
826                          bool Prologue) {
827   SW.startLine() << format("0x%02x                ; end\n", OC[Offset]);
828   ++Offset;
829   return true;
830 }
831 
832 bool Decoder::opcode_end_c(const uint8_t *OC, unsigned &Offset, unsigned Length,
833                            bool Prologue) {
834   SW.startLine() << format("0x%02x                ; end_c\n", OC[Offset]);
835   ++Offset;
836   return true;
837 }
838 
839 bool Decoder::opcode_save_next(const uint8_t *OC, unsigned &Offset,
840                                unsigned Length, bool Prologue) {
841   if (Prologue)
842     SW.startLine() << format("0x%02x                ; save next\n", OC[Offset]);
843   else
844     SW.startLine() << format("0x%02x                ; restore next\n",
845                              OC[Offset]);
846   ++Offset;
847   return false;
848 }
849 
850 bool Decoder::opcode_trap_frame(const uint8_t *OC, unsigned &Offset,
851                                 unsigned Length, bool Prologue) {
852   SW.startLine() << format("0x%02x                ; trap frame\n", OC[Offset]);
853   ++Offset;
854   return false;
855 }
856 
857 bool Decoder::opcode_machine_frame(const uint8_t *OC, unsigned &Offset,
858                                    unsigned Length, bool Prologue) {
859   SW.startLine() << format("0x%02x                ; machine frame\n",
860                            OC[Offset]);
861   ++Offset;
862   return false;
863 }
864 
865 bool Decoder::opcode_context(const uint8_t *OC, unsigned &Offset,
866                              unsigned Length, bool Prologue) {
867   SW.startLine() << format("0x%02x                ; context\n", OC[Offset]);
868   ++Offset;
869   return false;
870 }
871 
872 bool Decoder::opcode_clear_unwound_to_call(const uint8_t *OC, unsigned &Offset,
873                                            unsigned Length, bool Prologue) {
874   SW.startLine() << format("0x%02x                ; clear unwound to call\n",
875                            OC[Offset]);
876   ++Offset;
877   return false;
878 }
879 
880 void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
881                             bool Prologue) {
882   assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
883   const RingEntry* DecodeRing = isAArch64 ? Ring64 : Ring;
884   bool Terminated = false;
885   for (unsigned OI = Offset, OE = Opcodes.size(); !Terminated && OI < OE; ) {
886     for (unsigned DI = 0;; ++DI) {
887       if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
888           (!isAArch64 && (DI >= array_lengthof(Ring)))) {
889         SW.startLine() << format("0x%02x                ; Bad opcode!\n",
890                                  Opcodes.data()[OI]);
891         ++OI;
892         break;
893       }
894 
895       if ((Opcodes[OI] & DecodeRing[DI].Mask) == DecodeRing[DI].Value) {
896         if (OI + DecodeRing[DI].Length > OE) {
897           SW.startLine() << format("Opcode 0x%02x goes past the unwind data\n",
898                                     Opcodes[OI]);
899           OI += DecodeRing[DI].Length;
900           break;
901         }
902         Terminated =
903             (this->*DecodeRing[DI].Routine)(Opcodes.data(), OI, 0, Prologue);
904         break;
905       }
906     }
907   }
908 }
909 
910 bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
911                               const SectionRef &Section,
912                               uint64_t FunctionAddress, uint64_t VA) {
913   ArrayRef<uint8_t> Contents;
914   if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
915     return false;
916 
917   uint64_t SectionVA = Section.getAddress();
918   uint64_t Offset = VA - SectionVA;
919   const ulittle32_t *Data =
920     reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
921 
922   // Sanity check to ensure that the .xdata header is present.
923   // A header is one or two words, followed by at least one word to describe
924   // the unwind codes. Applicable to both ARM and AArch64.
925   if (Contents.size() - Offset < 8)
926     report_fatal_error(".xdata must be at least 8 bytes in size");
927 
928   const ExceptionDataRecord XData(Data, isAArch64);
929   DictScope XRS(SW, "ExceptionData");
930   SW.printNumber("FunctionLength",
931                  isAArch64 ? XData.FunctionLengthInBytesAArch64() :
932                  XData.FunctionLengthInBytesARM());
933   SW.printNumber("Version", XData.Vers());
934   SW.printBoolean("ExceptionData", XData.X());
935   SW.printBoolean("EpiloguePacked", XData.E());
936   if (!isAArch64)
937     SW.printBoolean("Fragment", XData.F());
938   SW.printNumber(XData.E() ? "EpilogueOffset" : "EpilogueScopes",
939                  XData.EpilogueCount());
940   uint64_t ByteCodeLength = XData.CodeWords() * sizeof(uint32_t);
941   SW.printNumber("ByteCodeLength", ByteCodeLength);
942 
943   if ((int64_t)(Contents.size() - Offset - 4 * HeaderWords(XData) -
944                 (XData.E() ? 0 : XData.EpilogueCount() * 4) -
945                 (XData.X() ? 8 : 0)) < (int64_t)ByteCodeLength) {
946     SW.flush();
947     report_fatal_error("Malformed unwind data");
948   }
949 
950   if (XData.E()) {
951     ArrayRef<uint8_t> UC = XData.UnwindByteCode();
952     if (isAArch64 || !XData.F()) {
953       ListScope PS(SW, "Prologue");
954       decodeOpcodes(UC, 0, /*Prologue=*/true);
955     }
956     if (XData.EpilogueCount()) {
957       ListScope ES(SW, "Epilogue");
958       decodeOpcodes(UC, XData.EpilogueCount(), /*Prologue=*/false);
959     }
960   } else {
961     {
962       ListScope PS(SW, "Prologue");
963       decodeOpcodes(XData.UnwindByteCode(), 0, /*Prologue=*/true);
964     }
965     ArrayRef<ulittle32_t> EpilogueScopes = XData.EpilogueScopes();
966     ListScope ESS(SW, "EpilogueScopes");
967     for (const EpilogueScope ES : EpilogueScopes) {
968       DictScope ESES(SW, "EpilogueScope");
969       SW.printNumber("StartOffset", ES.EpilogueStartOffset());
970       if (!isAArch64)
971         SW.printNumber("Condition", ES.Condition());
972       SW.printNumber("EpilogueStartIndex",
973                      isAArch64 ? ES.EpilogueStartIndexAArch64()
974                                : ES.EpilogueStartIndexARM());
975       if (ES.ES & ~0xffc3ffff)
976         SW.printNumber("ReservedBits", (ES.ES >> 18) & 0xF);
977 
978       ListScope Opcodes(SW, "Opcodes");
979       decodeOpcodes(XData.UnwindByteCode(),
980                     isAArch64 ? ES.EpilogueStartIndexAArch64()
981                               : ES.EpilogueStartIndexARM(),
982                     /*Prologue=*/false);
983     }
984   }
985 
986   if (XData.X()) {
987     const uint32_t Parameter = XData.ExceptionHandlerParameter();
988     const size_t HandlerOffset = HeaderWords(XData) +
989                                  (XData.E() ? 0 : XData.EpilogueCount()) +
990                                  XData.CodeWords();
991 
992     uint64_t Address, SymbolOffset;
993     ErrorOr<SymbolRef> Symbol = getSymbolForLocation(
994         COFF, Section, Offset + HandlerOffset * sizeof(uint32_t),
995         XData.ExceptionHandlerRVA(), Address, SymbolOffset,
996         /*FunctionOnly=*/true);
997     if (!Symbol) {
998       ListScope EHS(SW, "ExceptionHandler");
999       SW.printHex("Routine", Address);
1000       SW.printHex("Parameter", Parameter);
1001       return true;
1002     }
1003 
1004     Expected<StringRef> Name = Symbol->getName();
1005     if (!Name) {
1006       std::string Buf;
1007       llvm::raw_string_ostream OS(Buf);
1008       logAllUnhandledErrors(Name.takeError(), OS);
1009       OS.flush();
1010       report_fatal_error(Buf);
1011     }
1012 
1013     ListScope EHS(SW, "ExceptionHandler");
1014     SW.printString("Routine", formatSymbol(*Name, Address, SymbolOffset));
1015     SW.printHex("Parameter", Parameter);
1016   }
1017 
1018   return true;
1019 }
1020 
1021 bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
1022                                 const SectionRef Section, uint64_t Offset,
1023                                 unsigned Index, const RuntimeFunction &RF) {
1024   assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
1025          "packed entry cannot be treated as an unpacked entry");
1026 
1027   uint64_t FunctionAddress, FunctionOffset;
1028   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1029       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1030       /*FunctionOnly=*/true);
1031 
1032   uint64_t XDataAddress, XDataOffset;
1033   ErrorOr<SymbolRef> XDataRecord = getSymbolForLocation(
1034       COFF, Section, Offset + 4, RF.ExceptionInformationRVA(), XDataAddress,
1035       XDataOffset);
1036 
1037   if (!RF.BeginAddress && !Function)
1038     return false;
1039   if (!RF.UnwindData && !XDataRecord)
1040     return false;
1041 
1042   StringRef FunctionName;
1043   if (Function) {
1044     Expected<StringRef> FunctionNameOrErr = Function->getName();
1045     if (!FunctionNameOrErr) {
1046       std::string Buf;
1047       llvm::raw_string_ostream OS(Buf);
1048       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1049       OS.flush();
1050       report_fatal_error(Buf);
1051     }
1052     FunctionName = *FunctionNameOrErr;
1053   }
1054 
1055   SW.printString("Function",
1056                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1057 
1058   if (XDataRecord) {
1059     Expected<StringRef> Name = XDataRecord->getName();
1060     if (!Name) {
1061       std::string Buf;
1062       llvm::raw_string_ostream OS(Buf);
1063       logAllUnhandledErrors(Name.takeError(), OS);
1064       OS.flush();
1065       report_fatal_error(Buf);
1066     }
1067 
1068     SW.printString("ExceptionRecord",
1069                    formatSymbol(*Name, XDataAddress, XDataOffset));
1070 
1071     Expected<section_iterator> SIOrErr = XDataRecord->getSection();
1072     if (!SIOrErr) {
1073       // TODO: Actually report errors helpfully.
1074       consumeError(SIOrErr.takeError());
1075       return false;
1076     }
1077     section_iterator SI = *SIOrErr;
1078 
1079     return dumpXDataRecord(COFF, *SI, FunctionAddress, XDataAddress);
1080   } else {
1081     SW.printString("ExceptionRecord", formatSymbol("", XDataAddress));
1082 
1083     ErrorOr<SectionRef> Section = getSectionContaining(COFF, XDataAddress);
1084     if (!Section)
1085       return false;
1086 
1087     return dumpXDataRecord(COFF, *Section, FunctionAddress, XDataAddress);
1088   }
1089 }
1090 
1091 bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
1092                               const SectionRef Section, uint64_t Offset,
1093                               unsigned Index, const RuntimeFunction &RF) {
1094   assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
1095           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
1096          "unpacked entry cannot be treated as a packed entry");
1097 
1098   uint64_t FunctionAddress, FunctionOffset;
1099   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1100       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1101       /*FunctionOnly=*/true);
1102 
1103   StringRef FunctionName;
1104   if (Function) {
1105     Expected<StringRef> FunctionNameOrErr = Function->getName();
1106     if (!FunctionNameOrErr) {
1107       std::string Buf;
1108       llvm::raw_string_ostream OS(Buf);
1109       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1110       OS.flush();
1111       report_fatal_error(Buf);
1112     }
1113     FunctionName = *FunctionNameOrErr;
1114   }
1115 
1116   SW.printString("Function",
1117                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1118   if (!isAArch64)
1119     SW.printBoolean("Fragment",
1120                     RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
1121   SW.printNumber("FunctionLength", RF.FunctionLength());
1122   SW.startLine() << "ReturnType: " << RF.Ret() << '\n';
1123   SW.printBoolean("HomedParameters", RF.H());
1124   SW.startLine() << "SavedRegisters: ";
1125                  printRegisters(SavedRegisterMask(RF));
1126   OS << '\n';
1127   SW.printNumber("StackAdjustment", StackAdjustment(RF) << 2);
1128 
1129   return true;
1130 }
1131 
1132 bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
1133                                    const SectionRef Section, uint64_t Offset,
1134                                    unsigned Index,
1135                                    const RuntimeFunctionARM64 &RF) {
1136   assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
1137           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
1138          "unpacked entry cannot be treated as a packed entry");
1139 
1140   uint64_t FunctionAddress, FunctionOffset;
1141   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1142       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1143       /*FunctionOnly=*/true);
1144 
1145   StringRef FunctionName;
1146   if (Function) {
1147     Expected<StringRef> FunctionNameOrErr = Function->getName();
1148     if (!FunctionNameOrErr) {
1149       std::string Buf;
1150       llvm::raw_string_ostream OS(Buf);
1151       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1152       OS.flush();
1153       report_fatal_error(Buf);
1154     }
1155     FunctionName = *FunctionNameOrErr;
1156   }
1157 
1158   SW.printString("Function",
1159                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1160   SW.printBoolean("Fragment",
1161                   RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
1162   SW.printNumber("FunctionLength", RF.FunctionLength());
1163   SW.printNumber("RegF", RF.RegF());
1164   SW.printNumber("RegI", RF.RegI());
1165   SW.printBoolean("HomedParameters", RF.H());
1166   SW.printNumber("CR", RF.CR());
1167   SW.printNumber("FrameSize", RF.FrameSize() << 4);
1168   ListScope PS(SW, "Prologue");
1169 
1170   // Synthesize the equivalent prologue according to the documentation
1171   // at https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling,
1172   // printed in reverse order compared to the docs, to match how prologues
1173   // are printed for the non-packed case.
1174   int IntSZ = 8 * RF.RegI();
1175   if (RF.CR() == 1)
1176     IntSZ += 8;
1177   int FpSZ = 8 * RF.RegF();
1178   if (RF.RegF())
1179     FpSZ += 8;
1180   int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf;
1181   int LocSZ = (RF.FrameSize() << 4) - SavSZ;
1182 
1183   if (RF.CR() == 3) {
1184     SW.startLine() << "mov x29, sp\n";
1185     if (LocSZ <= 512) {
1186       SW.startLine() << format("stp x29, lr, [sp, #-%d]!\n", LocSZ);
1187     } else {
1188       SW.startLine() << "stp x29, lr, [sp, #0]\n";
1189     }
1190   }
1191   if (LocSZ > 4080) {
1192     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ - 4080);
1193     SW.startLine() << "sub sp, sp, #4080\n";
1194   } else if ((RF.CR() != 3 && LocSZ > 0) || LocSZ > 512) {
1195     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ);
1196   }
1197   if (RF.H()) {
1198     SW.startLine() << format("stp x6, x7, [sp, #%d]\n", IntSZ + FpSZ + 48);
1199     SW.startLine() << format("stp x4, x5, [sp, #%d]\n", IntSZ + FpSZ + 32);
1200     SW.startLine() << format("stp x2, x3, [sp, #%d]\n", IntSZ + FpSZ + 16);
1201     if (RF.RegI() > 0 || RF.RegF() > 0 || RF.CR() == 1) {
1202       SW.startLine() << format("stp x0, x1, [sp, #%d]\n", IntSZ + FpSZ);
1203     } else {
1204       // This case isn't documented; if neither RegI nor RegF nor CR=1
1205       // have decremented the stack pointer by SavSZ, we need to do it here
1206       // (as the final stack adjustment of LocSZ excludes SavSZ).
1207       SW.startLine() << format("stp x0, x1, [sp, #-%d]!\n", SavSZ);
1208     }
1209   }
1210   int FloatRegs = RF.RegF() > 0 ? RF.RegF() + 1 : 0;
1211   for (int I = (FloatRegs + 1) / 2 - 1; I >= 0; I--) {
1212     if (I == (FloatRegs + 1) / 2 - 1 && FloatRegs % 2 == 1) {
1213       // The last register, an odd register without a pair
1214       SW.startLine() << format("str d%d, [sp, #%d]\n", 8 + 2 * I,
1215                                IntSZ + 16 * I);
1216     } else if (I == 0 && RF.RegI() == 0 && RF.CR() != 1) {
1217       SW.startLine() << format("stp d%d, d%d, [sp, #-%d]!\n", 8 + 2 * I,
1218                                8 + 2 * I + 1, SavSZ);
1219     } else {
1220       SW.startLine() << format("stp d%d, d%d, [sp, #%d]\n", 8 + 2 * I,
1221                                8 + 2 * I + 1, IntSZ + 16 * I);
1222     }
1223   }
1224   if (RF.CR() == 1 && (RF.RegI() % 2) == 0) {
1225     if (RF.RegI() == 0)
1226       SW.startLine() << format("str lr, [sp, #-%d]!\n", SavSZ);
1227     else
1228       SW.startLine() << format("str lr, [sp, #%d]\n", IntSZ - 8);
1229   }
1230   for (int I = (RF.RegI() + 1) / 2 - 1; I >= 0; I--) {
1231     if (I == (RF.RegI() + 1) / 2 - 1 && RF.RegI() % 2 == 1) {
1232       // The last register, an odd register without a pair
1233       if (RF.CR() == 1) {
1234         if (I == 0) { // If this is the only register pair
1235           // CR=1 combined with RegI=1 doesn't map to a documented case;
1236           // it doesn't map to any regular unwind info opcode, and the
1237           // actual unwinder doesn't support it.
1238           SW.startLine() << "INVALID!\n";
1239         } else
1240           SW.startLine() << format("stp x%d, lr, [sp, #%d]\n", 19 + 2 * I,
1241                                    16 * I);
1242       } else {
1243         if (I == 0)
1244           SW.startLine() << format("str x%d, [sp, #-%d]!\n", 19 + 2 * I, SavSZ);
1245         else
1246           SW.startLine() << format("str x%d, [sp, #%d]\n", 19 + 2 * I, 16 * I);
1247       }
1248     } else if (I == 0) {
1249       // The first register pair
1250       SW.startLine() << format("stp x19, x20, [sp, #-%d]!\n", SavSZ);
1251     } else {
1252       SW.startLine() << format("stp x%d, x%d, [sp, #%d]\n", 19 + 2 * I,
1253                                19 + 2 * I + 1, 16 * I);
1254     }
1255   }
1256   SW.startLine() << "end\n";
1257 
1258   return true;
1259 }
1260 
1261 bool Decoder::dumpProcedureDataEntry(const COFFObjectFile &COFF,
1262                                      const SectionRef Section, unsigned Index,
1263                                      ArrayRef<uint8_t> Contents) {
1264   uint64_t Offset = PDataEntrySize * Index;
1265   const ulittle32_t *Data =
1266     reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
1267 
1268   const RuntimeFunction Entry(Data);
1269   DictScope RFS(SW, "RuntimeFunction");
1270   if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
1271     return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
1272   if (isAArch64) {
1273     const RuntimeFunctionARM64 EntryARM64(Data);
1274     return dumpPackedARM64Entry(COFF, Section, Offset, Index, EntryARM64);
1275   }
1276   return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
1277 }
1278 
1279 void Decoder::dumpProcedureData(const COFFObjectFile &COFF,
1280                                 const SectionRef Section) {
1281   ArrayRef<uint8_t> Contents;
1282   if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
1283     return;
1284 
1285   if (Contents.size() % PDataEntrySize) {
1286     errs() << ".pdata content is not " << PDataEntrySize << "-byte aligned\n";
1287     return;
1288   }
1289 
1290   for (unsigned EI = 0, EE = Contents.size() / PDataEntrySize; EI < EE; ++EI)
1291     if (!dumpProcedureDataEntry(COFF, Section, EI, Contents))
1292       break;
1293 }
1294 
1295 Error Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
1296   for (const auto &Section : COFF.sections()) {
1297     Expected<StringRef> NameOrErr =
1298         COFF.getSectionName(COFF.getCOFFSection(Section));
1299     if (!NameOrErr)
1300       return NameOrErr.takeError();
1301 
1302     if (NameOrErr->startswith(".pdata"))
1303       dumpProcedureData(COFF, Section);
1304   }
1305   return Error::success();
1306 }
1307 }
1308 }
1309 }
1310