1/****************************************************************************** 2 * 3 * Module Name: adisasm - Application-level disassembler routines 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#include "aslcompiler.h" 117#include "amlcode.h" 118#include "acdisasm.h" 119#include "acdispat.h" 120#include "acnamesp.h" 121#include "acparser.h" 122#include "acapps.h" 123 124#include <stdio.h> 125 126 127#define _COMPONENT ACPI_TOOLS 128 ACPI_MODULE_NAME ("adisasm") 129 130/* Local prototypes */ 131 132static ACPI_STATUS 133AdDoExternalFileList ( 134 char *Filename); 135 136static ACPI_STATUS 137AdDisassembleOneTable ( 138 ACPI_TABLE_HEADER *Table, 139 FILE *File, 140 char *Filename, 141 char *DisasmFilename); 142 143static ACPI_STATUS 144AdReparseOneTable ( 145 ACPI_TABLE_HEADER *Table, 146 FILE *File, 147 ACPI_OWNER_ID OwnerId); 148 149 150ACPI_TABLE_DESC LocalTables[1]; 151ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 152 153 154/* Stubs for everything except ASL compiler */ 155 156#ifndef ACPI_ASL_COMPILER 157BOOLEAN 158AcpiDsIsResultUsed ( 159 ACPI_PARSE_OBJECT *Op, 160 ACPI_WALK_STATE *WalkState) 161{ 162 return (TRUE); 163} 164 165ACPI_STATUS 166AcpiDsMethodError ( 167 ACPI_STATUS Status, 168 ACPI_WALK_STATE *WalkState) 169{ 170 return (Status); 171} 172#endif 173 174 175/******************************************************************************* 176 * 177 * FUNCTION: AdInitialize 178 * 179 * PARAMETERS: None 180 * 181 * RETURN: Status 182 * 183 * DESCRIPTION: ACPICA and local initialization 184 * 185 ******************************************************************************/ 186 187ACPI_STATUS 188AdInitialize ( 189 void) 190{ 191 ACPI_STATUS Status; 192 193 194 /* ACPICA subsystem initialization */ 195 196 Status = AcpiOsInitialize (); 197 if (ACPI_FAILURE (Status)) 198 { 199 return (Status); 200 } 201 202 Status = AcpiUtInitGlobals (); 203 if (ACPI_FAILURE (Status)) 204 { 205 return (Status); 206 } 207 208 Status = AcpiUtMutexInitialize (); 209 if (ACPI_FAILURE (Status)) 210 { 211 return (Status); 212 } 213 214 Status = AcpiNsRootInitialize (); 215 if (ACPI_FAILURE (Status)) 216 { 217 return (Status); 218 } 219 220 /* Setup the Table Manager (cheat - there is no RSDT) */ 221 222 AcpiGbl_RootTableList.MaxTableCount = 1; 223 AcpiGbl_RootTableList.CurrentTableCount = 0; 224 AcpiGbl_RootTableList.Tables = LocalTables; 225 226 return (Status); 227} 228 229 230/****************************************************************************** 231 * 232 * FUNCTION: AdAmlDisassemble 233 * 234 * PARAMETERS: Filename - AML input filename 235 * OutToFile - TRUE if output should go to a file 236 * Prefix - Path prefix for output 237 * OutFilename - where the filename is returned 238 * 239 * RETURN: Status 240 * 241 * DESCRIPTION: Disassembler entry point. Disassemble an entire ACPI table. 242 * 243 *****************************************************************************/ 244 245ACPI_STATUS 246AdAmlDisassemble ( 247 BOOLEAN OutToFile, 248 char *Filename, 249 char *Prefix, 250 char **OutFilename) 251{ 252 ACPI_STATUS Status; 253 char *DisasmFilename = NULL; 254 FILE *File = NULL; 255 ACPI_TABLE_HEADER *Table = NULL; 256 ACPI_NEW_TABLE_DESC *ListHead = NULL; 257 258 259 /* 260 * Input: AML code from either a file or via GetTables (memory or 261 * registry) 262 */ 263 if (Filename) 264 { 265 /* Get the list of all AML tables in the file */ 266 267 Status = AcGetAllTablesFromFile (Filename, 268 ACPI_GET_ALL_TABLES, &ListHead); 269 if (ACPI_FAILURE (Status)) 270 { 271 AcpiOsPrintf ("Could not get ACPI tables from %s, %s\n", 272 Filename, AcpiFormatException (Status)); 273 return (Status); 274 } 275 276 /* Process any user-specified files for external objects */ 277 278 Status = AdDoExternalFileList (Filename); 279 if (ACPI_FAILURE (Status)) 280 { 281 return (Status); 282 } 283 } 284 else 285 { 286 Status = AdGetLocalTables (); 287 if (ACPI_FAILURE (Status)) 288 { 289 AcpiOsPrintf ("Could not get ACPI tables, %s\n", 290 AcpiFormatException (Status)); 291 return (Status); 292 } 293 294 if (!AcpiGbl_DmOpt_Disasm) 295 { 296 return (AE_OK); 297 } 298 299 /* Obtained the local tables, just disassemble the DSDT */ 300 301 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table); 302 if (ACPI_FAILURE (Status)) 303 { 304 AcpiOsPrintf ("Could not get DSDT, %s\n", 305 AcpiFormatException (Status)); 306 return (Status); 307 } 308 309 AcpiOsPrintf ("\nDisassembly of DSDT\n"); 310 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId); 311 } 312 313 /* 314 * Output: ASL code. Redirect to a file if requested 315 */ 316 if (OutToFile) 317 { 318 /* Create/Open a disassembly output file */ 319 320 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY); 321 if (!DisasmFilename) 322 { 323 fprintf (stderr, "Could not generate output filename\n"); 324 Status = AE_ERROR; 325 goto Cleanup; 326 } 327 328 File = fopen (DisasmFilename, "w+"); 329 if (!File) 330 { 331 fprintf (stderr, "Could not open output file %s\n", 332 DisasmFilename); 333 Status = AE_ERROR; 334 goto Cleanup; 335 } 336 337 AcpiOsRedirectOutput (File); 338 } 339 340 *OutFilename = DisasmFilename; 341 342 /* Disassemble all AML tables within the file */ 343 344 while (ListHead) 345 { 346 Status = AdDisassembleOneTable (ListHead->Table, 347 File, Filename, DisasmFilename); 348 if (ACPI_FAILURE (Status)) 349 { 350 break; 351 } 352 353 ListHead = ListHead->Next; 354 } 355 356Cleanup: 357 358 if (Table && 359 !AcpiGbl_ForceAmlDisassembly && 360 !AcpiUtIsAmlTable (Table)) 361 { 362 ACPI_FREE (Table); 363 } 364 365 if (File) 366 { 367 fclose (File); 368 AcpiOsRedirectOutput (stdout); 369 } 370 371 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 372 AcpiGbl_ParseOpRoot = NULL; 373 return (Status); 374} 375 376 377/****************************************************************************** 378 * 379 * FUNCTION: AdDisassembleOneTable 380 * 381 * PARAMETERS: Table - Raw AML table 382 * File - Pointer for the input file 383 * Filename - AML input filename 384 * DisasmFilename - Output filename 385 * 386 * RETURN: Status 387 * 388 * DESCRIPTION: Disassemble a single ACPI table. AML or data table. 389 * 390 *****************************************************************************/ 391 392static ACPI_STATUS 393AdDisassembleOneTable ( 394 ACPI_TABLE_HEADER *Table, 395 FILE *File, 396 char *Filename, 397 char *DisasmFilename) 398{ 399 ACPI_STATUS Status; 400 ACPI_OWNER_ID OwnerId; 401 402 403 /* ForceAmlDisassembly means to assume the table contains valid AML */ 404 405 if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table)) 406 { 407 AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE); 408 409 /* This is a "Data Table" (non-AML table) */ 410 411 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", 412 Table->Signature); 413 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] " 414 "FieldName : FieldValue\n */\n\n"); 415 416 AcpiDmDumpDataTable (Table); 417 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n", 418 Table->Signature); 419 420 if (File) 421 { 422 fprintf (stderr, "Formatted output: %s - %u bytes\n", 423 DisasmFilename, CmGetFileSize (File)); 424 } 425 426 return (AE_OK); 427 } 428 429 /* 430 * This is an AML table (DSDT or SSDT). 431 * Always parse the tables, only option is what to display 432 */ 433 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); 434 if (ACPI_FAILURE (Status)) 435 { 436 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 437 AcpiFormatException (Status)); 438 return (Status); 439 } 440 441 /* Debug output, namespace and parse tree */ 442 443 if (AslCompilerdebug && File) 444 { 445 AcpiOsPrintf ("/**** Before second load\n"); 446 447 NsSetupNamespaceListing (File); 448 NsDisplayNamespace (); 449 450 AcpiOsPrintf ("*****/\n"); 451 } 452 453 /* Load namespace from names created within control methods */ 454 455 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 456 AcpiGbl_RootNode, OwnerId); 457 458 /* 459 * Cross reference the namespace here, in order to 460 * generate External() statements 461 */ 462 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 463 AcpiGbl_RootNode, OwnerId); 464 465 if (AslCompilerdebug) 466 { 467 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 468 } 469 470 /* Find possible calls to external control methods */ 471 472 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); 473 474 /* 475 * If we found any external control methods, we must reparse 476 * the entire tree with the new information (namely, the 477 * number of arguments per method) 478 */ 479 if (AcpiDmGetExternalMethodCount ()) 480 { 481 Status = AdReparseOneTable (Table, File, OwnerId); 482 if (ACPI_FAILURE (Status)) 483 { 484 return (Status); 485 } 486 } 487 488 /* 489 * Now that the namespace is finalized, we can perform namespace 490 * transforms. 491 * 492 * 1) Convert fixed-offset references to resource descriptors 493 * to symbolic references (Note: modifies namespace) 494 */ 495 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); 496 497 /* Optional displays */ 498 499 if (AcpiGbl_DmOpt_Disasm) 500 { 501 /* This is the real disassembly */ 502 503 AdDisplayTables (Filename, Table); 504 505 /* Dump hex table if requested (-vt) */ 506 507 AcpiDmDumpDataTable (Table); 508 509 fprintf (stderr, "Disassembly completed\n"); 510 if (File) 511 { 512 fprintf (stderr, "ASL Output: %s - %u bytes\n", 513 DisasmFilename, CmGetFileSize (File)); 514 } 515 516 if (Gbl_MapfileFlag) 517 { 518 fprintf (stderr, "%14s %s - %u bytes\n", 519 Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription, 520 Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename, 521 FlGetFileSize (ASL_FILE_MAP_OUTPUT)); 522 } 523 } 524 525 return (AE_OK); 526} 527 528 529/****************************************************************************** 530 * 531 * FUNCTION: AdReparseOneTable 532 * 533 * PARAMETERS: Table - Raw AML table 534 * File - Pointer for the input file 535 * OwnerId - ID for this table 536 * 537 * RETURN: Status 538 * 539 * DESCRIPTION: Reparse a table that has already been loaded. Used to 540 * integrate information about external control methods. 541 * These methods may have been previously parsed incorrectly. 542 * 543 *****************************************************************************/ 544 545static ACPI_STATUS 546AdReparseOneTable ( 547 ACPI_TABLE_HEADER *Table, 548 FILE *File, 549 ACPI_OWNER_ID OwnerId) 550{ 551 ACPI_STATUS Status; 552 553 554 fprintf (stderr, 555 "\nFound %u external control methods, " 556 "reparsing with new information\n", 557 AcpiDmGetExternalMethodCount ()); 558 559 /* Reparse, rebuild namespace */ 560 561 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 562 AcpiGbl_ParseOpRoot = NULL; 563 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 564 565 AcpiGbl_RootNode = NULL; 566 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; 567 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; 568 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; 569 AcpiGbl_RootNodeStruct.Parent = NULL; 570 AcpiGbl_RootNodeStruct.Child = NULL; 571 AcpiGbl_RootNodeStruct.Peer = NULL; 572 AcpiGbl_RootNodeStruct.Object = NULL; 573 AcpiGbl_RootNodeStruct.Flags = 0; 574 575 Status = AcpiNsRootInitialize (); 576 if (ACPI_FAILURE (Status)) 577 { 578 return (Status); 579 } 580 581 /* New namespace, add the external definitions first */ 582 583 AcpiDmAddExternalsToNamespace (); 584 585 /* Parse the table again. No need to reload it, however */ 586 587 Status = AdParseTable (Table, NULL, FALSE, FALSE); 588 if (ACPI_FAILURE (Status)) 589 { 590 AcpiOsPrintf ("Could not parse ACPI tables, %s\n", 591 AcpiFormatException (Status)); 592 return (Status); 593 } 594 595 /* Cross reference the namespace again */ 596 597 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 598 AcpiGbl_RootNode, OwnerId); 599 600 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, 601 AcpiGbl_RootNode, OwnerId); 602 603 /* Debug output - namespace and parse tree */ 604 605 if (AslCompilerdebug) 606 { 607 AcpiOsPrintf ("/**** After second load and resource conversion\n"); 608 if (File) 609 { 610 NsSetupNamespaceListing (File); 611 NsDisplayNamespace (); 612 } 613 614 AcpiOsPrintf ("*****/\n"); 615 AcpiDmDumpTree (AcpiGbl_ParseOpRoot); 616 } 617 618 return (AE_OK); 619} 620 621 622/****************************************************************************** 623 * 624 * FUNCTION: AdDoExternalFileList 625 * 626 * PARAMETERS: Filename - Input file for the table 627 * 628 * RETURN: Status 629 * 630 * DESCRIPTION: Process all tables found in the -e external files list 631 * 632 *****************************************************************************/ 633 634static ACPI_STATUS 635AdDoExternalFileList ( 636 char *Filename) 637{ 638 ACPI_EXTERNAL_FILE *ExternalFileList; 639 char *ExternalFilename; 640 ACPI_NEW_TABLE_DESC *ExternalListHead = NULL; 641 ACPI_STATUS Status; 642 ACPI_STATUS GlobalStatus = AE_OK; 643 ACPI_OWNER_ID OwnerId; 644 645 646 /* 647 * External filenames are specified on the command line like this: 648 * Example: iasl -e file1,file2,file3 -d xxx.aml 649 */ 650 ExternalFileList = AcpiGbl_ExternalFileList; 651 652 /* Process each external file */ 653 654 while (ExternalFileList) 655 { 656 ExternalFilename = ExternalFileList->Path; 657 if (!strcmp (ExternalFilename, Filename)) 658 { 659 /* Next external file */ 660 661 ExternalFileList = ExternalFileList->Next; 662 continue; 663 } 664 665 AcpiOsPrintf ("External object resolution file %16s\n", 666 ExternalFilename); 667 668 Status = AcGetAllTablesFromFile ( 669 ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead); 670 if (ACPI_FAILURE (Status)) 671 { 672 if (Status == AE_TYPE) 673 { 674 ExternalFileList = ExternalFileList->Next; 675 GlobalStatus = AE_TYPE; 676 Status = AE_OK; 677 continue; 678 } 679 680 return (Status); 681 } 682 683 /* Load external tables for symbol resolution */ 684 685 while (ExternalListHead) 686 { 687 Status = AdParseTable ( 688 ExternalListHead->Table, &OwnerId, TRUE, TRUE); 689 if (ACPI_FAILURE (Status)) 690 { 691 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n", 692 AcpiFormatException (Status)); 693 return (Status); 694 } 695 696 /* 697 * Load namespace from names created within control methods 698 * Set owner id of nodes in external table 699 */ 700 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, 701 AcpiGbl_RootNode, OwnerId); 702 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); 703 704 ExternalListHead = ExternalListHead->Next; 705 } 706 707 /* Next external file */ 708 709 ExternalFileList = ExternalFileList->Next; 710 } 711 712 if (ACPI_FAILURE (GlobalStatus)) 713 { 714 return (GlobalStatus); 715 } 716 717 /* Clear external list generated by Scope in external tables */ 718 719 if (AcpiGbl_ExternalFileList) 720 { 721 AcpiDmClearExternalList (); 722 } 723 724 /* Load any externals defined in the optional external ref file */ 725 726 AcpiDmGetExternalsFromFile (); 727 return (AE_OK); 728} 729