1 /****************************************************************************** 2 * 3 * Module Name: aslstartup - Compiler startup routines, called from main 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 "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 (Gbl_CaptureComments) 129 { 130 Gbl_CommentState.SpacesBefore = 0; 131 Gbl_CommentState.CommentType = 1; 132 Gbl_CommentState.Latest_Parse_Node = 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 212 Type = ASL_INPUT_TYPE_BINARY; 213 214 215 Cleanup: 216 217 /* Must seek back to the start of the file */ 218 219 fseek (Info->Handle, 0, SEEK_SET); 220 return (Type); 221 } 222 223 224 /******************************************************************************* 225 * 226 * FUNCTION: AslDoDisassembly 227 * 228 * PARAMETERS: None 229 * 230 * RETURN: Status 231 * 232 * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build 233 * namespace. 234 * 235 ******************************************************************************/ 236 237 static ACPI_STATUS 238 AslDoDisassembly ( 239 void) 240 { 241 ACPI_STATUS Status; 242 243 244 /* ACPICA subsystem initialization */ 245 246 Status = AdInitialize (); 247 if (ACPI_FAILURE (Status)) 248 { 249 return (Status); 250 } 251 252 Status = AcpiAllocateRootTable (4); 253 if (ACPI_FAILURE (Status)) 254 { 255 AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n", 256 AcpiFormatException (Status)); 257 return (Status); 258 } 259 260 /* Handle additional output files for disassembler */ 261 262 Gbl_FileType = ASL_INPUT_TYPE_BINARY_ACPI_TABLE; 263 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 264 265 /* This is where the disassembly happens */ 266 267 AcpiGbl_DmOpt_Disasm = TRUE; 268 Status = AdAmlDisassemble (AslToFile, 269 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_OutputFilenamePrefix, 270 &Gbl_Files[ASL_FILE_INPUT].Filename); 271 if (ACPI_FAILURE (Status)) 272 { 273 return (Status); 274 } 275 276 /* Check if any control methods were unresolved */ 277 278 AcpiDmUnresolvedWarning (0); 279 280 /* Shutdown compiler and ACPICA subsystem */ 281 282 AeClearErrorLog (); 283 (void) AcpiTerminate (); 284 285 /* 286 * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the 287 * .DSL disassembly file, which can now be compiled if requested 288 */ 289 if (Gbl_DoCompile) 290 { 291 AcpiOsPrintf ("\nCompiling \"%s\"\n", 292 Gbl_Files[ASL_FILE_INPUT].Filename); 293 return (AE_CTRL_CONTINUE); 294 } 295 296 /* No need to free the filename string */ 297 298 Gbl_Files[ASL_FILE_INPUT].Filename = NULL; 299 300 CmDeleteCaches (); 301 return (AE_OK); 302 } 303 304 305 /******************************************************************************* 306 * 307 * FUNCTION: AslDoOneFile 308 * 309 * PARAMETERS: Filename - Name of the file 310 * 311 * RETURN: Status 312 * 313 * DESCRIPTION: Process a single file - either disassemble, compile, or both 314 * 315 ******************************************************************************/ 316 317 ACPI_STATUS 318 AslDoOneFile ( 319 char *Filename) 320 { 321 ACPI_STATUS Status; 322 323 324 /* Re-initialize "some" compiler/preprocessor globals */ 325 326 AslInitializeGlobals (); 327 PrInitializeGlobals (); 328 329 /* 330 * Extract the directory path. This path is used for possible include 331 * files and the optional AML filename embedded in the input file 332 * DefinitionBlock declaration. 333 */ 334 Status = FlSplitInputPathname (Filename, &Gbl_DirectoryPath, NULL); 335 if (ACPI_FAILURE (Status)) 336 { 337 return (Status); 338 } 339 340 /* Take a copy of the input filename, convert any backslashes */ 341 342 Gbl_Files[ASL_FILE_INPUT].Filename = 343 UtStringCacheCalloc (strlen (Filename) + 1); 344 345 strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); 346 UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename); 347 348 /* 349 * AML Disassembly (Optional) 350 */ 351 if (Gbl_DisasmFlag) 352 { 353 Status = AslDoDisassembly (); 354 if (Status != AE_CTRL_CONTINUE) 355 { 356 return (Status); 357 } 358 } 359 360 /* 361 * Open the input file. Here, this should be an ASCII source file, 362 * either an ASL file or a Data Table file 363 */ 364 Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename); 365 if (ACPI_FAILURE (Status)) 366 { 367 AePrintErrorLog (ASL_FILE_STDERR); 368 return (AE_ERROR); 369 } 370 371 Gbl_OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT); 372 373 /* Determine input file type */ 374 375 Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]); 376 if (Gbl_FileType == ASL_INPUT_TYPE_BINARY) 377 { 378 return (AE_ERROR); 379 } 380 381 /* 382 * If -p not specified, we will use the input filename as the 383 * output filename prefix 384 */ 385 if (Gbl_UseDefaultAmlFilename) 386 { 387 Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename; 388 } 389 390 /* Open the optional output files (listings, etc.) */ 391 392 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 393 if (ACPI_FAILURE (Status)) 394 { 395 AePrintErrorLog (ASL_FILE_STDERR); 396 return (AE_ERROR); 397 } 398 399 /* 400 * Compilation of ASL source versus DataTable source uses different 401 * compiler subsystems 402 */ 403 switch (Gbl_FileType) 404 { 405 /* 406 * Data Table Compilation 407 */ 408 case ASL_INPUT_TYPE_ASCII_DATA: 409 410 Status = DtDoCompile (); 411 if (ACPI_FAILURE (Status)) 412 { 413 return (Status); 414 } 415 416 if (Gbl_Signature) 417 { 418 Gbl_Signature = NULL; 419 } 420 421 /* Check if any errors occurred during compile */ 422 423 Status = AslCheckForErrorExit (); 424 if (ACPI_FAILURE (Status)) 425 { 426 return (Status); 427 } 428 429 /* Cleanup (for next source file) and exit */ 430 431 AeClearErrorLog (); 432 PrTerminatePreprocessor (); 433 return (Status); 434 435 /* 436 * ASL Compilation 437 */ 438 case ASL_INPUT_TYPE_ASCII_ASL: 439 440 /* ACPICA subsystem initialization */ 441 442 Status = AdInitialize (); 443 if (ACPI_FAILURE (Status)) 444 { 445 return (Status); 446 } 447 448 (void) CmDoCompile (); 449 (void) AcpiTerminate (); 450 451 /* Check if any errors occurred during compile */ 452 453 Status = AslCheckForErrorExit (); 454 if (ACPI_FAILURE (Status)) 455 { 456 return (Status); 457 } 458 459 /* Cleanup (for next source file) and exit */ 460 461 AeClearErrorLog (); 462 PrTerminatePreprocessor (); 463 464 /* ASL-to-ASL+ conversion - Perform immediate disassembly */ 465 466 if (Gbl_DoAslConversion) 467 { 468 /* 469 * New input file is the output AML file from above. 470 * New output is from the input ASL file from above. 471 */ 472 Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename; 473 CvDbgPrint ("OUTPUTFILENAME: %s\n", Gbl_OutputFilenamePrefix); 474 Gbl_Files[ASL_FILE_INPUT].Filename = 475 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename; 476 477 fprintf (stderr, "\n"); 478 AslDoDisassembly (); 479 480 /* delete the AML file. This AML file should never be utilized by AML interpreters. */ 481 482 FlDeleteFile (ASL_FILE_AML_OUTPUT); 483 } 484 485 return (AE_OK); 486 487 /* 488 * Binary ACPI table was auto-detected, disassemble it 489 */ 490 case ASL_INPUT_TYPE_BINARY_ACPI_TABLE: 491 492 /* We have what appears to be an ACPI table, disassemble it */ 493 494 FlCloseFile (ASL_FILE_INPUT); 495 Gbl_DoCompile = FALSE; 496 Gbl_DisasmFlag = TRUE; 497 Status = AslDoDisassembly (); 498 return (Status); 499 500 /* Unknown binary table */ 501 502 case ASL_INPUT_TYPE_BINARY: 503 504 AePrintErrorLog (ASL_FILE_STDERR); 505 return (AE_ERROR); 506 507 default: 508 509 printf ("Unknown file type %X\n", Gbl_FileType); 510 return (AE_ERROR); 511 } 512 } 513 514 515 /******************************************************************************* 516 * 517 * FUNCTION: AslCheckForErrorExit 518 * 519 * PARAMETERS: None. Examines global exception count array 520 * 521 * RETURN: Status 522 * 523 * DESCRIPTION: Determine if compiler should abort with error status 524 * 525 ******************************************************************************/ 526 527 ACPI_STATUS 528 AslCheckForErrorExit ( 529 void) 530 { 531 532 /* 533 * Return non-zero exit code if there have been errors, unless the 534 * global ignore error flag has been set 535 */ 536 if (!Gbl_IgnoreErrors) 537 { 538 if (Gbl_ExceptionCount[ASL_ERROR] > 0) 539 { 540 return (AE_ERROR); 541 } 542 543 /* Optionally treat warnings as errors */ 544 545 if (Gbl_WarningsAsErrors) 546 { 547 if ((Gbl_ExceptionCount[ASL_WARNING] > 0) || 548 (Gbl_ExceptionCount[ASL_WARNING2] > 0) || 549 (Gbl_ExceptionCount[ASL_WARNING3] > 0)) 550 { 551 return (AE_ERROR); 552 } 553 } 554 } 555 556 return (AE_OK); 557 } 558