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