1747 lines
43 KiB
C
1747 lines
43 KiB
C
/*** unasm.c - Unassemble AML file and convert to Intel .ASM file
|
|
*
|
|
* Copyright (c) 1996,1997 Microsoft Corporation
|
|
* Author: Michael Tsang (MikeTs)
|
|
* Created: 10/01/97
|
|
*
|
|
* MODIFICATION HISTORY
|
|
*/
|
|
|
|
#include "pch.h"
|
|
|
|
//
|
|
// Local data
|
|
//
|
|
int giLevel = 0;
|
|
|
|
/***LP UnAsmFile - Unassemble AML file
|
|
*
|
|
* ENTRY
|
|
* pszAMLName -> AML file name
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmFile(PSZ pszAMLName, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PBYTE pb = NULL;
|
|
DWORD dwAddr = 0;
|
|
int fhAML = 0;
|
|
ULONG dwLen = 0;
|
|
|
|
ENTER((1, "UnAsmFile(AMLName=%s,pfnPrint=%p,pv=%p)\n",
|
|
pszAMLName, pfnPrint, pv));
|
|
ASSERT(pfnPrint != NULL);
|
|
|
|
if (gpszAMLFile != NULL)
|
|
{
|
|
if ((fhAML = _open(gpszAMLFile, _O_BINARY | _O_RDONLY)) == -1)
|
|
{
|
|
ERROR(("UnAsmFile: failed to open AML file - %s", gpszAMLFile));
|
|
rc = ASLERR_OPEN_FILE;
|
|
}
|
|
else if ((pb = MEMALLOC(sizeof(DESCRIPTION_HEADER))) == NULL)
|
|
{
|
|
ERROR(("UnAsmFile: failed to allocate description header block"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else if (_read(fhAML, pb, sizeof(DESCRIPTION_HEADER)) !=
|
|
sizeof(DESCRIPTION_HEADER))
|
|
{
|
|
ERROR(("UnAsmFile: failed to read description header block"));
|
|
rc = ASLERR_READ_FILE;
|
|
}
|
|
else if (_lseek(fhAML, 0, SEEK_SET) == -1)
|
|
{
|
|
ERROR(("UnAsmFile: failed seeking to beginning of AML file"));
|
|
rc = ASLERR_SEEK_FILE;
|
|
}
|
|
else
|
|
{
|
|
dwLen = ((PDESCRIPTION_HEADER)pb)->Length;
|
|
MEMFREE(pb);
|
|
if ((pb = MEMALLOC(dwLen)) == NULL)
|
|
{
|
|
ERROR(("UnAsmFile: failed to allocate AML file buffer"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else if (_read(fhAML, pb, dwLen) != (int)dwLen)
|
|
{
|
|
ERROR(("UnAsmFile: failed to read AML file"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
}
|
|
}
|
|
#ifdef __UNASM
|
|
else
|
|
{
|
|
DWORD dwTableSig = (gdwfASL & ASLF_DUMP_NONASL)? *((PDWORD)pszAMLName):
|
|
*((PDWORD)gpszTabSig);
|
|
|
|
ASSERT(gpszTabSig != NULL);
|
|
|
|
if ((pb = GetTableBySig(dwTableSig, &dwAddr)) != NULL)
|
|
{
|
|
dwLen = ((PDESCRIPTION_HEADER)pb)->Length;
|
|
}
|
|
else
|
|
{
|
|
rc = ASLERR_GET_TABLE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
rc = UnAsmAML(pszAMLName, dwAddr, pb, pfnPrint, pv);
|
|
}
|
|
|
|
if (pb != NULL)
|
|
{
|
|
MEMFREE(pb);
|
|
}
|
|
|
|
if (fhAML != 0)
|
|
{
|
|
_close(fhAML);
|
|
}
|
|
|
|
EXIT((1, "UnAsmFile=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmFile
|
|
|
|
/***LP BuildNameSpace - Do a NameSpace building pass
|
|
*
|
|
* ENTRY
|
|
* pszAMLName -> AML file name
|
|
* dwAddr - physical address of table
|
|
* pb -> AML buffer
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL BuildNameSpace(PSZ pszAMLName, DWORD dwAddr, PBYTE pb)
|
|
{
|
|
typedef struct _AMLName
|
|
{
|
|
struct _AMLName *panNext;
|
|
PSZ pszAMLName;
|
|
DWORD dwAddr;
|
|
} AMLNAME, *PAMLNAME;
|
|
int rc = ASLERR_NONE;
|
|
static PAMLNAME panAMLNames = NULL;
|
|
PAMLNAME pan;
|
|
|
|
ENTER((2, "BuildNameSpace(AMLName=%s,Addr=%x,pb=%p)\n",
|
|
pszAMLName, dwAddr, pb));
|
|
|
|
for (pan = panAMLNames; pan != NULL; pan = pan->panNext)
|
|
{
|
|
if ((strcmp(pszAMLName, pan->pszAMLName) == 0) &&
|
|
(dwAddr == pan->dwAddr))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pan == NULL)
|
|
{
|
|
if ((pan = MEMALLOC(sizeof(AMLNAME))) != NULL)
|
|
{
|
|
DWORD dwLen = ((PDESCRIPTION_HEADER)pb)->Length;
|
|
|
|
pan->pszAMLName = pszAMLName;
|
|
pan->dwAddr = dwAddr;
|
|
pan->panNext = panAMLNames;
|
|
panAMLNames = pan;
|
|
pb += sizeof(DESCRIPTION_HEADER);
|
|
rc = UnAsmScope(&pb, pb + dwLen - sizeof(DESCRIPTION_HEADER), NULL,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
ERROR(("BuildNameSpace: failed to allocate AMLName entry"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "BuildNameSpace=%d\n", rc));
|
|
return rc;
|
|
} //BuildNameSpace
|
|
|
|
/***LP UnAsmAML - Unassemble AML buffer
|
|
*
|
|
* ENTRY
|
|
* pszAMLName -> AML file name
|
|
* dwAddr - physical address of table
|
|
* pb -> AML buffer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmAML(PSZ pszAMLName, DWORD dwAddr, PBYTE pb, PFNPRINT pfnPrint,
|
|
PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PDESCRIPTION_HEADER pdh = (PDESCRIPTION_HEADER)pb;
|
|
|
|
ENTER((2, "UnAsmAML(AMLName=%s,Addr=%x,pb=%p,pfnPrint=%p,pv=%p)\n",
|
|
pszAMLName, dwAddr, pb, pfnPrint, pv));
|
|
|
|
ASSERT(gpnsNameSpaceRoot != NULL);
|
|
gpnsCurrentOwner = NULL;
|
|
gpnsCurrentScope = gpnsNameSpaceRoot;
|
|
|
|
if (ComputeDataChkSum(pb, pdh->Length) != 0)
|
|
{
|
|
ERROR(("UnAsmAML: failed to verify AML checksum"));
|
|
rc = ASLERR_CHECKSUM;
|
|
}
|
|
else if ((rc = BuildNameSpace(pszAMLName, dwAddr, pb)) == ASLERR_NONE)
|
|
{
|
|
gpbOpTop = gpbOpBegin = pb;
|
|
if ((rc = UnAsmHeader(pszAMLName, pdh, pfnPrint, pv)) == ASLERR_NONE)
|
|
{
|
|
pb += sizeof(DESCRIPTION_HEADER);
|
|
rc = UnAsmScope(&pb, pb + pdh->Length - sizeof(DESCRIPTION_HEADER),
|
|
pfnPrint, pv);
|
|
|
|
if ((rc == ASLERR_NONE) && (pfnPrint != NULL))
|
|
{
|
|
pfnPrint(pv, "\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((2, "UnAsmAML=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmAML
|
|
|
|
/***LP UnAsmHeader - Unassemble table header
|
|
*
|
|
* ENTRY
|
|
* pszAMLName -> AML file name
|
|
* pdh -> DESCRIPTION_HEADER
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmHeader(PSZ pszAMLName, PDESCRIPTION_HEADER pdh,
|
|
PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
char szSig[sizeof(pdh->Signature) + 1] = {0};
|
|
char szOEMID[sizeof(pdh->OEMID) + 1] = {0};
|
|
char szOEMTableID[sizeof(pdh->OEMTableID) + 1] = {0};
|
|
char szCreatorID[sizeof(pdh->CreatorID) + 1] = {0};
|
|
|
|
ENTER((2, "UnAsmHeader(AMLName=%s,pdh=%p,pfnPrint=%p,pv=%p)\n",
|
|
pszAMLName, pdh, pfnPrint, pv));
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
strncpy(szSig, (PSZ)&pdh->Signature, sizeof(pdh->Signature));
|
|
strncpy(szOEMID, (PSZ)pdh->OEMID, sizeof(pdh->OEMID));
|
|
strncpy(szOEMTableID, (PSZ)pdh->OEMTableID, sizeof(pdh->OEMTableID));
|
|
strncpy(szCreatorID, (PSZ)pdh->CreatorID, sizeof(pdh->CreatorID));
|
|
|
|
if ((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))
|
|
{
|
|
pfnPrint(pv, "; ");
|
|
}
|
|
|
|
pfnPrint(pv, "// CreatorID=%s\tCreatorRev=%x.%x.%d\n",
|
|
szCreatorID, pdh->CreatorRev >> 24,
|
|
(pdh->CreatorRev >> 16) & 0xff, pdh->CreatorRev & 0xffff);
|
|
|
|
if ((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))
|
|
{
|
|
pfnPrint(pv, "; ");
|
|
}
|
|
|
|
pfnPrint(pv, "// FileLength=%d\tFileChkSum=0x%x\n\n",
|
|
pdh->Length, pdh->Checksum);
|
|
|
|
if ((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))
|
|
{
|
|
pfnPrint(pv, "; ");
|
|
}
|
|
|
|
pfnPrint(pv, "DefinitionBlock(\"%s\", \"%s\", 0x%02x, \"%s\", \"%s\", 0x%08x)",
|
|
pszAMLName, szSig, pdh->Revision, szOEMID, szOEMTableID,
|
|
pdh->OEMRevision);
|
|
}
|
|
|
|
EXIT((2, "UnAsmHeader=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmHeader
|
|
|
|
/***LP DumpBytes - Dump byte stream in ASM file
|
|
*
|
|
* ENTRY
|
|
* pb -> buffer
|
|
* dwLen - length to dump
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT
|
|
* None
|
|
*/
|
|
|
|
VOID LOCAL DumpBytes(PBYTE pb, DWORD dwLen, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int i;
|
|
#define MAX_LINE_BYTES 8
|
|
|
|
ENTER((2, "DumpBytes(pb=%p,Len=%x,pfnPrint=%p,pv=%p)\n",
|
|
pb, dwLen, pfnPrint, pv));
|
|
|
|
while (dwLen > 0)
|
|
{
|
|
pfnPrint(pv, "\tdb\t0%02xh", *pb);
|
|
for (i = 1; i < MAX_LINE_BYTES; ++i)
|
|
{
|
|
if ((int)dwLen - i > 0)
|
|
{
|
|
pfnPrint(pv, ", 0%02xh", pb[i]);
|
|
}
|
|
else
|
|
{
|
|
pfnPrint(pv, " ");
|
|
}
|
|
}
|
|
|
|
pfnPrint(pv, "\t; ");
|
|
for (i = 0; (dwLen > 0) && (i < MAX_LINE_BYTES); ++i)
|
|
{
|
|
pfnPrint(pv, "%c", ((*pb >= ' ') && (*pb <= '~'))? *pb: '.');
|
|
dwLen--;
|
|
pb++;
|
|
}
|
|
|
|
pfnPrint(pv, "\n");
|
|
}
|
|
pfnPrint(pv, "\n");
|
|
|
|
EXIT((2, "DumpBytes!\n"));
|
|
} //DumpBytes
|
|
|
|
/***LP DumpCode - Dump code stream in ASM file
|
|
*
|
|
* ENTRY
|
|
* pbOp -> Opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT
|
|
* None
|
|
*/
|
|
|
|
VOID LOCAL DumpCode(PBYTE pbOp, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
ENTER((2, "DumpCode(pbOp=%p,pfnPrint=%p,pv=%p)\n", pbOp, pfnPrint, pv));
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
if (gdwfASL & ASLF_GENASM)
|
|
{
|
|
if (gpbOpBegin != pbOp)
|
|
{
|
|
pfnPrint(pv, "\n");
|
|
pfnPrint(pv, "; %08x:\n", gpbOpBegin - gpbOpTop);
|
|
DumpBytes(gpbOpBegin, (DWORD)(pbOp - gpbOpBegin), pfnPrint, pv);
|
|
gpbOpBegin = pbOp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pfnPrint(pv, "\n");
|
|
}
|
|
}
|
|
|
|
EXIT((2, "DumpCode!\n"));
|
|
} //DumpCode
|
|
|
|
/***LP PrintIndent - Print indent level
|
|
*
|
|
* ENTRY
|
|
* iLevel - indent level
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT
|
|
* None
|
|
*/
|
|
|
|
VOID LOCAL PrintIndent(int iLevel, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int i;
|
|
|
|
ENTER((3, "PrintIndent(Level=%d,pfnPrint=%p,pv=%p)\n",
|
|
iLevel, pfnPrint, pv));
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
if ((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))
|
|
{
|
|
pfnPrint(pv, "; ");
|
|
}
|
|
|
|
for (i = 0; i < iLevel; ++i)
|
|
{
|
|
pfnPrint(pv,
|
|
((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))?
|
|
"| ": " ");
|
|
}
|
|
}
|
|
|
|
EXIT((3, "PrintIndent!\n"));
|
|
} //PrintIndent
|
|
|
|
/***LP FindOpClass - Find opcode class of extended opcode
|
|
*
|
|
* ENTRY
|
|
* bOp - opcode
|
|
* pOpTable -> opcode table
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns opcode class
|
|
* EXIT-FAILURE
|
|
* returns OPCLASS_INVALID
|
|
*/
|
|
|
|
BYTE LOCAL FindOpClass(BYTE bOp, POPMAP pOpTable)
|
|
{
|
|
BYTE bOpClass = OPCLASS_INVALID;
|
|
|
|
ENTER((2, "FindOpClass(Op=%x,pOpTable=%x)\n", bOp, pOpTable));
|
|
|
|
while (pOpTable->bOpClass != 0)
|
|
{
|
|
if (bOp == pOpTable->bExOp)
|
|
{
|
|
bOpClass = pOpTable->bOpClass;
|
|
break;
|
|
}
|
|
else
|
|
pOpTable++;
|
|
}
|
|
|
|
EXIT((2, "FindOpClass=%x\n", bOpClass));
|
|
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(DWORD dwOpcode)
|
|
{
|
|
PASLTERM pterm = NULL;
|
|
int i;
|
|
|
|
ENTER((2, "FindOpTerm(Opcode=%x)\n", dwOpcode));
|
|
|
|
for (i = 0; TermTable[i].pszID != NULL; ++i)
|
|
{
|
|
if ((TermTable[i].dwOpcode == dwOpcode) &&
|
|
(TermTable[i].dwfTermClass &
|
|
(TC_CONST_NAME | TC_SHORT_NAME | TC_NAMESPACE_MODIFIER |
|
|
TC_DATA_OBJECT | TC_NAMED_OBJECT | TC_OPCODE_TYPE1 |
|
|
TC_OPCODE_TYPE2)))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (TermTable[i].pszID != NULL)
|
|
{
|
|
pterm = &TermTable[i];
|
|
}
|
|
|
|
EXIT((2, "FindOpTerm=%p (Term=%s)\n", pterm, pterm? pterm->pszID: ""));
|
|
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, BYTE bData)
|
|
{
|
|
PASLTERM pterm = NULL;
|
|
int i;
|
|
|
|
ENTER((2, "FindKeywordTerm(cKWGroup=%c,Data=%x)\n", cKWGroup, bData));
|
|
|
|
for (i = 0; TermTable[i].pszID != NULL; ++i)
|
|
{
|
|
if ((TermTable[i].dwfTermClass == TC_KEYWORD) &&
|
|
(TermTable[i].pszArgActions[0] == cKWGroup) &&
|
|
((bData & (BYTE)(TermTable[i].dwTermData >> 8)) ==
|
|
(BYTE)(TermTable[i].dwTermData & 0xff)))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (TermTable[i].pszID != NULL)
|
|
{
|
|
pterm = &TermTable[i];
|
|
}
|
|
|
|
EXIT((2, "FindKeywordTerm=%p (Term=%s)\n", pterm, pterm? pterm->pszID: ""));
|
|
return pterm;
|
|
} //FindKeywordTerm
|
|
|
|
/***LP UnAsmScope - Unassemble a scope
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> Opcode pointer
|
|
* pbEnd -> end of scope
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmScope(PBYTE *ppbOp, PBYTE pbEnd, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
|
|
ENTER((2, "UnAsmScope(pbOp=%p,pbEnd=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pbEnd, pfnPrint, pv));
|
|
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "{\n");
|
|
}
|
|
giLevel++;
|
|
|
|
while ((rc == ASLERR_NONE) && (*ppbOp < pbEnd))
|
|
{
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
rc = UnAsmOpcode(ppbOp, pfnPrint, pv);
|
|
if (gpbOpBegin != *ppbOp)
|
|
{
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
}
|
|
else if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "\n");
|
|
}
|
|
}
|
|
|
|
giLevel--;
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "}");
|
|
}
|
|
|
|
EXIT((2, "UnAsmScope=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmScope
|
|
|
|
/***LP UnAsmOpcode - Unassemble an Opcode
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> Opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmOpcode(PBYTE *ppbOp, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
DWORD dwOpcode;
|
|
BYTE bOp;
|
|
PASLTERM pterm;
|
|
char szUnAsmArgTypes[MAX_ARGS + 1];
|
|
PNSOBJ pns;
|
|
int i;
|
|
|
|
ENTER((2, "UnAsmOpcode(pbOp=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pfnPrint, pv));
|
|
|
|
if (**ppbOp == OP_EXT_PREFIX)
|
|
{
|
|
(*ppbOp)++;
|
|
dwOpcode = (((DWORD)**ppbOp) << 8) | OP_EXT_PREFIX;
|
|
bOp = FindOpClass(**ppbOp, ExOpClassTable);
|
|
}
|
|
else
|
|
{
|
|
dwOpcode = (DWORD)(**ppbOp);
|
|
bOp = OpClassTable[**ppbOp];
|
|
}
|
|
|
|
switch (bOp)
|
|
{
|
|
case OPCLASS_DATA_OBJ:
|
|
rc = UnAsmDataObj(ppbOp, pfnPrint, pv);
|
|
break;
|
|
|
|
case OPCLASS_NAME_OBJ:
|
|
if (((rc = UnAsmNameObj(ppbOp, pfnPrint, pv, &pns, NSTYPE_UNKNOWN))
|
|
== ASLERR_NONE) &&
|
|
(pns != NULL) &&
|
|
(pns->ObjData.dwDataType == OBJTYPE_METHOD))
|
|
{
|
|
for (i = 0; i < (int)pns->ObjData.uipDataValue; ++i)
|
|
{
|
|
szUnAsmArgTypes[i] = 'C';
|
|
}
|
|
szUnAsmArgTypes[i] = '\0';
|
|
rc = UnAsmArgs(szUnAsmArgTypes, NULL, 0, ppbOp, NULL, pfnPrint,
|
|
pv);
|
|
}
|
|
break;
|
|
|
|
case OPCLASS_ARG_OBJ:
|
|
case OPCLASS_LOCAL_OBJ:
|
|
case OPCLASS_CODE_OBJ:
|
|
case OPCLASS_CONST_OBJ:
|
|
if ((pterm = FindOpTerm(dwOpcode)) == NULL)
|
|
{
|
|
ERROR(("UnAsmOpcode: invalid opcode 0x%x", dwOpcode));
|
|
rc = ASLERR_INVALID_OPCODE;
|
|
}
|
|
else
|
|
{
|
|
(*ppbOp)++;
|
|
rc = UnAsmTermObj(pterm, ppbOp, pfnPrint, pv);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ERROR(("UnAsmOpcode: invalid opcode class %d", bOp));
|
|
rc = ASLERR_INTERNAL_ERROR;
|
|
}
|
|
|
|
EXIT((2, "UnAsmOpcode=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmOpcode
|
|
|
|
/***LP UnAsmDataObj - Unassemble data object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmDataObj(PBYTE *ppbOp, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
BYTE bOp = **ppbOp;
|
|
|
|
ENTER((2, "UnAsmDataObj(pbOp=%p,bOp=%x,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, bOp, pfnPrint, pv));
|
|
|
|
(*ppbOp)++;
|
|
switch (bOp)
|
|
{
|
|
case OP_BYTE:
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", **ppbOp);
|
|
}
|
|
*ppbOp += sizeof(BYTE);
|
|
break;
|
|
|
|
case OP_WORD:
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", *((PWORD)*ppbOp));
|
|
}
|
|
*ppbOp += sizeof(WORD);
|
|
break;
|
|
|
|
case OP_DWORD:
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", *((PDWORD)*ppbOp));
|
|
}
|
|
*ppbOp += sizeof(DWORD);
|
|
break;
|
|
|
|
case OP_STRING:
|
|
if (pfnPrint != NULL)
|
|
{
|
|
PSZ psz;
|
|
|
|
pfnPrint(pv, "\"");
|
|
for (psz = (PSZ)*ppbOp; *psz != '\0'; psz++)
|
|
{
|
|
if (*psz == '\\')
|
|
{
|
|
pfnPrint(pv, "\\");
|
|
}
|
|
pfnPrint(pv, "%c", *psz);
|
|
}
|
|
pfnPrint(pv, "\"");
|
|
}
|
|
*ppbOp += strlen((PSZ)*ppbOp) + 1;
|
|
break;
|
|
|
|
default:
|
|
ERROR(("UnAsmDataObj: unexpected opcode 0x%x", bOp));
|
|
rc = ASLERR_INVALID_OPCODE;
|
|
}
|
|
|
|
EXIT((2, "UnAsmDataObj=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmDataObj
|
|
|
|
/***LP UnAsmNameObj - Unassemble name object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
* ppns -> to hold object found or created
|
|
* c - object type
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmNameObj(PBYTE *ppbOp, PFNPRINT pfnPrint, PVOID pv, PNSOBJ *ppns,
|
|
char c)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
char szName[MAX_NSPATH_LEN + 1];
|
|
int iLen = 0;
|
|
|
|
ENTER((2, "UnAsmNameObj(pbOp=%p,pfnPrint=%p,pv=%p,ppns=%p,c=%c)\n",
|
|
*ppbOp, pfnPrint, pv, ppns, c));
|
|
|
|
szName[0] = '\0';
|
|
if (**ppbOp == OP_ROOT_PREFIX)
|
|
{
|
|
szName[iLen] = '\\';
|
|
iLen++;
|
|
(*ppbOp)++;
|
|
rc = ParseNameTail(ppbOp, szName, iLen);
|
|
}
|
|
else if (**ppbOp == OP_PARENT_PREFIX)
|
|
{
|
|
szName[iLen] = '^';
|
|
iLen++;
|
|
(*ppbOp)++;
|
|
while ((**ppbOp == OP_PARENT_PREFIX) && (iLen < MAX_NSPATH_LEN))
|
|
{
|
|
szName[iLen] = '^';
|
|
iLen++;
|
|
(*ppbOp)++;
|
|
}
|
|
|
|
if (**ppbOp == OP_PARENT_PREFIX)
|
|
{
|
|
ERROR(("UnAsmNameObj: name too long - \"%s\"", szName));
|
|
rc = ASLERR_NAME_TOO_LONG;
|
|
}
|
|
else
|
|
{
|
|
rc = ParseNameTail(ppbOp, szName, iLen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = ParseNameTail(ppbOp, szName, iLen);
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
PNSOBJ pns = NULL;
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "%s", szName);
|
|
}
|
|
|
|
if (islower(c) && (gdwfASL & ASLF_UNASM) &&
|
|
((pfnPrint == NULL) ||
|
|
(gpnsCurrentScope->ObjData.dwDataType == OBJTYPE_METHOD)))
|
|
{
|
|
rc = CreateObject(NULL, szName, (char)_toupper(c), &pns);
|
|
if ((rc == ASLERR_NSOBJ_EXIST) &&
|
|
(gpnsCurrentScope->ObjData.dwDataType == OBJTYPE_METHOD))
|
|
{
|
|
//
|
|
// If we are creating an object inside a method scope, it
|
|
// may already exist because we may have unassembled this
|
|
// method before. So it is not an error.
|
|
//
|
|
rc = ASLERR_NONE;
|
|
}
|
|
}
|
|
else if ((rc = GetNameSpaceObj(szName, gpnsCurrentScope, &pns, 0)) ==
|
|
ASLERR_NSOBJ_NOT_FOUND)
|
|
{
|
|
if (c == NSTYPE_SCOPE)
|
|
{
|
|
rc = CreateScopeObj(szName, &pns);
|
|
}
|
|
else
|
|
{
|
|
rc = ASLERR_NONE;
|
|
}
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
if ((c == NSTYPE_SCOPE) && (pns != NULL))
|
|
{
|
|
gpnsCurrentScope = pns;
|
|
}
|
|
|
|
if (ppns != NULL)
|
|
{
|
|
*ppns = pns;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((2, "UnAsmNameObj=%d (pns=%p)\n", rc, ppns? *ppns: 0));
|
|
return rc;
|
|
} //UnAsmNameObj
|
|
|
|
/***LP ParseNameTail - Parse AML name tail
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pszBuff -> to hold parsed name
|
|
* iLen - index to tail of pszBuff
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseNameTail(PBYTE *ppbOp, PSZ pszBuff, int iLen)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
int icNameSegs = 0;
|
|
|
|
ENTER((2, "ParseNameTail(pbOp=%x,Name=%s,iLen=%d)\n",
|
|
*ppbOp, pszBuff, iLen));
|
|
|
|
//
|
|
// 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_NSPATH_LEN))
|
|
{
|
|
strncpy(&pszBuff[iLen], (PSZ)(*ppbOp), sizeof(NAMESEG));
|
|
iLen += sizeof(NAMESEG);
|
|
*ppbOp += sizeof(NAMESEG);
|
|
icNameSegs--;
|
|
if ((icNameSegs > 0) && (iLen + 1 < MAX_NSPATH_LEN))
|
|
{
|
|
pszBuff[iLen] = '.';
|
|
iLen++;
|
|
}
|
|
}
|
|
|
|
if (icNameSegs > 0)
|
|
{
|
|
ERROR(("ParseNameTail: name too long - %s", pszBuff));
|
|
rc = ASLERR_NAME_TOO_LONG;
|
|
}
|
|
else
|
|
{
|
|
pszBuff[iLen] = '\0';
|
|
}
|
|
|
|
EXIT((2, "ParseNameTail=%x (Name=%s)\n", rc, pszBuff));
|
|
return rc;
|
|
} //ParseNameTail
|
|
|
|
/***LP UnAsmTermObj - Unassemble term object
|
|
*
|
|
* ENTRY
|
|
* pterm -> term table entry
|
|
* ppbOp -> opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmTermObj(PASLTERM pterm, PBYTE *ppbOp, PFNPRINT pfnPrint,
|
|
PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PBYTE pbEnd = NULL;
|
|
PNSOBJ pnsScopeSave = gpnsCurrentScope;
|
|
PNSOBJ pns = NULL;
|
|
|
|
ENTER((2, "UnAsmTermObj(pterm=%p,Term=%s,pbOp=%p,pfnPrint=%p,pv=%p)\n",
|
|
pterm, pterm->pszID, *ppbOp, pfnPrint, pv));
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "%s", pterm->pszID);
|
|
}
|
|
|
|
if (pterm->dwfTerm & TF_PACKAGE_LEN)
|
|
{
|
|
ParsePackageLen(ppbOp, &pbEnd);
|
|
}
|
|
|
|
if (pterm->pszUnAsmArgTypes != NULL)
|
|
{
|
|
rc = UnAsmArgs(pterm->pszUnAsmArgTypes, pterm->pszArgActions,
|
|
pterm->dwTermData, ppbOp, &pns, pfnPrint, pv);
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
if (pterm->dwfTerm & TF_DATA_LIST)
|
|
{
|
|
rc = UnAsmDataList(ppbOp, pbEnd, pfnPrint, pv);
|
|
}
|
|
else if (pterm->dwfTerm & TF_PACKAGE_LIST)
|
|
{
|
|
rc = UnAsmPkgList(ppbOp, pbEnd, pfnPrint, pv);
|
|
}
|
|
else if (pterm->dwfTerm & TF_FIELD_LIST)
|
|
{
|
|
rc = UnAsmFieldList(ppbOp, pbEnd, pfnPrint, pv);
|
|
}
|
|
else if (pterm->dwfTerm & TF_PACKAGE_LEN)
|
|
{
|
|
if ((pfnPrint == NULL) && (pterm->lID == ID_METHOD))
|
|
{
|
|
//
|
|
// We are in NameSpace building pass, so don't need to
|
|
// go into methods.
|
|
//
|
|
*ppbOp = pbEnd;
|
|
}
|
|
else
|
|
{
|
|
if (pterm->dwfTerm & TF_CHANGE_CHILDSCOPE)
|
|
{
|
|
ASSERT(pns != NULL);
|
|
gpnsCurrentScope = pns;
|
|
}
|
|
|
|
rc = UnAsmScope(ppbOp, pbEnd, pfnPrint, pv);
|
|
}
|
|
}
|
|
}
|
|
gpnsCurrentScope = pnsScopeSave;
|
|
|
|
EXIT((2, "UnAsmTermObj=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmTermObj
|
|
|
|
/***LP UnAsmArgs - Unassemble arguments
|
|
*
|
|
* ENTRY
|
|
* pszUnArgTypes -> UnAsm ArgTypes string
|
|
* pszArgActions -> Arg Action types
|
|
* dwTermData - Term data
|
|
* ppbOp -> opcode pointer
|
|
* ppns -> to hold created object
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmArgs(PSZ pszUnAsmArgTypes, PSZ pszArgActions, DWORD dwTermData,
|
|
PBYTE *ppbOp, PNSOBJ *ppns, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
static BYTE bArgData = 0;
|
|
int iNumArgs, i;
|
|
PASLTERM pterm;
|
|
|
|
ENTER((2, "UnAsmArgs(UnAsmArgTypes=%s,ArgActions=%s,TermData=%x,pbOp=%p,ppns=%p,pfnPrint=%p,pv=%p)\n",
|
|
pszUnAsmArgTypes, pszArgActions? pszArgActions: "", dwTermData,
|
|
*ppbOp, ppns, pfnPrint, pv));
|
|
|
|
iNumArgs = strlen(pszUnAsmArgTypes);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "(");
|
|
}
|
|
|
|
for (i = 0; i < iNumArgs; ++i)
|
|
{
|
|
if ((i != 0) && (pfnPrint != NULL))
|
|
{
|
|
pfnPrint(pv, ", ");
|
|
}
|
|
|
|
switch (pszUnAsmArgTypes[i])
|
|
{
|
|
case 'N':
|
|
ASSERT(pszArgActions != NULL);
|
|
rc = UnAsmNameObj(ppbOp, pfnPrint, pv, ppns, pszArgActions[i]);
|
|
break;
|
|
|
|
case 'O':
|
|
if ((**ppbOp == OP_BUFFER) || (**ppbOp == OP_PACKAGE) ||
|
|
(OpClassTable[**ppbOp] == OPCLASS_CONST_OBJ))
|
|
{
|
|
pterm = FindOpTerm((DWORD)(**ppbOp));
|
|
|
|
if(pterm)
|
|
{
|
|
(*ppbOp)++;
|
|
rc = UnAsmTermObj(pterm, ppbOp, pfnPrint, pv);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pterm != NULL);
|
|
rc = ASLERR_INVALID_OPCODE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = UnAsmDataObj(ppbOp, pfnPrint, pv);
|
|
}
|
|
break;
|
|
|
|
case 'C':
|
|
rc = UnAsmOpcode(ppbOp, pfnPrint, pv);
|
|
break;
|
|
|
|
case 'B':
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", **ppbOp);
|
|
}
|
|
|
|
*ppbOp += sizeof(BYTE);
|
|
break;
|
|
|
|
case 'E':
|
|
case 'e':
|
|
case 'K':
|
|
case 'k':
|
|
if ((pszUnAsmArgTypes[i] == 'K') ||
|
|
(pszUnAsmArgTypes[i] == 'E'))
|
|
{
|
|
bArgData = **ppbOp;
|
|
}
|
|
|
|
if ((pszArgActions != NULL) && (pszArgActions[i] == '!'))
|
|
{
|
|
if ((gdwfASL & ASLF_UNASM) && (*ppns != NULL))
|
|
{
|
|
(*ppns)->ObjData.uipDataValue = (DWORD)(**ppbOp & 0x07);
|
|
}
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", **ppbOp & 0x07);
|
|
}
|
|
}
|
|
else if (pfnPrint != NULL)
|
|
{
|
|
pterm = FindKeywordTerm(pszArgActions[i], bArgData);
|
|
if (pterm != NULL)
|
|
{
|
|
pfnPrint(pv, "%s", pterm->pszID);
|
|
}
|
|
else
|
|
{
|
|
pfnPrint(pv, "0x%x", bArgData & dwTermData & 0xff);
|
|
}
|
|
}
|
|
|
|
if ((pszUnAsmArgTypes[i] == 'K') ||
|
|
(pszUnAsmArgTypes[i] == 'E'))
|
|
{
|
|
*ppbOp += sizeof(BYTE);
|
|
}
|
|
break;
|
|
|
|
case 'W':
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", *((PWORD)*ppbOp));
|
|
}
|
|
|
|
*ppbOp += sizeof(WORD);
|
|
break;
|
|
|
|
case 'D':
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "0x%x", *((PDWORD)*ppbOp));
|
|
}
|
|
|
|
*ppbOp += sizeof(DWORD);
|
|
break;
|
|
|
|
case 'S':
|
|
ASSERT(pszArgActions != NULL);
|
|
rc = UnAsmSuperName(ppbOp, pfnPrint, pv);
|
|
break;
|
|
|
|
default:
|
|
ERROR(("UnAsmOpcode: invalid ArgType '%c'", pszUnAsmArgTypes[i]));
|
|
rc = ASLERR_INVALID_ARGTYPE;
|
|
}
|
|
}
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, ")");
|
|
}
|
|
|
|
EXIT((2, "UnAsmArgs=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmArgs
|
|
|
|
/***LP UnAsmSuperName - Unassemble supername
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmSuperName(PBYTE *ppbOp, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
|
|
ENTER((2, "UnAsmSuperName(pbOp=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pfnPrint, pv));
|
|
|
|
if (**ppbOp == 0)
|
|
{
|
|
(*ppbOp)++;
|
|
}
|
|
else if ((**ppbOp == OP_EXT_PREFIX) && (*(*ppbOp + 1) == EXOP_DEBUG))
|
|
{
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "Debug");
|
|
}
|
|
*ppbOp += 2;
|
|
}
|
|
else if (OpClassTable[**ppbOp] == OPCLASS_NAME_OBJ)
|
|
{
|
|
rc = UnAsmNameObj(ppbOp, pfnPrint, pv, NULL, NSTYPE_UNKNOWN);
|
|
}
|
|
else if ((**ppbOp == OP_INDEX) ||
|
|
(OpClassTable[**ppbOp] == OPCLASS_ARG_OBJ) ||
|
|
(OpClassTable[**ppbOp] == OPCLASS_LOCAL_OBJ))
|
|
{
|
|
rc = UnAsmOpcode(ppbOp, pfnPrint, pv);
|
|
}
|
|
else
|
|
{
|
|
ERROR(("UnAsmSuperName: invalid SuperName - 0x%02x", **ppbOp));
|
|
rc = ASLERR_INVALID_NAME;
|
|
}
|
|
|
|
EXIT((2, "UnAsmSuperName=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmSuperName
|
|
|
|
/***LP ParsePackageLen - parse package length
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> instruction pointer
|
|
* ppbOpNext -> to hold pointer to next instruction (can be NULL)
|
|
*
|
|
* EXIT
|
|
* returns package length
|
|
*/
|
|
|
|
DWORD LOCAL ParsePackageLen(PBYTE *ppbOp, PBYTE *ppbOpNext)
|
|
{
|
|
DWORD dwLen;
|
|
BYTE bFollowCnt, i;
|
|
|
|
ENTER((2, "ParsePackageLen(pbOp=%x,ppbOpNext=%x)\n", *ppbOp, ppbOpNext));
|
|
|
|
if (ppbOpNext != NULL)
|
|
*ppbOpNext = *ppbOp;
|
|
|
|
dwLen = (DWORD)(**ppbOp);
|
|
(*ppbOp)++;
|
|
bFollowCnt = (BYTE)((dwLen & 0xc0) >> 6);
|
|
if (bFollowCnt != 0)
|
|
{
|
|
dwLen &= 0x0000000f;
|
|
for (i = 0; i < bFollowCnt; ++i)
|
|
{
|
|
dwLen |= (DWORD)(**ppbOp) << (i*8 + 4);
|
|
(*ppbOp)++;
|
|
}
|
|
}
|
|
|
|
if (ppbOpNext != NULL)
|
|
*ppbOpNext += dwLen;
|
|
|
|
EXIT((2, "ParsePackageLen=%x (pbOp=%x,pbOpNext=%x)\n",
|
|
dwLen, *ppbOp, ppbOpNext? *ppbOpNext: 0));
|
|
return dwLen;
|
|
} //ParsePackageLen
|
|
|
|
/***LP UnAsmDataList - Unassemble data list
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pbEnd -> end of list
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmDataList(PBYTE *ppbOp, PBYTE pbEnd, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
int i;
|
|
|
|
ENTER((2, "UnAsmDataList(pbOp=%p,pbEnd=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pbEnd, pfnPrint, pv));
|
|
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "{\n");
|
|
}
|
|
|
|
while (*ppbOp < pbEnd)
|
|
{
|
|
if (pfnPrint != NULL)
|
|
{
|
|
if ((gdwfASL & ASLF_GENASM) || !(gdwfASL & ASLF_GENSRC))
|
|
{
|
|
pfnPrint(pv, ";");
|
|
}
|
|
pfnPrint(pv, "\t0x%02x", **ppbOp);
|
|
}
|
|
|
|
(*ppbOp)++;
|
|
for (i = 1; (*ppbOp < pbEnd) && (i < 12); ++i)
|
|
{
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, ", 0x%02x", **ppbOp);
|
|
}
|
|
(*ppbOp)++;
|
|
}
|
|
|
|
if (pfnPrint != NULL)
|
|
{
|
|
if (*ppbOp < pbEnd)
|
|
{
|
|
pfnPrint(pv, ",");
|
|
}
|
|
pfnPrint(pv, "\n");
|
|
}
|
|
}
|
|
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "}");
|
|
}
|
|
|
|
EXIT((2, "UnAsmDataList=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmDataList
|
|
|
|
/***LP UnAsmPkgList - Unassemble package list
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pbEnd -> end of list
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmPkgList(PBYTE *ppbOp, PBYTE pbEnd, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PASLTERM pterm;
|
|
|
|
ENTER((2, "UnAsmPkgList(pbOp=%p,pbEnd=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pbEnd, pfnPrint, pv));
|
|
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "{\n");
|
|
}
|
|
giLevel++;
|
|
|
|
while ((*ppbOp < pbEnd) && (rc == ASLERR_NONE))
|
|
{
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
|
|
if ((**ppbOp == OP_BUFFER) || (**ppbOp == OP_PACKAGE) ||
|
|
(OpClassTable[**ppbOp] == OPCLASS_CONST_OBJ))
|
|
{
|
|
pterm = FindOpTerm((DWORD)(**ppbOp));
|
|
ASSERT(pterm != NULL);
|
|
(*ppbOp)++;
|
|
rc = UnAsmTermObj(pterm, ppbOp, pfnPrint, pv);
|
|
}
|
|
else if (OpClassTable[**ppbOp] == OPCLASS_NAME_OBJ)
|
|
{
|
|
rc = UnAsmNameObj(ppbOp, pfnPrint, pv, NULL, NSTYPE_UNKNOWN);
|
|
}
|
|
else
|
|
{
|
|
rc = UnAsmDataObj(ppbOp, pfnPrint, pv);
|
|
}
|
|
|
|
if ((*ppbOp < pbEnd) && (rc == ASLERR_NONE) && (pfnPrint != NULL))
|
|
{
|
|
pfnPrint(pv, ",");
|
|
}
|
|
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
}
|
|
|
|
giLevel--;
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "}");
|
|
}
|
|
|
|
EXIT((2, "UnAsmPkgList=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmPkgList
|
|
|
|
/***LP UnAsmFieldList - Unassemble field list
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pbEnd -> end of list
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmFieldList(PBYTE *ppbOp, PBYTE pbEnd, PFNPRINT pfnPrint, PVOID pv)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
DWORD dwBitPos = 0;
|
|
|
|
ENTER((2, "UnAsmFieldList(pbOp=%p,pbEnd=%p,pfnPrint=%p,pv=%p)\n",
|
|
*ppbOp, pbEnd, pfnPrint, pv));
|
|
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "{\n");
|
|
}
|
|
giLevel++;
|
|
|
|
while ((*ppbOp < pbEnd) && (rc == ASLERR_NONE))
|
|
{
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (((rc = UnAsmField(ppbOp, pfnPrint, pv, &dwBitPos)) ==
|
|
ASLERR_NONE) &&
|
|
(*ppbOp < pbEnd) && (pfnPrint != NULL))
|
|
{
|
|
pfnPrint(pv, ",");
|
|
}
|
|
DumpCode(*ppbOp, pfnPrint, pv);
|
|
}
|
|
|
|
giLevel--;
|
|
PrintIndent(giLevel, pfnPrint, pv);
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "}");
|
|
}
|
|
|
|
EXIT((2, "UnAsmFieldList=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmFieldList
|
|
|
|
/***LP UnAsmField - Unassemble field
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pfnPrint -> print function
|
|
* pv - print function parameter
|
|
* pdwBitPos -> to hold cumulative bit position
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL UnAsmField(PBYTE *ppbOp, PFNPRINT pfnPrint, PVOID pv,
|
|
PDWORD pdwBitPos)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
|
|
ENTER((2, "UnAsmField(pbOp=%p,pfnPrint=%p,pv=%p,BitPos=%x)\n",
|
|
*ppbOp, pfnPrint, pv, *pdwBitPos));
|
|
|
|
if (**ppbOp == 0x01)
|
|
{
|
|
(*ppbOp)++;
|
|
if (pfnPrint != NULL)
|
|
{
|
|
PASLTERM pterm;
|
|
|
|
pterm = FindKeywordTerm('A', **ppbOp);
|
|
if(pterm)
|
|
pfnPrint(pv, "AccessAs(%s, 0x%x)",
|
|
pterm->pszID, *(*ppbOp + 1));
|
|
else
|
|
pfnPrint(pv, "FindKeywordTerm('A', **ppbOp); returned NULL");
|
|
}
|
|
*ppbOp += 2;
|
|
}
|
|
else
|
|
{
|
|
char szNameSeg[sizeof(NAMESEG) + 1];
|
|
DWORD dwcbBits;
|
|
|
|
if (**ppbOp == 0)
|
|
{
|
|
szNameSeg[0] = '\0';
|
|
(*ppbOp)++;
|
|
}
|
|
else
|
|
{
|
|
strncpy(szNameSeg, (PSZ)*ppbOp, sizeof(NAMESEG));
|
|
szNameSeg[4] = '\0';
|
|
*ppbOp += sizeof(NAMESEG);
|
|
}
|
|
|
|
dwcbBits = ParsePackageLen(ppbOp, NULL);
|
|
if (szNameSeg[0] == '\0')
|
|
{
|
|
if (pfnPrint != NULL)
|
|
{
|
|
if ((dwcbBits > 32) && (((*pdwBitPos + dwcbBits) % 8) == 0))
|
|
{
|
|
pfnPrint(pv, "Offset(0x%x)", (*pdwBitPos + dwcbBits)/8);
|
|
}
|
|
else
|
|
{
|
|
pfnPrint(pv, ", %d", dwcbBits);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pfnPrint != NULL)
|
|
{
|
|
pfnPrint(pv, "%s, %d", szNameSeg, dwcbBits);
|
|
}
|
|
|
|
if ((gdwfASL & ASLF_UNASM) && (pfnPrint == NULL))
|
|
{
|
|
rc = CreateObject(NULL, szNameSeg, NSTYPE_FIELDUNIT, NULL);
|
|
}
|
|
}
|
|
|
|
*pdwBitPos += dwcbBits;
|
|
}
|
|
|
|
EXIT((2, "UnAsmField=%d\n", rc));
|
|
return rc;
|
|
} //UnAsmField
|
|
|
|
/***LP CreateObject - Create NameSpace object for the term
|
|
*
|
|
* ENTRY
|
|
* ptoken -> TOKEN
|
|
* pszName -> object name
|
|
* c - object type to be created
|
|
* ppns -> to hold object created
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL CreateObject(PTOKEN ptoken, PSZ pszName, char c, PNSOBJ *ppns)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSOBJ pns;
|
|
|
|
ENTER((2, "CreateObject(ptoken=%p,Name=%s,Type=%c)\n",
|
|
ptoken, pszName, c));
|
|
|
|
if (((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pns, 0)) ==
|
|
ASLERR_NONE) &&
|
|
(pns->ObjData.dwDataType == OBJTYPE_EXTERNAL) ||
|
|
((rc = CreateNameSpaceObj(ptoken, pszName, gpnsCurrentScope,
|
|
gpnsCurrentOwner, &pns, NSF_EXIST_ERR)) ==
|
|
ASLERR_NONE))
|
|
{
|
|
#ifndef _UNASM_LIB
|
|
if (!(gdwfASL & ASLF_UNASM))
|
|
{
|
|
ASSERT(gpcodeScope->pnsObj == NULL);
|
|
gpcodeScope->dwfCode |= CF_CREATED_NSOBJ;
|
|
gpcodeScope->pnsObj = pns;
|
|
pns->Context = gpcodeScope;
|
|
}
|
|
#endif //ifndef _UNASM_LIB
|
|
|
|
switch (c)
|
|
{
|
|
case NSTYPE_UNKNOWN:
|
|
break;
|
|
|
|
case NSTYPE_FIELDUNIT:
|
|
pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
|
|
break;
|
|
|
|
case NSTYPE_DEVICE:
|
|
pns->ObjData.dwDataType = OBJTYPE_DEVICE;
|
|
break;
|
|
|
|
case NSTYPE_EVENT:
|
|
pns->ObjData.dwDataType = OBJTYPE_EVENT;
|
|
break;
|
|
|
|
case NSTYPE_METHOD:
|
|
pns->ObjData.dwDataType = OBJTYPE_METHOD;
|
|
break;
|
|
|
|
case NSTYPE_MUTEX:
|
|
pns->ObjData.dwDataType = OBJTYPE_MUTEX;
|
|
break;
|
|
|
|
case NSTYPE_OPREGION:
|
|
pns->ObjData.dwDataType = OBJTYPE_OPREGION;
|
|
break;
|
|
|
|
case NSTYPE_POWERRES:
|
|
pns->ObjData.dwDataType = OBJTYPE_POWERRES;
|
|
break;
|
|
|
|
case NSTYPE_PROCESSOR:
|
|
pns->ObjData.dwDataType = OBJTYPE_PROCESSOR;
|
|
break;
|
|
|
|
case NSTYPE_THERMALZONE:
|
|
pns->ObjData.dwDataType = OBJTYPE_THERMALZONE;
|
|
break;
|
|
|
|
case NSTYPE_OBJALIAS:
|
|
pns->ObjData.dwDataType = OBJTYPE_OBJALIAS;
|
|
break;
|
|
|
|
case NSTYPE_BUFFFIELD:
|
|
pns->ObjData.dwDataType = OBJTYPE_BUFFFIELD;
|
|
break;
|
|
|
|
default:
|
|
ERROR(("CreateObject: invalid object type %c", c));
|
|
rc = ASLERR_INVALID_OBJTYPE;
|
|
}
|
|
|
|
if (ppns != NULL)
|
|
{
|
|
*ppns = pns;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "CreateObject=%d\n", rc));
|
|
return rc;
|
|
} //CreateObject
|
|
|
|
/***LP CreateScopeObj - Create Scope object
|
|
*
|
|
* ENTRY
|
|
* pszName -> object name
|
|
* ppns -> to hold object created
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL CreateScopeObj(PSZ pszName, PNSOBJ *ppns)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSOBJ pnsScope;
|
|
PSZ psz;
|
|
|
|
ENTER((2, "CreateScopeObj(Name=%s)\n", pszName));
|
|
ASSERT(ppns != NULL);
|
|
|
|
if ((psz = strrchr(pszName, '.')) != NULL)
|
|
{
|
|
*psz = '\0';
|
|
if ((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pnsScope, 0)) ==
|
|
ASLERR_NSOBJ_NOT_FOUND)
|
|
{
|
|
rc = CreateScopeObj(pszName, &pnsScope);
|
|
}
|
|
*psz = '.';
|
|
psz++;
|
|
}
|
|
else if (pszName[0] == '\\')
|
|
{
|
|
pnsScope = gpnsNameSpaceRoot;
|
|
psz = &pszName[1];
|
|
}
|
|
else
|
|
{
|
|
pnsScope = gpnsCurrentScope;
|
|
psz = pszName;
|
|
}
|
|
|
|
if ((rc == ASLERR_NONE) &&
|
|
((rc = CreateNameSpaceObj(NULL, psz, pnsScope, NULL, ppns,
|
|
NSF_EXIST_OK)) == ASLERR_NONE))
|
|
{
|
|
(*ppns)->ObjData.dwDataType = OBJTYPE_EXTERNAL;
|
|
}
|
|
|
|
EXIT((2, "CreateScopeObj=%d (pns=%p)\n", rc, *ppns));
|
|
return rc;
|
|
} //CreateScopeObj
|
|
|
|
/***LP ComputeDataChkSum - Compute checksum of a data buffer
|
|
*
|
|
* ENTRY
|
|
* pb -> data buffer
|
|
* dwLen - size of data buffer
|
|
*
|
|
* EXIT
|
|
* returns the checksum byte
|
|
*/
|
|
|
|
BYTE LOCAL ComputeDataChkSum(PBYTE pb, DWORD dwLen)
|
|
{
|
|
BYTE bChkSum = 0;
|
|
|
|
ENTER((1, "ComputeDataChkSum(pb=%p,Len=%ld)\n", pb, dwLen));
|
|
|
|
while (dwLen > 0)
|
|
{
|
|
bChkSum = (BYTE)(bChkSum + *pb);
|
|
pb++;
|
|
dwLen--;
|
|
}
|
|
|
|
EXIT((1, "ComputeDataChkSum=%x\n", bChkSum));
|
|
return bChkSum;
|
|
} //ComputeDataChkSum
|