summaryrefslogtreecommitdiff
path: root/src/jit/unwindamd64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/unwindamd64.cpp')
-rw-r--r--src/jit/unwindamd64.cpp488
1 files changed, 277 insertions, 211 deletions
diff --git a/src/jit/unwindamd64.cpp b/src/jit/unwindamd64.cpp
index 6c8833bfc0..89abdff2b3 100644
--- a/src/jit/unwindamd64.cpp
+++ b/src/jit/unwindamd64.cpp
@@ -24,40 +24,104 @@ int Compiler::mapRegNumToDwarfReg(regNumber reg)
switch (reg)
{
- case REG_RAX: dwarfReg = 0; break;
- case REG_RCX: dwarfReg = 2; break;
- case REG_RDX: dwarfReg = 1; break;
- case REG_RBX: dwarfReg = 3; break;
- case REG_RSP: dwarfReg = 7; break;
- case REG_RBP: dwarfReg = 6; break;
- case REG_RSI: dwarfReg = 4; break;
- case REG_RDI: dwarfReg = 5; break;
- case REG_R8: dwarfReg = 8; break;
- case REG_R9: dwarfReg = 9; break;
- case REG_R10: dwarfReg = 10; break;
- case REG_R11: dwarfReg = 11; break;
- case REG_R12: dwarfReg = 12; break;
- case REG_R13: dwarfReg = 13; break;
- case REG_R14: dwarfReg = 14; break;
- case REG_R15: dwarfReg = 15; break;
- case REG_XMM0: dwarfReg = 17; break;
- case REG_XMM1: dwarfReg = 18; break;
- case REG_XMM2: dwarfReg = 19; break;
- case REG_XMM3: dwarfReg = 20; break;
- case REG_XMM4: dwarfReg = 21; break;
- case REG_XMM5: dwarfReg = 22; break;
- case REG_XMM6: dwarfReg = 23; break;
- case REG_XMM7: dwarfReg = 24; break;
- case REG_XMM8: dwarfReg = 25; break;
- case REG_XMM9: dwarfReg = 26; break;
- case REG_XMM10:dwarfReg = 27; break;
- case REG_XMM11:dwarfReg = 28; break;
- case REG_XMM12:dwarfReg = 29; break;
- case REG_XMM13:dwarfReg = 30; break;
- case REG_XMM14:dwarfReg = 31; break;
- case REG_XMM15:dwarfReg = 32; break;
- default:
- noway_assert(!"unexpected REG_NUM");
+ case REG_RAX:
+ dwarfReg = 0;
+ break;
+ case REG_RCX:
+ dwarfReg = 2;
+ break;
+ case REG_RDX:
+ dwarfReg = 1;
+ break;
+ case REG_RBX:
+ dwarfReg = 3;
+ break;
+ case REG_RSP:
+ dwarfReg = 7;
+ break;
+ case REG_RBP:
+ dwarfReg = 6;
+ break;
+ case REG_RSI:
+ dwarfReg = 4;
+ break;
+ case REG_RDI:
+ dwarfReg = 5;
+ break;
+ case REG_R8:
+ dwarfReg = 8;
+ break;
+ case REG_R9:
+ dwarfReg = 9;
+ break;
+ case REG_R10:
+ dwarfReg = 10;
+ break;
+ case REG_R11:
+ dwarfReg = 11;
+ break;
+ case REG_R12:
+ dwarfReg = 12;
+ break;
+ case REG_R13:
+ dwarfReg = 13;
+ break;
+ case REG_R14:
+ dwarfReg = 14;
+ break;
+ case REG_R15:
+ dwarfReg = 15;
+ break;
+ case REG_XMM0:
+ dwarfReg = 17;
+ break;
+ case REG_XMM1:
+ dwarfReg = 18;
+ break;
+ case REG_XMM2:
+ dwarfReg = 19;
+ break;
+ case REG_XMM3:
+ dwarfReg = 20;
+ break;
+ case REG_XMM4:
+ dwarfReg = 21;
+ break;
+ case REG_XMM5:
+ dwarfReg = 22;
+ break;
+ case REG_XMM6:
+ dwarfReg = 23;
+ break;
+ case REG_XMM7:
+ dwarfReg = 24;
+ break;
+ case REG_XMM8:
+ dwarfReg = 25;
+ break;
+ case REG_XMM9:
+ dwarfReg = 26;
+ break;
+ case REG_XMM10:
+ dwarfReg = 27;
+ break;
+ case REG_XMM11:
+ dwarfReg = 28;
+ break;
+ case REG_XMM12:
+ dwarfReg = 29;
+ break;
+ case REG_XMM13:
+ dwarfReg = 30;
+ break;
+ case REG_XMM14:
+ dwarfReg = 31;
+ break;
+ case REG_XMM15:
+ dwarfReg = 32;
+ break;
+ default:
+ noway_assert(!"unexpected REG_NUM");
}
return dwarfReg;
@@ -131,18 +195,17 @@ void Compiler::unwindBegPrologWindows()
unwindGetFuncLocations(func, false, &func->coldStartLoc, &func->coldEndLoc);
}
- func->unwindCodeSlot = sizeof(func->unwindCodes);
- func->unwindHeader.Version = 1;
- func->unwindHeader.Flags = 0;
+ func->unwindCodeSlot = sizeof(func->unwindCodes);
+ func->unwindHeader.Version = 1;
+ func->unwindHeader.Flags = 0;
func->unwindHeader.CountOfUnwindCodes = 0;
- func->unwindHeader.FrameRegister = 0;
- func->unwindHeader.FrameOffset = 0;
+ func->unwindHeader.FrameRegister = 0;
+ func->unwindHeader.FrameOffset = 0;
}
#ifdef UNIX_AMD64_ABI
template <typename T>
-inline
-static T* allocate_any(jitstd::allocator<void>& alloc, size_t count = 5)
+inline static T* allocate_any(jitstd::allocator<void>& alloc, size_t count = 5)
{
return jitstd::allocator<T>(alloc).allocate(count);
}
@@ -174,7 +237,7 @@ void Compiler::unwindBegPrologCFI()
// Compiler::unwindEndProlog: Called at the end of main function or funclet
// prolog generation to indicate there is no more unwind information for this prolog.
//
-void Compiler::unwindEndProlog()
+void Compiler::unwindEndProlog()
{
assert(compGeneratingProlog);
}
@@ -223,10 +286,10 @@ void Compiler::unwindPushWindows(regNumber reg)
FuncInfoDsc* func = funCurrentFunc();
- assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
+ assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
assert(func->unwindHeader.CountOfUnwindCodes == 0); // Can't call this after unwindReserve
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
- UNWIND_CODE * code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
unsigned int cbProlog = unwindGetCurrentOffset(func);
noway_assert((BYTE)cbProlog == cbProlog);
code->CodeOffset = (BYTE)cbProlog;
@@ -239,16 +302,16 @@ void Compiler::unwindPushWindows(regNumber reg)
// since it is pushed as a frame register.
|| (reg == REG_FPBASE)
#endif // ETW_EBP_FRAMED
- )
+ )
{
code->UnwindOp = UWOP_PUSH_NONVOL;
- code->OpInfo = (BYTE)reg;
+ code->OpInfo = (BYTE)reg;
}
else
{
// Push of a volatile register is just a small stack allocation
code->UnwindOp = UWOP_ALLOC_SMALL;
- code->OpInfo = 0;
+ code->OpInfo = 0;
}
}
@@ -271,7 +334,7 @@ void Compiler::unwindPushCFI(regNumber reg)
// since it is pushed as a frame register.
|| (reg == REG_FPBASE)
#endif // ETW_EBP_FRAMED
- )
+ )
{
createCfiCode(func, cbProlog, CFI_REL_OFFSET, mapRegNumToDwarfReg(reg));
}
@@ -304,34 +367,34 @@ void Compiler::unwindAllocStackWindows(unsigned size)
FuncInfoDsc* func = funCurrentFunc();
- assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
+ assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
assert(func->unwindHeader.CountOfUnwindCodes == 0); // Can't call this after unwindReserve
- assert(size % 8 == 0); // Stack size is *always* 8 byte aligned
- UNWIND_CODE * code;
+ assert(size % 8 == 0); // Stack size is *always* 8 byte aligned
+ UNWIND_CODE* code;
if (size <= 128)
{
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
- code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
code->UnwindOp = UWOP_ALLOC_SMALL;
- code->OpInfo = (size - 8) / 8;
+ code->OpInfo = (size - 8) / 8;
}
else if (size <= 0x7FFF8)
{
assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(USHORT)));
- USHORT * codedSize = (USHORT*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(USHORT)];
- *codedSize = (USHORT)(size / 8);
- code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
- code->UnwindOp = UWOP_ALLOC_LARGE;
- code->OpInfo = 0;
+ USHORT* codedSize = (USHORT*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(USHORT)];
+ *codedSize = (USHORT)(size / 8);
+ code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ code->UnwindOp = UWOP_ALLOC_LARGE;
+ code->OpInfo = 0;
}
else
{
assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(ULONG)));
- ULONG * codedSize = (ULONG*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(ULONG)];
- *codedSize = size;
- code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
- code->UnwindOp = UWOP_ALLOC_LARGE;
- code->OpInfo = 1;
+ ULONG* codedSize = (ULONG*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(ULONG)];
+ *codedSize = size;
+ code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ code->UnwindOp = UWOP_ALLOC_LARGE;
+ code->OpInfo = 1;
}
unsigned int cbProlog = unwindGetCurrentOffset(func);
noway_assert((BYTE)cbProlog == cbProlog);
@@ -378,7 +441,7 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
FuncInfoDsc* func = funCurrentFunc();
- assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
+ assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
assert(func->unwindHeader.CountOfUnwindCodes == 0); // Can't call this after unwindReserve
unsigned int cbProlog = unwindGetCurrentOffset(func);
noway_assert((BYTE)cbProlog == cbProlog);
@@ -397,10 +460,10 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
assert(offset % 16 == 0);
*codedSize = offset / 16;
- UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
- code->CodeOffset = (BYTE)cbProlog;
- code->OpInfo = 0;
- code->UnwindOp = UWOP_SET_FPREG_LARGE;
+ UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ code->CodeOffset = (BYTE)cbProlog;
+ code->OpInfo = 0;
+ code->UnwindOp = UWOP_SET_FPREG_LARGE;
func->unwindHeader.FrameOffset = 15;
}
else
@@ -408,9 +471,9 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
{
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
- code->CodeOffset = (BYTE)cbProlog;
- code->OpInfo = 0;
- code->UnwindOp = UWOP_SET_FPREG;
+ code->CodeOffset = (BYTE)cbProlog;
+ code->OpInfo = 0;
+ code->UnwindOp = UWOP_SET_FPREG;
assert(offset <= 240);
assert(offset % 16 == 0);
func->unwindHeader.FrameOffset = offset / 16;
@@ -461,38 +524,38 @@ void Compiler::unwindSaveRegWindows(regNumber reg, unsigned offset)
FuncInfoDsc* func = funCurrentFunc();
- assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
+ assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
assert(func->unwindHeader.CountOfUnwindCodes == 0); // Can't call this after unwindReserve
if (RBM_CALLEE_SAVED & genRegMask(reg))
{
- UNWIND_CODE * code;
+ UNWIND_CODE* code;
if (offset < 0x80000)
{
assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(USHORT)));
- USHORT * codedSize = (USHORT*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(USHORT)];
- code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ USHORT* codedSize = (USHORT*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(USHORT)];
+ code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
// As per AMD64 ABI, if saving entire xmm reg, then offset need to be scaled by 16.
if (genIsValidFloatReg(reg))
{
- *codedSize = (USHORT) (offset/16);
+ *codedSize = (USHORT)(offset / 16);
code->UnwindOp = UWOP_SAVE_XMM128;
}
else
{
- *codedSize = (USHORT) (offset/8);
+ *codedSize = (USHORT)(offset / 8);
code->UnwindOp = UWOP_SAVE_NONVOL;
}
}
else
{
assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(ULONG)));
- ULONG * codedSize = (ULONG*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(ULONG)];
- *codedSize = offset;
- code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
- code->UnwindOp = (genIsValidFloatReg(reg)) ? UWOP_SAVE_XMM128_FAR : UWOP_SAVE_NONVOL_FAR;
+ ULONG* codedSize = (ULONG*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(ULONG)];
+ *codedSize = offset;
+ code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
+ code->UnwindOp = (genIsValidFloatReg(reg)) ? UWOP_SAVE_XMM128_FAR : UWOP_SAVE_NONVOL_FAR;
}
- code->OpInfo = (BYTE)reg;
+ code->OpInfo = (BYTE)reg;
unsigned int cbProlog = unwindGetCurrentOffset(func);
noway_assert((BYTE)cbProlog == cbProlog);
code->CodeOffset = (BYTE)cbProlog;
@@ -526,7 +589,10 @@ void Compiler::unwindSaveRegCFI(regNumber reg, unsigned offset)
// endOffset - byte offset of the code end that this unwind data represents.
// pHeader - pointer to the unwind data blob.
//
-void DumpUnwindInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET endOffset, const UNWIND_INFO * const pHeader)
+void DumpUnwindInfo(bool isHotCode,
+ UNATIVE_OFFSET startOffset,
+ UNATIVE_OFFSET endOffset,
+ const UNWIND_INFO* const pHeader)
{
printf("Unwind Info%s:\n", isHotCode ? "" : " COLD");
printf(" >> Start offset : 0x%06x (not in unwind data)\n", dspOffset(startOffset));
@@ -546,135 +612,133 @@ void DumpUnwindInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET e
const UCHAR flags = pHeader->Flags;
printf(" (");
if (flags & UNW_FLAG_EHANDLER)
+ {
printf(" UNW_FLAG_EHANDLER");
+ }
if (flags & UNW_FLAG_UHANDLER)
+ {
printf(" UNW_FLAG_UHANDLER");
+ }
if (flags & UNW_FLAG_CHAININFO)
+ {
printf(" UNW_FLAG_CHAININFO");
+ }
printf(")");
}
printf("\n");
printf(" SizeOfProlog : 0x%02X\n", pHeader->SizeOfProlog);
printf(" CountOfUnwindCodes: %u\n", pHeader->CountOfUnwindCodes);
- printf(" FrameRegister : %s (%u)\n", (pHeader->FrameRegister == 0) ? "none" : getRegName(pHeader->FrameRegister), pHeader->FrameRegister); // RAX (0) is not allowed as a frame register
+ printf(" FrameRegister : %s (%u)\n",
+ (pHeader->FrameRegister == 0) ? "none" : getRegName(pHeader->FrameRegister),
+ pHeader->FrameRegister); // RAX (0) is not allowed as a frame register
if (pHeader->FrameRegister == 0)
{
- printf(" FrameOffset : N/A (no FrameRegister) (Value=%u)\n", pHeader->FrameOffset);
+ printf(" FrameOffset : N/A (no FrameRegister) (Value=%u)\n", pHeader->FrameOffset);
}
else
{
- printf(" FrameOffset : %u * 16 = 0x%02X\n", pHeader->FrameOffset, pHeader->FrameOffset * 16);
+ printf(" FrameOffset : %u * 16 = 0x%02X\n", pHeader->FrameOffset, pHeader->FrameOffset * 16);
}
printf(" UnwindCodes :\n");
for (unsigned i = 0; i < pHeader->CountOfUnwindCodes; i++)
{
- unsigned offset;
- const UNWIND_CODE * const pCode = &(pHeader->UnwindCode[i]);
- switch (pCode->UnwindOp)
+ unsigned offset;
+ const UNWIND_CODE* const pCode = &(pHeader->UnwindCode[i]);
+ switch (pCode->UnwindOp)
{
- case UWOP_PUSH_NONVOL:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_PUSH_NONVOL (%u) OpInfo: %s (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
- break;
+ case UWOP_PUSH_NONVOL:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_PUSH_NONVOL (%u) OpInfo: %s (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
+ break;
- case UWOP_ALLOC_LARGE:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_ALLOC_LARGE (%u) OpInfo: %u - ",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo);
- if (pCode->OpInfo == 0)
- {
- i++;
- printf("Scaled small \n Size: %u * 8 = %u = 0x%05X\n",
- pHeader->UnwindCode[i].FrameOffset,
- pHeader->UnwindCode[i].FrameOffset * 8,
- pHeader->UnwindCode[i].FrameOffset * 8);
- }
- else if (pCode->OpInfo == 1)
- {
- i++;
- printf("Unscaled large\n Size: %u = 0x%08X\n\n",
- *(ULONG*)&(pHeader->UnwindCode[i]),
- *(ULONG*)&(pHeader->UnwindCode[i]));
- i++;
- }
- else
- {
- printf("Unknown\n");
- }
- break;
+ case UWOP_ALLOC_LARGE:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_ALLOC_LARGE (%u) OpInfo: %u - ", pCode->CodeOffset,
+ pCode->UnwindOp, pCode->OpInfo);
+ if (pCode->OpInfo == 0)
+ {
+ i++;
+ printf("Scaled small \n Size: %u * 8 = %u = 0x%05X\n", pHeader->UnwindCode[i].FrameOffset,
+ pHeader->UnwindCode[i].FrameOffset * 8, pHeader->UnwindCode[i].FrameOffset * 8);
+ }
+ else if (pCode->OpInfo == 1)
+ {
+ i++;
+ printf("Unscaled large\n Size: %u = 0x%08X\n\n", *(ULONG*)&(pHeader->UnwindCode[i]),
+ *(ULONG*)&(pHeader->UnwindCode[i]));
+ i++;
+ }
+ else
+ {
+ printf("Unknown\n");
+ }
+ break;
- case UWOP_ALLOC_SMALL:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_ALLOC_SMALL (%u) OpInfo: %u * 8 + 8 = %u = 0x%02X\n",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo * 8 + 8, pCode->OpInfo * 8 + 8);
- break;
+ case UWOP_ALLOC_SMALL:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_ALLOC_SMALL (%u) OpInfo: %u * 8 + 8 = %u = 0x%02X\n",
+ pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo * 8 + 8, pCode->OpInfo * 8 + 8);
+ break;
- case UWOP_SET_FPREG:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG (%u) OpInfo: Unused (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
- break;
+ case UWOP_SET_FPREG:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG (%u) OpInfo: Unused (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
+ break;
#ifdef PLATFORM_UNIX
- case UWOP_SET_FPREG_LARGE:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG_LARGE (%u) OpInfo: Unused (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
- i++;
- offset = *(ULONG*)&(pHeader->UnwindCode[i]);
- i++;
- printf(" Scaled Offset: %u * 16 = %u = 0x%08X\n",
- offset,
- offset * 16,
- offset * 16);
- if ((offset & 0xF0000000) != 0)
- {
- printf(" Illegal unscaled offset: too large\n");
- }
- break;
+ case UWOP_SET_FPREG_LARGE:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG_LARGE (%u) OpInfo: Unused (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
+ i++;
+ offset = *(ULONG*)&(pHeader->UnwindCode[i]);
+ i++;
+ printf(" Scaled Offset: %u * 16 = %u = 0x%08X\n", offset, offset * 16, offset * 16);
+ if ((offset & 0xF0000000) != 0)
+ {
+ printf(" Illegal unscaled offset: too large\n");
+ }
+ break;
#endif // PLATFORM_UNIX
- case UWOP_SAVE_NONVOL:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL (%u) OpInfo: %s (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
- i++;
- printf(" Scaled Small Offset: %u * 8 = %u = 0x%05X\n",
- pHeader->UnwindCode[i].FrameOffset,
- pHeader->UnwindCode[i].FrameOffset * 8,
- pHeader->UnwindCode[i].FrameOffset * 8);
- break;
-
- case UWOP_SAVE_NONVOL_FAR:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL_FAR (%u) OpInfo: %s (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
- i++;
- printf(" Unscaled Large Offset: 0x%08X\n\n", *(ULONG*)&(pHeader->UnwindCode[i]));
- i++;
- break;
-
- case UWOP_SAVE_XMM128:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_XMM128 (%u) OpInfo: XMM%u (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo);
- i++;
- printf(" Scaled Small Offset: %u * 16 = %u = 0x%05X\n",
- pHeader->UnwindCode[i].FrameOffset,
- pHeader->UnwindCode[i].FrameOffset * 16,
- pHeader->UnwindCode[i].FrameOffset * 16);
- break;
-
- case UWOP_SAVE_XMM128_FAR:
- printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_XMM128_FAR (%u) OpInfo: XMM%u (%u)\n",
- pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo);
- i++;
- printf(" Unscaled Large Offset: 0x%08X\n\n", *(ULONG*)&(pHeader->UnwindCode[i]));
- i++;
- break;
-
- case UWOP_EPILOG:
- case UWOP_SPARE_CODE:
- case UWOP_PUSH_MACHFRAME:
- default:
- printf(" Unrecognized UNWIND_CODE: 0x%04X\n", *(USHORT*)pCode);
- break;
+ case UWOP_SAVE_NONVOL:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL (%u) OpInfo: %s (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
+ i++;
+ printf(" Scaled Small Offset: %u * 8 = %u = 0x%05X\n", pHeader->UnwindCode[i].FrameOffset,
+ pHeader->UnwindCode[i].FrameOffset * 8, pHeader->UnwindCode[i].FrameOffset * 8);
+ break;
+
+ case UWOP_SAVE_NONVOL_FAR:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL_FAR (%u) OpInfo: %s (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, getRegName(pCode->OpInfo), pCode->OpInfo);
+ i++;
+ printf(" Unscaled Large Offset: 0x%08X\n\n", *(ULONG*)&(pHeader->UnwindCode[i]));
+ i++;
+ break;
+
+ case UWOP_SAVE_XMM128:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_XMM128 (%u) OpInfo: XMM%u (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo);
+ i++;
+ printf(" Scaled Small Offset: %u * 16 = %u = 0x%05X\n", pHeader->UnwindCode[i].FrameOffset,
+ pHeader->UnwindCode[i].FrameOffset * 16, pHeader->UnwindCode[i].FrameOffset * 16);
+ break;
+
+ case UWOP_SAVE_XMM128_FAR:
+ printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_XMM128_FAR (%u) OpInfo: XMM%u (%u)\n",
+ pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo, pCode->OpInfo);
+ i++;
+ printf(" Unscaled Large Offset: 0x%08X\n\n", *(ULONG*)&(pHeader->UnwindCode[i]));
+ i++;
+ break;
+
+ case UWOP_EPILOG:
+ case UWOP_SPARE_CODE:
+ case UWOP_PUSH_MACHFRAME:
+ default:
+ printf(" Unrecognized UNWIND_CODE: 0x%04X\n", *(USHORT*)pCode);
+ break;
}
}
}
@@ -689,7 +753,11 @@ void DumpUnwindInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET e
// endOffset - byte offset of the code end that this cfi data represents.
// pcFiCode - pointer to the cfi data blob.
//
-void DumpCfiInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET endOffset, DWORD cfiCodeBytes, const CFI_CODE * const pCfiCode)
+void DumpCfiInfo(bool isHotCode,
+ UNATIVE_OFFSET startOffset,
+ UNATIVE_OFFSET endOffset,
+ DWORD cfiCodeBytes,
+ const CFI_CODE* const pCfiCode)
{
printf("Cfi Info%s:\n", isHotCode ? "" : " COLD");
printf(" >> Start offset : 0x%06x \n", dspOffset(startOffset));
@@ -697,16 +765,17 @@ void DumpCfiInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET endO
for (int i = 0; i < cfiCodeBytes / sizeof(CFI_CODE); i++)
{
- const CFI_CODE * const pCode = &(pCfiCode[i]);
+ const CFI_CODE* const pCode = &(pCfiCode[i]);
UCHAR codeOffset = pCode->CodeOffset;
- SHORT dwarfReg = pCode->DwarfReg;
- INT offset = pCode->Offset;
+ SHORT dwarfReg = pCode->DwarfReg;
+ INT offset = pCode->Offset;
switch (pCode->CfiOpCode)
{
case CFI_REL_OFFSET:
- printf(" CodeOffset: 0x%02X Op: RelOffset DwarfReg:0x%x Offset:0x%X\n", codeOffset, dwarfReg, offset);
+ printf(" CodeOffset: 0x%02X Op: RelOffset DwarfReg:0x%x Offset:0x%X\n", codeOffset, dwarfReg,
+ offset);
break;
case CFI_DEF_CFA_REGISTER:
assert(offset == 0);
@@ -725,7 +794,6 @@ void DumpCfiInfo(bool isHotCode, UNATIVE_OFFSET startOffset, UNATIVE_OFFSET endO
#endif // UNIX_AMD64_ABI
#endif // DEBUG
-
//------------------------------------------------------------------------
// Compiler::unwindReserve: Ask the VM to reserve space for the unwind information
// for the function and all its funclets. Called once, just before asking the VM
@@ -782,39 +850,39 @@ void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode)
else
#endif // UNIX_AMD64_ABI
{
- assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
+ assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog
assert(func->unwindHeader.CountOfUnwindCodes == 0); // Only call this once per prolog
// Set the size of the prolog to be the last encoded action
if (func->unwindCodeSlot < sizeof(func->unwindCodes))
{
- UNWIND_CODE * code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot];
+ UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot];
func->unwindHeader.SizeOfProlog = code->CodeOffset;
}
else
{
func->unwindHeader.SizeOfProlog = 0;
}
- func->unwindHeader.CountOfUnwindCodes = (BYTE)((sizeof(func->unwindCodes) - func->unwindCodeSlot) / sizeof(UNWIND_CODE));
+ func->unwindHeader.CountOfUnwindCodes =
+ (BYTE)((sizeof(func->unwindCodes) - func->unwindCodeSlot) / sizeof(UNWIND_CODE));
// Prepend the unwindHeader onto the unwind codes
assert(func->unwindCodeSlot >= offsetof(UNWIND_INFO, UnwindCode));
func->unwindCodeSlot -= offsetof(UNWIND_INFO, UnwindCode);
- UNWIND_INFO * pHeader = (UNWIND_INFO*)&func->unwindCodes[func->unwindCodeSlot];
+ UNWIND_INFO* pHeader = (UNWIND_INFO*)&func->unwindCodes[func->unwindCodeSlot];
memcpy(pHeader, &func->unwindHeader, offsetof(UNWIND_INFO, UnwindCode));
unwindCodeBytes = sizeof(func->unwindCodes) - func->unwindCodeSlot;
}
}
- BOOL isFunclet = (func->funKind != FUNC_ROOT);
+ BOOL isFunclet = (func->funKind != FUNC_ROOT);
BOOL isColdCode = isHotCode ? FALSE : TRUE;
eeReserveUnwindInfo(isFunclet, isColdCode, unwindCodeBytes);
}
-
//------------------------------------------------------------------------
// Compiler::unwindEmit: Report all the unwind information to the VM.
//
@@ -849,8 +917,8 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
{
UNATIVE_OFFSET startOffset;
UNATIVE_OFFSET endOffset;
- DWORD unwindCodeBytes = 0;
- BYTE* pUnwindBlock = nullptr;
+ DWORD unwindCodeBytes = 0;
+ BYTE* pUnwindBlock = nullptr;
if (isHotCode)
{
@@ -879,7 +947,7 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
if (size > 0)
{
unwindCodeBytes = size * sizeof(CFI_CODE);
- pUnwindBlock = (BYTE*)&(*func->cfiCodes)[0];
+ pUnwindBlock = (BYTE*)&(*func->cfiCodes)[0];
}
}
else
@@ -888,8 +956,11 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
unwindCodeBytes = sizeof(func->unwindCodes) - func->unwindCodeSlot;
#ifdef DEBUG
- UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *)(&func->unwindCodes[func->unwindCodeSlot]);
- DWORD unwindCodeBytesSpecified = offsetof(UNWIND_INFO, UnwindCode) + pUnwindInfo->CountOfUnwindCodes * sizeof(UNWIND_CODE); // This is what the unwind codes themselves say; it better match what we tell the VM.
+ UNWIND_INFO* pUnwindInfo = (UNWIND_INFO*)(&func->unwindCodes[func->unwindCodeSlot]);
+ DWORD unwindCodeBytesSpecified =
+ offsetof(UNWIND_INFO, UnwindCode) +
+ pUnwindInfo->CountOfUnwindCodes * sizeof(UNWIND_CODE); // This is what the unwind codes themselves say;
+ // it better match what we tell the VM.
assert(unwindCodeBytes == unwindCodeBytesSpecified);
#endif // DEBUG
@@ -926,12 +997,12 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- DumpCfiInfo(isHotCode, startOffset, endOffset, unwindCodeBytes, (const CFI_CODE * const)pUnwindBlock);
+ DumpCfiInfo(isHotCode, startOffset, endOffset, unwindCodeBytes, (const CFI_CODE* const)pUnwindBlock);
}
else
#endif // UNIX_AMD64_ABI
{
- DumpUnwindInfo(isHotCode, startOffset, endOffset, (const UNWIND_INFO * const)pUnwindBlock);
+ DumpUnwindInfo(isHotCode, startOffset, endOffset, (const UNWIND_INFO* const)pUnwindBlock);
}
}
#endif // DEBUG
@@ -950,15 +1021,10 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
{
assert(startOffset >= info.compTotalHotCodeSize);
startOffset -= info.compTotalHotCodeSize;
- endOffset -= info.compTotalHotCodeSize;
+ endOffset -= info.compTotalHotCodeSize;
}
- eeAllocUnwindInfo((BYTE*)pHotCode,
- (BYTE*)pColdCode,
- startOffset,
- endOffset,
- unwindCodeBytes,
- pUnwindBlock,
+ eeAllocUnwindInfo((BYTE*)pHotCode, (BYTE*)pColdCode, startOffset, endOffset, unwindCodeBytes, pUnwindBlock,
(CorJitFuncKind)func->funKind);
}
@@ -975,9 +1041,9 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
void Compiler::unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode)
{
// Verify that the JIT enum is in sync with the JIT-EE interface enum
- static_assert_no_msg(FUNC_ROOT == (FuncKind)CORJIT_FUNC_ROOT);
- static_assert_no_msg(FUNC_HANDLER == (FuncKind)CORJIT_FUNC_HANDLER);
- static_assert_no_msg(FUNC_FILTER == (FuncKind)CORJIT_FUNC_FILTER);
+ static_assert_no_msg(FUNC_ROOT == (FuncKind)CORJIT_FUNC_ROOT);
+ static_assert_no_msg(FUNC_HANDLER == (FuncKind)CORJIT_FUNC_HANDLER);
+ static_assert_no_msg(FUNC_FILTER == (FuncKind)CORJIT_FUNC_FILTER);
unwindEmitFuncHelper(func, pHotCode, pColdCode, true);