aslcompile.c revision 246849
1/****************************************************************************** 2 * 3 * Module Name: aslcompile - top level compile module 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45#include <contrib/dev/acpica/compiler/dtcompiler.h> 46 47#include <stdio.h> 48#include <time.h> 49#include <contrib/dev/acpica/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 70FlConsumeAnsiComment ( 71 FILE *Handle, 72 ASL_FILE_STATUS *Status); 73 74static void 75FlConsumeNewComment ( 76 FILE *Handle, 77 ASL_FILE_STATUS *Status); 78 79static void 80CmDumpAllEvents ( 81 void); 82 83 84/******************************************************************************* 85 * 86 * FUNCTION: AslCompilerSignon 87 * 88 * PARAMETERS: FileId - ID of the output file 89 * 90 * RETURN: None 91 * 92 * DESCRIPTION: Display compiler signon 93 * 94 ******************************************************************************/ 95 96void 97AslCompilerSignon ( 98 UINT32 FileId) 99{ 100 char *Prefix = ""; 101 char *UtilityName; 102 103 104 /* Set line prefix depending on the destination file type */ 105 106 switch (FileId) 107 { 108 case ASL_FILE_ASM_SOURCE_OUTPUT: 109 case ASL_FILE_ASM_INCLUDE_OUTPUT: 110 111 Prefix = "; "; 112 break; 113 114 case ASL_FILE_HEX_OUTPUT: 115 116 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 117 { 118 Prefix = "; "; 119 } 120 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 121 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 122 { 123 FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 124 Prefix = " * "; 125 } 126 break; 127 128 case ASL_FILE_C_SOURCE_OUTPUT: 129 case ASL_FILE_C_INCLUDE_OUTPUT: 130 131 Prefix = " * "; 132 break; 133 134 default: 135 /* No other output types supported */ 136 break; 137 } 138 139 /* Running compiler or disassembler? */ 140 141 if (Gbl_DisasmFlag) 142 { 143 UtilityName = AML_DISASSEMBLER_NAME; 144 } 145 else 146 { 147 UtilityName = ASL_COMPILER_NAME; 148 } 149 150 /* Compiler signon with copyright */ 151 152 FlPrintFile (FileId, "%s\n", Prefix); 153 FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 154} 155 156 157/******************************************************************************* 158 * 159 * FUNCTION: AslCompilerFileHeader 160 * 161 * PARAMETERS: FileId - ID of the output file 162 * 163 * RETURN: None 164 * 165 * DESCRIPTION: Header used at the beginning of output files 166 * 167 ******************************************************************************/ 168 169void 170AslCompilerFileHeader ( 171 UINT32 FileId) 172{ 173 struct tm *NewTime; 174 time_t Aclock; 175 char *Prefix = ""; 176 177 178 /* Set line prefix depending on the destination file type */ 179 180 switch (FileId) 181 { 182 case ASL_FILE_ASM_SOURCE_OUTPUT: 183 case ASL_FILE_ASM_INCLUDE_OUTPUT: 184 185 Prefix = "; "; 186 break; 187 188 case ASL_FILE_HEX_OUTPUT: 189 190 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 191 { 192 Prefix = "; "; 193 } 194 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 195 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 196 { 197 Prefix = " * "; 198 } 199 break; 200 201 case ASL_FILE_C_SOURCE_OUTPUT: 202 case ASL_FILE_C_INCLUDE_OUTPUT: 203 204 Prefix = " * "; 205 break; 206 207 default: 208 /* No other output types supported */ 209 break; 210 } 211 212 /* Compilation header with timestamp */ 213 214 (void) time (&Aclock); 215 NewTime = localtime (&Aclock); 216 217 FlPrintFile (FileId, 218 "%sCompilation of \"%s\" - %s%s\n", 219 Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 220 Prefix); 221 222 switch (FileId) 223 { 224 case ASL_FILE_C_SOURCE_OUTPUT: 225 case ASL_FILE_C_INCLUDE_OUTPUT: 226 FlPrintFile (FileId, " */\n"); 227 break; 228 229 default: 230 /* Nothing to do for other output types */ 231 break; 232 } 233} 234 235 236/******************************************************************************* 237 * 238 * FUNCTION: CmFlushSourceCode 239 * 240 * PARAMETERS: None 241 * 242 * RETURN: None 243 * 244 * DESCRIPTION: Read in any remaining source code after the parse tree 245 * has been constructed. 246 * 247 ******************************************************************************/ 248 249static void 250CmFlushSourceCode ( 251 void) 252{ 253 char Buffer; 254 255 256 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 257 { 258 AslInsertLineBuffer ((int) Buffer); 259 } 260 261 AslResetCurrentLineBuffer (); 262} 263 264 265/******************************************************************************* 266 * 267 * FUNCTION: FlConsume* 268 * 269 * PARAMETERS: Handle - Open input file 270 * Status - File current status struct 271 * 272 * RETURN: Number of lines consumed 273 * 274 * DESCRIPTION: Step over both types of comment during check for ascii chars 275 * 276 ******************************************************************************/ 277 278static void 279FlConsumeAnsiComment ( 280 FILE *Handle, 281 ASL_FILE_STATUS *Status) 282{ 283 UINT8 Byte; 284 BOOLEAN ClosingComment = FALSE; 285 286 287 while (fread (&Byte, 1, 1, Handle) == 1) 288 { 289 /* Scan until comment close is found */ 290 291 if (ClosingComment) 292 { 293 if (Byte == '/') 294 { 295 return; 296 } 297 298 if (Byte != '*') 299 { 300 /* Reset */ 301 302 ClosingComment = FALSE; 303 } 304 } 305 else if (Byte == '*') 306 { 307 ClosingComment = TRUE; 308 } 309 310 /* Maintain line count */ 311 312 if (Byte == 0x0A) 313 { 314 Status->Line++; 315 } 316 317 Status->Offset++; 318 } 319} 320 321 322static void 323FlConsumeNewComment ( 324 FILE *Handle, 325 ASL_FILE_STATUS *Status) 326{ 327 UINT8 Byte; 328 329 330 while (fread (&Byte, 1, 1, Handle) == 1) 331 { 332 Status->Offset++; 333 334 /* Comment ends at newline */ 335 336 if (Byte == 0x0A) 337 { 338 Status->Line++; 339 return; 340 } 341 } 342} 343 344 345/******************************************************************************* 346 * 347 * FUNCTION: FlCheckForAcpiTable 348 * 349 * PARAMETERS: Handle - Open input file 350 * 351 * RETURN: Status 352 * 353 * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the 354 * following checks on what would be the table header: 355 * 0) File must be at least as long as an ACPI_TABLE_HEADER 356 * 1) The header length field must match the file size 357 * 2) Signature, OemId, OemTableId, AslCompilerId must be ASCII 358 * 359 ******************************************************************************/ 360 361ACPI_STATUS 362FlCheckForAcpiTable ( 363 FILE *Handle) 364{ 365 ACPI_TABLE_HEADER Table; 366 UINT32 FileSize; 367 size_t Actual; 368 UINT32 i; 369 370 371 /* Read a potential table header */ 372 373 Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle); 374 fseek (Handle, 0, SEEK_SET); 375 376 if (Actual < sizeof (ACPI_TABLE_HEADER)) 377 { 378 return (AE_ERROR); 379 } 380 381 /* Header length field must match the file size */ 382 383 FileSize = DtGetFileSize (Handle); 384 if (Table.Length != FileSize) 385 { 386 return (AE_ERROR); 387 } 388 389 /* 390 * These fields must be ASCII: 391 * Signature, OemId, OemTableId, AslCompilerId. 392 * We allow a NULL terminator in OemId and OemTableId. 393 */ 394 for (i = 0; i < ACPI_NAME_SIZE; i++) 395 { 396 if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i])) 397 { 398 return (AE_ERROR); 399 } 400 401 if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i])) 402 { 403 return (AE_ERROR); 404 } 405 } 406 407 for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++) 408 { 409 if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i])) 410 { 411 return (AE_ERROR); 412 } 413 } 414 415 for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++) 416 { 417 if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i])) 418 { 419 return (AE_ERROR); 420 } 421 } 422 423 printf ("Binary file appears to be a valid ACPI table, disassembling\n"); 424 return (AE_OK); 425} 426 427 428/******************************************************************************* 429 * 430 * FUNCTION: FlCheckForAscii 431 * 432 * PARAMETERS: Handle - Open input file 433 * Filename - Input filename 434 * DisplayErrors - TRUE if error messages desired 435 * 436 * RETURN: Status 437 * 438 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 439 * within comments. Note: does not handle nested comments and does 440 * not handle comment delimiters within string literals. However, 441 * on the rare chance this happens and an invalid character is 442 * missed, the parser will catch the error by failing in some 443 * spectactular manner. 444 * 445 ******************************************************************************/ 446 447ACPI_STATUS 448FlCheckForAscii ( 449 FILE *Handle, 450 char *Filename, 451 BOOLEAN DisplayErrors) 452{ 453 UINT8 Byte; 454 ACPI_SIZE BadBytes = 0; 455 BOOLEAN OpeningComment = FALSE; 456 ASL_FILE_STATUS Status; 457 458 459 Status.Line = 1; 460 Status.Offset = 0; 461 462 /* Read the entire file */ 463 464 while (fread (&Byte, 1, 1, Handle) == 1) 465 { 466 /* Ignore comment fields (allow non-ascii within) */ 467 468 if (OpeningComment) 469 { 470 /* Check for second comment open delimiter */ 471 472 if (Byte == '*') 473 { 474 FlConsumeAnsiComment (Handle, &Status); 475 } 476 477 if (Byte == '/') 478 { 479 FlConsumeNewComment (Handle, &Status); 480 } 481 482 /* Reset */ 483 484 OpeningComment = FALSE; 485 } 486 else if (Byte == '/') 487 { 488 OpeningComment = TRUE; 489 } 490 491 /* Check for an ASCII character */ 492 493 if (!ACPI_IS_ASCII (Byte)) 494 { 495 if ((BadBytes < 10) && (DisplayErrors)) 496 { 497 AcpiOsPrintf ( 498 "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 499 Byte, Status.Line, Status.Offset); 500 } 501 502 BadBytes++; 503 } 504 505 /* Update line counter */ 506 507 else if (Byte == 0x0A) 508 { 509 Status.Line++; 510 } 511 512 Status.Offset++; 513 } 514 515 /* Seek back to the beginning of the source file */ 516 517 fseek (Handle, 0, SEEK_SET); 518 519 /* Were there any non-ASCII characters in the file? */ 520 521 if (BadBytes) 522 { 523 if (DisplayErrors) 524 { 525 AcpiOsPrintf ( 526 "%u non-ASCII characters found in input source text, could be a binary file\n", 527 BadBytes); 528 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 529 } 530 531 return (AE_BAD_CHARACTER); 532 } 533 534 /* File is OK (100% ASCII) */ 535 536 return (AE_OK); 537} 538 539 540/******************************************************************************* 541 * 542 * FUNCTION: CmDoCompile 543 * 544 * PARAMETERS: None 545 * 546 * RETURN: Status (0 = OK) 547 * 548 * DESCRIPTION: This procedure performs the entire compile 549 * 550 ******************************************************************************/ 551 552int 553CmDoCompile ( 554 void) 555{ 556 ACPI_STATUS Status; 557 UINT8 FullCompile; 558 UINT8 Event; 559 560 561 FullCompile = UtBeginEvent ("*** Total Compile time ***"); 562 Event = UtBeginEvent ("Open input and output files"); 563 UtEndEvent (Event); 564 565 Event = UtBeginEvent ("Preprocess input file"); 566 if (Gbl_PreprocessFlag) 567 { 568 /* Preprocessor */ 569 570 PrDoPreprocess (); 571 if (Gbl_PreprocessOnly) 572 { 573 UtEndEvent (Event); 574 CmCleanupAndExit (); 575 return (0); 576 } 577 } 578 UtEndEvent (Event); 579 580 /* Build the parse tree */ 581 582 Event = UtBeginEvent ("Parse source code and build parse tree"); 583 AslCompilerparse(); 584 UtEndEvent (Event); 585 586 /* Flush out any remaining source after parse tree is complete */ 587 588 Event = UtBeginEvent ("Flush source input"); 589 CmFlushSourceCode (); 590 591 /* Did the parse tree get successfully constructed? */ 592 593 if (!RootNode) 594 { 595 /* 596 * If there are no errors, then we have some sort of 597 * internal problem. 598 */ 599 Status = AslCheckForErrorExit (); 600 if (Status == AE_OK) 601 { 602 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 603 NULL, "- Could not resolve parse tree root node"); 604 } 605 606 goto ErrorExit; 607 } 608 609 /* Optional parse tree dump, compiler debug output only */ 610 611 LsDumpParseTree (); 612 613 OpcGetIntegerWidth (RootNode); 614 UtEndEvent (Event); 615 616 /* Pre-process parse tree for any operator transforms */ 617 618 Event = UtBeginEvent ("Parse tree transforms"); 619 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 620 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 621 TrAmlTransformWalk, NULL, NULL); 622 UtEndEvent (Event); 623 624 /* Generate AML opcodes corresponding to the parse tokens */ 625 626 Event = UtBeginEvent ("Generate AML opcodes"); 627 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 628 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 629 OpcAmlOpcodeWalk, NULL); 630 UtEndEvent (Event); 631 632 /* 633 * Now that the input is parsed, we can open the AML output file. 634 * Note: by default, the name of this file comes from the table descriptor 635 * within the input file. 636 */ 637 Event = UtBeginEvent ("Open AML output file"); 638 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 639 UtEndEvent (Event); 640 if (ACPI_FAILURE (Status)) 641 { 642 AePrintErrorLog (ASL_FILE_STDERR); 643 return (-1); 644 } 645 646 /* Interpret and generate all compile-time constants */ 647 648 Event = UtBeginEvent ("Constant folding via AML interpreter"); 649 DbgPrint (ASL_DEBUG_OUTPUT, 650 "\nInterpreting compile-time constant expressions\n\n"); 651 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 652 OpcAmlConstantWalk, NULL, NULL); 653 UtEndEvent (Event); 654 655 /* Update AML opcodes if necessary, after constant folding */ 656 657 Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 658 DbgPrint (ASL_DEBUG_OUTPUT, 659 "\nUpdating AML opcodes after constant folding\n\n"); 660 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 661 NULL, OpcAmlOpcodeUpdateWalk, NULL); 662 UtEndEvent (Event); 663 664 /* Calculate all AML package lengths */ 665 666 Event = UtBeginEvent ("Generate AML package lengths"); 667 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 668 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 669 LnPackageLengthWalk, NULL); 670 UtEndEvent (Event); 671 672 if (Gbl_ParseOnlyFlag) 673 { 674 AePrintErrorLog (ASL_FILE_STDERR); 675 UtDisplaySummary (ASL_FILE_STDERR); 676 if (Gbl_DebugFlag) 677 { 678 /* Print error summary to the stdout also */ 679 680 AePrintErrorLog (ASL_FILE_STDOUT); 681 UtDisplaySummary (ASL_FILE_STDOUT); 682 } 683 UtEndEvent (FullCompile); 684 return (0); 685 } 686 687 /* 688 * Create an internal namespace and use it as a symbol table 689 */ 690 691 /* Namespace loading */ 692 693 Event = UtBeginEvent ("Create ACPI Namespace"); 694 Status = LdLoadNamespace (RootNode); 695 UtEndEvent (Event); 696 if (ACPI_FAILURE (Status)) 697 { 698 goto ErrorExit; 699 } 700 701 /* Namespace cross-reference */ 702 703 AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 704 Status = XfCrossReferenceNamespace (); 705 if (ACPI_FAILURE (Status)) 706 { 707 goto ErrorExit; 708 } 709 710 /* Namespace - Check for non-referenced objects */ 711 712 LkFindUnreferencedObjects (); 713 UtEndEvent (AslGbl_NamespaceEvent); 714 715 /* 716 * Semantic analysis. This can happen only after the 717 * namespace has been loaded and cross-referenced. 718 * 719 * part one - check control methods 720 */ 721 Event = UtBeginEvent ("Analyze control method return types"); 722 AnalysisWalkInfo.MethodStack = NULL; 723 724 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 725 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 726 MtMethodAnalysisWalkBegin, 727 MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 728 UtEndEvent (Event); 729 730 /* Semantic error checking part two - typing of method returns */ 731 732 Event = UtBeginEvent ("Determine object types returned by methods"); 733 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 734 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 735 NULL, AnMethodTypingWalkEnd, NULL); 736 UtEndEvent (Event); 737 738 /* Semantic error checking part three - operand type checking */ 739 740 Event = UtBeginEvent ("Analyze AML operand types"); 741 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 742 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 743 NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 744 UtEndEvent (Event); 745 746 /* Semantic error checking part four - other miscellaneous checks */ 747 748 Event = UtBeginEvent ("Miscellaneous analysis"); 749 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 750 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 751 AnOtherSemanticAnalysisWalkBegin, 752 NULL, &AnalysisWalkInfo); 753 UtEndEvent (Event); 754 755 /* Calculate all AML package lengths */ 756 757 Event = UtBeginEvent ("Finish AML package length generation"); 758 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 759 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 760 LnInitLengthsWalk, NULL); 761 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 762 LnPackageLengthWalk, NULL); 763 UtEndEvent (Event); 764 765 /* Code generation - emit the AML */ 766 767 Event = UtBeginEvent ("Generate AML code and write output files"); 768 CgGenerateAmlOutput (); 769 UtEndEvent (Event); 770 771 Event = UtBeginEvent ("Write optional output files"); 772 CmDoOutputFiles (); 773 UtEndEvent (Event); 774 775 UtEndEvent (FullCompile); 776 CmCleanupAndExit (); 777 return (0); 778 779ErrorExit: 780 UtEndEvent (FullCompile); 781 CmCleanupAndExit (); 782 return (-1); 783} 784 785 786/******************************************************************************* 787 * 788 * FUNCTION: CmDoOutputFiles 789 * 790 * PARAMETERS: None 791 * 792 * RETURN: None. 793 * 794 * DESCRIPTION: Create all "listing" type files 795 * 796 ******************************************************************************/ 797 798void 799CmDoOutputFiles ( 800 void) 801{ 802 803 /* Create listings and hex files */ 804 805 LsDoListings (); 806 HxDoHexOutput (); 807 808 /* Dump the namespace to the .nsp file if requested */ 809 810 (void) NsDisplayNamespace (); 811} 812 813 814/******************************************************************************* 815 * 816 * FUNCTION: CmDumpAllEvents 817 * 818 * PARAMETERS: None 819 * 820 * RETURN: None. 821 * 822 * DESCRIPTION: Dump all compiler events 823 * 824 ******************************************************************************/ 825 826static void 827CmDumpAllEvents ( 828 void) 829{ 830 ASL_EVENT_INFO *Event; 831 UINT32 Delta; 832 UINT32 USec; 833 UINT32 MSec; 834 UINT32 i; 835 836 837 Event = AslGbl_Events; 838 839 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 840 if (Gbl_CompileTimesFlag) 841 { 842 printf ("\nElapsed time for major events\n\n"); 843 } 844 845 for (i = 0; i < AslGbl_NextEvent; i++) 846 { 847 if (Event->Valid) 848 { 849 /* Delta will be in 100-nanosecond units */ 850 851 Delta = (UINT32) (Event->EndTime - Event->StartTime); 852 853 USec = Delta / ACPI_100NSEC_PER_USEC; 854 MSec = Delta / ACPI_100NSEC_PER_MSEC; 855 856 /* Round milliseconds up */ 857 858 if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 859 { 860 MSec++; 861 } 862 863 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 864 USec, MSec, Event->EventName); 865 866 if (Gbl_CompileTimesFlag) 867 { 868 printf ("%8u usec %8u msec - %s\n", 869 USec, MSec, Event->EventName); 870 } 871 } 872 873 Event++; 874 } 875} 876 877 878/******************************************************************************* 879 * 880 * FUNCTION: CmCleanupAndExit 881 * 882 * PARAMETERS: None 883 * 884 * RETURN: None. 885 * 886 * DESCRIPTION: Close all open files and exit the compiler 887 * 888 ******************************************************************************/ 889 890void 891CmCleanupAndExit ( 892 void) 893{ 894 UINT32 i; 895 BOOLEAN DeleteAmlFile = FALSE; 896 897 898 AePrintErrorLog (ASL_FILE_STDERR); 899 if (Gbl_DebugFlag) 900 { 901 /* Print error summary to stdout also */ 902 903 AePrintErrorLog (ASL_FILE_STDOUT); 904 } 905 906 /* Emit compile times if enabled */ 907 908 CmDumpAllEvents (); 909 910 if (Gbl_CompileTimesFlag) 911 { 912 printf ("\nMiscellaneous compile statistics\n\n"); 913 printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 914 printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 915 printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 916 printf ("%11u : %s\n", TotalMethods, "Control methods"); 917 printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 918 printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 919 printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 920 printf ("\n"); 921 } 922 923 if (Gbl_NsLookupCount) 924 { 925 DbgPrint (ASL_DEBUG_OUTPUT, 926 "\n\nMiscellaneous compile statistics\n\n"); 927 928 DbgPrint (ASL_DEBUG_OUTPUT, 929 "%32s : %u\n", "Total Namespace searches", 930 Gbl_NsLookupCount); 931 932 DbgPrint (ASL_DEBUG_OUTPUT, 933 "%32s : %u usec\n", "Time per search", ((UINT32) 934 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 935 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 936 Gbl_NsLookupCount); 937 } 938 939 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 940 { 941 printf ("\nMaximum error count (%u) exceeded\n", 942 ASL_MAX_ERROR_COUNT); 943 } 944 945 UtDisplaySummary (ASL_FILE_STDOUT); 946 947 /* 948 * We will delete the AML file if there are errors and the 949 * force AML output option has not been used. 950 */ 951 if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 952 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 953 { 954 DeleteAmlFile = TRUE; 955 } 956 957 /* Close all open files */ 958 959 Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 960 961 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 962 { 963 FlCloseFile (i); 964 } 965 966 /* Delete AML file if there are errors */ 967 968 if (DeleteAmlFile) 969 { 970 FlDeleteFile (ASL_FILE_AML_OUTPUT); 971 } 972 973 /* Delete the preprocessor output file (.i) unless -li flag is set */ 974 975 if (!Gbl_PreprocessorOutputFlag && 976 Gbl_PreprocessFlag) 977 { 978 FlDeleteFile (ASL_FILE_PREPROCESSOR); 979 } 980 981 /* 982 * Delete intermediate ("combined") source file (if -ls flag not set) 983 * This file is created during normal ASL/AML compiles. It is not 984 * created by the data table compiler. 985 * 986 * If the -ls flag is set, then the .SRC file should not be deleted. 987 * In this case, Gbl_SourceOutputFlag is set to TRUE. 988 * 989 * Note: Handles are cleared by FlCloseFile above, so we look at the 990 * filename instead, to determine if the .SRC file was actually 991 * created. 992 * 993 * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 994 */ 995 if (!Gbl_SourceOutputFlag) 996 { 997 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 998 } 999} 1000