974 lines
21 KiB
C
974 lines
21 KiB
C
|
/*** unasm.c - Unassemble AML back to ASL
|
||
|
*
|
||
|
* Copyright (c) 1996,1998 Microsoft Corporation
|
||
|
* Author: Michael Tsang (MikeTs)
|
||
|
* Created: 10/01/97
|
||
|
*
|
||
|
* MODIFICATION HISTORY
|
||
|
*/
|
||
|
|
||
|
#include "pch.h"
|
||
|
|
||
|
//Local function prototype
|
||
|
VOID LOCAL Indent(PUCHAR pbOp, int iLevel);
|
||
|
UCHAR LOCAL FindOpClass(UCHAR bOp, POPMAP pOpTable);
|
||
|
PASLTERM LOCAL FindOpTerm(ULONG dwOpcode);
|
||
|
PASLTERM LOCAL FindKeywordTerm(char cKWGroup, UCHAR bData);
|
||
|
LONG LOCAL UnAsmOpcode(PUCHAR *ppbOp);
|
||
|
LONG LOCAL UnAsmDataObj(PUCHAR *ppbOp);
|
||
|
LONG LOCAL UnAsmNameObj(PUCHAR *ppbOp, PNSOBJ pns, char c);
|
||
|
LONG LOCAL UnAsmNameTail(PUCHAR *ppbOp, PSZ pszBuff, int iLen);
|
||
|
LONG LOCAL UnAsmTermObj(PASLTERM pterm, PUCHAR *ppbOp);
|
||
|
LONG LOCAL UnAsmArgs(PSZ pszUnAsmArgTypes, PSZ pszArgActions, PUCHAR *ppbOp,
|
||
|
PNSOBJ pns);
|
||
|
LONG LOCAL UnAsmSuperName(PUCHAR *ppbOp);
|
||
|
LONG LOCAL UnAsmDataList(PUCHAR *ppbOp, PUCHAR pbEnd);
|
||
|
LONG LOCAL UnAsmPkgList(PUCHAR *ppbOp, PUCHAR pbEnd);
|
||
|
LONG LOCAL UnAsmFieldList(PUCHAR *ppbOp, PUCHAR pbEnd);
|
||
|
LONG LOCAL UnAsmField(PUCHAR *ppbOp, PULONG pdwBitPos);
|
||
|
|
||
|
/***LP UnAsmScope - Unassemble a scope
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> Current Opcode pointer
|
||
|
* pbEnd -> end of scope
|
||
|
* uipbOp - Op address
|
||
|
* pnsScope - Scope object
|
||
|
* iLevel - level of indentation
|
||
|
* icLines - 1: unasm one line; 0: unasm all; -1: internal
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmScope(PUCHAR *ppbOp, PUCHAR pbEnd, ULONG_PTR uipbOp,
|
||
|
PNSOBJ pnsScope, int iLevel, int icLines)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
int icLinesLeft = icLines;
|
||
|
|
||
|
if (uipbOp != 0)
|
||
|
{
|
||
|
guipbOpXlate = uipbOp - (ULONG_PTR)(*ppbOp);
|
||
|
}
|
||
|
|
||
|
if (pnsScope != NULL)
|
||
|
{
|
||
|
gpnsCurUnAsmScope = pnsScope;
|
||
|
}
|
||
|
|
||
|
if (iLevel != -1)
|
||
|
{
|
||
|
giLevel = iLevel;
|
||
|
}
|
||
|
|
||
|
if (icLines < 0)
|
||
|
{
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("{");
|
||
|
giLevel++;
|
||
|
}
|
||
|
else if (icLines == 0)
|
||
|
{
|
||
|
icLinesLeft = -1;
|
||
|
}
|
||
|
|
||
|
while (*ppbOp < pbEnd)
|
||
|
{
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
|
||
|
if ((rc = UnAsmOpcode(ppbOp)) == UNASMERR_NONE)
|
||
|
{
|
||
|
if (icLinesLeft < 0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (--icLinesLeft == 0)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((rc == UNASMERR_NONE) && (icLines < 0))
|
||
|
{
|
||
|
giLevel--;
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("}");
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmScope
|
||
|
|
||
|
/***LP Indent - Print indent level
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pbOp -> opcode
|
||
|
* iLevel - indent level
|
||
|
*
|
||
|
* EXIT
|
||
|
* None
|
||
|
*/
|
||
|
|
||
|
VOID LOCAL Indent(PUCHAR pbOp, int iLevel)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
PRINTF("\n%08x: ", pbOp + guipbOpXlate);
|
||
|
for (i = 0; i < iLevel; ++i)
|
||
|
{
|
||
|
PRINTF("| ");
|
||
|
}
|
||
|
} //Indent
|
||
|
|
||
|
/***LP FindOpClass - Find opcode class of extended opcode
|
||
|
*
|
||
|
* ENTRY
|
||
|
* bOp - opcode
|
||
|
* pOpTable -> opcode table
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns opcode class
|
||
|
* EXIT-FAILURE
|
||
|
* returns OPCLASS_INVALID
|
||
|
*/
|
||
|
|
||
|
UCHAR LOCAL FindOpClass(UCHAR bOp, POPMAP pOpTable)
|
||
|
{
|
||
|
UCHAR bOpClass = OPCLASS_INVALID;
|
||
|
|
||
|
while (pOpTable->bOpClass != 0)
|
||
|
{
|
||
|
if (bOp == pOpTable->bExOp)
|
||
|
{
|
||
|
bOpClass = pOpTable->bOpClass;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pOpTable++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bOpClass;
|
||
|
} //FindOpClass
|
||
|
|
||
|
/***LP FindOpTerm - Find opcode in TermTable
|
||
|
*
|
||
|
* ENTRY
|
||
|
* dwOpcode - opcode
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns TermTable entry pointer
|
||
|
* EXIT-FAILURE
|
||
|
* returns NULL
|
||
|
*/
|
||
|
|
||
|
PASLTERM LOCAL FindOpTerm(ULONG dwOpcode)
|
||
|
{
|
||
|
PASLTERM pterm = NULL;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; TermTable[i].pszID != NULL; ++i)
|
||
|
{
|
||
|
if ((TermTable[i].dwOpcode == dwOpcode) &&
|
||
|
(TermTable[i].dwfTermClass &
|
||
|
(UTC_CONST_NAME | UTC_SHORT_NAME | UTC_NAMESPACE_MODIFIER |
|
||
|
UTC_DATA_OBJECT | UTC_NAMED_OBJECT | UTC_OPCODE_TYPE1 |
|
||
|
UTC_OPCODE_TYPE2)))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (TermTable[i].pszID != NULL)
|
||
|
{
|
||
|
pterm = &TermTable[i];
|
||
|
}
|
||
|
|
||
|
return pterm;
|
||
|
} //FindOpTerm
|
||
|
|
||
|
/***LP FindKeywordTerm - Find keyword in TermTable
|
||
|
*
|
||
|
* ENTRY
|
||
|
* cKWGroup - keyword group
|
||
|
* bData - data to match keyword
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns TermTable entry pointer
|
||
|
* EXIT-FAILURE
|
||
|
* returns NULL
|
||
|
*/
|
||
|
|
||
|
PASLTERM LOCAL FindKeywordTerm(char cKWGroup, UCHAR bData)
|
||
|
{
|
||
|
PASLTERM pterm = NULL;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; TermTable[i].pszID != NULL; ++i)
|
||
|
{
|
||
|
if ((TermTable[i].dwfTermClass == UTC_KEYWORD) &&
|
||
|
(TermTable[i].pszArgActions[0] == cKWGroup) &&
|
||
|
((bData & (UCHAR)(TermTable[i].dwTermData >> 8)) ==
|
||
|
(UCHAR)(TermTable[i].dwTermData & 0xff)))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (TermTable[i].pszID != NULL)
|
||
|
{
|
||
|
pterm = &TermTable[i];
|
||
|
}
|
||
|
|
||
|
return pterm;
|
||
|
} //FindKeywordTerm
|
||
|
|
||
|
/***LP UnAsmOpcode - Unassemble an Opcode
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> Opcode pointer
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmOpcode(PUCHAR *ppbOp)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
ULONG dwOpcode;
|
||
|
UCHAR bOp;
|
||
|
PASLTERM pterm;
|
||
|
char szUnAsmArgTypes[MAX_ARGS + 1];
|
||
|
int i;
|
||
|
|
||
|
if (**ppbOp == OP_EXT_PREFIX)
|
||
|
{
|
||
|
(*ppbOp)++;
|
||
|
dwOpcode = (((ULONG)**ppbOp) << 8) | OP_EXT_PREFIX;
|
||
|
bOp = FindOpClass(**ppbOp, ExOpClassTable);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwOpcode = (ULONG)(**ppbOp);
|
||
|
bOp = OpClassTable[**ppbOp];
|
||
|
}
|
||
|
|
||
|
switch (bOp)
|
||
|
{
|
||
|
case OPCLASS_DATA_OBJ:
|
||
|
rc = UnAsmDataObj(ppbOp);
|
||
|
break;
|
||
|
|
||
|
case OPCLASS_NAME_OBJ:
|
||
|
{
|
||
|
NSOBJ NSObj = {0};
|
||
|
|
||
|
if (((rc = UnAsmNameObj(ppbOp, &NSObj, NSTYPE_UNKNOWN)) ==
|
||
|
UNASMERR_NONE) &&
|
||
|
(NSObj.ObjData.dwDataType == OBJTYPE_METHOD))
|
||
|
{
|
||
|
PMETHODOBJ pm = (PMETHODOBJ)GetObjBuff(&NSObj.ObjData);
|
||
|
int iNumArgs;
|
||
|
|
||
|
if (pm != NULL)
|
||
|
{
|
||
|
iNumArgs = pm->bMethodFlags & METHOD_NUMARG_MASK;
|
||
|
|
||
|
for (i = 0; i < iNumArgs; ++i)
|
||
|
{
|
||
|
szUnAsmArgTypes[i] = 'C';
|
||
|
}
|
||
|
szUnAsmArgTypes[i] = '\0';
|
||
|
rc = UnAsmArgs(szUnAsmArgTypes, NULL, ppbOp, NULL);
|
||
|
LocalFree(pm);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case OPCLASS_ARG_OBJ:
|
||
|
case OPCLASS_LOCAL_OBJ:
|
||
|
case OPCLASS_CODE_OBJ:
|
||
|
case OPCLASS_CONST_OBJ:
|
||
|
if ((pterm = FindOpTerm(dwOpcode)) == NULL)
|
||
|
{
|
||
|
DBG_ERROR(("UnAsmOpcode: invalid opcode 0x%x", dwOpcode));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
(*ppbOp)++;
|
||
|
rc = UnAsmTermObj(pterm, ppbOp);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DBG_ERROR(("UnAsmOpcode: invalid opcode class %d", bOp));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmOpcode
|
||
|
|
||
|
/***LP UnAsmDataObj - Unassemble data object
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmDataObj(PUCHAR *ppbOp)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
UCHAR bOp = **ppbOp;
|
||
|
PSZ psz;
|
||
|
|
||
|
(*ppbOp)++;
|
||
|
switch (bOp)
|
||
|
{
|
||
|
case OP_BYTE:
|
||
|
PRINTF("0x%x", **ppbOp);
|
||
|
*ppbOp += sizeof(UCHAR);
|
||
|
break;
|
||
|
|
||
|
case OP_WORD:
|
||
|
PRINTF("0x%x", *((PUSHORT)*ppbOp));
|
||
|
*ppbOp += sizeof(USHORT);
|
||
|
break;
|
||
|
|
||
|
case OP_DWORD:
|
||
|
PRINTF("0x%x", *((PULONG)*ppbOp));
|
||
|
*ppbOp += sizeof(ULONG);
|
||
|
break;
|
||
|
|
||
|
case OP_STRING:
|
||
|
PRINTF("\"");
|
||
|
for (psz = (PSZ)*ppbOp; *psz != '\0'; psz++)
|
||
|
{
|
||
|
if (*psz == '\\')
|
||
|
{
|
||
|
PRINTF("\\");
|
||
|
}
|
||
|
PRINTF("%c", *psz);
|
||
|
}
|
||
|
PRINTF("\"");
|
||
|
*ppbOp += STRLEN((PSZ)*ppbOp) + 1;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DBG_ERROR(("UnAsmDataObj: unexpected opcode 0x%x", bOp));
|
||
|
rc = UNASMERR_INVALID_OPCODE;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmDataObj
|
||
|
|
||
|
/***LP UnAsmNameObj - Unassemble name object
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pns -> to hold object found or created
|
||
|
* c - object type
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmNameObj(PUCHAR *ppbOp, PNSOBJ pns, char c)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
char szName[MAX_NAME_LEN + 1];
|
||
|
int iLen = 0;
|
||
|
|
||
|
szName[0] = '\0';
|
||
|
if (**ppbOp == OP_ROOT_PREFIX)
|
||
|
{
|
||
|
szName[iLen] = '\\';
|
||
|
iLen++;
|
||
|
(*ppbOp)++;
|
||
|
rc = UnAsmNameTail(ppbOp, szName, iLen);
|
||
|
}
|
||
|
else if (**ppbOp == OP_PARENT_PREFIX)
|
||
|
{
|
||
|
szName[iLen] = '^';
|
||
|
iLen++;
|
||
|
(*ppbOp)++;
|
||
|
while ((**ppbOp == OP_PARENT_PREFIX) && (iLen < MAX_NAME_LEN))
|
||
|
{
|
||
|
szName[iLen] = '^';
|
||
|
iLen++;
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
|
||
|
if (**ppbOp == OP_PARENT_PREFIX)
|
||
|
{
|
||
|
DBG_ERROR(("UnAsmNameObj: name too long - \"%s\"", szName));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = UnAsmNameTail(ppbOp, szName, iLen);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = UnAsmNameTail(ppbOp, szName, iLen);
|
||
|
}
|
||
|
|
||
|
if (rc == UNASMERR_NONE)
|
||
|
{
|
||
|
ULONG_PTR uipns = 0;
|
||
|
NSOBJ NSObj;
|
||
|
|
||
|
PRINTF("%s", szName);
|
||
|
|
||
|
rc = GetNSObj(szName, gpnsCurUnAsmScope, &uipns, &NSObj, 0);
|
||
|
|
||
|
if (rc == UNASMERR_NONE)
|
||
|
{
|
||
|
if (pns != NULL)
|
||
|
{
|
||
|
MEMCPY(pns, &NSObj, sizeof(NSObj));
|
||
|
}
|
||
|
|
||
|
if ((c == NSTYPE_SCOPE) && (uipns != 0))
|
||
|
{
|
||
|
gpnsCurUnAsmScope = pns;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = UNASMERR_NONE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmNameObj
|
||
|
|
||
|
/***LP UnAsmNameTail - Parse AML name tail
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pszBuff -> to hold parsed name
|
||
|
* iLen - index to tail of pszBuff
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmNameTail(PUCHAR *ppbOp, PSZ pszBuff, int iLen)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
int icNameSegs = 0;
|
||
|
|
||
|
//
|
||
|
// We do not check for invalid NameSeg characters here and assume that
|
||
|
// the compiler does its job not generating it.
|
||
|
//
|
||
|
if (**ppbOp == '\0')
|
||
|
{
|
||
|
//
|
||
|
// There is no NameTail (i.e. either NULL name or name with just
|
||
|
// prefixes.
|
||
|
//
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
else if (**ppbOp == OP_MULTI_NAME_PREFIX)
|
||
|
{
|
||
|
(*ppbOp)++;
|
||
|
icNameSegs = (int)**ppbOp;
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
else if (**ppbOp == OP_DUAL_NAME_PREFIX)
|
||
|
{
|
||
|
(*ppbOp)++;
|
||
|
icNameSegs = 2;
|
||
|
}
|
||
|
else
|
||
|
icNameSegs = 1;
|
||
|
|
||
|
while ((icNameSegs > 0) && (iLen + sizeof(NAMESEG) < MAX_NAME_LEN))
|
||
|
{
|
||
|
STRCPYN(&pszBuff[iLen], (PSZ)(*ppbOp), sizeof(NAMESEG));
|
||
|
iLen += sizeof(NAMESEG);
|
||
|
*ppbOp += sizeof(NAMESEG);
|
||
|
icNameSegs--;
|
||
|
if ((icNameSegs > 0) && (iLen + 1 < MAX_NAME_LEN))
|
||
|
{
|
||
|
pszBuff[iLen] = '.';
|
||
|
iLen++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (icNameSegs > 0)
|
||
|
{
|
||
|
DBG_ERROR(("UnAsmNameTail: name too long - %s", pszBuff));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszBuff[iLen] = '\0';
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmNameTail
|
||
|
|
||
|
/***LP UnAsmTermObj - Unassemble term object
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pterm -> term table entry
|
||
|
* ppbOp -> opcode pointer
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmTermObj(PASLTERM pterm, PUCHAR *ppbOp)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
PUCHAR pbEnd = NULL;
|
||
|
PNSOBJ pnsScopeSave = gpnsCurUnAsmScope;
|
||
|
NSOBJ NSObj = {0};
|
||
|
|
||
|
PRINTF("%s", pterm->pszID);
|
||
|
|
||
|
if (pterm->dwfTerm & TF_PACKAGE_LEN)
|
||
|
{
|
||
|
ParsePackageLen(ppbOp, &pbEnd);
|
||
|
}
|
||
|
|
||
|
if (pterm->pszUnAsmArgTypes != NULL)
|
||
|
{
|
||
|
rc = UnAsmArgs(pterm->pszUnAsmArgTypes, pterm->pszArgActions, ppbOp,
|
||
|
&NSObj);
|
||
|
}
|
||
|
|
||
|
if (rc == UNASMERR_NONE)
|
||
|
{
|
||
|
if (pterm->dwfTerm & TF_DATA_LIST)
|
||
|
{
|
||
|
rc = UnAsmDataList(ppbOp, pbEnd);
|
||
|
}
|
||
|
else if (pterm->dwfTerm & TF_PACKAGE_LIST)
|
||
|
{
|
||
|
rc = UnAsmPkgList(ppbOp, pbEnd);
|
||
|
}
|
||
|
else if (pterm->dwfTerm & TF_FIELD_LIST)
|
||
|
{
|
||
|
rc = UnAsmFieldList(ppbOp, pbEnd);
|
||
|
}
|
||
|
else if (pterm->dwfTerm & TF_PACKAGE_LEN)
|
||
|
{
|
||
|
if ((pterm->dwfTerm & TF_CHANGE_CHILDSCOPE) &&
|
||
|
(NSObj.ObjData.dwDataType != 0))
|
||
|
{
|
||
|
gpnsCurUnAsmScope = &NSObj;
|
||
|
}
|
||
|
|
||
|
rc = UnAsmScope(ppbOp, pbEnd, 0, NULL, -1, -1);
|
||
|
}
|
||
|
}
|
||
|
gpnsCurUnAsmScope = pnsScopeSave;
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmTermObj
|
||
|
|
||
|
/***LP UnAsmArgs - Unassemble arguments
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pszUnArgTypes -> UnAsm ArgTypes string
|
||
|
* pszArgActions -> Arg Action types
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pns -> to hold created object
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmArgs(PSZ pszUnAsmArgTypes, PSZ pszArgActions, PUCHAR *ppbOp,
|
||
|
PNSOBJ pns)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
static UCHAR bArgData = 0;
|
||
|
int iNumArgs, i;
|
||
|
PASLTERM pterm;
|
||
|
|
||
|
iNumArgs = STRLEN(pszUnAsmArgTypes);
|
||
|
PRINTF("(");
|
||
|
|
||
|
for (i = 0; i < iNumArgs; ++i)
|
||
|
{
|
||
|
if (i != 0)
|
||
|
{
|
||
|
PRINTF(", ");
|
||
|
}
|
||
|
|
||
|
switch (pszUnAsmArgTypes[i])
|
||
|
{
|
||
|
case 'N':
|
||
|
ASSERT(pszArgActions != NULL);
|
||
|
rc = UnAsmNameObj(ppbOp, pns, pszArgActions[i]);
|
||
|
break;
|
||
|
|
||
|
case 'O':
|
||
|
if ((**ppbOp == OP_BUFFER) || (**ppbOp == OP_PACKAGE) ||
|
||
|
(OpClassTable[**ppbOp] == OPCLASS_CONST_OBJ))
|
||
|
{
|
||
|
pterm = FindOpTerm((ULONG)(**ppbOp));
|
||
|
ASSERT(pterm != NULL);
|
||
|
(*ppbOp)++;
|
||
|
rc = UnAsmTermObj(pterm, ppbOp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = UnAsmDataObj(ppbOp);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'C':
|
||
|
rc = UnAsmOpcode(ppbOp);
|
||
|
break;
|
||
|
|
||
|
case 'B':
|
||
|
PRINTF("0x%x", **ppbOp);
|
||
|
*ppbOp += sizeof(UCHAR);
|
||
|
break;
|
||
|
|
||
|
case 'K':
|
||
|
case 'k':
|
||
|
if (pszUnAsmArgTypes[i] == 'K')
|
||
|
{
|
||
|
bArgData = **ppbOp;
|
||
|
}
|
||
|
|
||
|
if ((pszArgActions != NULL) && (pszArgActions[i] == '!'))
|
||
|
{
|
||
|
PRINTF("0x%x", **ppbOp & 0x07);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pterm = FindKeywordTerm(pszArgActions[i], bArgData);
|
||
|
ASSERT(pterm != NULL);
|
||
|
PRINTF("%s", pterm->pszID);
|
||
|
}
|
||
|
|
||
|
if (pszUnAsmArgTypes[i] == 'K')
|
||
|
{
|
||
|
*ppbOp += sizeof(UCHAR);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'W':
|
||
|
PRINTF("0x%x", *((PUSHORT)*ppbOp));
|
||
|
*ppbOp += sizeof(USHORT);
|
||
|
break;
|
||
|
|
||
|
case 'D':
|
||
|
PRINTF("0x%x", *((PULONG)*ppbOp));
|
||
|
*ppbOp += sizeof(ULONG);
|
||
|
break;
|
||
|
|
||
|
case 'S':
|
||
|
ASSERT(pszArgActions != NULL);
|
||
|
rc = UnAsmSuperName(ppbOp);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DBG_ERROR(("UnAsmOpcode: invalid ArgType '%c'",
|
||
|
pszUnAsmArgTypes[i]));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PRINTF(")");
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmArgs
|
||
|
|
||
|
/***LP UnAsmSuperName - Unassemble supername
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmSuperName(PUCHAR *ppbOp)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
|
||
|
if (**ppbOp == 0)
|
||
|
{
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
else if ((**ppbOp == OP_EXT_PREFIX) && (*(*ppbOp + 1) == EXOP_DEBUG))
|
||
|
{
|
||
|
PRINTF("Debug");
|
||
|
*ppbOp += 2;
|
||
|
}
|
||
|
else if (OpClassTable[**ppbOp] == OPCLASS_NAME_OBJ)
|
||
|
{
|
||
|
rc = UnAsmNameObj(ppbOp, NULL, NSTYPE_UNKNOWN);
|
||
|
}
|
||
|
else if ((**ppbOp == OP_INDEX) ||
|
||
|
(OpClassTable[**ppbOp] == OPCLASS_ARG_OBJ) ||
|
||
|
(OpClassTable[**ppbOp] == OPCLASS_LOCAL_OBJ))
|
||
|
{
|
||
|
rc = UnAsmOpcode(ppbOp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DBG_ERROR(("UnAsmSuperName: invalid SuperName - 0x%02x", **ppbOp));
|
||
|
rc = UNASMERR_FATAL;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmSuperName
|
||
|
|
||
|
/***LP UnAsmDataList - Unassemble data list
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pbEnd -> end of list
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmDataList(PUCHAR *ppbOp, PUCHAR pbEnd)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
int i;
|
||
|
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("{");
|
||
|
|
||
|
while (*ppbOp < pbEnd)
|
||
|
{
|
||
|
Indent(*ppbOp, 0);
|
||
|
PRINTF("0x%02x", **ppbOp);
|
||
|
|
||
|
(*ppbOp)++;
|
||
|
for (i = 1; (*ppbOp < pbEnd) && (i < 8); ++i)
|
||
|
{
|
||
|
PRINTF(", 0x%02x", **ppbOp);
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
|
||
|
if (*ppbOp < pbEnd)
|
||
|
{
|
||
|
PRINTF(",");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("}");
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmDataList
|
||
|
|
||
|
/***LP UnAsmPkgList - Unassemble package list
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pbEnd -> end of list
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmPkgList(PUCHAR *ppbOp, PUCHAR pbEnd)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
PASLTERM pterm;
|
||
|
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("{");
|
||
|
giLevel++;
|
||
|
|
||
|
while (*ppbOp < pbEnd)
|
||
|
{
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
|
||
|
if ((**ppbOp == OP_BUFFER) || (**ppbOp == OP_PACKAGE) ||
|
||
|
(OpClassTable[**ppbOp] == OPCLASS_CONST_OBJ))
|
||
|
{
|
||
|
pterm = FindOpTerm((ULONG)(**ppbOp));
|
||
|
ASSERT(pterm != NULL);
|
||
|
(*ppbOp)++;
|
||
|
rc = UnAsmTermObj(pterm, ppbOp);
|
||
|
}
|
||
|
else if (OpClassTable[**ppbOp] == OPCLASS_NAME_OBJ)
|
||
|
{
|
||
|
rc = UnAsmNameObj(ppbOp, NULL, NSTYPE_UNKNOWN);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = UnAsmDataObj(ppbOp);
|
||
|
}
|
||
|
|
||
|
if (rc != UNASMERR_NONE)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
else if (*ppbOp < pbEnd)
|
||
|
{
|
||
|
PRINTF(",");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (rc == UNASMERR_NONE)
|
||
|
{
|
||
|
giLevel--;
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("}");
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmPkgList
|
||
|
|
||
|
/***LP UnAsmFieldList - Unassemble field list
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pbEnd -> end of list
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmFieldList(PUCHAR *ppbOp, PUCHAR pbEnd)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
ULONG dwBitPos = 0;
|
||
|
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("{");
|
||
|
giLevel++;
|
||
|
|
||
|
while (*ppbOp < pbEnd)
|
||
|
{
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
if ((rc = UnAsmField(ppbOp, &dwBitPos)) == UNASMERR_NONE)
|
||
|
{
|
||
|
if (*ppbOp < pbEnd)
|
||
|
{
|
||
|
PRINTF(",");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (rc == UNASMERR_NONE)
|
||
|
{
|
||
|
giLevel--;
|
||
|
Indent(*ppbOp, giLevel);
|
||
|
PRINTF("}");
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmFieldList
|
||
|
|
||
|
/***LP UnAsmField - Unassemble field
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ppbOp -> opcode pointer
|
||
|
* pdwBitPos -> to hold cumulative bit position
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns UNASMERR_NONE
|
||
|
* EXIT-FAILURE
|
||
|
* returns negative error code
|
||
|
*/
|
||
|
|
||
|
LONG LOCAL UnAsmField(PUCHAR *ppbOp, PULONG pdwBitPos)
|
||
|
{
|
||
|
LONG rc = UNASMERR_NONE;
|
||
|
|
||
|
if (**ppbOp == 0x01)
|
||
|
{
|
||
|
PASLTERM pterm = NULL;
|
||
|
|
||
|
(*ppbOp)++;
|
||
|
pterm = FindKeywordTerm('A', **ppbOp);
|
||
|
if (pterm != NULL) {
|
||
|
|
||
|
PRINTF("AccessAs(%s, 0x%x)", pterm->pszID, *(*ppbOp + 1));
|
||
|
|
||
|
}
|
||
|
*ppbOp += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char szNameSeg[sizeof(NAMESEG) + 1];
|
||
|
ULONG dwcbBits;
|
||
|
|
||
|
if (**ppbOp == 0)
|
||
|
{
|
||
|
szNameSeg[0] = '\0';
|
||
|
(*ppbOp)++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
STRCPYN(szNameSeg, (PSZ)*ppbOp, sizeof(NAMESEG));
|
||
|
szNameSeg[4] = '\0';
|
||
|
*ppbOp += sizeof(NAMESEG);
|
||
|
}
|
||
|
|
||
|
dwcbBits = ParsePackageLen(ppbOp, NULL);
|
||
|
if (szNameSeg[0] == '\0')
|
||
|
{
|
||
|
if ((dwcbBits > 32) && (((*pdwBitPos + dwcbBits) % 8) == 0))
|
||
|
{
|
||
|
PRINTF("Offset(0x%x)", (*pdwBitPos + dwcbBits)/8);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PRINTF(", %d", dwcbBits);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PRINTF("%s, %d", szNameSeg, dwcbBits);
|
||
|
}
|
||
|
|
||
|
*pdwBitPos += dwcbBits;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
} //UnAsmField
|