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 << "bx <reg>";
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 static void printRange(raw_ostream &OS, ListSeparator &LS, unsigned First,
178                        unsigned Last, char Letter) {
179   if (First == Last)
180     OS << LS << Letter << First;
181   else
182     OS << LS << Letter << First << "-" << Letter << Last;
183 }
184 
185 static void printRange(raw_ostream &OS, uint32_t Mask, ListSeparator &LS,
186                        unsigned Start, unsigned End, char Letter) {
187   int First = -1;
188   for (unsigned RI = Start; RI <= End; ++RI) {
189     if (Mask & (1 << RI)) {
190       if (First < 0)
191         First = RI;
192     } else {
193       if (First >= 0) {
194         printRange(OS, LS, First, RI - 1, Letter);
195         First = -1;
196       }
197     }
198   }
199   if (First >= 0)
200     printRange(OS, LS, First, End, Letter);
201 }
202 
203 void Decoder::printGPRMask(uint16_t GPRMask) {
204   OS << '{';
205   ListSeparator LS;
206   printRange(OS, GPRMask, LS, 0, 12, 'r');
207   if (GPRMask & (1 << 14))
208     OS << LS << "lr";
209   if (GPRMask & (1 << 15))
210     OS << LS << "pc";
211   OS << '}';
212 }
213 
214 void Decoder::printVFPMask(uint32_t VFPMask) {
215   OS << '{';
216   ListSeparator LS;
217   printRange(OS, VFPMask, LS, 0, 31, 'd');
218   OS << '}';
219 }
220 
221 ErrorOr<object::SectionRef>
222 Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) {
223   for (const auto &Section : COFF.sections()) {
224     uint64_t Address = Section.getAddress();
225     uint64_t Size = Section.getSize();
226 
227     if (VA >= Address && (VA - Address) <= Size)
228       return Section;
229   }
230   return inconvertibleErrorCode();
231 }
232 
233 ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF,
234                                               uint64_t VA, bool FunctionOnly) {
235   for (const auto &Symbol : COFF.symbols()) {
236     Expected<SymbolRef::Type> Type = Symbol.getType();
237     if (!Type)
238       return errorToErrorCode(Type.takeError());
239     if (FunctionOnly && *Type != SymbolRef::ST_Function)
240       continue;
241 
242     Expected<uint64_t> Address = Symbol.getAddress();
243     if (!Address)
244       return errorToErrorCode(Address.takeError());
245     if (*Address == VA)
246       return Symbol;
247   }
248   return inconvertibleErrorCode();
249 }
250 
251 ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
252                                                const SectionRef &Section,
253                                                uint64_t Offset) {
254   for (const auto &Relocation : Section.relocations()) {
255     uint64_t RelocationOffset = Relocation.getOffset();
256     if (RelocationOffset == Offset)
257       return *Relocation.getSymbol();
258   }
259   return inconvertibleErrorCode();
260 }
261 
262 SymbolRef Decoder::getPreferredSymbol(const COFFObjectFile &COFF, SymbolRef Sym,
263                                       uint64_t &SymbolOffset) {
264   // The symbol resolved by getRelocatedSymbol can be any internal
265   // nondescriptive symbol; try to resolve a more descriptive one.
266   COFFSymbolRef CoffSym = COFF.getCOFFSymbol(Sym);
267   if (CoffSym.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL &&
268       CoffSym.getSectionDefinition() == nullptr)
269     return Sym;
270   for (const auto &S : COFF.symbols()) {
271     COFFSymbolRef CS = COFF.getCOFFSymbol(S);
272     if (CS.getSectionNumber() == CoffSym.getSectionNumber() &&
273         CS.getValue() <= CoffSym.getValue() + SymbolOffset &&
274         CS.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL &&
275         CS.getSectionDefinition() == nullptr) {
276       uint32_t Offset = CoffSym.getValue() + SymbolOffset - CS.getValue();
277       if (Offset <= SymbolOffset) {
278         SymbolOffset = Offset;
279         Sym = S;
280         CoffSym = CS;
281         if (CS.isExternal() && SymbolOffset == 0)
282           return Sym;
283       }
284     }
285   }
286   return Sym;
287 }
288 
289 ErrorOr<SymbolRef> Decoder::getSymbolForLocation(
290     const COFFObjectFile &COFF, const SectionRef &Section,
291     uint64_t OffsetInSection, uint64_t ImmediateOffset, uint64_t &SymbolAddress,
292     uint64_t &SymbolOffset, bool FunctionOnly) {
293   // Try to locate a relocation that points at the offset in the section
294   ErrorOr<SymbolRef> SymOrErr =
295       getRelocatedSymbol(COFF, Section, OffsetInSection);
296   if (SymOrErr) {
297     // We found a relocation symbol; the immediate offset needs to be added
298     // to the symbol address.
299     SymbolOffset = ImmediateOffset;
300 
301     Expected<uint64_t> AddressOrErr = SymOrErr->getAddress();
302     if (!AddressOrErr) {
303       std::string Buf;
304       llvm::raw_string_ostream OS(Buf);
305       logAllUnhandledErrors(AddressOrErr.takeError(), OS);
306       report_fatal_error(Twine(OS.str()));
307     }
308     // We apply SymbolOffset here directly. We return it separately to allow
309     // the caller to print it as an offset on the symbol name.
310     SymbolAddress = *AddressOrErr + SymbolOffset;
311 
312     if (FunctionOnly) // Resolve label/section symbols into function names.
313       SymOrErr = getPreferredSymbol(COFF, *SymOrErr, SymbolOffset);
314   } else {
315     // No matching relocation found; operating on a linked image. Try to
316     // find a descriptive symbol if possible. The immediate offset contains
317     // the image relative address, and we shouldn't add any offset to the
318     // symbol.
319     SymbolAddress = COFF.getImageBase() + ImmediateOffset;
320     SymbolOffset = 0;
321     SymOrErr = getSymbol(COFF, SymbolAddress, FunctionOnly);
322   }
323   return SymOrErr;
324 }
325 
326 bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
327                               unsigned Length, bool Prologue) {
328   uint8_t Imm = OC[Offset] & 0x7f;
329   SW.startLine() << format("0x%02x                ; %s sp, #(%u * 4)\n",
330                            OC[Offset],
331                            static_cast<const char *>(Prologue ? "sub" : "add"),
332                            Imm);
333   ++Offset;
334   return false;
335 }
336 
337 bool Decoder::opcode_10Lxxxxx(const uint8_t *OC, unsigned &Offset,
338                               unsigned Length, bool Prologue) {
339   unsigned Link = (OC[Offset] & 0x20) >> 5;
340   uint16_t RegisterMask = (Link << (Prologue ? 14 : 15))
341                         | ((OC[Offset + 0] & 0x1f) << 8)
342                         | ((OC[Offset + 1] & 0xff) << 0);
343   assert((~RegisterMask & (1 << 13)) && "sp must not be set");
344   assert((~RegisterMask & (1 << (Prologue ? 15 : 14))) && "pc must not be set");
345 
346   SW.startLine() << format("0x%02x 0x%02x           ; %s.w ",
347                            OC[Offset + 0], OC[Offset + 1],
348                            Prologue ? "push" : "pop");
349   printGPRMask(RegisterMask);
350   OS << '\n';
351 
352   Offset += 2;
353   return false;
354 }
355 
356 bool Decoder::opcode_1100xxxx(const uint8_t *OC, unsigned &Offset,
357                               unsigned Length, bool Prologue) {
358   if (Prologue)
359     SW.startLine() << format("0x%02x                ; mov r%u, sp\n",
360                              OC[Offset], OC[Offset] & 0xf);
361   else
362     SW.startLine() << format("0x%02x                ; mov sp, r%u\n",
363                              OC[Offset], OC[Offset] & 0xf);
364   ++Offset;
365   return false;
366 }
367 
368 bool Decoder::opcode_11010Lxx(const uint8_t *OC, unsigned &Offset,
369                               unsigned Length, bool Prologue) {
370   unsigned Link = (OC[Offset] & 0x4) >> 2;
371   unsigned Count = (OC[Offset] & 0x3);
372 
373   uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
374                    | (((1 << (Count + 1)) - 1) << 4);
375 
376   SW.startLine() << format("0x%02x                ; %s ", OC[Offset],
377                            Prologue ? "push" : "pop");
378   printGPRMask(GPRMask);
379   OS << '\n';
380 
381   ++Offset;
382   return false;
383 }
384 
385 bool Decoder::opcode_11011Lxx(const uint8_t *OC, unsigned &Offset,
386                               unsigned Length, bool Prologue) {
387   unsigned Link = (OC[Offset] & 0x4) >> 2;
388   unsigned Count = (OC[Offset] & 0x3) + 4;
389 
390   uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
391                    | (((1 << (Count + 1)) - 1) << 4);
392 
393   SW.startLine() << format("0x%02x                ; %s.w ", OC[Offset],
394                            Prologue ? "push" : "pop");
395   printGPRMask(GPRMask);
396   OS << '\n';
397 
398   ++Offset;
399   return false;
400 }
401 
402 bool Decoder::opcode_11100xxx(const uint8_t *OC, unsigned &Offset,
403                               unsigned Length, bool Prologue) {
404   unsigned High = (OC[Offset] & 0x7);
405   uint32_t VFPMask = (((1 << (High + 1)) - 1) << 8);
406 
407   SW.startLine() << format("0x%02x                ; %s ", OC[Offset],
408                            Prologue ? "vpush" : "vpop");
409   printVFPMask(VFPMask);
410   OS << '\n';
411 
412   ++Offset;
413   return false;
414 }
415 
416 bool Decoder::opcode_111010xx(const uint8_t *OC, unsigned &Offset,
417                               unsigned Length, bool Prologue) {
418   uint16_t Imm = ((OC[Offset + 0] & 0x03) << 8) | ((OC[Offset + 1] & 0xff) << 0);
419 
420   SW.startLine() << format("0x%02x 0x%02x           ; %s.w sp, #(%u * 4)\n",
421                            OC[Offset + 0], OC[Offset + 1],
422                            static_cast<const char *>(Prologue ? "sub" : "add"),
423                            Imm);
424 
425   Offset += 2;
426   return false;
427 }
428 
429 bool Decoder::opcode_1110110L(const uint8_t *OC, unsigned &Offset,
430                               unsigned Length, bool Prologue) {
431   uint16_t GPRMask = ((OC[Offset + 0] & 0x01) << (Prologue ? 14 : 15))
432                    | ((OC[Offset + 1] & 0xff) << 0);
433 
434   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
435                            OC[Offset + 1], Prologue ? "push" : "pop");
436   printGPRMask(GPRMask);
437   OS << '\n';
438 
439   Offset += 2;
440   return false;
441 }
442 
443 bool Decoder::opcode_11101110(const uint8_t *OC, unsigned &Offset,
444                               unsigned Length, bool Prologue) {
445   assert(!Prologue && "may not be used in prologue");
446 
447   if (OC[Offset + 1] & 0xf0)
448     SW.startLine() << format("0x%02x 0x%02x           ; reserved\n",
449                              OC[Offset + 0], OC[Offset +  1]);
450   else
451     SW.startLine()
452       << format("0x%02x 0x%02x           ; microsoft-specific (type: %u)\n",
453                 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] & 0x0f);
454 
455   Offset += 2;
456   return false;
457 }
458 
459 bool Decoder::opcode_11101111(const uint8_t *OC, unsigned &Offset,
460                               unsigned Length, bool Prologue) {
461   if (OC[Offset + 1] & 0xf0)
462     SW.startLine() << format("0x%02x 0x%02x           ; reserved\n",
463                              OC[Offset + 0], OC[Offset +  1]);
464   else if (Prologue)
465     SW.startLine()
466       << format("0x%02x 0x%02x           ; str.w lr, [sp, #-%u]!\n",
467                 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] << 2);
468   else
469     SW.startLine()
470       << format("0x%02x 0x%02x           ; ldr.w lr, [sp], #%u\n",
471                 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] << 2);
472 
473   Offset += 2;
474   return false;
475 }
476 
477 bool Decoder::opcode_11110101(const uint8_t *OC, unsigned &Offset,
478                               unsigned Length, bool Prologue) {
479   unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
480   unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
481   uint32_t VFPMask = ((1 << (End + 1 - Start)) - 1) << Start;
482 
483   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
484                            OC[Offset + 1], Prologue ? "vpush" : "vpop");
485   printVFPMask(VFPMask);
486   OS << '\n';
487 
488   Offset += 2;
489   return false;
490 }
491 
492 bool Decoder::opcode_11110110(const uint8_t *OC, unsigned &Offset,
493                               unsigned Length, bool Prologue) {
494   unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
495   unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
496   uint32_t VFPMask = ((1 << (End + 1 - Start)) - 1) << (16 + Start);
497 
498   SW.startLine() << format("0x%02x 0x%02x           ; %s ", OC[Offset + 0],
499                            OC[Offset + 1], Prologue ? "vpush" : "vpop");
500   printVFPMask(VFPMask);
501   OS << '\n';
502 
503   Offset += 2;
504   return false;
505 }
506 
507 bool Decoder::opcode_11110111(const uint8_t *OC, unsigned &Offset,
508                               unsigned Length, bool Prologue) {
509   uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
510 
511   SW.startLine() << format("0x%02x 0x%02x 0x%02x      ; %s sp, sp, #(%u * 4)\n",
512                            OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
513                            static_cast<const char *>(Prologue ? "sub" : "add"),
514                            Imm);
515 
516   Offset += 3;
517   return false;
518 }
519 
520 bool Decoder::opcode_11111000(const uint8_t *OC, unsigned &Offset,
521                               unsigned Length, bool Prologue) {
522   uint32_t Imm = (OC[Offset + 1] << 16)
523                | (OC[Offset + 2] << 8)
524                | (OC[Offset + 3] << 0);
525 
526   SW.startLine()
527     << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s sp, sp, #(%u * 4)\n",
528               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
529               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
530 
531   Offset += 4;
532   return false;
533 }
534 
535 bool Decoder::opcode_11111001(const uint8_t *OC, unsigned &Offset,
536                               unsigned Length, bool Prologue) {
537   uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
538 
539   SW.startLine()
540     << format("0x%02x 0x%02x 0x%02x      ; %s.w sp, sp, #(%u * 4)\n",
541               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
542               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
543 
544   Offset += 3;
545   return false;
546 }
547 
548 bool Decoder::opcode_11111010(const uint8_t *OC, unsigned &Offset,
549                               unsigned Length, bool Prologue) {
550   uint32_t Imm = (OC[Offset + 1] << 16)
551                | (OC[Offset + 2] << 8)
552                | (OC[Offset + 3] << 0);
553 
554   SW.startLine()
555     << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s.w sp, sp, #(%u * 4)\n",
556               OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
557               static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
558 
559   Offset += 4;
560   return false;
561 }
562 
563 bool Decoder::opcode_11111011(const uint8_t *OC, unsigned &Offset,
564                               unsigned Length, bool Prologue) {
565   SW.startLine() << format("0x%02x                ; nop\n", OC[Offset]);
566   ++Offset;
567   return false;
568 }
569 
570 bool Decoder::opcode_11111100(const uint8_t *OC, unsigned &Offset,
571                               unsigned Length, bool Prologue) {
572   SW.startLine() << format("0x%02x                ; nop.w\n", OC[Offset]);
573   ++Offset;
574   return false;
575 }
576 
577 bool Decoder::opcode_11111101(const uint8_t *OC, unsigned &Offset,
578                               unsigned Length, bool Prologue) {
579   SW.startLine() << format("0x%02x                ; bx <reg>\n", OC[Offset]);
580   ++Offset;
581   return true;
582 }
583 
584 bool Decoder::opcode_11111110(const uint8_t *OC, unsigned &Offset,
585                               unsigned Length, bool Prologue) {
586   SW.startLine() << format("0x%02x                ; b.w <target>\n", OC[Offset]);
587   ++Offset;
588   return true;
589 }
590 
591 bool Decoder::opcode_11111111(const uint8_t *OC, unsigned &Offset,
592                               unsigned Length, bool Prologue) {
593   ++Offset;
594   return true;
595 }
596 
597 // ARM64 unwind codes start here.
598 bool Decoder::opcode_alloc_s(const uint8_t *OC, unsigned &Offset,
599                              unsigned Length, bool Prologue) {
600   uint32_t NumBytes = (OC[Offset] & 0x1F) << 4;
601   SW.startLine() << format("0x%02x                ; %s sp, #%u\n", OC[Offset],
602                            static_cast<const char *>(Prologue ? "sub" : "add"),
603                            NumBytes);
604   ++Offset;
605   return false;
606 }
607 
608 bool Decoder::opcode_save_r19r20_x(const uint8_t *OC, unsigned &Offset,
609                                    unsigned Length, bool Prologue) {
610   uint32_t Off = (OC[Offset] & 0x1F) << 3;
611   if (Prologue)
612     SW.startLine() << format(
613         "0x%02x                ; stp x19, x20, [sp, #-%u]!\n", OC[Offset], Off);
614   else
615     SW.startLine() << format(
616         "0x%02x                ; ldp x19, x20, [sp], #%u\n", OC[Offset], Off);
617   ++Offset;
618   return false;
619 }
620 
621 bool Decoder::opcode_save_fplr(const uint8_t *OC, unsigned &Offset,
622                                unsigned Length, bool Prologue) {
623   uint32_t Off = (OC[Offset] & 0x3F) << 3;
624   SW.startLine() << format(
625       "0x%02x                ; %s x29, x30, [sp, #%u]\n", OC[Offset],
626       static_cast<const char *>(Prologue ? "stp" : "ldp"), Off);
627   ++Offset;
628   return false;
629 }
630 
631 bool Decoder::opcode_save_fplr_x(const uint8_t *OC, unsigned &Offset,
632                                  unsigned Length, bool Prologue) {
633   uint32_t Off = ((OC[Offset] & 0x3F) + 1) << 3;
634   if (Prologue)
635     SW.startLine() << format(
636         "0x%02x                ; stp x29, x30, [sp, #-%u]!\n", OC[Offset], Off);
637   else
638     SW.startLine() << format(
639         "0x%02x                ; ldp x29, x30, [sp], #%u\n", OC[Offset], Off);
640   ++Offset;
641   return false;
642 }
643 
644 bool Decoder::opcode_alloc_m(const uint8_t *OC, unsigned &Offset,
645                              unsigned Length, bool Prologue) {
646   uint32_t NumBytes = ((OC[Offset] & 0x07) << 8);
647   NumBytes |= (OC[Offset + 1] & 0xFF);
648   NumBytes <<= 4;
649   SW.startLine() << format("0x%02x%02x              ; %s sp, #%u\n",
650                            OC[Offset], OC[Offset + 1],
651                            static_cast<const char *>(Prologue ? "sub" : "add"),
652                            NumBytes);
653   Offset += 2;
654   return false;
655 }
656 
657 bool Decoder::opcode_save_regp(const uint8_t *OC, unsigned &Offset,
658                                unsigned Length, bool Prologue) {
659   uint32_t Reg = ((OC[Offset] & 0x03) << 8);
660   Reg |= (OC[Offset + 1] & 0xC0);
661   Reg >>= 6;
662   Reg += 19;
663   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
664   SW.startLine() << format(
665       "0x%02x%02x              ; %s x%u, x%u, [sp, #%u]\n",
666       OC[Offset], OC[Offset + 1],
667       static_cast<const char *>(Prologue ? "stp" : "ldp"), Reg, Reg + 1, Off);
668   Offset += 2;
669   return false;
670 }
671 
672 bool Decoder::opcode_save_regp_x(const uint8_t *OC, unsigned &Offset,
673                                  unsigned Length, bool Prologue) {
674   uint32_t Reg = ((OC[Offset] & 0x03) << 8);
675   Reg |= (OC[Offset + 1] & 0xC0);
676   Reg >>= 6;
677   Reg += 19;
678   uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
679   if (Prologue)
680     SW.startLine() << format(
681         "0x%02x%02x              ; stp x%u, x%u, [sp, #-%u]!\n",
682         OC[Offset], OC[Offset + 1], Reg,
683         Reg + 1, Off);
684   else
685     SW.startLine() << format(
686         "0x%02x%02x              ; ldp x%u, x%u, [sp], #%u\n",
687         OC[Offset], OC[Offset + 1], Reg,
688         Reg + 1, Off);
689   Offset += 2;
690   return false;
691 }
692 
693 bool Decoder::opcode_save_reg(const uint8_t *OC, unsigned &Offset,
694                               unsigned Length, bool Prologue) {
695   uint32_t Reg = (OC[Offset] & 0x03) << 8;
696   Reg |= (OC[Offset + 1] & 0xC0);
697   Reg >>= 6;
698   Reg += 19;
699   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
700   SW.startLine() << format("0x%02x%02x              ; %s x%u, [sp, #%u]\n",
701                            OC[Offset], OC[Offset + 1],
702                            static_cast<const char *>(Prologue ? "str" : "ldr"),
703                            Reg, Off);
704   Offset += 2;
705   return false;
706 }
707 
708 bool Decoder::opcode_save_reg_x(const uint8_t *OC, unsigned &Offset,
709                                 unsigned Length, bool Prologue) {
710   uint32_t Reg = (OC[Offset] & 0x01) << 8;
711   Reg |= (OC[Offset + 1] & 0xE0);
712   Reg >>= 5;
713   Reg += 19;
714   uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
715   if (Prologue)
716     SW.startLine() << format("0x%02x%02x              ; str x%u, [sp, #-%u]!\n",
717                              OC[Offset], OC[Offset + 1], Reg, Off);
718   else
719     SW.startLine() << format("0x%02x%02x              ; ldr x%u, [sp], #%u\n",
720                              OC[Offset], OC[Offset + 1], Reg, Off);
721   Offset += 2;
722   return false;
723 }
724 
725 bool Decoder::opcode_save_lrpair(const uint8_t *OC, unsigned &Offset,
726                                  unsigned Length, bool Prologue) {
727   uint32_t Reg = (OC[Offset] & 0x01) << 8;
728   Reg |= (OC[Offset + 1] & 0xC0);
729   Reg >>= 6;
730   Reg *= 2;
731   Reg += 19;
732   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
733   SW.startLine() << format("0x%02x%02x              ; %s x%u, lr, [sp, #%u]\n",
734                            OC[Offset], OC[Offset + 1],
735                            static_cast<const char *>(Prologue ? "stp" : "ldp"),
736                            Reg, Off);
737   Offset += 2;
738   return false;
739 }
740 
741 bool Decoder::opcode_save_fregp(const uint8_t *OC, unsigned &Offset,
742                                 unsigned Length, bool Prologue) {
743   uint32_t Reg = (OC[Offset] & 0x01) << 8;
744   Reg |= (OC[Offset + 1] & 0xC0);
745   Reg >>= 6;
746   Reg += 8;
747   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
748   SW.startLine() << format("0x%02x%02x              ; %s d%u, d%u, [sp, #%u]\n",
749                            OC[Offset], OC[Offset + 1],
750                            static_cast<const char *>(Prologue ? "stp" : "ldp"),
751                            Reg, Reg + 1, Off);
752   Offset += 2;
753   return false;
754 }
755 
756 bool Decoder::opcode_save_fregp_x(const uint8_t *OC, unsigned &Offset,
757                                   unsigned Length, bool Prologue) {
758   uint32_t Reg = (OC[Offset] & 0x01) << 8;
759   Reg |= (OC[Offset + 1] & 0xC0);
760   Reg >>= 6;
761   Reg += 8;
762   uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
763   if (Prologue)
764     SW.startLine() << format(
765         "0x%02x%02x              ; stp d%u, d%u, [sp, #-%u]!\n", OC[Offset],
766         OC[Offset + 1], Reg, Reg + 1, Off);
767   else
768     SW.startLine() << format(
769         "0x%02x%02x              ; ldp d%u, d%u, [sp], #%u\n", OC[Offset],
770         OC[Offset + 1], Reg, Reg + 1, Off);
771   Offset += 2;
772   return false;
773 }
774 
775 bool Decoder::opcode_save_freg(const uint8_t *OC, unsigned &Offset,
776                                unsigned Length, bool Prologue) {
777   uint32_t Reg = (OC[Offset] & 0x01) << 8;
778   Reg |= (OC[Offset + 1] & 0xC0);
779   Reg >>= 6;
780   Reg += 8;
781   uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
782   SW.startLine() << format("0x%02x%02x              ; %s d%u, [sp, #%u]\n",
783                            OC[Offset], OC[Offset + 1],
784                            static_cast<const char *>(Prologue ? "str" : "ldr"),
785                            Reg, Off);
786   Offset += 2;
787   return false;
788 }
789 
790 bool Decoder::opcode_save_freg_x(const uint8_t *OC, unsigned &Offset,
791                                  unsigned Length, bool Prologue) {
792   uint32_t Reg = ((OC[Offset + 1] & 0xE0) >> 5) + 8;
793   uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
794   if (Prologue)
795     SW.startLine() << format(
796         "0x%02x%02x              ; str d%u, [sp, #-%u]!\n", OC[Offset],
797         OC[Offset + 1], Reg, Off);
798   else
799     SW.startLine() << format(
800         "0x%02x%02x              ; ldr d%u, [sp], #%u\n", OC[Offset],
801         OC[Offset + 1], Reg, Off);
802   Offset += 2;
803   return false;
804 }
805 
806 bool Decoder::opcode_alloc_l(const uint8_t *OC, unsigned &Offset,
807                              unsigned Length, bool Prologue) {
808   unsigned Off =
809       (OC[Offset + 1] << 16) | (OC[Offset + 2] << 8) | (OC[Offset + 3] << 0);
810   Off <<= 4;
811   SW.startLine() << format(
812       "0x%02x%02x%02x%02x          ; %s sp, #%u\n", OC[Offset], OC[Offset + 1],
813       OC[Offset + 2], OC[Offset + 3],
814       static_cast<const char *>(Prologue ? "sub" : "add"), Off);
815   Offset += 4;
816   return false;
817 }
818 
819 bool Decoder::opcode_setfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
820                            bool Prologue) {
821   SW.startLine() << format("0x%02x                ; mov %s, %s\n", OC[Offset],
822                            static_cast<const char *>(Prologue ? "fp" : "sp"),
823                            static_cast<const char *>(Prologue ? "sp" : "fp"));
824   ++Offset;
825   return false;
826 }
827 
828 bool Decoder::opcode_addfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
829                            bool Prologue) {
830   unsigned NumBytes = OC[Offset + 1] << 3;
831   SW.startLine() << format(
832       "0x%02x%02x              ; %s %s, %s, #%u\n", OC[Offset], OC[Offset + 1],
833       static_cast<const char *>(Prologue ? "add" : "sub"),
834       static_cast<const char *>(Prologue ? "fp" : "sp"),
835       static_cast<const char *>(Prologue ? "sp" : "fp"), NumBytes);
836   Offset += 2;
837   return false;
838 }
839 
840 bool Decoder::opcode_nop(const uint8_t *OC, unsigned &Offset, unsigned Length,
841                          bool Prologue) {
842   SW.startLine() << format("0x%02x                ; nop\n", OC[Offset]);
843   ++Offset;
844   return false;
845 }
846 
847 bool Decoder::opcode_end(const uint8_t *OC, unsigned &Offset, unsigned Length,
848                          bool Prologue) {
849   SW.startLine() << format("0x%02x                ; end\n", OC[Offset]);
850   ++Offset;
851   return true;
852 }
853 
854 bool Decoder::opcode_end_c(const uint8_t *OC, unsigned &Offset, unsigned Length,
855                            bool Prologue) {
856   SW.startLine() << format("0x%02x                ; end_c\n", OC[Offset]);
857   ++Offset;
858   return true;
859 }
860 
861 bool Decoder::opcode_save_next(const uint8_t *OC, unsigned &Offset,
862                                unsigned Length, bool Prologue) {
863   if (Prologue)
864     SW.startLine() << format("0x%02x                ; save next\n", OC[Offset]);
865   else
866     SW.startLine() << format("0x%02x                ; restore next\n",
867                              OC[Offset]);
868   ++Offset;
869   return false;
870 }
871 
872 bool Decoder::opcode_trap_frame(const uint8_t *OC, unsigned &Offset,
873                                 unsigned Length, bool Prologue) {
874   SW.startLine() << format("0x%02x                ; trap frame\n", OC[Offset]);
875   ++Offset;
876   return false;
877 }
878 
879 bool Decoder::opcode_machine_frame(const uint8_t *OC, unsigned &Offset,
880                                    unsigned Length, bool Prologue) {
881   SW.startLine() << format("0x%02x                ; machine frame\n",
882                            OC[Offset]);
883   ++Offset;
884   return false;
885 }
886 
887 bool Decoder::opcode_context(const uint8_t *OC, unsigned &Offset,
888                              unsigned Length, bool Prologue) {
889   SW.startLine() << format("0x%02x                ; context\n", OC[Offset]);
890   ++Offset;
891   return false;
892 }
893 
894 bool Decoder::opcode_clear_unwound_to_call(const uint8_t *OC, unsigned &Offset,
895                                            unsigned Length, bool Prologue) {
896   SW.startLine() << format("0x%02x                ; clear unwound to call\n",
897                            OC[Offset]);
898   ++Offset;
899   return false;
900 }
901 
902 void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
903                             bool Prologue) {
904   assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
905   const RingEntry* DecodeRing = isAArch64 ? Ring64 : Ring;
906   bool Terminated = false;
907   for (unsigned OI = Offset, OE = Opcodes.size(); !Terminated && OI < OE; ) {
908     for (unsigned DI = 0;; ++DI) {
909       if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
910           (!isAArch64 && (DI >= array_lengthof(Ring)))) {
911         SW.startLine() << format("0x%02x                ; Bad opcode!\n",
912                                  Opcodes.data()[OI]);
913         ++OI;
914         break;
915       }
916 
917       if ((Opcodes[OI] & DecodeRing[DI].Mask) == DecodeRing[DI].Value) {
918         if (OI + DecodeRing[DI].Length > OE) {
919           SW.startLine() << format("Opcode 0x%02x goes past the unwind data\n",
920                                     Opcodes[OI]);
921           OI += DecodeRing[DI].Length;
922           break;
923         }
924         Terminated =
925             (this->*DecodeRing[DI].Routine)(Opcodes.data(), OI, 0, Prologue);
926         break;
927       }
928     }
929   }
930 }
931 
932 bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
933                               const SectionRef &Section,
934                               uint64_t FunctionAddress, uint64_t VA) {
935   ArrayRef<uint8_t> Contents;
936   if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
937     return false;
938 
939   uint64_t SectionVA = Section.getAddress();
940   uint64_t Offset = VA - SectionVA;
941   const ulittle32_t *Data =
942     reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
943 
944   // Sanity check to ensure that the .xdata header is present.
945   // A header is one or two words, followed by at least one word to describe
946   // the unwind codes. Applicable to both ARM and AArch64.
947   if (Contents.size() - Offset < 8)
948     report_fatal_error(".xdata must be at least 8 bytes in size");
949 
950   const ExceptionDataRecord XData(Data, isAArch64);
951   DictScope XRS(SW, "ExceptionData");
952   SW.printNumber("FunctionLength",
953                  isAArch64 ? XData.FunctionLengthInBytesAArch64() :
954                  XData.FunctionLengthInBytesARM());
955   SW.printNumber("Version", XData.Vers());
956   SW.printBoolean("ExceptionData", XData.X());
957   SW.printBoolean("EpiloguePacked", XData.E());
958   if (!isAArch64)
959     SW.printBoolean("Fragment", XData.F());
960   SW.printNumber(XData.E() ? "EpilogueOffset" : "EpilogueScopes",
961                  XData.EpilogueCount());
962   uint64_t ByteCodeLength = XData.CodeWords() * sizeof(uint32_t);
963   SW.printNumber("ByteCodeLength", ByteCodeLength);
964 
965   if ((int64_t)(Contents.size() - Offset - 4 * HeaderWords(XData) -
966                 (XData.E() ? 0 : XData.EpilogueCount() * 4) -
967                 (XData.X() ? 8 : 0)) < (int64_t)ByteCodeLength) {
968     SW.flush();
969     report_fatal_error("Malformed unwind data");
970   }
971 
972   if (XData.E()) {
973     ArrayRef<uint8_t> UC = XData.UnwindByteCode();
974     {
975       ListScope PS(SW, "Prologue");
976       decodeOpcodes(UC, 0, /*Prologue=*/true);
977     }
978     if (XData.EpilogueCount()) {
979       ListScope ES(SW, "Epilogue");
980       decodeOpcodes(UC, XData.EpilogueCount(), /*Prologue=*/false);
981     }
982   } else {
983     {
984       ListScope PS(SW, "Prologue");
985       decodeOpcodes(XData.UnwindByteCode(), 0, /*Prologue=*/true);
986     }
987     ArrayRef<ulittle32_t> EpilogueScopes = XData.EpilogueScopes();
988     ListScope ESS(SW, "EpilogueScopes");
989     for (const EpilogueScope ES : EpilogueScopes) {
990       DictScope ESES(SW, "EpilogueScope");
991       SW.printNumber("StartOffset", ES.EpilogueStartOffset());
992       if (!isAArch64)
993         SW.printNumber("Condition", ES.Condition());
994       SW.printNumber("EpilogueStartIndex",
995                      isAArch64 ? ES.EpilogueStartIndexAArch64()
996                                : ES.EpilogueStartIndexARM());
997       unsigned ReservedMask = isAArch64 ? 0xF : 0x3;
998       if ((ES.ES >> 18) & ReservedMask)
999         SW.printNumber("ReservedBits", (ES.ES >> 18) & ReservedMask);
1000 
1001       ListScope Opcodes(SW, "Opcodes");
1002       decodeOpcodes(XData.UnwindByteCode(),
1003                     isAArch64 ? ES.EpilogueStartIndexAArch64()
1004                               : ES.EpilogueStartIndexARM(),
1005                     /*Prologue=*/false);
1006     }
1007   }
1008 
1009   if (XData.X()) {
1010     const uint32_t Parameter = XData.ExceptionHandlerParameter();
1011     const size_t HandlerOffset = HeaderWords(XData) +
1012                                  (XData.E() ? 0 : XData.EpilogueCount()) +
1013                                  XData.CodeWords();
1014 
1015     uint64_t Address, SymbolOffset;
1016     ErrorOr<SymbolRef> Symbol = getSymbolForLocation(
1017         COFF, Section, Offset + HandlerOffset * sizeof(uint32_t),
1018         XData.ExceptionHandlerRVA(), Address, SymbolOffset,
1019         /*FunctionOnly=*/true);
1020     if (!Symbol) {
1021       ListScope EHS(SW, "ExceptionHandler");
1022       SW.printHex("Routine", Address);
1023       SW.printHex("Parameter", Parameter);
1024       return true;
1025     }
1026 
1027     Expected<StringRef> Name = Symbol->getName();
1028     if (!Name) {
1029       std::string Buf;
1030       llvm::raw_string_ostream OS(Buf);
1031       logAllUnhandledErrors(Name.takeError(), OS);
1032       report_fatal_error(Twine(OS.str()));
1033     }
1034 
1035     ListScope EHS(SW, "ExceptionHandler");
1036     SW.printString("Routine", formatSymbol(*Name, Address, SymbolOffset));
1037     SW.printHex("Parameter", Parameter);
1038   }
1039 
1040   return true;
1041 }
1042 
1043 bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
1044                                 const SectionRef Section, uint64_t Offset,
1045                                 unsigned Index, const RuntimeFunction &RF) {
1046   assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
1047          "packed entry cannot be treated as an unpacked entry");
1048 
1049   uint64_t FunctionAddress, FunctionOffset;
1050   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1051       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1052       /*FunctionOnly=*/true);
1053 
1054   uint64_t XDataAddress, XDataOffset;
1055   ErrorOr<SymbolRef> XDataRecord = getSymbolForLocation(
1056       COFF, Section, Offset + 4, RF.ExceptionInformationRVA(), XDataAddress,
1057       XDataOffset);
1058 
1059   if (!RF.BeginAddress && !Function)
1060     return false;
1061   if (!RF.UnwindData && !XDataRecord)
1062     return false;
1063 
1064   StringRef FunctionName;
1065   if (Function) {
1066     Expected<StringRef> FunctionNameOrErr = Function->getName();
1067     if (!FunctionNameOrErr) {
1068       std::string Buf;
1069       llvm::raw_string_ostream OS(Buf);
1070       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1071       report_fatal_error(Twine(OS.str()));
1072     }
1073     FunctionName = *FunctionNameOrErr;
1074   }
1075 
1076   SW.printString("Function",
1077                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1078 
1079   if (XDataRecord) {
1080     Expected<StringRef> Name = XDataRecord->getName();
1081     if (!Name) {
1082       std::string Buf;
1083       llvm::raw_string_ostream OS(Buf);
1084       logAllUnhandledErrors(Name.takeError(), OS);
1085       report_fatal_error(Twine(OS.str()));
1086     }
1087 
1088     SW.printString("ExceptionRecord",
1089                    formatSymbol(*Name, XDataAddress, XDataOffset));
1090 
1091     Expected<section_iterator> SIOrErr = XDataRecord->getSection();
1092     if (!SIOrErr) {
1093       // TODO: Actually report errors helpfully.
1094       consumeError(SIOrErr.takeError());
1095       return false;
1096     }
1097     section_iterator SI = *SIOrErr;
1098 
1099     return dumpXDataRecord(COFF, *SI, FunctionAddress, XDataAddress);
1100   } else {
1101     SW.printString("ExceptionRecord", formatSymbol("", XDataAddress));
1102 
1103     ErrorOr<SectionRef> Section = getSectionContaining(COFF, XDataAddress);
1104     if (!Section)
1105       return false;
1106 
1107     return dumpXDataRecord(COFF, *Section, FunctionAddress, XDataAddress);
1108   }
1109 }
1110 
1111 bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
1112                               const SectionRef Section, uint64_t Offset,
1113                               unsigned Index, const RuntimeFunction &RF) {
1114   assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
1115           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
1116          "unpacked entry cannot be treated as a packed entry");
1117 
1118   uint64_t FunctionAddress, FunctionOffset;
1119   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1120       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1121       /*FunctionOnly=*/true);
1122 
1123   StringRef FunctionName;
1124   if (Function) {
1125     Expected<StringRef> FunctionNameOrErr = Function->getName();
1126     if (!FunctionNameOrErr) {
1127       std::string Buf;
1128       llvm::raw_string_ostream OS(Buf);
1129       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1130       report_fatal_error(Twine(OS.str()));
1131     }
1132     FunctionName = *FunctionNameOrErr;
1133   }
1134 
1135   SW.printString("Function",
1136                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1137   SW.printBoolean("Fragment",
1138                   RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
1139   SW.printNumber("FunctionLength", RF.FunctionLength());
1140   SW.startLine() << "ReturnType: " << RF.Ret() << '\n';
1141   SW.printBoolean("HomedParameters", RF.H());
1142   SW.printNumber("Reg", RF.Reg());
1143   SW.printNumber("R", RF.R());
1144   SW.printBoolean("LinkRegister", RF.L());
1145   SW.printBoolean("Chaining", RF.C());
1146   SW.printNumber("StackAdjustment", StackAdjustment(RF) << 2);
1147 
1148   {
1149     ListScope PS(SW, "Prologue");
1150 
1151     uint16_t GPRMask, VFPMask;
1152     std::tie(GPRMask, VFPMask) = SavedRegisterMask(RF, /*Prologue=*/true);
1153 
1154     if (StackAdjustment(RF) && !PrologueFolding(RF))
1155       SW.startLine() << "sub sp, sp, #" << StackAdjustment(RF) * 4 << "\n";
1156     if (VFPMask) {
1157       SW.startLine() << "vpush ";
1158       printVFPMask(VFPMask);
1159       OS << "\n";
1160     }
1161     if (RF.C()) {
1162       // Count the number of registers pushed below R11
1163       int FpOffset = 4 * countPopulation(GPRMask & ((1U << 11) - 1));
1164       if (FpOffset)
1165         SW.startLine() << "add.w r11, sp, #" << FpOffset << "\n";
1166       else
1167         SW.startLine() << "mov r11, sp\n";
1168     }
1169     if (GPRMask) {
1170       SW.startLine() << "push ";
1171       printGPRMask(GPRMask);
1172       OS << "\n";
1173     }
1174     if (RF.H())
1175       SW.startLine() << "push {r0-r3}\n";
1176   }
1177 
1178   if (RF.Ret() != ReturnType::RT_NoEpilogue) {
1179     ListScope PS(SW, "Epilogue");
1180 
1181     uint16_t GPRMask, VFPMask;
1182     std::tie(GPRMask, VFPMask) = SavedRegisterMask(RF, /*Prologue=*/false);
1183 
1184     if (StackAdjustment(RF) && !EpilogueFolding(RF))
1185       SW.startLine() << "add sp, sp, #" << StackAdjustment(RF) * 4 << "\n";
1186     if (VFPMask) {
1187       SW.startLine() << "vpop ";
1188       printVFPMask(VFPMask);
1189       OS << "\n";
1190     }
1191     if (GPRMask) {
1192       SW.startLine() << "pop ";
1193       printGPRMask(GPRMask);
1194       OS << "\n";
1195     }
1196     if (RF.H()) {
1197       if (RF.L() == 0 || RF.Ret() != ReturnType::RT_POP)
1198         SW.startLine() << "add sp, sp, #16\n";
1199       else
1200         SW.startLine() << "ldr pc, [sp], #20\n";
1201     }
1202     if (RF.Ret() != ReturnType::RT_POP)
1203       SW.startLine() << RF.Ret() << '\n';
1204   }
1205 
1206   return true;
1207 }
1208 
1209 bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
1210                                    const SectionRef Section, uint64_t Offset,
1211                                    unsigned Index,
1212                                    const RuntimeFunctionARM64 &RF) {
1213   assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
1214           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
1215          "unpacked entry cannot be treated as a packed entry");
1216 
1217   uint64_t FunctionAddress, FunctionOffset;
1218   ErrorOr<SymbolRef> Function = getSymbolForLocation(
1219       COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
1220       /*FunctionOnly=*/true);
1221 
1222   StringRef FunctionName;
1223   if (Function) {
1224     Expected<StringRef> FunctionNameOrErr = Function->getName();
1225     if (!FunctionNameOrErr) {
1226       std::string Buf;
1227       llvm::raw_string_ostream OS(Buf);
1228       logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
1229       report_fatal_error(Twine(OS.str()));
1230     }
1231     FunctionName = *FunctionNameOrErr;
1232   }
1233 
1234   SW.printString("Function",
1235                  formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
1236   SW.printBoolean("Fragment",
1237                   RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
1238   SW.printNumber("FunctionLength", RF.FunctionLength());
1239   SW.printNumber("RegF", RF.RegF());
1240   SW.printNumber("RegI", RF.RegI());
1241   SW.printBoolean("HomedParameters", RF.H());
1242   SW.printNumber("CR", RF.CR());
1243   SW.printNumber("FrameSize", RF.FrameSize() << 4);
1244   ListScope PS(SW, "Prologue");
1245 
1246   // Synthesize the equivalent prologue according to the documentation
1247   // at https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling,
1248   // printed in reverse order compared to the docs, to match how prologues
1249   // are printed for the non-packed case.
1250   int IntSZ = 8 * RF.RegI();
1251   if (RF.CR() == 1)
1252     IntSZ += 8;
1253   int FpSZ = 8 * RF.RegF();
1254   if (RF.RegF())
1255     FpSZ += 8;
1256   int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf;
1257   int LocSZ = (RF.FrameSize() << 4) - SavSZ;
1258 
1259   if (RF.CR() == 3) {
1260     SW.startLine() << "mov x29, sp\n";
1261     if (LocSZ <= 512) {
1262       SW.startLine() << format("stp x29, lr, [sp, #-%d]!\n", LocSZ);
1263     } else {
1264       SW.startLine() << "stp x29, lr, [sp, #0]\n";
1265     }
1266   }
1267   if (LocSZ > 4080) {
1268     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ - 4080);
1269     SW.startLine() << "sub sp, sp, #4080\n";
1270   } else if ((RF.CR() != 3 && LocSZ > 0) || LocSZ > 512) {
1271     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ);
1272   }
1273   if (RF.H()) {
1274     SW.startLine() << format("stp x6, x7, [sp, #%d]\n", SavSZ - 16);
1275     SW.startLine() << format("stp x4, x5, [sp, #%d]\n", SavSZ - 32);
1276     SW.startLine() << format("stp x2, x3, [sp, #%d]\n", SavSZ - 48);
1277     if (RF.RegI() > 0 || RF.RegF() > 0 || RF.CR() == 1) {
1278       SW.startLine() << format("stp x0, x1, [sp, #%d]\n", SavSZ - 64);
1279     } else {
1280       // This case isn't documented; if neither RegI nor RegF nor CR=1
1281       // have decremented the stack pointer by SavSZ, we need to do it here
1282       // (as the final stack adjustment of LocSZ excludes SavSZ).
1283       SW.startLine() << format("stp x0, x1, [sp, #-%d]!\n", SavSZ);
1284     }
1285   }
1286   int FloatRegs = RF.RegF() > 0 ? RF.RegF() + 1 : 0;
1287   for (int I = (FloatRegs + 1) / 2 - 1; I >= 0; I--) {
1288     if (I == (FloatRegs + 1) / 2 - 1 && FloatRegs % 2 == 1) {
1289       // The last register, an odd register without a pair
1290       SW.startLine() << format("str d%d, [sp, #%d]\n", 8 + 2 * I,
1291                                IntSZ + 16 * I);
1292     } else if (I == 0 && RF.RegI() == 0 && RF.CR() != 1) {
1293       SW.startLine() << format("stp d%d, d%d, [sp, #-%d]!\n", 8 + 2 * I,
1294                                8 + 2 * I + 1, SavSZ);
1295     } else {
1296       SW.startLine() << format("stp d%d, d%d, [sp, #%d]\n", 8 + 2 * I,
1297                                8 + 2 * I + 1, IntSZ + 16 * I);
1298     }
1299   }
1300   if (RF.CR() == 1 && (RF.RegI() % 2) == 0) {
1301     if (RF.RegI() == 0)
1302       SW.startLine() << format("str lr, [sp, #-%d]!\n", SavSZ);
1303     else
1304       SW.startLine() << format("str lr, [sp, #%d]\n", IntSZ - 8);
1305   }
1306   for (int I = (RF.RegI() + 1) / 2 - 1; I >= 0; I--) {
1307     if (I == (RF.RegI() + 1) / 2 - 1 && RF.RegI() % 2 == 1) {
1308       // The last register, an odd register without a pair
1309       if (RF.CR() == 1) {
1310         if (I == 0) { // If this is the only register pair
1311           // CR=1 combined with RegI=1 doesn't map to a documented case;
1312           // it doesn't map to any regular unwind info opcode, and the
1313           // actual unwinder doesn't support it.
1314           SW.startLine() << "INVALID!\n";
1315         } else
1316           SW.startLine() << format("stp x%d, lr, [sp, #%d]\n", 19 + 2 * I,
1317                                    16 * I);
1318       } else {
1319         if (I == 0)
1320           SW.startLine() << format("str x%d, [sp, #-%d]!\n", 19 + 2 * I, SavSZ);
1321         else
1322           SW.startLine() << format("str x%d, [sp, #%d]\n", 19 + 2 * I, 16 * I);
1323       }
1324     } else if (I == 0) {
1325       // The first register pair
1326       SW.startLine() << format("stp x19, x20, [sp, #-%d]!\n", SavSZ);
1327     } else {
1328       SW.startLine() << format("stp x%d, x%d, [sp, #%d]\n", 19 + 2 * I,
1329                                19 + 2 * I + 1, 16 * I);
1330     }
1331   }
1332   SW.startLine() << "end\n";
1333 
1334   return true;
1335 }
1336 
1337 bool Decoder::dumpProcedureDataEntry(const COFFObjectFile &COFF,
1338                                      const SectionRef Section, unsigned Index,
1339                                      ArrayRef<uint8_t> Contents) {
1340   uint64_t Offset = PDataEntrySize * Index;
1341   const ulittle32_t *Data =
1342     reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
1343 
1344   const RuntimeFunction Entry(Data);
1345   DictScope RFS(SW, "RuntimeFunction");
1346   if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
1347     return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
1348   if (isAArch64) {
1349     const RuntimeFunctionARM64 EntryARM64(Data);
1350     return dumpPackedARM64Entry(COFF, Section, Offset, Index, EntryARM64);
1351   }
1352   return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
1353 }
1354 
1355 void Decoder::dumpProcedureData(const COFFObjectFile &COFF,
1356                                 const SectionRef Section) {
1357   ArrayRef<uint8_t> Contents;
1358   if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
1359     return;
1360 
1361   if (Contents.size() % PDataEntrySize) {
1362     errs() << ".pdata content is not " << PDataEntrySize << "-byte aligned\n";
1363     return;
1364   }
1365 
1366   for (unsigned EI = 0, EE = Contents.size() / PDataEntrySize; EI < EE; ++EI)
1367     if (!dumpProcedureDataEntry(COFF, Section, EI, Contents))
1368       break;
1369 }
1370 
1371 Error Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
1372   for (const auto &Section : COFF.sections()) {
1373     Expected<StringRef> NameOrErr =
1374         COFF.getSectionName(COFF.getCOFFSection(Section));
1375     if (!NameOrErr)
1376       return NameOrErr.takeError();
1377 
1378     if (NameOrErr->startswith(".pdata"))
1379       dumpProcedureData(COFF, Section);
1380   }
1381   return Error::success();
1382 }
1383 }
1384 }
1385 }
1386