1 /****************************************************************************** 2 * 3 * Module Name: aslstartup - Compiler startup routines, called from main 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 61 /* Globals */ 62 63 static BOOLEAN AslToFile = TRUE; 64 65 66 /******************************************************************************* 67 * 68 * FUNCTION: AslInitializeGlobals 69 * 70 * PARAMETERS: None 71 * 72 * RETURN: None 73 * 74 * DESCRIPTION: Re-initialize globals needed to restart the compiler. This 75 * allows multiple files to be disassembled and/or compiled. 76 * 77 ******************************************************************************/ 78 79 void 80 AslInitializeGlobals ( 81 void) 82 { 83 UINT32 i; 84 85 86 /* Init compiler globals */ 87 88 AslGbl_SyntaxError = 0; 89 AslGbl_CurrentColumn = 0; 90 AslGbl_CurrentLineNumber = 1; 91 AslGbl_LogicalLineNumber = 1; 92 AslGbl_CurrentLineOffset = 0; 93 AslGbl_InputFieldCount = 0; 94 AslGbl_InputByteCount = 0; 95 AslGbl_NsLookupCount = 0; 96 AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer; 97 98 AslGbl_ErrorLog = NULL; 99 AslGbl_NextError = NULL; 100 AslGbl_Signature = NULL; 101 AslGbl_FileType = 0; 102 103 AslGbl_TotalExecutableOpcodes = 0; 104 AslGbl_TotalNamedObjects = 0; 105 AslGbl_TotalKeywords = 0; 106 AslGbl_TotalParseNodes = 0; 107 AslGbl_TotalMethods = 0; 108 AslGbl_TotalAllocations = 0; 109 AslGbl_TotalAllocated = 0; 110 AslGbl_TotalFolds = 0; 111 112 AslGbl_NextEvent = 0; 113 for (i = 0; i < ASL_NUM_REPORT_LEVELS; i++) 114 { 115 AslGbl_ExceptionCount[i] = 0; 116 } 117 118 if (AcpiGbl_CaptureComments) 119 { 120 AslGbl_CommentState.SpacesBefore = 0; 121 AslGbl_CommentState.CommentType = 1; 122 AslGbl_CommentState.LatestParseOp = NULL; 123 AslGbl_CommentState.ParsingParenBraceNode = NULL; 124 AslGbl_CommentState.CaptureComments = TRUE; 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 142 static UINT8 143 AslDetectSourceFileType ( 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 (AslGbl_CurrentLineBuffer, AslGbl_LineBufferSize, Info->Handle)) 161 { 162 /* Uppercase the buffer for caseless compare */ 163 164 FileChar = AslGbl_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 (AslGbl_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 else 202 { 203 fprintf (stderr, 204 "Binary file does not contain a valid ACPI table\n"); 205 } 206 207 Type = ASL_INPUT_TYPE_BINARY; 208 209 210 Cleanup: 211 212 /* Must seek back to the start of the file */ 213 214 fseek (Info->Handle, 0, SEEK_SET); 215 return (Type); 216 } 217 218 219 /******************************************************************************* 220 * 221 * FUNCTION: AslDoDisassembly 222 * 223 * PARAMETERS: None 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build 228 * namespace. This function assumes that the ACPI subsystem has 229 * been initialized. The caller of the initialization will also 230 * terminate the ACPI subsystem. 231 * 232 ******************************************************************************/ 233 234 ACPI_STATUS 235 AslDoDisassembly ( 236 void) 237 { 238 ACPI_STATUS Status; 239 240 241 Status = AcpiAllocateRootTable (4); 242 if (ACPI_FAILURE (Status)) 243 { 244 AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n", 245 AcpiFormatException (Status)); 246 return (Status); 247 } 248 249 /* This is where the disassembly happens */ 250 251 AcpiGbl_DmOpt_Disasm = TRUE; 252 Status = AdAmlDisassemble (AslToFile, 253 AslGbl_Files[ASL_FILE_INPUT].Filename, AslGbl_OutputFilenamePrefix, 254 &AslGbl_Files[ASL_FILE_INPUT].Filename); 255 if (ACPI_FAILURE (Status)) 256 { 257 return (Status); 258 } 259 260 /* Check if any control methods were unresolved */ 261 262 AcpiDmUnresolvedWarning (0); 263 264 /* Clear Error log */ 265 266 AeClearErrorLog (); 267 268 /* 269 * AslGbl_Files[ASL_FILE_INPUT].Filename was replaced with the 270 * .DSL disassembly file, which can now be compiled if requested 271 */ 272 if (AslGbl_DoCompile) 273 { 274 AcpiOsPrintf ("\nCompiling \"%s\"\n", 275 AslGbl_Files[ASL_FILE_INPUT].Filename); 276 return (AE_CTRL_CONTINUE); 277 } 278 279 return (AE_OK); 280 } 281 282 283 /******************************************************************************* 284 * 285 * FUNCTION: AslDoOneFile 286 * 287 * PARAMETERS: Filename - Name of the file 288 * 289 * RETURN: Status 290 * 291 * DESCRIPTION: Process a single file - either disassemble, compile, or both 292 * 293 ******************************************************************************/ 294 295 ACPI_STATUS 296 AslDoOneFile ( 297 char *Filename) 298 { 299 ACPI_STATUS Status; 300 UINT8 Event; 301 ASL_GLOBAL_FILE_NODE *FileNode; 302 303 304 /* Re-initialize "some" compiler/preprocessor globals */ 305 306 AslInitializeGlobals (); 307 PrInitializeGlobals (); 308 309 /* 310 * Extract the directory path. This path is used for possible include 311 * files and the optional AML filename embedded in the input file 312 * DefinitionBlock declaration. 313 */ 314 Status = FlSplitInputPathname (Filename, &AslGbl_DirectoryPath, NULL); 315 if (ACPI_FAILURE (Status)) 316 { 317 return (Status); 318 } 319 320 /* 321 * There was an input file detected at this point. Each input ASL file is 322 * associated with one global file node consisting of the input file and 323 * all output files associated with it. This is useful when compiling 324 * multiple files in one command. 325 */ 326 Status = FlInitOneFile(Filename); 327 if (ACPI_FAILURE (Status)) 328 { 329 return (AE_ERROR); 330 } 331 332 /* Take a copy of the input filename, convert any backslashes */ 333 334 AslGbl_Files[ASL_FILE_INPUT].Filename = 335 UtLocalCacheCalloc (strlen (Filename) + 1); 336 337 strcpy (AslGbl_Files[ASL_FILE_INPUT].Filename, Filename); 338 UtConvertBackslashes (AslGbl_Files[ASL_FILE_INPUT].Filename); 339 340 /* 341 * Open the input file. Here, this should be an ASCII source file, 342 * either an ASL file or a Data Table file 343 */ 344 Status = FlOpenInputFile (AslGbl_Files[ASL_FILE_INPUT].Filename); 345 if (ACPI_FAILURE (Status)) 346 { 347 AePrintErrorLog (ASL_FILE_STDERR); 348 return (AE_ERROR); 349 } 350 351 FileNode = FlGetCurrentFileNode(); 352 353 FileNode->OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT); 354 355 /* Determine input file type */ 356 357 AslGbl_FileType = AslDetectSourceFileType (&AslGbl_Files[ASL_FILE_INPUT]); 358 FileNode->FileType = AslGbl_FileType; 359 if (AslGbl_FileType == ASL_INPUT_TYPE_BINARY) 360 { 361 return (AE_ERROR); 362 } 363 364 /* 365 * If -p not specified, we will use the input filename as the 366 * output filename prefix 367 */ 368 if (AslGbl_UseDefaultAmlFilename) 369 { 370 AslGbl_OutputFilenamePrefix = AslGbl_Files[ASL_FILE_INPUT].Filename; 371 } 372 373 /* 374 * Open the output file. Note: by default, the name of this file comes from 375 * the table descriptor within the input file. 376 */ 377 if (AslGbl_FileType == ASL_INPUT_TYPE_ASCII_ASL) 378 { 379 Event = UtBeginEvent ("Open AML output file"); 380 Status = FlOpenAmlOutputFile (AslGbl_OutputFilenamePrefix); 381 UtEndEvent (Event); 382 if (ACPI_FAILURE (Status)) 383 { 384 AePrintErrorLog (ASL_FILE_STDERR); 385 return (AE_ERROR); 386 } 387 } 388 389 /* Open the optional output files (listings, etc.) */ 390 391 Status = FlOpenMiscOutputFiles (AslGbl_OutputFilenamePrefix); 392 if (ACPI_FAILURE (Status)) 393 { 394 AePrintErrorLog (ASL_FILE_STDERR); 395 return (AE_ERROR); 396 } 397 398 /* 399 * Compilation of ASL source versus DataTable source uses different 400 * compiler subsystems 401 */ 402 switch (AslGbl_FileType) 403 { 404 /* 405 * Data Table Compilation 406 */ 407 case ASL_INPUT_TYPE_ASCII_DATA: 408 409 Status = DtDoCompile (); 410 if (ACPI_FAILURE (Status)) 411 { 412 return (Status); 413 } 414 415 if (AslGbl_Signature) 416 { 417 AslGbl_Signature = NULL; 418 } 419 420 /* Check if any errors occurred during compile */ 421 422 Status = AslCheckForErrorExit (); 423 if (ACPI_FAILURE (Status)) 424 { 425 return (Status); 426 } 427 428 /* Cleanup (for next source file) and exit */ 429 430 AeClearErrorLog (); 431 PrTerminatePreprocessor (); 432 return (Status); 433 434 /* 435 * ASL Compilation 436 */ 437 case ASL_INPUT_TYPE_ASCII_ASL: 438 439 Status = CmDoCompile (); 440 if (ACPI_FAILURE (Status)) 441 { 442 PrTerminatePreprocessor (); 443 return (Status); 444 } 445 446 /* 447 * At this point, we know how many lines are in the input file. Save it 448 * to display for post-compilation summary. 449 */ 450 FileNode->TotalLineCount = AslGbl_CurrentLineNumber; 451 return (AE_OK); 452 453 /* 454 * Binary ACPI table was auto-detected, disassemble it 455 */ 456 case ASL_INPUT_TYPE_BINARY_ACPI_TABLE: 457 458 /* We have what appears to be an ACPI table, disassemble it */ 459 460 FlCloseFile (ASL_FILE_INPUT); 461 AslGbl_DoCompile = FALSE; 462 AcpiGbl_DisasmFlag = TRUE; 463 Status = AslDoDisassembly (); 464 return (Status); 465 466 /* Unknown binary table */ 467 468 case ASL_INPUT_TYPE_BINARY: 469 470 AePrintErrorLog (ASL_FILE_STDERR); 471 return (AE_ERROR); 472 473 default: 474 475 printf ("Unknown file type %X\n", AslGbl_FileType); 476 return (AE_ERROR); 477 } 478 } 479 480 481 /******************************************************************************* 482 * 483 * FUNCTION: AslCheckForErrorExit 484 * 485 * PARAMETERS: None. Examines global exception count array 486 * 487 * RETURN: Status 488 * 489 * DESCRIPTION: Determine if compiler should abort with error status 490 * 491 ******************************************************************************/ 492 493 ACPI_STATUS 494 AslCheckForErrorExit ( 495 void) 496 { 497 498 /* 499 * Return non-zero exit code if there have been errors, unless the 500 * global ignore error flag has been set 501 */ 502 if (!AslGbl_IgnoreErrors) 503 { 504 if (AslGbl_ExceptionCount[ASL_ERROR] > 0) 505 { 506 return (AE_ERROR); 507 } 508 509 /* Optionally treat warnings as errors */ 510 511 if (AslGbl_WarningsAsErrors) 512 { 513 if ((AslGbl_ExceptionCount[ASL_WARNING] > 0) || 514 (AslGbl_ExceptionCount[ASL_WARNING2] > 0) || 515 (AslGbl_ExceptionCount[ASL_WARNING3] > 0)) 516 { 517 AslError (ASL_ERROR, ASL_MSG_WARNING_AS_ERROR, NULL, 518 "(reporting warnings as errors)"); 519 return (AE_ERROR); 520 } 521 } 522 } 523 524 return (AE_OK); 525 } 526