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