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