diff options
Diffstat (limited to 'source/compiler')
-rw-r--r-- | source/compiler/aslascii.c | 5 | ||||
-rw-r--r-- | source/compiler/aslcompile.c | 4 | ||||
-rw-r--r-- | source/compiler/asldefine.h | 7 | ||||
-rw-r--r-- | source/compiler/aslfiles.c | 40 | ||||
-rw-r--r-- | source/compiler/asllookup.c | 65 | ||||
-rw-r--r-- | source/compiler/aslmessages.c | 6 | ||||
-rw-r--r-- | source/compiler/aslmessages.h | 3 | ||||
-rw-r--r-- | source/compiler/aslmethod.c | 2 | ||||
-rw-r--r-- | source/compiler/aslnamesp.c | 2 | ||||
-rw-r--r-- | source/compiler/asloffset.c | 2 | ||||
-rw-r--r-- | source/compiler/aslopcodes.c | 46 | ||||
-rw-r--r-- | source/compiler/aslopt.c | 4 | ||||
-rw-r--r-- | source/compiler/asloptions.c | 5 | ||||
-rw-r--r-- | source/compiler/aslstartup.c | 12 | ||||
-rw-r--r-- | source/compiler/aslstubs.c | 63 | ||||
-rw-r--r-- | source/compiler/asltypes.h | 14 | ||||
-rw-r--r-- | source/compiler/aslutils.c | 8 | ||||
-rw-r--r-- | source/compiler/aslxref.c | 481 | ||||
-rw-r--r-- | source/compiler/dtcompiler.h | 4 | ||||
-rw-r--r-- | source/compiler/dttable.c | 71 | ||||
-rw-r--r-- | source/compiler/dttemplate.h | 18 | ||||
-rw-r--r-- | source/compiler/prparser.l | 89 | ||||
-rw-r--r-- | source/compiler/prparser.y | 5 | ||||
-rw-r--r-- | source/compiler/prscan.c | 92 |
24 files changed, 770 insertions, 278 deletions
diff --git a/source/compiler/aslascii.c b/source/compiler/aslascii.c index 7ff1c4a653c7c..f164e98f5edf9 100644 --- a/source/compiler/aslascii.c +++ b/source/compiler/aslascii.c @@ -177,6 +177,11 @@ FlCheckForAscii ( /* Open file in text mode so file offset is always accurate */ Handle = fopen (Filename, "rb"); + if (!Handle) + { + perror ("Could not open input file"); + return (AE_ERROR); + } Status.Line = 1; Status.Offset = 0; diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index afc004d7deeef..9e5b53a512748 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -100,6 +100,10 @@ CmDoCompile ( Event = UtBeginEvent ("Preprocess input file"); if (Gbl_PreprocessFlag) { + /* Enter compiler name as a #define */ + + PrAddDefine (ASL_DEFINE, "", FALSE); + /* Preprocessor */ PrDoPreprocess (); diff --git a/source/compiler/asldefine.h b/source/compiler/asldefine.h index 0b5f614a6481e..9e42ddf8b2489 100644 --- a/source/compiler/asldefine.h +++ b/source/compiler/asldefine.h @@ -52,6 +52,7 @@ #define AML_DISASSEMBLER_NAME "AML/ASL+ Disassembler" #define ASL_INVOCATION_NAME "iasl" #define ASL_CREATOR_ID "INTL" +#define ASL_DEFINE "__IASL__" #define ASL_COMPLIANCE "Supports ACPI Specification Revision 6.0" @@ -155,12 +156,6 @@ #define ACPI_COMPILER_RESERVED_NAME (ACPI_UINT32_MAX - 3) -/* String to Integer conversion */ - -#define NEGATIVE 1 -#define POSITIVE 0 - - /* Helper macros for resource tag creation */ #define RsCreateMultiBitField \ diff --git a/source/compiler/aslfiles.c b/source/compiler/aslfiles.c index 2ad62ecc18a45..1b738ccf15d88 100644 --- a/source/compiler/aslfiles.c +++ b/source/compiler/aslfiles.c @@ -546,6 +546,26 @@ FlOpenMiscOutputFiles ( char *Filename; + /* Create/Open a map file if requested */ + + if (Gbl_MapfileFlag) + { + Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP); + if (!Filename) + { + AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, + 0, 0, 0, 0, NULL, NULL); + return (AE_ERROR); + } + + /* Open the hex file, text mode (closed at compiler exit) */ + + FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t"); + + AslCompilerSignon (ASL_FILE_MAP_OUTPUT); + AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT); + } + /* All done for disassembler */ if (Gbl_FileType == ASL_INPUT_TYPE_ACPI_TABLE) @@ -812,26 +832,6 @@ FlOpenMiscOutputFiles ( AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT); } - /* Create/Open a map file if requested */ - - if (Gbl_MapfileFlag) - { - Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP); - if (!Filename) - { - AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, - 0, 0, 0, 0, NULL, NULL); - return (AE_ERROR); - } - - /* Open the hex file, text mode (closed at compiler exit) */ - - FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t"); - - AslCompilerSignon (ASL_FILE_MAP_OUTPUT); - AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT); - } - return (AE_OK); } diff --git a/source/compiler/asllookup.c b/source/compiler/asllookup.c index 61148225ffd69..49b4901b8a91b 100644 --- a/source/compiler/asllookup.c +++ b/source/compiler/asllookup.c @@ -119,8 +119,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) diff --git a/source/compiler/aslmessages.c b/source/compiler/aslmessages.c index 520ebe0760fe4..bd693110e0a59 100644 --- a/source/compiler/aslmessages.c +++ b/source/compiler/aslmessages.c @@ -235,7 +235,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 */ diff --git a/source/compiler/aslmessages.h b/source/compiler/aslmessages.h index 9837d540698fb..d7e3dd06e8b68 100644 --- a/source/compiler/aslmessages.h +++ b/source/compiler/aslmessages.h @@ -238,6 +238,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 */ diff --git a/source/compiler/aslmethod.c b/source/compiler/aslmethod.c index 6d53cec5555d9..40ed971e07122 100644 --- a/source/compiler/aslmethod.c +++ b/source/compiler/aslmethod.c @@ -255,7 +255,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 diff --git a/source/compiler/aslnamesp.c b/source/compiler/aslnamesp.c index c35ebfd6b4aca..e2dea6fff5f6b 100644 --- a/source/compiler/aslnamesp.c +++ b/source/compiler/aslnamesp.c @@ -409,7 +409,7 @@ NsDoOnePathname ( TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiNsHandleToPathname (Node, &TargetPath); + Status = AcpiNsHandleToPathname (Node, &TargetPath, FALSE); if (ACPI_FAILURE (Status)) { return (Status); diff --git a/source/compiler/asloffset.c b/source/compiler/asloffset.c index baf436ef8dc48..b1e6f5ac146f9 100644 --- a/source/compiler/asloffset.c +++ b/source/compiler/asloffset.c @@ -363,7 +363,7 @@ LsEmitOffsetTableEntry ( /* Get the full pathname to the namespace node */ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiNsHandleToPathname (Node, &TargetPath); + Status = AcpiNsHandleToPathname (Node, &TargetPath, FALSE); if (ACPI_FAILURE (Status)) { return; diff --git a/source/compiler/aslopcodes.c b/source/compiler/aslopcodes.c index fa3d1fca0e110..a7f14de6d3b81 100644 --- a/source/compiler/aslopcodes.c +++ b/source/compiler/aslopcodes.c @@ -791,43 +791,6 @@ OpcEncodePldBuffer ( /******************************************************************************* * - * FUNCTION: OpcStrupr (strupr) - * - * PARAMETERS: SrcString - The source string to convert - * - * RETURN: None - * - * DESCRIPTION: Convert string to uppercase - * - * NOTE: This is not a POSIX function, so it appears here, not in utclib.c - * - ******************************************************************************/ - -static void -OpcStrupr ( - char *SrcString) -{ - char *String; - - - if (!SrcString) - { - return; - } - - /* Walk entire string, uppercasing the letters */ - - for (String = SrcString; *String; String++) - { - *String = (char) toupper ((int) *String); - } - - return; -} - - -/******************************************************************************* - * * FUNCTION: OpcFindName * * PARAMETERS: List - Array of char strings to be searched @@ -851,7 +814,7 @@ OpcFindName ( UINT32 i; - OpcStrupr (Name); + AcpiUtStrupr (Name); for (i = 0, Str = List[0]; Str; i++, Str = List[i]) { @@ -900,13 +863,6 @@ OpcDoPld ( return; } - Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE); - if (!Buffer) - { - AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL); - return; - } - memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO)); Node = Op->Asl.Child; diff --git a/source/compiler/aslopt.c b/source/compiler/aslopt.c index 7770f3eb4bb14..e41e22f087b09 100644 --- a/source/compiler/aslopt.c +++ b/source/compiler/aslopt.c @@ -655,7 +655,7 @@ OptOptimizeNamePath ( * format -- something we can easily manipulate */ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiNsHandleToPathname (TargetNode, &TargetPath); + Status = AcpiNsHandleToPathname (TargetNode, &TargetPath, FALSE); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Getting Target NamePath", @@ -667,7 +667,7 @@ OptOptimizeNamePath ( /* CurrentPath is the path to this scope (where we are in the namespace) */ CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath); + Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath, FALSE); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Getting Current NamePath", diff --git a/source/compiler/asloptions.c b/source/compiler/asloptions.c index 57bb12b03f8e1..69c83257a550c 100644 --- a/source/compiler/asloptions.c +++ b/source/compiler/asloptions.c @@ -286,6 +286,11 @@ AslDoOptions ( AcpiGbl_CstyleDisassembly = FALSE; break; + case 'v': + + AcpiGbl_DbOpt_Verbose = TRUE; + break; + default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); diff --git a/source/compiler/aslstartup.c b/source/compiler/aslstartup.c index 1ec9a351e2cdd..0e05da401c0be 100644 --- a/source/compiler/aslstartup.c +++ b/source/compiler/aslstartup.c @@ -246,6 +246,11 @@ AslDoDisassembly ( return (Status); } + /* Handle additional output files for disassembler */ + + Gbl_FileType = ASL_INPUT_TYPE_ACPI_TABLE; + Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); + /* This is where the disassembly happens */ AcpiGbl_DbOpt_Disasm = TRUE; @@ -261,13 +266,6 @@ AslDoDisassembly ( AcpiDmUnresolvedWarning (0); -#if 0 - /* TBD: Handle additional output files for disassembler */ - - Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); - NsDisplayNamespace (); -#endif - /* Shutdown compiler and ACPICA subsystem */ AeClearErrorLog (); diff --git a/source/compiler/aslstubs.c b/source/compiler/aslstubs.c index d624fc43cd292..26f607fbbe9c5 100644 --- a/source/compiler/aslstubs.c +++ b/source/compiler/aslstubs.c @@ -165,15 +165,6 @@ AcpiEvInitializeRegion ( return (AE_OK); } -void -AcpiExDoDebugObject ( - ACPI_OPERAND_OBJECT *SourceDesc, - UINT32 Level, - UINT32 Index) -{ - return; -} - ACPI_STATUS AcpiExReadDataFromField ( ACPI_WALK_STATE *WalkState, @@ -216,6 +207,60 @@ AcpiExLoadOp ( return (AE_SUPPORT); } +void +AcpiExDoDebugObject ( + ACPI_OPERAND_OBJECT *SourceDesc, + UINT32 Level, + UINT32 Index) +{ + return; +} + +void +AcpiExStartTraceMethod ( + ACPI_NAMESPACE_NODE *MethodNode, + ACPI_OPERAND_OBJECT *ObjDesc, + ACPI_WALK_STATE *WalkState) +{ + return; +} + +void +AcpiExStopTraceMethod ( + ACPI_NAMESPACE_NODE *MethodNode, + ACPI_OPERAND_OBJECT *ObjDesc, + ACPI_WALK_STATE *WalkState) +{ + return; +} + +void +AcpiExStartTraceOpcode ( + ACPI_PARSE_OBJECT *Op, + ACPI_WALK_STATE *WalkState) +{ + return; +} + +void +AcpiExStopTraceOpcode ( + ACPI_PARSE_OBJECT *Op, + ACPI_WALK_STATE *WalkState) + +{ + return; +} + +void +AcpiExTracePoint ( + ACPI_TRACE_EVENT_TYPE Type, + BOOLEAN Begin, + UINT8 *Aml, + char *Pathname) +{ + return; +} + ACPI_STATUS AcpiTbFindTable ( char *Signature, diff --git a/source/compiler/asltypes.h b/source/compiler/asltypes.h index 343c364c49ffb..ce2f75888ff54 100644 --- a/source/compiler/asltypes.h +++ b/source/compiler/asltypes.h @@ -302,5 +302,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 */ diff --git a/source/compiler/aslutils.c b/source/compiler/aslutils.c index 8b77c8e1f4fae..9ea4c19c48a09 100644 --- a/source/compiler/aslutils.c +++ b/source/compiler/aslutils.c @@ -1008,17 +1008,17 @@ stroul64 ( */ if (*String == '-') { - Sign = NEGATIVE; + Sign = ACPI_SIGN_NEGATIVE; ++String; } else if (*String == '+') { ++String; - Sign = POSITIVE; + Sign = ACPI_SIGN_POSITIVE; } else { - Sign = POSITIVE; + Sign = ACPI_SIGN_POSITIVE; } /* @@ -1106,7 +1106,7 @@ stroul64 ( /* If a minus sign was present, then "the conversion is negated": */ - if (Sign == NEGATIVE) + if (Sign == ACPI_SIGN_NEGATIVE) { ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; } diff --git a/source/compiler/aslxref.c b/source/compiler/aslxref.c index 8ffe5ad6a1d18..6b65bb1699bf9 100644 --- a/source/compiler/aslxref.c +++ b/source/compiler/aslxref.c @@ -66,6 +66,10 @@ XfNamespaceLocateEnd ( UINT32 Level, void *Context); +static ACPI_PARSE_OBJECT * +XfGetParentMethod ( + ACPI_PARSE_OBJECT *Op); + static BOOLEAN XfObjectExists ( char *Name); @@ -280,59 +284,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 - * - * RETURN: Op for parent method. NULL if object is not within a method. + * PARAMETERS: Op - Parse Op to be checked * - * DESCRIPTION: Determine if an object is within a control method. Used to - * implement special rules for named references from within a - * control method. + * RETURN: Control method Op if found. NULL otherwise * - * 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. * ******************************************************************************/ @@ -340,120 +301,22 @@ 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; - } + ACPI_PARSE_OBJECT *NextOp; - /* Objects not in the same method? */ - if (MethodOp1 != MethodOp2) + NextOp = Op->Asl.Parent; + while (NextOp) { - /* - * 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)) + if (NextOp->Asl.AmlOpcode == AML_METHOD_OP) { - AslError (ASL_ERROR, ASL_MSG_ILLEGAL_METHOD_REF, Op, - Op->Asl.ExternalName); + return (NextOp); } - } - /* - * 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); + NextOp = NextOp->Asl.Parent; } + return (NULL); /* No parent method found */ } -#endif - /******************************************************************************* * @@ -496,10 +359,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)"], @@ -512,10 +432,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) && @@ -1094,3 +1092,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 diff --git a/source/compiler/dtcompiler.h b/source/compiler/dtcompiler.h index 44fc56de812b5..55d7c1285225d 100644 --- a/source/compiler/dtcompiler.h +++ b/source/compiler/dtcompiler.h @@ -537,6 +537,10 @@ DtCompileStao ( void **PFieldList); ACPI_STATUS +DtCompileTcpa ( + void **PFieldList); + +ACPI_STATUS DtCompileUefi ( void **PFieldList); diff --git a/source/compiler/dttable.c b/source/compiler/dttable.c index 22b4c9c4c165e..c5b2ef9f6f2e6 100644 --- a/source/compiler/dttable.c +++ b/source/compiler/dttable.c @@ -3122,6 +3122,77 @@ DtCompileStao ( /****************************************************************************** * + * FUNCTION: DtCompileTcpa + * + * PARAMETERS: PFieldList - Current field list pointer + * + * RETURN: Status + * + * DESCRIPTION: Compile TCPA. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileTcpa ( + void **List) +{ + DT_FIELD **PFieldList = (DT_FIELD **) List; + DT_SUBTABLE *Subtable; + ACPI_TABLE_TCPA_HDR *TcpaHeader; + DT_SUBTABLE *ParentTable; + ACPI_STATUS Status; + + + /* Compile the main table */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + /* + * Examine the PlatformClass field to determine the table type. + * Either a client or server table. Only one. + */ + TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); + + switch (TcpaHeader->PlatformClass) + { + case ACPI_TCPA_CLIENT_TABLE: + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, + &Subtable, TRUE); + break; + + case ACPI_TCPA_SERVER_TABLE: + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, + &Subtable, TRUE); + break; + + default: + + AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", + TcpaHeader->PlatformClass); + Status = AE_ERROR; + break; + } + + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + return (Status); +} + + +/****************************************************************************** + * * FUNCTION: DtGetGenericTableInfo * * PARAMETERS: Name - Generic type name diff --git a/source/compiler/dttemplate.h b/source/compiler/dttemplate.h index 6d76f4d64b9c0..6f3ed6407012f 100644 --- a/source/compiler/dttemplate.h +++ b/source/compiler/dttemplate.h @@ -1144,13 +1144,19 @@ const unsigned char TemplateStao[] = const unsigned char TemplateTcpa[] = { - 0x54,0x43,0x50,0x41,0x32,0x00,0x00,0x00, /* 00000000 "TCPA2..." */ - 0x01,0x67,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".gINTEL " */ - 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */ + 0x54,0x43,0x50,0x41,0x64,0x00,0x00,0x00, /* 00000000 "TCPAd..." */ + 0x02,0xFF,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */ + 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */ 0x80,0x31,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 ".1..INTL" */ - 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */ - 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */ - 0x00,0x00 /* 00000030 ".." */ + 0x19,0x06,0x15,0x20,0x01,0x00,0x00,0x00, /* 00000020 "... ...." */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */ + 0x11,0x00,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA, /* 00000030 "........" */ + 0x02,0x01,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */ + 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x03, /* 00000040 "..... .." */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */ + 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x03, /* 00000050 "..... .." */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */ + 0x01,0x01,0x01,0x01 /* 00000060 "...." */ }; const unsigned char TemplateTpm2[] = diff --git a/source/compiler/prparser.l b/source/compiler/prparser.l index 10bd130487f5a..3ef0f453fe46f 100644 --- a/source/compiler/prparser.l +++ b/source/compiler/prparser.l @@ -50,14 +50,22 @@ #define STRING_SETUP strcpy (StringBuffer, PrParsertext);\ PrParserlval.str = StringBuffer -#define YY_NO_INPUT /* No file input, we use strings only */ - #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("prscanner") + + +/* Local prototypes */ + +static char +PrDoCommentType1 ( + void); + +static char +PrDoCommentType2 ( + void); %} %option noyywrap -%option nounput Number [0-9a-fA-F]+ HexNumber 0[xX][0-9a-fA-F]+ @@ -66,6 +74,8 @@ NewLine [\n] Identifier [a-zA-Z][0-9a-zA-Z]* %% +"/*" { if (!PrDoCommentType1 ()) {yyterminate ();} } +"//" { if (!PrDoCommentType2 ()) {yyterminate ();} } \( return (EXPOP_PAREN_OPEN); \) return (EXPOP_PAREN_CLOSE); @@ -151,3 +161,76 @@ PrTerminateLexer ( yy_delete_buffer (LexBuffer); } + + +/******************************************************************************** + * + * FUNCTION: PrDoCommentType1 + * + * PARAMETERS: none + * + * RETURN: none + * + * DESCRIPTION: Process a new legacy comment. Just toss it. + * + ******************************************************************************/ + +static char +PrDoCommentType1 ( + void) +{ + int c; + + +Loop: + while (((c = input ()) != '*') && (c != EOF)) + { + } + if (c == EOF) + { + return (FALSE); + } + + if (((c = input ()) != '/') && (c != EOF)) + { + unput (c); + goto Loop; + } + if (c == EOF) + { + return (FALSE); + } + + return (TRUE); +} + + +/******************************************************************************** + * + * FUNCTION: PrDoCommentType2 + * + * PARAMETERS: none + * + * RETURN: none + * + * DESCRIPTION: Process a new "//" comment. Just toss it. + * + ******************************************************************************/ + +static char +PrDoCommentType2 ( + void) +{ + int c; + + + while (((c = input ()) != '\n') && (c != EOF)) + { + } + if (c == EOF) + { + return (FALSE); + } + + return (TRUE); +} diff --git a/source/compiler/prparser.y b/source/compiler/prparser.y index 67587331a119d..5ed30f53bc15a 100644 --- a/source/compiler/prparser.y +++ b/source/compiler/prparser.y @@ -213,8 +213,11 @@ void PrParsererror ( char const *Message) { + + sprintf (StringBuffer, "Preprocessor Parser : %s (near line %u)", + Message, Gbl_CurrentLineNumber); DtError (ASL_ERROR, ASL_MSG_SYNTAX, - NULL, (char *) Message); + NULL, (char *) StringBuffer); } diff --git a/source/compiler/prscan.c b/source/compiler/prscan.c index 393d80149fb10..27eb6be85318e 100644 --- a/source/compiler/prscan.c +++ b/source/compiler/prscan.c @@ -120,7 +120,6 @@ static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = {"include", 0}, /* Argument is not standard format, so just use 0 here */ {"includebuffer", 0}, /* Argument is not standard format, so just use 0 here */ {"line", 1}, - {"loadbuffer", 0}, {"pragma", 1}, {"undef", 1}, {"warning", 1}, @@ -144,7 +143,7 @@ enum Gbl_DirectiveIndexes PR_DIRECTIVE_LINE, PR_DIRECTIVE_PRAGMA, PR_DIRECTIVE_UNDEF, - PR_DIRECTIVE_WARNING, + PR_DIRECTIVE_WARNING }; #define ASL_DIRECTIVE_NOT_FOUND -1 @@ -328,7 +327,7 @@ PrPreprocessInputFile ( PrGetNextLineInit (); - /* Scan line-by-line. Comments and blank lines are skipped by this function */ + /* Scan source line-by-line and process directives. Then write the .i file */ while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) { @@ -479,6 +478,16 @@ PrDoDirective ( } /* + * Emit a line directive into the preprocessor file (.pre) after + * every matched directive. This is passed through to the compiler + * so that error/warning messages are kept in sync with the + * original source file. + */ + FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n", + Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename, + Gbl_DirectiveInfo[Directive].Name); + + /* * If we are currently ignoring this block and we encounter a #else or * #elif, we must ignore their blocks also if the parent block is also * being ignored. @@ -825,6 +834,9 @@ PrDoDirective ( PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); + + Gbl_SourceLine = 0; + Gbl_NextError = Gbl_ErrorLog; break; default: @@ -863,7 +875,9 @@ SyntaxError: ******************************************************************************/ #define PR_NORMAL_TEXT 0 -#define PR_WITHIN_COMMENT 1 +#define PR_MULTI_LINE_COMMENT 1 +#define PR_SINGLE_LINE_COMMENT 2 +#define PR_QUOTED_STRING 3 static UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT; @@ -904,22 +918,55 @@ PrGetNextLine ( return (ASL_EOF); } - /* We need to worry about multi-line slash-asterisk comments */ - - /* Check for comment open */ + /* Update state machine as necessary */ - if ((AcpiGbl_LineScanState == PR_NORMAL_TEXT) && - (PreviousChar == '/') && (c == '*')) + switch (AcpiGbl_LineScanState) { - AcpiGbl_LineScanState = PR_WITHIN_COMMENT; - } + case PR_NORMAL_TEXT: - /* Check for comment close */ + /* Check for multi-line comment start */ - if ((AcpiGbl_LineScanState == PR_WITHIN_COMMENT) && - (PreviousChar == '*') && (c == '/')) - { - AcpiGbl_LineScanState = PR_NORMAL_TEXT; + if ((PreviousChar == '/') && (c == '*')) + { + AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT; + } + + /* Check for single-line comment start */ + + else if ((PreviousChar == '/') && (c == '/')) + { + AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT; + } + + /* Check for quoted string start */ + + else if (PreviousChar == '"') + { + AcpiGbl_LineScanState = PR_QUOTED_STRING; + } + break; + + case PR_QUOTED_STRING: + + if (PreviousChar == '"') + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + } + break; + + case PR_MULTI_LINE_COMMENT: + + /* Check for multi-line comment end */ + + if ((PreviousChar == '*') && (c == '/')) + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + } + break; + + case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */ + default: + break; } /* Always copy the character into line buffer */ @@ -933,10 +980,21 @@ PrGetNextLine ( { /* Handle multi-line comments */ - if (AcpiGbl_LineScanState == PR_WITHIN_COMMENT) + if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT) { return (ASL_WITHIN_COMMENT); } + + /* End of single-line comment */ + + if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT) + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + return (AE_OK); + } + + /* Blank line */ + if (i == 1) { return (ASL_BLANK_LINE); |