summaryrefslogtreecommitdiff
path: root/source/compiler/aslxref.c
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2019-02-20 23:04:28 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2019-02-20 23:04:28 +0000
commit933b0124ad04366156cb4793d2530ad791d88ead (patch)
tree6d20df0ad987596d76c7b0f8e58ef8e8e25b4b69 /source/compiler/aslxref.c
parentca9862327327526f102b9370cc74b2a9e4641b0d (diff)
Notes
Diffstat (limited to 'source/compiler/aslxref.c')
-rw-r--r--source/compiler/aslxref.c118
1 files changed, 117 insertions, 1 deletions
diff --git a/source/compiler/aslxref.c b/source/compiler/aslxref.c
index 87a2df28e651..b3067feb7c4e 100644
--- a/source/compiler/aslxref.c
+++ b/source/compiler/aslxref.c
@@ -174,6 +174,12 @@ XfNamespaceLocateEnd (
UINT32 Level,
void *Context);
+static BOOLEAN
+XfValidateCrossReference (
+ ACPI_PARSE_OBJECT *Op,
+ const ACPI_OPCODE_INFO *OpInfo,
+ ACPI_NAMESPACE_NODE *Node);
+
static ACPI_PARSE_OBJECT *
XfGetParentMethod (
ACPI_PARSE_OBJECT *Op);
@@ -408,6 +414,7 @@ XfGetParentMethod (
return (NULL); /* No parent method found */
}
+
/*******************************************************************************
*
* FUNCTION: XfNamespaceLocateBegin
@@ -488,7 +495,7 @@ XfNamespaceLocateBegin (
Node->ArgCount = (UINT8)
(((UINT8) NextOp->Asl.Value.Integer) & 0x07);
- /* We will track all posible ArgXs */
+ /* We will track all possible ArgXs */
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
{
@@ -776,6 +783,15 @@ XfNamespaceLocateBegin (
return_ACPI_STATUS (Status);
}
+ /* Check for an attempt to access an object in another method */
+
+ if (!XfValidateCrossReference (Op, OpInfo, Node))
+ {
+ AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
+ Op->Asl.ExternalName);
+ return_ACPI_STATUS (Status);
+ }
+
/* Object was found above, check for an illegal forward reference */
if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
@@ -1234,3 +1250,103 @@ XfNamespaceLocateEnd (
return_ACPI_STATUS (AE_OK);
}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfValidateCrossReference
+ *
+ * PARAMETERS: Op - Parse Op that references the object
+ * OpInfo - Parse Op info struct
+ * Node - Node for the referenced object
+ *
+ * RETURN: TRUE if the reference is legal, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a reference to another object is allowed.
+ *
+ * EXAMPLE:
+ * Method (A) {Name (INT1, 1)} Declaration of object INT1
+ * Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
+ * (INT1 is temporary, valid only during
+ * execution of A)
+ *
+ * NOTES:
+ * A null pointer returned by either XfGetParentMethod or
+ * UtGetParentMethod indicates that the parameter object is not
+ * within a control method.
+ *
+ * Five cases are handled: Case(Op, Node)
+ * 1) Case(0,0): Op is not within a method, Node is not --> OK
+ * 2) Case(0,1): Op is not within a method, but Node is --> Illegal
+ * 3) Case(1,0): Op is within a method, Node is not --> OK
+ * 4) Case(1,1): Both are within the same method --> OK
+ * 5) Case(1,1): Both are in methods, but not same method --> Illegal
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+XfValidateCrossReference (
+ ACPI_PARSE_OBJECT *Op,
+ const ACPI_OPCODE_INFO *OpInfo,
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_PARSE_OBJECT *ReferencingMethodOp;
+ ACPI_NAMESPACE_NODE *ReferencedMethodNode;
+
+
+ /* Ignore actual named (and related) object declarations */
+
+ if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
+ {
+ return (TRUE);
+ }
+
+ /*
+ * 1) Search upwards in parse tree for owner of the referencing object
+ * 2) Search upwards in namespace to find the owner of the referenced object
+ */
+ ReferencingMethodOp = XfGetParentMethod (Op);
+ ReferencedMethodNode = UtGetParentMethod (Node);
+
+ if (!ReferencingMethodOp && !ReferencedMethodNode)
+ {
+ /*
+ * 1) Case (0,0): Both Op and Node are not within methods
+ * --> OK
+ */
+ return (TRUE);
+ }
+
+ if (!ReferencingMethodOp && ReferencedMethodNode)
+ {
+ /*
+ * 2) Case (0,1): Op is not in a method, but Node is within a
+ * method --> illegal
+ */
+ return (FALSE);
+ }
+ else if (ReferencingMethodOp && !ReferencedMethodNode)
+ {
+ /*
+ * 3) Case (1,0): Op is within a method, but Node is not
+ * --> OK
+ */
+ return (TRUE);
+ }
+ else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
+ {
+ /*
+ * 4) Case (1,1): Both Op and Node are within the same method
+ * --> OK
+ */
+ return (TRUE);
+ }
+ else
+ {
+ /*
+ * 5) Case (1,1), Op and Node are in different methods
+ * --> Illegal
+ */
+ return (FALSE);
+ }
+}