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