aslstartup.c revision 234623
1 2/****************************************************************************** 3 * 4 * Module Name: aslstartup - Compiler startup routines, called from main 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2012, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 46#include <contrib/dev/acpica/compiler/aslcompiler.h> 47#include <contrib/dev/acpica/include/actables.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 70 71/******************************************************************************* 72 * 73 * FUNCTION: AslInitializeGlobals 74 * 75 * PARAMETERS: None 76 * 77 * RETURN: None 78 * 79 * DESCRIPTION: Re-initialize globals needed to restart the compiler. This 80 * allows multiple files to be disassembled and/or compiled. 81 * 82 ******************************************************************************/ 83 84void 85AslInitializeGlobals ( 86 void) 87{ 88 UINT32 i; 89 90 91 /* Init compiler globals */ 92 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 129 130/****************************************************************************** 131 * 132 * FUNCTION: AsDoWildcard 133 * 134 * PARAMETERS: None 135 * 136 * RETURN: None 137 * 138 * DESCRIPTION: Process files via wildcards. This function is for the Windows 139 * case only. 140 * 141 ******************************************************************************/ 142 143static char ** 144AsDoWildcard ( 145 char *DirectoryPathname, 146 char *FileSpecifier) 147{ 148#ifdef WIN32 149 void *DirInfo; 150 char *Filename; 151 int FileCount; 152 153 154 FileCount = 0; 155 156 /* Open parent directory */ 157 158 DirInfo = AcpiOsOpenDirectory (DirectoryPathname, FileSpecifier, REQUEST_FILE_ONLY); 159 if (!DirInfo) 160 { 161 /* Either the directory of file does not exist */ 162 163 Gbl_Files[ASL_FILE_INPUT].Filename = FileSpecifier; 164 FlFileError (ASL_FILE_INPUT, ASL_MSG_OPEN); 165 AslAbort (); 166 } 167 168 /* Process each file that matches the wildcard specification */ 169 170 while ((Filename = AcpiOsGetNextFilename (DirInfo))) 171 { 172 /* Add the filename to the file list */ 173 174 FileList[FileCount] = AcpiOsAllocate (strlen (Filename) + 1); 175 strcpy (FileList[FileCount], Filename); 176 FileCount++; 177 178 if (FileCount >= ASL_MAX_FILES) 179 { 180 printf ("Max files reached\n"); 181 FileList[0] = NULL; 182 return (FileList); 183 } 184 } 185 186 /* Cleanup */ 187 188 AcpiOsCloseDirectory (DirInfo); 189 FileList[FileCount] = NULL; 190 return (FileList); 191 192#else 193 /* 194 * Linux/Unix cases - Wildcards are expanded by the shell automatically. 195 * Just return the filename in a null terminated list 196 */ 197 FileList[0] = AcpiOsAllocate (strlen (FileSpecifier) + 1); 198 strcpy (FileList[0], FileSpecifier); 199 FileList[1] = NULL; 200 201 return (FileList); 202#endif 203} 204 205 206/******************************************************************************* 207 * 208 * FUNCTION: AslDetectSourceFileType 209 * 210 * PARAMETERS: Info - Name/Handle for the file (must be open) 211 * 212 * RETURN: File Type 213 * 214 * DESCRIPTION: Determine the type of the input file. Either binary (contains 215 * non-ASCII characters), ASL file, or an ACPI Data Table file. 216 * 217 ******************************************************************************/ 218 219static UINT8 220AslDetectSourceFileType ( 221 ASL_FILE_INFO *Info) 222{ 223 char *FileChar; 224 UINT8 Type; 225 ACPI_STATUS Status; 226 227 228 /* Check for 100% ASCII source file (comments are ignored) */ 229 230 Status = FlCheckForAscii (Info); 231 if (ACPI_FAILURE (Status)) 232 { 233 printf ("Non-ascii input file - %s\n", Info->Filename); 234 Type = ASL_INPUT_TYPE_BINARY; 235 goto Cleanup; 236 } 237 238 /* 239 * File is ASCII. Determine if this is an ASL file or an ACPI data 240 * table file. 241 */ 242 while (fgets (Gbl_CurrentLineBuffer, ASL_LINE_BUFFER_SIZE, Info->Handle)) 243 { 244 /* Uppercase the buffer for caseless compare */ 245 246 FileChar = Gbl_CurrentLineBuffer; 247 while (*FileChar) 248 { 249 *FileChar = (char) toupper ((int) *FileChar); 250 FileChar++; 251 } 252 253 /* Presence of "DefinitionBlock" indicates actual ASL code */ 254 255 if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK")) 256 { 257 /* Appears to be an ASL file */ 258 259 Type = ASL_INPUT_TYPE_ASCII_ASL; 260 goto Cleanup; 261 } 262 } 263 264 /* Not an ASL source file, default to a data table source file */ 265 266 Type = ASL_INPUT_TYPE_ASCII_DATA; 267 268Cleanup: 269 270 /* Must seek back to the start of the file */ 271 272 fseek (Info->Handle, 0, SEEK_SET); 273 return (Type); 274} 275 276 277/******************************************************************************* 278 * 279 * FUNCTION: AslDoOneFile 280 * 281 * PARAMETERS: Filename - Name of the file 282 * 283 * RETURN: Status 284 * 285 * DESCRIPTION: Process a single file - either disassemble, compile, or both 286 * 287 ******************************************************************************/ 288 289ACPI_STATUS 290AslDoOneFile ( 291 char *Filename) 292{ 293 ACPI_STATUS Status; 294 295 296 /* Re-initialize "some" compiler/preprocessor globals */ 297 298 AslInitializeGlobals (); 299 PrInitializeGlobals (); 300 301 Gbl_Files[ASL_FILE_INPUT].Filename = Filename; 302 303 /* 304 * AML Disassembly (Optional) 305 */ 306 if (Gbl_DisasmFlag || Gbl_GetAllTables) 307 { 308 /* ACPICA subsystem initialization */ 309 310 Status = AdInitialize (); 311 if (ACPI_FAILURE (Status)) 312 { 313 return (Status); 314 } 315 316 Status = AcpiAllocateRootTable (4); 317 if (ACPI_FAILURE (Status)) 318 { 319 AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n", 320 AcpiFormatException (Status)); 321 return (Status); 322 } 323 324 /* This is where the disassembly happens */ 325 326 AcpiGbl_DbOpt_disasm = TRUE; 327 Status = AdAmlDisassemble (AslToFile, 328 Gbl_Files[ASL_FILE_INPUT].Filename, 329 Gbl_OutputFilenamePrefix, 330 &Gbl_Files[ASL_FILE_INPUT].Filename, 331 Gbl_GetAllTables); 332 if (ACPI_FAILURE (Status)) 333 { 334 return (Status); 335 } 336 337 /* Shutdown compiler and ACPICA subsystem */ 338 339 AeClearErrorLog (); 340 (void) AcpiTerminate (); 341 342 /* 343 * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the 344 * .DSL disassembly file, which can now be compiled if requested 345 */ 346 if (Gbl_DoCompile) 347 { 348 AcpiOsPrintf ("\nCompiling \"%s\"\n", 349 Gbl_Files[ASL_FILE_INPUT].Filename); 350 } 351 else 352 { 353 Gbl_Files[ASL_FILE_INPUT].Filename = NULL; 354 return (AE_OK); 355 } 356 } 357 358 /* 359 * Open the input file. Here, this should be an ASCII source file, 360 * either an ASL file or a Data Table file 361 */ 362 Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename); 363 if (ACPI_FAILURE (Status)) 364 { 365 AePrintErrorLog (ASL_FILE_STDERR); 366 return (AE_ERROR); 367 } 368 369 /* Determine input file type */ 370 371 Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]); 372 if (Gbl_FileType == ASL_INPUT_TYPE_BINARY) 373 { 374 return (AE_ERROR); 375 } 376 377 /* 378 * If -p not specified, we will use the input filename as the 379 * output filename prefix 380 */ 381 if (Gbl_UseDefaultAmlFilename) 382 { 383 Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename; 384 } 385 386 /* Open the optional output files (listings, etc.) */ 387 388 Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix); 389 if (ACPI_FAILURE (Status)) 390 { 391 AePrintErrorLog (ASL_FILE_STDERR); 392 return (AE_ERROR); 393 } 394 395 /* 396 * Compilation of ASL source versus DataTable source uses different 397 * compiler subsystems 398 */ 399 switch (Gbl_FileType) 400 { 401 /* 402 * Data Table Compilation 403 */ 404 case ASL_INPUT_TYPE_ASCII_DATA: 405 406 Status = DtDoCompile (); 407 if (ACPI_FAILURE (Status)) 408 { 409 return (Status); 410 } 411 412 if (Gbl_Signature) 413 { 414 ACPI_FREE (Gbl_Signature); 415 Gbl_Signature = NULL; 416 } 417 418 /* Check if any errors occurred during compile */ 419 420 Status = AslCheckForErrorExit (); 421 if (ACPI_FAILURE (Status)) 422 { 423 return (Status); 424 } 425 426 /* Cleanup (for next source file) and exit */ 427 428 AeClearErrorLog (); 429 PrTerminatePreprocessor (); 430 return (Status); 431 432 /* 433 * ASL Compilation 434 */ 435 case ASL_INPUT_TYPE_ASCII_ASL: 436 437 /* ACPICA subsystem initialization */ 438 439 Status = AdInitialize (); 440 if (ACPI_FAILURE (Status)) 441 { 442 return (Status); 443 } 444 445 (void) CmDoCompile (); 446 (void) AcpiTerminate (); 447 448 /* Check if any errors occurred during compile */ 449 450 Status = AslCheckForErrorExit (); 451 if (ACPI_FAILURE (Status)) 452 { 453 return (Status); 454 } 455 456 /* Cleanup (for next source file) and exit */ 457 458 AeClearErrorLog (); 459 PrTerminatePreprocessor (); 460 return (AE_OK); 461 462 case ASL_INPUT_TYPE_BINARY: 463 464 AePrintErrorLog (ASL_FILE_STDERR); 465 return (AE_ERROR); 466 467 default: 468 printf ("Unknown file type %X\n", Gbl_FileType); 469 return (AE_ERROR); 470 } 471} 472 473 474/******************************************************************************* 475 * 476 * FUNCTION: AslDoOnePathname 477 * 478 * PARAMETERS: Pathname - Full pathname, possibly with wildcards 479 * 480 * RETURN: Status 481 * 482 * DESCRIPTION: Process one pathname, possible terminated with a wildcard 483 * specification. If a wildcard, it is expanded and the multiple 484 * files are processed. 485 * 486 ******************************************************************************/ 487 488ACPI_STATUS 489AslDoOnePathname ( 490 char *Pathname, 491 ASL_PATHNAME_CALLBACK PathCallback) 492{ 493 ACPI_STATUS Status = AE_OK; 494 char **WildcardList; 495 char *Filename; 496 char *FullPathname; 497 498 499 /* Split incoming path into a directory/filename combo */ 500 501 Status = FlSplitInputPathname (Pathname, &Gbl_DirectoryPath, &Filename); 502 if (ACPI_FAILURE (Status)) 503 { 504 return (Status); 505 } 506 507 /* Expand possible wildcard into a file list (Windows/DOS only) */ 508 509 WildcardList = AsDoWildcard (Gbl_DirectoryPath, Filename); 510 while (*WildcardList) 511 { 512 FullPathname = ACPI_ALLOCATE ( 513 strlen (Gbl_DirectoryPath) + strlen (*WildcardList) + 1); 514 515 /* Construct a full path to the file */ 516 517 strcpy (FullPathname, Gbl_DirectoryPath); 518 strcat (FullPathname, *WildcardList); 519 520 /* 521 * If -p not specified, we will use the input filename as the 522 * output filename prefix 523 */ 524 if (Gbl_UseDefaultAmlFilename) 525 { 526 Gbl_OutputFilenamePrefix = FullPathname; 527 } 528 529 /* Save status from all compiles */ 530 531 Status |= (*PathCallback) (FullPathname); 532 533 ACPI_FREE (FullPathname); 534 ACPI_FREE (*WildcardList); 535 *WildcardList = NULL; 536 WildcardList++; 537 } 538 539 ACPI_FREE (Gbl_DirectoryPath); 540 ACPI_FREE (Filename); 541 return (Status); 542} 543 544 545/******************************************************************************* 546 * 547 * FUNCTION: AslCheckForErrorExit 548 * 549 * PARAMETERS: None. Examines global exception count array 550 * 551 * RETURN: Status 552 * 553 * DESCRIPTION: Determine if compiler should abort with error status 554 * 555 ******************************************************************************/ 556 557ACPI_STATUS 558AslCheckForErrorExit ( 559 void) 560{ 561 562 /* 563 * Return non-zero exit code if there have been errors, unless the 564 * global ignore error flag has been set 565 */ 566 if (!Gbl_IgnoreErrors) 567 { 568 if (Gbl_ExceptionCount[ASL_ERROR] > 0) 569 { 570 return (AE_ERROR); 571 } 572 573 /* Optionally treat warnings as errors */ 574 575 if (Gbl_WarningsAsErrors) 576 { 577 if ((Gbl_ExceptionCount[ASL_WARNING] > 0) || 578 (Gbl_ExceptionCount[ASL_WARNING2] > 0) || 579 (Gbl_ExceptionCount[ASL_WARNING3] > 0)) 580 { 581 return (AE_ERROR); 582 } 583 } 584 } 585 586 return (AE_OK); 587} 588