Home | History | Annotate | Line # | Download | only in compiler
aslxrefout.c revision 1.1
      1  1.1  christos /******************************************************************************
      2  1.1  christos  *
      3  1.1  christos  * Module Name: aslxrefout.c - support for optional cross-reference file
      4  1.1  christos  *
      5  1.1  christos  *****************************************************************************/
      6  1.1  christos 
      7  1.1  christos /*
      8  1.1  christos  * Copyright (C) 2000 - 2016, Intel Corp.
      9  1.1  christos  * All rights reserved.
     10  1.1  christos  *
     11  1.1  christos  * Redistribution and use in source and binary forms, with or without
     12  1.1  christos  * modification, are permitted provided that the following conditions
     13  1.1  christos  * are met:
     14  1.1  christos  * 1. Redistributions of source code must retain the above copyright
     15  1.1  christos  *    notice, this list of conditions, and the following disclaimer,
     16  1.1  christos  *    without modification.
     17  1.1  christos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  1.1  christos  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  1.1  christos  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  1.1  christos  *    including a substantially similar Disclaimer requirement for further
     21  1.1  christos  *    binary redistribution.
     22  1.1  christos  * 3. Neither the names of the above-listed copyright holders nor the names
     23  1.1  christos  *    of any contributors may be used to endorse or promote products derived
     24  1.1  christos  *    from this software without specific prior written permission.
     25  1.1  christos  *
     26  1.1  christos  * Alternatively, this software may be distributed under the terms of the
     27  1.1  christos  * GNU General Public License ("GPL") version 2 as published by the Free
     28  1.1  christos  * Software Foundation.
     29  1.1  christos  *
     30  1.1  christos  * NO WARRANTY
     31  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  1.1  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  1.1  christos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  1.1  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  1.1  christos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  1.1  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  1.1  christos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  1.1  christos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  1.1  christos  * POSSIBILITY OF SUCH DAMAGES.
     42  1.1  christos  */
     43  1.1  christos 
     44  1.1  christos #include "aslcompiler.h"
     45  1.1  christos #include "aslcompiler.y.h"
     46  1.1  christos #include "acnamesp.h"
     47  1.1  christos #include "acparser.h"
     48  1.1  christos #include "amlcode.h"
     49  1.1  christos 
     50  1.1  christos #define _COMPONENT          ACPI_COMPILER
     51  1.1  christos         ACPI_MODULE_NAME    ("aslxrefout")
     52  1.1  christos 
     53  1.1  christos 
     54  1.1  christos /* Local prototypes */
     55  1.1  christos 
     56  1.1  christos static ACPI_STATUS
     57  1.1  christos OtXrefWalkPart2 (
     58  1.1  christos     ACPI_PARSE_OBJECT       *Op,
     59  1.1  christos     UINT32                  Level,
     60  1.1  christos     void                    *Context);
     61  1.1  christos 
     62  1.1  christos static ACPI_STATUS
     63  1.1  christos OtXrefWalkPart3 (
     64  1.1  christos     ACPI_PARSE_OBJECT       *Op,
     65  1.1  christos     UINT32                  Level,
     66  1.1  christos     void                    *Context);
     67  1.1  christos 
     68  1.1  christos static ACPI_STATUS
     69  1.1  christos OtXrefAnalysisWalkPart1 (
     70  1.1  christos     ACPI_PARSE_OBJECT       *Op,
     71  1.1  christos     UINT32                  Level,
     72  1.1  christos     void                    *Context);
     73  1.1  christos 
     74  1.1  christos 
     75  1.1  christos static ACPI_STATUS
     76  1.1  christos OtXrefAnalysisWalkPart2 (
     77  1.1  christos     ACPI_PARSE_OBJECT       *Op,
     78  1.1  christos     UINT32                  Level,
     79  1.1  christos     void                    *Context);
     80  1.1  christos 
     81  1.1  christos static ACPI_STATUS
     82  1.1  christos OtXrefAnalysisWalkPart3 (
     83  1.1  christos     ACPI_PARSE_OBJECT       *Op,
     84  1.1  christos     UINT32                  Level,
     85  1.1  christos     void                    *Context);
     86  1.1  christos 
     87  1.1  christos 
     88  1.1  christos /*******************************************************************************
     89  1.1  christos  *
     90  1.1  christos  * FUNCTION:    OtPrintHeaders
     91  1.1  christos  *
     92  1.1  christos  * PARAMETERS:  Message             - Main header message
     93  1.1  christos  *
     94  1.1  christos  * RETURN:      None
     95  1.1  christos  *
     96  1.1  christos  * DESCRIPTION: Emits the main header message along with field descriptions
     97  1.1  christos  *
     98  1.1  christos  ******************************************************************************/
     99  1.1  christos 
    100  1.1  christos void
    101  1.1  christos OtPrintHeaders (
    102  1.1  christos     char                    *Message)
    103  1.1  christos {
    104  1.1  christos     UINT32                  Length;
    105  1.1  christos 
    106  1.1  christos 
    107  1.1  christos     Length = strlen (Message);
    108  1.1  christos 
    109  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\n%s\n", Message);
    110  1.1  christos     while (Length)
    111  1.1  christos     {
    112  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT, "-");
    113  1.1  christos         Length--;
    114  1.1  christos     }
    115  1.1  christos 
    116  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nLineno   %-40s Description\n",
    117  1.1  christos         "Full Pathname");
    118  1.1  christos }
    119  1.1  christos 
    120  1.1  christos 
    121  1.1  christos /*******************************************************************************
    122  1.1  christos  *
    123  1.1  christos  * FUNCTION:    OtCreateXrefFile
    124  1.1  christos  *
    125  1.1  christos  * PARAMETERS:  None
    126  1.1  christos  *
    127  1.1  christos  * RETURN:      None
    128  1.1  christos  *
    129  1.1  christos  * DESCRIPTION  Main entry point for parts 2 and 3 of the cross-reference
    130  1.1  christos  *              file.
    131  1.1  christos  *
    132  1.1  christos  ******************************************************************************/
    133  1.1  christos 
    134  1.1  christos void
    135  1.1  christos OtCreateXrefFile (
    136  1.1  christos     void)
    137  1.1  christos {
    138  1.1  christos     ASL_XREF_INFO           XrefInfo;
    139  1.1  christos 
    140  1.1  christos 
    141  1.1  christos     /* Build cross-reference output file if requested */
    142  1.1  christos 
    143  1.1  christos     if (!Gbl_CrossReferenceOutput)
    144  1.1  christos     {
    145  1.1  christos         return;
    146  1.1  christos     }
    147  1.1  christos 
    148  1.1  christos     memset (&XrefInfo, 0, sizeof (ASL_XREF_INFO));
    149  1.1  christos 
    150  1.1  christos     /* Cross-reference output file, part 2 (Method invocations) */
    151  1.1  christos 
    152  1.1  christos     OtPrintHeaders ("Part 2: Method Reference Map "
    153  1.1  christos         "(Invocations of each user-defined control method)");
    154  1.1  christos 
    155  1.1  christos     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    156  1.1  christos         OtXrefWalkPart2, NULL, &XrefInfo);
    157  1.1  christos 
    158  1.1  christos     /* Cross-reference output file, part 3 (All other object refs) */
    159  1.1  christos 
    160  1.1  christos     OtPrintHeaders ("Part 3: Full Object Reference Map "
    161  1.1  christos         "(Methods that reference each object in namespace");
    162  1.1  christos 
    163  1.1  christos     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    164  1.1  christos         OtXrefWalkPart3, NULL, &XrefInfo);
    165  1.1  christos 
    166  1.1  christos     /* Cross-reference summary */
    167  1.1  christos 
    168  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nObject Summary\n");
    169  1.1  christos 
    170  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    171  1.1  christos         "\nTotal methods:                   %u\n",
    172  1.1  christos         XrefInfo.TotalPredefinedMethods + XrefInfo.TotalUserMethods);
    173  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    174  1.1  christos         "Total predefined methods:        %u\n",
    175  1.1  christos         XrefInfo.TotalPredefinedMethods);
    176  1.1  christos 
    177  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    178  1.1  christos         "\nTotal user methods:              %u\n",
    179  1.1  christos         XrefInfo.TotalUserMethods);
    180  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    181  1.1  christos         "Total unreferenced user methods  %u\n",
    182  1.1  christos         XrefInfo.TotalUnreferenceUserMethods);
    183  1.1  christos 
    184  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    185  1.1  christos         "\nTotal defined objects:           %u\n",
    186  1.1  christos         XrefInfo.TotalObjects);
    187  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    188  1.1  christos         "Total unreferenced objects:      %u\n",
    189  1.1  christos         XrefInfo.TotalUnreferencedObjects);
    190  1.1  christos }
    191  1.1  christos 
    192  1.1  christos 
    193  1.1  christos /*
    194  1.1  christos  * Part 1 of the cross reference file. This part emits the namespace objects
    195  1.1  christos  * that are referenced by each control method in the namespace.
    196  1.1  christos  *
    197  1.1  christos  * Part 2 and 3 are below part 1.
    198  1.1  christos  */
    199  1.1  christos 
    200  1.1  christos /*******************************************************************************
    201  1.1  christos  *
    202  1.1  christos  * FUNCTION:    OtXrefWalkPart1
    203  1.1  christos  *
    204  1.1  christos  * PARAMETERS:  Op                      - Current parse Op
    205  1.1  christos  *              Level                   - Current tree nesting level
    206  1.1  christos  *              MethodInfo              - Info block for the current method
    207  1.1  christos  *
    208  1.1  christos  *
    209  1.1  christos  * RETURN:      None
    210  1.1  christos  *
    211  1.1  christos  * DESCRIPTION: Entry point for the creation of the method call reference map.
    212  1.1  christos  *              For each control method in the namespace, all other methods
    213  1.1  christos  *              that invoke the method are listed. Predefined names/methods
    214  1.1  christos  *              that start with an underscore are ignored, because these are
    215  1.1  christos  *              essentially external/public interfaces.
    216  1.1  christos 
    217  1.1  christos  * DESCRIPTION: Entry point for the creation of the object reference map.
    218  1.1  christos  *              For each control method in the namespace, all objects that
    219  1.1  christos  *              are referenced by the method are listed.
    220  1.1  christos  *
    221  1.1  christos  *              Called during a normal namespace walk, once per namespace
    222  1.1  christos  *              object. (MtMethodAnalysisWalkBegin)
    223  1.1  christos  *
    224  1.1  christos  ******************************************************************************/
    225  1.1  christos 
    226  1.1  christos void
    227  1.1  christos OtXrefWalkPart1 (
    228  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    229  1.1  christos     UINT32                  Level,
    230  1.1  christos     ASL_METHOD_INFO         *MethodInfo)
    231  1.1  christos {
    232  1.1  christos     ACPI_NAMESPACE_NODE     *Node;
    233  1.1  christos     ACPI_PARSE_OBJECT       *NextOp;
    234  1.1  christos     ACPI_PARSE_OBJECT       *FieldOp;
    235  1.1  christos     char                    *ParentPath;
    236  1.1  christos     UINT32                  Length;
    237  1.1  christos     ACPI_STATUS             Status;
    238  1.1  christos 
    239  1.1  christos 
    240  1.1  christos     switch (Op->Asl.ParseOpcode)
    241  1.1  christos     {
    242  1.1  christos     case PARSEOP_NAMESEG:
    243  1.1  christos     case PARSEOP_NAMESTRING:
    244  1.1  christos     case PARSEOP_METHODCALL:
    245  1.1  christos 
    246  1.1  christos         if (!MethodInfo ||
    247  1.1  christos             (MethodInfo->Op->Asl.Child == Op) ||
    248  1.1  christos             !Op->Asl.Node)
    249  1.1  christos         {
    250  1.1  christos             break;
    251  1.1  christos         }
    252  1.1  christos 
    253  1.1  christos         MethodInfo->CurrentOp = Op;
    254  1.1  christos         Node = Op->Asl.Node;
    255  1.1  christos 
    256  1.1  christos         /* Find all objects referenced by this method */
    257  1.1  christos 
    258  1.1  christos         Status = TrWalkParseTree (MethodInfo->Op, ASL_WALK_VISIT_DOWNWARD,
    259  1.1  christos             OtXrefAnalysisWalkPart1, NULL, MethodInfo);
    260  1.1  christos 
    261  1.1  christos         if (Status == AE_CTRL_TERMINATE)
    262  1.1  christos         {
    263  1.1  christos             ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    264  1.1  christos 
    265  1.1  christos             FlPrintFile (ASL_FILE_XREF_OUTPUT, "            %-40s %s",
    266  1.1  christos                 ParentPath, AcpiUtGetTypeName (Node->Type));
    267  1.1  christos             ACPI_FREE (ParentPath);
    268  1.1  christos 
    269  1.1  christos             switch (Node->Type)
    270  1.1  christos             {
    271  1.1  christos                 /* Handle externals */
    272  1.1  christos 
    273  1.1  christos             case ACPI_TYPE_ANY:
    274  1.1  christos             case ACPI_TYPE_FIELD_UNIT:
    275  1.1  christos 
    276  1.1  christos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " <External Object>");
    277  1.1  christos                 break;
    278  1.1  christos 
    279  1.1  christos             case ACPI_TYPE_INTEGER:
    280  1.1  christos 
    281  1.1  christos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " %8.8X%8.8X",
    282  1.1  christos                     ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
    283  1.1  christos                 break;
    284  1.1  christos 
    285  1.1  christos             case ACPI_TYPE_METHOD:
    286  1.1  christos 
    287  1.1  christos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " Invocation (%u args)",
    288  1.1  christos                     Node->ArgCount);
    289  1.1  christos                 break;
    290  1.1  christos 
    291  1.1  christos             case ACPI_TYPE_BUFFER_FIELD:
    292  1.1  christos 
    293  1.1  christos                 NextOp = Node->Op;              /* Create Buffer Field Op */
    294  1.1  christos                 switch (NextOp->Asl.ParseOpcode)
    295  1.1  christos                 {
    296  1.1  christos                 case PARSEOP_CREATEBITFIELD:
    297  1.1  christos                     Length = 1;
    298  1.1  christos                     break;
    299  1.1  christos 
    300  1.1  christos                 case PARSEOP_CREATEBYTEFIELD:
    301  1.1  christos                     Length = 8;
    302  1.1  christos                     break;
    303  1.1  christos 
    304  1.1  christos                 case PARSEOP_CREATEWORDFIELD:
    305  1.1  christos                     Length = 16;
    306  1.1  christos                     break;
    307  1.1  christos 
    308  1.1  christos                 case PARSEOP_CREATEDWORDFIELD:
    309  1.1  christos                     Length = 32;
    310  1.1  christos                     break;
    311  1.1  christos 
    312  1.1  christos                 case PARSEOP_CREATEQWORDFIELD:
    313  1.1  christos                     Length = 64;
    314  1.1  christos                     break;
    315  1.1  christos 
    316  1.1  christos                 default:
    317  1.1  christos                     Length = 0;
    318  1.1  christos                     break;
    319  1.1  christos                 }
    320  1.1  christos 
    321  1.1  christos                 NextOp = NextOp->Asl.Child;     /* Buffer name */
    322  1.1  christos 
    323  1.1  christos                 if (!NextOp->Asl.ExternalName)
    324  1.1  christos                 {
    325  1.1  christos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " in Arg/Local");
    326  1.1  christos                 }
    327  1.1  christos                 else
    328  1.1  christos                 {
    329  1.1  christos                     ParentPath = AcpiNsGetNormalizedPathname (
    330  1.1  christos                         NextOp->Asl.Node, TRUE);
    331  1.1  christos 
    332  1.1  christos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Buffer %s",
    333  1.1  christos                         Length, ParentPath);
    334  1.1  christos                     ACPI_FREE (ParentPath);
    335  1.1  christos                 }
    336  1.1  christos                 break;
    337  1.1  christos 
    338  1.1  christos             case ACPI_TYPE_LOCAL_REGION_FIELD:
    339  1.1  christos 
    340  1.1  christos                 NextOp = Node->Op;
    341  1.1  christos                 FieldOp = NextOp->Asl.Parent;
    342  1.1  christos                 NextOp = FieldOp->Asl.Child;
    343  1.1  christos 
    344  1.1  christos                 ParentPath = AcpiNsGetNormalizedPathname (
    345  1.1  christos                     NextOp->Asl.Node, TRUE);
    346  1.1  christos 
    347  1.1  christos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Region %s",
    348  1.1  christos                     (UINT32) Node->Op->Asl.Child->Asl.Value.Integer,
    349  1.1  christos                     ParentPath);
    350  1.1  christos                 ACPI_FREE (ParentPath);
    351  1.1  christos 
    352  1.1  christos                 if (FieldOp->Asl.ParseOpcode == PARSEOP_FIELD)
    353  1.1  christos                 {
    354  1.1  christos                     Node = NextOp->Asl.Node;        /* Region node */
    355  1.1  christos                     NextOp = Node->Op;              /* PARSEOP_REGION */
    356  1.1  christos                     NextOp = NextOp->Asl.Child;     /* Region name */
    357  1.1  christos                     NextOp = NextOp->Asl.Next;
    358  1.1  christos 
    359  1.1  christos                     /* Get region space/addr/len? */
    360  1.1  christos 
    361  1.1  christos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%s)",
    362  1.1  christos                         AcpiUtGetRegionName ((UINT8)
    363  1.1  christos                         NextOp->Asl.Value.Integer));
    364  1.1  christos                 }
    365  1.1  christos                 break;
    366  1.1  christos 
    367  1.1  christos             default:
    368  1.1  christos                 break;
    369  1.1  christos             }
    370  1.1  christos 
    371  1.1  christos             FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n");
    372  1.1  christos         }
    373  1.1  christos         break;
    374  1.1  christos 
    375  1.1  christos     case PARSEOP_METHOD:
    376  1.1  christos 
    377  1.1  christos         ParentPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
    378  1.1  christos 
    379  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    380  1.1  christos             "\n[%5u]  %-40s %s Declaration (%u args)\n",
    381  1.1  christos             Op->Asl.LogicalLineNumber, ParentPath,
    382  1.1  christos             AcpiUtGetTypeName (Op->Asl.Node->Type), Op->Asl.Node->ArgCount);
    383  1.1  christos 
    384  1.1  christos         ACPI_FREE (ParentPath);
    385  1.1  christos         break;
    386  1.1  christos 
    387  1.1  christos     default:
    388  1.1  christos         break;
    389  1.1  christos     }
    390  1.1  christos }
    391  1.1  christos 
    392  1.1  christos 
    393  1.1  christos /*******************************************************************************
    394  1.1  christos  *
    395  1.1  christos  * FUNCTION:    OtXrefAnalysisWalkPart1
    396  1.1  christos  *
    397  1.1  christos  * PARAMETERS:  ASL_WALK_CALLBACK
    398  1.1  christos  *
    399  1.1  christos  * RETURN:      Status
    400  1.1  christos  *
    401  1.1  christos  * DESCRIPTION: Secondary walk for cross-reference part 1.
    402  1.1  christos  *
    403  1.1  christos  ******************************************************************************/
    404  1.1  christos 
    405  1.1  christos static ACPI_STATUS
    406  1.1  christos OtXrefAnalysisWalkPart1 (
    407  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    408  1.1  christos     UINT32                  Level,
    409  1.1  christos     void                    *Context)
    410  1.1  christos {
    411  1.1  christos     ASL_METHOD_INFO         *MethodInfo = (ASL_METHOD_INFO *) Context;
    412  1.1  christos     ACPI_PARSE_OBJECT       *Next;
    413  1.1  christos 
    414  1.1  christos 
    415  1.1  christos     /* Only interested in name string Ops -- ignore all others */
    416  1.1  christos 
    417  1.1  christos     if ((Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
    418  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
    419  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
    420  1.1  christos     {
    421  1.1  christos         return (AE_OK);
    422  1.1  christos     }
    423  1.1  christos 
    424  1.1  christos     /* No node means a locally declared object -- ignore */
    425  1.1  christos 
    426  1.1  christos     if (!Op->Asl.Node)
    427  1.1  christos     {
    428  1.1  christos         return (AE_OK);
    429  1.1  christos     }
    430  1.1  christos 
    431  1.1  christos     /* When we encounter the source Op, we are done */
    432  1.1  christos 
    433  1.1  christos     Next = MethodInfo->CurrentOp;
    434  1.1  christos     if (Next == Op)
    435  1.1  christos     {
    436  1.1  christos         return (AE_CTRL_TERMINATE);
    437  1.1  christos     }
    438  1.1  christos 
    439  1.1  christos     /* If we have a name match, this Op is a duplicate */
    440  1.1  christos 
    441  1.1  christos     if ((Next->Asl.ParseOpcode == PARSEOP_NAMESEG)      ||
    442  1.1  christos         (Next->Asl.ParseOpcode == PARSEOP_NAMESTRING)   ||
    443  1.1  christos         (Next->Asl.ParseOpcode == PARSEOP_METHODCALL))
    444  1.1  christos     {
    445  1.1  christos         if (!strcmp (Op->Asl.ExternalName, Next->Asl.ExternalName))
    446  1.1  christos         {
    447  1.1  christos             return (AE_ALREADY_EXISTS);
    448  1.1  christos         }
    449  1.1  christos     }
    450  1.1  christos 
    451  1.1  christos     return (AE_OK);
    452  1.1  christos }
    453  1.1  christos 
    454  1.1  christos 
    455  1.1  christos /*
    456  1.1  christos  * Part 2 of the cross reference file. This part emits the names of each
    457  1.1  christos  * non-predefined method in the namespace (user methods), along with the
    458  1.1  christos  * names of each control method that references that method.
    459  1.1  christos  */
    460  1.1  christos 
    461  1.1  christos /*******************************************************************************
    462  1.1  christos  *
    463  1.1  christos  * FUNCTION:    OtXrefWalkPart2
    464  1.1  christos  *
    465  1.1  christos  * PARAMETERS:  ASL_WALK_CALLBACK
    466  1.1  christos  *
    467  1.1  christos  * RETURN:      Status
    468  1.1  christos  *
    469  1.1  christos  * DESCRIPTION: For each control method in the namespace, we will re-walk the
    470  1.1  christos  *              namespace to find each and every invocation of that control
    471  1.1  christos  *              method. Brute force, but does not matter, even for large
    472  1.1  christos  *              namespaces. Ignore predefined names (start with underscore).
    473  1.1  christos  *
    474  1.1  christos  ******************************************************************************/
    475  1.1  christos 
    476  1.1  christos static ACPI_STATUS
    477  1.1  christos OtXrefWalkPart2 (
    478  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    479  1.1  christos     UINT32                  Level,
    480  1.1  christos     void                    *Context)
    481  1.1  christos {
    482  1.1  christos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    483  1.1  christos     ACPI_NAMESPACE_NODE     *Node;
    484  1.1  christos     char                    *ParentPath;
    485  1.1  christos 
    486  1.1  christos 
    487  1.1  christos     /* Looking for Method Declaration Ops only */
    488  1.1  christos 
    489  1.1  christos     if (!Op->Asl.Node ||
    490  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_METHOD))
    491  1.1  christos     {
    492  1.1  christos         return (AE_OK);
    493  1.1  christos     }
    494  1.1  christos 
    495  1.1  christos     /* Ignore predefined names */
    496  1.1  christos 
    497  1.1  christos     if (Op->Asl.Node->Name.Ascii[0] == '_')
    498  1.1  christos     {
    499  1.1  christos         XrefInfo->TotalPredefinedMethods++;
    500  1.1  christos         return (AE_OK);
    501  1.1  christos     }
    502  1.1  christos 
    503  1.1  christos     Node = Op->Asl.Node;
    504  1.1  christos     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    505  1.1  christos 
    506  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    507  1.1  christos         "\n[%5u]  %-40s %s Declaration (%u args)\n",
    508  1.1  christos         Op->Asl.LogicalLineNumber, ParentPath,
    509  1.1  christos         AcpiUtGetTypeName (Node->Type), Node->ArgCount);
    510  1.1  christos 
    511  1.1  christos     XrefInfo->TotalUserMethods++;
    512  1.1  christos     XrefInfo->ThisMethodInvocations = 0;
    513  1.1  christos     XrefInfo->MethodOp = Op;
    514  1.1  christos 
    515  1.1  christos     (void) TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    516  1.1  christos         OtXrefAnalysisWalkPart2, NULL, XrefInfo);
    517  1.1  christos 
    518  1.1  christos     if (!XrefInfo->ThisMethodInvocations)
    519  1.1  christos     {
    520  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    521  1.1  christos             "            Zero invocations of this method in this module\n");
    522  1.1  christos         XrefInfo->TotalUnreferenceUserMethods++;
    523  1.1  christos     }
    524  1.1  christos     else
    525  1.1  christos     {
    526  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    527  1.1  christos             "            %u invocations of method %s in this module\n",
    528  1.1  christos             XrefInfo->ThisMethodInvocations, ParentPath);
    529  1.1  christos     }
    530  1.1  christos 
    531  1.1  christos     ACPI_FREE (ParentPath);
    532  1.1  christos     return (AE_OK);
    533  1.1  christos }
    534  1.1  christos 
    535  1.1  christos 
    536  1.1  christos /*******************************************************************************
    537  1.1  christos  *
    538  1.1  christos  * FUNCTION:    OtXrefAnalysisWalkPart2
    539  1.1  christos  *
    540  1.1  christos  * PARAMETERS:  ASL_WALK_CALLBACK
    541  1.1  christos  *
    542  1.1  christos  * RETURN:      Status
    543  1.1  christos  *
    544  1.1  christos  * DESCRIPTION: For every Op that is a method invocation, emit a reference
    545  1.1  christos  *              line if the Op is invoking the target method.
    546  1.1  christos  *
    547  1.1  christos  ******************************************************************************/
    548  1.1  christos 
    549  1.1  christos static ACPI_STATUS
    550  1.1  christos OtXrefAnalysisWalkPart2 (
    551  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    552  1.1  christos     UINT32                  Level,
    553  1.1  christos     void                    *Context)
    554  1.1  christos {
    555  1.1  christos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    556  1.1  christos     ACPI_PARSE_OBJECT       *CallerOp;
    557  1.1  christos     char                    *CallerFullPathname;
    558  1.1  christos 
    559  1.1  christos 
    560  1.1  christos     /* Looking for MethodCall Ops only */
    561  1.1  christos 
    562  1.1  christos     if (!Op->Asl.Node ||
    563  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
    564  1.1  christos     {
    565  1.1  christos         return (AE_OK);
    566  1.1  christos     }
    567  1.1  christos 
    568  1.1  christos     /* If not a match to the target method, we are done */
    569  1.1  christos 
    570  1.1  christos     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
    571  1.1  christos     {
    572  1.1  christos         return (AE_CTRL_DEPTH);
    573  1.1  christos     }
    574  1.1  christos 
    575  1.1  christos     /* Find parent method to get method caller namepath */
    576  1.1  christos 
    577  1.1  christos     CallerOp = Op->Asl.Parent;
    578  1.1  christos     while (CallerOp &&
    579  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD))
    580  1.1  christos     {
    581  1.1  christos         CallerOp = CallerOp->Asl.Parent;
    582  1.1  christos     }
    583  1.1  christos 
    584  1.1  christos     /* There is no parent method for External() statements */
    585  1.1  christos 
    586  1.1  christos     if (!CallerOp)
    587  1.1  christos     {
    588  1.1  christos         return (AE_OK);
    589  1.1  christos     }
    590  1.1  christos 
    591  1.1  christos     CallerFullPathname = AcpiNsGetNormalizedPathname (
    592  1.1  christos         CallerOp->Asl.Node, TRUE);
    593  1.1  christos 
    594  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    595  1.1  christos         "[%5u]     %-40s Invocation path: %s\n",
    596  1.1  christos         Op->Asl.LogicalLineNumber, CallerFullPathname,
    597  1.1  christos         Op->Asl.ExternalName);
    598  1.1  christos 
    599  1.1  christos     ACPI_FREE (CallerFullPathname);
    600  1.1  christos     XrefInfo->ThisMethodInvocations++;
    601  1.1  christos     return (AE_OK);
    602  1.1  christos }
    603  1.1  christos 
    604  1.1  christos 
    605  1.1  christos /*
    606  1.1  christos  * Part 3 of the cross reference file. This part emits the names of each
    607  1.1  christos  * non-predefined method in the namespace (user methods), along with the
    608  1.1  christos  * names of each control method that references that method.
    609  1.1  christos  */
    610  1.1  christos 
    611  1.1  christos /*******************************************************************************
    612  1.1  christos  *
    613  1.1  christos  * FUNCTION:    OtXrefWalkPart3
    614  1.1  christos  *
    615  1.1  christos  * PARAMETERS:  ASL_WALK_CALLBACK
    616  1.1  christos  *
    617  1.1  christos  * RETURN:      Status
    618  1.1  christos  *
    619  1.1  christos  * DESCRIPTION: Cross-reference part 3. references to objects other than
    620  1.1  christos  *              control methods.
    621  1.1  christos  *
    622  1.1  christos  ******************************************************************************/
    623  1.1  christos 
    624  1.1  christos static ACPI_STATUS
    625  1.1  christos OtXrefWalkPart3 (
    626  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    627  1.1  christos     UINT32                  Level,
    628  1.1  christos     void                    *Context)
    629  1.1  christos {
    630  1.1  christos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    631  1.1  christos     ACPI_NAMESPACE_NODE     *Node;
    632  1.1  christos     char                    *ParentPath;
    633  1.1  christos     const ACPI_OPCODE_INFO  *OpInfo;
    634  1.1  christos 
    635  1.1  christos 
    636  1.1  christos     /* Ignore method declarations */
    637  1.1  christos 
    638  1.1  christos     if (!Op->Asl.Node ||
    639  1.1  christos         (Op->Asl.ParseOpcode == PARSEOP_METHOD))
    640  1.1  christos     {
    641  1.1  christos         return (AE_OK);
    642  1.1  christos     }
    643  1.1  christos 
    644  1.1  christos     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    645  1.1  christos     if (!(OpInfo->Class & AML_CLASS_NAMED_OBJECT))
    646  1.1  christos     {
    647  1.1  christos         return (AE_OK);
    648  1.1  christos     }
    649  1.1  christos 
    650  1.1  christos     /* Only care about named object creation opcodes */
    651  1.1  christos 
    652  1.1  christos     if ((Op->Asl.ParseOpcode != PARSEOP_NAME) &&
    653  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_DEVICE) &&
    654  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_MUTEX) &&
    655  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION) &&
    656  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_FIELD) &&
    657  1.1  christos         (Op->Asl.ParseOpcode != PARSEOP_EVENT))
    658  1.1  christos     {
    659  1.1  christos         return (AE_OK);
    660  1.1  christos     }
    661  1.1  christos 
    662  1.1  christos     /* Ignore predefined names */
    663  1.1  christos 
    664  1.1  christos     if (Op->Asl.Node->Name.Ascii[0] == '_')
    665  1.1  christos     {
    666  1.1  christos         return (AE_OK);
    667  1.1  christos     }
    668  1.1  christos 
    669  1.1  christos     Node = Op->Asl.Node;
    670  1.1  christos     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
    671  1.1  christos 
    672  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    673  1.1  christos         "\n[%5u]  %-40s %s Declaration\n",
    674  1.1  christos         Op->Asl.LogicalLineNumber, ParentPath,
    675  1.1  christos         AcpiUtGetTypeName (Node->Type));
    676  1.1  christos     ACPI_FREE (ParentPath);
    677  1.1  christos 
    678  1.1  christos     XrefInfo->MethodOp = Op;
    679  1.1  christos     XrefInfo->ThisObjectReferences = 0;
    680  1.1  christos     XrefInfo->TotalObjects = 0;
    681  1.1  christos 
    682  1.1  christos     (void) TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    683  1.1  christos         OtXrefAnalysisWalkPart3, NULL, XrefInfo);
    684  1.1  christos 
    685  1.1  christos     if (!XrefInfo->ThisObjectReferences)
    686  1.1  christos     {
    687  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    688  1.1  christos             "            Zero references to this object in this module\n");
    689  1.1  christos         XrefInfo->TotalUnreferencedObjects++;
    690  1.1  christos     }
    691  1.1  christos     else
    692  1.1  christos     {
    693  1.1  christos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
    694  1.1  christos             "            %u references to this object in this module\n",
    695  1.1  christos             XrefInfo->ThisObjectReferences, ParentPath);
    696  1.1  christos     }
    697  1.1  christos 
    698  1.1  christos     return (AE_OK);
    699  1.1  christos }
    700  1.1  christos 
    701  1.1  christos 
    702  1.1  christos /*******************************************************************************
    703  1.1  christos  *
    704  1.1  christos  * FUNCTION:    OtXrefAnalysisWalkPart3
    705  1.1  christos  *
    706  1.1  christos  * PARAMETERS:  ASL_WALK_CALLBACK
    707  1.1  christos  *
    708  1.1  christos  * RETURN:      Status
    709  1.1  christos  *
    710  1.1  christos  * DESCRIPTION: Secondary walk for cross-reference part 3.
    711  1.1  christos  *
    712  1.1  christos  ******************************************************************************/
    713  1.1  christos 
    714  1.1  christos static ACPI_STATUS
    715  1.1  christos OtXrefAnalysisWalkPart3 (
    716  1.1  christos     ACPI_PARSE_OBJECT       *Op,
    717  1.1  christos     UINT32                  Level,
    718  1.1  christos     void                    *Context)
    719  1.1  christos {
    720  1.1  christos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
    721  1.1  christos     char                    *CallerFullPathname = NULL;
    722  1.1  christos     ACPI_PARSE_OBJECT       *CallerOp;
    723  1.1  christos     const char              *Operator;
    724  1.1  christos 
    725  1.1  christos 
    726  1.1  christos     if (!Op->Asl.Node)
    727  1.1  christos     {
    728  1.1  christos         return (AE_OK);
    729  1.1  christos     }
    730  1.1  christos 
    731  1.1  christos     XrefInfo->TotalObjects++;
    732  1.1  christos 
    733  1.1  christos     /* Ignore Op that actually defined the object */
    734  1.1  christos 
    735  1.1  christos     if (Op == XrefInfo->MethodOp)
    736  1.1  christos     {
    737  1.1  christos         return (AE_OK);
    738  1.1  christos     }
    739  1.1  christos 
    740  1.1  christos     /* Only interested in Ops that reference the target node */
    741  1.1  christos 
    742  1.1  christos     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
    743  1.1  christos     {
    744  1.1  christos         return (AE_OK);
    745  1.1  christos     }
    746  1.1  christos 
    747  1.1  christos     /* Find parent "open scope" object to get method caller namepath */
    748  1.1  christos 
    749  1.1  christos     CallerOp = Op->Asl.Parent;
    750  1.1  christos     while (CallerOp &&
    751  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_NAME) &&
    752  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD) &&
    753  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_DEVICE) &&
    754  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_POWERRESOURCE) &&
    755  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_PROCESSOR) &&
    756  1.1  christos         (CallerOp->Asl.ParseOpcode != PARSEOP_THERMALZONE))
    757  1.1  christos     {
    758  1.1  christos         CallerOp = CallerOp->Asl.Parent;
    759  1.1  christos     }
    760  1.1  christos 
    761  1.1  christos     if (CallerOp == XrefInfo->CurrentMethodOp)
    762  1.1  christos     {
    763  1.1  christos         return (AE_OK);
    764  1.1  christos     }
    765  1.1  christos 
    766  1.1  christos     /* Null CallerOp means the caller is at the namespace root */
    767  1.1  christos 
    768  1.1  christos     if (CallerOp)
    769  1.1  christos     {
    770  1.1  christos         CallerFullPathname = AcpiNsGetNormalizedPathname (
    771  1.1  christos             CallerOp->Asl.Node, TRUE);
    772  1.1  christos     }
    773  1.1  christos 
    774  1.1  christos     /* There are some special cases for the oddball operators */
    775  1.1  christos 
    776  1.1  christos     if (Op->Asl.ParseOpcode == PARSEOP_SCOPE)
    777  1.1  christos     {
    778  1.1  christos         Operator = "Scope";
    779  1.1  christos     }
    780  1.1  christos     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)
    781  1.1  christos     {
    782  1.1  christos         Operator = "Alias";
    783  1.1  christos     }
    784  1.1  christos     else if (!CallerOp)
    785  1.1  christos     {
    786  1.1  christos         Operator = "ModLevel";
    787  1.1  christos     }
    788  1.1  christos     else
    789  1.1  christos     {
    790  1.1  christos         Operator = AcpiUtGetTypeName (CallerOp->Asl.Node->Type);
    791  1.1  christos     }
    792  1.1  christos 
    793  1.1  christos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
    794  1.1  christos         "[%5u]     %-40s %-8s via path: %s, Operator: %s\n",
    795  1.1  christos         Op->Asl.LogicalLineNumber,
    796  1.1  christos         CallerFullPathname ? CallerFullPathname : "<root>",
    797  1.1  christos         Operator,
    798  1.1  christos         Op->Asl.ExternalName,
    799  1.1  christos         Op->Asl.Parent->Asl.ParseOpName);
    800  1.1  christos 
    801  1.1  christos     if (!CallerOp)
    802  1.1  christos     {
    803  1.1  christos         CallerOp = ACPI_TO_POINTER (0xFFFFFFFF);
    804  1.1  christos     }
    805  1.1  christos 
    806  1.1  christos     if (CallerFullPathname)
    807  1.1  christos     {
    808  1.1  christos         ACPI_FREE (CallerFullPathname);
    809  1.1  christos     }
    810  1.1  christos 
    811  1.1  christos     XrefInfo->CurrentMethodOp = CallerOp;
    812  1.1  christos     XrefInfo->ThisObjectReferences++;
    813  1.1  christos     return (AE_OK);
    814  1.1  christos }
    815