aslstartup.c revision 284460
1/******************************************************************************
2 *
3 * Module Name: aslstartup - Compiler startup routines, called from main
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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#include <contrib/dev/acpica/compiler/aslcompiler.h>
45#include <contrib/dev/acpica/include/actables.h>
46#include <contrib/dev/acpica/include/acdisasm.h>
47#include <contrib/dev/acpica/include/acapps.h>
48
49#define _COMPONENT          ACPI_COMPILER
50        ACPI_MODULE_NAME    ("aslstartup")
51
52
53/* Local prototypes */
54
55static UINT8
56AslDetectSourceFileType (
57    ASL_FILE_INFO           *Info);
58
59static ACPI_STATUS
60AslDoDisassembly (
61    void);
62
63
64/* Globals */
65
66static BOOLEAN          AslToFile = TRUE;
67
68
69/*******************************************************************************
70 *
71 * FUNCTION:    AslInitializeGlobals
72 *
73 * PARAMETERS:  None
74 *
75 * RETURN:      None
76 *
77 * DESCRIPTION: Re-initialize globals needed to restart the compiler. This
78 *              allows multiple files to be disassembled and/or compiled.
79 *
80 ******************************************************************************/
81
82void
83AslInitializeGlobals (
84    void)
85{
86    UINT32                  i;
87
88
89    /* Init compiler globals */
90
91    Gbl_SyntaxError = 0;
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
142static UINT8
143AslDetectSourceFileType (
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->Filename, TRUE);
163    if (ACPI_FAILURE (Status))
164    {
165        printf ("Invalid characters in 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
204Cleanup:
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
226static ACPI_STATUS
227AslDoDisassembly (
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);
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    /* No need to free the filename string */
288
289    Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
290
291    CmDeleteCaches ();
292    return (AE_OK);
293}
294
295
296/*******************************************************************************
297 *
298 * FUNCTION:    AslDoOneFile
299 *
300 * PARAMETERS:  Filename        - Name of the file
301 *
302 * RETURN:      Status
303 *
304 * DESCRIPTION: Process a single file - either disassemble, compile, or both
305 *
306 ******************************************************************************/
307
308ACPI_STATUS
309AslDoOneFile (
310    char                    *Filename)
311{
312    ACPI_STATUS             Status;
313
314
315    /* Re-initialize "some" compiler/preprocessor globals */
316
317    AslInitializeGlobals ();
318    PrInitializeGlobals ();
319
320    /*
321     * Extract the directory path. This path is used for possible include
322     * files and the optional AML filename embedded in the input file
323     * DefinitionBlock declaration.
324     */
325    Status = FlSplitInputPathname (Filename, &Gbl_DirectoryPath, NULL);
326    if (ACPI_FAILURE (Status))
327    {
328        return (Status);
329    }
330
331    /* Take a copy of the input filename, convert any backslashes */
332
333    Gbl_Files[ASL_FILE_INPUT].Filename =
334        UtStringCacheCalloc (strlen (Filename) + 1);
335
336    strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
337    UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename);
338
339    /*
340     * AML Disassembly (Optional)
341     */
342    if (Gbl_DisasmFlag)
343    {
344        Status = AslDoDisassembly ();
345        if (Status != AE_CTRL_CONTINUE)
346        {
347            return (Status);
348        }
349    }
350
351    /*
352     * Open the input file. Here, this should be an ASCII source file,
353     * either an ASL file or a Data Table file
354     */
355    Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
356    if (ACPI_FAILURE (Status))
357    {
358        AePrintErrorLog (ASL_FILE_STDERR);
359        return (AE_ERROR);
360    }
361
362    /* Determine input file type */
363
364    Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
365    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
366    {
367        return (AE_ERROR);
368    }
369
370    /*
371     * If -p not specified, we will use the input filename as the
372     * output filename prefix
373     */
374    if (Gbl_UseDefaultAmlFilename)
375    {
376        Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
377    }
378
379    /* Open the optional output files (listings, etc.) */
380
381    Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
382    if (ACPI_FAILURE (Status))
383    {
384        AePrintErrorLog (ASL_FILE_STDERR);
385        return (AE_ERROR);
386    }
387
388    /*
389     * Compilation of ASL source versus DataTable source uses different
390     * compiler subsystems
391     */
392    switch (Gbl_FileType)
393    {
394    /*
395     * Data Table Compilation
396     */
397    case ASL_INPUT_TYPE_ASCII_DATA:
398
399        Status = DtDoCompile ();
400        if (ACPI_FAILURE (Status))
401        {
402            return (Status);
403        }
404
405        if (Gbl_Signature)
406        {
407            Gbl_Signature = NULL;
408        }
409
410        /* Check if any errors occurred during compile */
411
412        Status = AslCheckForErrorExit ();
413        if (ACPI_FAILURE (Status))
414        {
415            return (Status);
416        }
417
418        /* Cleanup (for next source file) and exit */
419
420        AeClearErrorLog ();
421        PrTerminatePreprocessor ();
422        return (Status);
423
424    /*
425     * ASL Compilation
426     */
427    case ASL_INPUT_TYPE_ASCII_ASL:
428
429        /* ACPICA subsystem initialization */
430
431        Status = AdInitialize ();
432        if (ACPI_FAILURE (Status))
433        {
434            return (Status);
435        }
436
437        (void) CmDoCompile ();
438        (void) AcpiTerminate ();
439
440        /* Check if any errors occurred during compile */
441
442        Status = AslCheckForErrorExit ();
443        if (ACPI_FAILURE (Status))
444        {
445            return (Status);
446        }
447
448        /* Cleanup (for next source file) and exit */
449
450        AeClearErrorLog ();
451        PrTerminatePreprocessor ();
452        return (AE_OK);
453
454    /*
455     * Binary ACPI table was auto-detected, disassemble it
456     */
457    case ASL_INPUT_TYPE_ACPI_TABLE:
458
459        /* We have what appears to be an ACPI table, disassemble it */
460
461        FlCloseFile (ASL_FILE_INPUT);
462        Gbl_DoCompile = FALSE;
463        Gbl_DisasmFlag = TRUE;
464        Status = AslDoDisassembly ();
465        return (Status);
466
467    /* Unknown binary table */
468
469    case ASL_INPUT_TYPE_BINARY:
470
471        AePrintErrorLog (ASL_FILE_STDERR);
472        return (AE_ERROR);
473
474    default:
475
476        printf ("Unknown file type %X\n", Gbl_FileType);
477        return (AE_ERROR);
478    }
479}
480
481
482/*******************************************************************************
483 *
484 * FUNCTION:    AslCheckForErrorExit
485 *
486 * PARAMETERS:  None. Examines global exception count array
487 *
488 * RETURN:      Status
489 *
490 * DESCRIPTION: Determine if compiler should abort with error status
491 *
492 ******************************************************************************/
493
494ACPI_STATUS
495AslCheckForErrorExit (
496    void)
497{
498
499    /*
500     * Return non-zero exit code if there have been errors, unless the
501     * global ignore error flag has been set
502     */
503    if (!Gbl_IgnoreErrors)
504    {
505        if (Gbl_ExceptionCount[ASL_ERROR] > 0)
506        {
507            return (AE_ERROR);
508        }
509
510        /* Optionally treat warnings as errors */
511
512        if (Gbl_WarningsAsErrors)
513        {
514            if ((Gbl_ExceptionCount[ASL_WARNING] > 0)  ||
515                (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
516                (Gbl_ExceptionCount[ASL_WARNING3] > 0))
517            {
518                return (AE_ERROR);
519            }
520        }
521    }
522
523    return (AE_OK);
524}
525