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 */ 59int 60AslCompilerparse( 61 void); 62 63/* Local prototypes */ 64 65static void 66CmFlushSourceCode ( 67 void); 68 69static void 70CmDumpAllEvents ( 71 void); 72 73static void 74CmFinishFiles( 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 90ACPI_STATUS 91CmDoCompile ( 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; 189ErrorExit: 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 208int 209CmDoAslMiddleAndBackEnd ( 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 470void 471AslCompilerSignon ( 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 546void 547AslCompilerFileHeader ( 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 637static void 638CmFlushSourceCode ( 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 665void 666CmDoOutputFiles ( 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 697static void 698CmDumpAllEvents ( 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 761int 762CmCleanupAndExit ( 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 897static void 898CmFinishFiles( 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