1 //===--- ARMWinEHPrinter.h - Windows on ARM Unwind Information Printer ----===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
10 #define LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
12 #include "llvm/Object/COFF.h"
13 #include "llvm/Support/ErrorOr.h"
14 #include "llvm/Support/ScopedPrinter.h"
19 class RuntimeFunction
;
20 class RuntimeFunctionARM64
;
23 static const size_t PDataEntrySize
;
33 bool (Decoder::*Routine
)(const uint8_t *, unsigned &, unsigned, bool);
35 static const RingEntry Ring
[];
36 static const RingEntry Ring64
[];
38 bool opcode_0xxxxxxx(const uint8_t *Opcodes
, unsigned &Offset
,
39 unsigned Length
, bool Prologue
);
40 bool opcode_10Lxxxxx(const uint8_t *Opcodes
, unsigned &Offset
,
41 unsigned Length
, bool Prologue
);
42 bool opcode_1100xxxx(const uint8_t *Opcodes
, unsigned &Offset
,
43 unsigned Length
, bool Prologue
);
44 bool opcode_11010Lxx(const uint8_t *Opcodes
, unsigned &Offset
,
45 unsigned Length
, bool Prologue
);
46 bool opcode_11011Lxx(const uint8_t *Opcodes
, unsigned &Offset
,
47 unsigned Length
, bool Prologue
);
48 bool opcode_11100xxx(const uint8_t *Opcodes
, unsigned &Offset
,
49 unsigned Length
, bool Prologue
);
50 bool opcode_111010xx(const uint8_t *Opcodes
, unsigned &Offset
,
51 unsigned Length
, bool Prologue
);
52 bool opcode_1110110L(const uint8_t *Opcodes
, unsigned &Offset
,
53 unsigned Length
, bool Prologue
);
54 bool opcode_11101110(const uint8_t *Opcodes
, unsigned &Offset
,
55 unsigned Length
, bool Prologue
);
56 bool opcode_11101111(const uint8_t *Opcodes
, unsigned &Offset
,
57 unsigned Length
, bool Prologue
);
58 bool opcode_11110101(const uint8_t *Opcodes
, unsigned &Offset
,
59 unsigned Length
, bool Prologue
);
60 bool opcode_11110110(const uint8_t *Opcodes
, unsigned &Offset
,
61 unsigned Length
, bool Prologue
);
62 bool opcode_11110111(const uint8_t *Opcodes
, unsigned &Offset
,
63 unsigned Length
, bool Prologue
);
64 bool opcode_11111000(const uint8_t *Opcodes
, unsigned &Offset
,
65 unsigned Length
, bool Prologue
);
66 bool opcode_11111001(const uint8_t *Opcodes
, unsigned &Offset
,
67 unsigned Length
, bool Prologue
);
68 bool opcode_11111010(const uint8_t *Opcodes
, unsigned &Offset
,
69 unsigned Length
, bool Prologue
);
70 bool opcode_11111011(const uint8_t *Opcodes
, unsigned &Offset
,
71 unsigned Length
, bool Prologue
);
72 bool opcode_11111100(const uint8_t *Opcodes
, unsigned &Offset
,
73 unsigned Length
, bool Prologue
);
74 bool opcode_11111101(const uint8_t *Opcodes
, unsigned &Offset
,
75 unsigned Length
, bool Prologue
);
76 bool opcode_11111110(const uint8_t *Opcodes
, unsigned &Offset
,
77 unsigned Length
, bool Prologue
);
78 bool opcode_11111111(const uint8_t *Opcodes
, unsigned &Offset
,
79 unsigned Length
, bool Prologue
);
81 // ARM64 unwind codes start here.
82 bool opcode_alloc_s(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
84 bool opcode_save_r19r20_x(const uint8_t *Opcodes
, unsigned &Offset
,
85 unsigned Length
, bool Prologue
);
86 bool opcode_save_fplr(const uint8_t *Opcodes
, unsigned &Offset
,
87 unsigned Length
, bool Prologue
);
88 bool opcode_save_fplr_x(const uint8_t *Opcodes
, unsigned &Offset
,
89 unsigned Length
, bool Prologue
);
90 bool opcode_alloc_m(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
92 bool opcode_save_regp(const uint8_t *Opcodes
, unsigned &Offset
,
93 unsigned Length
, bool Prologue
);
94 bool opcode_save_regp_x(const uint8_t *Opcodes
, unsigned &Offset
,
95 unsigned Length
, bool Prologue
);
96 bool opcode_save_reg(const uint8_t *Opcodes
, unsigned &Offset
,
97 unsigned Length
, bool Prologue
);
98 bool opcode_save_reg_x(const uint8_t *Opcodes
, unsigned &Offset
,
99 unsigned Length
, bool Prologue
);
100 bool opcode_save_lrpair(const uint8_t *Opcodes
, unsigned &Offset
,
101 unsigned Length
, bool Prologue
);
102 bool opcode_save_fregp(const uint8_t *Opcodes
, unsigned &Offset
,
103 unsigned Length
, bool Prologue
);
104 bool opcode_save_fregp_x(const uint8_t *Opcodes
, unsigned &Offset
,
105 unsigned Length
, bool Prologue
);
106 bool opcode_save_freg(const uint8_t *Opcodes
, unsigned &Offset
,
107 unsigned Length
, bool Prologue
);
108 bool opcode_save_freg_x(const uint8_t *Opcodes
, unsigned &Offset
,
109 unsigned Length
, bool Prologue
);
110 bool opcode_alloc_l(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
112 bool opcode_setfp(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
114 bool opcode_addfp(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
116 bool opcode_nop(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
118 bool opcode_end(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
120 bool opcode_end_c(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
122 bool opcode_save_next(const uint8_t *Opcodes
, unsigned &Offset
,
123 unsigned Length
, bool Prologue
);
124 bool opcode_save_any_reg(const uint8_t *Opcodes
, unsigned &Offset
,
125 unsigned Length
, bool Prologue
);
126 bool opcode_trap_frame(const uint8_t *Opcodes
, unsigned &Offset
,
127 unsigned Length
, bool Prologue
);
128 bool opcode_machine_frame(const uint8_t *Opcodes
, unsigned &Offset
,
129 unsigned Length
, bool Prologue
);
130 bool opcode_context(const uint8_t *Opcodes
, unsigned &Offset
, unsigned Length
,
132 bool opcode_ec_context(const uint8_t *Opcodes
, unsigned &Offset
,
133 unsigned Length
, bool Prologue
);
134 bool opcode_clear_unwound_to_call(const uint8_t *Opcodes
, unsigned &Offset
,
135 unsigned Length
, bool Prologue
);
136 bool opcode_pac_sign_lr(const uint8_t *Opcodes
, unsigned &Offset
,
137 unsigned Length
, bool Prologue
);
139 void decodeOpcodes(ArrayRef
<uint8_t> Opcodes
, unsigned Offset
,
142 void printGPRMask(uint16_t Mask
);
143 void printVFPMask(uint32_t Mask
);
145 ErrorOr
<object::SectionRef
>
146 getSectionContaining(const object::COFFObjectFile
&COFF
, uint64_t Address
);
148 ErrorOr
<object::SymbolRef
>
149 getSymbol(const object::COFFObjectFile
&COFF
, uint64_t Address
,
150 bool FunctionOnly
= false);
152 ErrorOr
<object::SymbolRef
>
153 getRelocatedSymbol(const object::COFFObjectFile
&COFF
,
154 const object::SectionRef
&Section
, uint64_t Offset
);
156 ErrorOr
<object::SymbolRef
>
157 getSymbolForLocation(const object::COFFObjectFile
&COFF
,
158 const object::SectionRef
&Section
,
159 uint64_t OffsetInSection
, uint64_t ImmediateOffset
,
160 uint64_t &SymbolAddress
, uint64_t &SymbolOffset
,
161 bool FunctionOnly
= false);
163 object::SymbolRef
getPreferredSymbol(const object::COFFObjectFile
&COFF
,
164 object::SymbolRef Sym
,
165 uint64_t &SymbolOffset
);
167 bool dumpXDataRecord(const object::COFFObjectFile
&COFF
,
168 const object::SectionRef
&Section
,
169 uint64_t FunctionAddress
, uint64_t VA
);
170 bool dumpUnpackedEntry(const object::COFFObjectFile
&COFF
,
171 const object::SectionRef Section
, uint64_t Offset
,
172 unsigned Index
, const RuntimeFunction
&Entry
);
173 bool dumpPackedEntry(const object::COFFObjectFile
&COFF
,
174 const object::SectionRef Section
, uint64_t Offset
,
175 unsigned Index
, const RuntimeFunction
&Entry
);
176 bool dumpPackedARM64Entry(const object::COFFObjectFile
&COFF
,
177 const object::SectionRef Section
, uint64_t Offset
,
178 unsigned Index
, const RuntimeFunctionARM64
&Entry
);
179 bool dumpProcedureDataEntry(const object::COFFObjectFile
&COFF
,
180 const object::SectionRef Section
, unsigned Entry
,
181 ArrayRef
<uint8_t> Contents
);
182 void dumpProcedureData(const object::COFFObjectFile
&COFF
,
183 const object::SectionRef Section
);
186 Decoder(ScopedPrinter
&SW
, bool isAArch64
) : SW(SW
),
188 isAArch64(isAArch64
) {}
189 Error
dumpProcedureData(const object::COFFObjectFile
&COFF
);