xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===--- ARMWinEHPrinter.h - Windows on ARM Unwind Information Printer ----===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
10*0b57cec5SDimitry Andric #define LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
11*0b57cec5SDimitry Andric 
12*0b57cec5SDimitry Andric #include "llvm/Object/COFF.h"
13*0b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h"
14*0b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric namespace llvm {
17*0b57cec5SDimitry Andric namespace ARM {
18*0b57cec5SDimitry Andric namespace WinEH {
19*0b57cec5SDimitry Andric class RuntimeFunction;
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric class Decoder {
22*0b57cec5SDimitry Andric   static const size_t PDataEntrySize;
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric   ScopedPrinter &SW;
25*0b57cec5SDimitry Andric   raw_ostream &OS;
26*0b57cec5SDimitry Andric   bool isAArch64;
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric   struct RingEntry {
29*0b57cec5SDimitry Andric     uint8_t Mask;
30*0b57cec5SDimitry Andric     uint8_t Value;
31*0b57cec5SDimitry Andric     uint8_t Length;
32*0b57cec5SDimitry Andric     bool (Decoder::*Routine)(const uint8_t *, unsigned &, unsigned, bool);
33*0b57cec5SDimitry Andric   };
34*0b57cec5SDimitry Andric   static const RingEntry Ring[];
35*0b57cec5SDimitry Andric   static const RingEntry Ring64[];
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric   bool opcode_0xxxxxxx(const uint8_t *Opcodes, unsigned &Offset,
38*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
39*0b57cec5SDimitry Andric   bool opcode_10Lxxxxx(const uint8_t *Opcodes, unsigned &Offset,
40*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
41*0b57cec5SDimitry Andric   bool opcode_1100xxxx(const uint8_t *Opcodes, unsigned &Offset,
42*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
43*0b57cec5SDimitry Andric   bool opcode_11010Lxx(const uint8_t *Opcodes, unsigned &Offset,
44*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
45*0b57cec5SDimitry Andric   bool opcode_11011Lxx(const uint8_t *Opcodes, unsigned &Offset,
46*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
47*0b57cec5SDimitry Andric   bool opcode_11100xxx(const uint8_t *Opcodes, unsigned &Offset,
48*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
49*0b57cec5SDimitry Andric   bool opcode_111010xx(const uint8_t *Opcodes, unsigned &Offset,
50*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
51*0b57cec5SDimitry Andric   bool opcode_1110110L(const uint8_t *Opcodes, unsigned &Offset,
52*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
53*0b57cec5SDimitry Andric   bool opcode_11101110(const uint8_t *Opcodes, unsigned &Offset,
54*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
55*0b57cec5SDimitry Andric   bool opcode_11101111(const uint8_t *Opcodes, unsigned &Offset,
56*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
57*0b57cec5SDimitry Andric   bool opcode_11110101(const uint8_t *Opcodes, unsigned &Offset,
58*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
59*0b57cec5SDimitry Andric   bool opcode_11110110(const uint8_t *Opcodes, unsigned &Offset,
60*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
61*0b57cec5SDimitry Andric   bool opcode_11110111(const uint8_t *Opcodes, unsigned &Offset,
62*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
63*0b57cec5SDimitry Andric   bool opcode_11111000(const uint8_t *Opcodes, unsigned &Offset,
64*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
65*0b57cec5SDimitry Andric   bool opcode_11111001(const uint8_t *Opcodes, unsigned &Offset,
66*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
67*0b57cec5SDimitry Andric   bool opcode_11111010(const uint8_t *Opcodes, unsigned &Offset,
68*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
69*0b57cec5SDimitry Andric   bool opcode_11111011(const uint8_t *Opcodes, unsigned &Offset,
70*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
71*0b57cec5SDimitry Andric   bool opcode_11111100(const uint8_t *Opcodes, unsigned &Offset,
72*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
73*0b57cec5SDimitry Andric   bool opcode_11111101(const uint8_t *Opcodes, unsigned &Offset,
74*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
75*0b57cec5SDimitry Andric   bool opcode_11111110(const uint8_t *Opcodes, unsigned &Offset,
76*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
77*0b57cec5SDimitry Andric   bool opcode_11111111(const uint8_t *Opcodes, unsigned &Offset,
78*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
79*0b57cec5SDimitry Andric 
80*0b57cec5SDimitry Andric   // ARM64 unwind codes start here.
81*0b57cec5SDimitry Andric   bool opcode_alloc_s(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
82*0b57cec5SDimitry Andric                       bool Prologue);
83*0b57cec5SDimitry Andric   bool opcode_save_r19r20_x(const uint8_t *Opcodes, unsigned &Offset,
84*0b57cec5SDimitry Andric                             unsigned Length, bool Prologue);
85*0b57cec5SDimitry Andric   bool opcode_save_fplr(const uint8_t *Opcodes, unsigned &Offset,
86*0b57cec5SDimitry Andric                         unsigned Length, bool Prologue);
87*0b57cec5SDimitry Andric   bool opcode_save_fplr_x(const uint8_t *Opcodes, unsigned &Offset,
88*0b57cec5SDimitry Andric                           unsigned Length, bool Prologue);
89*0b57cec5SDimitry Andric   bool opcode_alloc_m(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
90*0b57cec5SDimitry Andric                       bool Prologue);
91*0b57cec5SDimitry Andric   bool opcode_save_regp(const uint8_t *Opcodes, unsigned &Offset,
92*0b57cec5SDimitry Andric                         unsigned Length, bool Prologue);
93*0b57cec5SDimitry Andric   bool opcode_save_regp_x(const uint8_t *Opcodes, unsigned &Offset,
94*0b57cec5SDimitry Andric                           unsigned Length, bool Prologue);
95*0b57cec5SDimitry Andric   bool opcode_save_reg(const uint8_t *Opcodes, unsigned &Offset,
96*0b57cec5SDimitry Andric                        unsigned Length, bool Prologue);
97*0b57cec5SDimitry Andric   bool opcode_save_reg_x(const uint8_t *Opcodes, unsigned &Offset,
98*0b57cec5SDimitry Andric                          unsigned Length, bool Prologue);
99*0b57cec5SDimitry Andric   bool opcode_save_lrpair(const uint8_t *Opcodes, unsigned &Offset,
100*0b57cec5SDimitry Andric                           unsigned Length, bool Prologue);
101*0b57cec5SDimitry Andric   bool opcode_save_fregp(const uint8_t *Opcodes, unsigned &Offset,
102*0b57cec5SDimitry Andric                          unsigned Length, bool Prologue);
103*0b57cec5SDimitry Andric   bool opcode_save_fregp_x(const uint8_t *Opcodes, unsigned &Offset,
104*0b57cec5SDimitry Andric                            unsigned Length, bool Prologue);
105*0b57cec5SDimitry Andric   bool opcode_save_freg(const uint8_t *Opcodes, unsigned &Offset,
106*0b57cec5SDimitry Andric                         unsigned Length, bool Prologue);
107*0b57cec5SDimitry Andric   bool opcode_save_freg_x(const uint8_t *Opcodes, unsigned &Offset,
108*0b57cec5SDimitry Andric                           unsigned Length, bool Prologue);
109*0b57cec5SDimitry Andric   bool opcode_alloc_l(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
110*0b57cec5SDimitry Andric                       bool Prologue);
111*0b57cec5SDimitry Andric   bool opcode_setfp(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
112*0b57cec5SDimitry Andric                     bool Prologue);
113*0b57cec5SDimitry Andric   bool opcode_addfp(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
114*0b57cec5SDimitry Andric                     bool Prologue);
115*0b57cec5SDimitry Andric   bool opcode_nop(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
116*0b57cec5SDimitry Andric                   bool Prologue);
117*0b57cec5SDimitry Andric   bool opcode_end(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
118*0b57cec5SDimitry Andric                   bool Prologue);
119*0b57cec5SDimitry Andric   bool opcode_end_c(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
120*0b57cec5SDimitry Andric                     bool Prologue);
121*0b57cec5SDimitry Andric   bool opcode_save_next(const uint8_t *Opcodes, unsigned &Offset,
122*0b57cec5SDimitry Andric                         unsigned Length, bool Prologue);
123*0b57cec5SDimitry Andric 
124*0b57cec5SDimitry Andric   void decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
125*0b57cec5SDimitry Andric                      bool Prologue);
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric   void printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask);
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric   ErrorOr<object::SectionRef>
130*0b57cec5SDimitry Andric   getSectionContaining(const object::COFFObjectFile &COFF, uint64_t Address);
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric   ErrorOr<object::SymbolRef>
133*0b57cec5SDimitry Andric   getSymbol(const object::COFFObjectFile &COFF, uint64_t Address,
134*0b57cec5SDimitry Andric             bool FunctionOnly = false);
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric   ErrorOr<object::SymbolRef>
137*0b57cec5SDimitry Andric   getRelocatedSymbol(const object::COFFObjectFile &COFF,
138*0b57cec5SDimitry Andric                      const object::SectionRef &Section, uint64_t Offset);
139*0b57cec5SDimitry Andric 
140*0b57cec5SDimitry Andric   bool dumpXDataRecord(const object::COFFObjectFile &COFF,
141*0b57cec5SDimitry Andric                        const object::SectionRef &Section,
142*0b57cec5SDimitry Andric                        uint64_t FunctionAddress, uint64_t VA);
143*0b57cec5SDimitry Andric   bool dumpUnpackedEntry(const object::COFFObjectFile &COFF,
144*0b57cec5SDimitry Andric                          const object::SectionRef Section, uint64_t Offset,
145*0b57cec5SDimitry Andric                          unsigned Index, const RuntimeFunction &Entry);
146*0b57cec5SDimitry Andric   bool dumpPackedEntry(const object::COFFObjectFile &COFF,
147*0b57cec5SDimitry Andric                        const object::SectionRef Section, uint64_t Offset,
148*0b57cec5SDimitry Andric                        unsigned Index, const RuntimeFunction &Entry);
149*0b57cec5SDimitry Andric   bool dumpProcedureDataEntry(const object::COFFObjectFile &COFF,
150*0b57cec5SDimitry Andric                               const object::SectionRef Section, unsigned Entry,
151*0b57cec5SDimitry Andric                               ArrayRef<uint8_t> Contents);
152*0b57cec5SDimitry Andric   void dumpProcedureData(const object::COFFObjectFile &COFF,
153*0b57cec5SDimitry Andric                          const object::SectionRef Section);
154*0b57cec5SDimitry Andric 
155*0b57cec5SDimitry Andric public:
156*0b57cec5SDimitry Andric   Decoder(ScopedPrinter &SW, bool isAArch64) : SW(SW),
157*0b57cec5SDimitry Andric                                                OS(SW.getOStream()),
158*0b57cec5SDimitry Andric                                                isAArch64(isAArch64) {}
159*0b57cec5SDimitry Andric   Error dumpProcedureData(const object::COFFObjectFile &COFF);
160*0b57cec5SDimitry Andric };
161*0b57cec5SDimitry Andric }
162*0b57cec5SDimitry Andric }
163*0b57cec5SDimitry Andric }
164*0b57cec5SDimitry Andric 
165*0b57cec5SDimitry Andric #endif
166