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