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