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