abcompare.c revision 1.1.1.3 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
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
619
620 /******************************************************************************
621 *
622 * FUNCTION: Stubs
623 *
624 * DESCRIPTION: For linkage
625 *
626 ******************************************************************************/
627