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