22 static const char *
const Names[] = {
23 "RAX",
"RCX",
"RDX",
"RBX",
"RSP",
"RBP",
"RSI",
"RDI",
24 "R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15",
25 "R16",
"R17",
"R18",
"R19",
"R20",
"R21",
"R22",
"R23",
26 "R24",
"R25",
"R26",
"R27",
"R28",
"R29",
"R30",
"R31",
28 if (Reg >= std::size(Names))
48 uint8_t Low3 = FirstByte & 0x07;
56 W.Register = (FirstByte >> 3) & 0x1F;
65 W.Register = (FirstByte >> 3) & 0x1F;
75 W.Register = (FirstByte >> 3) & 0x1F;
83 W.Register = (FirstByte >> 3) & 0x1F;
86 "WOD_PUSH_CONSECUTIVE_2 Register=%u out of range [0,30] at pool "
98 uint8_t Low4 = FirstByte & 0x0F;
104 W.Size = (
unsigned)(((FirstByte >> 4) & 0x0F) + 1) * 8;
113 W.Register = (FirstByte >> 4) & 0x0F;
123 W.Register = (FirstByte >> 4) & 0x0F;
135 uint8_t Low6 = FirstByte & 0x3F;
144 W.Register = ((FirstByte >> 6) & 0x03) | ((SecondByte & 0x07) << 2);
145 W.Register2 = (SecondByte >> 3) & 0x1F;
157 W.Register = SecondByte & 0x0F;
158 W.Displacement = (
unsigned)((SecondByte >> 4) & 0x0F) * 16;
183 "WOD_PUSH_CANONICAL_FRAME truncated at offset %u",
Offset);
184 W.Type = Pool[
Offset + 1];
201 Info.Flags = (
Data[0] >> 3) & 0x1F;
202 Info.SizeOfProlog =
Data[1];
203 Info.PayloadWords =
Data[2];
204 Info.NumberOfOps =
Data[3] & 0x1F;
205 Info.NumberOfEpilogs = (
Data[3] >> 5) & 0x07;
218 unsigned PayloadEnd = 4 + Info.PayloadWords * 2;
219 if (PayloadEnd >
Data.size())
221 "V3 unwind info PayloadWords (%u) extends past end of buffer",
224 bool IsLarge = Info.isLarge();
228 "V3 unwind info with UNW_FlagLarge too short: PayloadWords (%u) "
229 "leaves no room for UNWIND_INFO_LARGE_V3",
236 for (
unsigned I = 0;
I < Info.NumberOfOps; ++
I) {
238 if (
Offset + 2 > PayloadEnd)
240 "V3 payload truncated reading prolog IP offset %u",
I);
246 "V3 payload truncated reading prolog IP offset %u",
I);
247 Info.PrologIpOffsets.push_back(
Data[
Offset++]);
252 int32_t PrevResolvedOffset = 0;
253 for (
unsigned I = 0;
I < Info.NumberOfEpilogs; ++
I) {
257 "V3 payload truncated reading epilog %u FlagsAndNumOps",
I);
259 Epi.
Flags = FlagsAndNumOps & 0x07;
262 if (
Offset + 2 > PayloadEnd)
264 "V3 payload truncated reading epilog %u EpilogOffset",
I);
290 if (!Info.Epilogs.empty()) {
304 Info.Epilogs.push_back(std::move(Epi));
310 if (
Offset + 2 > PayloadEnd)
318 if (
Offset + 2 > PayloadEnd)
320 "V3 payload truncated reading epilog %u IpOffsetOfLastInstruction",
327 "V3 payload truncated reading epilog %u IpOffsetOfLastInstruction",
335 if (
Offset + 2 > PayloadEnd)
337 "V3 payload truncated reading epilog %u IP offset %u",
I, J);
343 "V3 payload truncated reading epilog %u IP offset %u",
I, J);
348 Info.Epilogs.push_back(std::move(Epi));
361 Info.PayloadSize =
alignTo(PayloadEnd, 4);
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Tagged union holding either a T or a Error.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
StringRef getRegisterNameV3(unsigned Reg)
Return the register name for a 5-bit AMD64 integer register number.
Expected< DecodedWOD > decodeWOD(ArrayRef< uint8_t > Pool, unsigned Offset)
Decode one WOD from the pool at the given byte offset.
@ WOD_PUSH_CANONICAL_FRAME
Expected< DecodedUnwindInfoV3 > decodeUnwindInfoV3(ArrayRef< uint8_t > Data)
Parse a V3 UNWIND_INFO from raw bytes.
uint16_t read16le(const void *P)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Decoded V3 epilog descriptor.
uint16_t IpOffsetOfLastInstruction
bool isLarge() const
Whether the EPILOG_INFO_LARGE flag is set.
SmallVector< uint16_t, 8 > IpOffsets
Decoded V3 Winding Operation Descriptor.