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