Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: aslxrefout.c - support for optional cross-reference file
      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 "acnamesp.h"
    155 #include "acparser.h"
    156 #include "amlcode.h"
    157 
    158 #define _COMPONENT          ACPI_COMPILER
    159         ACPI_MODULE_NAME    ("aslxrefout")
    160 
    161 
    162 /* Local prototypes */
    163 
    164 static ACPI_STATUS
    165 OtXrefWalkPart2 (
    166     ACPI_PARSE_OBJECT       *Op,
    167     UINT32                  Level,
    168     void                    *Context);
    169 
    170 static ACPI_STATUS
    171 OtXrefWalkPart3 (
    172     ACPI_PARSE_OBJECT       *Op,
    173     UINT32                  Level,
    174     void                    *Context);
    175 
    176 static ACPI_STATUS
    177 OtXrefAnalysisWalkPart1 (
    178     ACPI_PARSE_OBJECT       *Op,
    179     UINT32                  Level,
    180     void                    *Context);
    181 
    182 
    183 static ACPI_STATUS
    184 OtXrefAnalysisWalkPart2 (
    185     ACPI_PARSE_OBJECT       *Op,
    186     UINT32                  Level,
    187     void                    *Context);
    188 
    189 static ACPI_STATUS
    190 OtXrefAnalysisWalkPart3 (
    191     ACPI_PARSE_OBJECT       *Op,
    192     UINT32                  Level,
    193     void                    *Context);
    194 
    195 
    196 /*******************************************************************************
    197  *
    198  * FUNCTION:    OtPrintHeaders
    199  *
    200  * PARAMETERS:  Message             - Main header message
    201  *
    202  * RETURN:      None
    203  *
    204  * DESCRIPTION: Emits the main header message along with field descriptions
    205  *
    206  ******************************************************************************/
    207 
    208 void
    209 OtPrintHeaders (
    210     char                    *Message)
    211 {
    212     UINT32                  Length;
    213 
    214 
    215     Length = strlen (Message);
    216 
    217     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\n%s\n", Message);
    218     while (Length)
    219     {
    220         FlPrintFile (ASL_FILE_XREF_OUTPUT, "-");
    221         Length--;
    222     }
    223 
    224     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nLineno   %-40s Description\n",
    225         "Full Pathname");
    226 }
    227 
    228 
    229 /*******************************************************************************
    230  *
    231  * FUNCTION:    OtCreateXrefFile
    232  *
    233  * PARAMETERS:  None
    234  *
    235  * RETURN:      None
    236  *
    237  * DESCRIPTION  Main entry point for parts 2 and 3 of the cross-reference
    238  *              file.
    239  *
    240  ******************************************************************************/
    241 
    242 void
    243 OtCreateXrefFile (
    244     void)
    245 {
    246     ASL_XREF_INFO           XrefInfo;
    247 
    248 
    249     /* Build cross-reference output file if requested */
    250 
    251     if (!AslGbl_CrossReferenceOutput)
    252     {
    253         return;
    254     }
    255 
    256     memset (&XrefInfo, 0, sizeof (ASL_XREF_INFO));
    257 
    258     /* Cross-reference output file, part 2 (Method invocations) */
    259 
    260     OtPrintHeaders ("Part 2: Method Reference Map "
    261         "(Invocations of each user-defined control method)");
    262 
    263     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    264         OtXrefWalkPart2, NULL, &XrefInfo);
    265 
    266     /* Cross-reference output file, part 3 (All other object refs) */
    267 
    268     OtPrintHeaders ("Part 3: Full Object Reference Map "
    269         "(Methods that reference each object in namespace");
    270 
    271     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    272         OtXrefWalkPart3, NULL, &XrefInfo);
    273 
    274     /* Cross-reference summary */
    275 
    276     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nObject Summary\n");
    277 
    278     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    279         "\nTotal methods:                   %u\n",
    280         XrefInfo.TotalPredefinedMethods + XrefInfo.TotalUserMethods);
    281     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    282         "Total predefined methods:        %u\n",
    283         XrefInfo.TotalPredefinedMethods);
    284 
    285     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    286         "\nTotal user methods:              %u\n",
    287         XrefInfo.TotalUserMethods);
    288     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    289         "Total unreferenced user methods  %u\n",
    290         XrefInfo.TotalUnreferenceUserMethods);
    291 
    292     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    293         "\nTotal defined objects:           %u\n",
    294         XrefInfo.TotalObjects);
    295     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    296         "Total unreferenced objects:      %u\n",
    297         XrefInfo.TotalUnreferencedObjects);
    298 }
    299 
    300 
    301 /*
    302  * Part 1 of the cross reference file. This part emits the namespace objects
    303  * that are referenced by each control method in the namespace.
    304  *
    305  * Part 2 and 3 are below part 1.
    306  */
    307 
    308 /*******************************************************************************
    309  *
    310  * FUNCTION:    OtXrefWalkPart1
    311  *
    312  * PARAMETERS:  Op                      - Current parse Op
    313  *              Level                   - Current tree nesting level
    314  *              MethodInfo              - Info block for the current method
    315  *
    316  *
    317  * RETURN:      None
    318  *
    319  * DESCRIPTION: Entry point for the creation of the method call reference map.
    320  *              For each control method in the namespace, all other methods
    321  *              that invoke the method are listed. Predefined names/methods
    322  *              that start with an underscore are ignored, because these are
    323  *              essentially external/public interfaces.
    324 
    325  * DESCRIPTION: Entry point for the creation of the object reference map.
    326  *              For each control method in the namespace, all objects that
    327  *              are referenced by the method are listed.
    328  *
    329  *              Called during a normal namespace walk, once per namespace
    330  *              object. (MtMethodAnalysisWalkBegin)
    331  *
    332  ******************************************************************************/
    333 
    334 void
    335 OtXrefWalkPart1 (
    336     ACPI_PARSE_OBJECT       *Op,
    337     UINT32                  Level,
    338     ASL_METHOD_INFO         *MethodInfo)
    339 {
    340     ACPI_NAMESPACE_NODE     *Node;
    341     ACPI_PARSE_OBJECT       *NextOp;
    342     ACPI_PARSE_OBJECT       *FieldOp;
    343     char                    *ParentPath;
    344     UINT32                  Length;
    345     ACPI_STATUS             Status;
    346 
    347 
    348     switch (Op->Asl.ParseOpcode)
    349     {
    350     case PARSEOP_NAMESEG:
    351     case PARSEOP_NAMESTRING:
    352     case PARSEOP_METHODCALL:
    353 
    354         if (!MethodInfo ||
    355             (MethodInfo->Op->Asl.Child == Op) ||
    356             !Op->Asl.Node)
    357         {
    358             break;
    359         }
    360 
    361         MethodInfo->CurrentOp = Op;
    362         Node = Op->Asl.Node;
    363 
    364         /* Find all objects referenced by this method */
    365 
    366         Status = TrWalkParseTree (MethodInfo->Op, ASL_WALK_VISIT_DOWNWARD,
    367             OtXrefAnalysisWalkPart1, NULL, MethodInfo);
    368 
    369         if (Status == AE_CTRL_TERMINATE)
    370         {
    371             ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    372 
    373             FlPrintFile (ASL_FILE_XREF_OUTPUT, "            %-40s %s",
    374                 ParentPath, AcpiUtGetTypeName (Node->Type));
    375             ACPI_FREE (ParentPath);
    376 
    377             switch (Node->Type)
    378             {
    379                 /* Handle externals */
    380 
    381             case ACPI_TYPE_ANY:
    382             case ACPI_TYPE_FIELD_UNIT:
    383 
    384                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " <External Object>");
    385                 break;
    386 
    387             case ACPI_TYPE_INTEGER:
    388 
    389                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " %8.8X%8.8X",
    390                     ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
    391                 break;
    392 
    393             case ACPI_TYPE_METHOD:
    394 
    395                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " Invocation (%u args)",
    396                     Node->ArgCount);
    397                 break;
    398 
    399             case ACPI_TYPE_BUFFER_FIELD:
    400 
    401                 NextOp = Node->Op;              /* Create Buffer Field Op */
    402                 switch (NextOp->Asl.ParseOpcode)
    403                 {
    404                 case PARSEOP_CREATEBITFIELD:
    405                     Length = 1;
    406                     break;
    407 
    408                 case PARSEOP_CREATEBYTEFIELD:
    409                     Length = 8;
    410                     break;
    411 
    412                 case PARSEOP_CREATEWORDFIELD:
    413                     Length = 16;
    414                     break;
    415 
    416                 case PARSEOP_CREATEDWORDFIELD:
    417                     Length = 32;
    418                     break;
    419 
    420                 case PARSEOP_CREATEQWORDFIELD:
    421                     Length = 64;
    422                     break;
    423 
    424                 default:
    425                     Length = 0;
    426                     break;
    427                 }
    428 
    429                 NextOp = NextOp->Asl.Child;     /* Buffer name */
    430 
    431                 if (!NextOp->Asl.ExternalName)
    432                 {
    433                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " in Arg/Local");
    434                 }
    435                 else
    436                 {
    437                     ParentPath = AcpiNsGetNormalizedPathname (
    438                         NextOp->Asl.Node, TRUE);
    439 
    440                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Buffer %s",
    441                         Length, ParentPath);
    442                     ACPI_FREE (ParentPath);
    443                 }
    444                 break;
    445 
    446             case ACPI_TYPE_LOCAL_REGION_FIELD:
    447 
    448                 NextOp = Node->Op;
    449                 FieldOp = NextOp->Asl.Parent;
    450                 NextOp = FieldOp->Asl.Child;
    451 
    452                 ParentPath = AcpiNsGetNormalizedPathname (
    453                     NextOp->Asl.Node, TRUE);
    454 
    455                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Region %s",
    456                     (UINT32) Node->Op->Asl.Child->Asl.Value.Integer,
    457                     ParentPath);
    458                 ACPI_FREE (ParentPath);
    459 
    460                 if (FieldOp->Asl.ParseOpcode == PARSEOP_FIELD)
    461                 {
    462                     Node = NextOp->Asl.Node;        /* Region node */
    463                     NextOp = Node->Op;              /* PARSEOP_REGION */
    464                     NextOp = NextOp->Asl.Child;     /* Region name */
    465                     NextOp = NextOp->Asl.Next;
    466 
    467                     /* Get region space/addr/len? */
    468 
    469                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%s)",
    470                         AcpiUtGetRegionName ((UINT8)
    471                         NextOp->Asl.Value.Integer));
    472                 }
    473                 break;
    474 
    475             default:
    476                 break;
    477             }
    478 
    479             FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n");
    480         }
    481         break;
    482 
    483     case PARSEOP_METHOD:
    484 
    485         ParentPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
    486 
    487         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    488             "\n[%5u]  %-40s %s Declaration (%u args)\n",
    489             Op->Asl.LogicalLineNumber, ParentPath,
    490             AcpiUtGetTypeName (Op->Asl.Node->Type), Op->Asl.Node->ArgCount);
    491 
    492         ACPI_FREE (ParentPath);
    493         break;
    494 
    495     default:
    496         break;
    497     }
    498 }
    499 
    500 
    501 /*******************************************************************************
    502  *
    503  * FUNCTION:    OtXrefAnalysisWalkPart1
    504  *
    505  * PARAMETERS:  ASL_WALK_CALLBACK
    506  *
    507  * RETURN:      Status
    508  *
    509  * DESCRIPTION: Secondary walk for cross-reference part 1.
    510  *
    511  ******************************************************************************/
    512 
    513 static ACPI_STATUS
    514 OtXrefAnalysisWalkPart1 (
    515     ACPI_PARSE_OBJECT       *Op,
    516     UINT32                  Level,
    517     void                    *Context)
    518 {
    519     ASL_METHOD_INFO         *MethodInfo = (ASL_METHOD_INFO *) Context;
    520     ACPI_PARSE_OBJECT       *Next;
    521 
    522 
    523     /* Only interested in name string Ops -- ignore all others */
    524 
    525     if ((Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
    526         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
    527         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
    528     {
    529         return (AE_OK);
    530     }
    531 
    532     /* No node means a locally declared object -- ignore */
    533 
    534     if (!Op->Asl.Node)
    535     {
    536         return (AE_OK);
    537     }
    538 
    539     /* When we encounter the source Op, we are done */
    540 
    541     Next = MethodInfo->CurrentOp;
    542     if (Next == Op)
    543     {
    544         return (AE_CTRL_TERMINATE);
    545     }
    546 
    547     /* If we have a name match, this Op is a duplicate */
    548 
    549     if ((Next->Asl.ParseOpcode == PARSEOP_NAMESEG)      ||
    550         (Next->Asl.ParseOpcode == PARSEOP_NAMESTRING)   ||
    551         (Next->Asl.ParseOpcode == PARSEOP_METHODCALL))
    552     {
    553         if (!strcmp (Op->Asl.ExternalName, Next->Asl.ExternalName))
    554         {
    555             return (AE_ALREADY_EXISTS);
    556         }
    557     }
    558 
    559     return (AE_OK);
    560 }
    561 
    562 
    563 /*
    564  * Part 2 of the cross reference file. This part emits the names of each
    565  * non-predefined method in the namespace (user methods), along with the
    566  * names of each control method that references that method.
    567  */
    568 
    569 /*******************************************************************************
    570  *
    571  * FUNCTION:    OtXrefWalkPart2
    572  *
    573  * PARAMETERS:  ASL_WALK_CALLBACK
    574  *
    575  * RETURN:      Status
    576  *
    577  * DESCRIPTION: For each control method in the namespace, we will re-walk the
    578  *              namespace to find each and every invocation of that control
    579  *              method. Brute force, but does not matter, even for large
    580  *              namespaces. Ignore predefined names (start with underscore).
    581  *
    582  ******************************************************************************/
    583 
    584 static ACPI_STATUS
    585 OtXrefWalkPart2 (
    586     ACPI_PARSE_OBJECT       *Op,
    587     UINT32                  Level,
    588     void                    *Context)
    589 {
    590     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    591     ACPI_NAMESPACE_NODE     *Node;
    592     char                    *ParentPath;
    593 
    594 
    595     /* Looking for Method Declaration Ops only */
    596 
    597     if (!Op->Asl.Node ||
    598         (Op->Asl.ParseOpcode != PARSEOP_METHOD))
    599     {
    600         return (AE_OK);
    601     }
    602 
    603     /* Ignore predefined names */
    604 
    605     if (Op->Asl.Node->Name.Ascii[0] == '_')
    606     {
    607         XrefInfo->TotalPredefinedMethods++;
    608         return (AE_OK);
    609     }
    610 
    611     Node = Op->Asl.Node;
    612     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    613 
    614     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    615         "\n[%5u]  %-40s %s Declaration (%u args)\n",
    616         Op->Asl.LogicalLineNumber, ParentPath,
    617         AcpiUtGetTypeName (Node->Type), Node->ArgCount);
    618 
    619     XrefInfo->TotalUserMethods++;
    620     XrefInfo->ThisMethodInvocations = 0;
    621     XrefInfo->MethodOp = Op;
    622 
    623     (void) TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    624         OtXrefAnalysisWalkPart2, NULL, XrefInfo);
    625 
    626     if (!XrefInfo->ThisMethodInvocations)
    627     {
    628         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    629             "            Zero invocations of this method in this module\n");
    630         XrefInfo->TotalUnreferenceUserMethods++;
    631     }
    632     else
    633     {
    634         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    635             "            %u invocations of method %s in this module\n",
    636             XrefInfo->ThisMethodInvocations, ParentPath);
    637     }
    638 
    639     ACPI_FREE (ParentPath);
    640     return (AE_OK);
    641 }
    642 
    643 
    644 /*******************************************************************************
    645  *
    646  * FUNCTION:    OtXrefAnalysisWalkPart2
    647  *
    648  * PARAMETERS:  ASL_WALK_CALLBACK
    649  *
    650  * RETURN:      Status
    651  *
    652  * DESCRIPTION: For every Op that is a method invocation, emit a reference
    653  *              line if the Op is invoking the target method.
    654  *
    655  ******************************************************************************/
    656 
    657 static ACPI_STATUS
    658 OtXrefAnalysisWalkPart2 (
    659     ACPI_PARSE_OBJECT       *Op,
    660     UINT32                  Level,
    661     void                    *Context)
    662 {
    663     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    664     ACPI_PARSE_OBJECT       *CallerOp;
    665     char                    *CallerFullPathname;
    666 
    667 
    668     /* Looking for MethodCall Ops only */
    669 
    670     if (!Op->Asl.Node ||
    671         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
    672     {
    673         return (AE_OK);
    674     }
    675 
    676     /* If not a match to the target method, we are done */
    677 
    678     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
    679     {
    680         return (AE_CTRL_DEPTH);
    681     }
    682 
    683     /* Find parent method to get method caller namepath */
    684 
    685     CallerOp = Op->Asl.Parent;
    686     while (CallerOp &&
    687         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD))
    688     {
    689         CallerOp = CallerOp->Asl.Parent;
    690     }
    691 
    692     /* There is no parent method for External() statements */
    693 
    694     if (!CallerOp)
    695     {
    696         return (AE_OK);
    697     }
    698 
    699     CallerFullPathname = AcpiNsGetNormalizedPathname (
    700         CallerOp->Asl.Node, TRUE);
    701 
    702     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    703         "[%5u]     %-40s Invocation path: %s\n",
    704         Op->Asl.LogicalLineNumber, CallerFullPathname,
    705         Op->Asl.ExternalName);
    706 
    707     ACPI_FREE (CallerFullPathname);
    708     XrefInfo->ThisMethodInvocations++;
    709     return (AE_OK);
    710 }
    711 
    712 
    713 /*
    714  * Part 3 of the cross reference file. This part emits the names of each
    715  * non-predefined method in the namespace (user methods), along with the
    716  * names of each control method that references that method.
    717  */
    718 
    719 /*******************************************************************************
    720  *
    721  * FUNCTION:    OtXrefWalkPart3
    722  *
    723  * PARAMETERS:  ASL_WALK_CALLBACK
    724  *
    725  * RETURN:      Status
    726  *
    727  * DESCRIPTION: Cross-reference part 3. references to objects other than
    728  *              control methods.
    729  *
    730  ******************************************************************************/
    731 
    732 static ACPI_STATUS
    733 OtXrefWalkPart3 (
    734     ACPI_PARSE_OBJECT       *Op,
    735     UINT32                  Level,
    736     void                    *Context)
    737 {
    738     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    739     ACPI_NAMESPACE_NODE     *Node;
    740     char                    *ParentPath;
    741     const ACPI_OPCODE_INFO  *OpInfo;
    742 
    743 
    744     /* Ignore method declarations */
    745 
    746     if (!Op->Asl.Node ||
    747         (Op->Asl.ParseOpcode == PARSEOP_METHOD))
    748     {
    749         return (AE_OK);
    750     }
    751 
    752     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    753     if (!(OpInfo->Class & AML_CLASS_NAMED_OBJECT))
    754     {
    755         return (AE_OK);
    756     }
    757 
    758     /* Only care about named object creation opcodes */
    759 
    760     if ((Op->Asl.ParseOpcode != PARSEOP_NAME) &&
    761         (Op->Asl.ParseOpcode != PARSEOP_DEVICE) &&
    762         (Op->Asl.ParseOpcode != PARSEOP_MUTEX) &&
    763         (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION) &&
    764         (Op->Asl.ParseOpcode != PARSEOP_FIELD) &&
    765         (Op->Asl.ParseOpcode != PARSEOP_EVENT))
    766     {
    767         return (AE_OK);
    768     }
    769 
    770     /* Ignore predefined names */
    771 
    772     if (Op->Asl.Node->Name.Ascii[0] == '_')
    773     {
    774         return (AE_OK);
    775     }
    776 
    777     Node = Op->Asl.Node;
    778     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    779 
    780     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    781         "\n[%5u]  %-40s %s Declaration\n",
    782         Op->Asl.LogicalLineNumber, ParentPath,
    783         AcpiUtGetTypeName (Node->Type));
    784     ACPI_FREE (ParentPath);
    785 
    786     XrefInfo->MethodOp = Op;
    787     XrefInfo->ThisObjectReferences = 0;
    788     XrefInfo->TotalObjects = 0;
    789 
    790     (void) TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    791         OtXrefAnalysisWalkPart3, NULL, XrefInfo);
    792 
    793     if (!XrefInfo->ThisObjectReferences)
    794     {
    795         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    796             "            Zero references to this object in this module\n");
    797         XrefInfo->TotalUnreferencedObjects++;
    798     }
    799     else
    800     {
    801         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    802             "            %u references to this object in this module [%s]\n",
    803             XrefInfo->ThisObjectReferences, ParentPath);
    804     }
    805 
    806     return (AE_OK);
    807 }
    808 
    809 
    810 /*******************************************************************************
    811  *
    812  * FUNCTION:    OtXrefAnalysisWalkPart3
    813  *
    814  * PARAMETERS:  ASL_WALK_CALLBACK
    815  *
    816  * RETURN:      Status
    817  *
    818  * DESCRIPTION: Secondary walk for cross-reference part 3.
    819  *
    820  ******************************************************************************/
    821 
    822 static ACPI_STATUS
    823 OtXrefAnalysisWalkPart3 (
    824     ACPI_PARSE_OBJECT       *Op,
    825     UINT32                  Level,
    826     void                    *Context)
    827 {
    828     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    829     char                    *CallerFullPathname = NULL;
    830     ACPI_PARSE_OBJECT       *CallerOp;
    831     const char              *Operator;
    832 
    833 
    834     if (!Op->Asl.Node)
    835     {
    836         return (AE_OK);
    837     }
    838 
    839     XrefInfo->TotalObjects++;
    840 
    841     /* Ignore Op that actually defined the object */
    842 
    843     if (Op == XrefInfo->MethodOp)
    844     {
    845         return (AE_OK);
    846     }
    847 
    848     /* Only interested in Ops that reference the target node */
    849 
    850     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
    851     {
    852         return (AE_OK);
    853     }
    854 
    855     /* Find parent "open scope" object to get method caller namepath */
    856 
    857     CallerOp = Op->Asl.Parent;
    858     while (CallerOp &&
    859         (CallerOp->Asl.ParseOpcode != PARSEOP_NAME) &&
    860         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD) &&
    861         (CallerOp->Asl.ParseOpcode != PARSEOP_DEVICE) &&
    862         (CallerOp->Asl.ParseOpcode != PARSEOP_POWERRESOURCE) &&
    863         (CallerOp->Asl.ParseOpcode != PARSEOP_PROCESSOR) &&
    864         (CallerOp->Asl.ParseOpcode != PARSEOP_THERMALZONE))
    865     {
    866         CallerOp = CallerOp->Asl.Parent;
    867     }
    868 
    869     if (CallerOp == XrefInfo->CurrentMethodOp)
    870     {
    871         return (AE_OK);
    872     }
    873 
    874     /* Null CallerOp means the caller is at the namespace root */
    875 
    876     if (CallerOp)
    877     {
    878         CallerFullPathname = AcpiNsGetNormalizedPathname (
    879             CallerOp->Asl.Node, TRUE);
    880     }
    881 
    882     /* There are some special cases for the oddball operators */
    883 
    884     if (Op->Asl.ParseOpcode == PARSEOP_SCOPE)
    885     {
    886         Operator = "Scope";
    887     }
    888     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)
    889     {
    890         Operator = "Alias";
    891     }
    892     else if (!CallerOp)
    893     {
    894         Operator = "ModLevel";
    895     }
    896     else
    897     {
    898         Operator = AcpiUtGetTypeName (CallerOp->Asl.Node->Type);
    899     }
    900 
    901     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    902         "[%5u]     %-40s %-8s via path: %s, Operator: %s\n",
    903         Op->Asl.LogicalLineNumber,
    904         CallerFullPathname ? CallerFullPathname : "<root>",
    905         Operator,
    906         Op->Asl.ExternalName,
    907         Op->Asl.Parent->Asl.ParseOpName);
    908 
    909     if (!CallerOp)
    910     {
    911         CallerOp = ACPI_TO_POINTER (0xFFFFFFFF);
    912     }
    913 
    914     if (CallerFullPathname)
    915     {
    916         ACPI_FREE (CallerFullPathname);
    917     }
    918 
    919     XrefInfo->CurrentMethodOp = CallerOp;
    920     XrefInfo->ThisObjectReferences++;
    921     return (AE_OK);
    922 }
    923