aslstartup.c revision 229989
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_LineBufPtr = Gbl_CurrentLineBuffer;
99
100    Gbl_ErrorLog = NULL;
101    Gbl_NextError = NULL;
102    Gbl_Signature = NULL;
103    Gbl_FileType = 0;
104
105    AslGbl_NextEvent = 0;
106    for (i = 0; i < ASL_NUM_REPORT_LEVELS; i++)
107    {
108        Gbl_ExceptionCount[i] = 0;
109    }
110
111    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
112    Gbl_Files[ASL_FILE_AML_OUTPUT].Handle = NULL;
113
114    Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename = NULL;
115    Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle = NULL;
116}
117
118
119/******************************************************************************
120 *
121 * FUNCTION:    AsDoWildcard
122 *
123 * PARAMETERS:  None
124 *
125 * RETURN:      None
126 *
127 * DESCRIPTION: Process files via wildcards. This function is for the Windows
128 *              case only.
129 *
130 ******************************************************************************/
131
132static char **
133AsDoWildcard (
134    char                    *DirectoryPathname,
135    char                    *FileSpecifier)
136{
137#ifdef WIN32
138    void                    *DirInfo;
139    char                    *Filename;
140    int                     FileCount;
141
142
143    FileCount = 0;
144
145    /* Open parent directory */
146
147    DirInfo = AcpiOsOpenDirectory (DirectoryPathname, FileSpecifier, REQUEST_FILE_ONLY);
148    if (!DirInfo)
149    {
150        /* Either the directory of file does not exist */
151
152        Gbl_Files[ASL_FILE_INPUT].Filename = FileSpecifier;
153        FlFileError (ASL_FILE_INPUT, ASL_MSG_OPEN);
154        AslAbort ();
155    }
156
157    /* Process each file that matches the wildcard specification */
158
159    while ((Filename = AcpiOsGetNextFilename (DirInfo)))
160    {
161        /* Add the filename to the file list */
162
163        FileList[FileCount] = AcpiOsAllocate (strlen (Filename) + 1);
164        strcpy (FileList[FileCount], Filename);
165        FileCount++;
166
167        if (FileCount >= ASL_MAX_FILES)
168        {
169            printf ("Max files reached\n");
170            FileList[0] = NULL;
171            return (FileList);
172        }
173    }
174
175    /* Cleanup */
176
177    AcpiOsCloseDirectory (DirInfo);
178    FileList[FileCount] = NULL;
179    return (FileList);
180
181#else
182    /*
183     * Linux/Unix cases - Wildcards are expanded by the shell automatically.
184     * Just return the filename in a null terminated list
185     */
186    FileList[0] = AcpiOsAllocate (strlen (FileSpecifier) + 1);
187    strcpy (FileList[0], FileSpecifier);
188    FileList[1] = NULL;
189
190    return (FileList);
191#endif
192}
193
194
195/*******************************************************************************
196 *
197 * FUNCTION:    AslDetectSourceFileType
198 *
199 * PARAMETERS:  Info            - Name/Handle for the file (must be open)
200 *
201 * RETURN:      File Type
202 *
203 * DESCRIPTION: Determine the type of the input file. Either binary (contains
204 *              non-ASCII characters), ASL file, or an ACPI Data Table file.
205 *
206 ******************************************************************************/
207
208static UINT8
209AslDetectSourceFileType (
210    ASL_FILE_INFO           *Info)
211{
212    char                    *FileChar;
213    UINT8                   Type;
214    ACPI_STATUS             Status;
215
216
217    /* Check for 100% ASCII source file (comments are ignored) */
218
219    Status = FlCheckForAscii (Info);
220    if (ACPI_FAILURE (Status))
221    {
222        printf ("Non-ascii input file - %s\n", Info->Filename);
223        Type = ASL_INPUT_TYPE_BINARY;
224        goto Cleanup;
225    }
226
227    /*
228     * File is ASCII. Determine if this is an ASL file or an ACPI data
229     * table file.
230     */
231    while (fgets (Gbl_CurrentLineBuffer, ASL_LINE_BUFFER_SIZE, Info->Handle))
232    {
233        /* Uppercase the buffer for caseless compare */
234
235        FileChar = Gbl_CurrentLineBuffer;
236        while (*FileChar)
237        {
238            *FileChar = (char) toupper ((int) *FileChar);
239            FileChar++;
240        }
241
242        /* Presence of "DefinitionBlock" indicates actual ASL code */
243
244        if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK"))
245        {
246            /* Appears to be an ASL file */
247
248            Type = ASL_INPUT_TYPE_ASCII_ASL;
249            goto Cleanup;
250        }
251    }
252
253    /* Not an ASL source file, default to a data table source file */
254
255    Type = ASL_INPUT_TYPE_ASCII_DATA;
256
257Cleanup:
258
259    /* Must seek back to the start of the file */
260
261    fseek (Info->Handle, 0, SEEK_SET);
262    return (Type);
263}
264
265
266/*******************************************************************************
267 *
268 * FUNCTION:    AslDoOneFile
269 *
270 * PARAMETERS:  Filename        - Name of the file
271 *
272 * RETURN:      Status
273 *
274 * DESCRIPTION: Process a single file - either disassemble, compile, or both
275 *
276 ******************************************************************************/
277
278ACPI_STATUS
279AslDoOneFile (
280    char                    *Filename)
281{
282    ACPI_STATUS             Status;
283
284
285    Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
286
287    /* Re-initialize "some" compiler globals */
288
289    AslInitializeGlobals ();
290
291    /*
292     * AML Disassembly (Optional)
293     */
294    if (Gbl_DisasmFlag || Gbl_GetAllTables)
295    {
296        /* ACPICA subsystem initialization */
297
298        Status = AdInitialize ();
299        if (ACPI_FAILURE (Status))
300        {
301            return (Status);
302        }
303
304        Status = AcpiAllocateRootTable (4);
305        if (ACPI_FAILURE (Status))
306        {
307            AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n",
308                AcpiFormatException (Status));
309            return (Status);
310        }
311
312        /* This is where the disassembly happens */
313
314        AcpiGbl_DbOpt_disasm = TRUE;
315        Status = AdAmlDisassemble (AslToFile,
316                    Gbl_Files[ASL_FILE_INPUT].Filename,
317                    Gbl_OutputFilenamePrefix,
318                    &Gbl_Files[ASL_FILE_INPUT].Filename,
319                    Gbl_GetAllTables);
320        if (ACPI_FAILURE (Status))
321        {
322            return (Status);
323        }
324
325        /* Shutdown compiler and ACPICA subsystem */
326
327        AeClearErrorLog ();
328        (void) AcpiTerminate ();
329
330        /*
331         * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the
332         * .DSL disassembly file, which can now be compiled if requested
333         */
334        if (Gbl_DoCompile)
335        {
336            AcpiOsPrintf ("\nCompiling \"%s\"\n",
337                Gbl_Files[ASL_FILE_INPUT].Filename);
338        }
339        else
340        {
341            Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
342            return (AE_OK);
343        }
344    }
345
346    /*
347     * Open the input file. Here, this should be an ASCII source file,
348     * either an ASL file or a Data Table file
349     */
350    Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
351    if (ACPI_FAILURE (Status))
352    {
353        AePrintErrorLog (ASL_FILE_STDERR);
354        return (AE_ERROR);
355    }
356
357    /* Determine input file type */
358
359    Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
360    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
361    {
362        return (AE_ERROR);
363    }
364
365    /*
366     * If -p not specified, we will use the input filename as the
367     * output filename prefix
368     */
369    if (Gbl_UseDefaultAmlFilename)
370    {
371        Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
372    }
373
374    /* Open the optional output files (listings, etc.) */
375
376    Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
377    if (ACPI_FAILURE (Status))
378    {
379        AePrintErrorLog (ASL_FILE_STDERR);
380        return (AE_ERROR);
381    }
382
383    /*
384     * Compilation of ASL source versus DataTable source uses different
385     * compiler subsystems
386     */
387    switch (Gbl_FileType)
388    {
389    /*
390     * Data Table Compilation
391     */
392    case ASL_INPUT_TYPE_ASCII_DATA:
393
394        Status = DtDoCompile ();
395
396        if (Gbl_Signature)
397        {
398            ACPI_FREE (Gbl_Signature);
399            Gbl_Signature = NULL;
400        }
401        AeClearErrorLog ();
402        return (Status);
403
404    /*
405     * ASL Compilation (Optional)
406     */
407    case ASL_INPUT_TYPE_ASCII_ASL:
408
409        /* ACPICA subsystem initialization */
410
411        Status = AdInitialize ();
412        if (ACPI_FAILURE (Status))
413        {
414            return (Status);
415        }
416
417        Status = CmDoCompile ();
418        (void) AcpiTerminate ();
419
420        /*
421         * Return non-zero exit code if there have been errors, unless the
422         * global ignore error flag has been set
423         */
424        if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
425        {
426            return (AE_ERROR);
427        }
428
429        AeClearErrorLog ();
430        return (AE_OK);
431
432    case ASL_INPUT_TYPE_BINARY:
433
434        AePrintErrorLog (ASL_FILE_STDERR);
435        return (AE_ERROR);
436
437    default:
438        printf ("Unknown file type %X\n", Gbl_FileType);
439        return (AE_ERROR);
440    }
441}
442
443
444/*******************************************************************************
445 *
446 * FUNCTION:    AslDoOnePathname
447 *
448 * PARAMETERS:  Pathname            - Full pathname, possibly with wildcards
449 *
450 * RETURN:      Status
451 *
452 * DESCRIPTION: Process one pathname, possible terminated with a wildcard
453 *              specification. If a wildcard, it is expanded and the multiple
454 *              files are processed.
455 *
456 ******************************************************************************/
457
458ACPI_STATUS
459AslDoOnePathname (
460    char                    *Pathname,
461    ASL_PATHNAME_CALLBACK   PathCallback)
462{
463    ACPI_STATUS             Status = AE_OK;
464    char                    **WildcardList;
465    char                    *Filename;
466    char                    *FullPathname;
467
468
469    /* Split incoming path into a directory/filename combo */
470
471    Status = FlSplitInputPathname (Pathname, &Gbl_DirectoryPath, &Filename);
472    if (ACPI_FAILURE (Status))
473    {
474        return (Status);
475    }
476
477    /* Expand possible wildcard into a file list (Windows/DOS only) */
478
479    WildcardList = AsDoWildcard (Gbl_DirectoryPath, Filename);
480    while (*WildcardList)
481    {
482        FullPathname = ACPI_ALLOCATE (
483            strlen (Gbl_DirectoryPath) + strlen (*WildcardList) + 1);
484
485        /* Construct a full path to the file */
486
487        strcpy (FullPathname, Gbl_DirectoryPath);
488        strcat (FullPathname, *WildcardList);
489
490        /*
491         * If -p not specified, we will use the input filename as the
492         * output filename prefix
493         */
494        if (Gbl_UseDefaultAmlFilename)
495        {
496            Gbl_OutputFilenamePrefix = FullPathname;
497        }
498
499        /* Save status from all compiles */
500
501        Status |= (*PathCallback) (FullPathname);
502
503        ACPI_FREE (FullPathname);
504        ACPI_FREE (*WildcardList);
505        *WildcardList = NULL;
506        WildcardList++;
507    }
508
509    ACPI_FREE (Gbl_DirectoryPath);
510    ACPI_FREE (Filename);
511    return (Status);
512}
513
514