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 - 2018, 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 (!Gbl_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 (Gbl_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 (Gbl_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 (Gbl_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 (Gbl_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\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