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