1 /******************************************************************************
3 * Module Name: adisasm - Application-level disassembler routines
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include "aslcompiler.h"
55 #define _COMPONENT ACPI_TOOLS
56 ACPI_MODULE_NAME ("adisasm")
58 /* Local prototypes */
61 AdDoExternalFileList (
65 AdDisassembleOneTable (
66 ACPI_TABLE_HEADER *Table,
69 char *DisasmFilename);
73 ACPI_TABLE_HEADER *Table,
75 ACPI_OWNER_ID OwnerId);
78 ACPI_TABLE_DESC LocalTables[1];
79 ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot;
82 /* Stubs for everything except ASL compiler */
84 #ifndef ACPI_ASL_COMPILER
87 ACPI_PARSE_OBJECT *Op,
88 ACPI_WALK_STATE *WalkState)
96 ACPI_WALK_STATE *WalkState)
103 /*******************************************************************************
105 * FUNCTION: AdInitialize
111 * DESCRIPTION: ACPICA and local initialization
113 ******************************************************************************/
122 /* ACPICA subsystem initialization */
124 Status = AcpiOsInitialize ();
125 if (ACPI_FAILURE (Status))
130 Status = AcpiUtInitGlobals ();
131 if (ACPI_FAILURE (Status))
136 Status = AcpiUtMutexInitialize ();
137 if (ACPI_FAILURE (Status))
142 Status = AcpiNsRootInitialize ();
143 if (ACPI_FAILURE (Status))
148 /* Setup the Table Manager (cheat - there is no RSDT) */
150 AcpiGbl_RootTableList.MaxTableCount = 1;
151 AcpiGbl_RootTableList.CurrentTableCount = 0;
152 AcpiGbl_RootTableList.Tables = LocalTables;
158 /******************************************************************************
160 * FUNCTION: AdAmlDisassemble
162 * PARAMETERS: Filename - AML input filename
163 * OutToFile - TRUE if output should go to a file
164 * Prefix - Path prefix for output
165 * OutFilename - where the filename is returned
169 * DESCRIPTION: Disassembler entry point. Disassemble an entire ACPI table.
171 *****************************************************************************/
181 char *DisasmFilename = NULL;
183 ACPI_TABLE_HEADER *Table = NULL;
184 ACPI_NEW_TABLE_DESC *ListHead = NULL;
188 * Input: AML code from either a file or via GetTables (memory or
193 /* Get the list of all AML tables in the file */
195 Status = AcpiAcGetAllTablesFromFile (Filename,
196 ACPI_GET_ALL_TABLES, &ListHead);
197 if (ACPI_FAILURE (Status))
202 /* Process any user-specified files for external objects */
204 Status = AdDoExternalFileList (Filename);
205 if (ACPI_FAILURE (Status))
212 Status = AdGetLocalTables ();
213 if (ACPI_FAILURE (Status))
215 AcpiOsPrintf ("Could not get ACPI tables, %s\n",
216 AcpiFormatException (Status));
220 if (!AcpiGbl_DmOpt_Disasm)
225 /* Obtained the local tables, just disassemble the DSDT */
227 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
228 if (ACPI_FAILURE (Status))
230 AcpiOsPrintf ("Could not get DSDT, %s\n",
231 AcpiFormatException (Status));
235 AcpiOsPrintf ("\nDisassembly of DSDT\n");
236 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
240 * Output: ASL code. Redirect to a file if requested
244 /* Create/Open a disassembly output file */
246 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
249 fprintf (stderr, "Could not generate output filename\n");
254 File = fopen (DisasmFilename, "w+");
257 fprintf (stderr, "Could not open output file %s\n",
263 AcpiOsRedirectOutput (File);
266 *OutFilename = DisasmFilename;
268 /* Disassemble all AML tables within the file */
272 Status = AdDisassembleOneTable (ListHead->Table,
273 File, Filename, DisasmFilename);
274 if (ACPI_FAILURE (Status))
279 ListHead = ListHead->Next;
286 if (Table && !AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
295 AcpiOsRedirectOutput (stdout);
298 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
299 AcpiGbl_ParseOpRoot = NULL;
304 /******************************************************************************
306 * FUNCTION: AdDisassembleOneTable
308 * PARAMETERS: Table - Raw AML table
309 * File - Pointer for the input file
310 * Filename - AML input filename
311 * DisasmFilename - Output filename
315 * DESCRIPTION: Disassemble a single ACPI table. AML or data table.
317 *****************************************************************************/
320 AdDisassembleOneTable (
321 ACPI_TABLE_HEADER *Table,
324 char *DisasmFilename)
327 ACPI_OWNER_ID OwnerId;
330 /* ForceAmlDisassembly means to assume the table contains valid AML */
332 if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
334 AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
336 /* This is a "Data Table" (non-AML table) */
338 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
340 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] "
341 "FieldName : FieldValue\n */\n\n");
343 AcpiDmDumpDataTable (Table);
344 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
349 fprintf (stderr, "Formatted output: %s - %u bytes\n",
350 DisasmFilename, CmGetFileSize (File));
357 * This is an AML table (DSDT or SSDT).
358 * Always parse the tables, only option is what to display
360 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
361 if (ACPI_FAILURE (Status))
363 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
364 AcpiFormatException (Status));
368 /* Debug output, namespace and parse tree */
370 if (AslCompilerdebug && File)
372 AcpiOsPrintf ("/**** Before second load\n");
374 NsSetupNamespaceListing (File);
375 NsDisplayNamespace ();
377 AcpiOsPrintf ("*****/\n");
380 /* Load namespace from names created within control methods */
382 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
383 AcpiGbl_RootNode, OwnerId);
386 * Cross reference the namespace here, in order to
387 * generate External() statements
389 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
390 AcpiGbl_RootNode, OwnerId);
392 if (AslCompilerdebug)
394 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
397 /* Find possible calls to external control methods */
399 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
402 * If we found any external control methods, we must reparse
403 * the entire tree with the new information (namely, the
404 * number of arguments per method)
406 if (AcpiDmGetExternalMethodCount ())
408 Status = AdReparseOneTable (Table, File, OwnerId);
409 if (ACPI_FAILURE (Status))
416 * Now that the namespace is finalized, we can perform namespace
419 * 1) Convert fixed-offset references to resource descriptors
420 * to symbolic references (Note: modifies namespace)
422 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
424 /* Optional displays */
426 if (AcpiGbl_DmOpt_Disasm)
428 /* This is the real disassembly */
430 AdDisplayTables (Filename, Table);
432 /* Dump hex table if requested (-vt) */
434 AcpiDmDumpDataTable (Table);
436 fprintf (stderr, "Disassembly completed\n");
439 fprintf (stderr, "ASL Output: %s - %u bytes\n",
440 DisasmFilename, CmGetFileSize (File));
445 fprintf (stderr, "%14s %s - %u bytes\n",
446 Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription,
447 Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
448 FlGetFileSize (ASL_FILE_MAP_OUTPUT));
456 /******************************************************************************
458 * FUNCTION: AdReparseOneTable
460 * PARAMETERS: Table - Raw AML table
461 * File - Pointer for the input file
462 * OwnerId - ID for this table
466 * DESCRIPTION: Reparse a table that has already been loaded. Used to
467 * integrate information about external control methods.
468 * These methods may have been previously parsed incorrectly.
470 *****************************************************************************/
474 ACPI_TABLE_HEADER *Table,
476 ACPI_OWNER_ID OwnerId)
482 "\nFound %u external control methods, "
483 "reparsing with new information\n",
484 AcpiDmGetExternalMethodCount ());
486 /* Reparse, rebuild namespace */
488 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
489 AcpiGbl_ParseOpRoot = NULL;
490 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
492 AcpiGbl_RootNode = NULL;
493 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
494 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
495 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE;
496 AcpiGbl_RootNodeStruct.Parent = NULL;
497 AcpiGbl_RootNodeStruct.Child = NULL;
498 AcpiGbl_RootNodeStruct.Peer = NULL;
499 AcpiGbl_RootNodeStruct.Object = NULL;
500 AcpiGbl_RootNodeStruct.Flags = 0;
502 Status = AcpiNsRootInitialize ();
503 if (ACPI_FAILURE (Status))
508 /* New namespace, add the external definitions first */
510 AcpiDmAddExternalsToNamespace ();
512 /* Parse the table again. No need to reload it, however */
514 Status = AdParseTable (Table, NULL, FALSE, FALSE);
515 if (ACPI_FAILURE (Status))
517 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
518 AcpiFormatException (Status));
522 /* Cross reference the namespace again */
524 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
525 AcpiGbl_RootNode, OwnerId);
527 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
528 AcpiGbl_RootNode, OwnerId);
530 /* Debug output - namespace and parse tree */
532 if (AslCompilerdebug)
534 AcpiOsPrintf ("/**** After second load and resource conversion\n");
537 NsSetupNamespaceListing (File);
538 NsDisplayNamespace ();
541 AcpiOsPrintf ("*****/\n");
542 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
549 /******************************************************************************
551 * FUNCTION: AdDoExternalFileList
553 * PARAMETERS: Filename - Input file for the table
557 * DESCRIPTION: Process all tables found in the -e external files list
559 *****************************************************************************/
562 AdDoExternalFileList (
565 ACPI_EXTERNAL_FILE *ExternalFileList;
566 char *ExternalFilename;
567 ACPI_NEW_TABLE_DESC *ExternalListHead = NULL;
569 ACPI_STATUS GlobalStatus = AE_OK;
570 ACPI_OWNER_ID OwnerId;
574 * External filenames are specified on the command line like this:
575 * Example: iasl -e file1,file2,file3 -d xxx.aml
577 ExternalFileList = AcpiGbl_ExternalFileList;
579 /* Process each external file */
581 while (ExternalFileList)
583 ExternalFilename = ExternalFileList->Path;
584 if (!strcmp (ExternalFilename, Filename))
586 /* Next external file */
588 ExternalFileList = ExternalFileList->Next;
592 AcpiOsPrintf ("External object resolution file %16s\n",
595 Status = AcpiAcGetAllTablesFromFile (
596 ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead);
597 if (ACPI_FAILURE (Status))
599 if (Status == AE_TYPE)
601 ExternalFileList = ExternalFileList->Next;
602 GlobalStatus = AE_TYPE;
610 /* Load external tables for symbol resolution */
612 while (ExternalListHead)
614 Status = AdParseTable (
615 ExternalListHead->Table, &OwnerId, TRUE, TRUE);
616 if (ACPI_FAILURE (Status))
618 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
619 AcpiFormatException (Status));
624 * Load namespace from names created within control methods
625 * Set owner id of nodes in external table
627 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
628 AcpiGbl_RootNode, OwnerId);
629 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
631 ExternalListHead = ExternalListHead->Next;
634 /* Next external file */
636 ExternalFileList = ExternalFileList->Next;
639 if (ACPI_FAILURE (GlobalStatus))
641 return (GlobalStatus);
644 /* Clear external list generated by Scope in external tables */
646 if (AcpiGbl_ExternalFileList)
648 AcpiDmClearExternalList ();
651 /* Load any externals defined in the optional external ref file */
653 AcpiDmGetExternalsFromFile ();