diff options
Diffstat (limited to 'source/compiler/aslmethod.c')
-rw-r--r-- | source/compiler/aslmethod.c | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/source/compiler/aslmethod.c b/source/compiler/aslmethod.c index f191991..94e73d3 100644 --- a/source/compiler/aslmethod.c +++ b/source/compiler/aslmethod.c @@ -44,12 +44,22 @@ #include "aslcompiler.h" #include "aslcompiler.y.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("aslmethod") +/* Local prototypes */ + +void +MtCheckNamedObjectInMethod ( + ACPI_PARSE_OBJECT *Op, + ASL_METHOD_INFO *MethodInfo); + + /******************************************************************************* * * FUNCTION: MtMethodAnalysisWalkBegin @@ -111,6 +121,8 @@ MtMethodAnalysisWalkBegin ( /* Get the SerializeRule and SyncLevel nodes, ignored here */ Next = Next->Asl.Next; + MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer; + Next = Next->Asl.Next; ArgNode = Next; @@ -181,7 +193,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_METHODCALL: if (MethodInfo && @@ -191,7 +202,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_LOCAL0: case PARSEOP_LOCAL1: case PARSEOP_LOCAL2: @@ -236,7 +246,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_ARG0: case PARSEOP_ARG1: case PARSEOP_ARG2: @@ -287,7 +296,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_RETURN: if (!MethodInfo) @@ -320,7 +328,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_BREAK: case PARSEOP_CONTINUE: @@ -340,7 +347,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_STALL: /* We can range check if the argument is an integer */ @@ -352,7 +358,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_DEVICE: case PARSEOP_EVENT: case PARSEOP_MUTEX: @@ -372,7 +377,6 @@ MtMethodAnalysisWalkBegin ( } break; - case PARSEOP_NAME: /* Typecheck any predefined names statically defined with Name() */ @@ -410,17 +414,76 @@ MtMethodAnalysisWalkBegin ( } break; - default: + break; } + /* Check for named object creation within a non-serialized method */ + + MtCheckNamedObjectInMethod (Op, MethodInfo); return (AE_OK); } /******************************************************************************* * + * FUNCTION: MtCheckNamedObjectInMethod + * + * PARAMETERS: Op - Current parser op + * MethodInfo - Info for method being parsed + * + * RETURN: None + * + * DESCRIPTION: Detect if a non-serialized method is creating a named object, + * which could possibly cause problems if two threads execute + * the method concurrently. Emit a remark in this case. + * + ******************************************************************************/ + +void +MtCheckNamedObjectInMethod ( + ACPI_PARSE_OBJECT *Op, + ASL_METHOD_INFO *MethodInfo) +{ + const ACPI_OPCODE_INFO *OpInfo; + + + /* We don't care about actual method declarations */ + + if (Op->Asl.AmlOpcode == AML_METHOD_OP) + { + return; + } + + /* Determine if we are creating a named object */ + + OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); + if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) + { + /* + * If we have a named object created within a non-serialized method, + * emit a remark that the method should be serialized. + * + * Reason: If a thread blocks within the method for any reason, and + * another thread enters the method, the method will fail because an + * attempt will be made to create the same object twice. + */ + if (MethodInfo && !MethodInfo->ShouldBeSerialized) + { + AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, + "due to creation of named objects within"); + + /* Emit message only ONCE per method */ + + MethodInfo->ShouldBeSerialized = TRUE; + } + } +} + + +/******************************************************************************* + * * FUNCTION: MtMethodAnalysisWalkEnd * * PARAMETERS: ASL_WALK_CALLBACK @@ -446,6 +509,7 @@ MtMethodAnalysisWalkEnd ( { case PARSEOP_METHOD: case PARSEOP_RETURN: + if (!MethodInfo) { printf ("No method info for method! [%s]\n", Op->Asl.Namepath); @@ -458,6 +522,7 @@ MtMethodAnalysisWalkEnd ( break; default: + break; } @@ -534,7 +599,6 @@ MtMethodAnalysisWalkEnd ( ACPI_FREE (MethodInfo); break; - case PARSEOP_NAME: /* Special check for two names like _L01 and _E01 in same scope */ @@ -542,7 +606,6 @@ MtMethodAnalysisWalkEnd ( ApCheckForGpeNameConflict (Op); break; - case PARSEOP_RETURN: /* @@ -572,7 +635,6 @@ MtMethodAnalysisWalkEnd ( } break; - case PARSEOP_IF: if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && @@ -588,7 +650,6 @@ MtMethodAnalysisWalkEnd ( } break; - case PARSEOP_ELSE: if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && |