📄 aslanalyze.c
字号:
char LocalName[] = "Local0"; char ArgName[] = "Arg0"; ACPI_PARSE_OBJECT *ArgNode; ACPI_PARSE_OBJECT *NextType; ACPI_PARSE_OBJECT *NextParamType; UINT8 ActualArgs = 0; switch (Op->Asl.ParseOpcode) { case PARSEOP_METHOD: TotalMethods++; /* Create and init method info */ MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); MethodInfo->Next = WalkInfo->MethodStack; MethodInfo->Op = Op; WalkInfo->MethodStack = MethodInfo; /* Get the name node, ignored here */ Next = Op->Asl.Child; /* Get the NumArguments node */ Next = Next->Asl.Next; MethodInfo->NumArguments = (UINT8) (((UINT8) Next->Asl.Value.Integer) & 0x07); /* Get the SerializeRule and SyncLevel nodes, ignored here */ Next = Next->Asl.Next; Next = Next->Asl.Next; ArgNode = Next; /* Get the ReturnType node */ Next = Next->Asl.Next; NextType = Next->Asl.Child; while (NextType) { /* Get and map each of the ReturnTypes */ MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; NextType = NextType->Asl.Next; } /* Get the ParameterType node */ Next = Next->Asl.Next; NextType = Next->Asl.Child; while (NextType) { if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) { NextParamType = NextType->Asl.Child; while (NextParamType) { MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType); NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; NextParamType = NextParamType->Asl.Next; } } else { MethodInfo->ValidArgTypes[ActualArgs] = AnMapObjTypeToBtype (NextType); NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; ActualArgs++; } NextType = NextType->Asl.Next; } if ((MethodInfo->NumArguments) && (MethodInfo->NumArguments != ActualArgs)) { /* error: Param list did not match number of args */ } /* Allow numarguments == 0 for Function() */ if ((!MethodInfo->NumArguments) && (ActualArgs)) { MethodInfo->NumArguments = ActualArgs; ArgNode->Asl.Value.Integer |= ActualArgs; } /* * Actual arguments are initialized at method entry. * All other ArgX "registers" can be used as locals, so we * track their initialization. */ for (i = 0; i < MethodInfo->NumArguments; i++) { MethodInfo->ArgInitialized[i] = TRUE; } break; case PARSEOP_METHODCALL: if (MethodInfo && (Op->Asl.Node == MethodInfo->Op->Asl.Node)) { AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); } break; case PARSEOP_LOCAL0: case PARSEOP_LOCAL1: case PARSEOP_LOCAL2: case PARSEOP_LOCAL3: case PARSEOP_LOCAL4: case PARSEOP_LOCAL5: case PARSEOP_LOCAL6: case PARSEOP_LOCAL7: if (!MethodInfo) { /* * Probably was an error in the method declaration, * no additional error here */ ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); return (AE_ERROR); } RegisterNumber = (Op->Asl.AmlOpcode & 0x000F); /* * If the local is being used as a target, mark the local * initialized */ if (Op->Asl.CompileFlags & NODE_IS_TARGET) { MethodInfo->LocalInitialized[RegisterNumber] = TRUE; } /* * Otherwise, this is a reference, check if the local * has been previously initialized. * * The only operator that accepts an uninitialized value is ObjectType() */ else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) { LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); } break; case PARSEOP_ARG0: case PARSEOP_ARG1: case PARSEOP_ARG2: case PARSEOP_ARG3: case PARSEOP_ARG4: case PARSEOP_ARG5: case PARSEOP_ARG6: if (!MethodInfo) { /* * Probably was an error in the method declaration, * no additional error here */ ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); return (AE_ERROR); } RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); /* * If the Arg is being used as a target, mark the local * initialized */ if (Op->Asl.CompileFlags & NODE_IS_TARGET) { MethodInfo->ArgInitialized[RegisterNumber] = TRUE; } /* * Otherwise, this is a reference, check if the Arg * has been previously initialized. * * The only operator that accepts an uninitialized value is ObjectType() */ else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) { AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); } /* Flag this arg if it is not a "real" argument to the method */ if (RegisterNumber >= MethodInfo->NumArguments) { AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); } break; case PARSEOP_RETURN: if (!MethodInfo) { /* * Probably was an error in the method declaration, * no additional error here */ ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); return (AE_ERROR); } /* Child indicates a return value */ if ((Op->Asl.Child) && (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) { MethodInfo->NumReturnWithValue++; } else { MethodInfo->NumReturnNoValue++; } break; case PARSEOP_BREAK: case PARSEOP_CONTINUE: Next = Op->Asl.Parent; while (Next) { if (Next->Asl.ParseOpcode == PARSEOP_WHILE) { break; } Next = Next->Asl.Parent; } if (!Next) { AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); } break; case PARSEOP_STALL: /* We can range check if the argument is an integer */ if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) { AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); } break; case PARSEOP_DEVICE: case PARSEOP_EVENT: case PARSEOP_MUTEX: case PARSEOP_OPERATIONREGION: case PARSEOP_POWERRESOURCE: case PARSEOP_PROCESSOR: case PARSEOP_THERMALZONE: /* * The first operand is a name to be created in the namespace. * Check against the reserved list. */ i = AnCheckForReservedName (Op, Op->Asl.NameSeg); if (i < ACPI_VALID_RESERVED_NAME_MAX) { AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); } break; case PARSEOP_NAME: i = AnCheckForReservedName (Op, Op->Asl.NameSeg); if (i < ACPI_VALID_RESERVED_NAME_MAX) { if (ReservedMethods[i].NumArguments > 0) { /* * This reserved name must be a control method because * it must have arguments */ AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments"); } /* Typechecking for _HID */ else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name)) { /* Examine the second operand to typecheck it */ Next = Op->Asl.Child->Asl.Next; if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) && (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)) { /* _HID must be a string or an integer */ AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer"); } if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) { /* * _HID is a string, all characters must be alphanumeric. * One of the things we want to catch here is the use of * a leading asterisk in the string. */ for (i = 0; Next->Asl.Value.String[i]; i++) { if (!isalnum (Next->Asl.Value.String[i])) { AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String); break; } } } } } break; default: break; } return AE_OK;}/******************************************************************************* * * FUNCTION: AnLastStatementIsReturn * * PARAMETERS: Op - A method parse node * * RETURN: TRUE if last statement is an ASL RETURN. False otherwise * * DESCRIPTION: Walk down the list of top level statements within a method * to find the last one. Check if that last statement is in * fact a RETURN statement. * ******************************************************************************/static BOOLEANAnLastStatementIsReturn ( ACPI_PARSE_OBJECT *Op){ ACPI_PARSE_OBJECT *Next; /* * Check if last statement is a return */ Next = ASL_GET_CHILD_NODE (Op); while (Next) { if ((!Next->Asl.Next) && (Next->Asl.ParseOpcode == PARSEOP_RETURN)) { return TRUE; } Next = ASL_GET_PEER_NODE (Next); } return FALSE;}/******************************************************************************* * * FUNCTION: AnMethodAnalysisWalkEnd * * PARAMETERS: ASL_WALK_CALLBACK * * RETURN: Status * * DESCRIPTION: Ascending callback for analysis walk. Complete method * return analysis. * ******************************************************************************/ACPI_STATUSAnMethodAnalysisWalkEnd ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context){ ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; switch (Op->Asl.ParseOpcode) { case PARSEOP_METHOD: case PARSEOP_RETURN: if (!MethodInfo) { printf ("No method info for method! [%s]\n", Op->Asl.Namepath); AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method"); CmCleanupAndExit (); return (AE_AML_INTERNAL); } break; default: break; } switch (Op->Asl.ParseOpcode) { case PARSEOP_METHOD: WalkInfo->MethodStack = MethodInfo->Next; /* * Check if there is no return statement at the end of the * method AND we can actually get there -- i.e., the execution * of the method can possibly terminate without a return statement. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -