]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/GuidChk/GuidChk.c
Initial import.
[mirror_edk2.git] / Tools / Source / TianoTools / GuidChk / GuidChk.c
1 /*++
2
3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 GuidChk.c
15
16 Abstract:
17
18 Parse files in a directory and subdirectories to find all guid definitions.
19 Then check them against each other to make sure there are no duplicates.
20
21 --*/
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27
28 #include "CommonUtils.h"
29 #include "FileSearch.h"
30 #include "UtilsMsgs.h"
31
32 #define MAX_LINE_LEN 180 // we concatenate two lines sometimes
33 // Define a structure that correlates filename extensions to an enumerated
34 // type.
35 //
36 typedef struct {
37 INT8 *Extension;
38 INT8 ExtensionCode;
39 } FILE_TYPE_TABLE_ENTRY;
40
41 #define FILE_EXTENSION_UNKNOWN 0
42 #define FILE_EXTENSION_C 1
43 #define FILE_EXTENSION_H 2
44 #define FILE_EXTENSION_IA32_ASM 3
45 #define FILE_EXTENSION_IA32_INC 4
46 #define FILE_EXTENSION_IA64_ASM 5
47 #define FILE_EXTENSION_IA64_INC 6
48 #define FILE_EXTENSION_PKG 7
49 #define FILE_EXTENSION_INF 8
50
51 FILE_TYPE_TABLE_ENTRY FileTypeTable[] = {
52 ".c",
53 FILE_EXTENSION_C,
54 ".h",
55 FILE_EXTENSION_H,
56 ".inc",
57 FILE_EXTENSION_IA32_INC,
58 ".asm",
59 FILE_EXTENSION_IA32_ASM,
60 ".s",
61 FILE_EXTENSION_IA64_ASM,
62 ".pkg",
63 FILE_EXTENSION_PKG,
64 ".inf",
65 FILE_EXTENSION_INF,
66 ".i",
67 FILE_EXTENSION_IA64_INC,
68 NULL,
69 0
70 };
71
72 typedef struct EFI_GUID {
73 UINT32 Data1;
74 UINT16 Data2;
75 UINT16 Data3;
76 UINT8 Data4[8];
77 } EFI_GUID;
78
79 typedef struct {
80 INT8 Data[4];
81 INT8 DataLen;
82 } EFI_SIGNATURE;
83
84 typedef struct _GUID_RECORD {
85 struct _GUID_RECORD *Next;
86 BOOLEAN Reported;
87 INT8 *FileName;
88 INT8 *SymName;
89 EFI_GUID Guid;
90 } GUID_RECORD;
91
92 typedef struct _SIGNATURE_RECORD {
93 struct _SIGNATURE_RECORD *Next;
94 BOOLEAN Reported;
95 INT8 *FileName;
96 EFI_SIGNATURE Signature;
97 } SIGNATURE_RECORD;
98
99 //
100 // Utility options
101 //
102 typedef struct {
103 INT8 DatabaseOutputFileName[MAX_PATH]; // with -b option
104 STRING_LIST *ExcludeDirs; // list of directory names not to process
105 STRING_LIST *ExcludeSubDirs; // list of directory names to not process subdirectories (build)
106 STRING_LIST *ExcludeFiles; // list of files to exclude (make.inf)
107 STRING_LIST *ExcludeExtensions; // list of filename extensions to exclude (.inf, .pkg)
108 BOOLEAN Verbose;
109 BOOLEAN PrintFound;
110 BOOLEAN CheckGuids;
111 BOOLEAN CheckSignatures;
112 BOOLEAN GuidXReference;
113 } OPTIONS;
114
115 static
116 STATUS
117 ProcessArgs (
118 int Argc,
119 char *Argv[]
120 );
121
122 static
123 VOID
124 Usage (
125 VOID
126 );
127
128 static
129 STATUS
130 ProcessDirectory (
131 INT8 *Path,
132 INT8 *DirectoryName
133 );
134
135 static
136 STATUS
137 ProcessFile (
138 INT8 *DirectoryName,
139 INT8 *FileName
140 );
141
142 static
143 UINT32
144 GetFileExtension (
145 INT8 *FileName
146 );
147
148 static
149 UINT32
150 SkipWhiteSpace (
151 INT8 *Str
152 );
153
154 static
155 UINT32
156 ValidSymbolName (
157 INT8 *Name
158 );
159
160 static
161 STATUS
162 ProcessCFileGuids (
163 INT8 *FileName
164 );
165
166 static
167 STATUS
168 AddSignature (
169 INT8 *FileName,
170 INT8 *StrDef,
171 UINT32 SigSize
172 );
173
174 static
175 STATUS
176 ProcessCFileSigs (
177 INT8 *FileName
178 );
179
180 static
181 STATUS
182 ProcessINFFileGuids (
183 INT8 *FileName
184 );
185
186 static
187 STATUS
188 ProcessPkgFileGuids (
189 INT8 *FileName
190 );
191
192 static
193 STATUS
194 ProcessIA32FileGuids (
195 INT8 *FileName
196 );
197
198 static
199 STATUS
200 ProcessIA64FileGuids (
201 INT8 *FileName
202 );
203
204 static
205 BOOLEAN
206 IsIA64GuidLine (
207 INT8 *Line,
208 UINT32 *GuidHigh,
209 UINT32 *GuidLow,
210 BOOLEAN *Low,
211 INT8 *SymName
212 );
213
214 static
215 STATUS
216 AddGuid11 (
217 INT8 *FileName,
218 UINT32 *Data,
219 INT8 *SymName
220 );
221
222 static
223 STATUS
224 AddPkgGuid (
225 INT8 *FileName,
226 UINT32 *Data,
227 UINT64 *Data64
228 );
229
230 static
231 STATUS
232 AddGuid16 (
233 INT8 *FileName,
234 UINT32 *Data
235 );
236
237 static
238 STATUS
239 AddGuid64x2 (
240 INT8 *FileName,
241 UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid
242 UINT32 DataHL, // Lower 32-bits of upper 64 bits
243 UINT32 DataLH,
244 UINT32 DataLL
245 );
246
247 static
248 VOID
249 FreeGuids (
250 VOID
251 );
252
253 static
254 VOID
255 FreeSigs (
256 VOID
257 );
258
259 static
260 STATUS
261 CheckDuplicates (
262 VOID
263 );
264
265 //
266 // static
267 // VOID
268 // ReportGuid (
269 // INT8 *FileName,
270 // GUID_RECORD *FileRecord
271 // );
272 //
273 static
274 VOID
275 FreeOptions (
276 VOID
277 );
278
279 static
280 BOOLEAN
281 CheckGuidData (
282 UINT32 *GuidData,
283 UINT32 DataCount
284 );
285
286 /**************************** GLOBALS ****************************************/
287 static GUID_RECORD *gGuidList = NULL;
288 static SIGNATURE_RECORD *gSignatureList = NULL;
289 static OPTIONS gOptions;
290
291 /*****************************************************************************/
292 int
293 main (
294 int Argc,
295 char *Argv[]
296 )
297 {
298 INT8 *Cwd;
299 STATUS Status;
300
301 SetUtilityName ("GuidChk");
302 //
303 // Get the current working directory and then process the command line
304 // arguments.
305 //
306 Cwd = _getcwd (NULL, 0);
307 Status = ProcessArgs (Argc, Argv);
308 if (Status != STATUS_SUCCESS) {
309 return Status;
310 }
311
312 if (gOptions.CheckGuids || gOptions.CheckSignatures) {
313 Status = ProcessDirectory (Cwd, NULL);
314 if (Status == STATUS_SUCCESS) {
315 //
316 // Check for duplicates
317 //
318 Status = CheckDuplicates ();
319 }
320 }
321
322 if (gOptions.DatabaseOutputFileName[0] != 0) {
323 CreateGuidList (gOptions.DatabaseOutputFileName);
324 }
325 //
326 // Free up the memory
327 //
328 free (Cwd);
329 FreeGuids ();
330 FreeSigs ();
331 FreeOptions ();
332 return GetUtilityStatus ();
333 }
334
335 static
336 STATUS
337 ProcessArgs (
338 int Argc,
339 char *Argv[]
340 )
341 {
342 STRING_LIST *StrList;
343
344 memset ((char *) &gOptions, 0, sizeof (gOptions));
345 //
346 // skip over program name
347 //
348 Argc--;
349 Argv++;
350
351 if (Argc == 0) {
352 Usage ();
353 return STATUS_ERROR;
354 }
355
356 while (Argc > 0) {
357 //
358 // Look for options
359 //
360 if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {
361 switch (Argv[0][1]) {
362 //
363 // Help option
364 //
365 case 'h':
366 case 'H':
367 case '?':
368 Usage ();
369 return STATUS_ERROR;
370 break;
371
372 //
373 // Check guids option
374 //
375 case 'g':
376 case 'G':
377 gOptions.CheckGuids = TRUE;
378 break;
379
380 //
381 // Check signatures option
382 //
383 case 's':
384 case 'S':
385 gOptions.CheckSignatures = TRUE;
386 break;
387
388 //
389 // Print guids found option
390 //
391 case 'p':
392 case 'P':
393 gOptions.PrintFound = TRUE;
394 break;
395
396 //
397 // Exclude files option
398 //
399 case 'f':
400 case 'F':
401 //
402 // Check for another arg
403 //
404 if (Argc < 2) {
405 Error (NULL, 0, 0, Argv[0], "missing argument with option");
406 Usage ();
407 return STATUS_ERROR;
408 }
409
410 StrList = malloc (sizeof (STRING_LIST));
411 if (StrList == NULL) {
412 Error (NULL, 0, 0, "memory allocation failure", NULL);
413 return STATUS_ERROR;
414 }
415
416 memset ((char *) StrList, 0, sizeof (STRING_LIST));
417 StrList->Str = Argv[1];
418 StrList->Next = gOptions.ExcludeFiles;
419 gOptions.ExcludeFiles = StrList;
420 Argc--;
421 Argv++;
422 break;
423
424 //
425 // Exclude directories option
426 //
427 case 'd':
428 case 'D':
429 //
430 // Check for another arg
431 //
432 if (Argc < 2) {
433 Error (NULL, 0, 0, Argv[0], "missing argument with option");
434 Usage ();
435 return STATUS_ERROR;
436 }
437
438 StrList = malloc (sizeof (STRING_LIST));
439 if (StrList == NULL) {
440 Error (NULL, 0, 0, "memory allocation failure", NULL);
441 return STATUS_ERROR;
442 }
443
444 memset ((char *) StrList, 0, sizeof (STRING_LIST));
445 StrList->Str = Argv[1];
446 StrList->Next = gOptions.ExcludeDirs;
447 gOptions.ExcludeDirs = StrList;
448 Argc--;
449 Argv++;
450 break;
451
452 //
453 // -u exclude all subdirectories of a given directory option
454 //
455 case 'u':
456 case 'U':
457 //
458 // Check for another arg
459 //
460 if (Argc < 2) {
461 Error (NULL, 0, 0, Argv[0], "missing argument with option");
462 Usage ();
463 return STATUS_ERROR;
464 }
465
466 StrList = malloc (sizeof (STRING_LIST));
467 if (StrList == NULL) {
468 Error (NULL, 0, 0, "memory allocation failure", NULL);
469 return STATUS_ERROR;
470 }
471
472 memset ((char *) StrList, 0, sizeof (STRING_LIST));
473 StrList->Str = Argv[1];
474 StrList->Next = gOptions.ExcludeSubDirs;
475 gOptions.ExcludeSubDirs = StrList;
476 Argc--;
477 Argv++;
478 break;
479
480 //
481 // -e exclude by filename extension option
482 //
483 case 'e':
484 case 'E':
485 //
486 // Check for another arg
487 //
488 if (Argc < 2) {
489 Error (NULL, 0, 0, Argv[0], "missing argument with option");
490 Usage ();
491 return STATUS_ERROR;
492 }
493
494 StrList = malloc (sizeof (STRING_LIST));
495 if (StrList == NULL) {
496 Error (NULL, 0, 0, "memory allocation failure", NULL);
497 return STATUS_ERROR;
498 }
499
500 memset ((char *) StrList, 0, sizeof (STRING_LIST));
501 //
502 // Let them put a * in front of the filename extension
503 //
504 StrList->Str = Argv[1];
505 if (StrList->Str[0] == '*') {
506 StrList->Str++;
507 }
508
509 StrList->Next = gOptions.ExcludeExtensions;
510 gOptions.ExcludeExtensions = StrList;
511 Argc--;
512 Argv++;
513 break;
514
515 //
516 // Print guid with matching symbol name for guid definitions found
517 //
518 case 'x':
519 case 'X':
520 gOptions.GuidXReference = 1;
521 break;
522
523 //
524 // -b Print the internal database list to a file
525 //
526 case 'b':
527 case 'B':
528 //
529 // Check for one more arg
530 //
531 if (Argc < 2) {
532 Error (NULL, 0, 0, Argv[0], "must specify file name with option");
533 Usage ();
534 return STATUS_ERROR;
535 }
536
537 strcpy (gOptions.DatabaseOutputFileName, Argv[1]);
538 Argc--;
539 Argv++;
540 break;
541
542 default:
543 Error (NULL, 0, 0, Argv[0], "invalid option");
544 Usage ();
545 return STATUS_ERROR;
546 }
547 } else {
548 break;
549 }
550 //
551 // Next arg
552 //
553 Argc--;
554 Argv++;
555 }
556
557 if (Argc > 0) {
558 Error (NULL, 0, 0, Argv[0], "invalid argument");
559 Usage ();
560 return STATUS_ERROR;
561 }
562 //
563 // Have to check signatures, GUIDs, or dump the GUID database.
564 //
565 if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) {
566 Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b");
567 Usage ();
568 return STATUS_ERROR;
569 }
570
571 return STATUS_SUCCESS;
572 }
573 //
574 // Print usage instructions
575 //
576 static
577 VOID
578 Usage (
579 VOID
580 )
581 {
582 int Index;
583 char *Str[] = {
584 "GuidChk - scan files for duplicate GUID or signature definitions",
585 "",
586 "Usage: GuidChk {options}\n",
587 " Options: ",
588 " -d dirname exclude searching of a directory",
589 " -f filename exclude searching of a file",
590 " -e extension exclude searching of files by extension",
591 " -p print all GUIDS found",
592 " -g check for duplicate guids",
593 " -s check for duplicate signatures",
594 " -x print guid+defined symbol name",
595 " -b outfile write internal GUID+basename list to outfile",
596 " -u dirname exclude searching all subdirectories of a directory",
597 " -h -? print this help text",
598 " ",
599 " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg",
600 "",
601 NULL
602 };
603 for (Index = 0; Str[Index] != NULL; Index++) {
604 fprintf (stdout, "%s\n", Str[Index]);
605 }
606 }
607 //
608 // Process an entire directory by name
609 //
610 static
611 STATUS
612 ProcessDirectory (
613 INT8 *Path,
614 INT8 *DirectoryName
615 )
616 {
617 FILE_SEARCH_DATA FSData;
618 char *FileMask;
619 BOOLEAN Done;
620 UINT32 Len;
621 BOOLEAN NoSubdirs;
622 STRING_LIST *SLPtr;
623
624 //
625 // Root directory may be null
626 //
627 if (DirectoryName != NULL) {
628 //
629 // printf ("Processing directory: %s\n", DirectoryName);
630 //
631 }
632 //
633 // Initialize our file searching
634 //
635 FileSearchInit (&FSData);
636
637 //
638 // Exclude some directories, files, and extensions
639 //
640 FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs);
641 FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions);
642 FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles);
643 //
644 // See if this directory is in the list of directories that they
645 // don't want to process subdirectories of
646 //
647 NoSubdirs = FALSE;
648 if (DirectoryName != NULL) {
649 for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) {
650 if (stricmp (SLPtr->Str, DirectoryName) == 0) {
651 //
652 // printf ("not processing subdirectories of %s\n", DirectoryName);
653 //
654 NoSubdirs = TRUE;
655 break;
656 }
657 }
658 }
659 //
660 // Create a filemask of files to search for. We'll append "\*.*" on the
661 // end, so allocate some extra bytes.
662 //
663 Len = strlen (Path) + 10;
664 if (DirectoryName != NULL) {
665 Len += strlen (DirectoryName);
666 }
667
668 FileMask = malloc (Len);
669 if (FileMask == NULL) {
670 Error (NULL, 0, 0, "memory allocation failure", NULL);
671 return STATUS_ERROR;
672 }
673 //
674 // Now put it all together
675 //
676 strcpy (FileMask, Path);
677 if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) {
678 strcat (FileMask, "\\");
679 strcat (FileMask, DirectoryName);
680 }
681
682 strcat (FileMask, "\\*.*");
683
684 //
685 // Start file searching for files and directories
686 //
687 FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR);
688
689 //
690 // Now hack the "\*.*" off the end of the filemask so we can use it to pass
691 // the full directory path on recursive calls to process directories.
692 //
693 FileMask[strlen (FileMask) - 4] = 0;
694
695 //
696 // Loop until no more files
697 //
698 Done = FALSE;
699 while (!Done) {
700 //
701 // printf ("Found %s...", FSData.FileName);
702 //
703 if (FSData.FileFlags & FILE_SEARCH_DIR) {
704 //
705 // printf ("directory\n");
706 //
707 if (!NoSubdirs) {
708 ProcessDirectory (FileMask, FSData.FileName);
709 }
710 } else if (FSData.FileFlags & FILE_SEARCH_FILE) {
711 //
712 // printf ("file\n");
713 //
714 ProcessFile (FileMask, FSData.FileName);
715 } else {
716 //
717 // printf ("unknown\n");
718 //
719 }
720
721 if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) {
722 Done = TRUE;
723 }
724 }
725 //
726 // Free up allocated memory
727 //
728 free (FileMask);
729
730 //
731 // Free up our file searching
732 //
733 FileSearchDestroy (&FSData);
734
735 return STATUS_SUCCESS;
736 }
737 //
738 // Process a single file.
739 //
740 static
741 STATUS
742 ProcessFile (
743 INT8 *DirectoryName,
744 INT8 *FileName
745 )
746 {
747 STATUS Status;
748 UINT32 FileExtension;
749 INT8 FullFileName[MAX_PATH];
750
751 Status = STATUS_SUCCESS;
752
753 sprintf (FullFileName, "%s\\%s", DirectoryName, FileName);
754 //
755 // printf ("Found file: %s\n", FullFileName);
756 //
757 FileExtension = GetFileExtension (FileName);
758
759 //
760 // Process these for GUID checks
761 //
762 if (gOptions.CheckGuids) {
763 switch (FileExtension) {
764 case FILE_EXTENSION_C:
765 case FILE_EXTENSION_H:
766 Status = ProcessCFileGuids (FullFileName);
767 break;
768
769 case FILE_EXTENSION_PKG:
770 Status = ProcessPkgFileGuids (FullFileName);
771 break;
772
773 case FILE_EXTENSION_IA32_INC:
774 case FILE_EXTENSION_IA32_ASM:
775 Status = ProcessIA32FileGuids (FullFileName);
776 break;
777
778 case FILE_EXTENSION_INF:
779 Status = ProcessINFFileGuids (FullFileName);
780 break;
781
782 case FILE_EXTENSION_IA64_INC:
783 case FILE_EXTENSION_IA64_ASM:
784 Status = ProcessIA64FileGuids (FullFileName);
785 break;
786
787 default:
788 //
789 // No errors anyway
790 //
791 Status = STATUS_SUCCESS;
792 break;
793 }
794 }
795
796 if (gOptions.CheckSignatures) {
797 switch (FileExtension) {
798 case FILE_EXTENSION_C:
799 case FILE_EXTENSION_H:
800 Status = ProcessCFileSigs (FullFileName);
801 break;
802
803 default:
804 //
805 // No errors anyway
806 //
807 Status = STATUS_SUCCESS;
808 break;
809 }
810 }
811
812 return Status;
813 }
814 //
815 // Return a code indicating the file name extension.
816 //
817 static
818 UINT32
819 GetFileExtension (
820 INT8 *FileName
821 )
822 {
823 INT8 *Extension;
824 int Index;
825
826 //
827 // Look back for a filename extension
828 //
829 for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) {
830 if (*Extension == '.') {
831 for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) {
832 if (stricmp (FileTypeTable[Index].Extension, Extension) == 0) {
833 return FileTypeTable[Index].ExtensionCode;
834 }
835 }
836 }
837 }
838
839 return FILE_TYPE_UNKNOWN;
840 }
841 //
842 // Process a .pkg file.
843 //
844 // Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
845 //
846 static
847 STATUS
848 ProcessPkgFileGuids (
849 INT8 *FileName
850 )
851 {
852 FILE *Fptr;
853 INT8 Line[MAX_LINE_LEN * 2];
854 INT8 *Cptr;
855 INT8 *Cptr2;
856 UINT32 GuidScan[11];
857 UINT64 Guid64;
858
859 if ((Fptr = fopen (FileName, "r")) == NULL) {
860 Error (NULL, 0, 0, FileName, "could not open input file for reading");
861 return STATUS_ERROR;
862 }
863 //
864 // Read lines from the file until done
865 //
866 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
867 Cptr = Line;
868 Cptr += SkipWhiteSpace (Line);
869 if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) {
870 Cptr += 12;
871 Cptr += SkipWhiteSpace (Cptr);
872 if (*Cptr == '=') {
873 Cptr++;
874 Cptr += SkipWhiteSpace (Cptr + 1);
875 //
876 // Blank out dashes on the line.
877 //
878 for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
879 if (*Cptr2 == '-') {
880 *Cptr2 = ' ';
881 }
882 }
883
884 if (sscanf (
885 Cptr,
886 "%X %X %X %X %I64X",
887 &GuidScan[0],
888 &GuidScan[1],
889 &GuidScan[2],
890 &GuidScan[3],
891 &Guid64
892 ) == 5) {
893 AddPkgGuid (FileName, GuidScan, &Guid64);
894 } else {
895 DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
896 }
897 }
898 }
899 }
900
901 fclose (Fptr);
902 return STATUS_SUCCESS;
903 }
904 //
905 // Process an IA32 assembly file.
906 //
907 // Look for:
908 // FIND_FD_GUID_VAL equ 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h
909 // PEI_GUID_FileNameGuid_Gmch815 equ 081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h
910 //
911 static
912 STATUS
913 ProcessIA32FileGuids (
914 INT8 *FileName
915 )
916 {
917 FILE *Fptr;
918 INT8 Line[MAX_LINE_LEN];
919 INT8 *Cptr;
920 INT8 CSave;
921 INT8 *CSavePtr;
922 UINT32 Len;
923 UINT32 GuidData[16];
924 UINT32 Index;
925
926 if ((Fptr = fopen (FileName, "r")) == NULL) {
927 Error (NULL, 0, 0, FileName, "could not open input file for reading");
928 return STATUS_ERROR;
929 }
930 //
931 // Read lines from the file until done
932 //
933 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
934 Cptr = Line;
935 Cptr += SkipWhiteSpace (Line);
936 //
937 // Look for xxxGUIDyyy equ 01h, 02h, 03h, ...
938 //
939 Len = ValidSymbolName (Cptr);
940 if (Len) {
941 //
942 // Terminate the line after the symbol name, then look for "guid" in
943 // the name.
944 //
945 CSavePtr = Cptr + Len;
946 CSave = *CSavePtr;
947 *CSavePtr = 0;
948 while (*Cptr) {
949 if (strnicmp (Cptr, "guid", 4) == 0) {
950 break;
951 }
952
953 Cptr++;
954 }
955 //
956 // If we found the string "guid", continue
957 //
958 if (*Cptr) {
959 //
960 // Restore the character on the line where we null-terminated the symbol
961 //
962 *CSavePtr = CSave;
963 Cptr = CSavePtr;
964 Len = SkipWhiteSpace (Cptr);
965 //
966 // Had to be some white space
967 //
968 if (Len) {
969 Cptr += Len;
970 //
971 // now look for "equ"
972 //
973 if (strnicmp (Cptr, "equ", 3) == 0) {
974 Cptr += 3;
975 Cptr += SkipWhiteSpace (Cptr);
976 //
977 // Now scan all the data
978 //
979 for (Index = 0; Index < 16; Index++) {
980 if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) {
981 break;
982 }
983 //
984 // Skip to next
985 //
986 while (isxdigit (*Cptr)) {
987 Cptr++;
988 }
989
990 if ((*Cptr != 'h') && (*Cptr != 'H')) {
991 break;
992 } else {
993 Cptr++;
994 while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) {
995 Cptr++;
996 }
997 }
998 }
999 //
1000 // Now see which form we had
1001 //
1002 if (Index == 16) {
1003 AddGuid16 (FileName, GuidData);
1004 } else if (Index == 11) {
1005 AddGuid11 (FileName, GuidData, NULL);
1006 }
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 fclose (Fptr);
1014 return STATUS_SUCCESS;
1015 }
1016 //
1017 // Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list
1018 // of guids.
1019 //
1020 static
1021 STATUS
1022 AddGuid16 (
1023 INT8 *FileName,
1024 UINT32 *Data
1025 )
1026 {
1027 GUID_RECORD *NewRec;
1028 int Index;
1029
1030 //
1031 // Sanity check the data
1032 //
1033 if (!CheckGuidData (Data, 16)) {
1034 return STATUS_ERROR;
1035 }
1036 //
1037 // Allocate memory for a new guid structure
1038 //
1039 NewRec = malloc (sizeof (GUID_RECORD));
1040 if (NewRec == NULL) {
1041 Error (NULL, 0, 0, "memory allocation failure", NULL);
1042 return STATUS_ERROR;
1043 }
1044
1045 memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1046 NewRec->FileName = malloc (strlen (FileName) + 1);
1047 if (NewRec->FileName == NULL) {
1048 free (NewRec);
1049 Error (NULL, 0, 0, "memory allocation failure", NULL);
1050 return STATUS_ERROR;
1051 }
1052
1053 strcpy (NewRec->FileName, FileName);
1054 NewRec->Guid.Data1 = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24));
1055 NewRec->Guid.Data2 = (UINT16) (Data[4] | (Data[5] << 8));
1056 NewRec->Guid.Data3 = (UINT16) (Data[6] | (Data[7] << 8));
1057 for (Index = 0; Index < 8; Index++) {
1058 NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8];
1059 }
1060 //
1061 // Add it to the list
1062 //
1063 NewRec->Next = gGuidList;
1064 gGuidList = NewRec;
1065
1066 //
1067 // Report it
1068 // ReportGuid (FileName, NewRec);
1069 //
1070 return STATUS_SUCCESS;
1071 }
1072 //
1073 // Add a GUID defined as GuidLow: 0x1122334455667788
1074 // GuidHi: 0x99AABBCCDDEEFF00
1075 //
1076 // These are equivalent:
1077 // { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }
1078 // and:
1079 // Low: 00FFEEDDCCBBAA99
1080 // Hi: 7788556611223344
1081 //
1082 static
1083 STATUS
1084 AddGuid64x2 (
1085 INT8 *FileName,
1086 UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid
1087 UINT32 DataHL, // Lower 32-bits of upper 64 bits
1088 UINT32 DataLH,
1089 UINT32 DataLL
1090 )
1091 {
1092 GUID_RECORD *NewRec;
1093 int Index;
1094
1095 //
1096 // Allocate memory for a new guid structure
1097 //
1098 NewRec = malloc (sizeof (GUID_RECORD));
1099 if (NewRec == NULL) {
1100 Error (NULL, 0, 0, "memory allocation failure", NULL);
1101 return STATUS_ERROR;
1102 }
1103
1104 memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1105 NewRec->FileName = malloc (strlen (FileName) + 1);
1106 if (NewRec->FileName == NULL) {
1107 free (NewRec);
1108 Error (NULL, 0, 0, "memory allocation failure", NULL);
1109 return STATUS_ERROR;
1110 }
1111
1112 strcpy (NewRec->FileName, FileName);
1113 NewRec->Guid.Data1 = DataHL;
1114 NewRec->Guid.Data2 = (UINT16) DataHH;
1115 NewRec->Guid.Data3 = (UINT16) (DataHH >> 16);
1116 for (Index = 0; Index < 4; Index++) {
1117 NewRec->Guid.Data4[Index] = (UINT8) DataLL;
1118 DataLL >>= 8;
1119 }
1120
1121 for (Index = 0; Index < 4; Index++) {
1122 NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH;
1123 DataLH >>= 8;
1124 }
1125 //
1126 // Add it to the list
1127 //
1128 NewRec->Next = gGuidList;
1129 gGuidList = NewRec;
1130
1131 //
1132 // Report it
1133 // ReportGuid (FileName, NewRec);
1134 //
1135 return STATUS_SUCCESS;
1136 }
1137 //
1138 // Process INF files. Look for:
1139 // FILE_GUID = 240612B6-A063-11d4-9A3A-0090273FC14D
1140 //
1141 static
1142 STATUS
1143 ProcessINFFileGuids (
1144 INT8 *FileName
1145 )
1146 {
1147 FILE *Fptr;
1148 INT8 Line[MAX_LINE_LEN * 2];
1149 INT8 *Cptr;
1150 INT8 *Cptr2;
1151 UINT32 GuidScan[11];
1152 UINT64 Guid64;
1153
1154 if ((Fptr = fopen (FileName, "r")) == NULL) {
1155 Error (NULL, 0, 0, FileName, "could not open input file for reading");
1156 return STATUS_ERROR;
1157 }
1158 //
1159 // Read lines from the file until done
1160 //
1161 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1162 Cptr = Line;
1163 Cptr += SkipWhiteSpace (Line);
1164 if (strncmp (Cptr, "FILE_GUID", 9) == 0) {
1165 Cptr += 9;
1166 Cptr += SkipWhiteSpace (Cptr);
1167 if (*Cptr == '=') {
1168 Cptr++;
1169 Cptr += SkipWhiteSpace (Cptr + 1);
1170 //
1171 // Blank out dashes on the line.
1172 //
1173 for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
1174 if (*Cptr2 == '-') {
1175 *Cptr2 = ' ';
1176 }
1177 }
1178
1179 if (sscanf (
1180 Cptr,
1181 "%X %X %X %X %I64X",
1182 &GuidScan[0],
1183 &GuidScan[1],
1184 &GuidScan[2],
1185 &GuidScan[3],
1186 &Guid64
1187 ) == 5) {
1188 AddPkgGuid (FileName, GuidScan, &Guid64);
1189 } else {
1190 DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
1191 }
1192 }
1193 }
1194 }
1195
1196 fclose (Fptr);
1197 return STATUS_SUCCESS;
1198 }
1199 //
1200 // Parse ('g','m','a','p','a','b','c','d')
1201 //
1202 static
1203 STATUS
1204 AddSignature (
1205 INT8 *FileName,
1206 INT8 *StrDef,
1207 UINT32 SigSize
1208 )
1209 {
1210 SIGNATURE_RECORD *NewRec;
1211 INT8 *Cptr;
1212 UINT32 Index;
1213 BOOLEAN Fail;
1214
1215 //
1216 // Allocate memory for the new record
1217 //
1218 Fail = FALSE;
1219 NewRec = malloc (sizeof (SIGNATURE_RECORD));
1220 if (NewRec == NULL) {
1221 Error (NULL, 0, 0, "memory allocation failure", NULL);
1222 return STATUS_ERROR;
1223 }
1224 //
1225 // Allocate memory to save the file name
1226 //
1227 NewRec->FileName = malloc (strlen (FileName) + 1);
1228 if (NewRec->FileName == NULL) {
1229 Error (NULL, 0, 0, "memory allocation failure", NULL);
1230 free (NewRec);
1231 return STATUS_ERROR;
1232 }
1233 //
1234 // Fill in the fields
1235 //
1236 strcpy (NewRec->FileName, FileName);
1237 NewRec->Signature.DataLen = (UINT8) SigSize;
1238 //
1239 // Skip to open parenthesis
1240 //
1241 Cptr = StrDef;
1242 Cptr += SkipWhiteSpace (Cptr);
1243 if (*Cptr != '(') {
1244 Fail = TRUE;
1245 goto Done;
1246 }
1247
1248 Cptr++;
1249 //
1250 // Skip to first ' and start processing
1251 //
1252 while (*Cptr && (*Cptr != '\'')) {
1253 Cptr++;
1254 }
1255
1256 for (Index = 0; Index < SigSize; Index++) {
1257 if (*Cptr == '\'') {
1258 Cptr++;
1259 NewRec->Signature.Data[Index] = (INT8) *Cptr;
1260 //
1261 // Skip to closing quote
1262 //
1263 Cptr++;
1264 if (*Cptr != '\'') {
1265 Fail = TRUE;
1266 break;
1267 }
1268 //
1269 // Skip over closing quote, go to next one
1270 //
1271 Cptr++;
1272 while (*Cptr && (*Cptr != '\'')) {
1273 Cptr++;
1274 }
1275 } else {
1276 Fail = TRUE;
1277 DebugMsg (NULL, 0, 0, StrDef, "failed to parse signature");
1278 break;
1279 }
1280 }
1281
1282 Done:
1283 if (Fail) {
1284 free (NewRec->FileName);
1285 free (NewRec);
1286 return STATUS_ERROR;
1287 }
1288
1289 NewRec->Next = gSignatureList;
1290 gSignatureList = NewRec;
1291 return STATUS_SUCCESS;
1292 }
1293 //
1294 // Look for:
1295 // #define POOL_HEAD_SIGNATURE EFI_SIGNATURE_16('p','h')
1296 // #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('g','m','a','p')
1297 // #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_64('g','m','a','p','a','b','c','d')
1298 //
1299 static
1300 STATUS
1301 ProcessCFileSigs (
1302 INT8 *FileName
1303 )
1304 {
1305 FILE *Fptr;
1306 INT8 Line[MAX_LINE_LEN * 2];
1307 INT8 *Cptr;
1308 UINT32 Len;
1309 UINT32 LineLen;
1310
1311 if ((Fptr = fopen (FileName, "r")) == NULL) {
1312 Error (NULL, 0, 0, FileName, "could not open input file for reading");
1313 return STATUS_ERROR;
1314 }
1315 //
1316 // Read lines from the file until done
1317 //
1318 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1319 Cptr = Line;
1320 Cptr += SkipWhiteSpace (Line);
1321 //
1322 // look for #define xxxGUIDxxx value
1323 //
1324 if (*Cptr == '#') {
1325 Cptr++;
1326 Cptr += SkipWhiteSpace (Cptr);
1327 //
1328 // Look for "define"
1329 //
1330 if (!strncmp (Cptr, "define", 6)) {
1331 Cptr += 6;
1332 //
1333 // Better be whitespace
1334 //
1335 Len = SkipWhiteSpace (Cptr);
1336 if (Len) {
1337 Cptr += Len;
1338 //
1339 // See if it's a valid symbol name
1340 //
1341 Len = ValidSymbolName (Cptr);
1342 if (Len) {
1343 //
1344 // It is a valid symbol name. See if there's a line continuation,
1345 // and if so, read one more line.
1346 // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx"
1347 //
1348 LineLen = strlen (Line);
1349 if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {
1350 fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);
1351 } else if (Line[LineLen - 1] == '\\') {
1352 fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);
1353 }
1354
1355 Cptr += Len;
1356 Cptr += SkipWhiteSpace (Cptr);
1357 if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) {
1358 AddSignature (FileName, Cptr + 16, 2);
1359 } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) {
1360 AddSignature (FileName, Cptr + 16, 4);
1361 } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) {
1362 AddSignature (FileName, Cptr + 16, 8);
1363 }
1364 }
1365 }
1366 }
1367 }
1368 }
1369
1370 fclose (Fptr);
1371 return STATUS_SUCCESS;
1372 }
1373 //
1374 // look for #define xxxGUIDyyy { 0x...}
1375 // xxx EFI_GUID GuidName = { 0x... };
1376 //
1377 static
1378 STATUS
1379 ProcessCFileGuids (
1380 INT8 *FileName
1381 )
1382 {
1383 FILE *Fptr;
1384 INT8 Line[MAX_LINE_LEN * 2];
1385 INT8 *Cptr;
1386 INT8 CSave;
1387 INT8 *CSavePtr;
1388 INT8 *TempCptr;
1389 INT8 *SymName;
1390 UINT32 Len;
1391 UINT32 LineLen;
1392 UINT32 GuidScan[11];
1393
1394 if ((Fptr = fopen (FileName, "r")) == NULL) {
1395 Error (NULL, 0, 0, FileName, "could not open input file for reading");
1396 return STATUS_ERROR;
1397 }
1398 //
1399 // Read lines from the file until done
1400 //
1401 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1402 Cptr = Line;
1403 Cptr += SkipWhiteSpace (Line);
1404 //
1405 // look for #define xxxGUIDxxx value
1406 //
1407 if (*Cptr == '#') {
1408 Cptr++;
1409 Cptr += SkipWhiteSpace (Cptr);
1410 //
1411 // Look for "define"
1412 //
1413 if (!strncmp (Cptr, "define", 6)) {
1414 Cptr += 6;
1415 //
1416 // Better be whitespace
1417 //
1418 Len = SkipWhiteSpace (Cptr);
1419 if (Len) {
1420 Cptr += Len;
1421 //
1422 // See if it's a valid symbol name
1423 //
1424 Len = ValidSymbolName (Cptr);
1425 if (Len) {
1426 //
1427 // It is a valid symbol name. See if there's a line continuation,
1428 // and if so, read one more line.
1429 // Then truncate after the symbol name, look for the string "GUID",
1430 // and continue.
1431 //
1432 SymName = Cptr;
1433 LineLen = strlen (Line);
1434 if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {
1435 fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);
1436 } else if (Line[LineLen - 1] == '\\') {
1437 fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);
1438 }
1439
1440 CSavePtr = Cptr + Len;
1441 CSave = *CSavePtr;
1442 *CSavePtr = 0;
1443 while (*Cptr) {
1444 if (strncmp (Cptr, "GUID", 4) == 0) {
1445 break;
1446 }
1447
1448 Cptr++;
1449 }
1450 //
1451 // If we didn't run out of string, then we found the GUID string.
1452 // Now look for { 0x....... }
1453 //
1454 if (*Cptr) {
1455 Cptr = CSavePtr;
1456 *CSavePtr = CSave;
1457 Cptr += SkipWhiteSpace (Cptr);
1458 if (*Cptr == '{') {
1459 *Cptr = 0;
1460 Cptr++;
1461 //
1462 // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
1463 // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters
1464 // in the string.
1465 //
1466 for (TempCptr = Cptr; *TempCptr; TempCptr++) {
1467 if (*TempCptr == 'L') {
1468 if (*(TempCptr + 1) == ',') {
1469 *TempCptr = ',';
1470 *(TempCptr + 1) = ' ';
1471 }
1472 }
1473 }
1474
1475 if (sscanf (
1476 Cptr,
1477 "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",
1478 &GuidScan[0],
1479 &GuidScan[1],
1480 &GuidScan[2],
1481 &GuidScan[3],
1482 &GuidScan[4],
1483 &GuidScan[5],
1484 &GuidScan[6],
1485 &GuidScan[7],
1486 &GuidScan[8],
1487 &GuidScan[9],
1488 &GuidScan[10]
1489 ) == 11) {
1490 AddGuid11 (FileName, GuidScan, SymName);
1491 }
1492 }
1493 }
1494 }
1495 }
1496 }
1497 //
1498 // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... };
1499 //
1500 } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) {
1501 //
1502 // Read the next line if line continuation
1503 //
1504 LineLen = strlen (Line);
1505 if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {
1506 fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);
1507 } else if (Line[LineLen - 1] == '\\') {
1508 fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);
1509 }
1510
1511 Cptr = CSavePtr + 8;
1512 Cptr += SkipWhiteSpace (Cptr);
1513 //
1514 // Should be variable name next
1515 //
1516 Len = ValidSymbolName (Cptr);
1517 SymName = Cptr;
1518 Cptr += Len;
1519 Cptr += SkipWhiteSpace (Cptr);
1520 if (*Cptr == '=') {
1521 Cptr++;
1522 Cptr += SkipWhiteSpace (Cptr);
1523 //
1524 // Should be open-brace next to define guid
1525 //
1526 if (*Cptr == '{') {
1527 Cptr++;
1528 //
1529 // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
1530 //
1531 if (sscanf (
1532 Cptr,
1533 "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",
1534 &GuidScan[0],
1535 &GuidScan[1],
1536 &GuidScan[2],
1537 &GuidScan[3],
1538 &GuidScan[4],
1539 &GuidScan[5],
1540 &GuidScan[6],
1541 &GuidScan[7],
1542 &GuidScan[8],
1543 &GuidScan[9],
1544 &GuidScan[10]
1545 ) == 11) {
1546 AddGuid11 (FileName, GuidScan, Cptr);
1547 //
1548 // printf ("Found guid: %s", Cptr);
1549 //
1550 }
1551 }
1552 }
1553 }
1554 }
1555
1556 fclose (Fptr);
1557 return STATUS_SUCCESS;
1558 }
1559 //
1560 // Process Intel Itanium(TM) GUID definitions. Look for:
1561 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1562 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1563 // in either order.
1564 // This function assumes no blank lines between definitions.
1565 //
1566 static
1567 STATUS
1568 ProcessIA64FileGuids (
1569 INT8 *FileName
1570 )
1571 {
1572 FILE *Fptr;
1573 INT8 Line[MAX_LINE_LEN];
1574 UINT32 Guid1H;
1575 UINT32 Guid1L;
1576 UINT32 Guid2H;
1577 UINT32 Guid2L;
1578 INT8 SymName1[MAX_LINE_LEN];
1579 INT8 SymName2[MAX_LINE_LEN];
1580 BOOLEAN Done;
1581 BOOLEAN LowFirst;
1582 BOOLEAN FoundLow;
1583
1584 if ((Fptr = fopen (FileName, "r")) == NULL) {
1585 Error (NULL, 0, 0, FileName, "could not open input file for reading");
1586 return STATUS_ERROR;
1587 }
1588
1589 Done = FALSE;
1590 if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1591 Done = 1;
1592 }
1593 //
1594 // Read lines from the file until done. Since the guid definition takes
1595 // two lines, we read lines in different places to recover gracefully
1596 // from mismatches. For example, if you thought you found the first half,
1597 // but the next line had a symbol mismatch, then you have to process the
1598 // line again in case it's the start of a new definition.
1599 //
1600 while (!Done) {
1601 //
1602 // Check current line for GUID definition. Assume low define first.
1603 //
1604 if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) {
1605 //
1606 // Might have to swap guids later. Save off if we found the LOW first
1607 //
1608 if (FoundLow) {
1609 LowFirst = TRUE;
1610 } else {
1611 LowFirst = FALSE;
1612 }
1613 //
1614 // Read the next line and try for the rest of the guid definition
1615 //
1616 if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1617 Done = 1;
1618 } else {
1619 if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) {
1620 //
1621 // Found another. If the symbol names match, then save it off.
1622 //
1623 if (strcmp (SymName1, SymName2) == 0) {
1624 //
1625 // Yea, found one. Save it off.
1626 //
1627 if (LowFirst) {
1628 AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L);
1629 } else {
1630 AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L);
1631 }
1632 //
1633 // Read the next line for processing
1634 //
1635 if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1636 Done = 1;
1637 }
1638 } else {
1639 //
1640 // Don't get another line so that we reprocess this line in case it
1641 // contains the start of a new definition.
1642 // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n",
1643 // FileName, SymName1, SymName2);
1644 //
1645 }
1646 } else {
1647 //
1648 // Second line was not a guid definition. Get the next line from the
1649 // file.
1650 //
1651 if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1652 Done = 1;
1653 }
1654 }
1655 }
1656 } else {
1657 //
1658 // Not a guid define line. Next.
1659 //
1660 if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1661 Done = 1;
1662 }
1663 }
1664 }
1665
1666 fclose (Fptr);
1667 return STATUS_SUCCESS;
1668 }
1669 //
1670 // Given a line from an Itanium-based assembly file, check the line for a guid
1671 // defininition. One of either:
1672 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1673 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1674 // Return the defined value as two 32-bit values, and whether it's a high
1675 // or low guid.
1676 //
1677 static
1678 BOOLEAN
1679 IsIA64GuidLine (
1680 INT8 *Line,
1681 UINT32 *GuidHigh,
1682 UINT32 *GuidLow,
1683 BOOLEAN *FoundLow,
1684 INT8 *SymName
1685 )
1686 {
1687 INT8 *Cptr;
1688 INT8 CSave;
1689 INT8 *CSavePtr;
1690 INT8 *SymStart;
1691 UINT32 Len;
1692
1693 Cptr = Line;
1694 Cptr += SkipWhiteSpace (Cptr);
1695 //
1696 // look for #define xxxGUID[L|H] 0xHexValue
1697 //
1698 if (*Cptr == '#') {
1699 Cptr++;
1700 Cptr += SkipWhiteSpace (Cptr);
1701 //
1702 // Look for "define"
1703 //
1704 if (!strncmp (Cptr, "define", 6)) {
1705 Cptr += 6;
1706 //
1707 // Better be whitespace
1708 //
1709 Len = SkipWhiteSpace (Cptr);
1710 if (Len) {
1711 Cptr += Len;
1712 //
1713 // See if it's a valid symbol name
1714 //
1715 Len = ValidSymbolName (Cptr);
1716 if (Len) {
1717 //
1718 // Save the start so we can copy it to their string if later checks are ok
1719 //
1720 SymStart = Cptr;
1721 //
1722 // It is a valid symbol name, look for the string GuidL or GuidH
1723 //
1724 CSavePtr = Cptr + Len;
1725 CSave = *CSavePtr;
1726 *CSavePtr = 0;
1727 while (*Cptr) {
1728 if (strncmp (Cptr, "GuidL", 5) == 0) {
1729 *FoundLow = 1;
1730 break;
1731 } else if (strncmp (Cptr, "GuidH", 5) == 0) {
1732 *FoundLow = 0;
1733 break;
1734 }
1735
1736 Cptr++;
1737 }
1738 //
1739 // If we didn't run out of string, then we found the GUID string.
1740 // Restore the null character we inserted above and continue.
1741 // Now look for 0x.......
1742 //
1743 if (*Cptr) {
1744 //
1745 // Return symbol name less the "L" or "H"
1746 //
1747 strcpy (SymName, SymStart);
1748 SymName[strlen (SymName) - 1] = 0;
1749 Cptr = CSavePtr;
1750 *CSavePtr = CSave;
1751 Cptr += SkipWhiteSpace (Cptr);
1752 if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) {
1753 //
1754 // skip over "0x"
1755 //
1756 Cptr += 2;
1757 //
1758 // 0x0123456789ABCDEF -- null terminate after 8 characters,
1759 // scan, replace the character and scan at that point.
1760 //
1761 CSave = *(Cptr + 8);
1762 *(Cptr + 8) = 0;
1763 if (sscanf (Cptr, "%X", GuidHigh) == 1) {
1764 *(Cptr + 8) = CSave;
1765 if (sscanf (Cptr + 8, "%X", GuidLow) == 1) {
1766 return TRUE;
1767 }
1768 }
1769 }
1770 }
1771 }
1772 }
1773 }
1774 }
1775
1776 return FALSE;
1777 }
1778 //
1779 // Look at the characters in the string and determine if it's a valid
1780 // symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]*
1781 //
1782 static
1783 UINT32
1784 ValidSymbolName (
1785 INT8 *Name
1786 )
1787 {
1788 int Len;
1789
1790 Len = 0;
1791
1792 //
1793 // Test first character
1794 //
1795 if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) {
1796 Name++;
1797 Len = 1;
1798 while (*Name) {
1799 if (((*Name >= 'a') && (*Name <= 'z')) ||
1800 ((*Name >= 'A') && (*Name <= 'Z')) ||
1801 ((*Name >= '0') && (*Name <= '9')) ||
1802 (*Name == '_')
1803 ) {
1804 Name++;
1805 Len++;
1806 } else {
1807 break;
1808 }
1809 }
1810 }
1811
1812 return Len;
1813 }
1814
1815 static
1816 UINT32
1817 SkipWhiteSpace (
1818 INT8 *Str
1819 )
1820 {
1821 UINT32 Len;
1822 Len = 0;
1823 while (isspace (*Str) && *Str) {
1824 Len++;
1825 Str++;
1826 }
1827
1828 return Len;
1829 }
1830 //
1831 // found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
1832 //
1833 static
1834 STATUS
1835 AddPkgGuid (
1836 INT8 *FileName,
1837 UINT32 *Data,
1838 UINT64 *Data64
1839 )
1840 {
1841 GUID_RECORD *NewRec;
1842 int Index;
1843
1844 //
1845 // Sanity check the data
1846 //
1847 if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) {
1848 Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL);
1849 return STATUS_ERROR;
1850 }
1851 //
1852 // More checks for Data64?
1853 // Allocate memory for a new one guid structure
1854 //
1855 NewRec = malloc (sizeof (GUID_RECORD));
1856 if (NewRec == NULL) {
1857 Error (NULL, 0, 0, "memory allocation failure", NULL);
1858 return STATUS_ERROR;
1859 }
1860
1861 memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1862 NewRec->FileName = malloc (strlen (FileName) + 1);
1863 if (NewRec->FileName == NULL) {
1864 free (NewRec);
1865 Error (NULL, 0, 0, "memory allocation failure", NULL);
1866 return STATUS_ERROR;
1867 }
1868
1869 strcpy (NewRec->FileName, FileName);
1870 NewRec->Guid.Data1 = Data[0];
1871 NewRec->Guid.Data2 = (UINT16) Data[1];
1872 NewRec->Guid.Data3 = (UINT16) Data[2];
1873 NewRec->Guid.Data4[0] = (UINT8) Data[3];
1874 NewRec->Guid.Data4[1] = (UINT8) (Data[3] >> 8);
1875 for (Index = 2; Index < 8; Index++) {
1876 NewRec->Guid.Data4[Index] = (UINT8) *Data64;
1877 *Data64 >>= 8;
1878 }
1879 //
1880 // Add it to the list
1881 //
1882 NewRec->Next = gGuidList;
1883 gGuidList = NewRec;
1884
1885 //
1886 // Report it
1887 // ReportGuid (FileName, NewRec);
1888 //
1889 return STATUS_SUCCESS;
1890 }
1891 //
1892 // Add a guid consisting of 11 fields to our list of guids
1893 //
1894 static
1895 STATUS
1896 AddGuid11 (
1897 INT8 *FileName,
1898 UINT32 *Data,
1899 INT8 *SymName
1900 )
1901 {
1902 GUID_RECORD *NewRec;
1903 int Index;
1904
1905 //
1906 // Sanity check the data
1907 //
1908 if (!CheckGuidData (Data, 11)) {
1909 return STATUS_ERROR;
1910 }
1911 //
1912 // Allocate memory for a new one guid structure
1913 //
1914 NewRec = malloc (sizeof (GUID_RECORD));
1915 if (NewRec == NULL) {
1916 Error (NULL, 0, 0, "memory allocation failure", NULL);
1917 return STATUS_ERROR;
1918 }
1919
1920 memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1921 NewRec->FileName = malloc (strlen (FileName) + 1);
1922 if (NewRec->FileName == NULL) {
1923 free (NewRec);
1924 Error (NULL, 0, 0, "memory allocation failure", NULL);
1925 return STATUS_ERROR;
1926 }
1927
1928 strcpy (NewRec->FileName, FileName);
1929 if (SymName != NULL) {
1930 NewRec->SymName = malloc (strlen (SymName) + 1);
1931 if (NewRec->SymName == NULL) {
1932 free (NewRec);
1933 Error (NULL, 0, 0, "memory allocation failure", NULL);
1934 return STATUS_ERROR;
1935 }
1936 }
1937
1938 strcpy (NewRec->SymName, SymName);
1939
1940 NewRec->Guid.Data1 = Data[0];
1941 NewRec->Guid.Data2 = (UINT16) Data[1];
1942 NewRec->Guid.Data3 = (UINT16) Data[2];
1943 for (Index = 0; Index < 8; Index++) {
1944 NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index];
1945 }
1946 //
1947 // Add it to the list
1948 //
1949 NewRec->Next = gGuidList;
1950 gGuidList = NewRec;
1951
1952 //
1953 // Report it
1954 // ReportGuid (FileName, NewRec);
1955 //
1956 return STATUS_SUCCESS;
1957 }
1958 //
1959 // For debug purposes, print each guid found
1960 //
1961 // static
1962 // VOID
1963 // ReportGuid (
1964 // INT8 *FileName,
1965 // GUID_RECORD *NewGuid
1966 // )
1967 // {
1968 // //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1);
1969 // }
1970 //
1971 // Free up memory we allocated to keep track of guids defined.
1972 //
1973 static
1974 VOID
1975 FreeGuids (
1976 VOID
1977 )
1978 {
1979 GUID_RECORD *NextRec;
1980 while (gGuidList != NULL) {
1981 NextRec = gGuidList->Next;
1982 if (gGuidList->FileName != NULL) {
1983 free (gGuidList->FileName);
1984 }
1985
1986 if (gGuidList->SymName != NULL) {
1987 free (gGuidList->SymName);
1988 }
1989
1990 free (gGuidList);
1991 gGuidList = NextRec;
1992 }
1993 }
1994
1995 static
1996 VOID
1997 FreeSigs (
1998 VOID
1999 )
2000 {
2001 SIGNATURE_RECORD *NextRec;
2002 while (gSignatureList != NULL) {
2003 NextRec = gSignatureList->Next;
2004 if (gSignatureList->FileName != NULL) {
2005 free (gSignatureList->FileName);
2006 }
2007
2008 free (gSignatureList);
2009 gSignatureList = NextRec;
2010 }
2011 }
2012 //
2013 // Scan through all guids defined and compare each for duplicates.
2014 //
2015 static
2016 STATUS
2017 CheckDuplicates (
2018 VOID
2019 )
2020 {
2021 GUID_RECORD *CurrentFile;
2022
2023 GUID_RECORD *TempFile;
2024 SIGNATURE_RECORD *CurrentSig;
2025 SIGNATURE_RECORD *TempSig;
2026 STATUS Status;
2027 int Index;
2028 int DupCount;
2029 int Len;
2030 BOOLEAN Same;
2031 UINT32 GuidSum;
2032 INT8 *SymName;
2033
2034 Status = STATUS_SUCCESS;
2035
2036 //
2037 // If we're checking guids.....
2038 //
2039 if (gOptions.CheckGuids) {
2040 //
2041 // If -p option, print all guids found
2042 //
2043 if (gOptions.PrintFound) {
2044 CurrentFile = gGuidList;
2045 while (CurrentFile != NULL) {
2046 fprintf (
2047 stdout,
2048 "GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X %s\n",
2049 (UINT32) CurrentFile->Guid.Data1,
2050 (UINT32) CurrentFile->Guid.Data2,
2051 (UINT32) CurrentFile->Guid.Data3,
2052 (UINT32) CurrentFile->Guid.Data4[0],
2053 (UINT32) CurrentFile->Guid.Data4[1],
2054 (UINT32) CurrentFile->Guid.Data4[2],
2055 (UINT32) CurrentFile->Guid.Data4[3],
2056 (UINT32) CurrentFile->Guid.Data4[4],
2057 (UINT32) CurrentFile->Guid.Data4[5],
2058 (UINT32) CurrentFile->Guid.Data4[6],
2059 (UINT32) CurrentFile->Guid.Data4[7],
2060 CurrentFile->FileName
2061 );
2062 CurrentFile = CurrentFile->Next;
2063 }
2064 }
2065
2066 if (gOptions.GuidXReference) {
2067 CurrentFile = gGuidList;
2068 while (CurrentFile != NULL) {
2069 //
2070 // If no symbol name, print "unknown"
2071 //
2072 SymName = CurrentFile->SymName;
2073 if (SymName == NULL) {
2074 SymName = "unknown";
2075 }
2076
2077 fprintf (
2078 stdout,
2079 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n",
2080 (UINT32) CurrentFile->Guid.Data1,
2081 (UINT32) CurrentFile->Guid.Data2,
2082 (UINT32) CurrentFile->Guid.Data3,
2083 (UINT32) CurrentFile->Guid.Data4[0],
2084 (UINT32) CurrentFile->Guid.Data4[1],
2085 (UINT32) CurrentFile->Guid.Data4[2],
2086 (UINT32) CurrentFile->Guid.Data4[3],
2087 (UINT32) CurrentFile->Guid.Data4[4],
2088 (UINT32) CurrentFile->Guid.Data4[5],
2089 (UINT32) CurrentFile->Guid.Data4[6],
2090 (UINT32) CurrentFile->Guid.Data4[7],
2091 SymName
2092 );
2093 CurrentFile = CurrentFile->Next;
2094 }
2095 }
2096 //
2097 // Now go through all guids and report duplicates.
2098 //
2099 CurrentFile = gGuidList;
2100 while (CurrentFile != NULL) {
2101 DupCount = 0;
2102 TempFile = CurrentFile->Next;
2103 while (TempFile) {
2104 //
2105 // Compare the guids
2106 //
2107 if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) &&
2108 (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) &&
2109 (CurrentFile->Guid.Data3 == TempFile->Guid.Data3)
2110 ) {
2111 //
2112 // OR in all the guid bytes so we can ignore NULL-guid definitions.
2113 //
2114 GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3;
2115 Same = TRUE;
2116 for (Index = 0; Index < 8; Index++) {
2117 GuidSum |= CurrentFile->Guid.Data4[Index];
2118 if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) {
2119 Same = FALSE;
2120 break;
2121 }
2122 }
2123 //
2124 // If they're the same, and the guid was non-zero, print a message.
2125 //
2126 if (Same && GuidSum) {
2127 if (DupCount == 0) {
2128 Error (NULL, 0, 0, "duplicate GUIDS found", NULL);
2129 fprintf (stdout, " FILE1: %s\n", CurrentFile->FileName);
2130 }
2131
2132 DupCount++;
2133 fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempFile->FileName);
2134 //
2135 // Flag it as reported so we don't report it again if there's three or more
2136 //
2137 TempFile->Reported = TRUE;
2138 }
2139 }
2140 //
2141 // Next one
2142 //
2143 TempFile = TempFile->Next;
2144 }
2145 //
2146 // Print the guid if we found duplicates
2147 //
2148 if (DupCount) {
2149 fprintf (
2150 stdout,
2151 " GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
2152 (UINT32) CurrentFile->Guid.Data1,
2153 (UINT32) CurrentFile->Guid.Data2,
2154 (UINT32) CurrentFile->Guid.Data3,
2155 (UINT32) CurrentFile->Guid.Data4[0],
2156 (UINT32) CurrentFile->Guid.Data4[1],
2157 (UINT32) CurrentFile->Guid.Data4[2],
2158 (UINT32) CurrentFile->Guid.Data4[3],
2159 (UINT32) CurrentFile->Guid.Data4[4],
2160 (UINT32) CurrentFile->Guid.Data4[5],
2161 (UINT32) CurrentFile->Guid.Data4[6],
2162 (UINT32) CurrentFile->Guid.Data4[7]
2163 );
2164 //
2165 // return STATUS_ERROR;
2166 //
2167 }
2168 //
2169 // Find the next one that hasn't been reported
2170 //
2171 do {
2172 CurrentFile = CurrentFile->Next;
2173 } while ((CurrentFile != NULL) && (CurrentFile->Reported));
2174 }
2175 }
2176
2177 if (gOptions.CheckSignatures) {
2178 //
2179 // Print ones found if specified
2180 //
2181 if (gOptions.PrintFound) {
2182 CurrentSig = gSignatureList;
2183 while (CurrentSig != NULL) {
2184 Len = CurrentSig->Signature.DataLen;
2185 for (Index = 0; Index < Len; Index++) {
2186 fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
2187 }
2188
2189 fprintf (stdout, " %s\n", CurrentSig->FileName);
2190 CurrentSig = CurrentSig->Next;
2191 }
2192 }
2193
2194 CurrentSig = gSignatureList;
2195 while (CurrentSig != NULL) {
2196 DupCount = 0;
2197 TempSig = CurrentSig->Next;
2198 Len = CurrentSig->Signature.DataLen;
2199 while (TempSig) {
2200 //
2201 // Check for same length, then do string compare
2202 //
2203 if (Len == TempSig->Signature.DataLen) {
2204 if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) {
2205 //
2206 // Print header message if first failure for this sig
2207 //
2208 if (DupCount == 0) {
2209 Error (NULL, 0, 0, "duplicate signatures found", NULL);
2210 fprintf (stdout, " FILE1: %s\n", CurrentSig->FileName);
2211 }
2212
2213 DupCount++;
2214 fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempSig->FileName);
2215 TempSig->Reported = TRUE;
2216 }
2217 }
2218
2219 TempSig = TempSig->Next;
2220 }
2221
2222 if (DupCount) {
2223 fprintf (stdout, " SIG: ");
2224 for (Index = 0; Index < Len; Index++) {
2225 fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
2226 }
2227
2228 fprintf (stdout, "\n");
2229 }
2230 //
2231 // On to the next one that hasn't been reported
2232 //
2233 do {
2234 CurrentSig = CurrentSig->Next;
2235 } while ((CurrentSig != NULL) && (CurrentSig->Reported));
2236 }
2237 }
2238
2239 return Status;
2240 }
2241
2242 static
2243 VOID
2244 FreeOptions (
2245 VOID
2246 )
2247 /*++
2248
2249 Routine Description:
2250 Free up any memory we allocated when processing command-line options.
2251
2252 Arguments:
2253 None.
2254
2255 Returns:
2256 NA
2257
2258 Notes:
2259 We don't free up the ->Str fields because we did not allocate them.
2260 Instead, we just set the pointer to point to the actual parameter
2261 from the command line.
2262
2263 --*/
2264 {
2265 STRING_LIST *Ptr;
2266 while (gOptions.ExcludeDirs != NULL) {
2267 Ptr = gOptions.ExcludeDirs->Next;
2268 //
2269 // free (gOptions.ExcludeDirs->Str);
2270 //
2271 free (gOptions.ExcludeDirs);
2272 gOptions.ExcludeDirs = Ptr;
2273 }
2274
2275 while (gOptions.ExcludeSubDirs != NULL) {
2276 Ptr = gOptions.ExcludeSubDirs->Next;
2277 //
2278 // free (gOptions.ExcludeSubDirs->Str);
2279 //
2280 free (gOptions.ExcludeSubDirs);
2281 gOptions.ExcludeSubDirs = Ptr;
2282 }
2283
2284 while (gOptions.ExcludeExtensions != NULL) {
2285 Ptr = gOptions.ExcludeExtensions->Next;
2286 //
2287 // free (gOptions.ExcludeExtensions->Str);
2288 //
2289 free (gOptions.ExcludeExtensions);
2290 gOptions.ExcludeExtensions = Ptr;
2291 }
2292
2293 while (gOptions.ExcludeFiles != NULL) {
2294 Ptr = gOptions.ExcludeFiles->Next;
2295 //
2296 // free (gOptions.ExcludeFiles->Str);
2297 //
2298 free (gOptions.ExcludeFiles);
2299 gOptions.ExcludeFiles = Ptr;
2300 }
2301 }
2302 //
2303 // Given an array of 32-bit data, validate the data for the given number of
2304 // guid data. For example, it might have been scanned as 16 bytes of data, or
2305 // 11 fields of data.
2306 //
2307 static
2308 BOOLEAN
2309 CheckGuidData (
2310 UINT32 *Data,
2311 UINT32 DataCount
2312 )
2313 {
2314 UINT32 Index;
2315
2316 if (DataCount == 16) {
2317 for (Index = 0; Index < 16; Index++) {
2318 if (Data[Index] &~0xFF) {
2319 return FALSE;
2320 }
2321 }
2322
2323 return TRUE;
2324 } else if (DataCount == 11) {
2325 //
2326 // Data[0] never out of range (32-bit)
2327 //
2328 if ((Data[1] | Data[2]) &~0xFFFF) {
2329 //
2330 // Error ("Out of range value for GUID data word(s) [1] and/or [2]");
2331 //
2332 return FALSE;
2333 }
2334
2335 for (Index = 0; Index < 8; Index++) {
2336 if (Data[Index + 3] &~0xFF) {
2337 //
2338 // Error ("Out of range value for GUID data byte(s) [4] - [11]");
2339 //
2340 return FALSE;
2341 }
2342 }
2343
2344 return TRUE;
2345 }
2346
2347 return FALSE;
2348 }