xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcompile.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 - 2023, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include <contrib/dev/acpica/include/acnamesp.h>
154 
155 #include <stdio.h>
156 #include <time.h>
157 #include <contrib/dev/acpica/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     Aclock = time (NULL);
703     NewTime = ctime (&Aclock);
704 
705     FlPrintFile (FileId,
706         "%sCompilation of \"%s\" -",
707         Prefix, AslGbl_Files[ASL_FILE_INPUT].Filename);
708 
709     if (NewTime)
710     {
711         FlPrintFile (FileId, " %s%s\n", NewTime, Prefix);
712     }
713 
714     switch (FileId)
715     {
716     case ASL_FILE_C_SOURCE_OUTPUT:
717     case ASL_FILE_C_OFFSET_OUTPUT:
718     case ASL_FILE_C_INCLUDE_OUTPUT:
719 
720         FlPrintFile (FileId, " */\n");
721         break;
722 
723     default:
724 
725         /* Nothing to do for other output types */
726 
727         break;
728     }
729 }
730 
731 
732 /*******************************************************************************
733  *
734  * FUNCTION:    CmFlushSourceCode
735  *
736  * PARAMETERS:  None
737  *
738  * RETURN:      None
739  *
740  * DESCRIPTION: Read in any remaining source code after the parse tree
741  *              has been constructed.
742  *
743  ******************************************************************************/
744 
745 static void
746 CmFlushSourceCode (
747     void)
748 {
749     char                    Buffer;
750 
751 
752     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
753     {
754         AslInsertLineBuffer ((int) Buffer);
755     }
756 
757     AslResetCurrentLineBuffer ();
758 }
759 
760 
761 /*******************************************************************************
762  *
763  * FUNCTION:    CmDoOutputFiles
764  *
765  * PARAMETERS:  None
766  *
767  * RETURN:      None.
768  *
769  * DESCRIPTION: Create all "listing" type files
770  *
771  ******************************************************************************/
772 
773 void
774 CmDoOutputFiles (
775     void)
776 {
777 
778     /* Create listings and hex files */
779 
780     LsDoListings ();
781     HxDoHexOutput ();
782 
783     /* Dump the namespace to the .nsp file if requested */
784 
785     (void) NsDisplayNamespace ();
786 
787     /* Dump the device mapping file */
788 
789     MpEmitMappingInfo ();
790 }
791 
792 
793 /*******************************************************************************
794  *
795  * FUNCTION:    CmDumpAllEvents
796  *
797  * PARAMETERS:  None
798  *
799  * RETURN:      None.
800  *
801  * DESCRIPTION: Dump all compiler events
802  *
803  ******************************************************************************/
804 
805 static void
806 CmDumpAllEvents (
807     void)
808 {
809     ASL_EVENT_INFO          *Event;
810     UINT32                  Delta;
811     UINT32                  MicroSeconds;
812     UINT32                  MilliSeconds;
813     UINT32                  i;
814 
815 
816     Event = AslGbl_Events;
817 
818     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
819     if (AslGbl_CompileTimesFlag)
820     {
821         printf ("\nElapsed time for major events\n\n");
822     }
823 
824     for (i = 0; i < AslGbl_NextEvent; i++)
825     {
826         if (Event->Valid)
827         {
828             /* Delta will be in 100-nanosecond units */
829 
830             Delta = (UINT32) (Event->EndTime - Event->StartTime);
831 
832             MicroSeconds = Delta / ACPI_100NSEC_PER_USEC;
833             MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC;
834 
835             /* Round milliseconds up */
836 
837             if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500)
838             {
839                 MilliSeconds++;
840             }
841 
842             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
843                 MicroSeconds, MilliSeconds, Event->EventName);
844 
845             if (AslGbl_CompileTimesFlag)
846             {
847                 printf ("%8u usec %8u msec - %s\n",
848                     MicroSeconds, MilliSeconds, Event->EventName);
849             }
850         }
851 
852         Event++;
853     }
854 }
855 
856 
857 /*******************************************************************************
858  *
859  * FUNCTION:    CmCleanupAndExit
860  *
861  * PARAMETERS:  None
862  *
863  * RETURN:      None.
864  *
865  * DESCRIPTION: Close all open files and exit the compiler
866  *
867  ******************************************************************************/
868 
869 int
870 CmCleanupAndExit (
871     void)
872 {
873     int                     Status = 0;
874     BOOLEAN                 DeleteAmlFile = FALSE;
875     ASL_GLOBAL_FILE_NODE    *CurrentFileNode = AslGbl_FilesList;
876 
877 
878     /* Check if any errors occurred during compile */
879 
880     (void) AslCheckForErrorExit ();
881 
882     AePrintErrorLog (ASL_FILE_STDERR);
883     if (AslGbl_DebugFlag)
884     {
885         /* Print error summary to stdout also */
886 
887         AePrintErrorLog (ASL_FILE_STDOUT);
888     }
889 
890     /* Emit compile times if enabled */
891 
892     CmDumpAllEvents ();
893 
894     if (AslGbl_CompileTimesFlag)
895     {
896         printf ("\nMiscellaneous compile statistics\n\n");
897         printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes");
898         printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches");
899         printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects");
900         printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods");
901         printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations");
902         printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory");
903         printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded");
904         printf ("\n");
905     }
906 
907     if (AslGbl_NsLookupCount)
908     {
909         DbgPrint (ASL_DEBUG_OUTPUT,
910             "\n\nMiscellaneous compile statistics\n\n");
911 
912         DbgPrint (ASL_DEBUG_OUTPUT,
913             "%32s : %u\n", "Total Namespace searches",
914             AslGbl_NsLookupCount);
915 
916         DbgPrint (ASL_DEBUG_OUTPUT,
917             "%32s : %u usec\n", "Time per search", ((UINT32)
918             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
919                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
920                 AslGbl_NsLookupCount);
921     }
922 
923     if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
924     {
925         printf ("\nMaximum error count (%d) exceeded (aslcompile.c)\n",
926             ASL_MAX_ERROR_COUNT);
927     }
928 
929     UtDisplaySummary (ASL_FILE_STDOUT);
930 
931     /*
932      * Delete the AML file if there are errors and the force AML output option
933      * (-f) has not been used.
934      *
935      * Return -1 as a status of the compiler if no AML files are generated. If
936      * the AML file is generated in the presence of errors, return 0. In the
937      * latter case, the errors were ignored by the user so the compilation is
938      * considered successful.
939      */
940     if (AslGbl_ParserErrorDetected || AslGbl_PreprocessOnly ||
941         ((AslGbl_ExceptionCount[ASL_ERROR] > 0) &&
942         (!AslGbl_IgnoreErrors) &&
943         AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle))
944     {
945         DeleteAmlFile = TRUE;
946         Status = -1;
947     }
948 
949     /* Close all open files */
950 
951     while (CurrentFileNode)
952     {
953         /*
954          * Set the program return status based on file errors. If there are any
955          * errors and during compilation, the command is not considered
956          * successful.
957          */
958         if (Status != -1 && !AslGbl_IgnoreErrors &&
959             CurrentFileNode->ParserErrorDetected)
960         {
961             Status = -1;
962         }
963 
964         switch  (FlSwitchFileSet (CurrentFileNode->Files[ASL_FILE_INPUT].Filename))
965         {
966             case SWITCH_TO_SAME_FILE:
967             case SWITCH_TO_DIFFERENT_FILE:
968 
969                 CmFinishFiles (DeleteAmlFile);
970                 CurrentFileNode = CurrentFileNode->Next;
971                 break;
972 
973             case FILE_NOT_FOUND:
974             default:
975 
976                 CurrentFileNode = NULL;
977                 break;
978         }
979     }
980 
981     /* Final cleanup after compiling one file */
982 
983     if (!AslGbl_DoAslConversion)
984     {
985         UtDeleteLocalCaches ();
986     }
987 
988     return (Status);
989 }
990 
991 
992 /*******************************************************************************
993  *
994  * FUNCTION:    CmFinishFiles
995  *
996  * PARAMETERS:  DeleteAmlFile
997  *
998  * RETURN:      None.
999  *
1000  * DESCRIPTION: Close all open files, delete AML files depending on the
1001  *              function parameter is true.
1002  *
1003  ******************************************************************************/
1004 
1005 static void
1006 CmFinishFiles(
1007     BOOLEAN                 DeleteAmlFile)
1008 {
1009     UINT32                  i;
1010 
1011 
1012     /*
1013      * Take care with the preprocessor file (.pre), it might be the same
1014      * as the "input" file, depending on where the compiler has terminated
1015      * or aborted. Prevent attempt to close the same file twice in
1016      * loop below.
1017      */
1018     if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
1019         AslGbl_Files[ASL_FILE_INPUT].Handle)
1020     {
1021         AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
1022     }
1023 
1024     /* Close the standard I/O files */
1025 
1026     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
1027     {
1028         /*
1029          * Some files such as debug output files could be pointing to
1030          * stderr or stdout. Leave these alone.
1031          */
1032         if (AslGbl_Files[i].Handle != stderr &&
1033             AslGbl_Files[i].Handle != stdout)
1034         {
1035             FlCloseFile (i);
1036         }
1037     }
1038 
1039     /* Delete AML file if there are errors */
1040 
1041     if (DeleteAmlFile)
1042     {
1043         FlDeleteFile (ASL_FILE_AML_OUTPUT);
1044     }
1045 
1046     /* Delete the preprocessor temp file unless full debug was specified */
1047 
1048     if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile)
1049     {
1050         FlDeleteFile (ASL_FILE_PREPROCESSOR);
1051     }
1052 
1053     /*
1054      * Delete intermediate ("combined") source file (if -ls flag not set)
1055      * This file is created during normal ASL/AML compiles. It is not
1056      * created by the data table compiler.
1057      *
1058      * If the -ls flag is set, then the .SRC file should not be deleted.
1059      * In this case, Gbl_SourceOutputFlag is set to TRUE.
1060      *
1061      * Note: Handles are cleared by FlCloseFile above, so we look at the
1062      * filename instead, to determine if the .SRC file was actually
1063      * created.
1064      */
1065     if (!AslGbl_SourceOutputFlag)
1066     {
1067         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
1068     }
1069 }
1070