1 /****************************************************************************** 2 * 3 * Module Name: acpixtract - convert ascii ACPI tables to binary 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2017, 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 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include "acpixtract.h" 153 154 155 /* Local prototypes */ 156 157 static BOOLEAN 158 AxIsFileAscii ( 159 FILE *Handle); 160 161 162 /****************************************************************************** 163 * 164 * FUNCTION: AxExtractTables 165 * 166 * PARAMETERS: InputPathname - Filename for input acpidump file 167 * Signature - Requested ACPI signature to extract. 168 * NULL means extract ALL tables. 169 * MinimumInstances - Min instances that are acceptable 170 * 171 * RETURN: Status 172 * 173 * DESCRIPTION: Convert text ACPI tables to binary 174 * 175 ******************************************************************************/ 176 177 int 178 AxExtractTables ( 179 char *InputPathname, 180 char *Signature, 181 unsigned int MinimumInstances) 182 { 183 FILE *InputFile; 184 FILE *OutputFile = NULL; 185 unsigned int BytesConverted; 186 unsigned int ThisTableBytesWritten = 0; 187 unsigned int FoundTable = 0; 188 unsigned int Instances = 0; 189 unsigned int ThisInstance; 190 char ThisSignature[5]; 191 char UpperSignature[5]; 192 int Status = 0; 193 unsigned int State = AX_STATE_FIND_HEADER; 194 195 196 /* Open input in text mode, output is in binary mode */ 197 198 InputFile = fopen (InputPathname, "r"); 199 if (!InputFile) 200 { 201 printf ("Could not open input file %s\n", InputPathname); 202 return (-1); 203 } 204 205 if (!AxIsFileAscii (InputFile)) 206 { 207 fclose (InputFile); 208 return (-1); 209 } 210 211 if (Signature) 212 { 213 strncpy (UpperSignature, Signature, 4); 214 UpperSignature[4] = 0; 215 AcpiUtStrupr (UpperSignature); 216 217 /* Are there enough instances of the table to continue? */ 218 219 AxNormalizeSignature (UpperSignature); 220 221 Instances = AxCountTableInstances (InputPathname, UpperSignature); 222 if (Instances < MinimumInstances) 223 { 224 printf ("Table [%s] was not found in %s\n", 225 UpperSignature, InputPathname); 226 fclose (InputFile); 227 return (-1); 228 } 229 230 if (Instances == 0) 231 { 232 fclose (InputFile); 233 return (-1); 234 } 235 } 236 237 /* Convert all instances of the table to binary */ 238 239 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) 240 { 241 switch (State) 242 { 243 case AX_STATE_FIND_HEADER: 244 245 if (!AxIsDataBlockHeader ()) 246 { 247 continue; 248 } 249 250 ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer); 251 if (Signature) 252 { 253 /* Ignore signatures that don't match */ 254 255 if (!ACPI_COMPARE_NAME (ThisSignature, UpperSignature)) 256 { 257 continue; 258 } 259 } 260 261 /* 262 * Get the instance number for this signature. Only the 263 * SSDT and PSDT tables can have multiple instances. 264 */ 265 ThisInstance = AxGetNextInstance (InputPathname, ThisSignature); 266 267 /* Build an output filename and create/open the output file */ 268 269 if (ThisInstance > 0) 270 { 271 /* Add instance number to the output filename */ 272 273 sprintf (Gbl_OutputFilename, "%4.4s%u.dat", 274 ThisSignature, ThisInstance); 275 } 276 else 277 { 278 sprintf (Gbl_OutputFilename, "%4.4s.dat", 279 ThisSignature); 280 } 281 282 AcpiUtStrlwr (Gbl_OutputFilename); 283 OutputFile = fopen (Gbl_OutputFilename, "w+b"); 284 if (!OutputFile) 285 { 286 printf ("Could not open output file %s\n", 287 Gbl_OutputFilename); 288 fclose (InputFile); 289 return (-1); 290 } 291 292 /* 293 * Toss this block header of the form "<sig> @ <addr>" line 294 * and move on to the actual data block 295 */ 296 Gbl_TableCount++; 297 FoundTable = 1; 298 ThisTableBytesWritten = 0; 299 State = AX_STATE_EXTRACT_DATA; 300 continue; 301 302 case AX_STATE_EXTRACT_DATA: 303 304 /* Empty line or non-data line terminates the data block */ 305 306 BytesConverted = AxProcessOneTextLine ( 307 OutputFile, ThisSignature, ThisTableBytesWritten); 308 switch (BytesConverted) 309 { 310 case 0: 311 312 State = AX_STATE_FIND_HEADER; /* No more data block lines */ 313 continue; 314 315 case -1: 316 317 goto CleanupAndExit; /* There was a write error */ 318 319 default: /* Normal case, get next line */ 320 321 ThisTableBytesWritten += BytesConverted; 322 continue; 323 } 324 325 default: 326 327 Status = -1; 328 goto CleanupAndExit; 329 } 330 } 331 332 if (!FoundTable) 333 { 334 printf ("No ACPI tables were found in %s\n", InputPathname); 335 } 336 337 338 CleanupAndExit: 339 340 if (State == AX_STATE_EXTRACT_DATA) 341 { 342 /* Received an input file EOF while extracting data */ 343 344 printf (AX_TABLE_INFO_FORMAT, 345 ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename); 346 } 347 348 if (Gbl_TableCount > 1) 349 { 350 printf ("\n%u binary ACPI tables extracted\n", 351 Gbl_TableCount); 352 } 353 354 if (OutputFile) 355 { 356 fclose (OutputFile); 357 } 358 359 fclose (InputFile); 360 return (Status); 361 } 362 363 364 /****************************************************************************** 365 * 366 * FUNCTION: AxExtractToMultiAmlFile 367 * 368 * PARAMETERS: InputPathname - Filename for input acpidump file 369 * 370 * RETURN: Status 371 * 372 * DESCRIPTION: Convert all DSDT/SSDT tables to binary and append them all 373 * into a single output file. Used to simplify the loading of 374 * multiple/many SSDTs into a utility like acpiexec -- instead 375 * of creating many separate output files. 376 * 377 ******************************************************************************/ 378 379 int 380 AxExtractToMultiAmlFile ( 381 char *InputPathname) 382 { 383 FILE *InputFile; 384 FILE *OutputFile; 385 int Status = 0; 386 unsigned int TotalBytesWritten = 0; 387 unsigned int ThisTableBytesWritten = 0; 388 unsigned int BytesConverted; 389 char ThisSignature[4]; 390 unsigned int State = AX_STATE_FIND_HEADER; 391 392 393 strcpy (Gbl_OutputFilename, AX_MULTI_TABLE_FILENAME); 394 395 /* Open the input file in text mode */ 396 397 InputFile = fopen (InputPathname, "r"); 398 if (!InputFile) 399 { 400 printf ("Could not open input file %s\n", InputPathname); 401 return (-1); 402 } 403 404 if (!AxIsFileAscii (InputFile)) 405 { 406 fclose (InputFile); 407 return (-1); 408 } 409 410 /* Open the output file in binary mode */ 411 412 OutputFile = fopen (Gbl_OutputFilename, "w+b"); 413 if (!OutputFile) 414 { 415 printf ("Could not open output file %s\n", Gbl_OutputFilename); 416 fclose (InputFile); 417 return (-1); 418 } 419 420 /* Convert the DSDT and all SSDTs to binary */ 421 422 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) 423 { 424 switch (State) 425 { 426 case AX_STATE_FIND_HEADER: 427 428 if (!AxIsDataBlockHeader ()) 429 { 430 continue; 431 } 432 433 ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer); 434 435 /* Only want DSDT and SSDTs */ 436 437 if (!ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_DSDT) && 438 !ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_SSDT)) 439 { 440 continue; 441 } 442 443 /* 444 * Toss this block header of the form "<sig> @ <addr>" line 445 * and move on to the actual data block 446 */ 447 Gbl_TableCount++; 448 ThisTableBytesWritten = 0; 449 State = AX_STATE_EXTRACT_DATA; 450 continue; 451 452 case AX_STATE_EXTRACT_DATA: 453 454 /* Empty line or non-data line terminates the data block */ 455 456 BytesConverted = AxProcessOneTextLine ( 457 OutputFile, ThisSignature, ThisTableBytesWritten); 458 switch (BytesConverted) 459 { 460 case 0: 461 462 State = AX_STATE_FIND_HEADER; /* No more data block lines */ 463 continue; 464 465 case -1: 466 467 goto CleanupAndExit; /* There was a write error */ 468 469 default: /* Normal case, get next line */ 470 471 ThisTableBytesWritten += BytesConverted; 472 TotalBytesWritten += BytesConverted; 473 continue; 474 } 475 476 default: 477 478 Status = -1; 479 goto CleanupAndExit; 480 } 481 } 482 483 484 CleanupAndExit: 485 486 if (State == AX_STATE_EXTRACT_DATA) 487 { 488 /* Received an input file EOF or error while writing data */ 489 490 printf (AX_TABLE_INFO_FORMAT, 491 ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename); 492 } 493 494 printf ("\n%u binary ACPI tables extracted and written to %s (%u bytes)\n", 495 Gbl_TableCount, Gbl_OutputFilename, TotalBytesWritten); 496 497 fclose (InputFile); 498 fclose (OutputFile); 499 return (Status); 500 } 501 502 503 /****************************************************************************** 504 * 505 * FUNCTION: AxListTables 506 * 507 * PARAMETERS: InputPathname - Filename for acpidump file 508 * 509 * RETURN: Status 510 * 511 * DESCRIPTION: Display info for all ACPI tables found in input. Does not 512 * perform an actual extraction of the tables. 513 * 514 ******************************************************************************/ 515 516 int 517 AxListTables ( 518 char *InputPathname) 519 { 520 FILE *InputFile; 521 size_t HeaderSize; 522 unsigned char Header[48]; 523 ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) (void *) Header; 524 525 526 /* Open input in text mode, output is in binary mode */ 527 528 InputFile = fopen (InputPathname, "r"); 529 if (!InputFile) 530 { 531 printf ("Could not open input file %s\n", InputPathname); 532 return (-1); 533 } 534 535 if (!AxIsFileAscii (InputFile)) 536 { 537 fclose (InputFile); 538 return (-1); 539 } 540 541 /* Dump the headers for all tables found in the input file */ 542 543 printf ("\nSignature Length Revision OemId OemTableId" 544 " OemRevision CompilerId CompilerRevision\n\n"); 545 546 while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) 547 { 548 /* Ignore empty lines and lines that start with a space */ 549 550 if (AxIsEmptyLine (Gbl_LineBuffer) || 551 (Gbl_LineBuffer[0] == ' ')) 552 { 553 continue; 554 } 555 556 /* Get the 36 byte header and display the fields */ 557 558 HeaderSize = AxGetTableHeader (InputFile, Header); 559 if (HeaderSize < 16) 560 { 561 continue; 562 } 563 564 /* RSDP has an oddball signature and header */ 565 566 if (!strncmp (TableHeader->Signature, "RSD PTR ", 8)) 567 { 568 AxCheckAscii ((char *) &Header[9], 6); 569 printf ("%7.4s \"%6.6s\"\n", "RSDP", 570 &Header[9]); 571 Gbl_TableCount++; 572 continue; 573 } 574 575 /* Minimum size for table with standard header */ 576 577 if (HeaderSize < sizeof (ACPI_TABLE_HEADER)) 578 { 579 continue; 580 } 581 582 if (!AcpiUtValidNameseg (TableHeader->Signature)) 583 { 584 continue; 585 } 586 587 /* Signature and Table length */ 588 589 Gbl_TableCount++; 590 printf ("%7.4s 0x%8.8X", TableHeader->Signature, 591 TableHeader->Length); 592 593 /* FACS has only signature and length */ 594 595 if (ACPI_COMPARE_NAME (TableHeader->Signature, "FACS")) 596 { 597 printf ("\n"); 598 continue; 599 } 600 601 /* OEM IDs and Compiler IDs */ 602 603 AxCheckAscii (TableHeader->OemId, 6); 604 AxCheckAscii (TableHeader->OemTableId, 8); 605 AxCheckAscii (TableHeader->AslCompilerId, 4); 606 607 printf ( 608 " 0x%2.2X \"%6.6s\" \"%8.8s\" 0x%8.8X" 609 " \"%4.4s\" 0x%8.8X\n", 610 TableHeader->Revision, TableHeader->OemId, 611 TableHeader->OemTableId, TableHeader->OemRevision, 612 TableHeader->AslCompilerId, TableHeader->AslCompilerRevision); 613 } 614 615 printf ("\nFound %u ACPI tables in %s\n", Gbl_TableCount, InputPathname); 616 fclose (InputFile); 617 return (0); 618 } 619 620 621 /******************************************************************************* 622 * 623 * FUNCTION: AxIsFileAscii 624 * 625 * PARAMETERS: Handle - To open input file 626 * 627 * RETURN: TRUE if file is entirely ASCII and printable 628 * 629 * DESCRIPTION: Verify that the input file is entirely ASCII. 630 * 631 ******************************************************************************/ 632 633 static BOOLEAN 634 AxIsFileAscii ( 635 FILE *Handle) 636 { 637 UINT8 Byte; 638 639 640 /* Read the entire file */ 641 642 while (fread (&Byte, 1, 1, Handle) == 1) 643 { 644 /* Check for an ASCII character */ 645 646 if (!ACPI_IS_ASCII (Byte)) 647 { 648 goto ErrorExit; 649 } 650 651 /* Ensure character is either printable or a "space" char */ 652 653 else if (!isprint (Byte) && !isspace (Byte)) 654 { 655 goto ErrorExit; 656 } 657 } 658 659 /* File is OK (100% ASCII) */ 660 661 fseek (Handle, 0, SEEK_SET); 662 return (TRUE); 663 664 ErrorExit: 665 666 printf ("File is binary (contains non-text or non-ascii characters)\n"); 667 fseek (Handle, 0, SEEK_SET); 668 return (FALSE); 669 670 } 671