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