mirror of
https://github.com/acpica/acpica/
synced 2025-02-24 09:24:08 +03:00
iASL: Add new warnings for method LocalX and ArgX variables.
1) Warn if a Local is set but never used 2) Warn if a ArgX is never used (for non-predefined method names) 3) Warn if a ArgX that is used as a local is never used
This commit is contained in:
parent
03c66d2425
commit
eb9f8cb9fd
@ -191,8 +191,73 @@ LkIsObjectUsed (
|
||||
{
|
||||
ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
|
||||
ACPI_NAMESPACE_NODE *Next;
|
||||
ASL_METHOD_LOCAL *MethodLocals;
|
||||
ASL_METHOD_LOCAL *MethodArgs;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
if (Node->Type == ACPI_TYPE_METHOD)
|
||||
{
|
||||
if (!Node->Op || !Node->MethodLocals)
|
||||
{
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
MethodLocals = (ASL_METHOD_LOCAL *) Node->MethodLocals;
|
||||
MethodArgs = (ASL_METHOD_LOCAL *) Node->MethodArgs;
|
||||
|
||||
/*
|
||||
* Analysis of LocalX variables
|
||||
*/
|
||||
for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
|
||||
{
|
||||
/* Warn for Locals that are set but never referenced */
|
||||
|
||||
if ((MethodLocals[i].Flags & ASL_LOCAL_INITIALIZED) &&
|
||||
(!(MethodLocals[i].Flags & ASL_LOCAL_REFERENCED)))
|
||||
{
|
||||
sprintf (MsgBuffer, "Local%u", i);
|
||||
AslError (ASL_WARNING, ASL_MSG_LOCAL_NOT_USED,
|
||||
MethodLocals[i].Op, MsgBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Analysis of ArgX variables (standard method arguments,
|
||||
* and remaining unused ArgX can also be used as locals)
|
||||
*/
|
||||
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
|
||||
{
|
||||
if (MethodArgs[i].Flags & ASL_ARG_IS_LOCAL)
|
||||
{
|
||||
/* Warn if ArgX is being used as a local, but not referenced */
|
||||
|
||||
if ((MethodArgs[i].Flags & ASL_ARG_INITIALIZED) &&
|
||||
(!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
|
||||
{
|
||||
sprintf (MsgBuffer, "Arg%u", i);
|
||||
AslError (ASL_WARNING, ASL_MSG_ARG_AS_LOCAL_NOT_USED,
|
||||
MethodArgs[i].Op, MsgBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Remark if a normal method ArgX is not referenced.
|
||||
* We ignore the predefined methods since often, not
|
||||
* all arguments are needed or used.
|
||||
*/
|
||||
if ((Node->Name.Ascii[0] != '_') &&
|
||||
(!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
|
||||
{
|
||||
sprintf (MsgBuffer, "Arg%u", i);
|
||||
AslError (ASL_REMARK, ASL_MSG_ARG_NOT_USED,
|
||||
MethodArgs[i].Op, MsgBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Referenced flag is set during the namespace xref */
|
||||
|
||||
if (Node->Flags & ANOBJ_IS_REFERENCED)
|
||||
|
@ -307,7 +307,11 @@ const char *AslCompilerMsgs [] =
|
||||
/* ASL_MSG_BUFFER_ALLOCATION */ "Could not allocate line buffer",
|
||||
/* ASL_MSG_MISSING_DEPENDENCY */ "Missing dependency",
|
||||
/* ASL_MSG_ILLEGAL_FORWARD_REF */ "Illegal forward reference within a method",
|
||||
/* ASL_MSG_ILLEGAL_METHOD_REF */ "Illegal reference across two methods"
|
||||
/* ASL_MSG_ILLEGAL_METHOD_REF */ "Illegal reference across two methods",
|
||||
/* ASL_MSG_LOCAL_NOT_USED */ "Method Local is set but never used",
|
||||
/* ASL_MSG_ARG_AS_LOCAL_NOT_USED */ "Method Argument (as a local) is set but never used",
|
||||
/* ASL_MSG_ARG_NOT_USED */ "Method Argument is never used"
|
||||
|
||||
};
|
||||
|
||||
/* Table compiler */
|
||||
|
@ -310,6 +310,9 @@ typedef enum
|
||||
ASL_MSG_MISSING_DEPENDENCY,
|
||||
ASL_MSG_ILLEGAL_FORWARD_REF,
|
||||
ASL_MSG_ILLEGAL_METHOD_REF,
|
||||
ASL_MSG_LOCAL_NOT_USED,
|
||||
ASL_MSG_ARG_AS_LOCAL_NOT_USED,
|
||||
ASL_MSG_ARG_NOT_USED,
|
||||
|
||||
/* These messages are used by the Data Table compiler only */
|
||||
|
||||
|
@ -327,7 +327,7 @@ MtMethodAnalysisWalkBegin (
|
||||
return (AE_ERROR);
|
||||
}
|
||||
|
||||
RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
|
||||
RegisterNumber = (Op->Asl.AmlOpcode & 0x0007);
|
||||
|
||||
/*
|
||||
* If the local is being used as a target, mark the local
|
||||
|
@ -374,5 +374,19 @@ typedef struct acpi_serial_info
|
||||
|
||||
} ACPI_SERIAL_INFO;
|
||||
|
||||
typedef struct asl_method_local
|
||||
{
|
||||
ACPI_PARSE_OBJECT *Op;
|
||||
UINT8 Flags;
|
||||
|
||||
} ASL_METHOD_LOCAL;
|
||||
|
||||
/* Values for Flags field above */
|
||||
|
||||
#define ASL_LOCAL_INITIALIZED (1)
|
||||
#define ASL_LOCAL_REFERENCED (1<<1)
|
||||
#define ASL_ARG_IS_LOCAL (1<<2)
|
||||
#define ASL_ARG_INITIALIZED (1<<3)
|
||||
#define ASL_ARG_REFERENCED (1<<4)
|
||||
|
||||
#endif /* __ASLTYPES_H */
|
||||
|
@ -138,6 +138,10 @@ XfNamespaceLocateEnd (
|
||||
UINT32 Level,
|
||||
void *Context);
|
||||
|
||||
static ACPI_PARSE_OBJECT *
|
||||
XfGetParentMethod (
|
||||
ACPI_PARSE_OBJECT *Op);
|
||||
|
||||
static BOOLEAN
|
||||
XfObjectExists (
|
||||
char *Name);
|
||||
@ -352,59 +356,16 @@ XfCheckFieldRange (
|
||||
}
|
||||
|
||||
|
||||
#ifdef __UNDER_DEVELOPMENT
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfIsObjectParental
|
||||
*
|
||||
* PARAMETERS: ChildOp - Op to be checked
|
||||
* PossibleParentOp - Determine if this op is in the family
|
||||
*
|
||||
* RETURN: TRUE if ChildOp is a descendent of PossibleParentOp
|
||||
*
|
||||
* DESCRIPTION: Determine if an Op is a descendent of another Op. Used to
|
||||
* detect if a method is declared within another method.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static BOOLEAN
|
||||
XfIsObjectParental (
|
||||
ACPI_PARSE_OBJECT *ChildOp,
|
||||
ACPI_PARSE_OBJECT *PossibleParentOp)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *ParentOp;
|
||||
|
||||
|
||||
/* Search upwards through the tree for possible parent */
|
||||
|
||||
ParentOp = ChildOp;
|
||||
while (ParentOp)
|
||||
{
|
||||
if (ParentOp == PossibleParentOp)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
ParentOp = ParentOp->Asl.Parent;
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfGetParentMethod
|
||||
*
|
||||
* PARAMETERS: Op - Op to be checked
|
||||
* PARAMETERS: Op - Parse Op to be checked
|
||||
*
|
||||
* RETURN: Op for parent method. NULL if object is not within a method.
|
||||
* RETURN: Control method Op if found. NULL otherwise
|
||||
*
|
||||
* DESCRIPTION: Determine if an object is within a control method. Used to
|
||||
* implement special rules for named references from within a
|
||||
* control method.
|
||||
*
|
||||
* NOTE: It would be better to have the parser set a flag in the Op if possible.
|
||||
* DESCRIPTION: Find the control method parent of a parse op. Returns NULL if
|
||||
* the input Op is not within a control method.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -412,121 +373,23 @@ static ACPI_PARSE_OBJECT *
|
||||
XfGetParentMethod (
|
||||
ACPI_PARSE_OBJECT *Op)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *ParentOp;
|
||||
ACPI_PARSE_OBJECT *NextOp;
|
||||
|
||||
|
||||
if (!Op)
|
||||
NextOp = Op->Asl.Parent;
|
||||
while (NextOp)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Walk upwards through the parse tree, up to the root if necessary */
|
||||
|
||||
ParentOp = Op;
|
||||
while (ParentOp)
|
||||
{
|
||||
if (ParentOp->Asl.ParseOpcode == PARSEOP_METHOD)
|
||||
if (NextOp->Asl.AmlOpcode == AML_METHOD_OP)
|
||||
{
|
||||
return (ParentOp);
|
||||
return (NextOp);
|
||||
}
|
||||
|
||||
ParentOp = ParentOp->Asl.Parent;
|
||||
NextOp = NextOp->Asl.Parent;
|
||||
}
|
||||
|
||||
/* Object is not within a method */
|
||||
|
||||
return (NULL);
|
||||
return (NULL); /* No parent method found */
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfCheckIllegalReference
|
||||
*
|
||||
* PARAMETERS: Op - Op referring to the target
|
||||
* TargetNode - Target of the reference
|
||||
*
|
||||
* RETURN: None. Emits error message for an illegal reference
|
||||
*
|
||||
* DESCRIPTION: Determine if a named reference is legal. A "named" reference
|
||||
* is something like: Store(ABCD, ...), where ABCD is an AML
|
||||
* Nameseg or Namepath.
|
||||
*
|
||||
* NOTE: Caller must ensure that the name Op is in fact a reference, and not
|
||||
* an actual name declaration (creation of a named object).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void
|
||||
XfCheckIllegalReference (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
ACPI_NAMESPACE_NODE *TargetNode)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *MethodOp1;
|
||||
ACPI_PARSE_OBJECT *MethodOp2;
|
||||
ACPI_PARSE_OBJECT *TargetOp;
|
||||
|
||||
|
||||
/*
|
||||
* Check for an illegal reference to a named object:
|
||||
*
|
||||
* 1) References from one control method to another, non-parent
|
||||
* method are not allowed, they will fail at runtime.
|
||||
*
|
||||
* 2) Forward references within a control method are not allowed.
|
||||
* AML interpreters use a one-pass parse of control methods
|
||||
* so these forward references will fail at runtime.
|
||||
*/
|
||||
TargetOp = TargetNode->Op;
|
||||
|
||||
MethodOp1 = XfGetParentMethod (Op);
|
||||
MethodOp2 = XfGetParentMethod (TargetOp);
|
||||
|
||||
/* Are both objects within control method(s)? */
|
||||
|
||||
if (!MethodOp1 || !MethodOp2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Objects not in the same method? */
|
||||
|
||||
if (MethodOp1 != MethodOp2)
|
||||
{
|
||||
/*
|
||||
* 1) Cross-method named reference
|
||||
*
|
||||
* This is OK if and only if the target reference is within in a
|
||||
* method that is a parent of current method
|
||||
*/
|
||||
if (!XfIsObjectParental (MethodOp1, MethodOp2))
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_ILLEGAL_METHOD_REF, Op,
|
||||
Op->Asl.ExternalName);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 2) Both reference and target are in the same method. Check if this is
|
||||
* an (illegal) forward reference by examining the exact source code
|
||||
* location of each (the referenced object and the object declaration).
|
||||
* This is a bit nasty, yet effective.
|
||||
*/
|
||||
else if (Op->Asl.LogicalByteOffset < TargetOp->Asl.LogicalByteOffset)
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
|
||||
Op->Asl.ExternalName);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfNamespaceLocateBegin
|
||||
@ -568,10 +431,67 @@ XfNamespaceLocateBegin (
|
||||
UINT8 Message = 0;
|
||||
const ACPI_OPCODE_INFO *OpInfo;
|
||||
UINT32 Flags;
|
||||
ASL_METHOD_LOCAL *MethodLocals = NULL;
|
||||
ASL_METHOD_LOCAL *MethodArgs = NULL;
|
||||
int RegisterNumber;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
|
||||
|
||||
|
||||
if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
|
||||
{
|
||||
Node = Op->Asl.Node;
|
||||
|
||||
/* Support for method LocalX/ArgX analysis */
|
||||
|
||||
if (!Node->MethodLocals)
|
||||
{
|
||||
/* Create local/arg info blocks */
|
||||
|
||||
MethodLocals = UtLocalCalloc (
|
||||
sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
|
||||
Node->MethodLocals = MethodLocals;
|
||||
|
||||
MethodArgs = UtLocalCalloc (
|
||||
sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
|
||||
Node->MethodArgs = MethodArgs;
|
||||
|
||||
/*
|
||||
* Get the method argument count
|
||||
* First, get the name node
|
||||
*/
|
||||
NextOp = Op->Asl.Child;
|
||||
|
||||
/* Get the NumArguments node */
|
||||
|
||||
NextOp = NextOp->Asl.Next;
|
||||
Node->ArgCount = (UINT8)
|
||||
(((UINT8) NextOp->Asl.Value.Integer) & 0x07);
|
||||
|
||||
/* We will track all posible ArgXs */
|
||||
|
||||
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
|
||||
{
|
||||
if (i < Node->ArgCount)
|
||||
{
|
||||
/* Real Args are always "initialized" */
|
||||
|
||||
MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other ArgXs can be used as locals */
|
||||
|
||||
MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
|
||||
}
|
||||
|
||||
MethodArgs[i].Op = Op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this node is the actual declaration of a name
|
||||
* [such as the XXXX name in "Method (XXXX)"],
|
||||
@ -584,10 +504,88 @@ XfNamespaceLocateBegin (
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* We are only interested in opcodes that have an associated name */
|
||||
|
||||
OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
|
||||
|
||||
/* Check method LocalX variables */
|
||||
|
||||
if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
|
||||
{
|
||||
/* Find parent method Op */
|
||||
|
||||
NextOp = XfGetParentMethod (Op);
|
||||
if (!NextOp)
|
||||
{
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Get method node */
|
||||
|
||||
Node = NextOp->Asl.Node;
|
||||
|
||||
RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
|
||||
MethodLocals = Node->MethodLocals;
|
||||
|
||||
if (Op->Asl.CompileFlags & NODE_IS_TARGET)
|
||||
{
|
||||
/* Local is being initialized */
|
||||
|
||||
MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
|
||||
MethodLocals[RegisterNumber].Op = Op;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Mark this Local as referenced */
|
||||
|
||||
MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
|
||||
MethodLocals[RegisterNumber].Op = Op;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Check method ArgX variables */
|
||||
|
||||
if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
|
||||
{
|
||||
/* Find parent method Op */
|
||||
|
||||
NextOp = XfGetParentMethod (Op);
|
||||
if (!NextOp)
|
||||
{
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Get method node */
|
||||
|
||||
Node = NextOp->Asl.Node;
|
||||
|
||||
/* Get Arg # */
|
||||
|
||||
RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
|
||||
MethodArgs = Node->MethodArgs;
|
||||
|
||||
if (Op->Asl.CompileFlags & NODE_IS_TARGET)
|
||||
{
|
||||
/* Arg is being initialized */
|
||||
|
||||
MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
|
||||
MethodArgs[RegisterNumber].Op = Op;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Mark this Arg as referenced */
|
||||
|
||||
MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
|
||||
MethodArgs[RegisterNumber].Op = Op;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* After method ArgX and LocalX, we are only interested in opcodes
|
||||
* that have an associated name
|
||||
*/
|
||||
if ((!(OpInfo->Flags & AML_NAMED)) &&
|
||||
(!(OpInfo->Flags & AML_CREATE)) &&
|
||||
(Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
|
||||
@ -1166,3 +1164,178 @@ XfNamespaceLocateEnd (
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __UNDER_DEVELOPMENT
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfIsObjectParental
|
||||
*
|
||||
* PARAMETERS: ChildOp - Op to be checked
|
||||
* PossibleParentOp - Determine if this op is in the family
|
||||
*
|
||||
* RETURN: TRUE if ChildOp is a descendent of PossibleParentOp
|
||||
*
|
||||
* DESCRIPTION: Determine if an Op is a descendent of another Op. Used to
|
||||
* detect if a method is declared within another method.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static BOOLEAN
|
||||
XfIsObjectParental (
|
||||
ACPI_PARSE_OBJECT *ChildOp,
|
||||
ACPI_PARSE_OBJECT *PossibleParentOp)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *ParentOp;
|
||||
|
||||
|
||||
/* Search upwards through the tree for possible parent */
|
||||
|
||||
ParentOp = ChildOp;
|
||||
while (ParentOp)
|
||||
{
|
||||
if (ParentOp == PossibleParentOp)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
ParentOp = ParentOp->Asl.Parent;
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfGetParentMethod
|
||||
*
|
||||
* PARAMETERS: Op - Op to be checked
|
||||
*
|
||||
* RETURN: Op for parent method. NULL if object is not within a method.
|
||||
*
|
||||
* DESCRIPTION: Determine if an object is within a control method. Used to
|
||||
* implement special rules for named references from within a
|
||||
* control method.
|
||||
*
|
||||
* NOTE: It would be better to have the parser set a flag in the Op if possible.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static ACPI_PARSE_OBJECT *
|
||||
XfGetParentMethod (
|
||||
ACPI_PARSE_OBJECT *Op)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *ParentOp;
|
||||
|
||||
|
||||
if (!Op)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Walk upwards through the parse tree, up to the root if necessary */
|
||||
|
||||
ParentOp = Op;
|
||||
while (ParentOp)
|
||||
{
|
||||
if (ParentOp->Asl.ParseOpcode == PARSEOP_METHOD)
|
||||
{
|
||||
return (ParentOp);
|
||||
}
|
||||
|
||||
ParentOp = ParentOp->Asl.Parent;
|
||||
}
|
||||
|
||||
/* Object is not within a method */
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfCheckIllegalReference
|
||||
*
|
||||
* PARAMETERS: Op - Op referring to the target
|
||||
* TargetNode - Target of the reference
|
||||
*
|
||||
* RETURN: None. Emits error message for an illegal reference
|
||||
*
|
||||
* DESCRIPTION: Determine if a named reference is legal. A "named" reference
|
||||
* is something like: Store(ABCD, ...), where ABCD is an AML
|
||||
* Nameseg or Namepath.
|
||||
*
|
||||
* NOTE: Caller must ensure that the name Op is in fact a reference, and not
|
||||
* an actual name declaration (creation of a named object).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void
|
||||
XfCheckIllegalReference (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
ACPI_NAMESPACE_NODE *TargetNode)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *MethodOp1;
|
||||
ACPI_PARSE_OBJECT *MethodOp2;
|
||||
ACPI_PARSE_OBJECT *TargetOp;
|
||||
|
||||
|
||||
/*
|
||||
* Check for an illegal reference to a named object:
|
||||
*
|
||||
* 1) References from one control method to another, non-parent
|
||||
* method are not allowed, they will fail at runtime.
|
||||
*
|
||||
* 2) Forward references within a control method are not allowed.
|
||||
* AML interpreters use a one-pass parse of control methods
|
||||
* so these forward references will fail at runtime.
|
||||
*/
|
||||
TargetOp = TargetNode->Op;
|
||||
|
||||
MethodOp1 = XfGetParentMethod (Op);
|
||||
MethodOp2 = XfGetParentMethod (TargetOp);
|
||||
|
||||
/* Are both objects within control method(s)? */
|
||||
|
||||
if (!MethodOp1 || !MethodOp2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Objects not in the same method? */
|
||||
|
||||
if (MethodOp1 != MethodOp2)
|
||||
{
|
||||
/*
|
||||
* 1) Cross-method named reference
|
||||
*
|
||||
* This is OK if and only if the target reference is within in a
|
||||
* method that is a parent of current method
|
||||
*/
|
||||
if (!XfIsObjectParental (MethodOp1, MethodOp2))
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_ILLEGAL_METHOD_REF, Op,
|
||||
Op->Asl.ExternalName);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 2) Both reference and target are in the same method. Check if this is
|
||||
* an (illegal) forward reference by examining the exact source code
|
||||
* location of each (the referenced object and the object declaration).
|
||||
* This is a bit nasty, yet effective.
|
||||
*/
|
||||
else if (Op->Asl.LogicalByteOffset < TargetOp->Asl.LogicalByteOffset)
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
|
||||
Op->Asl.ExternalName);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -265,8 +265,12 @@ typedef struct acpi_namespace_node
|
||||
*/
|
||||
#ifdef ACPI_LARGE_NAMESPACE_NODE
|
||||
union acpi_parse_object *Op;
|
||||
void *MethodLocals;
|
||||
void *MethodArgs;
|
||||
UINT32 Value;
|
||||
UINT32 Length;
|
||||
UINT8 ArgCount;
|
||||
|
||||
#endif
|
||||
|
||||
} ACPI_NAMESPACE_NODE;
|
||||
|
@ -336,6 +336,7 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = {
|
||||
{"ACPI_MEM_SPACE_CONTEXT", SRC_TYPE_STRUCT},
|
||||
{"ACPI_MEMORY_ATTRIBUTE", SRC_TYPE_STRUCT},
|
||||
{"ACPI_MEMORY_LIST", SRC_TYPE_STRUCT},
|
||||
{"ACPI_METHOD_LOCAL", SRC_TYPE_STRUCT},
|
||||
{"ACPI_MTMR_ENTRY", SRC_TYPE_STRUCT},
|
||||
{"ACPI_MUTEX", SRC_TYPE_SIMPLE},
|
||||
{"ACPI_MUTEX_HANDLE", SRC_TYPE_SIMPLE},
|
||||
@ -563,6 +564,7 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = {
|
||||
{"ASL_LISTING_NODE", SRC_TYPE_STRUCT},
|
||||
{"ASL_MAPPING_ENTRY", SRC_TYPE_STRUCT},
|
||||
{"ASL_METHOD_INFO", SRC_TYPE_STRUCT},
|
||||
{"ASL_METHOD_LOCAL", SRC_TYPE_STRUCT},
|
||||
{"ASL_RESERVED_INFO", SRC_TYPE_STRUCT},
|
||||
{"ASL_RESOURCE_INFO", SRC_TYPE_STRUCT},
|
||||
{"ASL_RESOURCE_NODE", SRC_TYPE_STRUCT},
|
||||
|
@ -396,5 +396,12 @@ DefinitionBlock ("badcode.aml", "DSDT", 1, "Intel", "Example", 0x00000001)
|
||||
CreateField (RSC3, \DWI1._MIF, 5, MIF)
|
||||
CreateField (RSC3, \DWI1._RNG, 3, RNG2)
|
||||
}
|
||||
|
||||
Method (L100)
|
||||
{
|
||||
/* Method Local is set but never used */
|
||||
|
||||
Store (40, Local0)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user