1 /****************************************************************************** 2 * 3 * Module Name: aslstartup - Compiler startup routines, called from main 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 45 #include <contrib/dev/acpica/compiler/aslcompiler.h> 46 #include <contrib/dev/acpica/include/actables.h> 47 #include <contrib/dev/acpica/include/acapps.h> 48 49 #define _COMPONENT ACPI_COMPILER 50 ACPI_MODULE_NAME ("aslstartup") 51 52 53 #define ASL_MAX_FILES 256 54 static char *FileList[ASL_MAX_FILES]; 55 static BOOLEAN AslToFile = TRUE; 56 57 58 /* Local prototypes */ 59 60 static char ** 61 AsDoWildcard ( 62 char *DirectoryPathname, 63 char *FileSpecifier); 64 65 static UINT8 66 AslDetectSourceFileType ( 67 ASL_FILE_INFO *Info); 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_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: AsDoWildcard 132 * 133 * PARAMETERS: None 134 * 135 * RETURN: None 136 * 137 * DESCRIPTION: Process files via wildcards. This function is for the Windows 138 * case only. 139 * 140 ******************************************************************************/ 141 142 static char ** 143 AsDoWildcard ( 144 char *DirectoryPathname, 145 char *FileSpecifier) 146 { 147 #ifdef WIN32 148 void *DirInfo; 149 char *Filename; 150 int FileCount; 151 152 153 FileCount = 0; 154 155 /* Open parent directory */ 156 157 DirInfo = AcpiOsOpenDirectory (DirectoryPathname, FileSpecifier, REQUEST_FILE_ONLY); 158 if (!DirInfo) 159 { 160 /* Either the directory of file does not exist */ 161 162 Gbl_Files[ASL_FILE_INPUT].Filename = FileSpecifier; 163 FlFileError (ASL_FILE_INPUT, ASL_MSG_OPEN); 164 AslAbort (); 165 } 166 167 /* Process each file that matches the wildcard specification */ 168 169 while ((Filename = AcpiOsGetNextFilename (DirInfo))) 170 { 171 /* Add the filename to the file list */ 172 173 FileList[FileCount] = AcpiOsAllocate (strlen (Filename) + 1); 174 strcpy (FileList[FileCount], Filename); 175 FileCount++; 176 177 if (FileCount >= ASL_MAX_FILES) 178 { 179 printf ("Max files reached\n"); 180 FileList[0] = NULL; 181 return (FileList); 182 } 183 } 184 185 /* Cleanup */ 186 187 AcpiOsCloseDirectory (DirInfo); 188 FileList[FileCount] = NULL; 189 return (FileList); 190 191 #else 192 /* 193 * Linux/Unix cases - Wildcards are expanded by the shell automatically. 194 * Just return the filename in a null terminated list 195 */ 196 FileList[0] = AcpiOsAllocate (strlen (FileSpecifier) + 1); 197 strcpy (FileList[0], FileSpecifier); 198 FileList[1] = NULL; 199 200 return (FileList); 201 #endif 202 } 203 204 205 /******************************************************************************* 206 * 207 * FUNCTION: AslDetectSourceFileType 208 * 209 * PARAMETERS: Info - Name/Handle for the file (must be open) 210 * 211 * RETURN: File Type 212 * 213 * DESCRIPTION: Determine the type of the input file. Either binary (contains 214 * non-ASCII characters), ASL file, or an ACPI Data Table file. 215 * 216 ******************************************************************************/ 217 218 static UINT8 219 AslDetectSourceFileType ( 220 ASL_FILE_INFO *Info) 221 { 222 char *FileChar; 223 UINT8 Type; 224 ACPI_STATUS Status; 225 226 227 /* Check for 100% ASCII source file (comments are ignored) */ 228 229 Status = FlCheckForAscii (Info->Handle, Info->Filename, TRUE); 230 if (ACPI_FAILURE (Status)) 231 { 232 printf ("Non-ascii input file - %s\n", Info->Filename); 233 234 if (!Gbl_IgnoreErrors) 235 { 236 Type = ASL_INPUT_TYPE_BINARY; 237 goto Cleanup; 238 } 239 } 240 241 /* 242 * File is ASCII. Determine if this is an ASL file or an ACPI data 243 * table file. 244 */ 245 while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle)) 246 { 247 /* Uppercase the buffer for caseless compare */ 248 249 FileChar = Gbl_CurrentLineBuffer; 250 while (*FileChar) 251 { 252 *FileChar = (char) toupper ((int) *FileChar); 253 FileChar++; 254 } 255 256 /* Presence of "DefinitionBlock" indicates actual ASL code */ 257 258 if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK")) 259 { 260 /* Appears to be an ASL file */ 261 262 Type = ASL_INPUT_TYPE_ASCII_ASL; 263 goto Cleanup; 264 } 265 } 266 267 /* Not an ASL source file, default to a data table source file */ 268 269 Type = ASL_INPUT_TYPE_ASCII_DATA; 270 271 Cleanup: 272 273 /* Must seek back to the start of the file */ 274 275 fseek (Info->Handle, 0, SEEK_SET); 276 return (Type); 277 } 278 279 280 /******************************************************************************* 281 * 282 * FUNCTION: AslDoOneFile 283 * 284 * PARAMETERS: Filename - Name of the file 285 * 286 * RETURN: Status 287 * 288 * DESCRIPTION: Process a single file - either disassemble, compile, or both 289 * 290 ******************************************************************************/ 291 292 ACPI_STATUS 293 AslDoOneFile ( 294 char *Filename) 295 { 296 ACPI_STATUS Status; 297 298 299 /* Re-initialize "some" compiler/preprocessor globals */ 300 301 AslInitializeGlobals (); 302 PrInitializeGlobals (); 303 304 Gbl_Files[ASL_FILE_INPUT].Filename = Filename; 305 306 /* 307 * AML Disassembly (Optional) 308 */ 309 if (Gbl_DisasmFlag || Gbl_GetAllTables) 310 { 311 /* ACPICA subsystem initialization */ 312 313 Status = AdInitialize (); 314 if (ACPI_FAILURE (Status)) 315 { 316 return (Status); 317 } 318 319 Status = AcpiAllocateRootTable (4); 320 if (ACPI_FAILURE (Status)) 321 { 322 AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n", 323 AcpiFormatException (Status)); 324 return (Status); 325 } 326 327 /* This is where the disassembly happens */ 328 329 AcpiGbl_DbOpt_disasm = TRUE; 330 Status = AdAmlDisassemble (AslToFile, 331 Gbl_Files[ASL_FILE_INPUT].Filename, 332 Gbl_OutputFilenamePrefix, 333 &Gbl_Files[ASL_FILE_INPUT].Filename, 334 Gbl_GetAllTables); 335 if (ACPI_FAILURE (Status)) 336 { 337 return (Status); 338 } 339 340 #if 0 341 /* TBD: Handle additional output files for disassembler */ 342 343 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 344 LsDisplayNamespace (); 345 #endif 346 347 /* Shutdown compiler and ACPICA subsystem */ 348 349 AeClearErrorLog (); 350 (void) AcpiTerminate (); 351 352 /* 353 * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the 354 * .DSL disassembly file, which can now be compiled if requested 355 */ 356 if (Gbl_DoCompile) 357 { 358 AcpiOsPrintf ("\nCompiling \"%s\"\n", 359 Gbl_Files[ASL_FILE_INPUT].Filename); 360 } 361 else 362 { 363 Gbl_Files[ASL_FILE_INPUT].Filename = NULL; 364 return (AE_OK); 365 } 366 } 367 368 /* 369 * Open the input file. Here, this should be an ASCII source file, 370 * either an ASL file or a Data Table file 371 */ 372 Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename); 373 if (ACPI_FAILURE (Status)) 374 { 375 AePrintErrorLog (ASL_FILE_STDERR); 376 return (AE_ERROR); 377 } 378 379 /* Determine input file type */ 380 381 Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]); 382 if (Gbl_FileType == ASL_INPUT_TYPE_BINARY) 383 { 384 return (AE_ERROR); 385 } 386 387 /* 388 * If -p not specified, we will use the input filename as the 389 * output filename prefix 390 */ 391 if (Gbl_UseDefaultAmlFilename) 392 { 393 Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename; 394 } 395 396 /* Open the optional output files (listings, etc.) */ 397 398 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 399 if (ACPI_FAILURE (Status)) 400 { 401 AePrintErrorLog (ASL_FILE_STDERR); 402 return (AE_ERROR); 403 } 404 405 /* 406 * Compilation of ASL source versus DataTable source uses different 407 * compiler subsystems 408 */ 409 switch (Gbl_FileType) 410 { 411 /* 412 * Data Table Compilation 413 */ 414 case ASL_INPUT_TYPE_ASCII_DATA: 415 416 Status = DtDoCompile (); 417 if (ACPI_FAILURE (Status)) 418 { 419 return (Status); 420 } 421 422 if (Gbl_Signature) 423 { 424 ACPI_FREE (Gbl_Signature); 425 Gbl_Signature = NULL; 426 } 427 428 /* Check if any errors occurred during compile */ 429 430 Status = AslCheckForErrorExit (); 431 if (ACPI_FAILURE (Status)) 432 { 433 return (Status); 434 } 435 436 /* Cleanup (for next source file) and exit */ 437 438 AeClearErrorLog (); 439 PrTerminatePreprocessor (); 440 return (Status); 441 442 /* 443 * ASL Compilation 444 */ 445 case ASL_INPUT_TYPE_ASCII_ASL: 446 447 /* ACPICA subsystem initialization */ 448 449 Status = AdInitialize (); 450 if (ACPI_FAILURE (Status)) 451 { 452 return (Status); 453 } 454 455 (void) CmDoCompile (); 456 (void) AcpiTerminate (); 457 458 /* Check if any errors occurred during compile */ 459 460 Status = AslCheckForErrorExit (); 461 if (ACPI_FAILURE (Status)) 462 { 463 return (Status); 464 } 465 466 /* Cleanup (for next source file) and exit */ 467 468 AeClearErrorLog (); 469 PrTerminatePreprocessor (); 470 return (AE_OK); 471 472 case ASL_INPUT_TYPE_BINARY: 473 474 AePrintErrorLog (ASL_FILE_STDERR); 475 return (AE_ERROR); 476 477 default: 478 printf ("Unknown file type %X\n", Gbl_FileType); 479 return (AE_ERROR); 480 } 481 } 482 483 484 /******************************************************************************* 485 * 486 * FUNCTION: AslDoOnePathname 487 * 488 * PARAMETERS: Pathname - Full pathname, possibly with wildcards 489 * 490 * RETURN: Status 491 * 492 * DESCRIPTION: Process one pathname, possible terminated with a wildcard 493 * specification. If a wildcard, it is expanded and the multiple 494 * files are processed. 495 * 496 ******************************************************************************/ 497 498 ACPI_STATUS 499 AslDoOnePathname ( 500 char *Pathname, 501 ASL_PATHNAME_CALLBACK PathCallback) 502 { 503 ACPI_STATUS Status = AE_OK; 504 char **WildcardList; 505 char *Filename; 506 char *FullPathname; 507 508 509 /* Split incoming path into a directory/filename combo */ 510 511 Status = FlSplitInputPathname (Pathname, &Gbl_DirectoryPath, &Filename); 512 if (ACPI_FAILURE (Status)) 513 { 514 return (Status); 515 } 516 517 /* Expand possible wildcard into a file list (Windows/DOS only) */ 518 519 WildcardList = AsDoWildcard (Gbl_DirectoryPath, Filename); 520 while (*WildcardList) 521 { 522 FullPathname = ACPI_ALLOCATE ( 523 strlen (Gbl_DirectoryPath) + strlen (*WildcardList) + 1); 524 525 /* Construct a full path to the file */ 526 527 strcpy (FullPathname, Gbl_DirectoryPath); 528 strcat (FullPathname, *WildcardList); 529 530 /* 531 * If -p not specified, we will use the input filename as the 532 * output filename prefix 533 */ 534 if (Gbl_UseDefaultAmlFilename) 535 { 536 Gbl_OutputFilenamePrefix = FullPathname; 537 } 538 539 /* Save status from all compiles */ 540 541 Status |= (*PathCallback) (FullPathname); 542 543 ACPI_FREE (FullPathname); 544 ACPI_FREE (*WildcardList); 545 *WildcardList = NULL; 546 WildcardList++; 547 } 548 549 ACPI_FREE (Gbl_DirectoryPath); 550 ACPI_FREE (Filename); 551 return (Status); 552 } 553 554 555 /******************************************************************************* 556 * 557 * FUNCTION: AslCheckForErrorExit 558 * 559 * PARAMETERS: None. Examines global exception count array 560 * 561 * RETURN: Status 562 * 563 * DESCRIPTION: Determine if compiler should abort with error status 564 * 565 ******************************************************************************/ 566 567 ACPI_STATUS 568 AslCheckForErrorExit ( 569 void) 570 { 571 572 /* 573 * Return non-zero exit code if there have been errors, unless the 574 * global ignore error flag has been set 575 */ 576 if (!Gbl_IgnoreErrors) 577 { 578 if (Gbl_ExceptionCount[ASL_ERROR] > 0) 579 { 580 return (AE_ERROR); 581 } 582 583 /* Optionally treat warnings as errors */ 584 585 if (Gbl_WarningsAsErrors) 586 { 587 if ((Gbl_ExceptionCount[ASL_WARNING] > 0) || 588 (Gbl_ExceptionCount[ASL_WARNING2] > 0) || 589 (Gbl_ExceptionCount[ASL_WARNING3] > 0)) 590 { 591 return (AE_ERROR); 592 } 593 } 594 } 595 596 return (AE_OK); 597 } 598