Home | History | Annotate | Line # | Download | only in acpixtract
acpixtract.c revision 1.6
      1 /******************************************************************************
      2  *
      3  * Module Name: acpixtract - convert ascii ACPI tables to binary
      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 "acpixtract.h"
     45 
     46 
     47 /******************************************************************************
     48  *
     49  * FUNCTION:    AxExtractTables
     50  *
     51  * PARAMETERS:  InputPathname       - Filename for input acpidump file
     52  *              Signature           - Requested ACPI signature to extract.
     53  *                                    NULL means extract ALL tables.
     54  *              MinimumInstances    - Min instances that are acceptable
     55  *
     56  * RETURN:      Status
     57  *
     58  * DESCRIPTION: Convert text ACPI tables to binary
     59  *
     60  ******************************************************************************/
     61 
     62 int
     63 AxExtractTables (
     64     char                    *InputPathname,
     65     char                    *Signature,
     66     unsigned int            MinimumInstances)
     67 {
     68     FILE                    *InputFile;
     69     FILE                    *OutputFile = NULL;
     70     unsigned int            BytesConverted;
     71     unsigned int            ThisTableBytesWritten = 0;
     72     unsigned int            FoundTable = 0;
     73     unsigned int            Instances = 0;
     74     unsigned int            ThisInstance;
     75     char                    ThisSignature[4];
     76     int                     Status = 0;
     77     unsigned int            State = AX_STATE_FIND_HEADER;
     78 
     79 
     80     /* Open input in text mode, output is in binary mode */
     81 
     82     InputFile = fopen (InputPathname, "rt");
     83     if (!InputFile)
     84     {
     85         printf ("Could not open input file %s\n", InputPathname);
     86         return (-1);
     87     }
     88 
     89     if (Signature)
     90     {
     91         /* Are there enough instances of the table to continue? */
     92 
     93         AxNormalizeSignature (Signature);
     94 
     95         Instances = AxCountTableInstances (InputPathname, Signature);
     96         if (Instances < MinimumInstances)
     97         {
     98             printf ("Table [%s] was not found in %s\n",
     99                 Signature, InputPathname);
    100             fclose (InputFile);
    101             return (-1);
    102         }
    103 
    104         if (Instances == 0)
    105         {
    106             fclose (InputFile);
    107             return (-1);
    108         }
    109     }
    110 
    111     /* Convert all instances of the table to binary */
    112 
    113     while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
    114     {
    115         switch (State)
    116         {
    117         case AX_STATE_FIND_HEADER:
    118 
    119             if (!AxIsDataBlockHeader ())
    120             {
    121                 continue;
    122             }
    123 
    124             ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer);
    125             if (Signature)
    126             {
    127                 /* Ignore signatures that don't match */
    128 
    129                 if (!ACPI_COMPARE_NAME (ThisSignature, Signature))
    130                 {
    131                     continue;
    132                 }
    133             }
    134 
    135             /*
    136              * Get the instance number for this signature. Only the
    137              * SSDT and PSDT tables can have multiple instances.
    138              */
    139             ThisInstance = AxGetNextInstance (InputPathname, ThisSignature);
    140 
    141             /* Build an output filename and create/open the output file */
    142 
    143             if (ThisInstance > 0)
    144             {
    145                 /* Add instance number to the output filename */
    146 
    147                 sprintf (Gbl_OutputFilename, "%4.4s%u.dat",
    148                     ThisSignature, ThisInstance);
    149             }
    150             else
    151             {
    152                 sprintf (Gbl_OutputFilename, "%4.4s.dat",
    153                     ThisSignature);
    154             }
    155 
    156             AcpiUtStrlwr (Gbl_OutputFilename);
    157             OutputFile = fopen (Gbl_OutputFilename, "w+b");
    158             if (!OutputFile)
    159             {
    160                 printf ("Could not open output file %s\n",
    161                     Gbl_OutputFilename);
    162                 fclose (InputFile);
    163                 return (-1);
    164             }
    165 
    166             /*
    167              * Toss this block header of the form "<sig> @ <addr>" line
    168              * and move on to the actual data block
    169              */
    170             Gbl_TableCount++;
    171             FoundTable = 1;
    172             ThisTableBytesWritten = 0;
    173             State = AX_STATE_EXTRACT_DATA;
    174             continue;
    175 
    176         case AX_STATE_EXTRACT_DATA:
    177 
    178             /* Empty line or non-data line terminates the data block */
    179 
    180             BytesConverted = AxProcessOneTextLine (
    181                 OutputFile, ThisSignature, ThisTableBytesWritten);
    182             switch (BytesConverted)
    183             {
    184             case 0:
    185 
    186                 State = AX_STATE_FIND_HEADER; /* No more data block lines */
    187                 continue;
    188 
    189             case -1:
    190 
    191                 goto CleanupAndExit; /* There was a write error */
    192 
    193             default: /* Normal case, get next line */
    194 
    195                 ThisTableBytesWritten += BytesConverted;
    196                 continue;
    197             }
    198 
    199         default:
    200 
    201             Status = -1;
    202             goto CleanupAndExit;
    203         }
    204     }
    205 
    206     if (!FoundTable)
    207     {
    208         printf ("Table [%s] was not found in %s\n",
    209             Signature, InputPathname);
    210     }
    211 
    212 
    213 CleanupAndExit:
    214 
    215     if (State == AX_STATE_EXTRACT_DATA)
    216     {
    217         /* Received an input file EOF while extracting data */
    218 
    219         printf (AX_TABLE_INFO_FORMAT,
    220             ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename);
    221     }
    222 
    223     if (Gbl_TableCount > 1)
    224     {
    225         printf ("\n%d binary ACPI tables extracted\n",
    226             Gbl_TableCount);
    227     }
    228 
    229     if (OutputFile)
    230     {
    231         fclose (OutputFile);
    232     }
    233 
    234     fclose (InputFile);
    235     return (Status);
    236 }
    237 
    238 
    239 /******************************************************************************
    240  *
    241  * FUNCTION:    AxExtractToMultiAmlFile
    242  *
    243  * PARAMETERS:  InputPathname       - Filename for input acpidump file
    244  *
    245  * RETURN:      Status
    246  *
    247  * DESCRIPTION: Convert all DSDT/SSDT tables to binary and append them all
    248  *              into a single output file. Used to simplify the loading of
    249  *              multiple/many SSDTs into a utility like acpiexec -- instead
    250  *              of creating many separate output files.
    251  *
    252  ******************************************************************************/
    253 
    254 int
    255 AxExtractToMultiAmlFile (
    256     char                    *InputPathname)
    257 {
    258     FILE                    *InputFile;
    259     FILE                    *OutputFile;
    260     int                     Status = 0;
    261     unsigned int            TotalBytesWritten = 0;
    262     unsigned int            ThisTableBytesWritten = 0;
    263     unsigned int             BytesConverted;
    264     char                    ThisSignature[4];
    265     unsigned int            State = AX_STATE_FIND_HEADER;
    266 
    267 
    268     strcpy (Gbl_OutputFilename, AX_MULTI_TABLE_FILENAME);
    269 
    270     /* Open the input file in text mode */
    271 
    272     InputFile = fopen (InputPathname, "rt");
    273     if (!InputFile)
    274     {
    275         printf ("Could not open input file %s\n", InputPathname);
    276         return (-1);
    277     }
    278 
    279     /* Open the output file in binary mode */
    280 
    281     OutputFile = fopen (Gbl_OutputFilename, "w+b");
    282     if (!OutputFile)
    283     {
    284         printf ("Could not open output file %s\n", Gbl_OutputFilename);
    285         fclose (InputFile);
    286         return (-1);
    287     }
    288 
    289     /* Convert the DSDT and all SSDTs to binary */
    290 
    291     while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
    292     {
    293         switch (State)
    294         {
    295         case AX_STATE_FIND_HEADER:
    296 
    297             if (!AxIsDataBlockHeader ())
    298             {
    299                 continue;
    300             }
    301 
    302             ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer);
    303 
    304             /* Only want DSDT and SSDTs */
    305 
    306             if (!ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_DSDT) &&
    307                 !ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_SSDT))
    308             {
    309                 continue;
    310             }
    311 
    312             /*
    313              * Toss this block header of the form "<sig> @ <addr>" line
    314              * and move on to the actual data block
    315              */
    316             Gbl_TableCount++;
    317             ThisTableBytesWritten = 0;
    318             State = AX_STATE_EXTRACT_DATA;
    319             continue;
    320 
    321         case AX_STATE_EXTRACT_DATA:
    322 
    323             /* Empty line or non-data line terminates the data block */
    324 
    325             BytesConverted = AxProcessOneTextLine (
    326                 OutputFile, ThisSignature, ThisTableBytesWritten);
    327             switch (BytesConverted)
    328             {
    329             case 0:
    330 
    331                 State = AX_STATE_FIND_HEADER; /* No more data block lines */
    332                 continue;
    333 
    334             case -1:
    335 
    336                 goto CleanupAndExit; /* There was a write error */
    337 
    338             default: /* Normal case, get next line */
    339 
    340                 ThisTableBytesWritten += BytesConverted;
    341                 TotalBytesWritten += BytesConverted;
    342                 continue;
    343             }
    344 
    345         default:
    346 
    347             Status = -1;
    348             goto CleanupAndExit;
    349         }
    350     }
    351 
    352 
    353 CleanupAndExit:
    354 
    355     if (State == AX_STATE_EXTRACT_DATA)
    356     {
    357         /* Received an input file EOF or error while writing data */
    358 
    359         printf (AX_TABLE_INFO_FORMAT,
    360             ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename);
    361     }
    362 
    363     printf ("\n%d binary ACPI tables extracted and written to %s (%u bytes)\n",
    364         Gbl_TableCount, Gbl_OutputFilename, TotalBytesWritten);
    365 
    366     fclose (InputFile);
    367     fclose (OutputFile);
    368     return (Status);
    369 }
    370 
    371 
    372 /******************************************************************************
    373  *
    374  * FUNCTION:    AxListTables
    375  *
    376  * PARAMETERS:  InputPathname       - Filename for acpidump file
    377  *
    378  * RETURN:      Status
    379  *
    380  * DESCRIPTION: Display info for all ACPI tables found in input. Does not
    381  *              perform an actual extraction of the tables.
    382  *
    383  ******************************************************************************/
    384 
    385 int
    386 AxListTables (
    387     char                    *InputPathname)
    388 {
    389     FILE                    *InputFile;
    390     size_t                  HeaderSize;
    391     unsigned char           Header[48];
    392     ACPI_TABLE_HEADER       *TableHeader = (ACPI_TABLE_HEADER *) (void *) Header;
    393 
    394 
    395     /* Open input in text mode, output is in binary mode */
    396 
    397     InputFile = fopen (InputPathname, "rt");
    398     if (!InputFile)
    399     {
    400         printf ("Could not open input file %s\n", InputPathname);
    401         return (-1);
    402     }
    403 
    404     /* Dump the headers for all tables found in the input file */
    405 
    406     printf ("\nSignature  Length      Revision   OemId    OemTableId"
    407         "   OemRevision CompilerId CompilerRevision\n\n");
    408 
    409     while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile))
    410     {
    411         /* Ignore empty lines and lines that start with a space */
    412 
    413         if (AxIsEmptyLine (Gbl_LineBuffer) ||
    414             (Gbl_LineBuffer[0] == ' '))
    415         {
    416             continue;
    417         }
    418 
    419         /* Get the 36 byte header and display the fields */
    420 
    421         HeaderSize = AxGetTableHeader (InputFile, Header);
    422         if (HeaderSize < 16)
    423         {
    424             continue;
    425         }
    426 
    427         /* RSDP has an oddball signature and header */
    428 
    429         if (!strncmp (TableHeader->Signature, "RSD PTR ", 8))
    430         {
    431             AxCheckAscii ((char *) &Header[9], 6);
    432             printf ("%7.4s                          \"%6.6s\"\n", "RSDP",
    433                 &Header[9]);
    434             Gbl_TableCount++;
    435             continue;
    436         }
    437 
    438         /* Minimum size for table with standard header */
    439 
    440         if (HeaderSize < sizeof (ACPI_TABLE_HEADER))
    441         {
    442             continue;
    443         }
    444 
    445         /* Signature and Table length */
    446 
    447         Gbl_TableCount++;
    448         printf ("%7.4s   0x%8.8X", TableHeader->Signature,
    449             TableHeader->Length);
    450 
    451         /* FACS has only signature and length */
    452 
    453         if (ACPI_COMPARE_NAME (TableHeader->Signature, "FACS"))
    454         {
    455             printf ("\n");
    456             continue;
    457         }
    458 
    459         /* OEM IDs and Compiler IDs */
    460 
    461         AxCheckAscii (TableHeader->OemId, 6);
    462         AxCheckAscii (TableHeader->OemTableId, 8);
    463         AxCheckAscii (TableHeader->AslCompilerId, 4);
    464 
    465         printf (
    466             "     0x%2.2X    \"%6.6s\"  \"%8.8s\"   0x%8.8X"
    467             "    \"%4.4s\"     0x%8.8X\n",
    468             TableHeader->Revision, TableHeader->OemId,
    469             TableHeader->OemTableId, TableHeader->OemRevision,
    470             TableHeader->AslCompilerId, TableHeader->AslCompilerRevision);
    471     }
    472 
    473     printf ("\nFound %u ACPI tables\n", Gbl_TableCount);
    474     fclose (InputFile);
    475     return (0);
    476 }
    477