1 /****************************************************************************** 2 * 3 * Module Name: asloptions - compiler command line processing 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "acapps.h" 46 #include "acdisasm.h" 47 48 #define _COMPONENT ACPI_COMPILER 49 ACPI_MODULE_NAME ("asloption") 50 51 52 /* Local prototypes */ 53 54 static int 55 AslDoOptions ( 56 int argc, 57 char **argv, 58 BOOLEAN IsResponseFile); 59 60 static void 61 AslMergeOptionTokens ( 62 char *InBuffer, 63 char *OutBuffer); 64 65 static int 66 AslDoResponseFile ( 67 char *Filename); 68 69 70 #define ASL_TOKEN_SEPARATORS " \t\n" 71 #define ASL_SUPPORTED_OPTIONS "@:a:b|c|d^D:e:f^gh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z" 72 73 static char ASL_BUILD_DATE[] = __DATE__; 74 static char ASL_BUILD_TIME[] = __TIME__; 75 76 77 /******************************************************************************* 78 * 79 * FUNCTION: AslCommandLine 80 * 81 * PARAMETERS: argc/argv 82 * 83 * RETURN: Last argv index 84 * 85 * DESCRIPTION: Command line processing 86 * 87 ******************************************************************************/ 88 89 int 90 AslCommandLine ( 91 int argc, 92 char **argv) 93 { 94 int BadCommandLine = 0; 95 ACPI_STATUS Status; 96 97 98 /* Minimum command line contains at least the command and an input file */ 99 100 if (argc < 2) 101 { 102 printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); 103 Usage (); 104 exit (1); 105 } 106 107 /* Process all command line options */ 108 109 BadCommandLine = AslDoOptions (argc, argv, FALSE); 110 111 if (Gbl_DoTemplates) 112 { 113 Status = DtCreateTemplates (argv); 114 if (ACPI_FAILURE (Status)) 115 { 116 exit (-1); 117 } 118 exit (1); 119 } 120 121 /* Next parameter must be the input filename */ 122 123 if (!argv[AcpiGbl_Optind] && 124 !Gbl_DisasmFlag) 125 { 126 printf ("Missing input filename\n"); 127 BadCommandLine = TRUE; 128 } 129 130 if (Gbl_DoSignon) 131 { 132 printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); 133 if (Gbl_IgnoreErrors) 134 { 135 printf ("Ignoring all errors, forcing AML file generation\n\n"); 136 } 137 } 138 139 if (BadCommandLine) 140 { 141 printf ("Use -h option for help information\n"); 142 exit (1); 143 } 144 145 return (AcpiGbl_Optind); 146 } 147 148 149 /******************************************************************************* 150 * 151 * FUNCTION: AslDoOptions 152 * 153 * PARAMETERS: argc/argv - Standard argc/argv 154 * IsResponseFile - TRUE if executing a response file. 155 * 156 * RETURN: Status 157 * 158 * DESCRIPTION: Command line option processing 159 * 160 ******************************************************************************/ 161 162 static int 163 AslDoOptions ( 164 int argc, 165 char **argv, 166 BOOLEAN IsResponseFile) 167 { 168 ACPI_STATUS Status; 169 UINT32 j; 170 171 172 /* Get the command line options */ 173 174 while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 175 { 176 case '@': /* Begin a response file */ 177 178 if (IsResponseFile) 179 { 180 printf ("Nested command files are not supported\n"); 181 return (-1); 182 } 183 184 if (AslDoResponseFile (AcpiGbl_Optarg)) 185 { 186 return (-1); 187 } 188 break; 189 190 case 'a': /* Debug options */ 191 192 switch (AcpiGbl_Optarg[0]) 193 { 194 case 'r': 195 196 Gbl_EnableReferenceTypechecking = TRUE; 197 break; 198 199 default: 200 201 printf ("Unknown option: -a%s\n", AcpiGbl_Optarg); 202 return (-1); 203 } 204 205 break; 206 207 208 case 'b': /* Debug options */ 209 210 switch (AcpiGbl_Optarg[0]) 211 { 212 case 'f': 213 214 AslCompilerdebug = 1; /* same as yydebug */ 215 DtParserdebug = 1; 216 PrParserdebug = 1; 217 Gbl_DebugFlag = TRUE; 218 Gbl_KeepPreprocessorTempFile = TRUE; 219 break; 220 221 case 'p': /* Prune ASL parse tree */ 222 223 /* Get the required argument */ 224 225 if (AcpiGetoptArgument (argc, argv)) 226 { 227 return (-1); 228 } 229 230 Gbl_PruneParseTree = TRUE; 231 Gbl_PruneDepth = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 232 break; 233 234 case 's': 235 236 Gbl_DebugFlag = TRUE; 237 break; 238 239 case 't': 240 241 /* Get the required argument */ 242 243 if (AcpiGetoptArgument (argc, argv)) 244 { 245 return (-1); 246 } 247 248 Gbl_PruneType = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 249 break; 250 251 default: 252 253 printf ("Unknown option: -b%s\n", AcpiGbl_Optarg); 254 return (-1); 255 } 256 257 break; 258 259 case 'c': 260 261 switch (AcpiGbl_Optarg[0]) 262 { 263 case 'r': 264 265 Gbl_NoResourceChecking = TRUE; 266 break; 267 268 default: 269 270 printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); 271 return (-1); 272 } 273 break; 274 275 case 'd': /* Disassembler */ 276 277 switch (AcpiGbl_Optarg[0]) 278 { 279 case '^': 280 281 /* Get the required argument */ 282 283 if (AcpiGetoptArgument (argc, argv)) 284 { 285 return (-1); 286 } 287 288 Gbl_DoCompile = FALSE; 289 break; 290 291 case 'a': 292 293 /* Get the required argument */ 294 295 if (AcpiGetoptArgument (argc, argv)) 296 { 297 return (-1); 298 } 299 300 Gbl_DoCompile = FALSE; 301 Gbl_DisassembleAll = TRUE; 302 break; 303 304 case 'b': /* Do not convert buffers to resource descriptors */ 305 306 AcpiGbl_NoResourceDisassembly = TRUE; 307 break; 308 309 case 'c': 310 311 break; 312 313 case 'f': 314 315 AcpiGbl_ForceAmlDisassembly = TRUE; 316 break; 317 318 case 'l': /* Use legacy ASL code (not ASL+) for disassembly */ 319 320 Gbl_DoCompile = FALSE; 321 AcpiGbl_CstyleDisassembly = FALSE; 322 break; 323 324 default: 325 326 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 327 return (-1); 328 } 329 330 Gbl_DisasmFlag = TRUE; 331 break; 332 333 case 'D': /* Define a symbol */ 334 335 PrAddDefine (AcpiGbl_Optarg, NULL, TRUE); 336 break; 337 338 case 'e': /* External files for disassembler */ 339 340 /* Get entire list of external files */ 341 342 AcpiGbl_Optind--; 343 argv[AcpiGbl_Optind] = AcpiGbl_Optarg; 344 345 while (argv[AcpiGbl_Optind] && 346 (argv[AcpiGbl_Optind][0] != '-')) 347 { 348 Status = AcpiDmAddToExternalFileList (argv[AcpiGbl_Optind]); 349 if (ACPI_FAILURE (Status)) 350 { 351 printf ("Could not add %s to external list\n", 352 argv[AcpiGbl_Optind]); 353 return (-1); 354 } 355 356 AcpiGbl_Optind++; 357 } 358 break; 359 360 case 'f': 361 362 switch (AcpiGbl_Optarg[0]) 363 { 364 case '^': /* Ignore errors and force creation of aml file */ 365 366 Gbl_IgnoreErrors = TRUE; 367 break; 368 369 case 'e': /* Disassembler: Get external declaration file */ 370 371 if (AcpiGetoptArgument (argc, argv)) 372 { 373 return (-1); 374 } 375 376 Gbl_ExternalRefFilename = AcpiGbl_Optarg; 377 break; 378 379 default: 380 381 printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); 382 return (-1); 383 } 384 break; 385 386 case 'G': 387 388 Gbl_CompileGeneric = TRUE; 389 break; 390 391 case 'g': /* Get all ACPI tables */ 392 393 printf ("-g option is deprecated, use acpidump utility instead\n"); 394 exit (1); 395 396 case 'h': 397 398 switch (AcpiGbl_Optarg[0]) 399 { 400 case '^': 401 402 Usage (); 403 exit (0); 404 405 case 'c': 406 407 UtDisplayConstantOpcodes (); 408 exit (0); 409 410 case 'd': 411 412 AslDisassemblyHelp (); 413 exit (0); 414 415 case 'f': 416 417 AslFilenameHelp (); 418 exit (0); 419 420 case 'r': 421 422 /* reserved names */ 423 424 ApDisplayReservedNames (); 425 exit (0); 426 427 case 't': 428 429 UtDisplaySupportedTables (); 430 exit (0); 431 432 default: 433 434 printf ("Unknown option: -h%s\n", AcpiGbl_Optarg); 435 return (-1); 436 } 437 438 case 'I': /* Add an include file search directory */ 439 440 FlAddIncludeDirectory (AcpiGbl_Optarg); 441 break; 442 443 case 'i': /* Output AML as an include file */ 444 445 switch (AcpiGbl_Optarg[0]) 446 { 447 case 'a': 448 449 /* Produce assembly code include file */ 450 451 Gbl_AsmIncludeOutputFlag = TRUE; 452 break; 453 454 case 'c': 455 456 /* Produce C include file */ 457 458 Gbl_C_IncludeOutputFlag = TRUE; 459 break; 460 461 case 'n': 462 463 /* Compiler/Disassembler: Ignore the NOOP operator */ 464 465 AcpiGbl_IgnoreNoopOperator = TRUE; 466 break; 467 468 default: 469 470 printf ("Unknown option: -i%s\n", AcpiGbl_Optarg); 471 return (-1); 472 } 473 break; 474 475 case 'l': /* Listing files */ 476 477 switch (AcpiGbl_Optarg[0]) 478 { 479 case '^': 480 481 /* Produce listing file (Mixed source/aml) */ 482 483 Gbl_ListingFlag = TRUE; 484 AcpiGbl_DmOpt_Listing = TRUE; 485 break; 486 487 case 'i': 488 489 /* Produce preprocessor output file */ 490 491 Gbl_PreprocessorOutputFlag = TRUE; 492 break; 493 494 case 'm': 495 496 /* Produce hardware map summary file */ 497 498 Gbl_MapfileFlag = TRUE; 499 break; 500 501 case 'n': 502 503 /* Produce namespace file */ 504 505 Gbl_NsOutputFlag = TRUE; 506 break; 507 508 case 's': 509 510 /* Produce combined source file */ 511 512 Gbl_SourceOutputFlag = TRUE; 513 break; 514 515 case 'x': 516 517 /* Produce cross-reference file */ 518 519 Gbl_CrossReferenceOutput = TRUE; 520 break; 521 522 default: 523 524 printf ("Unknown option: -l%s\n", AcpiGbl_Optarg); 525 return (-1); 526 } 527 break; 528 529 case 'm': /* Set line buffer size */ 530 531 Gbl_LineBufferSize = (UINT32) strtoul (AcpiGbl_Optarg, NULL, 0) * 1024; 532 if (Gbl_LineBufferSize < ASL_DEFAULT_LINE_BUFFER_SIZE) 533 { 534 Gbl_LineBufferSize = ASL_DEFAULT_LINE_BUFFER_SIZE; 535 } 536 printf ("Line Buffer Size: %u\n", Gbl_LineBufferSize); 537 break; 538 539 case 'n': /* Parse only */ 540 541 Gbl_ParseOnlyFlag = TRUE; 542 break; 543 544 case 'o': /* Control compiler AML optimizations */ 545 546 switch (AcpiGbl_Optarg[0]) 547 { 548 case 'a': 549 550 /* Disable all optimizations */ 551 552 Gbl_FoldConstants = FALSE; 553 Gbl_IntegerOptimizationFlag = FALSE; 554 Gbl_ReferenceOptimizationFlag = FALSE; 555 break; 556 557 case 'c': 558 559 /* Display compile time(s) */ 560 561 Gbl_CompileTimesFlag = TRUE; 562 break; 563 564 case 'e': 565 566 /* iASL: Disable External opcode generation */ 567 568 Gbl_DoExternals = FALSE; 569 570 /* Disassembler: Emit embedded external operators */ 571 572 AcpiGbl_DmEmitExternalOpcodes = TRUE; 573 break; 574 575 case 'f': 576 577 /* Disable folding on "normal" expressions */ 578 579 Gbl_FoldConstants = FALSE; 580 break; 581 582 case 'i': 583 584 /* Disable integer optimization to constants */ 585 586 Gbl_IntegerOptimizationFlag = FALSE; 587 break; 588 589 case 'n': 590 591 /* Disable named reference optimization */ 592 593 Gbl_ReferenceOptimizationFlag = FALSE; 594 break; 595 596 case 't': 597 598 /* Disable heavy typechecking */ 599 600 Gbl_DoTypechecking = FALSE; 601 break; 602 603 default: 604 605 printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); 606 return (-1); 607 } 608 break; 609 610 case 'P': /* Preprocessor options */ 611 612 switch (AcpiGbl_Optarg[0]) 613 { 614 case '^': /* Proprocess only, emit (.i) file */ 615 616 Gbl_PreprocessOnly = TRUE; 617 Gbl_PreprocessorOutputFlag = TRUE; 618 break; 619 620 case 'n': /* Disable preprocessor */ 621 622 Gbl_PreprocessFlag = FALSE; 623 break; 624 625 default: 626 627 printf ("Unknown option: -P%s\n", AcpiGbl_Optarg); 628 return (-1); 629 } 630 break; 631 632 case 'p': /* Override default AML output filename */ 633 634 Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; 635 UtConvertBackslashes (Gbl_OutputFilenamePrefix); 636 Gbl_UseDefaultAmlFilename = FALSE; 637 break; 638 639 case 'r': /* Override revision found in table header */ 640 641 Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 642 break; 643 644 case 's': /* Create AML in a source code file */ 645 646 switch (AcpiGbl_Optarg[0]) 647 { 648 case 'a': 649 650 /* Produce assembly code output file */ 651 652 Gbl_AsmOutputFlag = TRUE; 653 break; 654 655 case 'c': 656 657 /* Produce C hex output file */ 658 659 Gbl_C_OutputFlag = TRUE; 660 break; 661 662 case 'o': 663 664 /* Produce AML offset table in C */ 665 666 Gbl_C_OffsetTableFlag = TRUE; 667 break; 668 669 default: 670 671 printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); 672 return (-1); 673 } 674 break; 675 676 case 't': /* Produce hex table output file */ 677 678 switch (AcpiGbl_Optarg[0]) 679 { 680 case 'a': 681 682 Gbl_HexOutputFlag = HEX_OUTPUT_ASM; 683 break; 684 685 case 'c': 686 687 Gbl_HexOutputFlag = HEX_OUTPUT_C; 688 break; 689 690 case 's': 691 692 Gbl_HexOutputFlag = HEX_OUTPUT_ASL; 693 break; 694 695 default: 696 697 printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); 698 return (-1); 699 } 700 break; 701 702 case 'T': /* Create a ACPI table template file */ 703 704 Gbl_DoTemplates = TRUE; 705 break; 706 707 case 'v': /* Version and verbosity settings */ 708 709 switch (AcpiGbl_Optarg[0]) 710 { 711 case '^': 712 713 printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); 714 exit (0); 715 716 case 'a': 717 718 /* Disable all error/warning/remark messages */ 719 720 Gbl_NoErrors = TRUE; 721 break; 722 723 case 'd': 724 725 printf ("%s Build date/time: %s %s\n", 726 ASL_COMPILER_NAME, ASL_BUILD_DATE, ASL_BUILD_TIME); 727 exit (0); 728 729 case 'e': 730 731 /* Disable all warning/remark messages (errors only) */ 732 733 Gbl_DisplayRemarks = FALSE; 734 Gbl_DisplayWarnings = FALSE; 735 break; 736 737 case 'i': 738 /* 739 * Support for integrated development environment(s). 740 * 741 * 1) No compiler signon 742 * 2) Send stderr messages to stdout 743 * 3) Less verbose error messages (single line only for each) 744 * 4) Error/warning messages are formatted appropriately to 745 * be recognized by MS Visual Studio 746 */ 747 Gbl_VerboseErrors = FALSE; 748 Gbl_DoSignon = FALSE; 749 Gbl_Files[ASL_FILE_STDERR].Handle = stdout; 750 break; 751 752 case 'o': 753 754 Gbl_DisplayOptimizations = TRUE; 755 break; 756 757 case 'r': 758 759 Gbl_DisplayRemarks = FALSE; 760 break; 761 762 case 's': 763 764 Gbl_DoSignon = FALSE; 765 break; 766 767 case 't': 768 769 Gbl_VerboseTemplates = TRUE; 770 break; 771 772 case 'w': 773 774 /* Get the required argument */ 775 776 if (AcpiGetoptArgument (argc, argv)) 777 { 778 return (-1); 779 } 780 781 Status = AslDisableException (AcpiGbl_Optarg); 782 if (ACPI_FAILURE (Status)) 783 { 784 return (-1); 785 } 786 break; 787 788 default: 789 790 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 791 return (-1); 792 } 793 break; 794 795 case 'w': /* Set warning levels */ 796 797 switch (AcpiGbl_Optarg[0]) 798 { 799 case '1': 800 801 Gbl_WarningLevel = ASL_WARNING; 802 break; 803 804 case '2': 805 806 Gbl_WarningLevel = ASL_WARNING2; 807 break; 808 809 case '3': 810 811 Gbl_WarningLevel = ASL_WARNING3; 812 break; 813 814 case 'e': 815 816 Gbl_WarningsAsErrors = TRUE; 817 break; 818 819 default: 820 821 printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); 822 return (-1); 823 } 824 break; 825 826 case 'x': /* Set debug print output level */ 827 828 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); 829 break; 830 831 case 'z': 832 833 Gbl_UseOriginalCompilerId = TRUE; 834 break; 835 836 default: 837 838 return (-1); 839 } 840 841 return (0); 842 } 843 844 845 /******************************************************************************* 846 * 847 * FUNCTION: AslMergeOptionTokens 848 * 849 * PARAMETERS: InBuffer - Input containing an option string 850 * OutBuffer - Merged output buffer 851 * 852 * RETURN: None 853 * 854 * DESCRIPTION: Remove all whitespace from an option string. 855 * 856 ******************************************************************************/ 857 858 static void 859 AslMergeOptionTokens ( 860 char *InBuffer, 861 char *OutBuffer) 862 { 863 char *Token; 864 865 866 *OutBuffer = 0; 867 868 Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS); 869 while (Token) 870 { 871 strcat (OutBuffer, Token); 872 Token = strtok (NULL, ASL_TOKEN_SEPARATORS); 873 } 874 } 875 876 877 /******************************************************************************* 878 * 879 * FUNCTION: AslDoResponseFile 880 * 881 * PARAMETERS: Filename - Name of the response file 882 * 883 * RETURN: Status 884 * 885 * DESCRIPTION: Open a response file and process all options within. 886 * 887 ******************************************************************************/ 888 889 static int 890 AslDoResponseFile ( 891 char *Filename) 892 { 893 char *argv = StringBuffer2; 894 FILE *ResponseFile; 895 int OptStatus = 0; 896 int Opterr; 897 int Optind; 898 899 900 ResponseFile = fopen (Filename, "r"); 901 if (!ResponseFile) 902 { 903 printf ("Could not open command file %s, %s\n", 904 Filename, strerror (errno)); 905 return (-1); 906 } 907 908 /* Must save the current GetOpt globals */ 909 910 Opterr = AcpiGbl_Opterr; 911 Optind = AcpiGbl_Optind; 912 913 /* 914 * Process all lines in the response file. There must be one complete 915 * option per line 916 */ 917 while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile)) 918 { 919 /* Compress all tokens, allowing us to use a single argv entry */ 920 921 AslMergeOptionTokens (StringBuffer, StringBuffer2); 922 923 /* Process the option */ 924 925 AcpiGbl_Opterr = 0; 926 AcpiGbl_Optind = 0; 927 928 OptStatus = AslDoOptions (1, &argv, TRUE); 929 if (OptStatus) 930 { 931 printf ("Invalid option in command file %s: %s\n", 932 Filename, StringBuffer); 933 break; 934 } 935 } 936 937 /* Restore the GetOpt globals */ 938 939 AcpiGbl_Opterr = Opterr; 940 AcpiGbl_Optind = Optind; 941 942 fclose (ResponseFile); 943 return (OptStatus); 944 } 945