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 "aslcompiler.h"
  46 #include "actables.h"
  47 #include "acdisasm.h"
  48 #include "acapps.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 static ACPI_STATUS
  61 AslDoDisassembly (
  62     void);
  63 
  64 
  65 /* Globals */
  66 
  67 static BOOLEAN          AslToFile = TRUE;
  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:    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;
 148     ACPI_STATUS             Status;
 149 
 150 
 151     /* Check for a valid binary ACPI table */
 152 
 153     Status = FlCheckForAcpiTable (Info->Handle);
 154     if (ACPI_SUCCESS (Status))
 155     {
 156         Type = ASL_INPUT_TYPE_ACPI_TABLE;
 157         goto Cleanup;
 158     }
 159 
 160     /* Check for 100% ASCII source file (comments are ignored) */
 161 
 162     Status = FlCheckForAscii (Info->Handle, Info->Filename, TRUE);
 163     if (ACPI_FAILURE (Status))
 164     {
 165         printf ("Non-ascii input file - %s\n", Info->Filename);
 166 
 167         if (!Gbl_IgnoreErrors)
 168         {
 169             Type = ASL_INPUT_TYPE_BINARY;
 170             goto Cleanup;
 171         }
 172     }
 173 
 174     /*
 175      * File is ASCII. Determine if this is an ASL file or an ACPI data
 176      * table file.
 177      */
 178     while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle))
 179     {
 180         /* Uppercase the buffer for caseless compare */
 181 
 182         FileChar = Gbl_CurrentLineBuffer;
 183         while (*FileChar)
 184         {
 185             *FileChar = (char) toupper ((int) *FileChar);
 186             FileChar++;
 187         }
 188 
 189         /* Presence of "DefinitionBlock" indicates actual ASL code */
 190 
 191         if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK"))
 192         {
 193             /* Appears to be an ASL file */
 194 
 195             Type = ASL_INPUT_TYPE_ASCII_ASL;
 196             goto Cleanup;
 197         }
 198     }
 199 
 200     /* Not an ASL source file, default to a data table source file */
 201 
 202     Type = ASL_INPUT_TYPE_ASCII_DATA;
 203 
 204 Cleanup:
 205 
 206     /* Must seek back to the start of the file */
 207 
 208     fseek (Info->Handle, 0, SEEK_SET);
 209     return (Type);
 210 }
 211 
 212 
 213 /*******************************************************************************
 214  *
 215  * FUNCTION:    AslDoDisassembly
 216  *
 217  * PARAMETERS:  None
 218  *
 219  * RETURN:      Status
 220  *
 221  * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build
 222  *              namespace.
 223  *
 224  ******************************************************************************/
 225 
 226 static ACPI_STATUS
 227 AslDoDisassembly (
 228     void)
 229 {
 230     ACPI_STATUS             Status;
 231 
 232 
 233     /* ACPICA subsystem initialization */
 234 
 235     Status = AdInitialize ();
 236     if (ACPI_FAILURE (Status))
 237     {
 238         return (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_DbOpt_disasm = TRUE;
 252     Status = AdAmlDisassemble (AslToFile,
 253         Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_OutputFilenamePrefix,
 254         &Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_GetAllTables);
 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 #if 0
 265     /* TBD: Handle additional output files for disassembler */
 266 
 267     Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
 268     NsDisplayNamespace ();
 269 #endif
 270 
 271     /* Shutdown compiler and ACPICA subsystem */
 272 
 273     AeClearErrorLog ();
 274     (void) AcpiTerminate ();
 275 
 276     /*
 277      * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the
 278      * .DSL disassembly file, which can now be compiled if requested
 279      */
 280     if (Gbl_DoCompile)
 281     {
 282         AcpiOsPrintf ("\nCompiling \"%s\"\n",
 283             Gbl_Files[ASL_FILE_INPUT].Filename);
 284         return (AE_CTRL_CONTINUE);
 285     }
 286 
 287     ACPI_FREE (Gbl_Files[ASL_FILE_INPUT].Filename);
 288     Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
 289     return (AE_OK);
 290 }
 291 
 292 
 293 /*******************************************************************************
 294  *
 295  * FUNCTION:    AslDoOneFile
 296  *
 297  * PARAMETERS:  Filename        - Name of the file
 298  *
 299  * RETURN:      Status
 300  *
 301  * DESCRIPTION: Process a single file - either disassemble, compile, or both
 302  *
 303  ******************************************************************************/
 304 
 305 ACPI_STATUS
 306 AslDoOneFile (
 307     char                    *Filename)
 308 {
 309     ACPI_STATUS             Status;
 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, &Gbl_DirectoryPath, NULL);
 323     if (ACPI_FAILURE (Status))
 324     {
 325         return (Status);
 326     }
 327 
 328     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
 329     UtConvertBackslashes (Filename);
 330 
 331     /*
 332      * AML Disassembly (Optional)
 333      */
 334     if (Gbl_DisasmFlag || Gbl_GetAllTables)
 335     {
 336         Status = AslDoDisassembly ();
 337         if (Status != AE_CTRL_CONTINUE)
 338         {
 339             return (Status);
 340         }
 341     }
 342 
 343     /*
 344      * Open the input file. Here, this should be an ASCII source file,
 345      * either an ASL file or a Data Table file
 346      */
 347     Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
 348     if (ACPI_FAILURE (Status))
 349     {
 350         AePrintErrorLog (ASL_FILE_STDERR);
 351         return (AE_ERROR);
 352     }
 353 
 354     /* Determine input file type */
 355 
 356     Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
 357     if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
 358     {
 359         return (AE_ERROR);
 360     }
 361 
 362     /*
 363      * If -p not specified, we will use the input filename as the
 364      * output filename prefix
 365      */
 366     if (Gbl_UseDefaultAmlFilename)
 367     {
 368         Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
 369     }
 370 
 371     /* Open the optional output files (listings, etc.) */
 372 
 373     Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
 374     if (ACPI_FAILURE (Status))
 375     {
 376         AePrintErrorLog (ASL_FILE_STDERR);
 377         return (AE_ERROR);
 378     }
 379 
 380     /*
 381      * Compilation of ASL source versus DataTable source uses different
 382      * compiler subsystems
 383      */
 384     switch (Gbl_FileType)
 385     {
 386     /*
 387      * Data Table Compilation
 388      */
 389     case ASL_INPUT_TYPE_ASCII_DATA:
 390 
 391         Status = DtDoCompile ();
 392         if (ACPI_FAILURE (Status))
 393         {
 394             return (Status);
 395         }
 396 
 397         if (Gbl_Signature)
 398         {
 399             ACPI_FREE (Gbl_Signature);
 400             Gbl_Signature = NULL;
 401         }
 402 
 403         /* Check if any errors occurred during compile */
 404 
 405         Status = AslCheckForErrorExit ();
 406         if (ACPI_FAILURE (Status))
 407         {
 408             return (Status);
 409         }
 410 
 411         /* Cleanup (for next source file) and exit */
 412 
 413         AeClearErrorLog ();
 414         PrTerminatePreprocessor ();
 415         return (Status);
 416 
 417     /*
 418      * ASL Compilation
 419      */
 420     case ASL_INPUT_TYPE_ASCII_ASL:
 421 
 422         /* ACPICA subsystem initialization */
 423 
 424         Status = AdInitialize ();
 425         if (ACPI_FAILURE (Status))
 426         {
 427             return (Status);
 428         }
 429 
 430         (void) CmDoCompile ();
 431         (void) AcpiTerminate ();
 432 
 433         /* Check if any errors occurred during compile */
 434 
 435         Status = AslCheckForErrorExit ();
 436         if (ACPI_FAILURE (Status))
 437         {
 438             return (Status);
 439         }
 440 
 441         /* Cleanup (for next source file) and exit */
 442 
 443         AeClearErrorLog ();
 444         PrTerminatePreprocessor ();
 445         return (AE_OK);
 446 
 447     /*
 448      * Binary ACPI table was auto-detected, disassemble it
 449      */
 450     case ASL_INPUT_TYPE_ACPI_TABLE:
 451 
 452         /* We have what appears to be an ACPI table, disassemble it */
 453 
 454         FlCloseFile (ASL_FILE_INPUT);
 455         Gbl_DoCompile = FALSE;
 456         Gbl_DisasmFlag = TRUE;
 457         Status = AslDoDisassembly ();
 458         return (Status);
 459 
 460     /* Unknown binary table */
 461 
 462     case ASL_INPUT_TYPE_BINARY:
 463 
 464         AePrintErrorLog (ASL_FILE_STDERR);
 465         return (AE_ERROR);
 466 
 467     default:
 468 
 469         printf ("Unknown file type %X\n", Gbl_FileType);
 470         return (AE_ERROR);
 471     }
 472 }
 473 
 474 
 475 /*******************************************************************************
 476  *
 477  * FUNCTION:    AslCheckForErrorExit
 478  *
 479  * PARAMETERS:  None. Examines global exception count array
 480  *
 481  * RETURN:      Status
 482  *
 483  * DESCRIPTION: Determine if compiler should abort with error status
 484  *
 485  ******************************************************************************/
 486 
 487 ACPI_STATUS
 488 AslCheckForErrorExit (
 489     void)
 490 {
 491 
 492     /*
 493      * Return non-zero exit code if there have been errors, unless the
 494      * global ignore error flag has been set
 495      */
 496     if (!Gbl_IgnoreErrors)
 497     {
 498         if (Gbl_ExceptionCount[ASL_ERROR] > 0)
 499         {
 500             return (AE_ERROR);
 501         }
 502 
 503         /* Optionally treat warnings as errors */
 504 
 505         if (Gbl_WarningsAsErrors)
 506         {
 507             if ((Gbl_ExceptionCount[ASL_WARNING] > 0)  ||
 508                 (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
 509                 (Gbl_ExceptionCount[ASL_WARNING3] > 0))
 510             {
 511                 return (AE_ERROR);
 512             }
 513         }
 514     }
 515 
 516     return (AE_OK);
 517 }