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