Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "aslcompiler.h"
    153 #include "aslcompiler.y.h"
    154 #include "acparser.h"
    155 #include "amlcode.h"
    156 
    157 
    158 #define _COMPONENT          ACPI_COMPILER
    159         ACPI_MODULE_NAME    ("aslwalks")
    160 
    161 
    162 /* Local prototypes */
    163 
    164 static void
    165 AnAnalyzeStoreOperator (
    166     ACPI_PARSE_OBJECT       *Op);
    167 
    168 static BOOLEAN
    169 AnIsValidBufferConstant (
    170     ACPI_PARSE_OBJECT       *Op);
    171 
    172 static void
    173 AnValidateCreateBufferField (
    174     ACPI_PARSE_OBJECT       *CreateBufferFieldOp);
    175 
    176 
    177 /*******************************************************************************
    178  *
    179  * FUNCTION:    AnMethodTypingWalkEnd
    180  *
    181  * PARAMETERS:  ASL_WALK_CALLBACK
    182  *
    183  * RETURN:      Status
    184  *
    185  * DESCRIPTION: Ascending callback for typing walk. Complete the method
    186  *              return analysis. Check methods for:
    187  *              1) Initialized local variables
    188  *              2) Valid arguments
    189  *              3) Return types
    190  *
    191  ******************************************************************************/
    192 
    193 ACPI_STATUS
    194 AnMethodTypingWalkEnd (
    195     ACPI_PARSE_OBJECT       *Op,
    196     UINT32                  Level,
    197     void                    *Context)
    198 {
    199     UINT32                  ThisOpBtype;
    200 
    201 
    202     switch (Op->Asl.ParseOpcode)
    203     {
    204     case PARSEOP_METHOD:
    205 
    206         Op->Asl.CompileFlags |= OP_METHOD_TYPED;
    207         break;
    208 
    209     case PARSEOP_RETURN:
    210 
    211         if ((Op->Asl.Child) &&
    212             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
    213         {
    214             ThisOpBtype = AnGetBtype (Op->Asl.Child);
    215 
    216             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
    217                 (ThisOpBtype == (ACPI_UINT32_MAX -1)))
    218             {
    219                 /*
    220                  * The called method is untyped at this time (typically a
    221                  * forward reference).
    222                  *
    223                  * Check for a recursive method call first. Note: the
    224                  * Child->Node will be null if the method has not been
    225                  * resolved.
    226                  */
    227                 if (Op->Asl.Child->Asl.Node &&
    228                     (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op))
    229                 {
    230                     /* We must type the method here */
    231 
    232                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
    233                         ASL_WALK_VISIT_UPWARD, NULL,
    234                         AnMethodTypingWalkEnd, NULL);
    235 
    236                     ThisOpBtype = AnGetBtype (Op->Asl.Child);
    237                 }
    238             }
    239 
    240             /* Returns a value, save the value type */
    241 
    242             if (Op->Asl.ParentMethod)
    243             {
    244                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
    245             }
    246         }
    247         break;
    248 
    249     default:
    250 
    251         break;
    252     }
    253 
    254     return (AE_OK);
    255 }
    256 
    257 
    258 /*******************************************************************************
    259  *
    260  * FUNCTION:    AnOperandTypecheckWalkEnd
    261  *
    262  * PARAMETERS:  ASL_WALK_CALLBACK
    263  *
    264  * RETURN:      Status
    265  *
    266  * DESCRIPTION: Ascending callback for analysis walk. Complete method
    267  *              return analysis.
    268  *
    269  ******************************************************************************/
    270 
    271 ACPI_STATUS
    272 AnOperandTypecheckWalkEnd (
    273     ACPI_PARSE_OBJECT       *Op,
    274     UINT32                  Level,
    275     void                    *Context)
    276 {
    277     const ACPI_OPCODE_INFO  *OpInfo;
    278     UINT32                  RuntimeArgTypes;
    279     UINT32                  RuntimeArgTypes2;
    280     UINT32                  RequiredBtypes;
    281     UINT32                  ThisNodeBtype;
    282     UINT32                  CommonBtypes;
    283     UINT32                  OpcodeClass;
    284     ACPI_PARSE_OBJECT       *ArgOp;
    285     UINT32                  ArgType;
    286 
    287 
    288     switch (Op->Asl.AmlOpcode)
    289     {
    290     case AML_RAW_DATA_BYTE:
    291     case AML_RAW_DATA_WORD:
    292     case AML_RAW_DATA_DWORD:
    293     case AML_RAW_DATA_QWORD:
    294     case AML_RAW_DATA_BUFFER:
    295     case AML_RAW_DATA_CHAIN:
    296     case AML_PACKAGE_LENGTH:
    297     case AML_UNASSIGNED_OPCODE:
    298     case AML_DEFAULT_ARG_OP:
    299 
    300         /* Ignore the internal (compiler-only) AML opcodes */
    301 
    302         return (AE_OK);
    303 
    304     default:
    305 
    306         break;
    307     }
    308 
    309     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    310     if (!OpInfo)
    311     {
    312         return (AE_OK);
    313     }
    314 
    315     ArgOp = Op->Asl.Child;
    316     OpcodeClass = OpInfo->Class;
    317     RuntimeArgTypes = OpInfo->RuntimeArgs;
    318 
    319 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
    320     /*
    321      * Update 11/2008: In practice, we can't perform this check. A simple
    322      * analysis is not sufficient. Also, it can cause errors when compiling
    323      * disassembled code because of the way Switch operators are implemented
    324      * (a While(One) loop with a named temp variable created within.)
    325      */
    326 
    327     /*
    328      * If we are creating a named object, check if we are within a while loop
    329      * by checking if the parent is a WHILE op. This is a simple analysis, but
    330      * probably sufficient for many cases.
    331      *
    332      * Allow Scope(), Buffer(), and Package().
    333      */
    334     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
    335         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
    336     {
    337         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
    338         {
    339             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
    340         }
    341     }
    342 #endif
    343 
    344     /*
    345      * Special case for control opcodes IF/RETURN/WHILE since they
    346      * have no runtime arg list (at this time)
    347      */
    348     switch (Op->Asl.AmlOpcode)
    349     {
    350     case AML_IF_OP:
    351     case AML_WHILE_OP:
    352     case AML_RETURN_OP:
    353 
    354         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
    355         {
    356             /* Check for an internal method */
    357 
    358             if (AnIsInternalMethod (ArgOp))
    359             {
    360                 return (AE_OK);
    361             }
    362 
    363             /* The lone arg is a method call, check it */
    364 
    365             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
    366             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
    367             {
    368                 RequiredBtypes = 0xFFFFFFFF;
    369             }
    370 
    371             ThisNodeBtype = AnGetBtype (ArgOp);
    372             if (ThisNodeBtype == ACPI_UINT32_MAX)
    373             {
    374                 return (AE_OK);
    375             }
    376 
    377             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
    378                 RequiredBtypes, ThisNodeBtype);
    379         }
    380         return (AE_OK);
    381 
    382     case AML_EXTERNAL_OP:
    383         /*
    384          * Not really a "runtime" opcode since it used by disassembler only.
    385          * The parser will find any issues with the operands.
    386          */
    387         return (AE_OK);
    388 
    389     default:
    390 
    391         break;
    392     }
    393 
    394     /* Ignore the non-executable opcodes */
    395 
    396     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
    397     {
    398         return (AE_OK);
    399     }
    400 
    401     /*
    402      * Special handling for certain opcodes.
    403      */
    404     switch (Op->Asl.AmlOpcode)
    405     {
    406         /* BankField has one TermArg */
    407 
    408     case AML_BANK_FIELD_OP:
    409 
    410         OpcodeClass = AML_CLASS_EXECUTE;
    411         ArgOp = ArgOp->Asl.Next;
    412         ArgOp = ArgOp->Asl.Next;
    413         break;
    414 
    415         /* Operation Region has 2 TermArgs */
    416 
    417     case AML_REGION_OP:
    418 
    419         OpcodeClass = AML_CLASS_EXECUTE;
    420         ArgOp = ArgOp->Asl.Next;
    421         ArgOp = ArgOp->Asl.Next;
    422         break;
    423 
    424         /* DataTableRegion has 3 TermArgs */
    425 
    426     case AML_DATA_REGION_OP:
    427 
    428         OpcodeClass = AML_CLASS_EXECUTE;
    429         ArgOp = ArgOp->Asl.Next;
    430         break;
    431 
    432         /* Buffers/Packages have a length that is a TermArg */
    433 
    434     case AML_BUFFER_OP:
    435     case AML_PACKAGE_OP:
    436     case AML_VARIABLE_PACKAGE_OP:
    437 
    438             /* If length is a constant, we are done */
    439 
    440         if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
    441             (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
    442         {
    443             return (AE_OK);
    444         }
    445         break;
    446 
    447         /* Store can write any object to the Debug object */
    448 
    449     case AML_STORE_OP:
    450         /*
    451          * If this is a Store() to the Debug object, we don't need
    452          * to perform any further validation -- because a Store of
    453          * any object to Debug is permitted and supported.
    454          */
    455         if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
    456         {
    457             return (AE_OK);
    458         }
    459         break;
    460 
    461     default:
    462         break;
    463     }
    464 
    465     switch (OpcodeClass)
    466     {
    467     case AML_CLASS_EXECUTE:
    468     case AML_CLASS_CREATE:
    469     case AML_CLASS_CONTROL:
    470     case AML_CLASS_RETURN_VALUE:
    471 
    472         /* Reverse the runtime argument list */
    473 
    474         RuntimeArgTypes2 = 0;
    475         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
    476         {
    477             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
    478             RuntimeArgTypes2 |= ArgType;
    479             INCREMENT_ARG_LIST (RuntimeArgTypes);
    480         }
    481 
    482         /* Typecheck each argument */
    483 
    484         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
    485         {
    486             /* Get the required type(s) for the argument */
    487 
    488             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
    489 
    490             if (!ArgOp)
    491             {
    492                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
    493                     "Null ArgOp in argument loop");
    494                 AslAbort ();
    495             }
    496 
    497             /* Get the actual type of the argument */
    498 
    499             ThisNodeBtype = AnGetBtype (ArgOp);
    500             if (ThisNodeBtype == ACPI_UINT32_MAX)
    501             {
    502                 goto NextArgument;
    503             }
    504 
    505             /* Examine the arg based on the required type of the arg */
    506 
    507             switch (ArgType)
    508             {
    509             case ARGI_TARGETREF:
    510 
    511                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
    512                 {
    513                     /* ZERO is the placeholder for "don't store result" */
    514 
    515                     ThisNodeBtype = RequiredBtypes;
    516                     break;
    517                 }
    518 
    519                 ACPI_FALLTHROUGH;
    520 
    521             case ARGI_STORE_TARGET:
    522 
    523                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
    524                 {
    525                     /*
    526                      * This is the case where an original reference to a resource
    527                      * descriptor field has been replaced by an (Integer) offset.
    528                      * These named fields are supported at compile-time only;
    529                      * the names are not passed to the interpreter (via the AML).
    530                      */
    531                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
    532                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
    533                     {
    534                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
    535                             ArgOp, NULL);
    536                     }
    537                     else
    538                     {
    539                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
    540                             ArgOp, NULL);
    541                     }
    542                 }
    543                 break;
    544 
    545 
    546 #ifdef __FUTURE_IMPLEMENTATION
    547 /*
    548  * Possible future typechecking support
    549  */
    550             case ARGI_REFERENCE:            /* References */
    551             case ARGI_INTEGER_REF:
    552             case ARGI_OBJECT_REF:
    553             case ARGI_DEVICE_REF:
    554 
    555                 switch (ArgOp->Asl.ParseOpcode)
    556                 {
    557                 case PARSEOP_LOCAL0:
    558                 case PARSEOP_LOCAL1:
    559                 case PARSEOP_LOCAL2:
    560                 case PARSEOP_LOCAL3:
    561                 case PARSEOP_LOCAL4:
    562                 case PARSEOP_LOCAL5:
    563                 case PARSEOP_LOCAL6:
    564                 case PARSEOP_LOCAL7:
    565 
    566                     /* TBD: implement analysis of current value (type) of the local */
    567                     /* For now, just treat any local as a typematch */
    568 
    569                     /*ThisNodeBtype = RequiredBtypes;*/
    570                     break;
    571 
    572                 case PARSEOP_ARG0:
    573                 case PARSEOP_ARG1:
    574                 case PARSEOP_ARG2:
    575                 case PARSEOP_ARG3:
    576                 case PARSEOP_ARG4:
    577                 case PARSEOP_ARG5:
    578                 case PARSEOP_ARG6:
    579 
    580                     /* Hard to analyze argument types, so we won't */
    581                     /* for now. Just treat any arg as a typematch */
    582 
    583                     /* ThisNodeBtype = RequiredBtypes; */
    584                     break;
    585 
    586                 case PARSEOP_DEBUG:
    587                 case PARSEOP_REFOF:
    588                 case PARSEOP_INDEX:
    589                 default:
    590 
    591                     break;
    592                 }
    593                 break;
    594 #endif
    595             case ARGI_INTEGER:
    596             default:
    597 
    598                 break;
    599             }
    600 
    601 
    602             /* Check for a type mismatch (required versus actual) */
    603 
    604             CommonBtypes = ThisNodeBtype & RequiredBtypes;
    605 
    606             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
    607             {
    608                 if (AnIsInternalMethod (ArgOp))
    609                 {
    610                     return (AE_OK);
    611                 }
    612 
    613                 /* Check a method call for a valid return value */
    614 
    615                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
    616                     RequiredBtypes, ThisNodeBtype);
    617             }
    618 
    619             /*
    620              * Now check if the actual type(s) match at least one
    621              * bit to the required type
    622              */
    623             else if (!CommonBtypes)
    624             {
    625                 /* No match -- this is a type mismatch error */
    626 
    627                 AnFormatBtype (AslGbl_StringBuffer, ThisNodeBtype);
    628                 AnFormatBtype (AslGbl_StringBuffer2, RequiredBtypes);
    629 
    630                 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "[%s] found, %s operator requires [%s]",
    631                     AslGbl_StringBuffer, OpInfo->Name, AslGbl_StringBuffer2);
    632 
    633                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
    634                     ArgOp, AslGbl_MsgBuffer);
    635             }
    636 
    637         NextArgument:
    638             ArgOp = ArgOp->Asl.Next;
    639             INCREMENT_ARG_LIST (RuntimeArgTypes2);
    640         }
    641         break;
    642 
    643     default:
    644 
    645         break;
    646     }
    647 
    648     return (AE_OK);
    649 }
    650 
    651 
    652 /*******************************************************************************
    653  *
    654  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
    655  *
    656  * PARAMETERS:  ASL_WALK_CALLBACK
    657  *
    658  * RETURN:      Status
    659  *
    660  * DESCRIPTION: Descending callback for the analysis walk. Checks for
    661  *              miscellaneous issues in the code.
    662  *
    663  ******************************************************************************/
    664 
    665 ACPI_STATUS
    666 AnOtherSemanticAnalysisWalkBegin (
    667     ACPI_PARSE_OBJECT       *Op,
    668     UINT32                  Level,
    669     void                    *Context)
    670 {
    671     ACPI_PARSE_OBJECT       *ArgOp;
    672     ACPI_PARSE_OBJECT       *PrevArgOp = NULL;
    673     const ACPI_OPCODE_INFO  *OpInfo;
    674     ACPI_NAMESPACE_NODE     *Node;
    675 
    676 
    677     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    678 
    679 
    680     if (OpInfo->Flags & AML_CREATE)
    681     {
    682         /* This group contains all of the Create Buffer Field operators */
    683 
    684         AnValidateCreateBufferField (Op);
    685         return (AE_OK);
    686     }
    687 
    688     /*
    689      * Determine if an execution class operator actually does something by
    690      * checking if it has a target and/or the function return value is used.
    691      * (Target is optional, so a standalone statement can actually do nothing.)
    692      */
    693     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
    694         (OpInfo->Flags & AML_HAS_RETVAL) &&
    695         (!AnIsResultUsed (Op)))
    696     {
    697         if (OpInfo->Flags & AML_HAS_TARGET)
    698         {
    699             /*
    700              * Find the target node, it is always the last child. If the target
    701              * is not specified in the ASL, a default node of type Zero was
    702              * created by the parser.
    703              */
    704             ArgOp = Op->Asl.Child;
    705             while (ArgOp->Asl.Next)
    706             {
    707                 PrevArgOp = ArgOp;
    708                 ArgOp = ArgOp->Asl.Next;
    709             }
    710 
    711             /* Divide() is the only weird case, it has two targets */
    712 
    713             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
    714             {
    715                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
    716                     (PrevArgOp) &&
    717                     (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
    718                 {
    719                     AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    720                         Op, Op->Asl.ExternalName);
    721                 }
    722             }
    723 
    724             else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
    725             {
    726                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    727                     Op, Op->Asl.ExternalName);
    728             }
    729         }
    730         else
    731         {
    732             /*
    733              * Has no target and the result is not used. Only a couple opcodes
    734              * can have this combination.
    735              */
    736             switch (Op->Asl.ParseOpcode)
    737             {
    738             case PARSEOP_ACQUIRE:
    739             case PARSEOP_WAIT:
    740             case PARSEOP_LOADTABLE:
    741 
    742                 break;
    743 
    744             default:
    745 
    746                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    747                     Op, Op->Asl.ExternalName);
    748                 break;
    749             }
    750         }
    751     }
    752 
    753     /*
    754      * Semantic checks for individual ASL operators
    755      */
    756 
    757     switch (Op->Asl.ParseOpcode)
    758     {
    759     case PARSEOP_STORE:
    760 
    761         if (AslGbl_DoTypechecking)
    762         {
    763             AnAnalyzeStoreOperator (Op);
    764         }
    765         break;
    766 
    767 
    768     case PARSEOP_ACQUIRE:
    769     case PARSEOP_WAIT:
    770         /*
    771          * Emit a warning if the timeout parameter for these operators is not
    772          * ACPI_WAIT_FOREVER, and the result value from the operator is not
    773          * checked, meaning that a timeout could happen, but the code
    774          * would not know about it.
    775          */
    776 
    777         /* First child is the namepath, 2nd child is timeout */
    778 
    779         ArgOp = Op->Asl.Child;
    780         ArgOp = ArgOp->Asl.Next;
    781 
    782         /*
    783          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
    784          * 0xFFFF or greater
    785          */
    786         if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
    787              (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
    788              (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
    789         {
    790             break;
    791         }
    792 
    793         /*
    794          * The operation could timeout. If the return value is not used
    795          * (indicates timeout occurred), issue a warning
    796          */
    797         if (!AnIsResultUsed (Op))
    798         {
    799             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
    800                 Op->Asl.ExternalName);
    801         }
    802         break;
    803 
    804     case PARSEOP_CONNECTION:
    805         /*
    806          * Ensure that the referenced operation region has the correct SPACE_ID.
    807          * From the grammar/parser, we know the parent is a FIELD definition.
    808          */
    809         ArgOp = Op->Asl.Parent;     /* Field definition */
    810         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    811         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
    812         if (!Node)
    813         {
    814             break;
    815         }
    816 
    817         ArgOp = Node->Op;           /* OpRegion definition */
    818         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    819         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
    820 
    821         /*
    822          * The Connection() operator is only valid for the following operation
    823          * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
    824          */
    825         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
    826             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
    827         {
    828             AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
    829         }
    830         break;
    831 
    832     case PARSEOP_FIELD:
    833         /*
    834          * Ensure that fields for GeneralPurposeIo and GenericSerialBus
    835          * contain at least one Connection() operator
    836          */
    837         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
    838         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
    839         if (!Node)
    840         {
    841             break;
    842         }
    843 
    844         ArgOp = Node->Op;           /* OpRegion definition */
    845         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    846         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
    847 
    848         /* We are only interested in GeneralPurposeIo and GenericSerialBus */
    849 
    850         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
    851             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
    852         {
    853             break;
    854         }
    855 
    856         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
    857         ArgOp = ArgOp->Asl.Next;    /* AccessType */
    858         ArgOp = ArgOp->Asl.Next;    /* LockRule */
    859         ArgOp = ArgOp->Asl.Next;    /* UpdateRule */
    860         ArgOp = ArgOp->Asl.Next;    /* Start of FieldUnitList */
    861 
    862         /* Walk the FieldUnitList */
    863 
    864         while (ArgOp)
    865         {
    866             if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
    867             {
    868                 break;
    869             }
    870             else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
    871             {
    872                 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
    873                 break;
    874             }
    875 
    876             ArgOp = ArgOp->Asl.Next;
    877         }
    878         break;
    879 
    880     default:
    881 
    882         break;
    883     }
    884 
    885     return (AE_OK);
    886 }
    887 
    888 
    889 /*******************************************************************************
    890  *
    891  * FUNCTION:    AnValidateCreateBufferField
    892  *
    893  * PARAMETERS:  Op                  - A create buffer field operator
    894  *
    895  * RETURN:      None
    896  *
    897  * DESCRIPTION: Check if a buffer index argument to a create buffer field
    898  *              operation is beyond the end of the target buffer.
    899  *
    900  *  Validates these AML operators:
    901  *
    902  *  AML_CREATE_FIELD_OP
    903  *  AML_CREATE_BIT_FIELD_OP
    904  *  AML_CREATE_BYTE_FIELD_OP
    905  *  AML_CREATE_WORD_FIELD_OP
    906  *  AML_CREATE_DWORD_FIELD_OP
    907  *  AML_CREATE_QWORD_FIELD_OP
    908  *
    909  *  There are two conditions that must be satisfied in order to enable
    910  *  validation at compile time:
    911  *
    912  *  1) The length of the target buffer must be an integer constant
    913  *  2) The index specified in the create* must be an integer constant
    914  *  3) For CreateField, the bit length argument must be non-zero.
    915  *
    916  ******************************************************************************/
    917 
    918 static void
    919 AnValidateCreateBufferField (
    920     ACPI_PARSE_OBJECT       *CreateBufferFieldOp)
    921 {
    922     ACPI_PARSE_OBJECT       *TargetBufferOp;
    923     ACPI_PARSE_OBJECT       *ArgOp;
    924     UINT32                  TargetBufferLength;
    925     UINT32                  LastFieldByteIndex;
    926 
    927 
    928     /*
    929      * 1) Get the length of the target buffer
    930      */
    931     ArgOp = CreateBufferFieldOp->Asl.Child;     /* Reference to target buffer */
    932 
    933     /*
    934      * If no attached Node, the target buffer may be something like an
    935      * ArgX or LocalX and cannot be evaluated at compile time.
    936      */
    937     if (!ArgOp->Asl.Node)
    938     {
    939         return;
    940     }
    941 
    942     TargetBufferOp = ArgOp->Asl.Node->Op;
    943     TargetBufferOp = TargetBufferOp->Asl.Child; /* Target buffer */
    944     TargetBufferOp = TargetBufferOp->Asl.Next;  /* "Buffer" keyword */
    945     if (!TargetBufferOp)
    946     {
    947         /* Not a statement of the form NAME(XXXX, Buffer.... */
    948 
    949         return;
    950     }
    951 
    952     /* Get the buffer length argument. It must be an integer constant */
    953 
    954     ArgOp = TargetBufferOp->Asl.Child;
    955     if (!AnIsValidBufferConstant (ArgOp))
    956     {
    957         return;
    958     }
    959 
    960     TargetBufferLength = (UINT32) ArgOp->Asl.Value.Integer;
    961 
    962     /*
    963      * 2) Get the value of the buffer index argument. It must be
    964      * an integer constant.
    965      */
    966     ArgOp = CreateBufferFieldOp->Asl.Child;     /* Reference to target buffer */
    967     ArgOp = ArgOp->Asl.Next;                    /* Buffer Index argument*/
    968     if (!AnIsValidBufferConstant (ArgOp))
    969     {
    970         return;
    971     }
    972 
    973     LastFieldByteIndex =
    974         (UINT32) ArgOp->Asl.Value.Integer;      /* Index can be in either bytes or bits */
    975 
    976     /*
    977      * 3) Get the length of the new buffer field, in bytes. Also,
    978      * create the final target buffer index for the last byte of the field
    979      */
    980     switch (CreateBufferFieldOp->Asl.ParseOpcode)
    981     {
    982     case PARSEOP_CREATEBITFIELD:                /* A one bit field */
    983 
    984         LastFieldByteIndex = ACPI_ROUND_BITS_DOWN_TO_BYTES (LastFieldByteIndex);
    985         break;
    986 
    987     case PARSEOP_CREATEBYTEFIELD:
    988         break;
    989 
    990     case PARSEOP_CREATEWORDFIELD:
    991 
    992         LastFieldByteIndex += (sizeof (UINT16) - 1);
    993         break;
    994 
    995     case PARSEOP_CREATEDWORDFIELD:
    996 
    997         LastFieldByteIndex += (sizeof (UINT32) - 1);
    998         break;
    999 
   1000     case PARSEOP_CREATEQWORDFIELD:
   1001 
   1002         LastFieldByteIndex += (sizeof (UINT64) - 1);
   1003         break;
   1004 
   1005     case PARSEOP_CREATEFIELD:                   /* Multi-bit field */
   1006 
   1007         ArgOp = ArgOp->Asl.Next;                /* Length argument, in bits */
   1008         if (!AnIsValidBufferConstant (ArgOp))
   1009         {
   1010             return;
   1011         }
   1012 
   1013         /* The buffer field length is not allowed to be zero */
   1014 
   1015         if (ArgOp->Asl.Value.Integer == 0)
   1016         {
   1017             AslError (ASL_WARNING,  ASL_MSG_BUFFER_FIELD_LENGTH, ArgOp, NULL);
   1018             return;
   1019         }
   1020 
   1021         LastFieldByteIndex +=
   1022             ((UINT32) ArgOp->Asl.Value.Integer - 1);    /* Create final bit index */
   1023 
   1024         /* Convert bit index to a byte index */
   1025 
   1026         LastFieldByteIndex = ACPI_ROUND_BITS_DOWN_TO_BYTES (LastFieldByteIndex);
   1027         break;
   1028 
   1029     default:
   1030         return;
   1031     }
   1032 
   1033     /*
   1034      * 4) Check for an access (index) beyond the end of the target buffer,
   1035      * or a zero length target buffer.
   1036      */
   1037     if (!TargetBufferLength || (LastFieldByteIndex >= TargetBufferLength))
   1038     {
   1039         AslError (ASL_WARNING, ASL_MSG_BUFFER_FIELD_OVERFLOW, ArgOp, NULL);
   1040     }
   1041 }
   1042 
   1043 
   1044 /*******************************************************************************
   1045  *
   1046  * FUNCTION:    AnIsValidBufferConstant
   1047  *
   1048  * PARAMETERS:  Op                  - A buffer-related operand
   1049  *
   1050  * RETURN:      TRUE if operand is valid constant, FALSE otherwise
   1051  *
   1052  * DESCRIPTION: Check if the input Op is valid constant that can be used
   1053  *              in compile-time analysis.
   1054  *
   1055  ******************************************************************************/
   1056 
   1057 static BOOLEAN
   1058 AnIsValidBufferConstant (
   1059     ACPI_PARSE_OBJECT       *Op)
   1060 {
   1061     if (!Op)
   1062     {
   1063         return (FALSE);
   1064     }
   1065 
   1066     if ((Op->Asl.ParseOpcode == PARSEOP_INTEGER) ||
   1067         (Op->Asl.ParseOpcode == PARSEOP_ZERO)    ||
   1068         (Op->Asl.ParseOpcode == PARSEOP_ONE))
   1069     {
   1070         return (TRUE);
   1071     }
   1072 
   1073     return (FALSE);
   1074 }
   1075 
   1076 
   1077 /*******************************************************************************
   1078  *
   1079  * FUNCTION:    AnAnalyzeStoreOperator
   1080  *
   1081  * PARAMETERS:  Op                  - Store() operator
   1082  *
   1083  * RETURN:      None
   1084  *
   1085  * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
   1086  *              objects where there are more restrictions than other data
   1087  *              types.
   1088  *
   1089  ******************************************************************************/
   1090 
   1091 static void
   1092 AnAnalyzeStoreOperator (
   1093     ACPI_PARSE_OBJECT       *Op)
   1094 {
   1095     ACPI_NAMESPACE_NODE     *SourceNode;
   1096     ACPI_NAMESPACE_NODE     *TargetNode;
   1097     ACPI_PARSE_OBJECT       *SourceOperandOp;
   1098     ACPI_PARSE_OBJECT       *TargetOperandOp;
   1099     UINT32                  SourceOperandBtype;
   1100     UINT32                  TargetOperandBtype;
   1101 
   1102 
   1103     /* Extract the two operands for STORE */
   1104 
   1105     SourceOperandOp = Op->Asl.Child;
   1106     TargetOperandOp = SourceOperandOp->Asl.Next;
   1107 
   1108     /*
   1109      * Ignore these Source operand opcodes, they cannot be typechecked,
   1110      * the actual result is unknown here.
   1111      */
   1112     switch (SourceOperandOp->Asl.ParseOpcode)
   1113     {
   1114     /* For these, type of the returned value is unknown at compile time */
   1115 
   1116     case PARSEOP_DEREFOF:
   1117     case PARSEOP_METHODCALL:
   1118     case PARSEOP_STORE:
   1119     case PARSEOP_COPYOBJECT:
   1120 
   1121         return;
   1122 
   1123     case PARSEOP_INDEX:
   1124     case PARSEOP_REFOF:
   1125 
   1126         if (!AslGbl_EnableReferenceTypechecking)
   1127         {
   1128             return;
   1129         }
   1130 
   1131         /*
   1132          * These opcodes always return an object reference, and thus
   1133          * the result can only be stored to a Local, Arg, or Debug.
   1134          */
   1135         if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
   1136         {
   1137             return;
   1138         }
   1139 
   1140         if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
   1141             (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
   1142         {
   1143             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
   1144                 "Source [Reference], Target must be [Local/Arg/Debug]");
   1145         }
   1146         return;
   1147 
   1148     default:
   1149         break;
   1150     }
   1151 
   1152     /*
   1153      * Ignore these Target operand opcodes, they cannot be typechecked
   1154      */
   1155     switch (TargetOperandOp->Asl.ParseOpcode)
   1156     {
   1157     case PARSEOP_DEBUG:
   1158     case PARSEOP_DEREFOF:
   1159     case PARSEOP_REFOF:
   1160     case PARSEOP_INDEX:
   1161     case PARSEOP_STORE:
   1162 
   1163         return;
   1164 
   1165     default:
   1166         break;
   1167     }
   1168 
   1169     /*
   1170      * Ignore typecheck for External() operands of type "UnknownObj",
   1171      * we don't know the actual type (source or target).
   1172      */
   1173     SourceNode = SourceOperandOp->Asl.Node;
   1174     if (SourceNode &&
   1175         (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
   1176         (SourceNode->Type == ACPI_TYPE_ANY))
   1177     {
   1178         return;
   1179     }
   1180 
   1181     TargetNode = TargetOperandOp->Asl.Node;
   1182     if (TargetNode &&
   1183         (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
   1184         (TargetNode->Type == ACPI_TYPE_ANY))
   1185     {
   1186         return;
   1187     }
   1188 
   1189     /*
   1190      * A NULL node with a namepath AML opcode indicates non-existent
   1191      * name. Just return, the error message is generated elsewhere.
   1192      */
   1193     if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
   1194         (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
   1195     {
   1196         return;
   1197     }
   1198 
   1199     /*
   1200      * Simple check for source same as target via NS node.
   1201      * -- Could be expanded to locals and args.
   1202      */
   1203     if (SourceNode && TargetNode)
   1204     {
   1205         if (SourceNode == TargetNode)
   1206         {
   1207             AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
   1208                 TargetOperandOp, "Source is the same as Target");
   1209             return;
   1210         }
   1211     }
   1212 
   1213     /* Ignore typecheck if either source or target is a local or arg */
   1214 
   1215     if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
   1216         (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
   1217     {
   1218         return; /* Cannot type a local/arg at compile time */
   1219     }
   1220 
   1221     if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
   1222         (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
   1223     {
   1224         return; /* Cannot type a local/arg at compile time */
   1225     }
   1226 
   1227     /*
   1228      * Package objects are a special case because they cannot by implicitly
   1229      * converted to/from anything. Check for these two illegal cases:
   1230      *
   1231      *      Store (non-package, package)
   1232      *      Store (package, non-package)
   1233      */
   1234     SourceOperandBtype = AnGetBtype (SourceOperandOp);
   1235     TargetOperandBtype = AnGetBtype (TargetOperandOp);
   1236 
   1237     /* Check source first for (package, non-package) case */
   1238 
   1239     if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
   1240     {
   1241         /* If Source is PACKAGE-->Target must be PACKAGE */
   1242 
   1243         if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
   1244         {
   1245             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
   1246                 "Source is [Package], Target must be a package also");
   1247         }
   1248     }
   1249 
   1250     /* Else check target for (non-package, package) case */
   1251 
   1252     else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
   1253     {
   1254         /* If Target is PACKAGE, Source must be PACKAGE */
   1255 
   1256         if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
   1257         {
   1258             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
   1259                 "Target is [Package], Source must be a package also");
   1260         }
   1261     }
   1262 }
   1263