/****************************************************************************** * * Module Name: aslmain - compiler main and utilities * *****************************************************************************/ /* * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ #define _DECLARE_GLOBALS #include "aslcompiler.h" #include "acapps.h" #include "acdisasm.h" #ifdef _DEBUG #include #endif #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("aslmain") /* Local prototypes */ static void Options ( void); static void HelpMessage ( void); static void Usage ( void); static void AslInitialize ( void); static int AslCommandLine ( int argc, char **argv); static int AslDoOptions ( int argc, char **argv, BOOLEAN IsResponseFile); static void AslMergeOptionTokens ( char *InBuffer, char *OutBuffer); static int AslDoResponseFile ( char *Filename); #define ASL_TOKEN_SEPARATORS " \t\n" #define ASL_SUPPORTED_OPTIONS "@:2b:c:d^e:fgh^i^I:l^no:p:r:s:t:T:v:w:x:z" /******************************************************************************* * * FUNCTION: Options * * PARAMETERS: None * * RETURN: None * * DESCRIPTION: Display option help message * ******************************************************************************/ static void Options ( void) { printf ("Global:\n"); printf (" -@ Specify command file\n"); printf (" -I Specify additional include directory\n"); printf ("\nGeneral Output:\n"); printf (" -p Specify path/filename prefix for all output files\n"); printf (" -va Disable all errors and warnings (summary only)\n"); printf (" -vi Less verbose errors and warnings for use with IDEs\n"); printf (" -vo Enable optimization comments\n"); printf (" -vr Disable remarks\n"); printf (" -vs Disable signon\n"); printf (" -w<1|2|3> Set warning reporting level\n"); printf ("\nAML Output Files:\n"); printf (" -s Create AML in assembler or C source file (*.asm or *.c)\n"); printf (" -i Create assembler or C include file (*.inc or *.h)\n"); printf (" -t Create AML in assembler, C, or ASL hex table (*.hex)\n"); printf ("\nAML Code Generation:\n"); printf (" -oa Disable all optimizations (compatibility mode)\n"); printf (" -of Disable constant folding\n"); printf (" -oi Disable integer optimization to Zero/One/Ones\n"); printf (" -on Disable named reference string optimization\n"); printf (" -cr Disable Resource Descriptor error checking\n"); printf (" -r Override table header Revision (1-255)\n"); printf ("\nASL Listing Files:\n"); printf (" -l Create mixed listing file (ASL source and AML) (*.lst)\n"); printf (" -ln Create namespace file (*.nsp)\n"); printf (" -ls Create combined source file (expanded includes) (*.src)\n"); printf ("\nACPI Data Tables:\n"); printf (" -T Create table template file for (or \"ALL\")\n"); printf (" -vt Create verbose templates (full disassembly)\n"); printf ("\nAML Disassembler:\n"); printf (" -d [file] Disassemble or decode binary ACPI table to file (*.dsl)\n"); printf (" -da [f1,f2] Disassemble multiple tables from single namespace\n"); printf (" -dc [file] Disassemble AML and immediately compile it\n"); printf (" (Obtain DSDT from current system if no input file)\n"); printf (" -e [f1,f2] Include ACPI table(s) for external symbol resolution\n"); printf (" -2 Emit ACPI 2.0 compatible ASL code\n"); printf (" -g Get ACPI tables and write to files (*.dat)\n"); printf ("\nHelp:\n"); printf (" -h Additional help and compiler debug options\n"); printf (" -hc Display operators allowed in constant expressions\n"); printf (" -hr Display ACPI reserved method names\n"); printf (" -ht Display currently supported ACPI table names\n"); } /******************************************************************************* * * FUNCTION: HelpMessage * * PARAMETERS: None * * RETURN: None * * DESCRIPTION: Display help message * ******************************************************************************/ static void HelpMessage ( void) { printf ("AML output filename generation:\n"); printf (" Output filenames are generated by appending an extension to a common\n"); printf (" filename prefix. The filename prefix is obtained via one of the\n"); printf (" following methods (in priority order):\n"); printf (" 1) The -p option specifies the prefix\n"); printf (" 2) The prefix of the AMLFileName in the ASL Definition Block\n"); printf (" 3) The prefix of the input filename\n"); printf ("\n"); Options (); printf ("\nCompiler/Disassembler Debug Options:\n"); printf (" -b Create compiler debug/trace file (*.txt)\n"); printf (" Types: Parse/Tree/Both\n"); printf (" -f Ignore errors, force creation of AML output file(s)\n"); printf (" -n Parse only, no output generation\n"); printf (" -ot Display compile times\n"); printf (" -x Set debug level for trace output\n"); printf (" -z Do not insert new compiler ID for DataTables\n"); } /******************************************************************************* * * FUNCTION: Usage * * PARAMETERS: None * * RETURN: None * * DESCRIPTION: Display usage and option message * ******************************************************************************/ static void Usage ( void) { printf ("%s\n", ASL_COMPLIANCE); printf ("Usage: %s [Options] [Files]\n\n", ASL_INVOCATION_NAME); Options (); } /******************************************************************************* * * FUNCTION: AslInitialize * * PARAMETERS: None * * RETURN: None * * DESCRIPTION: Initialize compiler globals * ******************************************************************************/ static void AslInitialize ( void) { UINT32 i; #ifdef _DEBUG _CrtSetDbgFlag (_CRTDBG_CHECK_ALWAYS_DF | _CrtSetDbgFlag(0)); #endif AcpiDbgLevel = 0; for (i = 0; i < ASL_NUM_FILES; i++) { Gbl_Files[i].Handle = NULL; Gbl_Files[i].Filename = NULL; } Gbl_Files[ASL_FILE_STDOUT].Handle = stdout; Gbl_Files[ASL_FILE_STDOUT].Filename = "STDOUT"; Gbl_Files[ASL_FILE_STDERR].Handle = stderr; Gbl_Files[ASL_FILE_STDERR].Filename = "STDERR"; } /******************************************************************************* * * FUNCTION: AslMergeOptionTokens * * PARAMETERS: InBuffer - Input containing an option string * OutBuffer - Merged output buffer * * RETURN: None * * DESCRIPTION: Remove all whitespace from an option string. * ******************************************************************************/ static void AslMergeOptionTokens ( char *InBuffer, char *OutBuffer) { char *Token; *OutBuffer = 0; Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS); while (Token) { strcat (OutBuffer, Token); Token = strtok (NULL, ASL_TOKEN_SEPARATORS); } } /******************************************************************************* * * FUNCTION: AslDoResponseFile * * PARAMETERS: Filename - Name of the response file * * RETURN: Status * * DESCRIPTION: Open a response file and process all options within. * ******************************************************************************/ static int AslDoResponseFile ( char *Filename) { char *argv = StringBuffer2; FILE *ResponseFile; int OptStatus = 0; int Opterr; int Optind; ResponseFile = fopen (Filename, "r"); if (!ResponseFile) { printf ("Could not open command file %s, %s\n", Filename, strerror (errno)); return -1; } /* Must save the current GetOpt globals */ Opterr = AcpiGbl_Opterr; Optind = AcpiGbl_Optind; /* * Process all lines in the response file. There must be one complete * option per line */ while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile)) { /* Compress all tokens, allowing us to use a single argv entry */ AslMergeOptionTokens (StringBuffer, StringBuffer2); /* Process the option */ AcpiGbl_Opterr = 0; AcpiGbl_Optind = 0; OptStatus = AslDoOptions (1, &argv, TRUE); if (OptStatus) { printf ("Invalid option in command file %s: %s\n", Filename, StringBuffer); break; } } /* Restore the GetOpt globals */ AcpiGbl_Opterr = Opterr; AcpiGbl_Optind = Optind; fclose (ResponseFile); return (OptStatus); } /******************************************************************************* * * FUNCTION: AslDoOptions * * PARAMETERS: argc/argv - Standard argc/argv * IsResponseFile - TRUE if executing a response file. * * RETURN: Status * * DESCRIPTION: Command line option processing * ******************************************************************************/ static int AslDoOptions ( int argc, char **argv, BOOLEAN IsResponseFile) { int j; ACPI_STATUS Status; /* Get the command line options */ while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != EOF) switch (j) { case '@': /* Begin a response file */ if (IsResponseFile) { printf ("Nested command files are not supported\n"); return -1; } if (AslDoResponseFile (AcpiGbl_Optarg)) { return -1; } break; case '2': Gbl_Acpi2 = TRUE; break; case 'b': switch (AcpiGbl_Optarg[0]) { case 'b': AslCompilerdebug = 1; /* same as yydebug */ break; case 'p': AslCompilerdebug = 1; /* same as yydebug */ break; case 't': break; default: printf ("Unknown option: -b%s\n", AcpiGbl_Optarg); return (-1); } /* Produce debug output file */ Gbl_DebugFlag = TRUE; break; case 'c': switch (AcpiGbl_Optarg[0]) { case 'r': Gbl_NoResourceChecking = TRUE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'd': switch (AcpiGbl_Optarg[0]) { case '^': Gbl_DoCompile = FALSE; break; case 'a': Gbl_DoCompile = FALSE; Gbl_DisassembleAll = TRUE; break; case 'c': break; default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); return (-1); } Gbl_DisasmFlag = TRUE; break; case 'e': Status = AcpiDmAddToExternalFileList (AcpiGbl_Optarg); if (ACPI_FAILURE (Status)) { printf ("Could not add %s to external list\n", AcpiGbl_Optarg); return (-1); } break; case 'f': /* Ignore errors and force creation of aml file */ Gbl_IgnoreErrors = TRUE; break; case 'g': /* Get all ACPI tables */ Gbl_GetAllTables = TRUE; Gbl_DoCompile = FALSE; break; case 'h': switch (AcpiGbl_Optarg[0]) { case '^': HelpMessage (); exit (0); case 'c': UtDisplayConstantOpcodes (); exit (0); case 'r': /* reserved names */ ApDisplayReservedNames (); exit (0); case 't': UtDisplaySupportedTables (); exit (0); default: printf ("Unknown option: -h%s\n", AcpiGbl_Optarg); return (-1); } case 'I': /* Add an include file search directory */ FlAddIncludeDirectory (AcpiGbl_Optarg); break; case 'i': switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code include file */ Gbl_AsmIncludeOutputFlag = TRUE; break; case 'c': /* Produce C include file */ Gbl_C_IncludeOutputFlag = TRUE; break; default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); return (-1); } break; case 'l': switch (AcpiGbl_Optarg[0]) { case '^': /* Produce listing file (Mixed source/aml) */ Gbl_ListingFlag = TRUE; break; case 'n': /* Produce namespace file */ Gbl_NsOutputFlag = TRUE; break; case 's': /* Produce combined source file */ Gbl_SourceOutputFlag = TRUE; break; default: printf ("Unknown option: -l%s\n", AcpiGbl_Optarg); return (-1); } break; case 'o': switch (AcpiGbl_Optarg[0]) { case 'a': /* Disable all optimizations */ Gbl_FoldConstants = FALSE; Gbl_IntegerOptimizationFlag = FALSE; Gbl_ReferenceOptimizationFlag = FALSE; break; case 'f': /* Disable folding on "normal" expressions */ Gbl_FoldConstants = FALSE; break; case 'i': /* Disable integer optimization to constants */ Gbl_IntegerOptimizationFlag = FALSE; break; case 'n': /* Disable named reference optimization */ Gbl_ReferenceOptimizationFlag = FALSE; break; case 't': /* Display compile time(s) */ Gbl_CompileTimesFlag = TRUE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'n': /* Parse only */ Gbl_ParseOnlyFlag = TRUE; break; case 'p': /* Override default AML output filename */ Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; Gbl_UseDefaultAmlFilename = FALSE; break; case 'r': Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; case 's': switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code output file */ Gbl_AsmOutputFlag = TRUE; break; case 'c': /* Produce C hex output file */ Gbl_C_OutputFlag = TRUE; break; default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); return (-1); } break; case 't': /* Produce hex table output file */ switch (AcpiGbl_Optarg[0]) { case 'a': Gbl_HexOutputFlag = HEX_OUTPUT_ASM; break; case 'c': Gbl_HexOutputFlag = HEX_OUTPUT_C; break; case 's': Gbl_HexOutputFlag = HEX_OUTPUT_ASL; break; default: printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); return (-1); } break; case 'T': Gbl_DoTemplates = TRUE; Gbl_TemplateSignature = AcpiGbl_Optarg; break; case 'v': switch (AcpiGbl_Optarg[0]) { case 'a': /* Disable All error/warning messages */ Gbl_NoErrors = TRUE; break; case 'i': /* Less verbose error messages */ Gbl_VerboseErrors = FALSE; break; case 'o': Gbl_DisplayOptimizations = TRUE; break; case 'r': Gbl_DisplayRemarks = FALSE; break; case 's': Gbl_DoSignon = FALSE; break; case 't': Gbl_VerboseTemplates = TRUE; break; default: printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); return (-1); } break; case 'w': /* Set warning levels */ switch (AcpiGbl_Optarg[0]) { case '1': Gbl_WarningLevel = ASL_WARNING; break; case '2': Gbl_WarningLevel = ASL_WARNING2; break; case '3': Gbl_WarningLevel = ASL_WARNING3; break; default: printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); return (-1); } break; case 'x': AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); break; case 'z': Gbl_UseOriginalCompilerId = TRUE; break; default: return (-1); } return (0); } /******************************************************************************* * * FUNCTION: AslCommandLine * * PARAMETERS: argc/argv * * RETURN: Last argv index * * DESCRIPTION: Command line processing * ******************************************************************************/ static int AslCommandLine ( int argc, char **argv) { int BadCommandLine = 0; ACPI_STATUS Status; /* Minimum command line contains at least the command and an input file */ if (argc < 2) { printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); Usage (); exit (1); } /* Process all command line options */ BadCommandLine = AslDoOptions (argc, argv, FALSE); if (Gbl_DoTemplates) { Status = DtCreateTemplates (Gbl_TemplateSignature); if (ACPI_FAILURE (Status)) { exit (-1); } exit (1); } /* Next parameter must be the input filename */ if (!argv[AcpiGbl_Optind] && !Gbl_DisasmFlag && !Gbl_GetAllTables) { printf ("Missing input filename\n"); BadCommandLine = TRUE; } if (Gbl_DoSignon) { printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); } /* Abort if anything went wrong on the command line */ if (BadCommandLine) { printf ("\n"); Usage (); exit (1); } return (AcpiGbl_Optind); } /******************************************************************************* * * FUNCTION: main * * PARAMETERS: Standard argc/argv * * RETURN: Program termination code * * DESCRIPTION: C main routine for the Asl Compiler. Handle command line * options and begin the compile for each file on the command line * ******************************************************************************/ int ACPI_SYSTEM_XFACE main ( int argc, char **argv) { ACPI_STATUS Status; int Index1; int Index2; AcpiGbl_ExternalFileList = NULL; #ifdef _DEBUG _CrtSetDbgFlag (_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); #endif /* Init and command line */ AslInitialize (); Index1 = Index2 = AslCommandLine (argc, argv); /* Options that have no additional parameters or pathnames */ if (Gbl_GetAllTables) { Status = AslDoOneFile (NULL); if (ACPI_FAILURE (Status)) { return (-1); } return (0); } if (Gbl_DisassembleAll) { while (argv[Index1]) { Status = AslDoOnePathname (argv[Index1], AcpiDmAddToExternalFileList); if (ACPI_FAILURE (Status)) { return (-1); } Index1++; } } /* Process each pathname/filename in the list, with possible wildcards */ while (argv[Index2]) { Status = AslDoOnePathname (argv[Index2], AslDoOneFile); if (ACPI_FAILURE (Status)) { return (-1); } Index2++; } if (AcpiGbl_ExternalFileList) { AcpiDmClearExternalFileList(); } return (0); }