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