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