xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcompile.c (revision 7cd2dcf07629713e5a3d60472cfe4701b705a167)
1 /******************************************************************************
2  *
3  * Module Name: aslcompile - top level compile module
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
45 
46 #include <stdio.h>
47 #include <time.h>
48 #include <contrib/dev/acpica/include/acapps.h>
49 
50 #define _COMPONENT          ACPI_COMPILER
51         ACPI_MODULE_NAME    ("aslcompile")
52 
53 /* Local prototypes */
54 
55 static void
56 CmFlushSourceCode (
57     void);
58 
59 static void
60 FlConsumeAnsiComment (
61     FILE                    *Handle,
62     ASL_FILE_STATUS         *Status);
63 
64 static void
65 FlConsumeNewComment (
66     FILE                    *Handle,
67     ASL_FILE_STATUS         *Status);
68 
69 static void
70 CmDumpAllEvents (
71     void);
72 
73 
74 /*******************************************************************************
75  *
76  * FUNCTION:    AslCompilerSignon
77  *
78  * PARAMETERS:  FileId      - ID of the output file
79  *
80  * RETURN:      None
81  *
82  * DESCRIPTION: Display compiler signon
83  *
84  ******************************************************************************/
85 
86 void
87 AslCompilerSignon (
88     UINT32                  FileId)
89 {
90     char                    *Prefix = "";
91     char                    *UtilityName;
92 
93 
94     /* Set line prefix depending on the destination file type */
95 
96     switch (FileId)
97     {
98     case ASL_FILE_ASM_SOURCE_OUTPUT:
99     case ASL_FILE_ASM_INCLUDE_OUTPUT:
100 
101         Prefix = "; ";
102         break;
103 
104     case ASL_FILE_HEX_OUTPUT:
105 
106         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
107         {
108             Prefix = "; ";
109         }
110         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
111                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
112         {
113             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
114             Prefix = " * ";
115         }
116         break;
117 
118     case ASL_FILE_C_SOURCE_OUTPUT:
119     case ASL_FILE_C_INCLUDE_OUTPUT:
120 
121         Prefix = " * ";
122         break;
123 
124     default:
125         /* No other output types supported */
126         break;
127     }
128 
129     /* Running compiler or disassembler? */
130 
131     if (Gbl_DisasmFlag)
132     {
133         UtilityName = AML_DISASSEMBLER_NAME;
134     }
135     else
136     {
137         UtilityName = ASL_COMPILER_NAME;
138     }
139 
140     /* Compiler signon with copyright */
141 
142     FlPrintFile (FileId, "%s\n", Prefix);
143     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
144 }
145 
146 
147 /*******************************************************************************
148  *
149  * FUNCTION:    AslCompilerFileHeader
150  *
151  * PARAMETERS:  FileId      - ID of the output file
152  *
153  * RETURN:      None
154  *
155  * DESCRIPTION: Header used at the beginning of output files
156  *
157  ******************************************************************************/
158 
159 void
160 AslCompilerFileHeader (
161     UINT32                  FileId)
162 {
163     struct tm               *NewTime;
164     time_t                  Aclock;
165     char                    *Prefix = "";
166 
167 
168     /* Set line prefix depending on the destination file type */
169 
170     switch (FileId)
171     {
172     case ASL_FILE_ASM_SOURCE_OUTPUT:
173     case ASL_FILE_ASM_INCLUDE_OUTPUT:
174 
175         Prefix = "; ";
176         break;
177 
178     case ASL_FILE_HEX_OUTPUT:
179 
180         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
181         {
182             Prefix = "; ";
183         }
184         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
185                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
186         {
187             Prefix = " * ";
188         }
189         break;
190 
191     case ASL_FILE_C_SOURCE_OUTPUT:
192     case ASL_FILE_C_INCLUDE_OUTPUT:
193 
194         Prefix = " * ";
195         break;
196 
197     default:
198         /* No other output types supported */
199         break;
200     }
201 
202     /* Compilation header with timestamp */
203 
204     (void) time (&Aclock);
205     NewTime = localtime (&Aclock);
206 
207     FlPrintFile (FileId,
208         "%sCompilation of \"%s\" - %s%s\n",
209         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
210         Prefix);
211 
212     switch (FileId)
213     {
214     case ASL_FILE_C_SOURCE_OUTPUT:
215     case ASL_FILE_C_INCLUDE_OUTPUT:
216         FlPrintFile (FileId, " */\n");
217         break;
218 
219     default:
220         /* Nothing to do for other output types */
221         break;
222     }
223 }
224 
225 
226 /*******************************************************************************
227  *
228  * FUNCTION:    CmFlushSourceCode
229  *
230  * PARAMETERS:  None
231  *
232  * RETURN:      None
233  *
234  * DESCRIPTION: Read in any remaining source code after the parse tree
235  *              has been constructed.
236  *
237  ******************************************************************************/
238 
239 static void
240 CmFlushSourceCode (
241     void)
242 {
243     char                    Buffer;
244 
245 
246     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
247     {
248         AslInsertLineBuffer ((int) Buffer);
249     }
250 
251     AslResetCurrentLineBuffer ();
252 }
253 
254 
255 /*******************************************************************************
256  *
257  * FUNCTION:    FlConsume*
258  *
259  * PARAMETERS:  Handle              - Open input file
260  *              Status              - File current status struct
261  *
262  * RETURN:      Number of lines consumed
263  *
264  * DESCRIPTION: Step over both types of comment during check for ascii chars
265  *
266  ******************************************************************************/
267 
268 static void
269 FlConsumeAnsiComment (
270     FILE                    *Handle,
271     ASL_FILE_STATUS         *Status)
272 {
273     UINT8                   Byte;
274     BOOLEAN                 ClosingComment = FALSE;
275 
276 
277     while (fread (&Byte, 1, 1, Handle))
278     {
279         /* Scan until comment close is found */
280 
281         if (ClosingComment)
282         {
283             if (Byte == '/')
284             {
285                 return;
286             }
287 
288             if (Byte != '*')
289             {
290                 /* Reset */
291 
292                 ClosingComment = FALSE;
293             }
294         }
295         else if (Byte == '*')
296         {
297             ClosingComment = TRUE;
298         }
299 
300         /* Maintain line count */
301 
302         if (Byte == 0x0A)
303         {
304             Status->Line++;
305         }
306 
307         Status->Offset++;
308     }
309 }
310 
311 
312 static void
313 FlConsumeNewComment (
314     FILE                    *Handle,
315     ASL_FILE_STATUS         *Status)
316 {
317     UINT8                   Byte;
318 
319 
320     while (fread (&Byte, 1, 1, Handle))
321     {
322         Status->Offset++;
323 
324         /* Comment ends at newline */
325 
326         if (Byte == 0x0A)
327         {
328             Status->Line++;
329             return;
330         }
331     }
332 }
333 
334 
335 /*******************************************************************************
336  *
337  * FUNCTION:    FlCheckForAscii
338  *
339  * PARAMETERS:  Handle              - Open input file
340  *              Filename            - Input filename
341  *              DisplayErrors       - TRUE if error messages desired
342  *
343  * RETURN:      Status
344  *
345  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
346  *              within comments. Note: does not handle nested comments and does
347  *              not handle comment delimiters within string literals. However,
348  *              on the rare chance this happens and an invalid character is
349  *              missed, the parser will catch the error by failing in some
350  *              spectactular manner.
351  *
352  ******************************************************************************/
353 
354 ACPI_STATUS
355 FlCheckForAscii (
356     FILE                    *Handle,
357     char                    *Filename,
358     BOOLEAN                 DisplayErrors)
359 {
360     UINT8                   Byte;
361     ACPI_SIZE               BadBytes = 0;
362     BOOLEAN                 OpeningComment = FALSE;
363     ASL_FILE_STATUS         Status;
364 
365 
366     Status.Line = 1;
367     Status.Offset = 0;
368 
369     /* Read the entire file */
370 
371     while (fread (&Byte, 1, 1, Handle))
372     {
373         /* Ignore comment fields (allow non-ascii within) */
374 
375         if (OpeningComment)
376         {
377             /* Check for second comment open delimiter */
378 
379             if (Byte == '*')
380             {
381                 FlConsumeAnsiComment (Handle, &Status);
382             }
383 
384             if (Byte == '/')
385             {
386                 FlConsumeNewComment (Handle, &Status);
387             }
388 
389             /* Reset */
390 
391             OpeningComment = FALSE;
392         }
393         else if (Byte == '/')
394         {
395             OpeningComment = TRUE;
396         }
397 
398         /* Check for an ASCII character */
399 
400         if (!ACPI_IS_ASCII (Byte))
401         {
402             if ((BadBytes < 10) && (DisplayErrors))
403             {
404                 AcpiOsPrintf (
405                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
406                     Byte, Status.Line, Status.Offset);
407             }
408 
409             BadBytes++;
410         }
411 
412         /* Update line counter */
413 
414         else if (Byte == 0x0A)
415         {
416             Status.Line++;
417         }
418 
419         Status.Offset++;
420     }
421 
422     /* Seek back to the beginning of the source file */
423 
424     fseek (Handle, 0, SEEK_SET);
425 
426     /* Were there any non-ASCII characters in the file? */
427 
428     if (BadBytes)
429     {
430         if (DisplayErrors)
431         {
432             AcpiOsPrintf (
433                 "%u non-ASCII characters found in input source text, could be a binary file\n",
434                 BadBytes);
435             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
436         }
437 
438         return (AE_BAD_CHARACTER);
439     }
440 
441     /* File is OK (100% ASCII) */
442 
443     return (AE_OK);
444 }
445 
446 
447 /*******************************************************************************
448  *
449  * FUNCTION:    CmDoCompile
450  *
451  * PARAMETERS:  None
452  *
453  * RETURN:      Status (0 = OK)
454  *
455  * DESCRIPTION: This procedure performs the entire compile
456  *
457  ******************************************************************************/
458 
459 int
460 CmDoCompile (
461     void)
462 {
463     ACPI_STATUS             Status;
464     UINT8                   FullCompile;
465     UINT8                   Event;
466 
467 
468     FullCompile = UtBeginEvent ("*** Total Compile time ***");
469     Event = UtBeginEvent ("Open input and output files");
470     UtEndEvent (Event);
471 
472     Event = UtBeginEvent ("Preprocess input file");
473     if (Gbl_PreprocessFlag)
474     {
475         /* Preprocessor */
476 
477         PrDoPreprocess ();
478         if (Gbl_PreprocessOnly)
479         {
480             UtEndEvent (Event);
481             CmCleanupAndExit ();
482             return (0);
483         }
484     }
485     UtEndEvent (Event);
486 
487     /* Build the parse tree */
488 
489     Event = UtBeginEvent ("Parse source code and build parse tree");
490     AslCompilerparse();
491     UtEndEvent (Event);
492 
493     /* Flush out any remaining source after parse tree is complete */
494 
495     Event = UtBeginEvent ("Flush source input");
496     CmFlushSourceCode ();
497 
498     /* Did the parse tree get successfully constructed? */
499 
500     if (!RootNode)
501     {
502         /*
503          * If there are no errors, then we have some sort of
504          * internal problem.
505          */
506         Status = AslCheckForErrorExit ();
507         if (Status == AE_OK)
508         {
509             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
510                 NULL, "- Could not resolve parse tree root node");
511         }
512 
513         goto ErrorExit;
514     }
515 
516     /* Optional parse tree dump, compiler debug output only */
517 
518     LsDumpParseTree ();
519 
520     OpcGetIntegerWidth (RootNode);
521     UtEndEvent (Event);
522 
523     /* Pre-process parse tree for any operator transforms */
524 
525     Event = UtBeginEvent ("Parse tree transforms");
526     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
527     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
528         TrAmlTransformWalk, NULL, NULL);
529     UtEndEvent (Event);
530 
531     /* Generate AML opcodes corresponding to the parse tokens */
532 
533     Event = UtBeginEvent ("Generate AML opcodes");
534     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
535     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
536         OpcAmlOpcodeWalk, NULL);
537     UtEndEvent (Event);
538 
539     /*
540      * Now that the input is parsed, we can open the AML output file.
541      * Note: by default, the name of this file comes from the table descriptor
542      * within the input file.
543      */
544     Event = UtBeginEvent ("Open AML output file");
545     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
546     UtEndEvent (Event);
547     if (ACPI_FAILURE (Status))
548     {
549         AePrintErrorLog (ASL_FILE_STDERR);
550         return (-1);
551     }
552 
553     /* Interpret and generate all compile-time constants */
554 
555     Event = UtBeginEvent ("Constant folding via AML interpreter");
556     DbgPrint (ASL_DEBUG_OUTPUT,
557         "\nInterpreting compile-time constant expressions\n\n");
558     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
559         OpcAmlConstantWalk, NULL, NULL);
560     UtEndEvent (Event);
561 
562     /* Update AML opcodes if necessary, after constant folding */
563 
564     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
565     DbgPrint (ASL_DEBUG_OUTPUT,
566         "\nUpdating AML opcodes after constant folding\n\n");
567     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
568         NULL, OpcAmlOpcodeUpdateWalk, NULL);
569     UtEndEvent (Event);
570 
571     /* Calculate all AML package lengths */
572 
573     Event = UtBeginEvent ("Generate AML package lengths");
574     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
575     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
576         LnPackageLengthWalk, NULL);
577     UtEndEvent (Event);
578 
579     if (Gbl_ParseOnlyFlag)
580     {
581         AePrintErrorLog (ASL_FILE_STDERR);
582         UtDisplaySummary (ASL_FILE_STDERR);
583         if (Gbl_DebugFlag)
584         {
585             /* Print error summary to the stdout also */
586 
587             AePrintErrorLog (ASL_FILE_STDOUT);
588             UtDisplaySummary (ASL_FILE_STDOUT);
589         }
590         UtEndEvent (FullCompile);
591         return (0);
592     }
593 
594     /*
595      * Create an internal namespace and use it as a symbol table
596      */
597 
598     /* Namespace loading */
599 
600     Event = UtBeginEvent ("Create ACPI Namespace");
601     Status = LdLoadNamespace (RootNode);
602     UtEndEvent (Event);
603     if (ACPI_FAILURE (Status))
604     {
605         goto ErrorExit;
606     }
607 
608     /* Namespace cross-reference */
609 
610     AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
611     Status = LkCrossReferenceNamespace ();
612     if (ACPI_FAILURE (Status))
613     {
614         goto ErrorExit;
615     }
616 
617     /* Namespace - Check for non-referenced objects */
618 
619     LkFindUnreferencedObjects ();
620     UtEndEvent (AslGbl_NamespaceEvent);
621 
622     /*
623      * Semantic analysis. This can happen only after the
624      * namespace has been loaded and cross-referenced.
625      *
626      * part one - check control methods
627      */
628     Event = UtBeginEvent ("Analyze control method return types");
629     AnalysisWalkInfo.MethodStack = NULL;
630 
631     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
632     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
633         AnMethodAnalysisWalkBegin,
634         AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
635     UtEndEvent (Event);
636 
637     /* Semantic error checking part two - typing of method returns */
638 
639     Event = UtBeginEvent ("Determine object types returned by methods");
640     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
641     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
642         NULL, AnMethodTypingWalkEnd, NULL);
643     UtEndEvent (Event);
644 
645     /* Semantic error checking part three - operand type checking */
646 
647     Event = UtBeginEvent ("Analyze AML operand types");
648     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
649     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
650         NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
651     UtEndEvent (Event);
652 
653     /* Semantic error checking part four - other miscellaneous checks */
654 
655     Event = UtBeginEvent ("Miscellaneous analysis");
656     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
657     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
658         AnOtherSemanticAnalysisWalkBegin,
659         NULL, &AnalysisWalkInfo);
660     UtEndEvent (Event);
661 
662     /* Calculate all AML package lengths */
663 
664     Event = UtBeginEvent ("Finish AML package length generation");
665     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
666     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
667         LnInitLengthsWalk, NULL);
668     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
669         LnPackageLengthWalk, NULL);
670     UtEndEvent (Event);
671 
672     /* Code generation - emit the AML */
673 
674     Event = UtBeginEvent ("Generate AML code and write output files");
675     CgGenerateAmlOutput ();
676     UtEndEvent (Event);
677 
678     Event = UtBeginEvent ("Write optional output files");
679     CmDoOutputFiles ();
680     UtEndEvent (Event);
681 
682     UtEndEvent (FullCompile);
683     CmCleanupAndExit ();
684     return (0);
685 
686 ErrorExit:
687     UtEndEvent (FullCompile);
688     CmCleanupAndExit ();
689     return (-1);
690 }
691 
692 
693 /*******************************************************************************
694  *
695  * FUNCTION:    CmDoOutputFiles
696  *
697  * PARAMETERS:  None
698  *
699  * RETURN:      None.
700  *
701  * DESCRIPTION: Create all "listing" type files
702  *
703  ******************************************************************************/
704 
705 void
706 CmDoOutputFiles (
707     void)
708 {
709 
710     /* Create listings and hex files */
711 
712     LsDoListings ();
713     LsDoHexOutput ();
714 
715     /* Dump the namespace to the .nsp file if requested */
716 
717     (void) LsDisplayNamespace ();
718 }
719 
720 
721 /*******************************************************************************
722  *
723  * FUNCTION:    CmDumpAllEvents
724  *
725  * PARAMETERS:  None
726  *
727  * RETURN:      None.
728  *
729  * DESCRIPTION: Dump all compiler events
730  *
731  ******************************************************************************/
732 
733 static void
734 CmDumpAllEvents (
735     void)
736 {
737     ASL_EVENT_INFO          *Event;
738     UINT32                  Delta;
739     UINT32                  USec;
740     UINT32                  MSec;
741     UINT32                  i;
742 
743 
744     Event = AslGbl_Events;
745 
746     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
747     if (Gbl_CompileTimesFlag)
748     {
749         printf ("\nElapsed time for major events\n\n");
750     }
751 
752     for (i = 0; i < AslGbl_NextEvent; i++)
753     {
754         if (Event->Valid)
755         {
756             /* Delta will be in 100-nanosecond units */
757 
758             Delta = (UINT32) (Event->EndTime - Event->StartTime);
759 
760             USec = Delta / 10;
761             MSec = Delta / 10000;
762 
763             /* Round milliseconds up */
764 
765             if ((USec - (MSec * 1000)) >= 500)
766             {
767                 MSec++;
768             }
769 
770             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
771                 USec, MSec, Event->EventName);
772 
773             if (Gbl_CompileTimesFlag)
774             {
775                 printf ("%8u usec %8u msec - %s\n",
776                     USec, MSec, Event->EventName);
777             }
778         }
779 
780         Event++;
781     }
782 }
783 
784 
785 /*******************************************************************************
786  *
787  * FUNCTION:    CmCleanupAndExit
788  *
789  * PARAMETERS:  None
790  *
791  * RETURN:      None.
792  *
793  * DESCRIPTION: Close all open files and exit the compiler
794  *
795  ******************************************************************************/
796 
797 void
798 CmCleanupAndExit (
799     void)
800 {
801     UINT32                  i;
802     BOOLEAN                 DeleteAmlFile = FALSE;
803 
804 
805     AePrintErrorLog (ASL_FILE_STDERR);
806     if (Gbl_DebugFlag)
807     {
808         /* Print error summary to stdout also */
809 
810         AePrintErrorLog (ASL_FILE_STDOUT);
811     }
812 
813     /* Emit compile times if enabled */
814 
815     CmDumpAllEvents ();
816 
817     if (Gbl_CompileTimesFlag)
818     {
819         printf ("\nMiscellaneous compile statistics\n\n");
820         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
821         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
822         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
823         printf ("%11u : %s\n", TotalMethods, "Control methods");
824         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
825         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
826         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
827         printf ("\n");
828     }
829 
830     if (Gbl_NsLookupCount)
831     {
832         DbgPrint (ASL_DEBUG_OUTPUT,
833             "\n\nMiscellaneous compile statistics\n\n");
834 
835         DbgPrint (ASL_DEBUG_OUTPUT,
836             "%32s : %u\n", "Total Namespace searches",
837             Gbl_NsLookupCount);
838 
839         DbgPrint (ASL_DEBUG_OUTPUT,
840             "%32s : %u usec\n", "Time per search", ((UINT32)
841             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
842                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
843                 Gbl_NsLookupCount);
844     }
845 
846     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
847     {
848         printf ("\nMaximum error count (%u) exceeded\n",
849             ASL_MAX_ERROR_COUNT);
850     }
851 
852     UtDisplaySummary (ASL_FILE_STDOUT);
853 
854     /*
855      * We will delete the AML file if there are errors and the
856      * force AML output option has not been used.
857      */
858     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
859         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
860     {
861         DeleteAmlFile = TRUE;
862     }
863 
864     /* Close all open files */
865 
866     Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
867 
868     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
869     {
870         FlCloseFile (i);
871     }
872 
873     /* Delete AML file if there are errors */
874 
875     if (DeleteAmlFile)
876     {
877         FlDeleteFile (ASL_FILE_AML_OUTPUT);
878     }
879 
880     /* Delete the preprocessor output file (.i) unless -li flag is set */
881 
882     if (!Gbl_PreprocessorOutputFlag &&
883         Gbl_PreprocessFlag)
884     {
885         FlDeleteFile (ASL_FILE_PREPROCESSOR);
886     }
887 
888     /*
889      * Delete intermediate ("combined") source file (if -ls flag not set)
890      * This file is created during normal ASL/AML compiles. It is not
891      * created by the data table compiler.
892      *
893      * If the -ls flag is set, then the .SRC file should not be deleted.
894      * In this case, Gbl_SourceOutputFlag is set to TRUE.
895      *
896      * Note: Handles are cleared by FlCloseFile above, so we look at the
897      * filename instead, to determine if the .SRC file was actually
898      * created.
899      *
900      * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
901      */
902     if (!Gbl_SourceOutputFlag)
903     {
904         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
905     }
906 }
907