1 /****************************************************************************** 2 * 3 * Module Name: aslcompile - top level compile module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2023, 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 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 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 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 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 FlPrintFile (FileId, 595 "%sCompilation of \"%s\"", 596 Prefix, AslGbl_Files[ASL_FILE_INPUT].Filename); 597 598 if (!AslGbl_Deterministic) 599 { 600 Aclock = time (NULL); 601 NewTime = ctime (&Aclock); 602 if (NewTime) 603 { 604 FlPrintFile (FileId, " - %s%s\n", NewTime, Prefix); 605 } 606 } 607 else 608 { 609 FlPrintFile (FileId, "\n"); 610 } 611 612 switch (FileId) 613 { 614 case ASL_FILE_C_SOURCE_OUTPUT: 615 case ASL_FILE_C_OFFSET_OUTPUT: 616 case ASL_FILE_C_INCLUDE_OUTPUT: 617 618 FlPrintFile (FileId, " */\n"); 619 break; 620 621 default: 622 623 /* Nothing to do for other output types */ 624 625 break; 626 } 627 } 628 629 630 /******************************************************************************* 631 * 632 * FUNCTION: CmFlushSourceCode 633 * 634 * PARAMETERS: None 635 * 636 * RETURN: None 637 * 638 * DESCRIPTION: Read in any remaining source code after the parse tree 639 * has been constructed. 640 * 641 ******************************************************************************/ 642 643 static void 644 CmFlushSourceCode ( 645 void) 646 { 647 char Buffer; 648 649 650 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 651 { 652 AslInsertLineBuffer ((int) Buffer); 653 } 654 655 AslResetCurrentLineBuffer (); 656 } 657 658 659 /******************************************************************************* 660 * 661 * FUNCTION: CmDoOutputFiles 662 * 663 * PARAMETERS: None 664 * 665 * RETURN: None. 666 * 667 * DESCRIPTION: Create all "listing" type files 668 * 669 ******************************************************************************/ 670 671 void 672 CmDoOutputFiles ( 673 void) 674 { 675 676 /* Create listings and hex files */ 677 678 LsDoListings (); 679 HxDoHexOutput (); 680 681 /* Dump the namespace to the .nsp file if requested */ 682 683 (void) NsDisplayNamespace (); 684 685 /* Dump the device mapping file */ 686 687 MpEmitMappingInfo (); 688 } 689 690 691 /******************************************************************************* 692 * 693 * FUNCTION: CmDumpAllEvents 694 * 695 * PARAMETERS: None 696 * 697 * RETURN: None. 698 * 699 * DESCRIPTION: Dump all compiler events 700 * 701 ******************************************************************************/ 702 703 static void 704 CmDumpAllEvents ( 705 void) 706 { 707 ASL_EVENT_INFO *Event; 708 UINT32 Delta; 709 UINT32 MicroSeconds; 710 UINT32 MilliSeconds; 711 UINT32 i; 712 713 714 Event = AslGbl_Events; 715 716 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 717 if (AslGbl_CompileTimesFlag) 718 { 719 printf ("\nElapsed time for major events\n\n"); 720 } 721 722 for (i = 0; i < AslGbl_NextEvent; i++) 723 { 724 if (Event->Valid) 725 { 726 /* Delta will be in 100-nanosecond units */ 727 728 Delta = (UINT32) (Event->EndTime - Event->StartTime); 729 730 MicroSeconds = Delta / ACPI_100NSEC_PER_USEC; 731 MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC; 732 733 /* Round milliseconds up */ 734 735 if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500) 736 { 737 MilliSeconds++; 738 } 739 740 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 741 MicroSeconds, MilliSeconds, Event->EventName); 742 743 if (AslGbl_CompileTimesFlag) 744 { 745 printf ("%8u usec %8u msec - %s\n", 746 MicroSeconds, MilliSeconds, Event->EventName); 747 } 748 } 749 750 Event++; 751 } 752 } 753 754 755 /******************************************************************************* 756 * 757 * FUNCTION: CmCleanupAndExit 758 * 759 * PARAMETERS: None 760 * 761 * RETURN: None. 762 * 763 * DESCRIPTION: Close all open files and exit the compiler 764 * 765 ******************************************************************************/ 766 767 int 768 CmCleanupAndExit ( 769 void) 770 { 771 int Status = 0; 772 BOOLEAN DeleteAmlFile = FALSE; 773 ASL_GLOBAL_FILE_NODE *CurrentFileNode = AslGbl_FilesList; 774 775 776 /* Check if any errors occurred during compile */ 777 778 (void) AslCheckForErrorExit (); 779 780 AePrintErrorLog (ASL_FILE_STDERR); 781 if (AslGbl_DebugFlag) 782 { 783 /* Print error summary to stdout also */ 784 785 AePrintErrorLog (ASL_FILE_STDOUT); 786 } 787 788 /* Emit compile times if enabled */ 789 790 CmDumpAllEvents (); 791 792 if (AslGbl_CompileTimesFlag) 793 { 794 printf ("\nMiscellaneous compile statistics\n\n"); 795 printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes"); 796 printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches"); 797 printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects"); 798 printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods"); 799 printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations"); 800 printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory"); 801 printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded"); 802 printf ("\n"); 803 } 804 805 if (AslGbl_NsLookupCount) 806 { 807 DbgPrint (ASL_DEBUG_OUTPUT, 808 "\n\nMiscellaneous compile statistics\n\n"); 809 810 DbgPrint (ASL_DEBUG_OUTPUT, 811 "%32s : %u\n", "Total Namespace searches", 812 AslGbl_NsLookupCount); 813 814 DbgPrint (ASL_DEBUG_OUTPUT, 815 "%32s : %u usec\n", "Time per search", ((UINT32) 816 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 817 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 818 AslGbl_NsLookupCount); 819 } 820 821 if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 822 { 823 printf ("\nMaximum error count (%d) exceeded (aslcompile.c)\n", 824 ASL_MAX_ERROR_COUNT); 825 } 826 827 UtDisplaySummary (ASL_FILE_STDOUT); 828 829 /* 830 * Delete the AML file if there are errors and the force AML output option 831 * (-f) has not been used. 832 * 833 * Return -1 as a status of the compiler if no AML files are generated. If 834 * the AML file is generated in the presence of errors, return 0. In the 835 * latter case, the errors were ignored by the user so the compilation is 836 * considered successful. 837 */ 838 if (AslGbl_ParserErrorDetected || AslGbl_PreprocessOnly || 839 ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && 840 (!AslGbl_IgnoreErrors) && 841 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle)) 842 { 843 DeleteAmlFile = TRUE; 844 Status = -1; 845 } 846 847 /* Close all open files */ 848 849 while (CurrentFileNode) 850 { 851 /* 852 * Set the program return status based on file errors. If there are any 853 * errors and during compilation, the command is not considered 854 * successful. 855 */ 856 if (Status != -1 && !AslGbl_IgnoreErrors && 857 CurrentFileNode->ParserErrorDetected) 858 { 859 Status = -1; 860 } 861 862 switch (FlSwitchFileSet (CurrentFileNode->Files[ASL_FILE_INPUT].Filename)) 863 { 864 case SWITCH_TO_SAME_FILE: 865 case SWITCH_TO_DIFFERENT_FILE: 866 867 CmFinishFiles (DeleteAmlFile); 868 CurrentFileNode = CurrentFileNode->Next; 869 break; 870 871 case FILE_NOT_FOUND: 872 default: 873 874 CurrentFileNode = NULL; 875 break; 876 } 877 } 878 879 /* Final cleanup after compiling one file */ 880 881 if (!AslGbl_DoAslConversion) 882 { 883 UtDeleteLocalCaches (); 884 } 885 886 return (Status); 887 } 888 889 890 /******************************************************************************* 891 * 892 * FUNCTION: CmFinishFiles 893 * 894 * PARAMETERS: DeleteAmlFile 895 * 896 * RETURN: None. 897 * 898 * DESCRIPTION: Close all open files, delete AML files depending on the 899 * function parameter is true. 900 * 901 ******************************************************************************/ 902 903 static void 904 CmFinishFiles( 905 BOOLEAN DeleteAmlFile) 906 { 907 UINT32 i; 908 909 910 /* 911 * Take care with the preprocessor file (.pre), it might be the same 912 * as the "input" file, depending on where the compiler has terminated 913 * or aborted. Prevent attempt to close the same file twice in 914 * loop below. 915 */ 916 if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle == 917 AslGbl_Files[ASL_FILE_INPUT].Handle) 918 { 919 AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; 920 } 921 922 /* Close the standard I/O files */ 923 924 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 925 { 926 /* 927 * Some files such as debug output files could be pointing to 928 * stderr or stdout. Leave these alone. 929 */ 930 if (AslGbl_Files[i].Handle != stderr && 931 AslGbl_Files[i].Handle != stdout) 932 { 933 FlCloseFile (i); 934 } 935 } 936 937 /* Delete AML file if there are errors */ 938 939 if (DeleteAmlFile) 940 { 941 FlDeleteFile (ASL_FILE_AML_OUTPUT); 942 } 943 944 /* Delete the preprocessor temp file unless full debug was specified */ 945 946 if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile) 947 { 948 FlDeleteFile (ASL_FILE_PREPROCESSOR); 949 } 950 951 /* 952 * Delete intermediate ("combined") source file (if -ls flag not set) 953 * This file is created during normal ASL/AML compiles. It is not 954 * created by the data table compiler. 955 * 956 * If the -ls flag is set, then the .SRC file should not be deleted. 957 * In this case, Gbl_SourceOutputFlag is set to TRUE. 958 * 959 * Note: Handles are cleared by FlCloseFile above, so we look at the 960 * filename instead, to determine if the .SRC file was actually 961 * created. 962 */ 963 if (!AslGbl_SourceOutputFlag) 964 { 965 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 966 } 967 } 968