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