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