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