Skip to content

Commit

Permalink
iASL: keep externals for methods that are referenced
Browse files Browse the repository at this point in the history
At the moment, the external analysis walk attempts to optimize the size
of AML by removing external method declarations that are not called.
This results in the external declaration in the following code being
removed during compilation:

External (EXT0, MethodObj) // EXT0 removed during compilation
if (!CondRefOf (EXT0))
{
    Method (EXT0)
    {
        ...
    }
}

This happens because referencing externals inside of CondRefOf is not a
method call. This results in the first line being removed during
compilation and breaks the re-compilation of the above code after
disassembly. In order to retain the external declaration, change the
external method analysis to look for any named referenced in addition to
method calls.

Signed-off-by: Erik Kaneda <erik.kaneda@intel.com>
  • Loading branch information
Erik Kaneda committed Feb 2, 2021
1 parent ffb2501 commit 537a03c
Showing 1 changed file with 69 additions and 25 deletions.
94 changes: 69 additions & 25 deletions source/compiler/aslexternal.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,57 @@ ExDoExternal (
}


/*******************************************************************************
*
* FUNCTION: ExFindUnvisitedExternal
*
* PARAMETERS: Name - Name to find in the external list
*
* RETURN: ACPI_PARSE_OBJECT
*
* DESCRIPTION: Find an entry in the external list that matches the Name
* argument
*
******************************************************************************/

static ACPI_PARSE_OBJECT *
ExFindUnvisitedExternal (
char *Name)
{
ACPI_PARSE_OBJECT *Current;
ACPI_PARSE_OBJECT *NameOp;
char *ExternalName;


Current = AslGbl_ExternalsListHead;
while (Current)
{
/* Skip if External node already handled */

if (Current->Asl.Child->Asl.CompileFlags & OP_VISITED)
{
Current = Current->Asl.Next;
continue;
}

NameOp = Current->Asl.Child->Asl.Child;
ExternalName = AcpiNsGetNormalizedPathname (NameOp->Asl.Node, TRUE);
if (strcmp (Name, ExternalName))
{
ACPI_FREE (ExternalName);
Current = Current->Asl.Next;
continue;
}
else
{
ACPI_FREE (ExternalName);
return Current;
}
}
return NULL;
}


/*******************************************************************************
*
* FUNCTION: ExInsertArgCount
Expand All @@ -301,44 +352,21 @@ ExInsertArgCount (
ACPI_PARSE_OBJECT *NameOp;
ACPI_PARSE_OBJECT *Child;
ACPI_PARSE_OBJECT *ArgCountOp;
char * ExternalName;
char * CallName;
UINT16 ArgCount = 0;
ACPI_STATUS Status;


CallName = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);

Next = AslGbl_ExternalsListHead;
while (Next)
{
ArgCount = 0;

/* Skip if External node already handled */

if (Next->Asl.Child->Asl.CompileFlags & OP_VISITED)
{
Next = Next->Asl.Next;
continue;
}

NameOp = Next->Asl.Child->Asl.Child;
ExternalName = AcpiNsGetNormalizedPathname (NameOp->Asl.Node, TRUE);
if (strcmp (CallName, ExternalName))
{
ACPI_FREE (ExternalName);
Next = Next->Asl.Next;
continue;
}
ACPI_FREE (ExternalName);
}

Next = ExFindUnvisitedExternal (CallName);
if (!Next)
{
goto Cleanup;
}

Next->Asl.Child->Asl.CompileFlags |= OP_VISITED;
NameOp = Next->Asl.Child->Asl.Child;

/*
* Since we will reposition Externals to the Root, set Namepath
Expand Down Expand Up @@ -392,6 +420,9 @@ ExAmlExternalWalkBegin (
UINT32 Level,
void *Context)
{
ACPI_PARSE_OBJECT *ExternalListOp;
char *Name;


/* External list head saved in the definition block op */

Expand All @@ -405,6 +436,19 @@ ExAmlExternalWalkBegin (
return (AE_OK);
}

if (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)
{
Name = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
ExternalListOp = ExFindUnvisitedExternal (Name);
if (ExternalListOp)
{
ExternalListOp->Asl.Child->Asl.CompileFlags |= OP_VISITED;
}

ACPI_FREE (Name);
return (AE_OK);
}

if (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)
{
return (AE_OK);
Expand Down

0 comments on commit 537a03c

Please sign in to comment.