mirror of
https://github.com/acpica/acpica/
synced 2025-01-13 21:09:18 +03:00
iASL/disassembler: Add support for external method reference file.
Adds the -fe option which allows the user to specify a file that contains control method external declarations, with the proper number of arguments. This tells the disassembler how to parse code that invokes these methods.
This commit is contained in:
parent
0631bf977d
commit
96f37ef6bf
@ -413,6 +413,10 @@ AdAmlDisassemble (
|
||||
{
|
||||
AcpiDmClearExternalList ();
|
||||
}
|
||||
|
||||
/* Load any externals defined in the optional external ref file */
|
||||
|
||||
AcpiDmGetExternalsFromFile ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -445,10 +445,18 @@ AcpiDmDumpDescending (
|
||||
switch (Op->Common.AmlOpcode)
|
||||
{
|
||||
case AML_BYTE_OP:
|
||||
|
||||
AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
|
||||
break;
|
||||
|
||||
case AML_WORD_OP:
|
||||
|
||||
AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
|
||||
break;
|
||||
|
||||
case AML_DWORD_OP:
|
||||
|
||||
AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
|
||||
AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
|
||||
break;
|
||||
|
||||
case AML_QWORD_OP:
|
||||
|
@ -118,7 +118,9 @@
|
||||
#include "amlcode.h"
|
||||
#include "acnamesp.h"
|
||||
#include "acdisasm.h"
|
||||
#include "aslcompiler.h"
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -159,6 +161,8 @@ static const char *AcpiGbl_DmTypeNames[] =
|
||||
/* 19 */ ", FieldUnitObj"
|
||||
};
|
||||
|
||||
#define METHOD_SEPARATORS " \t,()\n"
|
||||
|
||||
|
||||
/* Local prototypes */
|
||||
|
||||
@ -171,6 +175,12 @@ AcpiDmNormalizeParentPrefix (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
char *Path);
|
||||
|
||||
static void
|
||||
AcpiDmAddToExternalListFromFile (
|
||||
char *Path,
|
||||
UINT8 Type,
|
||||
UINT32 Value);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
@ -516,7 +526,7 @@ AcpiDmAddToExternalList (
|
||||
(NextExternal->Value != Value))
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO,
|
||||
"Argument count mismatch for method %s %u %u",
|
||||
"External method arg count mismatch %s: Current %u, attempted %u",
|
||||
NextExternal->Path, NextExternal->Value, Value));
|
||||
}
|
||||
|
||||
@ -606,6 +616,275 @@ AcpiDmAddToExternalList (
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDmGetExternalsFromFile
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Process the optional external reference file.
|
||||
*
|
||||
* Each line in the file should be of the form:
|
||||
* External (<Method namepath>, MethodObj, <ArgCount>)
|
||||
*
|
||||
* Example:
|
||||
* External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
AcpiDmGetExternalsFromFile (
|
||||
void)
|
||||
{
|
||||
FILE *ExternalRefFile;
|
||||
char *Token;
|
||||
char *MethodName;
|
||||
UINT32 ArgCount;
|
||||
UINT32 ImportCount = 0;
|
||||
|
||||
|
||||
if (!Gbl_ExternalRefFilename)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Open the file */
|
||||
|
||||
ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
|
||||
if (!ExternalRefFile)
|
||||
{
|
||||
fprintf (stderr, "Could not open external reference file \"%s\"\n",
|
||||
Gbl_ExternalRefFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Each line defines a method */
|
||||
|
||||
while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
|
||||
{
|
||||
Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
|
||||
if (!Token) continue;
|
||||
if (strcmp (Token, "External")) continue;
|
||||
|
||||
MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
|
||||
if (!MethodName) continue;
|
||||
|
||||
Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
|
||||
if (!Token) continue;
|
||||
if (strcmp (Token, "MethodObj")) continue;
|
||||
|
||||
Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
|
||||
if (!Token) continue;
|
||||
|
||||
/* Convert arg count string to an integer */
|
||||
|
||||
errno = 0;
|
||||
ArgCount = strtoul (Token, NULL, 0);
|
||||
if (errno)
|
||||
{
|
||||
fprintf (stderr, "Invalid argument count (%s)\n", Token);
|
||||
continue;
|
||||
}
|
||||
if (ArgCount > 7)
|
||||
{
|
||||
fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add this external to the global list */
|
||||
|
||||
AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
|
||||
Gbl_ExternalRefFilename, ArgCount, MethodName);
|
||||
|
||||
AcpiDmAddToExternalListFromFile (MethodName, ACPI_TYPE_METHOD, ArgCount | 0x80);
|
||||
ImportCount++;
|
||||
}
|
||||
|
||||
if (!ImportCount)
|
||||
{
|
||||
fprintf (stderr, "Did not find any external methods in reference file \"%s\"\n",
|
||||
Gbl_ExternalRefFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the external(s) to the namespace */
|
||||
|
||||
AcpiDmAddExternalsToNamespace ();
|
||||
|
||||
AcpiOsPrintf ("%s: Imported %u external method definitions\n",
|
||||
Gbl_ExternalRefFilename, ImportCount);
|
||||
}
|
||||
|
||||
fclose (ExternalRefFile);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDmAddToExternalListFromFile
|
||||
*
|
||||
* PARAMETERS: Path - Internal (AML) path to the object
|
||||
* Type - ACPI object type to be added
|
||||
* Value - Arg count if adding a Method object
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Insert a new name into the global list of Externals which
|
||||
* will in turn be later emitted as an External() declaration
|
||||
* in the disassembled output.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void
|
||||
AcpiDmAddToExternalListFromFile (
|
||||
char *Path,
|
||||
UINT8 Type,
|
||||
UINT32 Value)
|
||||
{
|
||||
char *InternalPath;
|
||||
char *ExternalPath;
|
||||
ACPI_EXTERNAL_LIST *NewExternal;
|
||||
ACPI_EXTERNAL_LIST *NextExternal;
|
||||
ACPI_EXTERNAL_LIST *PrevExternal = NULL;
|
||||
ACPI_STATUS Status;
|
||||
BOOLEAN Resolved = FALSE;
|
||||
|
||||
|
||||
if (!Path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* TBD: Add a flags parameter */
|
||||
|
||||
if (Type == ACPI_TYPE_METHOD)
|
||||
{
|
||||
if (Value & 0x80)
|
||||
{
|
||||
Resolved = TRUE;
|
||||
}
|
||||
Value &= 0x07;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't want External() statements to contain a leading '\'.
|
||||
* This prevents duplicate external statements of the form:
|
||||
*
|
||||
* External (\ABCD)
|
||||
* External (ABCD)
|
||||
*
|
||||
* This would cause a compile time error when the disassembled
|
||||
* output file is recompiled.
|
||||
*/
|
||||
if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
|
||||
{
|
||||
Path++;
|
||||
}
|
||||
|
||||
/* Check all existing externals to ensure no duplicates */
|
||||
|
||||
NextExternal = AcpiGbl_ExternalList;
|
||||
while (NextExternal)
|
||||
{
|
||||
if (!ACPI_STRCMP (Path, NextExternal->Path))
|
||||
{
|
||||
/* Duplicate method, check that the Value (ArgCount) is the same */
|
||||
|
||||
if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
|
||||
(NextExternal->Value != Value))
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO,
|
||||
"(File) External method arg count mismatch %s: Current %u, override to %u",
|
||||
NextExternal->Path, NextExternal->Value, Value));
|
||||
|
||||
/* Override, since new value came from external reference file */
|
||||
|
||||
NextExternal->Value = Value;
|
||||
}
|
||||
|
||||
/* Allow upgrade of type from ANY */
|
||||
|
||||
else if (NextExternal->Type == ACPI_TYPE_ANY)
|
||||
{
|
||||
NextExternal->Type = Type;
|
||||
NextExternal->Value = Value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NextExternal = NextExternal->Next;
|
||||
}
|
||||
|
||||
/* Get the internal pathname (AML format) */
|
||||
|
||||
Status = AcpiNsInternalizeName (Path, &InternalPath);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate and init a new External() descriptor */
|
||||
|
||||
NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
|
||||
if (!NewExternal)
|
||||
{
|
||||
ACPI_FREE (InternalPath);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Must copy and normalize the input path */
|
||||
|
||||
AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath, NULL, &ExternalPath);
|
||||
|
||||
NewExternal->Path = ExternalPath;
|
||||
NewExternal->Type = Type;
|
||||
NewExternal->Value = Value;
|
||||
NewExternal->Resolved = Resolved;
|
||||
NewExternal->Length = (UINT16) ACPI_STRLEN (Path);
|
||||
NewExternal->InternalPath = InternalPath;
|
||||
|
||||
/* Set flag to indicate External->InternalPath needs to be freed */
|
||||
|
||||
NewExternal->Flags |= ACPI_IPATH_ALLOCATED | ACPI_FROM_REFERENCE_FILE;
|
||||
|
||||
/* Link the new descriptor into the global list, alphabetically ordered */
|
||||
|
||||
NextExternal = AcpiGbl_ExternalList;
|
||||
while (NextExternal)
|
||||
{
|
||||
if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
|
||||
{
|
||||
if (PrevExternal)
|
||||
{
|
||||
PrevExternal->Next = NewExternal;
|
||||
}
|
||||
else
|
||||
{
|
||||
AcpiGbl_ExternalList = NewExternal;
|
||||
}
|
||||
|
||||
NewExternal->Next = NextExternal;
|
||||
return;
|
||||
}
|
||||
|
||||
PrevExternal = NextExternal;
|
||||
NextExternal = NextExternal->Next;
|
||||
}
|
||||
|
||||
if (PrevExternal)
|
||||
{
|
||||
PrevExternal->Next = NewExternal;
|
||||
}
|
||||
else
|
||||
{
|
||||
AcpiGbl_ExternalList = NewExternal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDmAddExternalsToNamespace
|
||||
@ -635,7 +914,7 @@ AcpiDmAddExternalsToNamespace (
|
||||
|
||||
Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
|
||||
ACPI_IMODE_LOAD_PASS1,
|
||||
ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
|
||||
ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
|
||||
NULL, &Node);
|
||||
|
||||
if (ACPI_FAILURE (Status))
|
||||
@ -803,7 +1082,8 @@ AcpiDmEmitExternals (
|
||||
NextExternal->Path,
|
||||
AcpiDmGetObjectTypeName (NextExternal->Type));
|
||||
|
||||
AcpiOsPrintf (") // Warning: Unresolved Method, "
|
||||
AcpiOsPrintf (
|
||||
") // Warning: Unresolved Method, "
|
||||
"guessing %u arguments (may be incorrect, see warning above)\n",
|
||||
NextExternal->Value);
|
||||
|
||||
@ -815,9 +1095,45 @@ AcpiDmEmitExternals (
|
||||
|
||||
AcpiOsPrintf ("\n");
|
||||
|
||||
|
||||
/* Emit externals that were imported from a file */
|
||||
|
||||
if (Gbl_ExternalRefFilename)
|
||||
{
|
||||
AcpiOsPrintf (
|
||||
" /*\n * External declarations that were imported from\n"
|
||||
" * the reference file [%s]\n */\n",
|
||||
Gbl_ExternalRefFilename);
|
||||
|
||||
NextExternal = AcpiGbl_ExternalList;
|
||||
while (NextExternal)
|
||||
{
|
||||
if (!NextExternal->Emitted && (NextExternal->Flags & ACPI_FROM_REFERENCE_FILE))
|
||||
{
|
||||
AcpiOsPrintf (" External (%s%s",
|
||||
NextExternal->Path,
|
||||
AcpiDmGetObjectTypeName (NextExternal->Type));
|
||||
|
||||
if (NextExternal->Type == ACPI_TYPE_METHOD)
|
||||
{
|
||||
AcpiOsPrintf (") // %u Arguments\n",
|
||||
NextExternal->Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
AcpiOsPrintf (")\n");
|
||||
}
|
||||
NextExternal->Emitted = TRUE;
|
||||
}
|
||||
|
||||
NextExternal = NextExternal->Next;
|
||||
}
|
||||
|
||||
AcpiOsPrintf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the list of externals (unresolved references)
|
||||
* found during the AML parsing
|
||||
* Walk the list of externals found during the AML parsing
|
||||
*/
|
||||
while (AcpiGbl_ExternalList)
|
||||
{
|
||||
|
@ -258,6 +258,7 @@ ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_IncludeFilename, NULL)
|
||||
ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_OutputFilenamePrefix, NULL);
|
||||
ASL_EXTERN ASL_INCLUDE_DIR ASL_INIT_GLOBAL (*Gbl_IncludeDirList, NULL);
|
||||
ASL_EXTERN char *Gbl_CurrentInputFilename;
|
||||
ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_ExternalRefFilename, NULL);
|
||||
|
||||
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HasIncludeFiles, FALSE);
|
||||
|
||||
|
@ -210,6 +210,7 @@ Usage (
|
||||
ACPI_OPTION ("-dc <f1,f2>", "Disassemble AML and immediately compile it");
|
||||
ACPI_OPTION ("", " (Obtain DSDT from current system if no input file)");
|
||||
ACPI_OPTION ("-e <f1,f2>", "Include ACPI table(s) for external symbol resolution");
|
||||
ACPI_OPTION ("-fe <file>", "Specify external symbol declaration file");
|
||||
ACPI_OPTION ("-g", "Get ACPI tables and write to files (*.dat)");
|
||||
ACPI_OPTION ("-in", "Ignore NoOp opcodes");
|
||||
ACPI_OPTION ("-vt", "Dump binary table data in hex format within output file");
|
||||
|
@ -140,7 +140,7 @@ AslDoResponseFile (
|
||||
|
||||
|
||||
#define ASL_TOKEN_SEPARATORS " \t\n"
|
||||
#define ASL_SUPPORTED_OPTIONS "@:b|c|d^D:e:fgh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z"
|
||||
#define ASL_SUPPORTED_OPTIONS "@:b|c|d^D:e:f^gh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z"
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -208,8 +208,7 @@ AslCommandLine (
|
||||
|
||||
if (BadCommandLine)
|
||||
{
|
||||
printf ("\n");
|
||||
Usage ();
|
||||
printf ("Use -h option for help information\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@ -348,9 +347,30 @@ AslDoOptions (
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f': /* Ignore errors and force creation of aml file */
|
||||
case 'f':
|
||||
|
||||
Gbl_IgnoreErrors = TRUE;
|
||||
switch (AcpiGbl_Optarg[0])
|
||||
{
|
||||
case '^': /* Ignore errors and force creation of aml file */
|
||||
|
||||
Gbl_IgnoreErrors = TRUE;
|
||||
break;
|
||||
|
||||
case 'e': /* Disassembler: Get external declaration file */
|
||||
|
||||
if (AcpiGetoptArgument (argc, argv))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
Gbl_ExternalRefFilename = AcpiGbl_Optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
printf ("Unknown option: -f%s\n", AcpiGbl_Optarg);
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
|
@ -766,6 +766,9 @@ void
|
||||
AcpiDmUnresolvedWarning (
|
||||
UINT8 Type);
|
||||
|
||||
void
|
||||
AcpiDmGetExternalsFromFile (
|
||||
void);
|
||||
|
||||
/*
|
||||
* dmresrc
|
||||
|
@ -1289,7 +1289,8 @@ typedef struct acpi_external_list
|
||||
|
||||
/* Values for Flags field above */
|
||||
|
||||
#define ACPI_IPATH_ALLOCATED 0x01
|
||||
#define ACPI_IPATH_ALLOCATED 0x01
|
||||
#define ACPI_FROM_REFERENCE_FILE 0x02
|
||||
|
||||
|
||||
typedef struct acpi_external_file
|
||||
|
Loading…
Reference in New Issue
Block a user