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