Home | History | Annotate | Line # | Download | only in compiler
aslcompile.c revision 1.15
      1 /******************************************************************************
      2  *
      3  * Module Name: aslcompile - top level compile module
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "acnamesp.h"
     46 
     47 #include <stdio.h>
     48 #include <time.h>
     49 #include <acapps.h>
     50 
     51 #define _COMPONENT          ACPI_COMPILER
     52         ACPI_MODULE_NAME    ("aslcompile")
     53 
     54 /*
     55  * Main parser entry
     56  * External is here in case the parser emits the same external in the
     57  * generated header. (Newer versions of Bison)
     58  */
     59 int
     60 AslCompilerparse(
     61     void);
     62 
     63 /* Local prototypes */
     64 
     65 static void
     66 CmFlushSourceCode (
     67     void);
     68 
     69 static void
     70 CmDumpAllEvents (
     71     void);
     72 
     73 
     74 /*******************************************************************************
     75  *
     76  * FUNCTION:    CmDoCompile
     77  *
     78  * PARAMETERS:  None
     79  *
     80  * RETURN:      Status (0 = OK)
     81  *
     82  * DESCRIPTION: This procedure performs the entire compile
     83  *
     84  ******************************************************************************/
     85 
     86 int
     87 CmDoCompile (
     88     void)
     89 {
     90     ACPI_STATUS             Status;
     91     UINT8                   FullCompile;
     92     UINT8                   Event;
     93 
     94 
     95     FullCompile = UtBeginEvent ("*** Total Compile time ***");
     96     Event = UtBeginEvent ("Open input and output files");
     97     UtEndEvent (Event);
     98 
     99     Event = UtBeginEvent ("Preprocess input file");
    100     if (AslGbl_PreprocessFlag)
    101     {
    102         /* Enter compiler name as a #define */
    103 
    104         PrAddDefine (ASL_DEFINE, "", FALSE);
    105 
    106         /* Preprocessor */
    107 
    108         PrDoPreprocess ();
    109         AslGbl_CurrentLineNumber = 1;
    110         AslGbl_LogicalLineNumber = 1;
    111 
    112         if (AslGbl_PreprocessOnly)
    113         {
    114             UtEndEvent (Event);
    115             CmCleanupAndExit ();
    116             return (0);
    117         }
    118     }
    119     UtEndEvent (Event);
    120 
    121 
    122     /* Build the parse tree */
    123 
    124     Event = UtBeginEvent ("Parse source code and build parse tree");
    125     AslCompilerparse();
    126     UtEndEvent (Event);
    127 
    128     /* Check for parser-detected syntax errors */
    129 
    130     if (AslGbl_SyntaxError)
    131     {
    132         fprintf (stderr,
    133             "Compiler aborting due to parser-detected syntax error(s)\n");
    134         LsDumpParseTree ();
    135         goto ErrorExit;
    136     }
    137 
    138     /* Did the parse tree get successfully constructed? */
    139 
    140     if (!AslGbl_ParseTreeRoot)
    141     {
    142         /*
    143          * If there are no errors, then we have some sort of
    144          * internal problem.
    145          */
    146         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
    147             NULL, "- Could not resolve parse tree root node");
    148 
    149         goto ErrorExit;
    150     }
    151 
    152     /* Flush out any remaining source after parse tree is complete */
    153 
    154     Event = UtBeginEvent ("Flush source input");
    155     CmFlushSourceCode ();
    156 
    157     /* Prune the parse tree if requested (debug purposes only) */
    158 
    159     if (AslGbl_PruneParseTree)
    160     {
    161         AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType);
    162     }
    163 
    164     /* Optional parse tree dump, compiler debug output only */
    165 
    166     LsDumpParseTree ();
    167 
    168     OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child);
    169     UtEndEvent (Event);
    170 
    171     /* Pre-process parse tree for any operator transforms */
    172 
    173     Event = UtBeginEvent ("Parse tree transforms");
    174     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
    175     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    176         TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL);
    177     UtEndEvent (Event);
    178 
    179     /* Generate AML opcodes corresponding to the parse tokens */
    180 
    181     Event = UtBeginEvent ("Generate AML opcodes");
    182     DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n");
    183     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    184         OpcAmlOpcodeWalk, NULL);
    185     UtEndEvent (Event);
    186 
    187     /*
    188      * Now that the input is parsed, we can open the AML output file.
    189      * Note: by default, the name of this file comes from the table
    190      * descriptor within the input file.
    191      */
    192     Event = UtBeginEvent ("Open AML output file");
    193     Status = FlOpenAmlOutputFile (AslGbl_OutputFilenamePrefix);
    194     UtEndEvent (Event);
    195     if (ACPI_FAILURE (Status))
    196     {
    197         AePrintErrorLog (ASL_FILE_STDERR);
    198         return (-1);
    199     }
    200 
    201     /* Interpret and generate all compile-time constants */
    202 
    203     Event = UtBeginEvent ("Constant folding via AML interpreter");
    204     DbgPrint (ASL_DEBUG_OUTPUT,
    205         "Interpreting compile-time constant expressions\n\n");
    206 
    207     if (AslGbl_FoldConstants)
    208     {
    209         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    210             NULL, OpcAmlConstantWalk, NULL);
    211     }
    212     else
    213     {
    214         DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
    215     }
    216     UtEndEvent (Event);
    217 
    218     /* Update AML opcodes if necessary, after constant folding */
    219 
    220     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    221     DbgPrint (ASL_DEBUG_OUTPUT,
    222         "Updating AML opcodes after constant folding\n\n");
    223     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    224         NULL, OpcAmlOpcodeUpdateWalk, NULL);
    225     UtEndEvent (Event);
    226 
    227     /* Calculate all AML package lengths */
    228 
    229     Event = UtBeginEvent ("Generate AML package lengths");
    230     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    231     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    232         LnPackageLengthWalk, NULL);
    233     UtEndEvent (Event);
    234 
    235     if (AslGbl_ParseOnlyFlag)
    236     {
    237         AePrintErrorLog (ASL_FILE_STDERR);
    238         UtDisplaySummary (ASL_FILE_STDERR);
    239         if (AslGbl_DebugFlag)
    240         {
    241             /* Print error summary to the stdout also */
    242 
    243             AePrintErrorLog (ASL_FILE_STDOUT);
    244             UtDisplaySummary (ASL_FILE_STDOUT);
    245         }
    246         UtEndEvent (FullCompile);
    247         return (0);
    248     }
    249 
    250     /*
    251      * Create an internal namespace and use it as a symbol table
    252      */
    253 
    254     /* Namespace loading */
    255 
    256     Event = UtBeginEvent ("Create ACPI Namespace");
    257     DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n");
    258     Status = LdLoadNamespace (AslGbl_ParseTreeRoot);
    259     UtEndEvent (Event);
    260     if (ACPI_FAILURE (Status))
    261     {
    262         goto ErrorExit;
    263     }
    264 
    265     /* Namespace cross-reference */
    266 
    267     AslGbl_NamespaceEvent = UtBeginEvent (
    268         "Cross reference parse tree and Namespace");
    269     DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n");
    270     Status = XfCrossReferenceNamespace ();
    271     if (ACPI_FAILURE (Status))
    272     {
    273         goto ErrorExit;
    274     }
    275 
    276     /* Namespace - Check for non-referenced objects */
    277 
    278     LkFindUnreferencedObjects ();
    279     UtEndEvent (AslGbl_NamespaceEvent);
    280 
    281     /* Resolve External Declarations */
    282 
    283     Event = UtBeginEvent ("Resolve all Externals");
    284     DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n");
    285 
    286     if (AslGbl_DoExternalsInPlace)
    287     {
    288         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    289             ExAmlExternalWalkBegin, NULL, NULL);
    290     }
    291     else
    292     {
    293         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    294             ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL);
    295     }
    296     UtEndEvent (Event);
    297 
    298     /*
    299      * Semantic analysis. This can happen only after the
    300      * namespace has been loaded and cross-referenced.
    301      *
    302      * part one - check control methods
    303      */
    304     Event = UtBeginEvent ("Analyze control method return types");
    305     AslGbl_AnalysisWalkInfo.MethodStack = NULL;
    306 
    307     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n");
    308 
    309     if (AslGbl_CrossReferenceOutput)
    310     {
    311         OtPrintHeaders ("Part 1: Object Reference Map "
    312             "(Object references from within each control method)");
    313     }
    314 
    315     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    316         MtMethodAnalysisWalkBegin,
    317         MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo);
    318     UtEndEvent (Event);
    319 
    320     /* Generate the object cross-reference file if requested */
    321 
    322     Event = UtBeginEvent ("Generate cross-reference file");
    323     OtCreateXrefFile ();
    324     UtEndEvent (Event);
    325 
    326     /* Semantic error checking part two - typing of method returns */
    327 
    328     Event = UtBeginEvent ("Determine object types returned by methods");
    329     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n");
    330     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    331         NULL, AnMethodTypingWalkEnd, NULL);
    332     UtEndEvent (Event);
    333 
    334     /* Semantic error checking part three - operand type checking */
    335 
    336     Event = UtBeginEvent ("Analyze AML operand types");
    337     DbgPrint (ASL_DEBUG_OUTPUT,
    338         "Semantic analysis - Operand type checking\n\n");
    339     if (AslGbl_DoTypechecking)
    340     {
    341         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    342             NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo);
    343     }
    344     UtEndEvent (Event);
    345 
    346     /* Semantic error checking part four - other miscellaneous checks */
    347 
    348     Event = UtBeginEvent ("Miscellaneous analysis");
    349     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n");
    350     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    351         AnOtherSemanticAnalysisWalkBegin,
    352         NULL, &AslGbl_AnalysisWalkInfo);
    353     UtEndEvent (Event);
    354 
    355     /*
    356      * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the
    357      * very last comment of a given ASL file because it's the last constructed
    358      * node during compilation. We take the very last comment and save it in a
    359      * global for it to be used by the disassembler.
    360      */
    361     if (AcpiGbl_CaptureComments)
    362     {
    363         AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList;
    364         AslGbl_ParseTreeRoot->Asl.CommentList = NULL;
    365     }
    366 
    367     /* Calculate all AML package lengths */
    368 
    369     Event = UtBeginEvent ("Finish AML package length generation");
    370     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    371     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    372         LnInitLengthsWalk, NULL);
    373     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    374         LnPackageLengthWalk, NULL);
    375     UtEndEvent (Event);
    376 
    377     /* Code generation - emit the AML */
    378 
    379     Event = UtBeginEvent ("Generate AML code and write output files");
    380     DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n");
    381     CgGenerateAmlOutput ();
    382     UtEndEvent (Event);
    383 
    384     Event = UtBeginEvent ("Write optional output files");
    385     CmDoOutputFiles ();
    386     UtEndEvent (Event);
    387 
    388     UtEndEvent (FullCompile);
    389     CmCleanupAndExit ();
    390     return (0);
    391 
    392 ErrorExit:
    393     UtEndEvent (FullCompile);
    394     CmCleanupAndExit ();
    395     return (-1);
    396 }
    397 
    398 
    399 /*******************************************************************************
    400  *
    401  * FUNCTION:    AslCompilerSignon
    402  *
    403  * PARAMETERS:  FileId      - ID of the output file
    404  *
    405  * RETURN:      None
    406  *
    407  * DESCRIPTION: Display compiler signon
    408  *
    409  ******************************************************************************/
    410 
    411 void
    412 AslCompilerSignon (
    413     UINT32                  FileId)
    414 {
    415     char                    *Prefix = "";
    416     char                    *UtilityName;
    417 
    418 
    419     /* Set line prefix depending on the destination file type */
    420 
    421     switch (FileId)
    422     {
    423     case ASL_FILE_ASM_SOURCE_OUTPUT:
    424     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    425 
    426         Prefix = "; ";
    427         break;
    428 
    429     case ASL_FILE_HEX_OUTPUT:
    430 
    431         if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM)
    432         {
    433             Prefix = "; ";
    434         }
    435         else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) ||
    436                  (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL))
    437         {
    438             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
    439             Prefix = " * ";
    440         }
    441         break;
    442 
    443     case ASL_FILE_C_SOURCE_OUTPUT:
    444     case ASL_FILE_C_OFFSET_OUTPUT:
    445     case ASL_FILE_C_INCLUDE_OUTPUT:
    446 
    447         Prefix = " * ";
    448         break;
    449 
    450     default:
    451 
    452         /* No other output types supported */
    453 
    454         break;
    455     }
    456 
    457     /* Running compiler or disassembler? */
    458 
    459     if (AcpiGbl_DisasmFlag)
    460     {
    461         UtilityName = AML_DISASSEMBLER_NAME;
    462     }
    463     else
    464     {
    465         UtilityName = ASL_COMPILER_NAME;
    466     }
    467 
    468     /* Compiler signon with copyright */
    469 
    470     FlPrintFile (FileId, "%s\n", Prefix);
    471     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
    472 }
    473 
    474 
    475 /*******************************************************************************
    476  *
    477  * FUNCTION:    AslCompilerFileHeader
    478  *
    479  * PARAMETERS:  FileId      - ID of the output file
    480  *
    481  * RETURN:      None
    482  *
    483  * DESCRIPTION: Header used at the beginning of output files
    484  *
    485  ******************************************************************************/
    486 
    487 void
    488 AslCompilerFileHeader (
    489     UINT32                  FileId)
    490 {
    491     struct tm               *NewTime;
    492     time_t                  Aclock;
    493     char                    *Prefix = "";
    494 
    495 
    496     /* Set line prefix depending on the destination file type */
    497 
    498     switch (FileId)
    499     {
    500     case ASL_FILE_ASM_SOURCE_OUTPUT:
    501     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    502 
    503         Prefix = "; ";
    504         break;
    505 
    506     case ASL_FILE_HEX_OUTPUT:
    507 
    508         if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM)
    509         {
    510             Prefix = "; ";
    511         }
    512         else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) ||
    513                  (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL))
    514         {
    515             Prefix = " * ";
    516         }
    517         break;
    518 
    519     case ASL_FILE_C_SOURCE_OUTPUT:
    520     case ASL_FILE_C_OFFSET_OUTPUT:
    521     case ASL_FILE_C_INCLUDE_OUTPUT:
    522 
    523         Prefix = " * ";
    524         break;
    525 
    526     default:
    527 
    528         /* No other output types supported */
    529 
    530         break;
    531     }
    532 
    533     /* Compilation header with timestamp */
    534 
    535     (void) time (&Aclock);
    536     NewTime = localtime (&Aclock);
    537 
    538     FlPrintFile (FileId,
    539         "%sCompilation of \"%s\" - %s%s\n",
    540         Prefix, AslGbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
    541         Prefix);
    542 
    543     switch (FileId)
    544     {
    545     case ASL_FILE_C_SOURCE_OUTPUT:
    546     case ASL_FILE_C_OFFSET_OUTPUT:
    547     case ASL_FILE_C_INCLUDE_OUTPUT:
    548 
    549         FlPrintFile (FileId, " */\n");
    550         break;
    551 
    552     default:
    553 
    554         /* Nothing to do for other output types */
    555 
    556         break;
    557     }
    558 }
    559 
    560 
    561 /*******************************************************************************
    562  *
    563  * FUNCTION:    CmFlushSourceCode
    564  *
    565  * PARAMETERS:  None
    566  *
    567  * RETURN:      None
    568  *
    569  * DESCRIPTION: Read in any remaining source code after the parse tree
    570  *              has been constructed.
    571  *
    572  ******************************************************************************/
    573 
    574 static void
    575 CmFlushSourceCode (
    576     void)
    577 {
    578     char                    Buffer;
    579 
    580 
    581     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
    582     {
    583         AslInsertLineBuffer ((int) Buffer);
    584     }
    585 
    586     AslResetCurrentLineBuffer ();
    587 }
    588 
    589 
    590 /*******************************************************************************
    591  *
    592  * FUNCTION:    CmDoOutputFiles
    593  *
    594  * PARAMETERS:  None
    595  *
    596  * RETURN:      None.
    597  *
    598  * DESCRIPTION: Create all "listing" type files
    599  *
    600  ******************************************************************************/
    601 
    602 void
    603 CmDoOutputFiles (
    604     void)
    605 {
    606 
    607     /* Create listings and hex files */
    608 
    609     LsDoListings ();
    610     HxDoHexOutput ();
    611 
    612     /* Dump the namespace to the .nsp file if requested */
    613 
    614     (void) NsDisplayNamespace ();
    615 
    616     /* Dump the device mapping file */
    617 
    618     MpEmitMappingInfo ();
    619 }
    620 
    621 
    622 /*******************************************************************************
    623  *
    624  * FUNCTION:    CmDumpAllEvents
    625  *
    626  * PARAMETERS:  None
    627  *
    628  * RETURN:      None.
    629  *
    630  * DESCRIPTION: Dump all compiler events
    631  *
    632  ******************************************************************************/
    633 
    634 static void
    635 CmDumpAllEvents (
    636     void)
    637 {
    638     ASL_EVENT_INFO          *Event;
    639     UINT32                  Delta;
    640     UINT32                  MicroSeconds;
    641     UINT32                  MilliSeconds;
    642     UINT32                  i;
    643 
    644 
    645     Event = AslGbl_Events;
    646 
    647     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
    648     if (AslGbl_CompileTimesFlag)
    649     {
    650         printf ("\nElapsed time for major events\n\n");
    651     }
    652 
    653     for (i = 0; i < AslGbl_NextEvent; i++)
    654     {
    655         if (Event->Valid)
    656         {
    657             /* Delta will be in 100-nanosecond units */
    658 
    659             Delta = (UINT32) (Event->EndTime - Event->StartTime);
    660 
    661             MicroSeconds = Delta / ACPI_100NSEC_PER_USEC;
    662             MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC;
    663 
    664             /* Round milliseconds up */
    665 
    666             if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500)
    667             {
    668                 MilliSeconds++;
    669             }
    670 
    671             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
    672                 MicroSeconds, MilliSeconds, Event->EventName);
    673 
    674             if (AslGbl_CompileTimesFlag)
    675             {
    676                 printf ("%8u usec %8u msec - %s\n",
    677                     MicroSeconds, MilliSeconds, Event->EventName);
    678             }
    679         }
    680 
    681         Event++;
    682     }
    683 }
    684 
    685 
    686 /*******************************************************************************
    687  *
    688  * FUNCTION:    CmCleanupAndExit
    689  *
    690  * PARAMETERS:  None
    691  *
    692  * RETURN:      None.
    693  *
    694  * DESCRIPTION: Close all open files and exit the compiler
    695  *
    696  ******************************************************************************/
    697 
    698 void
    699 CmCleanupAndExit (
    700     void)
    701 {
    702     UINT32                  i;
    703     BOOLEAN                 DeleteAmlFile = FALSE;
    704 
    705 
    706     AslCheckExpectedExceptions ();
    707     AePrintErrorLog (ASL_FILE_STDERR);
    708     if (AslGbl_DebugFlag)
    709     {
    710         /* Print error summary to stdout also */
    711 
    712         AePrintErrorLog (ASL_FILE_STDOUT);
    713     }
    714 
    715     /* Emit compile times if enabled */
    716 
    717     CmDumpAllEvents ();
    718 
    719     if (AslGbl_CompileTimesFlag)
    720     {
    721         printf ("\nMiscellaneous compile statistics\n\n");
    722         printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes");
    723         printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches");
    724         printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects");
    725         printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods");
    726         printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations");
    727         printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory");
    728         printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded");
    729         printf ("\n");
    730     }
    731 
    732     if (AslGbl_NsLookupCount)
    733     {
    734         DbgPrint (ASL_DEBUG_OUTPUT,
    735             "\n\nMiscellaneous compile statistics\n\n");
    736 
    737         DbgPrint (ASL_DEBUG_OUTPUT,
    738             "%32s : %u\n", "Total Namespace searches",
    739             AslGbl_NsLookupCount);
    740 
    741         DbgPrint (ASL_DEBUG_OUTPUT,
    742             "%32s : %u usec\n", "Time per search", ((UINT32)
    743             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
    744                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
    745                 AslGbl_NsLookupCount);
    746     }
    747 
    748     if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    749     {
    750         printf ("\nMaximum error count (%d) exceeded\n",
    751             ASL_MAX_ERROR_COUNT);
    752     }
    753 
    754     UtDisplaySummary (ASL_FILE_STDOUT);
    755 
    756     /*
    757      * We will delete the AML file if there are errors and the
    758      * force AML output option has not been used.
    759      */
    760     if ((AslGbl_ExceptionCount[ASL_ERROR] > 0) &&
    761         (!AslGbl_IgnoreErrors) &&
    762         AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle)
    763     {
    764         DeleteAmlFile = TRUE;
    765     }
    766 
    767     /* Close all open files */
    768 
    769     /*
    770      * Take care with the preprocessor file (.pre), it might be the same
    771      * as the "input" file, depending on where the compiler has terminated
    772      * or aborted. Prevent attempt to close the same file twice in
    773      * loop below.
    774      */
    775     if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
    776         AslGbl_Files[ASL_FILE_INPUT].Handle)
    777     {
    778         AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
    779     }
    780 
    781     /* Close the standard I/O files */
    782 
    783     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
    784     {
    785         FlCloseFile (i);
    786     }
    787 
    788     /* Delete AML file if there are errors */
    789 
    790     if (DeleteAmlFile)
    791     {
    792         FlDeleteFile (ASL_FILE_AML_OUTPUT);
    793     }
    794 
    795     /* Delete the preprocessor temp file unless full debug was specified */
    796 
    797     if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile)
    798     {
    799         FlDeleteFile (ASL_FILE_PREPROCESSOR);
    800     }
    801 
    802     /*
    803      * Delete intermediate ("combined") source file (if -ls flag not set)
    804      * This file is created during normal ASL/AML compiles. It is not
    805      * created by the data table compiler.
    806      *
    807      * If the -ls flag is set, then the .SRC file should not be deleted.
    808      * In this case, Gbl_SourceOutputFlag is set to TRUE.
    809      *
    810      * Note: Handles are cleared by FlCloseFile above, so we look at the
    811      * filename instead, to determine if the .SRC file was actually
    812      * created.
    813      */
    814     if (!AslGbl_SourceOutputFlag)
    815     {
    816         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
    817     }
    818 
    819     /* Final cleanup after compiling one file */
    820 
    821     if (!AslGbl_DoAslConversion)
    822     {
    823         UtDeleteLocalCaches ();
    824     }
    825 }
    826