Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: aslcompile - top level compile module
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "aslcompiler.h"
    153 #include "acnamesp.h"
    154 
    155 #include <stdio.h>
    156 #include <time.h>
    157 #include <acapps.h>
    158 
    159 #define _COMPONENT          ACPI_COMPILER
    160         ACPI_MODULE_NAME    ("aslcompile")
    161 
    162 /*
    163  * Main parser entry
    164  * External is here in case the parser emits the same external in the
    165  * generated header. (Newer versions of Bison)
    166  */
    167 int
    168 AslCompilerparse(
    169     void);
    170 
    171 /* Local prototypes */
    172 
    173 static void
    174 CmFlushSourceCode (
    175     void);
    176 
    177 static void
    178 CmDumpAllEvents (
    179     void);
    180 
    181 static void
    182 CmFinishFiles(
    183     BOOLEAN                 DeleteAmlFile);
    184 
    185 
    186 /*******************************************************************************
    187  *
    188  * FUNCTION:    CmDoCompile
    189  *
    190  * PARAMETERS:  None
    191  *
    192  * RETURN:      Status (0 = OK)
    193  *
    194  * DESCRIPTION: This procedure performs the entire compile
    195  *
    196  ******************************************************************************/
    197 
    198 ACPI_STATUS
    199 CmDoCompile (
    200     void)
    201 {
    202     UINT8                   FullCompile;
    203     UINT8                   Event;
    204     ASL_GLOBAL_FILE_NODE    *FileNode;
    205 
    206 
    207     FullCompile = UtBeginEvent ("*** Total Compile time ***");
    208     Event = UtBeginEvent ("Open input and output files");
    209     UtEndEvent (Event);
    210 
    211     Event = UtBeginEvent ("Preprocess input file");
    212     if (AslGbl_PreprocessFlag)
    213     {
    214         /* Enter compiler name as a #define */
    215 
    216         PrAddDefine (ASL_DEFINE, "", FALSE);
    217 
    218         /* Preprocessor */
    219 
    220         PrDoPreprocess ();
    221         AslGbl_CurrentLineNumber = 1;
    222         AslGbl_LogicalLineNumber = 1;
    223         AslGbl_CurrentLineOffset = 0;
    224 
    225         if (AslGbl_PreprocessOnly)
    226         {
    227             UtEndEvent (Event);
    228             return (AE_OK);
    229         }
    230     }
    231     UtEndEvent (Event);
    232 
    233 
    234     /* Build the parse tree */
    235 
    236     Event = UtBeginEvent ("Parse source code and build parse tree");
    237     AslCompilerparse();
    238     UtEndEvent (Event);
    239 
    240     /* Check for parser-detected syntax errors */
    241 
    242     if (AslGbl_SyntaxError)
    243     {
    244         AslError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
    245             "Compiler aborting due to parser-detected syntax error(s)\n");
    246 
    247         /* Flag this error in the FileNode for compilation summary */
    248 
    249         FileNode = FlGetCurrentFileNode ();
    250         FileNode->ParserErrorDetected = TRUE;
    251         AslGbl_ParserErrorDetected = TRUE;
    252         LsDumpParseTree ();
    253         AePrintErrorLog(ASL_FILE_STDERR);
    254 
    255         goto ErrorExit;
    256     }
    257 
    258     /* Did the parse tree get successfully constructed? */
    259 
    260     if (!AslGbl_ParseTreeRoot)
    261     {
    262         /*
    263          * If there are no errors, then we have some sort of
    264          * internal problem.
    265          */
    266         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
    267             NULL, "- Could not resolve parse tree root node");
    268 
    269         goto ErrorExit;
    270     }
    271 
    272     AePrintErrorLog(ASL_FILE_STDERR);
    273 
    274     /* Flush out any remaining source after parse tree is complete */
    275 
    276     Event = UtBeginEvent ("Flush source input");
    277     CmFlushSourceCode ();
    278 
    279     /* Prune the parse tree if requested (debug purposes only) */
    280 
    281     if (AslGbl_PruneParseTree)
    282     {
    283         AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType);
    284     }
    285 
    286     /* Optional parse tree dump, compiler debug output only */
    287 
    288     LsDumpParseTree ();
    289 
    290     AslGbl_ParserErrorDetected = FALSE;
    291     AslGbl_SyntaxError = FALSE;
    292     UtEndEvent (Event);
    293     UtEndEvent (FullCompile);
    294 
    295     AslGbl_ParserErrorDetected = FALSE;
    296     AslGbl_SyntaxError = FALSE;
    297 ErrorExit:
    298     UtEndEvent (FullCompile);
    299     return (AE_ERROR);
    300 }
    301 
    302 
    303 /*******************************************************************************
    304  *
    305  * FUNCTION:    CmDoAslMiddleAndBackEnd
    306  *
    307  * PARAMETERS:  None
    308  *
    309  * RETURN:      Status of middle-end and back-end
    310  *
    311  * DESCRIPTION: Perform compiler middle-end (type checking and semantic
    312  *              analysis) and back-end (code generation)
    313  *
    314  ******************************************************************************/
    315 
    316 int
    317 CmDoAslMiddleAndBackEnd (
    318     void)
    319 {
    320     UINT8                   Event;
    321     ACPI_STATUS             Status;
    322 
    323 
    324     OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child);
    325 
    326     /* Pre-process parse tree for any operator transforms */
    327 
    328     Event = UtBeginEvent ("Parse tree transforms");
    329     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
    330     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    331         TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL);
    332     UtEndEvent (Event);
    333 
    334     /* Generate AML opcodes corresponding to the parse tokens */
    335 
    336     Event = UtBeginEvent ("Generate AML opcodes");
    337     DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n");
    338     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    339         NULL, OpcAmlOpcodeWalk, NULL);
    340     UtEndEvent (Event);
    341 
    342 
    343     /* Interpret and generate all compile-time constants */
    344 
    345     Event = UtBeginEvent ("Constant folding via AML interpreter");
    346     DbgPrint (ASL_DEBUG_OUTPUT,
    347         "Interpreting compile-time constant expressions\n\n");
    348 
    349     if (AslGbl_FoldConstants)
    350     {
    351         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    352             NULL, OpcAmlConstantWalk, NULL);
    353     }
    354     else
    355     {
    356         DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
    357     }
    358     UtEndEvent (Event);
    359 
    360     /* Update AML opcodes if necessary, after constant folding */
    361 
    362     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    363     DbgPrint (ASL_DEBUG_OUTPUT,
    364         "Updating AML opcodes after constant folding\n\n");
    365     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    366         NULL, OpcAmlOpcodeUpdateWalk, NULL);
    367     UtEndEvent (Event);
    368 
    369     /* Calculate all AML package lengths */
    370 
    371     Event = UtBeginEvent ("Generate AML package lengths");
    372     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    373     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    374         LnPackageLengthWalk, NULL);
    375     UtEndEvent (Event);
    376 
    377     if (AslGbl_ParseOnlyFlag)
    378     {
    379         AePrintErrorLog (ASL_FILE_STDERR);
    380         UtDisplaySummary (ASL_FILE_STDERR);
    381         if (AslGbl_DebugFlag)
    382         {
    383             /* Print error summary to the stdout also */
    384 
    385             AePrintErrorLog (ASL_FILE_STDOUT);
    386             UtDisplaySummary (ASL_FILE_STDOUT);
    387         }
    388         return (0);
    389     }
    390 
    391     /*
    392      * Create an internal namespace and use it as a symbol table
    393      */
    394 
    395     /* Namespace loading */
    396 
    397     Event = UtBeginEvent ("Create ACPI Namespace");
    398     DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n");
    399     Status = LdLoadNamespace (AslGbl_ParseTreeRoot);
    400     UtEndEvent (Event);
    401     if (ACPI_FAILURE (Status))
    402     {
    403         return (-1);
    404     }
    405 
    406     /* Namespace cross-reference */
    407 
    408     AslGbl_NamespaceEvent = UtBeginEvent (
    409         "Cross reference parse tree and Namespace");
    410     DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n");
    411     Status = XfCrossReferenceNamespace ();
    412     if (ACPI_FAILURE (Status))
    413     {
    414         return (-1);
    415     }
    416 
    417     /* Namespace - Check for non-referenced objects */
    418 
    419     LkFindUnreferencedObjects ();
    420     UtEndEvent (AslGbl_NamespaceEvent);
    421 
    422     /* Resolve External Declarations */
    423 
    424     Event = UtBeginEvent ("Resolve all Externals");
    425     DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n");
    426 
    427     if (AslGbl_DoExternalsInPlace)
    428     {
    429         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    430             ExAmlExternalWalkBegin, NULL, NULL);
    431     }
    432     else
    433     {
    434         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    435             ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL);
    436     }
    437     UtEndEvent (Event);
    438 
    439     /*
    440      * Semantic analysis. This can happen only after the
    441      * namespace has been loaded and cross-referenced.
    442      *
    443      * part one - check control methods
    444      */
    445     Event = UtBeginEvent ("Analyze control method return types");
    446     AslGbl_AnalysisWalkInfo.MethodStack = NULL;
    447 
    448     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n");
    449 
    450     if (AslGbl_CrossReferenceOutput)
    451     {
    452         OtPrintHeaders ("Part 1: Object Reference Map "
    453             "(Object references from within each control method)");
    454     }
    455 
    456     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    457         MtMethodAnalysisWalkBegin,
    458         MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo);
    459     UtEndEvent (Event);
    460 
    461     /* Generate the object cross-reference file if requested */
    462 
    463     Event = UtBeginEvent ("Generate cross-reference file");
    464     OtCreateXrefFile ();
    465     UtEndEvent (Event);
    466 
    467     /* Semantic error checking part two - typing of method returns */
    468 
    469     Event = UtBeginEvent ("Determine object types returned by methods");
    470     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n");
    471     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    472         NULL, AnMethodTypingWalkEnd, NULL);
    473     UtEndEvent (Event);
    474 
    475     /* Semantic error checking part three - operand type checking */
    476 
    477     Event = UtBeginEvent ("Analyze AML operand types");
    478     DbgPrint (ASL_DEBUG_OUTPUT,
    479         "Semantic analysis - Operand type checking\n\n");
    480     if (AslGbl_DoTypechecking)
    481     {
    482         TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    483             NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo);
    484     }
    485     UtEndEvent (Event);
    486 
    487     /* Semantic error checking part four - other miscellaneous checks */
    488 
    489     Event = UtBeginEvent ("Miscellaneous analysis");
    490     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n");
    491     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    492         AnOtherSemanticAnalysisWalkBegin,
    493         NULL, &AslGbl_AnalysisWalkInfo);
    494     UtEndEvent (Event);
    495 
    496     /*
    497      * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the
    498      * very last comment of a given ASL file because it's the last constructed
    499      * node during compilation. We take the very last comment and save it in a
    500      * global for it to be used by the disassembler.
    501      */
    502     if (AcpiGbl_CaptureComments)
    503     {
    504         AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList;
    505         AslGbl_ParseTreeRoot->Asl.CommentList = NULL;
    506     }
    507 
    508     /* Calculate all AML package lengths */
    509 
    510     Event = UtBeginEvent ("Finish AML package length generation");
    511     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    512     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    513         LnInitLengthsWalk, NULL);
    514     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    515         LnPackageLengthWalk, NULL);
    516     UtEndEvent (Event);
    517 
    518     /* Code generation - emit the AML */
    519 
    520     Event = UtBeginEvent ("Generate AML code and write output files");
    521     DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n");
    522 
    523     AslGbl_CurrentDB = AslGbl_ParseTreeRoot->Asl.Child;
    524 
    525     while (AslGbl_CurrentDB)
    526     {
    527         switch  (FlSwitchFileSet(AslGbl_CurrentDB->Asl.Filename))
    528         {
    529             case SWITCH_TO_DIFFERENT_FILE:
    530                 /*
    531                  * Reset these parameters when definition blocks belong in
    532                  * different files. If they belong in the same file, there is
    533                  * no need to reset these parameters
    534                  */
    535                 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
    536                 AslGbl_SourceLine = 0;
    537                 AslGbl_NextError = AslGbl_ErrorLog;
    538 
    539                 /* fall-through */
    540 
    541             case SWITCH_TO_SAME_FILE:
    542 
    543                 CgGenerateAmlOutput ();
    544                 CmDoOutputFiles ();
    545                 AslGbl_CurrentDB = AslGbl_CurrentDB->Asl.Next;
    546 
    547                 break;
    548 
    549             default: /* FILE_NOT_FOUND */
    550 
    551                 /* The requested file could not be found. Get out of here */
    552 
    553                 AslGbl_CurrentDB = NULL;
    554                 break;
    555         }
    556     }
    557     UtEndEvent (Event);
    558 
    559     Event = UtBeginEvent ("Write optional output files");
    560     UtEndEvent (Event);
    561 
    562     return (0);
    563 }
    564 
    565 
    566 /*******************************************************************************
    567  *
    568  * FUNCTION:    AslCompilerSignon
    569  *
    570  * PARAMETERS:  FileId      - ID of the output file
    571  *
    572  * RETURN:      None
    573  *
    574  * DESCRIPTION: Display compiler signon
    575  *
    576  ******************************************************************************/
    577 
    578 void
    579 AslCompilerSignon (
    580     UINT32                  FileId)
    581 {
    582     char                    *Prefix = "";
    583     char                    *UtilityName;
    584 
    585 
    586     /* Set line prefix depending on the destination file type */
    587 
    588     switch (FileId)
    589     {
    590     case ASL_FILE_ASM_SOURCE_OUTPUT:
    591     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    592 
    593         Prefix = "; ";
    594         break;
    595 
    596     case ASL_FILE_HEX_OUTPUT:
    597 
    598         if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM)
    599         {
    600             Prefix = "; ";
    601         }
    602         else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) ||
    603                  (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL))
    604         {
    605             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
    606             Prefix = " * ";
    607         }
    608         break;
    609 
    610     case ASL_FILE_C_SOURCE_OUTPUT:
    611     case ASL_FILE_C_OFFSET_OUTPUT:
    612     case ASL_FILE_C_INCLUDE_OUTPUT:
    613 
    614         Prefix = " * ";
    615         break;
    616 
    617     default:
    618 
    619         /* No other output types supported */
    620 
    621         break;
    622     }
    623 
    624     /* Running compiler or disassembler? */
    625 
    626     if (AcpiGbl_DisasmFlag)
    627     {
    628         UtilityName = AML_DISASSEMBLER_NAME;
    629     }
    630     else
    631     {
    632         UtilityName = ASL_COMPILER_NAME;
    633     }
    634 
    635     /* Compiler signon with copyright */
    636 
    637     FlPrintFile (FileId, "%s\n", Prefix);
    638     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
    639 }
    640 
    641 
    642 /*******************************************************************************
    643  *
    644  * FUNCTION:    AslCompilerFileHeader
    645  *
    646  * PARAMETERS:  FileId      - ID of the output file
    647  *
    648  * RETURN:      None
    649  *
    650  * DESCRIPTION: Header used at the beginning of output files
    651  *
    652  ******************************************************************************/
    653 
    654 void
    655 AslCompilerFileHeader (
    656     UINT32                  FileId)
    657 {
    658     char                    *NewTime;
    659     time_t                  Aclock;
    660     char                    *Prefix = "";
    661 
    662 
    663     /* Set line prefix depending on the destination file type */
    664 
    665     switch (FileId)
    666     {
    667     case ASL_FILE_ASM_SOURCE_OUTPUT:
    668     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    669 
    670         Prefix = "; ";
    671         break;
    672 
    673     case ASL_FILE_HEX_OUTPUT:
    674 
    675         if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM)
    676         {
    677             Prefix = "; ";
    678         }
    679         else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) ||
    680                  (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL))
    681         {
    682             Prefix = " * ";
    683         }
    684         break;
    685 
    686     case ASL_FILE_C_SOURCE_OUTPUT:
    687     case ASL_FILE_C_OFFSET_OUTPUT:
    688     case ASL_FILE_C_INCLUDE_OUTPUT:
    689 
    690         Prefix = " * ";
    691         break;
    692 
    693     default:
    694 
    695         /* No other output types supported */
    696 
    697         break;
    698     }
    699 
    700     /* Compilation header (with timestamp) */
    701 
    702     FlPrintFile (FileId,
    703         "%sCompilation of \"%s\"",
    704         Prefix, AslGbl_Files[ASL_FILE_INPUT].Filename);
    705 
    706     if (!AslGbl_Deterministic)
    707     {
    708         Aclock = time (NULL);
    709         NewTime = ctime (&Aclock);
    710         if (NewTime)
    711         {
    712             FlPrintFile (FileId, " - %s%s\n", NewTime, Prefix);
    713         }
    714     }
    715     else
    716     {
    717         FlPrintFile (FileId, "\n");
    718     }
    719 
    720     switch (FileId)
    721     {
    722     case ASL_FILE_C_SOURCE_OUTPUT:
    723     case ASL_FILE_C_OFFSET_OUTPUT:
    724     case ASL_FILE_C_INCLUDE_OUTPUT:
    725 
    726         FlPrintFile (FileId, " */\n");
    727         break;
    728 
    729     default:
    730 
    731         /* Nothing to do for other output types */
    732 
    733         break;
    734     }
    735 }
    736 
    737 
    738 /*******************************************************************************
    739  *
    740  * FUNCTION:    CmFlushSourceCode
    741  *
    742  * PARAMETERS:  None
    743  *
    744  * RETURN:      None
    745  *
    746  * DESCRIPTION: Read in any remaining source code after the parse tree
    747  *              has been constructed.
    748  *
    749  ******************************************************************************/
    750 
    751 static void
    752 CmFlushSourceCode (
    753     void)
    754 {
    755     char                    Buffer;
    756 
    757 
    758     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
    759     {
    760         AslInsertLineBuffer ((int) Buffer);
    761     }
    762 
    763     AslResetCurrentLineBuffer ();
    764 }
    765 
    766 
    767 /*******************************************************************************
    768  *
    769  * FUNCTION:    CmDoOutputFiles
    770  *
    771  * PARAMETERS:  None
    772  *
    773  * RETURN:      None.
    774  *
    775  * DESCRIPTION: Create all "listing" type files
    776  *
    777  ******************************************************************************/
    778 
    779 void
    780 CmDoOutputFiles (
    781     void)
    782 {
    783 
    784     /* Create listings and hex files */
    785 
    786     LsDoListings ();
    787     HxDoHexOutput ();
    788 
    789     /* Dump the namespace to the .nsp file if requested */
    790 
    791     (void) NsDisplayNamespace ();
    792 
    793     /* Dump the device mapping file */
    794 
    795     MpEmitMappingInfo ();
    796 }
    797 
    798 
    799 /*******************************************************************************
    800  *
    801  * FUNCTION:    CmDumpAllEvents
    802  *
    803  * PARAMETERS:  None
    804  *
    805  * RETURN:      None.
    806  *
    807  * DESCRIPTION: Dump all compiler events
    808  *
    809  ******************************************************************************/
    810 
    811 static void
    812 CmDumpAllEvents (
    813     void)
    814 {
    815     ASL_EVENT_INFO          *Event;
    816     UINT32                  Delta;
    817     UINT32                  MicroSeconds;
    818     UINT32                  MilliSeconds;
    819     UINT32                  i;
    820 
    821 
    822     Event = AslGbl_Events;
    823 
    824     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
    825     if (AslGbl_CompileTimesFlag)
    826     {
    827         printf ("\nElapsed time for major events\n\n");
    828     }
    829 
    830     for (i = 0; i < AslGbl_NextEvent; i++)
    831     {
    832         if (Event->Valid)
    833         {
    834             /* Delta will be in 100-nanosecond units */
    835 
    836             Delta = (UINT32) (Event->EndTime - Event->StartTime);
    837 
    838             MicroSeconds = Delta / ACPI_100NSEC_PER_USEC;
    839             MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC;
    840 
    841             /* Round milliseconds up */
    842 
    843             if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500)
    844             {
    845                 MilliSeconds++;
    846             }
    847 
    848             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
    849                 MicroSeconds, MilliSeconds, Event->EventName);
    850 
    851             if (AslGbl_CompileTimesFlag)
    852             {
    853                 printf ("%8u usec %8u msec - %s\n",
    854                     MicroSeconds, MilliSeconds, Event->EventName);
    855             }
    856         }
    857 
    858         Event++;
    859     }
    860 }
    861 
    862 
    863 /*******************************************************************************
    864  *
    865  * FUNCTION:    CmCleanupAndExit
    866  *
    867  * PARAMETERS:  None
    868  *
    869  * RETURN:      None.
    870  *
    871  * DESCRIPTION: Close all open files and exit the compiler
    872  *
    873  ******************************************************************************/
    874 
    875 int
    876 CmCleanupAndExit (
    877     void)
    878 {
    879     int                     Status = 0;
    880     BOOLEAN                 DeleteAmlFile = FALSE;
    881     ASL_GLOBAL_FILE_NODE    *CurrentFileNode = AslGbl_FilesList;
    882 
    883 
    884     /* Check if any errors occurred during compile */
    885 
    886     (void) AslCheckForErrorExit ();
    887 
    888     AePrintErrorLog (ASL_FILE_STDERR);
    889     if (AslGbl_DebugFlag)
    890     {
    891         /* Print error summary to stdout also */
    892 
    893         AePrintErrorLog (ASL_FILE_STDOUT);
    894     }
    895 
    896     /* Emit compile times if enabled */
    897 
    898     CmDumpAllEvents ();
    899 
    900     if (AslGbl_CompileTimesFlag)
    901     {
    902         printf ("\nMiscellaneous compile statistics\n\n");
    903         printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes");
    904         printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches");
    905         printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects");
    906         printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods");
    907         printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations");
    908         printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory");
    909         printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded");
    910         printf ("\n");
    911     }
    912 
    913     if (AslGbl_NsLookupCount)
    914     {
    915         DbgPrint (ASL_DEBUG_OUTPUT,
    916             "\n\nMiscellaneous compile statistics\n\n");
    917 
    918         DbgPrint (ASL_DEBUG_OUTPUT,
    919             "%32s : %u\n", "Total Namespace searches",
    920             AslGbl_NsLookupCount);
    921 
    922         DbgPrint (ASL_DEBUG_OUTPUT,
    923             "%32s : %u usec\n", "Time per search", ((UINT32)
    924             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
    925                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
    926                 AslGbl_NsLookupCount);
    927     }
    928 
    929     if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    930     {
    931         printf ("\nMaximum error count (%d) exceeded (aslcompile.c)\n",
    932             ASL_MAX_ERROR_COUNT);
    933     }
    934 
    935     UtDisplaySummary (ASL_FILE_STDOUT);
    936 
    937     /*
    938      * Delete the AML file if there are errors and the force AML output option
    939      * (-f) has not been used.
    940      *
    941      * Return -1 as a status of the compiler if no AML files are generated. If
    942      * the AML file is generated in the presence of errors, return 0. In the
    943      * latter case, the errors were ignored by the user so the compilation is
    944      * considered successful.
    945      */
    946     if (AslGbl_ParserErrorDetected || AslGbl_PreprocessOnly ||
    947         ((AslGbl_ExceptionCount[ASL_ERROR] > 0) &&
    948         (!AslGbl_IgnoreErrors) &&
    949         AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle))
    950     {
    951         DeleteAmlFile = TRUE;
    952         Status = -1;
    953     }
    954 
    955     /* Close all open files */
    956 
    957     while (CurrentFileNode)
    958     {
    959         /*
    960          * Set the program return status based on file errors. If there are any
    961          * errors and during compilation, the command is not considered
    962          * successful.
    963          */
    964         if (Status != -1 && !AslGbl_IgnoreErrors &&
    965             CurrentFileNode->ParserErrorDetected)
    966         {
    967             Status = -1;
    968         }
    969 
    970         switch  (FlSwitchFileSet (CurrentFileNode->Files[ASL_FILE_INPUT].Filename))
    971         {
    972             case SWITCH_TO_SAME_FILE:
    973             case SWITCH_TO_DIFFERENT_FILE:
    974 
    975                 CmFinishFiles (DeleteAmlFile);
    976                 CurrentFileNode = CurrentFileNode->Next;
    977                 break;
    978 
    979             case FILE_NOT_FOUND:
    980             default:
    981 
    982                 CurrentFileNode = NULL;
    983                 break;
    984         }
    985     }
    986 
    987     /* Final cleanup after compiling one file */
    988 
    989     if (!AslGbl_DoAslConversion)
    990     {
    991         UtDeleteLocalCaches ();
    992     }
    993 
    994     return (Status);
    995 }
    996 
    997 
    998 /*******************************************************************************
    999  *
   1000  * FUNCTION:    CmFinishFiles
   1001  *
   1002  * PARAMETERS:  DeleteAmlFile
   1003  *
   1004  * RETURN:      None.
   1005  *
   1006  * DESCRIPTION: Close all open files, delete AML files depending on the
   1007  *              function parameter is true.
   1008  *
   1009  ******************************************************************************/
   1010 
   1011 static void
   1012 CmFinishFiles(
   1013     BOOLEAN                 DeleteAmlFile)
   1014 {
   1015     UINT32                  i;
   1016 
   1017 
   1018     /*
   1019      * Take care with the preprocessor file (.pre), it might be the same
   1020      * as the "input" file, depending on where the compiler has terminated
   1021      * or aborted. Prevent attempt to close the same file twice in
   1022      * loop below.
   1023      */
   1024     if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
   1025         AslGbl_Files[ASL_FILE_INPUT].Handle)
   1026     {
   1027         AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
   1028     }
   1029 
   1030     /* Close the standard I/O files */
   1031 
   1032     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
   1033     {
   1034         /*
   1035          * Some files such as debug output files could be pointing to
   1036          * stderr or stdout. Leave these alone.
   1037          */
   1038         if (AslGbl_Files[i].Handle != stderr &&
   1039             AslGbl_Files[i].Handle != stdout)
   1040         {
   1041             FlCloseFile (i);
   1042         }
   1043     }
   1044 
   1045     /* Delete AML file if there are errors */
   1046 
   1047     if (DeleteAmlFile)
   1048     {
   1049         FlDeleteFile (ASL_FILE_AML_OUTPUT);
   1050     }
   1051 
   1052     /* Delete the preprocessor temp file unless full debug was specified */
   1053 
   1054     if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile)
   1055     {
   1056         FlDeleteFile (ASL_FILE_PREPROCESSOR);
   1057     }
   1058 
   1059     /*
   1060      * Delete intermediate ("combined") source file (if -ls flag not set)
   1061      * This file is created during normal ASL/AML compiles. It is not
   1062      * created by the data table compiler.
   1063      *
   1064      * If the -ls flag is set, then the .SRC file should not be deleted.
   1065      * In this case, Gbl_SourceOutputFlag is set to TRUE.
   1066      *
   1067      * Note: Handles are cleared by FlCloseFile above, so we look at the
   1068      * filename instead, to determine if the .SRC file was actually
   1069      * created.
   1070      */
   1071     if (!AslGbl_SourceOutputFlag)
   1072     {
   1073         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
   1074     }
   1075 }
   1076