示例#1
0
//------------------------------------------------------------------------
// DumpCfiInfo: Dump the Cfi data.
//
// Arguments:
//    isHotCode   - true if this cfi data is for the hot section, false otherwise.
//    startOffset - byte offset of the code start that this cfi data represents.
//    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)
{
    printf("Cfi Info%s:\n", isHotCode ? "" : " COLD");
    printf("  >> Start offset   : 0x%06x \n", dspOffset(startOffset));
    printf("  >>   End offset   : 0x%06x \n", dspOffset(endOffset));

    for (int i = 0; i < cfiCodeBytes / sizeof(CFI_CODE); i++)
    {
        const CFI_CODE * const pCode = &(pCfiCode[i]);

        UCHAR codeOffset = pCode->CodeOffset;
        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);
                break;
            case CFI_DEF_CFA_REGISTER:
                assert(offset == 0);
                printf("    CodeOffset: 0x%02X Op: DefCfaRegister DwarfReg:0x%X\n", codeOffset, dwarfReg);
                break;
            case CFI_ADJUST_CFA_OFFSET:
                assert(dwarfReg == DWARF_REG_ILLEGAL);
                printf("    CodeOffset: 0x%02X Op: AdjustCfaOffset Offset:0x%X\n", codeOffset, offset);
                break;
            default:
                printf("    Unrecognized CFI_CODE: 0x%IX\n", *(UINT64*)pCode);
                break;
        }
    }
}
示例#2
0
//------------------------------------------------------------------------
// DumpUnwindInfo: Dump the unwind data.
//
// Arguments:
//    isHotCode   - true if this unwind data is for the hot section, false otherwise.
//    startOffset - byte offset of the code start that this unwind data represents.
//    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)
{
    printf("Unwind Info%s:\n", isHotCode ? "" : " COLD");
    printf("  >> Start offset   : 0x%06x (not in unwind data)\n", dspOffset(startOffset));
    printf("  >>   End offset   : 0x%06x (not in unwind data)\n", dspOffset(endOffset));

    if (pHeader == nullptr)
    {
        // Cold AMD64 code doesn't have unwind info; the VM creates chained unwind info.
        assert(!isHotCode);
        return;
    }

    printf("  Version           : %u\n", pHeader->Version);
    printf("  Flags             : 0x%02x", pHeader->Flags);
    if (pHeader->Flags)
    {
        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
    if (pHeader->FrameRegister == 0)
    {
    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("  UnwindCodes       :\n");

    for (unsigned i = 0; i < pHeader->CountOfUnwindCodes; i++)
    {
        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_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_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_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;
        }
    }
}