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 <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/include/acapps.h> 46 #include <contrib/dev/acpica/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 'd': 565 566 /* Disable disassembler code optimizations */ 567 568 AcpiGbl_DoDisassemblerOptimizations = FALSE; 569 break; 570 571 case 'e': 572 573 /* iASL: Disable External opcode generation */ 574 575 Gbl_DoExternals = FALSE; 576 577 /* Disassembler: Emit embedded external operators */ 578 579 AcpiGbl_DmEmitExternalOpcodes = TRUE; 580 break; 581 582 case 'f': 583 584 /* Disable folding on "normal" expressions */ 585 586 Gbl_FoldConstants = FALSE; 587 break; 588 589 case 'i': 590 591 /* Disable integer optimization to constants */ 592 593 Gbl_IntegerOptimizationFlag = FALSE; 594 break; 595 596 case 'n': 597 598 /* Disable named reference optimization */ 599 600 Gbl_ReferenceOptimizationFlag = FALSE; 601 break; 602 603 case 't': 604 605 /* Disable heavy typechecking */ 606 607 Gbl_DoTypechecking = FALSE; 608 break; 609 610 default: 611 612 printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); 613 return (-1); 614 } 615 break; 616 617 case 'P': /* Preprocessor options */ 618 619 switch (AcpiGbl_Optarg[0]) 620 { 621 case '^': /* Proprocess only, emit (.i) file */ 622 623 Gbl_PreprocessOnly = TRUE; 624 Gbl_PreprocessorOutputFlag = TRUE; 625 break; 626 627 case 'n': /* Disable preprocessor */ 628 629 Gbl_PreprocessFlag = FALSE; 630 break; 631 632 default: 633 634 printf ("Unknown option: -P%s\n", AcpiGbl_Optarg); 635 return (-1); 636 } 637 break; 638 639 case 'p': /* Override default AML output filename */ 640 641 Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; 642 UtConvertBackslashes (Gbl_OutputFilenamePrefix); 643 Gbl_UseDefaultAmlFilename = FALSE; 644 break; 645 646 case 'r': /* Override revision found in table header */ 647 648 Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 649 break; 650 651 case 's': /* Create AML in a source code file */ 652 653 switch (AcpiGbl_Optarg[0]) 654 { 655 case 'a': 656 657 /* Produce assembly code output file */ 658 659 Gbl_AsmOutputFlag = TRUE; 660 break; 661 662 case 'c': 663 664 /* Produce C hex output file */ 665 666 Gbl_C_OutputFlag = TRUE; 667 break; 668 669 case 'o': 670 671 /* Produce AML offset table in C */ 672 673 Gbl_C_OffsetTableFlag = TRUE; 674 break; 675 676 default: 677 678 printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); 679 return (-1); 680 } 681 break; 682 683 case 't': /* Produce hex table output file */ 684 685 switch (AcpiGbl_Optarg[0]) 686 { 687 case 'a': 688 689 Gbl_HexOutputFlag = HEX_OUTPUT_ASM; 690 break; 691 692 case 'c': 693 694 Gbl_HexOutputFlag = HEX_OUTPUT_C; 695 break; 696 697 case 's': 698 699 Gbl_HexOutputFlag = HEX_OUTPUT_ASL; 700 break; 701 702 default: 703 704 printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); 705 return (-1); 706 } 707 break; 708 709 case 'T': /* Create a ACPI table template file */ 710 711 Gbl_DoTemplates = TRUE; 712 break; 713 714 case 'v': /* Version and verbosity settings */ 715 716 switch (AcpiGbl_Optarg[0]) 717 { 718 case '^': 719 720 printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); 721 exit (0); 722 723 case 'a': 724 725 /* Disable all error/warning/remark messages */ 726 727 Gbl_NoErrors = TRUE; 728 break; 729 730 case 'd': 731 732 printf ("%s Build date/time: %s %s\n", 733 ASL_COMPILER_NAME, ASL_BUILD_DATE, ASL_BUILD_TIME); 734 exit (0); 735 736 case 'e': 737 738 /* Disable all warning/remark messages (errors only) */ 739 740 Gbl_DisplayRemarks = FALSE; 741 Gbl_DisplayWarnings = FALSE; 742 break; 743 744 case 'i': 745 /* 746 * Support for integrated development environment(s). 747 * 748 * 1) No compiler signon 749 * 2) Send stderr messages to stdout 750 * 3) Less verbose error messages (single line only for each) 751 * 4) Error/warning messages are formatted appropriately to 752 * be recognized by MS Visual Studio 753 */ 754 Gbl_VerboseErrors = FALSE; 755 Gbl_DoSignon = FALSE; 756 Gbl_Files[ASL_FILE_STDERR].Handle = stdout; 757 break; 758 759 case 'o': 760 761 Gbl_DisplayOptimizations = TRUE; 762 break; 763 764 case 'r': 765 766 Gbl_DisplayRemarks = FALSE; 767 break; 768 769 case 's': 770 771 Gbl_DoSignon = FALSE; 772 break; 773 774 case 't': 775 776 Gbl_VerboseTemplates = TRUE; 777 break; 778 779 case 'w': 780 781 /* Get the required argument */ 782 783 if (AcpiGetoptArgument (argc, argv)) 784 { 785 return (-1); 786 } 787 788 Status = AslDisableException (AcpiGbl_Optarg); 789 if (ACPI_FAILURE (Status)) 790 { 791 return (-1); 792 } 793 break; 794 795 default: 796 797 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 798 return (-1); 799 } 800 break; 801 802 case 'w': /* Set warning levels */ 803 804 switch (AcpiGbl_Optarg[0]) 805 { 806 case '1': 807 808 Gbl_WarningLevel = ASL_WARNING; 809 break; 810 811 case '2': 812 813 Gbl_WarningLevel = ASL_WARNING2; 814 break; 815 816 case '3': 817 818 Gbl_WarningLevel = ASL_WARNING3; 819 break; 820 821 case 'e': 822 823 Gbl_WarningsAsErrors = TRUE; 824 break; 825 826 default: 827 828 printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); 829 return (-1); 830 } 831 break; 832 833 case 'x': /* Set debug print output level */ 834 835 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); 836 break; 837 838 case 'z': 839 840 Gbl_UseOriginalCompilerId = TRUE; 841 break; 842 843 default: 844 845 return (-1); 846 } 847 848 return (0); 849 } 850 851 852 /******************************************************************************* 853 * 854 * FUNCTION: AslMergeOptionTokens 855 * 856 * PARAMETERS: InBuffer - Input containing an option string 857 * OutBuffer - Merged output buffer 858 * 859 * RETURN: None 860 * 861 * DESCRIPTION: Remove all whitespace from an option string. 862 * 863 ******************************************************************************/ 864 865 static void 866 AslMergeOptionTokens ( 867 char *InBuffer, 868 char *OutBuffer) 869 { 870 char *Token; 871 872 873 *OutBuffer = 0; 874 875 Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS); 876 while (Token) 877 { 878 strcat (OutBuffer, Token); 879 Token = strtok (NULL, ASL_TOKEN_SEPARATORS); 880 } 881 } 882 883 884 /******************************************************************************* 885 * 886 * FUNCTION: AslDoResponseFile 887 * 888 * PARAMETERS: Filename - Name of the response file 889 * 890 * RETURN: Status 891 * 892 * DESCRIPTION: Open a response file and process all options within. 893 * 894 ******************************************************************************/ 895 896 static int 897 AslDoResponseFile ( 898 char *Filename) 899 { 900 char *argv = StringBuffer2; 901 FILE *ResponseFile; 902 int OptStatus = 0; 903 int Opterr; 904 int Optind; 905 906 907 ResponseFile = fopen (Filename, "r"); 908 if (!ResponseFile) 909 { 910 printf ("Could not open command file %s, %s\n", 911 Filename, strerror (errno)); 912 return (-1); 913 } 914 915 /* Must save the current GetOpt globals */ 916 917 Opterr = AcpiGbl_Opterr; 918 Optind = AcpiGbl_Optind; 919 920 /* 921 * Process all lines in the response file. There must be one complete 922 * option per line 923 */ 924 while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile)) 925 { 926 /* Compress all tokens, allowing us to use a single argv entry */ 927 928 AslMergeOptionTokens (StringBuffer, StringBuffer2); 929 930 /* Process the option */ 931 932 AcpiGbl_Opterr = 0; 933 AcpiGbl_Optind = 0; 934 935 OptStatus = AslDoOptions (1, &argv, TRUE); 936 if (OptStatus) 937 { 938 printf ("Invalid option in command file %s: %s\n", 939 Filename, StringBuffer); 940 break; 941 } 942 } 943 944 /* Restore the GetOpt globals */ 945 946 AcpiGbl_Opterr = Opterr; 947 AcpiGbl_Optind = Optind; 948 949 fclose (ResponseFile); 950 return (OptStatus); 951 } 952