abcompare.c revision 1.1.1.10 1 /******************************************************************************
2 *
3 * Module Name: abcompare - compare AML files
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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
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 *Buffer = 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 Buffer = calloc (Size, 1);
539 if (!Buffer)
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 (Buffer, 1, Size, File);
548 if (Actual != Size)
549 {
550 printf ("Could not read the input file %s\n", Filename);
551 free (Buffer);
552 Buffer = NULL;
553 goto ErrorExit;
554 }
555
556 *FileSize = Size;
557
558 ErrorExit:
559 fclose (File);
560 return (Buffer);
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