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