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