Merge branch 'vendor/GCC50'
[dragonfly.git] / sys / contrib / dev / acpica / source / tools / acpibin / abcompare.c
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
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         AbPrintHeadersInfo (&Header1, &Header2);
418     }
419
420     if (memcmp (&Header1, &Header2, sizeof (ACPI_TABLE_HEADER)))
421     {
422         printf ("Headers do not match exactly\n");
423         HeaderMismatch = TRUE;
424     }
425
426     /* Do the byte-by-byte compare */
427
428     Actual1 = fread (&Char1, 1, 1, File1);
429     Actual2 = fread (&Char2, 1, 1, File2);
430     Offset = sizeof (ACPI_TABLE_HEADER);
431
432     while ((Actual1 == 1) && (Actual2 == 1))
433     {
434         if (Char1 != Char2)
435         {
436             printf ("Error - Byte mismatch at offset %8.8X: 0x%2.2X 0x%2.2X\n",
437                 Offset, Char1, Char2);
438             Mismatches++;
439             if (Mismatches > 100)
440             {
441                 printf ("100 Mismatches: Too many mismatches\n");
442                 goto Exit2;
443             }
444         }
445
446         Offset++;
447         Actual1 = fread (&Char1, 1, 1, File1);
448         Actual2 = fread (&Char2, 1, 1, File2);
449     }
450
451     if (Actual1)
452     {
453         printf ("Error - file %s is longer than file %s\n", File1Path, File2Path);
454         Mismatches++;
455     }
456     else if (Actual2)
457     {
458         printf ("Error - file %s is shorter than file %s\n", File1Path, File2Path);
459         Mismatches++;
460     }
461     else if (!Mismatches)
462     {
463         if (HeaderMismatch)
464         {
465             printf ("Files compare exactly after header\n");
466         }
467         else
468         {
469             printf ("Files compare exactly\n");
470         }
471     }
472
473     printf ("%u Mismatches found\n", Mismatches);
474     Status = 0;
475
476 Exit2:
477     fclose (File2);
478
479 Exit1:
480     fclose (File1);
481     return (Status);
482 }
483
484
485 /******************************************************************************
486  *
487  * FUNCTION:    AbGetFile
488  *
489  * DESCRIPTION: Open a file and read it entirely into a new buffer
490  *
491  ******************************************************************************/
492
493 static char *
494 AbGetFile (
495     char                    *Filename,
496     UINT32                  *FileSize)
497 {
498     FILE                    *File;
499     UINT32                  Size;
500     char                    *Buffer = NULL;
501     size_t                  Actual;
502
503
504     /* Binary mode does not alter CR/LF pairs */
505
506     File = fopen (Filename, "rb");
507     if (!File)
508     {
509         printf ("Could not open file %s\n", Filename);
510         return (NULL);
511     }
512
513     /* Need file size to allocate a buffer */
514
515     Size = CmGetFileSize (File);
516     if (Size == ACPI_UINT32_MAX)
517     {
518         printf ("Could not get file size (seek) for %s\n", Filename);
519         goto ErrorExit;
520     }
521
522     /* Allocate a buffer for the entire file */
523
524     Buffer = calloc (Size, 1);
525     if (!Buffer)
526     {
527         printf ("Could not allocate buffer of size %u\n", Size);
528         goto ErrorExit;
529     }
530
531     /* Read the entire file */
532
533     Actual = fread (Buffer, 1, Size, File);
534     if (Actual != Size)
535     {
536         printf ("Could not read the input file %s\n", Filename);
537         free (Buffer);
538         Buffer = NULL;
539         goto ErrorExit;
540     }
541
542     *FileSize = Size;
543
544 ErrorExit:
545     fclose (File);
546     return (Buffer);
547 }
548
549
550 /******************************************************************************
551  *
552  * FUNCTION:    AbDumpAmlFile
553  *
554  * DESCRIPTION: Dump a binary AML file to a text file
555  *
556  ******************************************************************************/
557
558 int
559 AbDumpAmlFile (
560     char                    *File1Path,
561     char                    *File2Path)
562 {
563     char                    *FileBuffer;
564     FILE                    *FileOutHandle;
565     UINT32                  FileSize = 0;
566     int                     Status = -1;
567
568
569     /* Get the entire AML file, validate header */
570
571     FileBuffer = AbGetFile (File1Path, &FileSize);
572     if (!FileBuffer)
573     {
574         return (-1);
575     }
576
577     printf ("Input file:  %s contains %u (0x%X) bytes\n",
578         File1Path, FileSize, FileSize);
579
580     FileOutHandle = fopen (File2Path, "wb");
581     if (!FileOutHandle)
582     {
583         printf ("Could not open file %s\n", File2Path);
584         goto Exit1;
585     }
586
587     if (!AbValidateHeader ((ACPI_TABLE_HEADER *) FileBuffer))
588     {
589         goto Exit2;
590     }
591
592     /* Convert binary AML to text, using common dump buffer routine */
593
594     AcpiGbl_DebugFile = FileOutHandle;
595     AcpiGbl_DbOutputFlags = ACPI_DB_REDIRECTABLE_OUTPUT;
596
597     AcpiOsPrintf ("%4.4s @ 0x%8.8X\n",
598         ((ACPI_TABLE_HEADER *) FileBuffer)->Signature, 0);
599
600     AcpiUtDumpBuffer ((UINT8 *) FileBuffer, FileSize, DB_BYTE_DISPLAY, 0);
601
602     /* Summary for the output file */
603
604     FileSize = CmGetFileSize (FileOutHandle);
605     printf ("Output file: %s contains %u (0x%X) bytes\n\n",
606         File2Path, FileSize, FileSize);
607
608     Status = 0;
609
610 Exit2:
611     fclose (FileOutHandle);
612
613 Exit1:
614     free (FileBuffer);
615     return (Status);
616 }