1 /******************************************************************************
3 * Module Name: aslcompile - top level compile module
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2012, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include "aslcompiler.h"
50 #define _COMPONENT ACPI_COMPILER
51 ACPI_MODULE_NAME ("aslcompile")
55 * External is here in case the parser emits the same external in the
56 * generated header. (Newer versions of Bison)
62 /* Local prototypes */
69 FlConsumeAnsiComment (
71 ASL_FILE_STATUS *Status);
76 ASL_FILE_STATUS *Status);
83 /*******************************************************************************
85 * FUNCTION: AslCompilerSignon
87 * PARAMETERS: FileId - ID of the output file
91 * DESCRIPTION: Display compiler signon
93 ******************************************************************************/
103 /* Set line prefix depending on the destination file type */
107 case ASL_FILE_ASM_SOURCE_OUTPUT:
108 case ASL_FILE_ASM_INCLUDE_OUTPUT:
113 case ASL_FILE_HEX_OUTPUT:
115 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
119 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
120 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
122 FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
127 case ASL_FILE_C_SOURCE_OUTPUT:
128 case ASL_FILE_C_INCLUDE_OUTPUT:
134 /* No other output types supported */
138 /* Running compiler or disassembler? */
142 UtilityName = AML_DISASSEMBLER_NAME;
146 UtilityName = ASL_COMPILER_NAME;
149 /* Compiler signon with copyright */
151 FlPrintFile (FileId, "%s\n", Prefix);
152 FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
156 /*******************************************************************************
158 * FUNCTION: AslCompilerFileHeader
160 * PARAMETERS: FileId - ID of the output file
164 * DESCRIPTION: Header used at the beginning of output files
166 ******************************************************************************/
169 AslCompilerFileHeader (
177 /* Set line prefix depending on the destination file type */
181 case ASL_FILE_ASM_SOURCE_OUTPUT:
182 case ASL_FILE_ASM_INCLUDE_OUTPUT:
187 case ASL_FILE_HEX_OUTPUT:
189 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
193 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
194 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
200 case ASL_FILE_C_SOURCE_OUTPUT:
201 case ASL_FILE_C_INCLUDE_OUTPUT:
207 /* No other output types supported */
211 /* Compilation header with timestamp */
213 (void) time (&Aclock);
214 NewTime = localtime (&Aclock);
217 "%sCompilation of \"%s\" - %s%s\n",
218 Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
223 case ASL_FILE_C_SOURCE_OUTPUT:
224 case ASL_FILE_C_INCLUDE_OUTPUT:
225 FlPrintFile (FileId, " */\n");
229 /* Nothing to do for other output types */
235 /*******************************************************************************
237 * FUNCTION: CmFlushSourceCode
243 * DESCRIPTION: Read in any remaining source code after the parse tree
244 * has been constructed.
246 ******************************************************************************/
255 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
257 AslInsertLineBuffer ((int) Buffer);
260 AslResetCurrentLineBuffer ();
264 /*******************************************************************************
266 * FUNCTION: FlConsume*
268 * PARAMETERS: Handle - Open input file
269 * Status - File current status struct
271 * RETURN: Number of lines consumed
273 * DESCRIPTION: Step over both types of comment during check for ascii chars
275 ******************************************************************************/
278 FlConsumeAnsiComment (
280 ASL_FILE_STATUS *Status)
283 BOOLEAN ClosingComment = FALSE;
286 while (fread (&Byte, 1, 1, Handle) == 1)
288 /* Scan until comment close is found */
301 ClosingComment = FALSE;
304 else if (Byte == '*')
306 ClosingComment = TRUE;
309 /* Maintain line count */
322 FlConsumeNewComment (
324 ASL_FILE_STATUS *Status)
329 while (fread (&Byte, 1, 1, Handle) == 1)
333 /* Comment ends at newline */
344 /*******************************************************************************
346 * FUNCTION: FlCheckForAscii
348 * PARAMETERS: Handle - Open input file
349 * Filename - Input filename
350 * DisplayErrors - TRUE if error messages desired
354 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
355 * within comments. Note: does not handle nested comments and does
356 * not handle comment delimiters within string literals. However,
357 * on the rare chance this happens and an invalid character is
358 * missed, the parser will catch the error by failing in some
359 * spectactular manner.
361 ******************************************************************************/
367 BOOLEAN DisplayErrors)
370 ACPI_SIZE BadBytes = 0;
371 BOOLEAN OpeningComment = FALSE;
372 ASL_FILE_STATUS Status;
378 /* Read the entire file */
380 while (fread (&Byte, 1, 1, Handle) == 1)
382 /* Ignore comment fields (allow non-ascii within) */
386 /* Check for second comment open delimiter */
390 FlConsumeAnsiComment (Handle, &Status);
395 FlConsumeNewComment (Handle, &Status);
400 OpeningComment = FALSE;
402 else if (Byte == '/')
404 OpeningComment = TRUE;
407 /* Check for an ASCII character */
409 if (!ACPI_IS_ASCII (Byte))
411 if ((BadBytes < 10) && (DisplayErrors))
414 "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
415 Byte, Status.Line, Status.Offset);
421 /* Update line counter */
423 else if (Byte == 0x0A)
431 /* Seek back to the beginning of the source file */
433 fseek (Handle, 0, SEEK_SET);
435 /* Were there any non-ASCII characters in the file? */
442 "%u non-ASCII characters found in input source text, could be a binary file\n",
444 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
447 return (AE_BAD_CHARACTER);
450 /* File is OK (100% ASCII) */
456 /*******************************************************************************
458 * FUNCTION: CmDoCompile
462 * RETURN: Status (0 = OK)
464 * DESCRIPTION: This procedure performs the entire compile
466 ******************************************************************************/
477 FullCompile = UtBeginEvent ("*** Total Compile time ***");
478 Event = UtBeginEvent ("Open input and output files");
481 Event = UtBeginEvent ("Preprocess input file");
482 if (Gbl_PreprocessFlag)
487 if (Gbl_PreprocessOnly)
496 /* Build the parse tree */
498 Event = UtBeginEvent ("Parse source code and build parse tree");
502 /* Flush out any remaining source after parse tree is complete */
504 Event = UtBeginEvent ("Flush source input");
505 CmFlushSourceCode ();
507 /* Did the parse tree get successfully constructed? */
512 * If there are no errors, then we have some sort of
515 Status = AslCheckForErrorExit ();
518 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
519 NULL, "- Could not resolve parse tree root node");
525 /* Optional parse tree dump, compiler debug output only */
529 OpcGetIntegerWidth (RootNode);
532 /* Pre-process parse tree for any operator transforms */
534 Event = UtBeginEvent ("Parse tree transforms");
535 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
536 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
537 TrAmlTransformWalk, NULL, NULL);
540 /* Generate AML opcodes corresponding to the parse tokens */
542 Event = UtBeginEvent ("Generate AML opcodes");
543 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
544 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
545 OpcAmlOpcodeWalk, NULL);
549 * Now that the input is parsed, we can open the AML output file.
550 * Note: by default, the name of this file comes from the table descriptor
551 * within the input file.
553 Event = UtBeginEvent ("Open AML output file");
554 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
556 if (ACPI_FAILURE (Status))
558 AePrintErrorLog (ASL_FILE_STDERR);
562 /* Interpret and generate all compile-time constants */
564 Event = UtBeginEvent ("Constant folding via AML interpreter");
565 DbgPrint (ASL_DEBUG_OUTPUT,
566 "\nInterpreting compile-time constant expressions\n\n");
567 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
568 OpcAmlConstantWalk, NULL, NULL);
571 /* Update AML opcodes if necessary, after constant folding */
573 Event = UtBeginEvent ("Updating AML opcodes after constant folding");
574 DbgPrint (ASL_DEBUG_OUTPUT,
575 "\nUpdating AML opcodes after constant folding\n\n");
576 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
577 NULL, OpcAmlOpcodeUpdateWalk, NULL);
580 /* Calculate all AML package lengths */
582 Event = UtBeginEvent ("Generate AML package lengths");
583 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
584 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
585 LnPackageLengthWalk, NULL);
588 if (Gbl_ParseOnlyFlag)
590 AePrintErrorLog (ASL_FILE_STDERR);
591 UtDisplaySummary (ASL_FILE_STDERR);
594 /* Print error summary to the stdout also */
596 AePrintErrorLog (ASL_FILE_STDOUT);
597 UtDisplaySummary (ASL_FILE_STDOUT);
599 UtEndEvent (FullCompile);
604 * Create an internal namespace and use it as a symbol table
607 /* Namespace loading */
609 Event = UtBeginEvent ("Create ACPI Namespace");
610 Status = LdLoadNamespace (RootNode);
612 if (ACPI_FAILURE (Status))
617 /* Namespace cross-reference */
619 AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
620 Status = LkCrossReferenceNamespace ();
621 if (ACPI_FAILURE (Status))
626 /* Namespace - Check for non-referenced objects */
628 LkFindUnreferencedObjects ();
629 UtEndEvent (AslGbl_NamespaceEvent);
632 * Semantic analysis. This can happen only after the
633 * namespace has been loaded and cross-referenced.
635 * part one - check control methods
637 Event = UtBeginEvent ("Analyze control method return types");
638 AnalysisWalkInfo.MethodStack = NULL;
640 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
641 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
642 AnMethodAnalysisWalkBegin,
643 AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
646 /* Semantic error checking part two - typing of method returns */
648 Event = UtBeginEvent ("Determine object types returned by methods");
649 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
650 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
651 NULL, AnMethodTypingWalkEnd, NULL);
654 /* Semantic error checking part three - operand type checking */
656 Event = UtBeginEvent ("Analyze AML operand types");
657 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
658 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
659 NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
662 /* Semantic error checking part four - other miscellaneous checks */
664 Event = UtBeginEvent ("Miscellaneous analysis");
665 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
666 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
667 AnOtherSemanticAnalysisWalkBegin,
668 NULL, &AnalysisWalkInfo);
671 /* Calculate all AML package lengths */
673 Event = UtBeginEvent ("Finish AML package length generation");
674 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
675 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
676 LnInitLengthsWalk, NULL);
677 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
678 LnPackageLengthWalk, NULL);
681 /* Code generation - emit the AML */
683 Event = UtBeginEvent ("Generate AML code and write output files");
684 CgGenerateAmlOutput ();
687 Event = UtBeginEvent ("Write optional output files");
691 UtEndEvent (FullCompile);
696 UtEndEvent (FullCompile);
702 /*******************************************************************************
704 * FUNCTION: CmDoOutputFiles
710 * DESCRIPTION: Create all "listing" type files
712 ******************************************************************************/
719 /* Create listings and hex files */
724 /* Dump the namespace to the .nsp file if requested */
726 (void) LsDisplayNamespace ();
730 /*******************************************************************************
732 * FUNCTION: CmDumpAllEvents
738 * DESCRIPTION: Dump all compiler events
740 ******************************************************************************/
746 ASL_EVENT_INFO *Event;
753 Event = AslGbl_Events;
755 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
756 if (Gbl_CompileTimesFlag)
758 printf ("\nElapsed time for major events\n\n");
761 for (i = 0; i < AslGbl_NextEvent; i++)
765 /* Delta will be in 100-nanosecond units */
767 Delta = (UINT32) (Event->EndTime - Event->StartTime);
770 MSec = Delta / 10000;
772 /* Round milliseconds up */
774 if ((USec - (MSec * 1000)) >= 500)
779 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
780 USec, MSec, Event->EventName);
782 if (Gbl_CompileTimesFlag)
784 printf ("%8u usec %8u msec - %s\n",
785 USec, MSec, Event->EventName);
794 /*******************************************************************************
796 * FUNCTION: CmCleanupAndExit
802 * DESCRIPTION: Close all open files and exit the compiler
804 ******************************************************************************/
811 BOOLEAN DeleteAmlFile = FALSE;
814 AePrintErrorLog (ASL_FILE_STDERR);
817 /* Print error summary to stdout also */
819 AePrintErrorLog (ASL_FILE_STDOUT);
822 /* Emit compile times if enabled */
826 if (Gbl_CompileTimesFlag)
828 printf ("\nMiscellaneous compile statistics\n\n");
829 printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
830 printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
831 printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
832 printf ("%11u : %s\n", TotalMethods, "Control methods");
833 printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
834 printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
835 printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
839 if (Gbl_NsLookupCount)
841 DbgPrint (ASL_DEBUG_OUTPUT,
842 "\n\nMiscellaneous compile statistics\n\n");
844 DbgPrint (ASL_DEBUG_OUTPUT,
845 "%32s : %u\n", "Total Namespace searches",
848 DbgPrint (ASL_DEBUG_OUTPUT,
849 "%32s : %u usec\n", "Time per search", ((UINT32)
850 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
851 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
855 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
857 printf ("\nMaximum error count (%u) exceeded\n",
858 ASL_MAX_ERROR_COUNT);
861 UtDisplaySummary (ASL_FILE_STDOUT);
864 * We will delete the AML file if there are errors and the
865 * force AML output option has not been used.
867 if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
868 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
870 DeleteAmlFile = TRUE;
873 /* Close all open files */
875 Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
877 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
882 /* Delete AML file if there are errors */
886 FlDeleteFile (ASL_FILE_AML_OUTPUT);
889 /* Delete the preprocessor output file (.i) unless -li flag is set */
891 if (!Gbl_PreprocessorOutputFlag &&
894 FlDeleteFile (ASL_FILE_PREPROCESSOR);
898 * Delete intermediate ("combined") source file (if -ls flag not set)
899 * This file is created during normal ASL/AML compiles. It is not
900 * created by the data table compiler.
902 * If the -ls flag is set, then the .SRC file should not be deleted.
903 * In this case, Gbl_SourceOutputFlag is set to TRUE.
905 * Note: Handles are cleared by FlCloseFile above, so we look at the
906 * filename instead, to determine if the .SRC file was actually
909 * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
911 if (!Gbl_SourceOutputFlag)
913 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);