diff options
Diffstat (limited to 'source/compiler/aslload.c')
-rw-r--r-- | source/compiler/aslload.c | 226 |
1 files changed, 173 insertions, 53 deletions
diff --git a/source/compiler/aslload.c b/source/compiler/aslload.c index d9728206f3c25..0d26c641d92ec 100644 --- a/source/compiler/aslload.c +++ b/source/compiler/aslload.c @@ -196,6 +196,15 @@ LdCheckSpecialNames ( ACPI_NAMESPACE_NODE *Node, ACPI_PARSE_OBJECT *Op); +static ACPI_STATUS +LdAnalyzeExternals ( + ACPI_NAMESPACE_NODE *Node, + ACPI_PARSE_OBJECT *Op, + ACPI_OBJECT_TYPE ExternalOpType, + ACPI_OBJECT_TYPE ObjectType, + ACPI_WALK_STATE *WalkState); + + /******************************************************************************* * * FUNCTION: LdLoadNamespace @@ -575,7 +584,8 @@ LdNamespace1Begin ( /* Check for a possible illegal forward reference */ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || - (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) + (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || + (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) { /* * Op->Asl.Namepath will be NULL for these opcodes. @@ -591,7 +601,8 @@ LdNamespace1Begin ( * We only want references to named objects: * Store (2, WXYZ) -> Attempt to resolve the name */ - if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) + if ((Op->Asl.ParseOpcode != PARSEOP_METHODCALL) && + (OpInfo->Class == AML_CLASS_NAMED_OBJECT)) { return (AE_OK); } @@ -899,56 +910,24 @@ LdNamespace1Begin ( Node->Type = (UINT8) ObjectType; Status = AE_OK; } - else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && - (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) + else if ((Node->Flags & ANOBJ_IS_EXTERNAL) || + (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) { - /* - * Allow one create on an object or segment that was - * previously declared External - */ - Node->Flags &= ~ANOBJ_IS_EXTERNAL; - Node->Type = (UINT8) ObjectType; - - /* Just retyped a node, probably will need to open a scope */ - - if (AcpiNsOpensScope (ObjectType)) + Status = LdAnalyzeExternals (Node, Op, ActualObjectType, + ObjectType, WalkState); + if (ACPI_FAILURE (Status)) { - Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); - if (ACPI_FAILURE (Status)) + if (Status == AE_ERROR) { - return_ACPI_STATUS (Status); + /* + * The use of AE_ERROR here indicates that there was a + * compiler error emitted in LdAnalyzeExternals which + * means that the caller should proceed to the next Op + * for analysis of subsequent parse objects. + */ + Status = AE_OK; } - } - - Status = AE_OK; - } - else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && - (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) - { - /* - * Allow externals in same scope as the definition of the - * actual object. Similar to C. Allows multiple definition - * blocks that refer to each other in the same file. - */ - Status = AE_OK; - } - else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && - (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && - (ObjectType == ACPI_TYPE_ANY)) - { - /* Allow update of externals of unknown type. */ - - if (AcpiNsOpensScope (ActualObjectType)) - { - Node->Type = (UINT8) ActualObjectType; - Status = AE_OK; - } - else - { - sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, - AcpiUtGetTypeName (Node->Type)); - AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (Status); } } else @@ -1013,15 +992,17 @@ FinishNode: * Set the actual data type if appropriate (EXTERNAL term only) * As of 11/19/2019, ASL External() does not support parameter * counts. When an External method is loaded, the parameter count is - * unknown setting Node->Value to ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS - * indicates that the parameter count for this method is unknown. - * This information is used in ASL cross reference to help determine the - * parameter count through method calls. + * recorded in the external's arg count parameter. The parameter count may + * or may not be known in the declaration. If the value of this node turns + * out to be ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS, it indicates that + * we do not know the parameter count and that we must look at the usage of + * the External method call to get this information. */ if (ActualObjectType != ACPI_TYPE_ANY) { Node->Type = (UINT8) ActualObjectType; - Node->Value = ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS; + Node->Value = (UINT32) + Op->Asl.Child->Asl.Next->Asl.Next->Asl.Value.Integer; } if (Op->Asl.ParseOpcode == PARSEOP_METHOD) @@ -1039,6 +1020,145 @@ FinishNode: /******************************************************************************* * + * FUNCTION: LdAnalyzeExternals + * + * PARAMETERS: Node - Node that represents the named object + * Op - Named object declaring this named object + * ExternalOpType - Type of ExternalOp + * ObjectType - Type of Declared object + * WalkState - Current WalkState + * + * RETURN: Status + * + * DESCRIPTION: Node and Op represents an identically named object declaration + * that is either declared by the ASL external keyword or declared + * by operators that declare named objects (i.e. Name, Device, + * OperationRegion, and etc.). This function ensures that the + * declarations do not contradict each other. + * + ******************************************************************************/ + +static ACPI_STATUS +LdAnalyzeExternals ( + ACPI_NAMESPACE_NODE *Node, + ACPI_PARSE_OBJECT *Op, + ACPI_OBJECT_TYPE ExternalOpType, + ACPI_OBJECT_TYPE ObjectType, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status = AE_OK; + ACPI_OBJECT_TYPE ActualExternalOpType; + ACPI_OBJECT_TYPE ActualOpType; + ACPI_PARSE_OBJECT *ExternalOp; + ACPI_PARSE_OBJECT *ActualOp; + + + /* + * The declaration represented by Node and Op must have the same type. + * The type of the external Op is represented by ExternalOpType. However, + * the type of the pre-existing declaration depends on whether if Op + * is an external declaration or an actual declaration. + */ + if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) + { + ActualExternalOpType = ExternalOpType; + ActualOpType = Node->Type; + } + else + { + ActualExternalOpType = Node->Type; + ActualOpType = ObjectType; + } + + if ((ActualOpType != ACPI_TYPE_ANY) && + (ActualExternalOpType != ACPI_TYPE_ANY) && + (ActualExternalOpType != ActualOpType)) + { + if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL && + Node->Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) + { + AslDualParseOpError (ASL_ERROR, + ASL_MSG_DUPLICATE_EXTERN_MISMATCH, Op, NULL, + ASL_MSG_DUPLICATE_EXTERN_FOUND_HERE, Node->Op, NULL); + } + else + { + if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL && + Node->Op->Asl.ParseOpcode != PARSEOP_EXTERNAL) + { + ExternalOp = Op; + ActualOp = Node->Op; + } + else + { + ExternalOp = Node->Op; + ActualOp = Op; + } + AslDualParseOpError (ASL_ERROR, + ASL_MSG_DECLARATION_TYPE_MISMATCH, ExternalOp, NULL, + ASL_MSG_TYPE_MISMATCH_FOUND_HERE, ActualOp, NULL); + } + } + + if ((Node->Flags & ANOBJ_IS_EXTERNAL) && + (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) + { + /* + * Allow one create on an object or segment that was + * previously declared External + */ + Node->Flags &= ~ANOBJ_IS_EXTERNAL; + Node->Type = (UINT8) ObjectType; + + /* Just retyped a node, probably will need to open a scope */ + + if (AcpiNsOpensScope (ObjectType)) + { + Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + + Status = AE_OK; + } + else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && + (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) + { + /* + * Allow externals in same scope as the definition of the + * actual object. Similar to C. Allows multiple definition + * blocks that refer to each other in the same file. + */ + Status = AE_OK; + } + else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && + (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && + (ObjectType == ACPI_TYPE_ANY)) + { + /* Allow update of externals of unknown type. */ + + if (AcpiNsOpensScope (ExternalOpType)) + { + Node->Type = (UINT8) ExternalOpType; + Status = AE_OK; + } + else + { + sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, + AcpiUtGetTypeName (Node->Type)); + AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); + Status = AE_ERROR; + } + } + + return (Status); +} + + +/******************************************************************************* + * * FUNCTION: LdCheckSpecialNames * * PARAMETERS: Node - Node that represents the named object |