]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/aslxrefout.c
MFV r306669:
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / compiler / aslxrefout.c
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 <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include "aslcompiler.y.h"
46 #include <contrib/dev/acpica/include/acnamesp.h>
47 #include <contrib/dev/acpica/include/acparser.h>
48 #include <contrib/dev/acpica/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
256         /* Find all objects referenced by this method */
257
258         Status = TrWalkParseTree (MethodInfo->Op, ASL_WALK_VISIT_DOWNWARD,
259             OtXrefAnalysisWalkPart1, NULL, MethodInfo);
260
261         if (Status == AE_CTRL_TERMINATE)
262         {
263             ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
264
265             FlPrintFile (ASL_FILE_XREF_OUTPUT, "            %-40s %s",
266                 ParentPath, AcpiUtGetTypeName (Node->Type));
267             ACPI_FREE (ParentPath);
268
269             switch (Node->Type)
270             {
271                 /* Handle externals */
272
273             case ACPI_TYPE_ANY:
274             case ACPI_TYPE_FIELD_UNIT:
275
276                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " <External Object>");
277                 break;
278
279             case ACPI_TYPE_INTEGER:
280
281                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " %8.8X%8.8X",
282                     ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
283                 break;
284
285             case ACPI_TYPE_METHOD:
286
287                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " Invocation (%u args)",
288                     Node->ArgCount);
289                 break;
290
291             case ACPI_TYPE_BUFFER_FIELD:
292
293                 NextOp = Node->Op;              /* Create Buffer Field Op */
294                 switch (NextOp->Asl.ParseOpcode)
295                 {
296                 case PARSEOP_CREATEBITFIELD:
297                     Length = 1;
298                     break;
299
300                 case PARSEOP_CREATEBYTEFIELD:
301                     Length = 8;
302                     break;
303
304                 case PARSEOP_CREATEWORDFIELD:
305                     Length = 16;
306                     break;
307
308                 case PARSEOP_CREATEDWORDFIELD:
309                     Length = 32;
310                     break;
311
312                 case PARSEOP_CREATEQWORDFIELD:
313                     Length = 64;
314                     break;
315
316                 default:
317                     Length = 0;
318                     break;
319                 }
320
321                 NextOp = NextOp->Asl.Child;     /* Buffer name */
322
323                 if (!NextOp->Asl.ExternalName)
324                 {
325                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " in Arg/Local");
326                 }
327                 else
328                 {
329                     ParentPath = AcpiNsGetNormalizedPathname (
330                         NextOp->Asl.Node, TRUE);
331
332                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Buffer %s",
333                         Length, ParentPath);
334                     ACPI_FREE (ParentPath);
335                 }
336                 break;
337
338             case ACPI_TYPE_LOCAL_REGION_FIELD:
339
340                 NextOp = Node->Op;
341                 FieldOp = NextOp->Asl.Parent;
342                 NextOp = FieldOp->Asl.Child;
343
344                 ParentPath = AcpiNsGetNormalizedPathname (
345                     NextOp->Asl.Node, TRUE);
346
347                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Region %s",
348                     (UINT32) Node->Op->Asl.Child->Asl.Value.Integer,
349                     ParentPath);
350                 ACPI_FREE (ParentPath);
351
352                 if (FieldOp->Asl.ParseOpcode == PARSEOP_FIELD)
353                 {
354                     Node = NextOp->Asl.Node;        /* Region node */
355                     NextOp = Node->Op;              /* PARSEOP_REGION */
356                     NextOp = NextOp->Asl.Child;     /* Region name */
357                     NextOp = NextOp->Asl.Next;
358
359                     /* Get region space/addr/len? */
360
361                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%s)",
362                         AcpiUtGetRegionName ((UINT8)
363                         NextOp->Asl.Value.Integer));
364                 }
365                 break;
366
367             default:
368                 break;
369             }
370
371             FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n");
372         }
373         break;
374
375     case PARSEOP_METHOD:
376
377         ParentPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
378
379         FlPrintFile (ASL_FILE_XREF_OUTPUT,
380             "\n[%5u]  %-40s %s Declaration (%u args)\n",
381             Op->Asl.LogicalLineNumber, ParentPath,
382             AcpiUtGetTypeName (Op->Asl.Node->Type), Op->Asl.Node->ArgCount);
383
384         ACPI_FREE (ParentPath);
385         break;
386
387     default:
388         break;
389     }
390 }
391
392
393 /*******************************************************************************
394  *
395  * FUNCTION:    OtXrefAnalysisWalkPart1
396  *
397  * PARAMETERS:  ASL_WALK_CALLBACK
398  *
399  * RETURN:      Status
400  *
401  * DESCRIPTION: Secondary walk for cross-reference part 1.
402  *
403  ******************************************************************************/
404
405 static ACPI_STATUS
406 OtXrefAnalysisWalkPart1 (
407     ACPI_PARSE_OBJECT       *Op,
408     UINT32                  Level,
409     void                    *Context)
410 {
411     ASL_METHOD_INFO         *MethodInfo = (ASL_METHOD_INFO *) Context;
412     ACPI_PARSE_OBJECT       *Next;
413
414
415     /* Only interested in name string Ops -- ignore all others */
416
417     if ((Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
418         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
419         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
420     {
421         return (AE_OK);
422     }
423
424     /* No node means a locally declared object -- ignore */
425
426     if (!Op->Asl.Node)
427     {
428         return (AE_OK);
429     }
430
431     /* When we encounter the source Op, we are done */
432
433     Next = MethodInfo->CurrentOp;
434     if (Next == Op)
435     {
436         return (AE_CTRL_TERMINATE);
437     }
438
439     /* If we have a name match, this Op is a duplicate */
440
441     if ((Next->Asl.ParseOpcode == PARSEOP_NAMESEG)      ||
442         (Next->Asl.ParseOpcode == PARSEOP_NAMESTRING)   ||
443         (Next->Asl.ParseOpcode == PARSEOP_METHODCALL))
444     {
445         if (!strcmp (Op->Asl.ExternalName, Next->Asl.ExternalName))
446         {
447             return (AE_ALREADY_EXISTS);
448         }
449     }
450
451     return (AE_OK);
452 }
453
454
455 /*
456  * Part 2 of the cross reference file. This part emits the names of each
457  * non-predefined method in the namespace (user methods), along with the
458  * names of each control method that references that method.
459  */
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    OtXrefWalkPart2
464  *
465  * PARAMETERS:  ASL_WALK_CALLBACK
466  *
467  * RETURN:      Status
468  *
469  * DESCRIPTION: For each control method in the namespace, we will re-walk the
470  *              namespace to find each and every invocation of that control
471  *              method. Brute force, but does not matter, even for large
472  *              namespaces. Ignore predefined names (start with underscore).
473  *
474  ******************************************************************************/
475
476 static ACPI_STATUS
477 OtXrefWalkPart2 (
478     ACPI_PARSE_OBJECT       *Op,
479     UINT32                  Level,
480     void                    *Context)
481 {
482     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
483     ACPI_NAMESPACE_NODE     *Node;
484     char                    *ParentPath;
485
486
487     /* Looking for Method Declaration Ops only */
488
489     if (!Op->Asl.Node ||
490         (Op->Asl.ParseOpcode != PARSEOP_METHOD))
491     {
492         return (AE_OK);
493     }
494
495     /* Ignore predefined names */
496
497     if (Op->Asl.Node->Name.Ascii[0] == '_')
498     {
499         XrefInfo->TotalPredefinedMethods++;
500         return (AE_OK);
501     }
502
503     Node = Op->Asl.Node;
504     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
505
506     FlPrintFile (ASL_FILE_XREF_OUTPUT,
507         "\n[%5u]  %-40s %s Declaration (%u args)\n",
508         Op->Asl.LogicalLineNumber, ParentPath,
509         AcpiUtGetTypeName (Node->Type), Node->ArgCount);
510
511     XrefInfo->TotalUserMethods++;
512     XrefInfo->ThisMethodInvocations = 0;
513     XrefInfo->MethodOp = Op;
514
515     (void) TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
516         OtXrefAnalysisWalkPart2, NULL, XrefInfo);
517
518     if (!XrefInfo->ThisMethodInvocations)
519     {
520         FlPrintFile (ASL_FILE_XREF_OUTPUT,
521             "            Zero invocations of this method in this module\n");
522         XrefInfo->TotalUnreferenceUserMethods++;
523     }
524     else
525     {
526         FlPrintFile (ASL_FILE_XREF_OUTPUT,
527             "            %u invocations of method %s in this module\n",
528             XrefInfo->ThisMethodInvocations, ParentPath);
529     }
530
531     ACPI_FREE (ParentPath);
532     return (AE_OK);
533 }
534
535
536 /*******************************************************************************
537  *
538  * FUNCTION:    OtXrefAnalysisWalkPart2
539  *
540  * PARAMETERS:  ASL_WALK_CALLBACK
541  *
542  * RETURN:      Status
543  *
544  * DESCRIPTION: For every Op that is a method invocation, emit a reference
545  *              line if the Op is invoking the target method.
546  *
547  ******************************************************************************/
548
549 static ACPI_STATUS
550 OtXrefAnalysisWalkPart2 (
551     ACPI_PARSE_OBJECT       *Op,
552     UINT32                  Level,
553     void                    *Context)
554 {
555     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
556     ACPI_PARSE_OBJECT       *CallerOp;
557     char                    *CallerFullPathname;
558
559
560     /* Looking for MethodCall Ops only */
561
562     if (!Op->Asl.Node ||
563         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
564     {
565         return (AE_OK);
566     }
567
568     /* If not a match to the target method, we are done */
569
570     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
571     {
572         return (AE_CTRL_DEPTH);
573     }
574
575     /* Find parent method to get method caller namepath */
576
577     CallerOp = Op->Asl.Parent;
578     while (CallerOp &&
579         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD))
580     {
581         CallerOp = CallerOp->Asl.Parent;
582     }
583
584     /* There is no parent method for External() statements */
585
586     if (!CallerOp)
587     {
588         return (AE_OK);
589     }
590
591     CallerFullPathname = AcpiNsGetNormalizedPathname (
592         CallerOp->Asl.Node, TRUE);
593
594     FlPrintFile (ASL_FILE_XREF_OUTPUT,
595         "[%5u]     %-40s Invocation path: %s\n",
596         Op->Asl.LogicalLineNumber, CallerFullPathname,
597         Op->Asl.ExternalName);
598
599     ACPI_FREE (CallerFullPathname);
600     XrefInfo->ThisMethodInvocations++;
601     return (AE_OK);
602 }
603
604
605 /*
606  * Part 3 of the cross reference file. This part emits the names of each
607  * non-predefined method in the namespace (user methods), along with the
608  * names of each control method that references that method.
609  */
610
611 /*******************************************************************************
612  *
613  * FUNCTION:    OtXrefWalkPart3
614  *
615  * PARAMETERS:  ASL_WALK_CALLBACK
616  *
617  * RETURN:      Status
618  *
619  * DESCRIPTION: Cross-reference part 3. references to objects other than
620  *              control methods.
621  *
622  ******************************************************************************/
623
624 static ACPI_STATUS
625 OtXrefWalkPart3 (
626     ACPI_PARSE_OBJECT       *Op,
627     UINT32                  Level,
628     void                    *Context)
629 {
630     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
631     ACPI_NAMESPACE_NODE     *Node;
632     char                    *ParentPath;
633     const ACPI_OPCODE_INFO  *OpInfo;
634
635
636     /* Ignore method declarations */
637
638     if (!Op->Asl.Node ||
639         (Op->Asl.ParseOpcode == PARSEOP_METHOD))
640     {
641         return (AE_OK);
642     }
643
644     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
645     if (!(OpInfo->Class & AML_CLASS_NAMED_OBJECT))
646     {
647         return (AE_OK);
648     }
649
650     /* Only care about named object creation opcodes */
651
652     if ((Op->Asl.ParseOpcode != PARSEOP_NAME) &&
653         (Op->Asl.ParseOpcode != PARSEOP_DEVICE) &&
654         (Op->Asl.ParseOpcode != PARSEOP_MUTEX) &&
655         (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION) &&
656         (Op->Asl.ParseOpcode != PARSEOP_FIELD) &&
657         (Op->Asl.ParseOpcode != PARSEOP_EVENT))
658     {
659         return (AE_OK);
660     }
661
662     /* Ignore predefined names */
663
664     if (Op->Asl.Node->Name.Ascii[0] == '_')
665     {
666         return (AE_OK);
667     }
668
669     Node = Op->Asl.Node;
670     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
671
672     FlPrintFile (ASL_FILE_XREF_OUTPUT,
673         "\n[%5u]  %-40s %s Declaration\n",
674         Op->Asl.LogicalLineNumber, ParentPath,
675         AcpiUtGetTypeName (Node->Type));
676     ACPI_FREE (ParentPath);
677
678     XrefInfo->MethodOp = Op;
679     XrefInfo->ThisObjectReferences = 0;
680     XrefInfo->TotalObjects = 0;
681
682     (void) TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
683         OtXrefAnalysisWalkPart3, NULL, XrefInfo);
684
685     if (!XrefInfo->ThisObjectReferences)
686     {
687         FlPrintFile (ASL_FILE_XREF_OUTPUT,
688             "            Zero references to this object in this module\n");
689         XrefInfo->TotalUnreferencedObjects++;
690     }
691     else
692     {
693         FlPrintFile (ASL_FILE_XREF_OUTPUT,
694             "            %u references to this object in this module\n",
695             XrefInfo->ThisObjectReferences, ParentPath);
696     }
697
698     return (AE_OK);
699 }
700
701
702 /*******************************************************************************
703  *
704  * FUNCTION:    OtXrefAnalysisWalkPart3
705  *
706  * PARAMETERS:  ASL_WALK_CALLBACK
707  *
708  * RETURN:      Status
709  *
710  * DESCRIPTION: Secondary walk for cross-reference part 3.
711  *
712  ******************************************************************************/
713
714 static ACPI_STATUS
715 OtXrefAnalysisWalkPart3 (
716     ACPI_PARSE_OBJECT       *Op,
717     UINT32                  Level,
718     void                    *Context)
719 {
720     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
721     char                    *CallerFullPathname = NULL;
722     ACPI_PARSE_OBJECT       *CallerOp;
723     const char              *Operator;
724
725
726     if (!Op->Asl.Node)
727     {
728         return (AE_OK);
729     }
730
731     XrefInfo->TotalObjects++;
732
733     /* Ignore Op that actually defined the object */
734
735     if (Op == XrefInfo->MethodOp)
736     {
737         return (AE_OK);
738     }
739
740     /* Only interested in Ops that reference the target node */
741
742     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
743     {
744         return (AE_OK);
745     }
746
747     /* Find parent "open scope" object to get method caller namepath */
748
749     CallerOp = Op->Asl.Parent;
750     while (CallerOp &&
751         (CallerOp->Asl.ParseOpcode != PARSEOP_NAME) &&
752         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD) &&
753         (CallerOp->Asl.ParseOpcode != PARSEOP_DEVICE) &&
754         (CallerOp->Asl.ParseOpcode != PARSEOP_POWERRESOURCE) &&
755         (CallerOp->Asl.ParseOpcode != PARSEOP_PROCESSOR) &&
756         (CallerOp->Asl.ParseOpcode != PARSEOP_THERMALZONE))
757     {
758         CallerOp = CallerOp->Asl.Parent;
759     }
760
761     if (CallerOp == XrefInfo->CurrentMethodOp)
762     {
763         return (AE_OK);
764     }
765
766     /* Null CallerOp means the caller is at the namespace root */
767
768     if (CallerOp)
769     {
770         CallerFullPathname = AcpiNsGetNormalizedPathname (
771             CallerOp->Asl.Node, TRUE);
772     }
773
774     /* There are some special cases for the oddball operators */
775
776     if (Op->Asl.ParseOpcode == PARSEOP_SCOPE)
777     {
778         Operator = "Scope";
779     }
780     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)
781     {
782         Operator = "Alias";
783     }
784     else if (!CallerOp)
785     {
786         Operator = "ModLevel";
787     }
788     else
789     {
790         Operator = AcpiUtGetTypeName (CallerOp->Asl.Node->Type);
791     }
792
793     FlPrintFile (ASL_FILE_XREF_OUTPUT,
794         "[%5u]     %-40s %-8s via path: %s, Operator: %s\n",
795         Op->Asl.LogicalLineNumber,
796         CallerFullPathname ? CallerFullPathname : "<root>",
797         Operator,
798         Op->Asl.ExternalName,
799         Op->Asl.Parent->Asl.ParseOpName);
800
801     if (!CallerOp)
802     {
803         CallerOp = ACPI_TO_POINTER (0xFFFFFFFF);
804     }
805
806     if (CallerFullPathname)
807     {
808         ACPI_FREE (CallerFullPathname);
809     }
810
811     XrefInfo->CurrentMethodOp = CallerOp;
812     XrefInfo->ThisObjectReferences++;
813     return (AE_OK);
814 }