dmnames.c revision 306536
1/*******************************************************************************
2 *
3 * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
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/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/amlcode.h>
47#include <contrib/dev/acpica/include/acnamesp.h>
48#include <contrib/dev/acpica/include/acdisasm.h>
49
50
51#define _COMPONENT          ACPI_CA_DEBUGGER
52        ACPI_MODULE_NAME    ("dmnames")
53
54/* Local prototypes */
55
56#ifdef ACPI_OBSOLETE_FUNCTIONS
57void
58AcpiDmDisplayPath (
59    ACPI_PARSE_OBJECT       *Op);
60#endif
61
62
63/*******************************************************************************
64 *
65 * FUNCTION:    AcpiDmDumpName
66 *
67 * PARAMETERS:  Name            - 4 character ACPI name
68 *
69 * RETURN:      Final length of name
70 *
71 * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
72 *
73 ******************************************************************************/
74
75UINT32
76AcpiDmDumpName (
77    UINT32                  Name)
78{
79    UINT32                  i;
80    UINT32                  Length;
81    char                    NewName[4];
82
83
84    /* Copy name locally in case the original name is not writeable */
85
86    *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
87
88    /* Ensure that the name is printable, even if we have to fix it */
89
90    AcpiUtRepairName (NewName);
91
92    /* Remove all trailing underscores from the name */
93
94    Length = ACPI_NAME_SIZE;
95    for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
96    {
97        if (NewName[i] == '_')
98        {
99            Length--;
100        }
101        else
102        {
103            break;
104        }
105    }
106
107    /* Dump the name, up to the start of the trailing underscores */
108
109    for (i = 0; i < Length; i++)
110    {
111        AcpiOsPrintf ("%c", NewName[i]);
112    }
113
114    return (Length);
115}
116
117
118/*******************************************************************************
119 *
120 * FUNCTION:    AcpiPsDisplayObjectPathname
121 *
122 * PARAMETERS:  WalkState       - Current walk state
123 *              Op              - Object whose pathname is to be obtained
124 *
125 * RETURN:      Status
126 *
127 * DESCRIPTION: Diplay the pathname associated with a named object. Two
128 *              versions. One searches the parse tree (for parser-only
129 *              applications suchas AcpiDump), and the other searches the
130 *              ACPI namespace (the parse tree is probably deleted)
131 *
132 ******************************************************************************/
133
134ACPI_STATUS
135AcpiPsDisplayObjectPathname (
136    ACPI_WALK_STATE         *WalkState,
137    ACPI_PARSE_OBJECT       *Op)
138{
139    ACPI_STATUS             Status;
140    ACPI_NAMESPACE_NODE     *Node;
141    ACPI_BUFFER             Buffer;
142    UINT32                  DebugLevel;
143
144
145    /* Save current debug level so we don't get extraneous debug output */
146
147    DebugLevel = AcpiDbgLevel;
148    AcpiDbgLevel = 0;
149
150    /* Just get the Node out of the Op object */
151
152    Node = Op->Common.Node;
153    if (!Node)
154    {
155        /* Node not defined in this scope, look it up */
156
157        Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
158            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
159            WalkState, &(Node));
160
161        if (ACPI_FAILURE (Status))
162        {
163            /*
164             * We can't get the pathname since the object is not in the
165             * namespace. This can happen during single stepping
166             * where a dynamic named object is *about* to be created.
167             */
168            AcpiOsPrintf ("  [Path not found]");
169            goto Exit;
170        }
171
172        /* Save it for next time. */
173
174        Op->Common.Node = Node;
175    }
176
177    /* Convert NamedDesc/handle to a full pathname */
178
179    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
180    Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
181    if (ACPI_FAILURE (Status))
182    {
183        AcpiOsPrintf ("****Could not get pathname****)");
184        goto Exit;
185    }
186
187    AcpiOsPrintf ("  (Path %s)", (char *) Buffer.Pointer);
188    ACPI_FREE (Buffer.Pointer);
189
190
191Exit:
192    /* Restore the debug level */
193
194    AcpiDbgLevel = DebugLevel;
195    return (Status);
196}
197
198
199/*******************************************************************************
200 *
201 * FUNCTION:    AcpiDmNamestring
202 *
203 * PARAMETERS:  Name                - ACPI Name string to store
204 *
205 * RETURN:      None
206 *
207 * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
208 *
209 ******************************************************************************/
210
211void
212AcpiDmNamestring (
213    char                    *Name)
214{
215    UINT32                  SegCount;
216
217
218    if (!Name)
219    {
220        return;
221    }
222
223    /* Handle all Scope Prefix operators */
224
225    while (ACPI_IS_ROOT_PREFIX (ACPI_GET8 (Name)) ||
226           ACPI_IS_PARENT_PREFIX (ACPI_GET8 (Name)))
227    {
228        /* Append prefix character */
229
230        AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
231        Name++;
232    }
233
234    switch (ACPI_GET8 (Name))
235    {
236    case 0:
237
238        SegCount = 0;
239        break;
240
241    case AML_DUAL_NAME_PREFIX:
242
243        SegCount = 2;
244        Name++;
245        break;
246
247    case AML_MULTI_NAME_PREFIX_OP:
248
249        SegCount = (UINT32) ACPI_GET8 (Name + 1);
250        Name += 2;
251        break;
252
253    default:
254
255        SegCount = 1;
256        break;
257    }
258
259    while (SegCount)
260    {
261        /* Append Name segment */
262
263        AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
264
265        SegCount--;
266        if (SegCount)
267        {
268            /* Not last name, append dot separator */
269
270            AcpiOsPrintf (".");
271        }
272
273        Name += ACPI_NAME_SIZE;
274    }
275}
276
277
278#ifdef ACPI_OBSOLETE_FUNCTIONS
279/*******************************************************************************
280 *
281 * FUNCTION:    AcpiDmDisplayPath
282 *
283 * PARAMETERS:  Op                  - Named Op whose path is to be constructed
284 *
285 * RETURN:      None
286 *
287 * DESCRIPTION: Walk backwards from current scope and display the name
288 *              of each previous level of scope up to the root scope
289 *              (like "pwd" does with file systems)
290 *
291 ******************************************************************************/
292
293void
294AcpiDmDisplayPath (
295    ACPI_PARSE_OBJECT       *Op)
296{
297    ACPI_PARSE_OBJECT       *Prev;
298    ACPI_PARSE_OBJECT       *Search;
299    UINT32                  Name;
300    BOOLEAN                 DoDot = FALSE;
301    ACPI_PARSE_OBJECT       *NamePath;
302    const ACPI_OPCODE_INFO  *OpInfo;
303
304
305    /* We are only interested in named objects */
306
307    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
308    if (!(OpInfo->Flags & AML_NSNODE))
309    {
310        return;
311    }
312
313    if (OpInfo->Flags & AML_CREATE)
314    {
315        /* Field creation - check for a fully qualified namepath */
316
317        if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
318        {
319            NamePath = AcpiPsGetArg (Op, 3);
320        }
321        else
322        {
323            NamePath = AcpiPsGetArg (Op, 2);
324        }
325
326        if ((NamePath) &&
327            (NamePath->Common.Value.String) &&
328            (ACPI_IS_ROOT_PREFIX (NamePath->Common.Value.String[0])))
329        {
330            AcpiDmNamestring (NamePath->Common.Value.String);
331            return;
332        }
333    }
334
335    Prev = NULL;            /* Start with Root Node */
336    while (Prev != Op)
337    {
338        /* Search upwards in the tree to find scope with "prev" as its parent */
339
340        Search = Op;
341        for (; ;)
342        {
343            if (Search->Common.Parent == Prev)
344            {
345                break;
346            }
347
348            /* Go up one level */
349
350            Search = Search->Common.Parent;
351        }
352
353        if (Prev)
354        {
355            OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
356            if (!(OpInfo->Flags & AML_FIELD))
357            {
358                /* Below root scope, append scope name */
359
360                if (DoDot)
361                {
362                    /* Append dot */
363
364                    AcpiOsPrintf (".");
365                }
366
367                if (OpInfo->Flags & AML_CREATE)
368                {
369                    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
370                    {
371                        NamePath = AcpiPsGetArg (Op, 3);
372                    }
373                    else
374                    {
375                        NamePath = AcpiPsGetArg (Op, 2);
376                    }
377
378                    if ((NamePath) &&
379                        (NamePath->Common.Value.String))
380                    {
381                        AcpiDmDumpName (NamePath->Common.Value.String);
382                    }
383                }
384                else
385                {
386                    Name = AcpiPsGetName (Search);
387                    AcpiDmDumpName ((char *) &Name);
388                }
389
390                DoDot = TRUE;
391            }
392        }
393
394        Prev = Search;
395    }
396}
397
398
399/*******************************************************************************
400 *
401 * FUNCTION:    AcpiDmValidateName
402 *
403 * PARAMETERS:  Name            - 4 character ACPI name
404 *
405 * RETURN:      None
406 *
407 * DESCRIPTION: Lookup the name
408 *
409 ******************************************************************************/
410
411void
412AcpiDmValidateName (
413    char                    *Name,
414    ACPI_PARSE_OBJECT       *Op)
415{
416    ACPI_PARSE_OBJECT       *TargetOp;
417
418
419    if ((!Name) ||
420        (!Op->Common.Parent))
421    {
422        return;
423    }
424
425    if (!Op->Common.Node)
426    {
427        AcpiOsPrintf (
428            " /**** Name not found or not accessible from this scope ****/ ");
429    }
430
431    if ((!Name) ||
432        (!Op->Common.Parent))
433    {
434        return;
435    }
436
437    TargetOp = AcpiPsFind (Op, Name, 0, 0);
438    if (!TargetOp)
439    {
440        /*
441         * Didn't find the name in the parse tree. This may be
442         * a problem, or it may simply be one of the predefined names
443         * (such as _OS_). Rather than worry about looking up all
444         * the predefined names, just display the name as given
445         */
446        AcpiOsPrintf (
447            " /**** Name not found or not accessible from this scope ****/ ");
448    }
449}
450#endif
451