aslstartup.c revision 243347
1/******************************************************************************
2 *
3 * Module Name: aslstartup - Compiler startup routines, called from main
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
46#include <contrib/dev/acpica/include/actables.h>
47#include <contrib/dev/acpica/include/acapps.h>
48
49#define _COMPONENT          ACPI_COMPILER
50        ACPI_MODULE_NAME    ("aslstartup")
51
52
53#define ASL_MAX_FILES   256
54static char             *FileList[ASL_MAX_FILES];
55static BOOLEAN          AslToFile = TRUE;
56
57
58/* Local prototypes */
59
60static char **
61AsDoWildcard (
62    char                    *DirectoryPathname,
63    char                    *FileSpecifier);
64
65static UINT8
66AslDetectSourceFileType (
67    ASL_FILE_INFO           *Info);
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
83void
84AslInitializeGlobals (
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:    AsDoWildcard
132 *
133 * PARAMETERS:  None
134 *
135 * RETURN:      None
136 *
137 * DESCRIPTION: Process files via wildcards. This function is for the Windows
138 *              case only.
139 *
140 ******************************************************************************/
141
142static char **
143AsDoWildcard (
144    char                    *DirectoryPathname,
145    char                    *FileSpecifier)
146{
147#ifdef WIN32
148    void                    *DirInfo;
149    char                    *Filename;
150    int                     FileCount;
151
152
153    FileCount = 0;
154
155    /* Open parent directory */
156
157    DirInfo = AcpiOsOpenDirectory (DirectoryPathname, FileSpecifier, REQUEST_FILE_ONLY);
158    if (!DirInfo)
159    {
160        /* Either the directory of file does not exist */
161
162        Gbl_Files[ASL_FILE_INPUT].Filename = FileSpecifier;
163        FlFileError (ASL_FILE_INPUT, ASL_MSG_OPEN);
164        AslAbort ();
165    }
166
167    /* Process each file that matches the wildcard specification */
168
169    while ((Filename = AcpiOsGetNextFilename (DirInfo)))
170    {
171        /* Add the filename to the file list */
172
173        FileList[FileCount] = AcpiOsAllocate (strlen (Filename) + 1);
174        strcpy (FileList[FileCount], Filename);
175        FileCount++;
176
177        if (FileCount >= ASL_MAX_FILES)
178        {
179            printf ("Max files reached\n");
180            FileList[0] = NULL;
181            return (FileList);
182        }
183    }
184
185    /* Cleanup */
186
187    AcpiOsCloseDirectory (DirInfo);
188    FileList[FileCount] = NULL;
189    return (FileList);
190
191#else
192    /*
193     * Linux/Unix cases - Wildcards are expanded by the shell automatically.
194     * Just return the filename in a null terminated list
195     */
196    FileList[0] = AcpiOsAllocate (strlen (FileSpecifier) + 1);
197    strcpy (FileList[0], FileSpecifier);
198    FileList[1] = NULL;
199
200    return (FileList);
201#endif
202}
203
204
205/*******************************************************************************
206 *
207 * FUNCTION:    AslDetectSourceFileType
208 *
209 * PARAMETERS:  Info            - Name/Handle for the file (must be open)
210 *
211 * RETURN:      File Type
212 *
213 * DESCRIPTION: Determine the type of the input file. Either binary (contains
214 *              non-ASCII characters), ASL file, or an ACPI Data Table file.
215 *
216 ******************************************************************************/
217
218static UINT8
219AslDetectSourceFileType (
220    ASL_FILE_INFO           *Info)
221{
222    char                    *FileChar;
223    UINT8                   Type;
224    ACPI_STATUS             Status;
225
226
227    /* Check for 100% ASCII source file (comments are ignored) */
228
229    Status = FlCheckForAscii (Info->Handle, Info->Filename, TRUE);
230    if (ACPI_FAILURE (Status))
231    {
232        printf ("Non-ascii input file - %s\n", Info->Filename);
233
234        if (!Gbl_IgnoreErrors)
235        {
236            Type = ASL_INPUT_TYPE_BINARY;
237            goto Cleanup;
238        }
239    }
240
241    /*
242     * File is ASCII. Determine if this is an ASL file or an ACPI data
243     * table file.
244     */
245    while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle))
246    {
247        /* Uppercase the buffer for caseless compare */
248
249        FileChar = Gbl_CurrentLineBuffer;
250        while (*FileChar)
251        {
252            *FileChar = (char) toupper ((int) *FileChar);
253            FileChar++;
254        }
255
256        /* Presence of "DefinitionBlock" indicates actual ASL code */
257
258        if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK"))
259        {
260            /* Appears to be an ASL file */
261
262            Type = ASL_INPUT_TYPE_ASCII_ASL;
263            goto Cleanup;
264        }
265    }
266
267    /* Not an ASL source file, default to a data table source file */
268
269    Type = ASL_INPUT_TYPE_ASCII_DATA;
270
271Cleanup:
272
273    /* Must seek back to the start of the file */
274
275    fseek (Info->Handle, 0, SEEK_SET);
276    return (Type);
277}
278
279
280/*******************************************************************************
281 *
282 * FUNCTION:    AslDoOneFile
283 *
284 * PARAMETERS:  Filename        - Name of the file
285 *
286 * RETURN:      Status
287 *
288 * DESCRIPTION: Process a single file - either disassemble, compile, or both
289 *
290 ******************************************************************************/
291
292ACPI_STATUS
293AslDoOneFile (
294    char                    *Filename)
295{
296    ACPI_STATUS             Status;
297
298
299    /* Re-initialize "some" compiler/preprocessor globals */
300
301    AslInitializeGlobals ();
302    PrInitializeGlobals ();
303
304    Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
305
306    /*
307     * AML Disassembly (Optional)
308     */
309    if (Gbl_DisasmFlag || Gbl_GetAllTables)
310    {
311        /* ACPICA subsystem initialization */
312
313        Status = AdInitialize ();
314        if (ACPI_FAILURE (Status))
315        {
316            return (Status);
317        }
318
319        Status = AcpiAllocateRootTable (4);
320        if (ACPI_FAILURE (Status))
321        {
322            AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n",
323                AcpiFormatException (Status));
324            return (Status);
325        }
326
327        /* This is where the disassembly happens */
328
329        AcpiGbl_DbOpt_disasm = TRUE;
330        Status = AdAmlDisassemble (AslToFile,
331                    Gbl_Files[ASL_FILE_INPUT].Filename,
332                    Gbl_OutputFilenamePrefix,
333                    &Gbl_Files[ASL_FILE_INPUT].Filename,
334                    Gbl_GetAllTables);
335        if (ACPI_FAILURE (Status))
336        {
337            return (Status);
338        }
339
340#if 0
341        /* TBD: Handle additional output files for disassembler */
342
343        Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
344        LsDisplayNamespace ();
345#endif
346
347        /* Shutdown compiler and ACPICA subsystem */
348
349        AeClearErrorLog ();
350        (void) AcpiTerminate ();
351
352        /*
353         * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the
354         * .DSL disassembly file, which can now be compiled if requested
355         */
356        if (Gbl_DoCompile)
357        {
358            AcpiOsPrintf ("\nCompiling \"%s\"\n",
359                Gbl_Files[ASL_FILE_INPUT].Filename);
360        }
361        else
362        {
363            Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
364            return (AE_OK);
365        }
366    }
367
368    /*
369     * Open the input file. Here, this should be an ASCII source file,
370     * either an ASL file or a Data Table file
371     */
372    Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
373    if (ACPI_FAILURE (Status))
374    {
375        AePrintErrorLog (ASL_FILE_STDERR);
376        return (AE_ERROR);
377    }
378
379    /* Determine input file type */
380
381    Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
382    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
383    {
384        return (AE_ERROR);
385    }
386
387    /*
388     * If -p not specified, we will use the input filename as the
389     * output filename prefix
390     */
391    if (Gbl_UseDefaultAmlFilename)
392    {
393        Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
394    }
395
396    /* Open the optional output files (listings, etc.) */
397
398    Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
399    if (ACPI_FAILURE (Status))
400    {
401        AePrintErrorLog (ASL_FILE_STDERR);
402        return (AE_ERROR);
403    }
404
405    /*
406     * Compilation of ASL source versus DataTable source uses different
407     * compiler subsystems
408     */
409    switch (Gbl_FileType)
410    {
411    /*
412     * Data Table Compilation
413     */
414    case ASL_INPUT_TYPE_ASCII_DATA:
415
416        Status = DtDoCompile ();
417        if (ACPI_FAILURE (Status))
418        {
419            return (Status);
420        }
421
422        if (Gbl_Signature)
423        {
424            ACPI_FREE (Gbl_Signature);
425            Gbl_Signature = NULL;
426        }
427
428        /* Check if any errors occurred during compile */
429
430        Status = AslCheckForErrorExit ();
431        if (ACPI_FAILURE (Status))
432        {
433            return (Status);
434        }
435
436        /* Cleanup (for next source file) and exit */
437
438        AeClearErrorLog ();
439        PrTerminatePreprocessor ();
440        return (Status);
441
442    /*
443     * ASL Compilation
444     */
445    case ASL_INPUT_TYPE_ASCII_ASL:
446
447        /* ACPICA subsystem initialization */
448
449        Status = AdInitialize ();
450        if (ACPI_FAILURE (Status))
451        {
452            return (Status);
453        }
454
455        (void) CmDoCompile ();
456        (void) AcpiTerminate ();
457
458        /* Check if any errors occurred during compile */
459
460        Status = AslCheckForErrorExit ();
461        if (ACPI_FAILURE (Status))
462        {
463            return (Status);
464        }
465
466        /* Cleanup (for next source file) and exit */
467
468        AeClearErrorLog ();
469        PrTerminatePreprocessor ();
470        return (AE_OK);
471
472    case ASL_INPUT_TYPE_BINARY:
473
474        AePrintErrorLog (ASL_FILE_STDERR);
475        return (AE_ERROR);
476
477    default:
478        printf ("Unknown file type %X\n", Gbl_FileType);
479        return (AE_ERROR);
480    }
481}
482
483
484/*******************************************************************************
485 *
486 * FUNCTION:    AslDoOnePathname
487 *
488 * PARAMETERS:  Pathname            - Full pathname, possibly with wildcards
489 *
490 * RETURN:      Status
491 *
492 * DESCRIPTION: Process one pathname, possible terminated with a wildcard
493 *              specification. If a wildcard, it is expanded and the multiple
494 *              files are processed.
495 *
496 ******************************************************************************/
497
498ACPI_STATUS
499AslDoOnePathname (
500    char                    *Pathname,
501    ASL_PATHNAME_CALLBACK   PathCallback)
502{
503    ACPI_STATUS             Status = AE_OK;
504    char                    **WildcardList;
505    char                    *Filename;
506    char                    *FullPathname;
507
508
509    /* Split incoming path into a directory/filename combo */
510
511    Status = FlSplitInputPathname (Pathname, &Gbl_DirectoryPath, &Filename);
512    if (ACPI_FAILURE (Status))
513    {
514        return (Status);
515    }
516
517    /* Expand possible wildcard into a file list (Windows/DOS only) */
518
519    WildcardList = AsDoWildcard (Gbl_DirectoryPath, Filename);
520    while (*WildcardList)
521    {
522        FullPathname = ACPI_ALLOCATE (
523            strlen (Gbl_DirectoryPath) + strlen (*WildcardList) + 1);
524
525        /* Construct a full path to the file */
526
527        strcpy (FullPathname, Gbl_DirectoryPath);
528        strcat (FullPathname, *WildcardList);
529
530        /*
531         * If -p not specified, we will use the input filename as the
532         * output filename prefix
533         */
534        if (Gbl_UseDefaultAmlFilename)
535        {
536            Gbl_OutputFilenamePrefix = FullPathname;
537        }
538
539        /* Save status from all compiles */
540
541        Status |= (*PathCallback) (FullPathname);
542
543        ACPI_FREE (FullPathname);
544        ACPI_FREE (*WildcardList);
545        *WildcardList = NULL;
546        WildcardList++;
547    }
548
549    ACPI_FREE (Gbl_DirectoryPath);
550    ACPI_FREE (Filename);
551    return (Status);
552}
553
554
555/*******************************************************************************
556 *
557 * FUNCTION:    AslCheckForErrorExit
558 *
559 * PARAMETERS:  None. Examines global exception count array
560 *
561 * RETURN:      Status
562 *
563 * DESCRIPTION: Determine if compiler should abort with error status
564 *
565 ******************************************************************************/
566
567ACPI_STATUS
568AslCheckForErrorExit (
569    void)
570{
571
572    /*
573     * Return non-zero exit code if there have been errors, unless the
574     * global ignore error flag has been set
575     */
576    if (!Gbl_IgnoreErrors)
577    {
578        if (Gbl_ExceptionCount[ASL_ERROR] > 0)
579        {
580            return (AE_ERROR);
581        }
582
583        /* Optionally treat warnings as errors */
584
585        if (Gbl_WarningsAsErrors)
586        {
587            if ((Gbl_ExceptionCount[ASL_WARNING] > 0)  ||
588                (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
589                (Gbl_ExceptionCount[ASL_WARNING3] > 0))
590            {
591                return (AE_ERROR);
592            }
593        }
594    }
595
596    return (AE_OK);
597}
598