Home | History | Annotate | Line # | Download | only in acpibin
abcompare.c revision 1.1.1.5
      1 /******************************************************************************
      2  *
      3  * Module Name: abcompare - compare AML files
      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 "acpibin.h"
     45 #include "acapps.h"
     46 
     47 
     48 ACPI_TABLE_HEADER           Header1;
     49 ACPI_TABLE_HEADER           Header2;
     50 
     51 #define BUFFER_SIZE         256
     52 char                        Buffer[BUFFER_SIZE];
     53 
     54 
     55 /* Local prototypes */
     56 
     57 static BOOLEAN
     58 AbValidateHeader (
     59     ACPI_TABLE_HEADER       *Header);
     60 
     61 static UINT8
     62 AcpiTbSumTable (
     63     void                    *Buffer,
     64     UINT32                  Length);
     65 
     66 static char *
     67 AbGetFile (
     68     char                    *Filename,
     69     UINT32                  *FileSize);
     70 
     71 static void
     72 AbPrintHeaderInfo (
     73     ACPI_TABLE_HEADER       *Header);
     74 
     75 static void
     76 AbPrintHeadersInfo (
     77     ACPI_TABLE_HEADER       *Header,
     78     ACPI_TABLE_HEADER       *Header2);
     79 
     80 
     81 /******************************************************************************
     82  *
     83  * FUNCTION:    AbValidateHeader
     84  *
     85  * DESCRIPTION: Check for valid ACPI table header
     86  *
     87  ******************************************************************************/
     88 
     89 static BOOLEAN
     90 AbValidateHeader (
     91     ACPI_TABLE_HEADER       *Header)
     92 {
     93 
     94     if (!AcpiUtValidAcpiName (Header->Signature))
     95     {
     96         printf ("Header signature is invalid\n");
     97         return (FALSE);
     98     }
     99 
    100     return (TRUE);
    101 }
    102 
    103 
    104 /*******************************************************************************
    105  *
    106  * FUNCTION:    AcpiTbSumTable
    107  *
    108  * PARAMETERS:  Buffer              - Buffer to checksum
    109  *              Length              - Size of the buffer
    110  *
    111  * RETURNS      8 bit checksum of buffer
    112  *
    113  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
    114  *
    115  ******************************************************************************/
    116 
    117 static UINT8
    118 AcpiTbSumTable (
    119     void                    *Buffer,
    120     UINT32                  Length)
    121 {
    122     const UINT8             *Limit;
    123     const UINT8             *Rover;
    124     UINT8                   Sum = 0;
    125 
    126 
    127     if (Buffer && Length)
    128     {
    129         /* Buffer and Length are valid */
    130 
    131         Limit = (UINT8 *) Buffer + Length;
    132 
    133         for (Rover = Buffer; Rover < Limit; Rover++)
    134         {
    135             Sum = (UINT8) (Sum + *Rover);
    136         }
    137     }
    138 
    139     return (Sum);
    140 }
    141 
    142 
    143 /*******************************************************************************
    144  *
    145  * FUNCTION:    AbPrintHeaderInfo
    146  *
    147  * PARAMETERS:  Header              - An ACPI table header
    148  *
    149  * RETURNS      None.
    150  *
    151  * DESCRIPTION: Format and display header contents.
    152  *
    153  ******************************************************************************/
    154 
    155 static void
    156 AbPrintHeaderInfo (
    157     ACPI_TABLE_HEADER       *Header)
    158 {
    159 
    160     /* Display header information */
    161 
    162     printf ("Signature         : %4.4s\n",    Header->Signature);
    163     printf ("Length            : %8.8X\n",    Header->Length);
    164     printf ("Revision          : %2.2X\n",    Header->Revision);
    165     printf ("Checksum          : %2.2X\n",    Header->Checksum);
    166     printf ("OEM ID            : %.6s\n",     Header->OemId);
    167     printf ("OEM Table ID      : %.8s\n",     Header->OemTableId);
    168     printf ("OEM Revision      : %8.8X\n",    Header->OemRevision);
    169     printf ("ASL Compiler ID   : %.4s\n",     Header->AslCompilerId);
    170     printf ("Compiler Revision : %8.8X\n",    Header->AslCompilerRevision);
    171     printf ("\n");
    172 }
    173 
    174 static void
    175 AbPrintHeadersInfo (
    176     ACPI_TABLE_HEADER       *Header,
    177     ACPI_TABLE_HEADER       *Header2)
    178 {
    179 
    180     /* Display header information for both headers */
    181 
    182     printf ("Signature          %8.4s : %4.4s\n",    Header->Signature, Header2->Signature);
    183     printf ("Length             %8.8X : %8.8X\n",    Header->Length, Header2->Length);
    184     printf ("Revision           %8.2X : %2.2X\n",    Header->Revision, Header2->Revision);
    185     printf ("Checksum           %8.2X : %2.2X\n",    Header->Checksum, Header2->Checksum);
    186     printf ("OEM ID             %8.6s : %.6s\n",     Header->OemId, Header2->OemId);
    187     printf ("OEM Table ID       %8.8s : %.8s\n",     Header->OemTableId, Header2->OemTableId);
    188     printf ("OEM Revision       %8.8X : %8.8X\n",    Header->OemRevision, Header2->OemRevision);
    189     printf ("ASL Compiler ID    %8.4s : %.4s\n",     Header->AslCompilerId, Header2->AslCompilerId);
    190     printf ("Compiler Revision  %8.8X : %8.8X\n",    Header->AslCompilerRevision, Header2->AslCompilerRevision);
    191     printf ("\n");
    192 }
    193 
    194 
    195 /******************************************************************************
    196  *
    197  * FUNCTION:    AbDisplayHeader
    198  *
    199  * DESCRIPTION: Display an ACPI table header
    200  *
    201  ******************************************************************************/
    202 
    203 void
    204 AbDisplayHeader (
    205     char                    *FilePath)
    206 {
    207     UINT32                  Actual;
    208     FILE                    *File;
    209 
    210 
    211     File = fopen (FilePath, "rb");
    212     if (!File)
    213     {
    214         printf ("Could not open file %s\n", FilePath);
    215         return;
    216     }
    217 
    218     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
    219     fclose (File);
    220 
    221     if (Actual != sizeof (ACPI_TABLE_HEADER))
    222     {
    223         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
    224         return;
    225     }
    226 
    227     if (!AbValidateHeader (&Header1))
    228     {
    229         return;
    230     }
    231 
    232     AbPrintHeaderInfo (&Header1);
    233 }
    234 
    235 
    236 /******************************************************************************
    237  *
    238  * FUNCTION:    AbComputeChecksum
    239  *
    240  * DESCRIPTION: Compute proper checksum for an ACPI table
    241  *
    242  ******************************************************************************/
    243 
    244 void
    245 AbComputeChecksum (
    246     char                    *FilePath)
    247 {
    248     UINT32                  Actual;
    249     ACPI_TABLE_HEADER       *Table;
    250     UINT8                   Checksum;
    251     FILE                    *File;
    252 
    253 
    254     File = fopen (FilePath, "rb");
    255     if (!File)
    256     {
    257         printf ("Could not open file %s\n", FilePath);
    258         return;
    259     }
    260 
    261     Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
    262     if (Actual < sizeof (ACPI_TABLE_HEADER))
    263     {
    264         printf ("File %s does not contain a valid ACPI table header\n", FilePath);
    265         goto Exit1;
    266     }
    267 
    268     if (!AbValidateHeader (&Header1))
    269     {
    270         goto Exit1;
    271     }
    272 
    273     if (!Gbl_TerseMode)
    274     {
    275         AbPrintHeaderInfo (&Header1);
    276     }
    277 
    278     /* Allocate a buffer to hold the entire table */
    279 
    280     Table = AcpiOsAllocate (Header1.Length);
    281     if (!Table)
    282     {
    283         printf ("Could not allocate buffer for table\n");
    284         goto Exit1;
    285     }
    286 
    287     /* Read the entire table, including header */
    288 
    289     fseek (File, 0, SEEK_SET);
    290     Actual = fread (Table, 1, Header1.Length, File);
    291     if (Actual != Header1.Length)
    292     {
    293         printf ("Could not read table, length %u\n", Header1.Length);
    294         goto Exit2;
    295     }
    296 
    297     /* Compute the checksum for the table */
    298 
    299     Table->Checksum = 0;
    300 
    301     Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length));
    302     printf ("Computed checksum: 0x%X\n\n", Checksum);
    303 
    304     if (Header1.Checksum == Checksum)
    305     {
    306         printf ("Checksum OK in AML file, not updating\n");
    307         goto Exit2;
    308     }
    309 
    310     /* Open the target file for writing, to update checksum */
    311 
    312     fclose (File);
    313     File = fopen (FilePath, "r+b");
    314     if (!File)
    315     {
    316         printf ("Could not open file %s for writing\n", FilePath);
    317         goto Exit2;
    318     }
    319 
    320     /* Set the checksum, write the new header */
    321 
    322     Header1.Checksum = Checksum;
    323 
    324     Actual = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File);
    325     if (Actual != sizeof (ACPI_TABLE_HEADER))
    326     {
    327         printf ("Could not write updated table header\n");
    328         goto Exit2;
    329     }
    330 
    331     printf ("Wrote new checksum\n");
    332 
    333 Exit2:
    334     AcpiOsFree (Table);
    335 
    336 Exit1:
    337     if (File)
    338     {
    339         fclose (File);
    340     }
    341     return;
    342 }
    343 
    344 
    345 /******************************************************************************
    346  *
    347  * FUNCTION:    AbCompareAmlFiles
    348  *
    349  * DESCRIPTION: Compare two AML files
    350  *
    351  ******************************************************************************/
    352 
    353 int
    354 AbCompareAmlFiles (
    355     char                    *File1Path,
    356     char                    *File2Path)
    357 {
    358     UINT32                  Actual1;
    359     UINT32                  Actual2;
    360     UINT32                  Offset;
    361     UINT8                   Char1;
    362     UINT8                   Char2;
    363     UINT8                   Mismatches = 0;
    364     BOOLEAN                 HeaderMismatch = FALSE;
    365     FILE                    *File1;
    366     FILE                    *File2;
    367     int                     Status = -1;
    368 
    369 
    370     File1 = fopen (File1Path, "rb");
    371     if (!File1)
    372     {
    373         printf ("Could not open file %s\n", File1Path);
    374         return (-1);
    375     }
    376 
    377     File2 = fopen (File2Path, "rb");
    378     if (!File2)
    379     {
    380         printf ("Could not open file %s\n", File2Path);
    381         goto Exit1;
    382     }
    383 
    384     /* Read the ACPI header from each file */
    385 
    386     Actual1 = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File1);
    387     if (Actual1 != sizeof (ACPI_TABLE_HEADER))
    388     {
    389         printf ("File %s does not contain an ACPI table header\n", File1Path);
    390         goto Exit2;
    391     }
    392 
    393     Actual2 = fread (&Header2, 1, sizeof (ACPI_TABLE_HEADER), File2);
    394     if (Actual2 != sizeof (ACPI_TABLE_HEADER))
    395     {
    396         printf ("File %s does not contain an ACPI table header\n", File2Path);
    397         goto Exit2;
    398     }
    399 
    400     if ((!AbValidateHeader (&Header1)) ||
    401         (!AbValidateHeader (&Header2)))
    402     {
    403         goto Exit2;
    404     }
    405 
    406     /* Table signatures must match */
    407 
    408     if (*((UINT32 *) Header1.Signature) != *((UINT32 *) Header2.Signature))
    409     {
    410         printf ("Table signatures do not match\n");
    411         goto Exit2;
    412     }
    413 
    414     if (!Gbl_TerseMode)
    415     {
    416         /* Display header information */
    417 
    418         AbPrintHeadersInfo (&Header1, &Header2);
    419     }
    420 
    421     if (memcmp (&Header1, &Header2, sizeof (ACPI_TABLE_HEADER)))
    422     {
    423         printf ("Headers do not match exactly\n");
    424         HeaderMismatch = TRUE;
    425     }
    426 
    427     /* Do the byte-by-byte compare */
    428 
    429     Actual1 = fread (&Char1, 1, 1, File1);
    430     Actual2 = fread (&Char2, 1, 1, File2);
    431     Offset = sizeof (ACPI_TABLE_HEADER);
    432 
    433     while ((Actual1 == 1) && (Actual2 == 1))
    434     {
    435         if (Char1 != Char2)
    436         {
    437             printf ("Error - Byte mismatch at offset %8.8X: 0x%2.2X 0x%2.2X\n",
    438                 Offset, Char1, Char2);
    439             Mismatches++;
    440             if (Mismatches > 100)
    441             {
    442                 printf ("100 Mismatches: Too many mismatches\n");
    443                 goto Exit2;
    444             }
    445         }
    446 
    447         Offset++;
    448         Actual1 = fread (&Char1, 1, 1, File1);
    449         Actual2 = fread (&Char2, 1, 1, File2);
    450     }
    451 
    452     if (Actual1)
    453     {
    454         printf ("Error - file %s is longer than file %s\n", File1Path, File2Path);
    455         Mismatches++;
    456     }
    457     else if (Actual2)
    458     {
    459         printf ("Error - file %s is shorter than file %s\n", File1Path, File2Path);
    460         Mismatches++;
    461     }
    462     else if (!Mismatches)
    463     {
    464         if (HeaderMismatch)
    465         {
    466             printf ("Files compare exactly after header\n");
    467         }
    468         else
    469         {
    470             printf ("Files compare exactly\n");
    471         }
    472     }
    473 
    474     printf ("%u Mismatches found\n", Mismatches);
    475     Status = 0;
    476 
    477 Exit2:
    478     fclose (File2);
    479 
    480 Exit1:
    481     fclose (File1);
    482     return (Status);
    483 }
    484 
    485 
    486 /******************************************************************************
    487  *
    488  * FUNCTION:    AbGetFile
    489  *
    490  * DESCRIPTION: Open a file and read it entirely into a new buffer
    491  *
    492  ******************************************************************************/
    493 
    494 static char *
    495 AbGetFile (
    496     char                    *Filename,
    497     UINT32                  *FileSize)
    498 {
    499     FILE                    *File;
    500     UINT32                  Size;
    501     char                    *Buffer = NULL;
    502     size_t                  Actual;
    503 
    504 
    505     /* Binary mode does not alter CR/LF pairs */
    506 
    507     File = fopen (Filename, "rb");
    508     if (!File)
    509     {
    510         printf ("Could not open file %s\n", Filename);
    511         return (NULL);
    512     }
    513 
    514     /* Need file size to allocate a buffer */
    515 
    516     Size = CmGetFileSize (File);
    517     if (Size == ACPI_UINT32_MAX)
    518     {
    519         printf ("Could not get file size (seek) for %s\n", Filename);
    520         goto ErrorExit;
    521     }
    522 
    523     /* Allocate a buffer for the entire file */
    524 
    525     Buffer = calloc (Size, 1);
    526     if (!Buffer)
    527     {
    528         printf ("Could not allocate buffer of size %u\n", Size);
    529         goto ErrorExit;
    530     }
    531 
    532     /* Read the entire file */
    533 
    534     Actual = fread (Buffer, 1, Size, File);
    535     if (Actual != Size)
    536     {
    537         printf ("Could not read the input file %s\n", Filename);
    538         free (Buffer);
    539         Buffer = NULL;
    540         goto ErrorExit;
    541     }
    542 
    543     *FileSize = Size;
    544 
    545 ErrorExit:
    546     fclose (File);
    547     return (Buffer);
    548 }
    549 
    550 
    551 /******************************************************************************
    552  *
    553  * FUNCTION:    AbDumpAmlFile
    554  *
    555  * DESCRIPTION: Dump a binary AML file to a text file
    556  *
    557  ******************************************************************************/
    558 
    559 int
    560 AbDumpAmlFile (
    561     char                    *File1Path,
    562     char                    *File2Path)
    563 {
    564     char                    *FileBuffer;
    565     FILE                    *FileOutHandle;
    566     UINT32                  FileSize = 0;
    567     int                     Status = -1;
    568 
    569 
    570     /* Get the entire AML file, validate header */
    571 
    572     FileBuffer = AbGetFile (File1Path, &FileSize);
    573     if (!FileBuffer)
    574     {
    575         return (-1);
    576     }
    577 
    578     printf ("Input file:  %s contains %u (0x%X) bytes\n",
    579         File1Path, FileSize, FileSize);
    580 
    581     FileOutHandle = fopen (File2Path, "wb");
    582     if (!FileOutHandle)
    583     {
    584         printf ("Could not open file %s\n", File2Path);
    585         goto Exit1;
    586     }
    587 
    588     if (!AbValidateHeader ((ACPI_TABLE_HEADER *) FileBuffer))
    589     {
    590         goto Exit2;
    591     }
    592 
    593     /* Convert binary AML to text, using common dump buffer routine */
    594 
    595     AcpiGbl_DebugFile = FileOutHandle;
    596     AcpiGbl_DbOutputFlags = ACPI_DB_REDIRECTABLE_OUTPUT;
    597 
    598     AcpiOsPrintf ("%4.4s @ 0x%8.8X\n",
    599         ((ACPI_TABLE_HEADER *) FileBuffer)->Signature, 0);
    600 
    601     AcpiUtDumpBuffer ((UINT8 *) FileBuffer, FileSize, DB_BYTE_DISPLAY, 0);
    602 
    603     /* Summary for the output file */
    604 
    605     FileSize = CmGetFileSize (FileOutHandle);
    606     printf ("Output file: %s contains %u (0x%X) bytes\n\n",
    607         File2Path, FileSize, FileSize);
    608 
    609     Status = 0;
    610 
    611 Exit2:
    612     fclose (FileOutHandle);
    613 
    614 Exit1:
    615     free (FileBuffer);
    616     return (Status);
    617 }
    618