aslstartup.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: aslstartup - Compiler startup routines, called from main
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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 = ASL_INPUT_TYPE_ASCII_DATA; /* default */
148    ACPI_STATUS             Status;
149
150
151    /* Check for 100% ASCII source file (comments are ignored) */
152
153    Status = FlIsFileAsciiSource (Info->Filename, FALSE);
154    if (ACPI_SUCCESS (Status))
155    {
156        /*
157         * File contains ASCII source code. Determine if this is an ASL
158         * file or an ACPI data table file.
159         */
160        while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle))
161        {
162            /* Uppercase the buffer for caseless compare */
163
164            FileChar = Gbl_CurrentLineBuffer;
165            while (*FileChar)
166            {
167                *FileChar = (char) toupper ((int) *FileChar);
168                FileChar++;
169            }
170
171            /* Presence of "DefinitionBlock" indicates actual ASL code */
172
173            if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK"))
174            {
175                /* Appears to be an ASL file */
176
177                Type = ASL_INPUT_TYPE_ASCII_ASL;
178                goto Cleanup;
179            }
180        }
181
182        /* Appears to be an ASCII data table source file */
183
184        Type = ASL_INPUT_TYPE_ASCII_DATA;
185        goto Cleanup;
186    }
187
188    /* We have some sort of binary table, check for valid ACPI table */
189
190    fseek (Info->Handle, 0, SEEK_SET);
191
192    Status = AcValidateTableHeader (Info->Handle, 0);
193    if (ACPI_SUCCESS (Status))
194    {
195        fprintf (stderr,
196            "Binary file appears to be a valid ACPI table, disassembling\n");
197
198        Type = ASL_INPUT_TYPE_BINARY_ACPI_TABLE;
199        goto Cleanup;
200    }
201
202    Type = ASL_INPUT_TYPE_BINARY;
203
204
205Cleanup:
206
207    /* Must seek back to the start of the file */
208
209    fseek (Info->Handle, 0, SEEK_SET);
210    return (Type);
211}
212
213
214/*******************************************************************************
215 *
216 * FUNCTION:    AslDoDisassembly
217 *
218 * PARAMETERS:  None
219 *
220 * RETURN:      Status
221 *
222 * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build
223 *              namespace.
224 *
225 ******************************************************************************/
226
227static ACPI_STATUS
228AslDoDisassembly (
229    void)
230{
231    ACPI_STATUS             Status;
232
233
234    /* ACPICA subsystem initialization */
235
236    Status = AdInitialize ();
237    if (ACPI_FAILURE (Status))
238    {
239        return (Status);
240    }
241
242    Status = AcpiAllocateRootTable (4);
243    if (ACPI_FAILURE (Status))
244    {
245        AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n",
246            AcpiFormatException (Status));
247        return (Status);
248    }
249
250    /* Handle additional output files for disassembler */
251
252    Gbl_FileType = ASL_INPUT_TYPE_BINARY_ACPI_TABLE;
253    Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
254
255    /* This is where the disassembly happens */
256
257    AcpiGbl_DmOpt_Disasm = TRUE;
258    Status = AdAmlDisassemble (AslToFile,
259        Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_OutputFilenamePrefix,
260        &Gbl_Files[ASL_FILE_INPUT].Filename);
261    if (ACPI_FAILURE (Status))
262    {
263        return (Status);
264    }
265
266    /* Check if any control methods were unresolved */
267
268    AcpiDmUnresolvedWarning (0);
269
270    /* Shutdown compiler and ACPICA subsystem */
271
272    AeClearErrorLog ();
273    (void) AcpiTerminate ();
274
275    /*
276     * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the
277     * .DSL disassembly file, which can now be compiled if requested
278     */
279    if (Gbl_DoCompile)
280    {
281        AcpiOsPrintf ("\nCompiling \"%s\"\n",
282            Gbl_Files[ASL_FILE_INPUT].Filename);
283        return (AE_CTRL_CONTINUE);
284    }
285
286    /* No need to free the filename string */
287
288    Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
289
290    CmDeleteCaches ();
291    return (AE_OK);
292}
293
294
295/*******************************************************************************
296 *
297 * FUNCTION:    AslDoOneFile
298 *
299 * PARAMETERS:  Filename        - Name of the file
300 *
301 * RETURN:      Status
302 *
303 * DESCRIPTION: Process a single file - either disassemble, compile, or both
304 *
305 ******************************************************************************/
306
307ACPI_STATUS
308AslDoOneFile (
309    char                    *Filename)
310{
311    ACPI_STATUS             Status;
312
313
314    /* Re-initialize "some" compiler/preprocessor globals */
315
316    AslInitializeGlobals ();
317    PrInitializeGlobals ();
318
319    /*
320     * Extract the directory path. This path is used for possible include
321     * files and the optional AML filename embedded in the input file
322     * DefinitionBlock declaration.
323     */
324    Status = FlSplitInputPathname (Filename, &Gbl_DirectoryPath, NULL);
325    if (ACPI_FAILURE (Status))
326    {
327        return (Status);
328    }
329
330    /* Take a copy of the input filename, convert any backslashes */
331
332    Gbl_Files[ASL_FILE_INPUT].Filename =
333        UtStringCacheCalloc (strlen (Filename) + 1);
334
335    strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
336    UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename);
337
338    /*
339     * AML Disassembly (Optional)
340     */
341    if (Gbl_DisasmFlag)
342    {
343        Status = AslDoDisassembly ();
344        if (Status != AE_CTRL_CONTINUE)
345        {
346            return (Status);
347        }
348    }
349
350    /*
351     * Open the input file. Here, this should be an ASCII source file,
352     * either an ASL file or a Data Table file
353     */
354    Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
355    if (ACPI_FAILURE (Status))
356    {
357        AePrintErrorLog (ASL_FILE_STDERR);
358        return (AE_ERROR);
359    }
360
361    Gbl_OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT);
362
363    /* Determine input file type */
364
365    Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
366    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
367    {
368        return (AE_ERROR);
369    }
370
371    /*
372     * If -p not specified, we will use the input filename as the
373     * output filename prefix
374     */
375    if (Gbl_UseDefaultAmlFilename)
376    {
377        Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
378    }
379
380    /* Open the optional output files (listings, etc.) */
381
382    Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
383    if (ACPI_FAILURE (Status))
384    {
385        AePrintErrorLog (ASL_FILE_STDERR);
386        return (AE_ERROR);
387    }
388
389    /*
390     * Compilation of ASL source versus DataTable source uses different
391     * compiler subsystems
392     */
393    switch (Gbl_FileType)
394    {
395    /*
396     * Data Table Compilation
397     */
398    case ASL_INPUT_TYPE_ASCII_DATA:
399
400        Status = DtDoCompile ();
401        if (ACPI_FAILURE (Status))
402        {
403            return (Status);
404        }
405
406        if (Gbl_Signature)
407        {
408            Gbl_Signature = NULL;
409        }
410
411        /* Check if any errors occurred during compile */
412
413        Status = AslCheckForErrorExit ();
414        if (ACPI_FAILURE (Status))
415        {
416            return (Status);
417        }
418
419        /* Cleanup (for next source file) and exit */
420
421        AeClearErrorLog ();
422        PrTerminatePreprocessor ();
423        return (Status);
424
425    /*
426     * ASL Compilation
427     */
428    case ASL_INPUT_TYPE_ASCII_ASL:
429
430        /* ACPICA subsystem initialization */
431
432        Status = AdInitialize ();
433        if (ACPI_FAILURE (Status))
434        {
435            return (Status);
436        }
437
438        (void) CmDoCompile ();
439        (void) AcpiTerminate ();
440
441        /* Check if any errors occurred during compile */
442
443        Status = AslCheckForErrorExit ();
444        if (ACPI_FAILURE (Status))
445        {
446            return (Status);
447        }
448
449        /* Cleanup (for next source file) and exit */
450
451        AeClearErrorLog ();
452        PrTerminatePreprocessor ();
453        return (AE_OK);
454
455    /*
456     * Binary ACPI table was auto-detected, disassemble it
457     */
458    case ASL_INPUT_TYPE_BINARY_ACPI_TABLE:
459
460        /* We have what appears to be an ACPI table, disassemble it */
461
462        FlCloseFile (ASL_FILE_INPUT);
463        Gbl_DoCompile = FALSE;
464        Gbl_DisasmFlag = TRUE;
465        Status = AslDoDisassembly ();
466        return (Status);
467
468    /* Unknown binary table */
469
470    case ASL_INPUT_TYPE_BINARY:
471
472        AePrintErrorLog (ASL_FILE_STDERR);
473        return (AE_ERROR);
474
475    default:
476
477        printf ("Unknown file type %X\n", Gbl_FileType);
478        return (AE_ERROR);
479    }
480}
481
482
483/*******************************************************************************
484 *
485 * FUNCTION:    AslCheckForErrorExit
486 *
487 * PARAMETERS:  None. Examines global exception count array
488 *
489 * RETURN:      Status
490 *
491 * DESCRIPTION: Determine if compiler should abort with error status
492 *
493 ******************************************************************************/
494
495ACPI_STATUS
496AslCheckForErrorExit (
497    void)
498{
499
500    /*
501     * Return non-zero exit code if there have been errors, unless the
502     * global ignore error flag has been set
503     */
504    if (!Gbl_IgnoreErrors)
505    {
506        if (Gbl_ExceptionCount[ASL_ERROR] > 0)
507        {
508            return (AE_ERROR);
509        }
510
511        /* Optionally treat warnings as errors */
512
513        if (Gbl_WarningsAsErrors)
514        {
515            if ((Gbl_ExceptionCount[ASL_WARNING] > 0)  ||
516                (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
517                (Gbl_ExceptionCount[ASL_WARNING3] > 0))
518            {
519                return (AE_ERROR);
520            }
521        }
522    }
523
524    return (AE_OK);
525}
526