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