Home | History | Annotate | Line # | Download | only in compiler
aslcompile.c revision 1.3.10.1
      1 /******************************************************************************
      2  *
      3  * Module Name: aslcompile - top level compile module
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, 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 "dtcompiler.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 FlConsumeAnsiComment (
     71     FILE                    *Handle,
     72     ASL_FILE_STATUS         *Status);
     73 
     74 static void
     75 FlConsumeNewComment (
     76     FILE                    *Handle,
     77     ASL_FILE_STATUS         *Status);
     78 
     79 static void
     80 CmDumpAllEvents (
     81     void);
     82 
     83 
     84 /*******************************************************************************
     85  *
     86  * FUNCTION:    AslCompilerSignon
     87  *
     88  * PARAMETERS:  FileId      - ID of the output file
     89  *
     90  * RETURN:      None
     91  *
     92  * DESCRIPTION: Display compiler signon
     93  *
     94  ******************************************************************************/
     95 
     96 void
     97 AslCompilerSignon (
     98     UINT32                  FileId)
     99 {
    100     char                    *Prefix = "";
    101     char                    *UtilityName;
    102 
    103 
    104     /* Set line prefix depending on the destination file type */
    105 
    106     switch (FileId)
    107     {
    108     case ASL_FILE_ASM_SOURCE_OUTPUT:
    109     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    110 
    111         Prefix = "; ";
    112         break;
    113 
    114     case ASL_FILE_HEX_OUTPUT:
    115 
    116         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
    117         {
    118             Prefix = "; ";
    119         }
    120         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
    121                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
    122         {
    123             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
    124             Prefix = " * ";
    125         }
    126         break;
    127 
    128     case ASL_FILE_C_SOURCE_OUTPUT:
    129     case ASL_FILE_C_OFFSET_OUTPUT:
    130     case ASL_FILE_C_INCLUDE_OUTPUT:
    131 
    132         Prefix = " * ";
    133         break;
    134 
    135     default:
    136 
    137         /* No other output types supported */
    138 
    139         break;
    140     }
    141 
    142     /* Running compiler or disassembler? */
    143 
    144     if (Gbl_DisasmFlag)
    145     {
    146         UtilityName = AML_DISASSEMBLER_NAME;
    147     }
    148     else
    149     {
    150         UtilityName = ASL_COMPILER_NAME;
    151     }
    152 
    153     /* Compiler signon with copyright */
    154 
    155     FlPrintFile (FileId, "%s\n", Prefix);
    156     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
    157 }
    158 
    159 
    160 /*******************************************************************************
    161  *
    162  * FUNCTION:    AslCompilerFileHeader
    163  *
    164  * PARAMETERS:  FileId      - ID of the output file
    165  *
    166  * RETURN:      None
    167  *
    168  * DESCRIPTION: Header used at the beginning of output files
    169  *
    170  ******************************************************************************/
    171 
    172 void
    173 AslCompilerFileHeader (
    174     UINT32                  FileId)
    175 {
    176     struct tm               *NewTime;
    177     time_t                  Aclock;
    178     char                    *Prefix = "";
    179 
    180 
    181     /* Set line prefix depending on the destination file type */
    182 
    183     switch (FileId)
    184     {
    185     case ASL_FILE_ASM_SOURCE_OUTPUT:
    186     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    187 
    188         Prefix = "; ";
    189         break;
    190 
    191     case ASL_FILE_HEX_OUTPUT:
    192 
    193         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
    194         {
    195             Prefix = "; ";
    196         }
    197         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
    198                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
    199         {
    200             Prefix = " * ";
    201         }
    202         break;
    203 
    204     case ASL_FILE_C_SOURCE_OUTPUT:
    205     case ASL_FILE_C_OFFSET_OUTPUT:
    206     case ASL_FILE_C_INCLUDE_OUTPUT:
    207 
    208         Prefix = " * ";
    209         break;
    210 
    211     default:
    212 
    213         /* No other output types supported */
    214 
    215         break;
    216     }
    217 
    218     /* Compilation header with timestamp */
    219 
    220     (void) time (&Aclock);
    221     NewTime = localtime (&Aclock);
    222 
    223     FlPrintFile (FileId,
    224         "%sCompilation of \"%s\" - %s%s\n",
    225         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
    226         Prefix);
    227 
    228     switch (FileId)
    229     {
    230     case ASL_FILE_C_SOURCE_OUTPUT:
    231     case ASL_FILE_C_OFFSET_OUTPUT:
    232     case ASL_FILE_C_INCLUDE_OUTPUT:
    233 
    234         FlPrintFile (FileId, " */\n");
    235         break;
    236 
    237     default:
    238 
    239         /* Nothing to do for other output types */
    240 
    241         break;
    242     }
    243 }
    244 
    245 
    246 /*******************************************************************************
    247  *
    248  * FUNCTION:    CmFlushSourceCode
    249  *
    250  * PARAMETERS:  None
    251  *
    252  * RETURN:      None
    253  *
    254  * DESCRIPTION: Read in any remaining source code after the parse tree
    255  *              has been constructed.
    256  *
    257  ******************************************************************************/
    258 
    259 static void
    260 CmFlushSourceCode (
    261     void)
    262 {
    263     char                    Buffer;
    264 
    265 
    266     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
    267     {
    268         AslInsertLineBuffer ((int) Buffer);
    269     }
    270 
    271     AslResetCurrentLineBuffer ();
    272 }
    273 
    274 
    275 /*******************************************************************************
    276  *
    277  * FUNCTION:    FlConsume*
    278  *
    279  * PARAMETERS:  Handle              - Open input file
    280  *              Status              - File current status struct
    281  *
    282  * RETURN:      Number of lines consumed
    283  *
    284  * DESCRIPTION: Step over both types of comment during check for ascii chars
    285  *
    286  ******************************************************************************/
    287 
    288 static void
    289 FlConsumeAnsiComment (
    290     FILE                    *Handle,
    291     ASL_FILE_STATUS         *Status)
    292 {
    293     UINT8                   Byte;
    294     BOOLEAN                 ClosingComment = FALSE;
    295 
    296 
    297     while (fread (&Byte, 1, 1, Handle) == 1)
    298     {
    299         /* Scan until comment close is found */
    300 
    301         if (ClosingComment)
    302         {
    303             if (Byte == '/')
    304             {
    305                 return;
    306             }
    307 
    308             if (Byte != '*')
    309             {
    310                 /* Reset */
    311 
    312                 ClosingComment = FALSE;
    313             }
    314         }
    315         else if (Byte == '*')
    316         {
    317             ClosingComment = TRUE;
    318         }
    319 
    320         /* Maintain line count */
    321 
    322         if (Byte == 0x0A)
    323         {
    324             Status->Line++;
    325         }
    326 
    327         Status->Offset++;
    328     }
    329 }
    330 
    331 
    332 static void
    333 FlConsumeNewComment (
    334     FILE                    *Handle,
    335     ASL_FILE_STATUS         *Status)
    336 {
    337     UINT8                   Byte;
    338 
    339 
    340     while (fread (&Byte, 1, 1, Handle) == 1)
    341     {
    342         Status->Offset++;
    343 
    344         /* Comment ends at newline */
    345 
    346         if (Byte == 0x0A)
    347         {
    348             Status->Line++;
    349             return;
    350         }
    351     }
    352 }
    353 
    354 
    355 /*******************************************************************************
    356  *
    357  * FUNCTION:    FlCheckForAcpiTable
    358  *
    359  * PARAMETERS:  Handle              - Open input file
    360  *
    361  * RETURN:      Status
    362  *
    363  * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
    364  *              following checks on what would be the table header:
    365  *              0) File must be at least as long as an ACPI_TABLE_HEADER
    366  *              1) The header length field must match the file size
    367  *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
    368  *
    369  ******************************************************************************/
    370 
    371 ACPI_STATUS
    372 FlCheckForAcpiTable (
    373     FILE                    *Handle)
    374 {
    375     ACPI_TABLE_HEADER       Table;
    376     UINT32                  FileSize;
    377     size_t                  Actual;
    378     UINT32                  i;
    379 
    380 
    381     /* Read a potential table header */
    382 
    383     Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
    384     fseek (Handle, 0, SEEK_SET);
    385 
    386     if (Actual < sizeof (ACPI_TABLE_HEADER))
    387     {
    388         return (AE_ERROR);
    389     }
    390 
    391     /* Header length field must match the file size */
    392 
    393     FileSize = DtGetFileSize (Handle);
    394     if (Table.Length != FileSize)
    395     {
    396         return (AE_ERROR);
    397     }
    398 
    399     /*
    400      * These fields must be ASCII:
    401      * Signature, OemId, OemTableId, AslCompilerId.
    402      * We allow a NULL terminator in OemId and OemTableId.
    403      */
    404     for (i = 0; i < ACPI_NAME_SIZE; i++)
    405     {
    406         if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
    407         {
    408             return (AE_ERROR);
    409         }
    410 
    411         if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
    412         {
    413             return (AE_ERROR);
    414         }
    415     }
    416 
    417     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
    418     {
    419         if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
    420         {
    421             return (AE_ERROR);
    422         }
    423     }
    424 
    425     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
    426     {
    427         if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
    428         {
    429             return (AE_ERROR);
    430         }
    431     }
    432 
    433     printf ("Binary file appears to be a valid ACPI table, disassembling\n");
    434     return (AE_OK);
    435 }
    436 
    437 
    438 /*******************************************************************************
    439  *
    440  * FUNCTION:    FlCheckForAscii
    441  *
    442  * PARAMETERS:  Handle              - Open input file
    443  *              Filename            - Input filename
    444  *              DisplayErrors       - TRUE if error messages desired
    445  *
    446  * RETURN:      Status
    447  *
    448  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
    449  *              within comments. Note: does not handle nested comments and does
    450  *              not handle comment delimiters within string literals. However,
    451  *              on the rare chance this happens and an invalid character is
    452  *              missed, the parser will catch the error by failing in some
    453  *              spectactular manner.
    454  *
    455  ******************************************************************************/
    456 
    457 ACPI_STATUS
    458 FlCheckForAscii (
    459     FILE                    *Handle,
    460     char                    *Filename,
    461     BOOLEAN                 DisplayErrors)
    462 {
    463     UINT8                   Byte;
    464     ACPI_SIZE               BadBytes = 0;
    465     BOOLEAN                 OpeningComment = FALSE;
    466     ASL_FILE_STATUS         Status;
    467 
    468 
    469     Status.Line = 1;
    470     Status.Offset = 0;
    471 
    472     /* Read the entire file */
    473 
    474     while (fread (&Byte, 1, 1, Handle) == 1)
    475     {
    476         /* Ignore comment fields (allow non-ascii within) */
    477 
    478         if (OpeningComment)
    479         {
    480             /* Check for second comment open delimiter */
    481 
    482             if (Byte == '*')
    483             {
    484                 FlConsumeAnsiComment (Handle, &Status);
    485             }
    486 
    487             if (Byte == '/')
    488             {
    489                 FlConsumeNewComment (Handle, &Status);
    490             }
    491 
    492             /* Reset */
    493 
    494             OpeningComment = FALSE;
    495         }
    496         else if (Byte == '/')
    497         {
    498             OpeningComment = TRUE;
    499         }
    500 
    501         /* Check for an ASCII character */
    502 
    503         if (!ACPI_IS_ASCII (Byte))
    504         {
    505             if ((BadBytes < 10) && (DisplayErrors))
    506             {
    507                 AcpiOsPrintf (
    508                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
    509                     Byte, Status.Line, Status.Offset);
    510             }
    511 
    512             BadBytes++;
    513         }
    514 
    515         /* Update line counter */
    516 
    517         else if (Byte == 0x0A)
    518         {
    519             Status.Line++;
    520         }
    521 
    522         Status.Offset++;
    523     }
    524 
    525     /* Seek back to the beginning of the source file */
    526 
    527     fseek (Handle, 0, SEEK_SET);
    528 
    529     /* Were there any non-ASCII characters in the file? */
    530 
    531     if (BadBytes)
    532     {
    533         if (DisplayErrors)
    534         {
    535             AcpiOsPrintf (
    536                 "%u non-ASCII characters found in input source text, could be a binary file\n",
    537                 BadBytes);
    538             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
    539         }
    540 
    541         return (AE_BAD_CHARACTER);
    542     }
    543 
    544     /* File is OK (100% ASCII) */
    545 
    546     return (AE_OK);
    547 }
    548 
    549 
    550 /*******************************************************************************
    551  *
    552  * FUNCTION:    CmDoCompile
    553  *
    554  * PARAMETERS:  None
    555  *
    556  * RETURN:      Status (0 = OK)
    557  *
    558  * DESCRIPTION: This procedure performs the entire compile
    559  *
    560  ******************************************************************************/
    561 
    562 int
    563 CmDoCompile (
    564     void)
    565 {
    566     ACPI_STATUS             Status;
    567     UINT8                   FullCompile;
    568     UINT8                   Event;
    569 
    570 
    571     FullCompile = UtBeginEvent ("*** Total Compile time ***");
    572     Event = UtBeginEvent ("Open input and output files");
    573     UtEndEvent (Event);
    574 
    575     Event = UtBeginEvent ("Preprocess input file");
    576     if (Gbl_PreprocessFlag)
    577     {
    578         /* Preprocessor */
    579 
    580         PrDoPreprocess ();
    581         if (Gbl_PreprocessOnly)
    582         {
    583             UtEndEvent (Event);
    584             CmCleanupAndExit ();
    585             return (0);
    586         }
    587     }
    588     UtEndEvent (Event);
    589 
    590     /* Build the parse tree */
    591 
    592     Event = UtBeginEvent ("Parse source code and build parse tree");
    593     AslCompilerparse();
    594     UtEndEvent (Event);
    595 
    596     /* Check for parse errors */
    597 
    598     Status = AslCheckForErrorExit ();
    599     if (ACPI_FAILURE (Status))
    600     {
    601         fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n");
    602         LsDumpParseTree ();
    603         goto ErrorExit;
    604     }
    605 
    606     /* Did the parse tree get successfully constructed? */
    607 
    608     if (!RootNode)
    609     {
    610         /*
    611          * If there are no errors, then we have some sort of
    612          * internal problem.
    613          */
    614         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
    615             NULL, "- Could not resolve parse tree root node");
    616 
    617         goto ErrorExit;
    618     }
    619 
    620 
    621     /* Flush out any remaining source after parse tree is complete */
    622 
    623     Event = UtBeginEvent ("Flush source input");
    624     CmFlushSourceCode ();
    625 
    626     /* Optional parse tree dump, compiler debug output only */
    627 
    628     LsDumpParseTree ();
    629 
    630     OpcGetIntegerWidth (RootNode);
    631     UtEndEvent (Event);
    632 
    633     /* Pre-process parse tree for any operator transforms */
    634 
    635     Event = UtBeginEvent ("Parse tree transforms");
    636     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
    637     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
    638         TrAmlTransformWalk, NULL, NULL);
    639     UtEndEvent (Event);
    640 
    641     /* Generate AML opcodes corresponding to the parse tokens */
    642 
    643     Event = UtBeginEvent ("Generate AML opcodes");
    644     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
    645     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
    646         OpcAmlOpcodeWalk, NULL);
    647     UtEndEvent (Event);
    648 
    649     /*
    650      * Now that the input is parsed, we can open the AML output file.
    651      * Note: by default, the name of this file comes from the table descriptor
    652      * within the input file.
    653      */
    654     Event = UtBeginEvent ("Open AML output file");
    655     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
    656     UtEndEvent (Event);
    657     if (ACPI_FAILURE (Status))
    658     {
    659         AePrintErrorLog (ASL_FILE_STDERR);
    660         return (-1);
    661     }
    662 
    663     /* Interpret and generate all compile-time constants */
    664 
    665     Event = UtBeginEvent ("Constant folding via AML interpreter");
    666     DbgPrint (ASL_DEBUG_OUTPUT,
    667         "\nInterpreting compile-time constant expressions\n\n");
    668     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
    669         OpcAmlConstantWalk, NULL, NULL);
    670     UtEndEvent (Event);
    671 
    672     /* Update AML opcodes if necessary, after constant folding */
    673 
    674     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    675     DbgPrint (ASL_DEBUG_OUTPUT,
    676         "\nUpdating AML opcodes after constant folding\n\n");
    677     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
    678         NULL, OpcAmlOpcodeUpdateWalk, NULL);
    679     UtEndEvent (Event);
    680 
    681     /* Calculate all AML package lengths */
    682 
    683     Event = UtBeginEvent ("Generate AML package lengths");
    684     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
    685     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
    686         LnPackageLengthWalk, NULL);
    687     UtEndEvent (Event);
    688 
    689     if (Gbl_ParseOnlyFlag)
    690     {
    691         AePrintErrorLog (ASL_FILE_STDERR);
    692         UtDisplaySummary (ASL_FILE_STDERR);
    693         if (Gbl_DebugFlag)
    694         {
    695             /* Print error summary to the stdout also */
    696 
    697             AePrintErrorLog (ASL_FILE_STDOUT);
    698             UtDisplaySummary (ASL_FILE_STDOUT);
    699         }
    700         UtEndEvent (FullCompile);
    701         return (0);
    702     }
    703 
    704     /*
    705      * Create an internal namespace and use it as a symbol table
    706      */
    707 
    708     /* Namespace loading */
    709 
    710     Event = UtBeginEvent ("Create ACPI Namespace");
    711     Status = LdLoadNamespace (RootNode);
    712     UtEndEvent (Event);
    713     if (ACPI_FAILURE (Status))
    714     {
    715         goto ErrorExit;
    716     }
    717 
    718     /* Namespace cross-reference */
    719 
    720     AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
    721     Status = XfCrossReferenceNamespace ();
    722     if (ACPI_FAILURE (Status))
    723     {
    724         goto ErrorExit;
    725     }
    726 
    727     /* Namespace - Check for non-referenced objects */
    728 
    729     LkFindUnreferencedObjects ();
    730     UtEndEvent (AslGbl_NamespaceEvent);
    731 
    732     /*
    733      * Semantic analysis. This can happen only after the
    734      * namespace has been loaded and cross-referenced.
    735      *
    736      * part one - check control methods
    737      */
    738     Event = UtBeginEvent ("Analyze control method return types");
    739     AnalysisWalkInfo.MethodStack = NULL;
    740 
    741     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
    742     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
    743         MtMethodAnalysisWalkBegin,
    744         MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
    745     UtEndEvent (Event);
    746 
    747     /* Semantic error checking part two - typing of method returns */
    748 
    749     Event = UtBeginEvent ("Determine object types returned by methods");
    750     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
    751     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
    752         NULL, AnMethodTypingWalkEnd, NULL);
    753     UtEndEvent (Event);
    754 
    755     /* Semantic error checking part three - operand type checking */
    756 
    757     Event = UtBeginEvent ("Analyze AML operand types");
    758     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
    759     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
    760         NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
    761     UtEndEvent (Event);
    762 
    763     /* Semantic error checking part four - other miscellaneous checks */
    764 
    765     Event = UtBeginEvent ("Miscellaneous analysis");
    766     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
    767     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
    768         AnOtherSemanticAnalysisWalkBegin,
    769         NULL, &AnalysisWalkInfo);
    770     UtEndEvent (Event);
    771 
    772     /* Calculate all AML package lengths */
    773 
    774     Event = UtBeginEvent ("Finish AML package length generation");
    775     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
    776     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
    777         LnInitLengthsWalk, NULL);
    778     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
    779         LnPackageLengthWalk, NULL);
    780     UtEndEvent (Event);
    781 
    782     /* Code generation - emit the AML */
    783 
    784     Event = UtBeginEvent ("Generate AML code and write output files");
    785     CgGenerateAmlOutput ();
    786     UtEndEvent (Event);
    787 
    788     Event = UtBeginEvent ("Write optional output files");
    789     CmDoOutputFiles ();
    790     UtEndEvent (Event);
    791 
    792     UtEndEvent (FullCompile);
    793     CmCleanupAndExit ();
    794     return (0);
    795 
    796 ErrorExit:
    797     UtEndEvent (FullCompile);
    798     CmCleanupAndExit ();
    799     return (-1);
    800 }
    801 
    802 
    803 /*******************************************************************************
    804  *
    805  * FUNCTION:    CmDoOutputFiles
    806  *
    807  * PARAMETERS:  None
    808  *
    809  * RETURN:      None.
    810  *
    811  * DESCRIPTION: Create all "listing" type files
    812  *
    813  ******************************************************************************/
    814 
    815 void
    816 CmDoOutputFiles (
    817     void)
    818 {
    819 
    820     /* Create listings and hex files */
    821 
    822     LsDoListings ();
    823     HxDoHexOutput ();
    824 
    825     /* Dump the namespace to the .nsp file if requested */
    826 
    827     (void) NsDisplayNamespace ();
    828 }
    829 
    830 
    831 /*******************************************************************************
    832  *
    833  * FUNCTION:    CmDumpAllEvents
    834  *
    835  * PARAMETERS:  None
    836  *
    837  * RETURN:      None.
    838  *
    839  * DESCRIPTION: Dump all compiler events
    840  *
    841  ******************************************************************************/
    842 
    843 static void
    844 CmDumpAllEvents (
    845     void)
    846 {
    847     ASL_EVENT_INFO          *Event;
    848     UINT32                  Delta;
    849     UINT32                  USec;
    850     UINT32                  MSec;
    851     UINT32                  i;
    852 
    853 
    854     Event = AslGbl_Events;
    855 
    856     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
    857     if (Gbl_CompileTimesFlag)
    858     {
    859         printf ("\nElapsed time for major events\n\n");
    860     }
    861 
    862     for (i = 0; i < AslGbl_NextEvent; i++)
    863     {
    864         if (Event->Valid)
    865         {
    866             /* Delta will be in 100-nanosecond units */
    867 
    868             Delta = (UINT32) (Event->EndTime - Event->StartTime);
    869 
    870             USec = Delta / ACPI_100NSEC_PER_USEC;
    871             MSec = Delta / ACPI_100NSEC_PER_MSEC;
    872 
    873             /* Round milliseconds up */
    874 
    875             if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
    876             {
    877                 MSec++;
    878             }
    879 
    880             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
    881                 USec, MSec, Event->EventName);
    882 
    883             if (Gbl_CompileTimesFlag)
    884             {
    885                 printf ("%8u usec %8u msec - %s\n",
    886                     USec, MSec, Event->EventName);
    887             }
    888         }
    889 
    890         Event++;
    891     }
    892 }
    893 
    894 
    895 /*******************************************************************************
    896  *
    897  * FUNCTION:    CmCleanupAndExit
    898  *
    899  * PARAMETERS:  None
    900  *
    901  * RETURN:      None.
    902  *
    903  * DESCRIPTION: Close all open files and exit the compiler
    904  *
    905  ******************************************************************************/
    906 
    907 void
    908 CmCleanupAndExit (
    909     void)
    910 {
    911     UINT32                  i;
    912     BOOLEAN                 DeleteAmlFile = FALSE;
    913 
    914 
    915     AePrintErrorLog (ASL_FILE_STDERR);
    916     if (Gbl_DebugFlag)
    917     {
    918         /* Print error summary to stdout also */
    919 
    920         AePrintErrorLog (ASL_FILE_STDOUT);
    921     }
    922 
    923     /* Emit compile times if enabled */
    924 
    925     CmDumpAllEvents ();
    926 
    927     if (Gbl_CompileTimesFlag)
    928     {
    929         printf ("\nMiscellaneous compile statistics\n\n");
    930         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
    931         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
    932         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
    933         printf ("%11u : %s\n", TotalMethods, "Control methods");
    934         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
    935         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
    936         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
    937         printf ("\n");
    938     }
    939 
    940     if (Gbl_NsLookupCount)
    941     {
    942         DbgPrint (ASL_DEBUG_OUTPUT,
    943             "\n\nMiscellaneous compile statistics\n\n");
    944 
    945         DbgPrint (ASL_DEBUG_OUTPUT,
    946             "%32s : %u\n", "Total Namespace searches",
    947             Gbl_NsLookupCount);
    948 
    949         DbgPrint (ASL_DEBUG_OUTPUT,
    950             "%32s : %u usec\n", "Time per search", ((UINT32)
    951             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
    952                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
    953                 Gbl_NsLookupCount);
    954     }
    955 
    956     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    957     {
    958         printf ("\nMaximum error count (%u) exceeded\n",
    959             ASL_MAX_ERROR_COUNT);
    960     }
    961 
    962     UtDisplaySummary (ASL_FILE_STDOUT);
    963 
    964     /*
    965      * We will delete the AML file if there are errors and the
    966      * force AML output option has not been used.
    967      */
    968     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
    969         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
    970     {
    971         DeleteAmlFile = TRUE;
    972     }
    973 
    974     /* Close all open files */
    975 
    976     /*
    977      * Take care with the preprocessor file (.i), it might be the same
    978      * as the "input" file, depending on where the compiler has terminated
    979      * or aborted. Prevent attempt to close the same file twice in
    980      * loop below.
    981      */
    982     if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
    983         Gbl_Files[ASL_FILE_INPUT].Handle)
    984     {
    985         Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
    986     }
    987 
    988     /* Close the standard I/O files */
    989 
    990     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
    991     {
    992         FlCloseFile (i);
    993     }
    994 
    995     /* Delete AML file if there are errors */
    996 
    997     if (DeleteAmlFile)
    998     {
    999         FlDeleteFile (ASL_FILE_AML_OUTPUT);
   1000     }
   1001 
   1002     /* Delete the preprocessor output file (.i) unless -li flag is set */
   1003 
   1004     if (!Gbl_PreprocessorOutputFlag &&
   1005         Gbl_PreprocessFlag)
   1006     {
   1007         FlDeleteFile (ASL_FILE_PREPROCESSOR);
   1008     }
   1009 
   1010     /*
   1011      * Delete intermediate ("combined") source file (if -ls flag not set)
   1012      * This file is created during normal ASL/AML compiles. It is not
   1013      * created by the data table compiler.
   1014      *
   1015      * If the -ls flag is set, then the .SRC file should not be deleted.
   1016      * In this case, Gbl_SourceOutputFlag is set to TRUE.
   1017      *
   1018      * Note: Handles are cleared by FlCloseFile above, so we look at the
   1019      * filename instead, to determine if the .SRC file was actually
   1020      * created.
   1021      *
   1022      * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
   1023      */
   1024     if (!Gbl_SourceOutputFlag)
   1025     {
   1026         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
   1027     }
   1028 }
   1029