xref: /freebsd/sys/contrib/dev/acpica/compiler/aslstartup.c (revision 884a2a699669ec61e2366e3e358342dbc94be24a)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslstartup - Compiler startup routines, called from main
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2011, 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_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 
132 static char **
133 AsDoWildcard (
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 
208 static UINT8
209 AslDetectSourceFileType (
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 
257 Cleanup:
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 
278 ACPI_STATUS
279 AslDoOneFile (
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 
458 ACPI_STATUS
459 AslDoOnePathname (
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