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