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