1/****************************************************************************** 2 * 3 * Module Name: aslstartup - Compiler startup routines, called from main 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/actables.h> 46#include <contrib/dev/acpica/include/acdisasm.h> 47#include <contrib/dev/acpica/include/acapps.h> 48 49#define _COMPONENT ACPI_COMPILER 50 ACPI_MODULE_NAME ("aslstartup") 51 52 53/* Local prototypes */ 54 55static UINT8 56AslDetectSourceFileType ( 57 ASL_FILE_INFO *Info); 58 59static ACPI_STATUS 60AslDoDisassembly ( 61 void); 62 63 64/* Globals */ 65 66static BOOLEAN AslToFile = TRUE; 67 68 69/******************************************************************************* 70 * 71 * FUNCTION: AslInitializeGlobals 72 * 73 * PARAMETERS: None 74 * 75 * RETURN: None 76 * 77 * DESCRIPTION: Re-initialize globals needed to restart the compiler. This 78 * allows multiple files to be disassembled and/or compiled. 79 * 80 ******************************************************************************/ 81 82void 83AslInitializeGlobals ( 84 void) 85{ 86 UINT32 i; 87 88 89 /* Init compiler globals */ 90 91 Gbl_SyntaxError = 0; 92 Gbl_CurrentColumn = 0; 93 Gbl_CurrentLineNumber = 1; 94 Gbl_LogicalLineNumber = 1; 95 Gbl_CurrentLineOffset = 0; 96 Gbl_InputFieldCount = 0; 97 Gbl_InputByteCount = 0; 98 Gbl_NsLookupCount = 0; 99 Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 100 101 Gbl_ErrorLog = NULL; 102 Gbl_NextError = NULL; 103 Gbl_Signature = NULL; 104 Gbl_FileType = 0; 105 106 TotalExecutableOpcodes = 0; 107 TotalNamedObjects = 0; 108 TotalKeywords = 0; 109 TotalParseNodes = 0; 110 TotalMethods = 0; 111 TotalAllocations = 0; 112 TotalAllocated = 0; 113 TotalFolds = 0; 114 115 AslGbl_NextEvent = 0; 116 for (i = 0; i < ASL_NUM_REPORT_LEVELS; i++) 117 { 118 Gbl_ExceptionCount[i] = 0; 119 } 120 121 for (i = ASL_FILE_INPUT; i <= ASL_MAX_FILE_TYPE; i++) 122 { 123 Gbl_Files[i].Handle = NULL; 124 Gbl_Files[i].Filename = NULL; 125 } 126} 127 128 129/******************************************************************************* 130 * 131 * FUNCTION: AslDetectSourceFileType 132 * 133 * PARAMETERS: Info - Name/Handle for the file (must be open) 134 * 135 * RETURN: File Type 136 * 137 * DESCRIPTION: Determine the type of the input file. Either binary (contains 138 * non-ASCII characters), ASL file, or an ACPI Data Table file. 139 * 140 ******************************************************************************/ 141 142static UINT8 143AslDetectSourceFileType ( 144 ASL_FILE_INFO *Info) 145{ 146 char *FileChar; 147 UINT8 Type = ASL_INPUT_TYPE_ASCII_DATA; /* default */ 148 ACPI_STATUS Status; 149 150 151 /* Check for 100% ASCII source file (comments are ignored) */ 152 153 Status = FlIsFileAsciiSource (Info->Filename, FALSE); 154 if (ACPI_SUCCESS (Status)) 155 { 156 /* 157 * File contains ASCII source code. Determine if this is an ASL 158 * file or an ACPI data table file. 159 */ 160 while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle)) 161 { 162 /* Uppercase the buffer for caseless compare */ 163 164 FileChar = Gbl_CurrentLineBuffer; 165 while (*FileChar) 166 { 167 *FileChar = (char) toupper ((int) *FileChar); 168 FileChar++; 169 } 170 171 /* Presence of "DefinitionBlock" indicates actual ASL code */ 172 173 if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK")) 174 { 175 /* Appears to be an ASL file */ 176 177 Type = ASL_INPUT_TYPE_ASCII_ASL; 178 goto Cleanup; 179 } 180 } 181 182 /* Appears to be an ASCII data table source file */ 183 184 Type = ASL_INPUT_TYPE_ASCII_DATA; 185 goto Cleanup; 186 } 187 188 /* We have some sort of binary table, check for valid ACPI table */ 189 190 fseek (Info->Handle, 0, SEEK_SET); 191 192 Status = AcValidateTableHeader (Info->Handle, 0); 193 if (ACPI_SUCCESS (Status)) 194 { 195 fprintf (stderr, 196 "Binary file appears to be a valid ACPI table, disassembling\n"); 197 198 Type = ASL_INPUT_TYPE_BINARY_ACPI_TABLE; 199 goto Cleanup; 200 } 201 202 Type = ASL_INPUT_TYPE_BINARY; 203 204 205Cleanup: 206 207 /* Must seek back to the start of the file */ 208 209 fseek (Info->Handle, 0, SEEK_SET); 210 return (Type); 211} 212 213 214/******************************************************************************* 215 * 216 * FUNCTION: AslDoDisassembly 217 * 218 * PARAMETERS: None 219 * 220 * RETURN: Status 221 * 222 * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build 223 * namespace. 224 * 225 ******************************************************************************/ 226 227static ACPI_STATUS 228AslDoDisassembly ( 229 void) 230{ 231 ACPI_STATUS Status; 232 233 234 /* ACPICA subsystem initialization */ 235 236 Status = AdInitialize (); 237 if (ACPI_FAILURE (Status)) 238 { 239 return (Status); 240 } 241 242 Status = AcpiAllocateRootTable (4); 243 if (ACPI_FAILURE (Status)) 244 { 245 AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n", 246 AcpiFormatException (Status)); 247 return (Status); 248 } 249 250 /* Handle additional output files for disassembler */ 251 252 Gbl_FileType = ASL_INPUT_TYPE_BINARY_ACPI_TABLE; 253 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 254 255 /* This is where the disassembly happens */ 256 257 AcpiGbl_DmOpt_Disasm = TRUE; 258 Status = AdAmlDisassemble (AslToFile, 259 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_OutputFilenamePrefix, 260 &Gbl_Files[ASL_FILE_INPUT].Filename); 261 if (ACPI_FAILURE (Status)) 262 { 263 return (Status); 264 } 265 266 /* Check if any control methods were unresolved */ 267 268 AcpiDmUnresolvedWarning (0); 269 270 /* Shutdown compiler and ACPICA subsystem */ 271 272 AeClearErrorLog (); 273 (void) AcpiTerminate (); 274 275 /* 276 * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the 277 * .DSL disassembly file, which can now be compiled if requested 278 */ 279 if (Gbl_DoCompile) 280 { 281 AcpiOsPrintf ("\nCompiling \"%s\"\n", 282 Gbl_Files[ASL_FILE_INPUT].Filename); 283 return (AE_CTRL_CONTINUE); 284 } 285 286 /* No need to free the filename string */ 287 288 Gbl_Files[ASL_FILE_INPUT].Filename = NULL; 289 290 CmDeleteCaches (); 291 return (AE_OK); 292} 293 294 295/******************************************************************************* 296 * 297 * FUNCTION: AslDoOneFile 298 * 299 * PARAMETERS: Filename - Name of the file 300 * 301 * RETURN: Status 302 * 303 * DESCRIPTION: Process a single file - either disassemble, compile, or both 304 * 305 ******************************************************************************/ 306 307ACPI_STATUS 308AslDoOneFile ( 309 char *Filename) 310{ 311 ACPI_STATUS Status; 312 313 314 /* Re-initialize "some" compiler/preprocessor globals */ 315 316 AslInitializeGlobals (); 317 PrInitializeGlobals (); 318 319 /* 320 * Extract the directory path. This path is used for possible include 321 * files and the optional AML filename embedded in the input file 322 * DefinitionBlock declaration. 323 */ 324 Status = FlSplitInputPathname (Filename, &Gbl_DirectoryPath, NULL); 325 if (ACPI_FAILURE (Status)) 326 { 327 return (Status); 328 } 329 330 /* Take a copy of the input filename, convert any backslashes */ 331 332 Gbl_Files[ASL_FILE_INPUT].Filename = 333 UtStringCacheCalloc (strlen (Filename) + 1); 334 335 strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); 336 UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename); 337 338 /* 339 * AML Disassembly (Optional) 340 */ 341 if (Gbl_DisasmFlag) 342 { 343 Status = AslDoDisassembly (); 344 if (Status != AE_CTRL_CONTINUE) 345 { 346 return (Status); 347 } 348 } 349 350 /* 351 * Open the input file. Here, this should be an ASCII source file, 352 * either an ASL file or a Data Table file 353 */ 354 Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename); 355 if (ACPI_FAILURE (Status)) 356 { 357 AePrintErrorLog (ASL_FILE_STDERR); 358 return (AE_ERROR); 359 } 360 361 Gbl_OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT); 362 363 /* Determine input file type */ 364 365 Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]); 366 if (Gbl_FileType == ASL_INPUT_TYPE_BINARY) 367 { 368 return (AE_ERROR); 369 } 370 371 /* 372 * If -p not specified, we will use the input filename as the 373 * output filename prefix 374 */ 375 if (Gbl_UseDefaultAmlFilename) 376 { 377 Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename; 378 } 379 380 /* Open the optional output files (listings, etc.) */ 381 382 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 383 if (ACPI_FAILURE (Status)) 384 { 385 AePrintErrorLog (ASL_FILE_STDERR); 386 return (AE_ERROR); 387 } 388 389 /* 390 * Compilation of ASL source versus DataTable source uses different 391 * compiler subsystems 392 */ 393 switch (Gbl_FileType) 394 { 395 /* 396 * Data Table Compilation 397 */ 398 case ASL_INPUT_TYPE_ASCII_DATA: 399 400 Status = DtDoCompile (); 401 if (ACPI_FAILURE (Status)) 402 { 403 return (Status); 404 } 405 406 if (Gbl_Signature) 407 { 408 Gbl_Signature = NULL; 409 } 410 411 /* Check if any errors occurred during compile */ 412 413 Status = AslCheckForErrorExit (); 414 if (ACPI_FAILURE (Status)) 415 { 416 return (Status); 417 } 418 419 /* Cleanup (for next source file) and exit */ 420 421 AeClearErrorLog (); 422 PrTerminatePreprocessor (); 423 return (Status); 424 425 /* 426 * ASL Compilation 427 */ 428 case ASL_INPUT_TYPE_ASCII_ASL: 429 430 /* ACPICA subsystem initialization */ 431 432 Status = AdInitialize (); 433 if (ACPI_FAILURE (Status)) 434 { 435 return (Status); 436 } 437 438 (void) CmDoCompile (); 439 (void) AcpiTerminate (); 440 441 /* Check if any errors occurred during compile */ 442 443 Status = AslCheckForErrorExit (); 444 if (ACPI_FAILURE (Status)) 445 { 446 return (Status); 447 } 448 449 /* Cleanup (for next source file) and exit */ 450 451 AeClearErrorLog (); 452 PrTerminatePreprocessor (); 453 return (AE_OK); 454 455 /* 456 * Binary ACPI table was auto-detected, disassemble it 457 */ 458 case ASL_INPUT_TYPE_BINARY_ACPI_TABLE: 459 460 /* We have what appears to be an ACPI table, disassemble it */ 461 462 FlCloseFile (ASL_FILE_INPUT); 463 Gbl_DoCompile = FALSE; 464 Gbl_DisasmFlag = TRUE; 465 Status = AslDoDisassembly (); 466 return (Status); 467 468 /* Unknown binary table */ 469 470 case ASL_INPUT_TYPE_BINARY: 471 472 AePrintErrorLog (ASL_FILE_STDERR); 473 return (AE_ERROR); 474 475 default: 476 477 printf ("Unknown file type %X\n", Gbl_FileType); 478 return (AE_ERROR); 479 } 480} 481 482 483/******************************************************************************* 484 * 485 * FUNCTION: AslCheckForErrorExit 486 * 487 * PARAMETERS: None. Examines global exception count array 488 * 489 * RETURN: Status 490 * 491 * DESCRIPTION: Determine if compiler should abort with error status 492 * 493 ******************************************************************************/ 494 495ACPI_STATUS 496AslCheckForErrorExit ( 497 void) 498{ 499 500 /* 501 * Return non-zero exit code if there have been errors, unless the 502 * global ignore error flag has been set 503 */ 504 if (!Gbl_IgnoreErrors) 505 { 506 if (Gbl_ExceptionCount[ASL_ERROR] > 0) 507 { 508 return (AE_ERROR); 509 } 510 511 /* Optionally treat warnings as errors */ 512 513 if (Gbl_WarningsAsErrors) 514 { 515 if ((Gbl_ExceptionCount[ASL_WARNING] > 0) || 516 (Gbl_ExceptionCount[ASL_WARNING2] > 0) || 517 (Gbl_ExceptionCount[ASL_WARNING3] > 0)) 518 { 519 return (AE_ERROR); 520 } 521 } 522 } 523 524 return (AE_OK); 525} 526