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_clear_unwound_to_call(const uint8_t *Opcodes
, unsigned &Offset
,
133 unsigned Length
, bool Prologue
);
134 bool opcode_pac_sign_lr(const uint8_t *Opcodes
, unsigned &Offset
,
135 unsigned Length
, bool Prologue
);
137 void decodeOpcodes(ArrayRef
<uint8_t> Opcodes
, unsigned Offset
,
140 void printGPRMask(uint16_t Mask
);
141 void printVFPMask(uint32_t Mask
);
143 ErrorOr
<object::SectionRef
>
144 getSectionContaining(const object::COFFObjectFile
&COFF
, uint64_t Address
);
146 ErrorOr
<object::SymbolRef
>
147 getSymbol(const object::COFFObjectFile
&COFF
, uint64_t Address
,
148 bool FunctionOnly
= false);
150 ErrorOr
<object::SymbolRef
>
151 getRelocatedSymbol(const object::COFFObjectFile
&COFF
,
152 const object::SectionRef
&Section
, uint64_t Offset
);
154 ErrorOr
<object::SymbolRef
>
155 getSymbolForLocation(const object::COFFObjectFile
&COFF
,
156 const object::SectionRef
&Section
,
157 uint64_t OffsetInSection
, uint64_t ImmediateOffset
,
158 uint64_t &SymbolAddress
, uint64_t &SymbolOffset
,
159 bool FunctionOnly
= false);
161 object::SymbolRef
getPreferredSymbol(const object::COFFObjectFile
&COFF
,
162 object::SymbolRef Sym
,
163 uint64_t &SymbolOffset
);
165 bool dumpXDataRecord(const object::COFFObjectFile
&COFF
,
166 const object::SectionRef
&Section
,
167 uint64_t FunctionAddress
, uint64_t VA
);
168 bool dumpUnpackedEntry(const object::COFFObjectFile
&COFF
,
169 const object::SectionRef Section
, uint64_t Offset
,
170 unsigned Index
, const RuntimeFunction
&Entry
);
171 bool dumpPackedEntry(const object::COFFObjectFile
&COFF
,
172 const object::SectionRef Section
, uint64_t Offset
,
173 unsigned Index
, const RuntimeFunction
&Entry
);
174 bool dumpPackedARM64Entry(const object::COFFObjectFile
&COFF
,
175 const object::SectionRef Section
, uint64_t Offset
,
176 unsigned Index
, const RuntimeFunctionARM64
&Entry
);
177 bool dumpProcedureDataEntry(const object::COFFObjectFile
&COFF
,
178 const object::SectionRef Section
, unsigned Entry
,
179 ArrayRef
<uint8_t> Contents
);
180 void dumpProcedureData(const object::COFFObjectFile
&COFF
,
181 const object::SectionRef Section
);
184 Decoder(ScopedPrinter
&SW
, bool isAArch64
) : SW(SW
),
186 isAArch64(isAArch64
) {}
187 Error
dumpProcedureData(const object::COFFObjectFile
&COFF
);