xref: /freebsd/sys/contrib/dev/acpica/compiler/aslascii.c (revision 313a0c13efa638cf248e35eed49f36ec0a1a7f26)
1*313a0c13SJung-uk Kim /******************************************************************************
2*313a0c13SJung-uk Kim  *
3*313a0c13SJung-uk Kim  * Module Name: aslascii - ASCII detection and support routines
4*313a0c13SJung-uk Kim  *
5*313a0c13SJung-uk Kim  *****************************************************************************/
6*313a0c13SJung-uk Kim 
7*313a0c13SJung-uk Kim /*
8*313a0c13SJung-uk Kim  * Copyright (C) 2000 - 2014, Intel Corp.
9*313a0c13SJung-uk Kim  * All rights reserved.
10*313a0c13SJung-uk Kim  *
11*313a0c13SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*313a0c13SJung-uk Kim  * modification, are permitted provided that the following conditions
13*313a0c13SJung-uk Kim  * are met:
14*313a0c13SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*313a0c13SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*313a0c13SJung-uk Kim  *    without modification.
17*313a0c13SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*313a0c13SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*313a0c13SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*313a0c13SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*313a0c13SJung-uk Kim  *    binary redistribution.
22*313a0c13SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*313a0c13SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*313a0c13SJung-uk Kim  *    from this software without specific prior written permission.
25*313a0c13SJung-uk Kim  *
26*313a0c13SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*313a0c13SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*313a0c13SJung-uk Kim  * Software Foundation.
29*313a0c13SJung-uk Kim  *
30*313a0c13SJung-uk Kim  * NO WARRANTY
31*313a0c13SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*313a0c13SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*313a0c13SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*313a0c13SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*313a0c13SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*313a0c13SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*313a0c13SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*313a0c13SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*313a0c13SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*313a0c13SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*313a0c13SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*313a0c13SJung-uk Kim  */
43*313a0c13SJung-uk Kim 
44*313a0c13SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
45*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/acapps.h>
46*313a0c13SJung-uk Kim 
47*313a0c13SJung-uk Kim #define _COMPONENT          ACPI_COMPILER
48*313a0c13SJung-uk Kim         ACPI_MODULE_NAME    ("aslascii")
49*313a0c13SJung-uk Kim 
50*313a0c13SJung-uk Kim 
51*313a0c13SJung-uk Kim /* Local prototypes */
52*313a0c13SJung-uk Kim 
53*313a0c13SJung-uk Kim static void
54*313a0c13SJung-uk Kim FlConsumeAnsiComment (
55*313a0c13SJung-uk Kim     FILE                    *Handle,
56*313a0c13SJung-uk Kim     ASL_FILE_STATUS         *Status);
57*313a0c13SJung-uk Kim 
58*313a0c13SJung-uk Kim static void
59*313a0c13SJung-uk Kim FlConsumeNewComment (
60*313a0c13SJung-uk Kim     FILE                    *Handle,
61*313a0c13SJung-uk Kim     ASL_FILE_STATUS         *Status);
62*313a0c13SJung-uk Kim 
63*313a0c13SJung-uk Kim 
64*313a0c13SJung-uk Kim /*******************************************************************************
65*313a0c13SJung-uk Kim  *
66*313a0c13SJung-uk Kim  * FUNCTION:    FlCheckForAcpiTable
67*313a0c13SJung-uk Kim  *
68*313a0c13SJung-uk Kim  * PARAMETERS:  Handle              - Open input file
69*313a0c13SJung-uk Kim  *
70*313a0c13SJung-uk Kim  * RETURN:      Status
71*313a0c13SJung-uk Kim  *
72*313a0c13SJung-uk Kim  * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
73*313a0c13SJung-uk Kim  *              following checks on what would be the table header:
74*313a0c13SJung-uk Kim  *              0) File must be at least as long as an ACPI_TABLE_HEADER
75*313a0c13SJung-uk Kim  *              1) The header length field must match the file size
76*313a0c13SJung-uk Kim  *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
77*313a0c13SJung-uk Kim  *
78*313a0c13SJung-uk Kim  ******************************************************************************/
79*313a0c13SJung-uk Kim 
80*313a0c13SJung-uk Kim ACPI_STATUS
81*313a0c13SJung-uk Kim FlCheckForAcpiTable (
82*313a0c13SJung-uk Kim     FILE                    *Handle)
83*313a0c13SJung-uk Kim {
84*313a0c13SJung-uk Kim     ACPI_TABLE_HEADER       Table;
85*313a0c13SJung-uk Kim     UINT32                  FileSize;
86*313a0c13SJung-uk Kim     size_t                  Actual;
87*313a0c13SJung-uk Kim     UINT32                  i;
88*313a0c13SJung-uk Kim 
89*313a0c13SJung-uk Kim 
90*313a0c13SJung-uk Kim     /* Read a potential table header */
91*313a0c13SJung-uk Kim 
92*313a0c13SJung-uk Kim     Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
93*313a0c13SJung-uk Kim     fseek (Handle, 0, SEEK_SET);
94*313a0c13SJung-uk Kim 
95*313a0c13SJung-uk Kim     if (Actual < sizeof (ACPI_TABLE_HEADER))
96*313a0c13SJung-uk Kim     {
97*313a0c13SJung-uk Kim         return (AE_ERROR);
98*313a0c13SJung-uk Kim     }
99*313a0c13SJung-uk Kim 
100*313a0c13SJung-uk Kim     /* Header length field must match the file size */
101*313a0c13SJung-uk Kim 
102*313a0c13SJung-uk Kim     FileSize = CmGetFileSize (Handle);
103*313a0c13SJung-uk Kim     if (Table.Length != FileSize)
104*313a0c13SJung-uk Kim     {
105*313a0c13SJung-uk Kim         return (AE_ERROR);
106*313a0c13SJung-uk Kim     }
107*313a0c13SJung-uk Kim 
108*313a0c13SJung-uk Kim     /*
109*313a0c13SJung-uk Kim      * These fields must be ASCII:
110*313a0c13SJung-uk Kim      * Signature, OemId, OemTableId, AslCompilerId.
111*313a0c13SJung-uk Kim      * We allow a NULL terminator in OemId and OemTableId.
112*313a0c13SJung-uk Kim      */
113*313a0c13SJung-uk Kim     for (i = 0; i < ACPI_NAME_SIZE; i++)
114*313a0c13SJung-uk Kim     {
115*313a0c13SJung-uk Kim         if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
116*313a0c13SJung-uk Kim         {
117*313a0c13SJung-uk Kim             return (AE_ERROR);
118*313a0c13SJung-uk Kim         }
119*313a0c13SJung-uk Kim 
120*313a0c13SJung-uk Kim         if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
121*313a0c13SJung-uk Kim         {
122*313a0c13SJung-uk Kim             return (AE_ERROR);
123*313a0c13SJung-uk Kim         }
124*313a0c13SJung-uk Kim     }
125*313a0c13SJung-uk Kim 
126*313a0c13SJung-uk Kim     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
127*313a0c13SJung-uk Kim     {
128*313a0c13SJung-uk Kim         if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
129*313a0c13SJung-uk Kim         {
130*313a0c13SJung-uk Kim             return (AE_ERROR);
131*313a0c13SJung-uk Kim         }
132*313a0c13SJung-uk Kim     }
133*313a0c13SJung-uk Kim 
134*313a0c13SJung-uk Kim     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
135*313a0c13SJung-uk Kim     {
136*313a0c13SJung-uk Kim         if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
137*313a0c13SJung-uk Kim         {
138*313a0c13SJung-uk Kim             return (AE_ERROR);
139*313a0c13SJung-uk Kim         }
140*313a0c13SJung-uk Kim     }
141*313a0c13SJung-uk Kim 
142*313a0c13SJung-uk Kim     printf ("Binary file appears to be a valid ACPI table, disassembling\n");
143*313a0c13SJung-uk Kim     return (AE_OK);
144*313a0c13SJung-uk Kim }
145*313a0c13SJung-uk Kim 
146*313a0c13SJung-uk Kim 
147*313a0c13SJung-uk Kim /*******************************************************************************
148*313a0c13SJung-uk Kim  *
149*313a0c13SJung-uk Kim  * FUNCTION:    FlCheckForAscii
150*313a0c13SJung-uk Kim  *
151*313a0c13SJung-uk Kim  * PARAMETERS:  Handle              - Open input file
152*313a0c13SJung-uk Kim  *              Filename            - Input filename
153*313a0c13SJung-uk Kim  *              DisplayErrors       - TRUE if error messages desired
154*313a0c13SJung-uk Kim  *
155*313a0c13SJung-uk Kim  * RETURN:      Status
156*313a0c13SJung-uk Kim  *
157*313a0c13SJung-uk Kim  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
158*313a0c13SJung-uk Kim  *              within comments. Note: does not handle nested comments and does
159*313a0c13SJung-uk Kim  *              not handle comment delimiters within string literals. However,
160*313a0c13SJung-uk Kim  *              on the rare chance this happens and an invalid character is
161*313a0c13SJung-uk Kim  *              missed, the parser will catch the error by failing in some
162*313a0c13SJung-uk Kim  *              spectactular manner.
163*313a0c13SJung-uk Kim  *
164*313a0c13SJung-uk Kim  ******************************************************************************/
165*313a0c13SJung-uk Kim 
166*313a0c13SJung-uk Kim ACPI_STATUS
167*313a0c13SJung-uk Kim FlCheckForAscii (
168*313a0c13SJung-uk Kim     FILE                    *Handle,
169*313a0c13SJung-uk Kim     char                    *Filename,
170*313a0c13SJung-uk Kim     BOOLEAN                 DisplayErrors)
171*313a0c13SJung-uk Kim {
172*313a0c13SJung-uk Kim     UINT8                   Byte;
173*313a0c13SJung-uk Kim     ACPI_SIZE               BadBytes = 0;
174*313a0c13SJung-uk Kim     BOOLEAN                 OpeningComment = FALSE;
175*313a0c13SJung-uk Kim     ASL_FILE_STATUS         Status;
176*313a0c13SJung-uk Kim 
177*313a0c13SJung-uk Kim 
178*313a0c13SJung-uk Kim     Status.Line = 1;
179*313a0c13SJung-uk Kim     Status.Offset = 0;
180*313a0c13SJung-uk Kim 
181*313a0c13SJung-uk Kim     /* Read the entire file */
182*313a0c13SJung-uk Kim 
183*313a0c13SJung-uk Kim     while (fread (&Byte, 1, 1, Handle) == 1)
184*313a0c13SJung-uk Kim     {
185*313a0c13SJung-uk Kim         /* Ignore comment fields (allow non-ascii within) */
186*313a0c13SJung-uk Kim 
187*313a0c13SJung-uk Kim         if (OpeningComment)
188*313a0c13SJung-uk Kim         {
189*313a0c13SJung-uk Kim             /* Check for second comment open delimiter */
190*313a0c13SJung-uk Kim 
191*313a0c13SJung-uk Kim             if (Byte == '*')
192*313a0c13SJung-uk Kim             {
193*313a0c13SJung-uk Kim                 FlConsumeAnsiComment (Handle, &Status);
194*313a0c13SJung-uk Kim             }
195*313a0c13SJung-uk Kim 
196*313a0c13SJung-uk Kim             if (Byte == '/')
197*313a0c13SJung-uk Kim             {
198*313a0c13SJung-uk Kim                 FlConsumeNewComment (Handle, &Status);
199*313a0c13SJung-uk Kim             }
200*313a0c13SJung-uk Kim 
201*313a0c13SJung-uk Kim             /* Reset */
202*313a0c13SJung-uk Kim 
203*313a0c13SJung-uk Kim             OpeningComment = FALSE;
204*313a0c13SJung-uk Kim         }
205*313a0c13SJung-uk Kim         else if (Byte == '/')
206*313a0c13SJung-uk Kim         {
207*313a0c13SJung-uk Kim             OpeningComment = TRUE;
208*313a0c13SJung-uk Kim         }
209*313a0c13SJung-uk Kim 
210*313a0c13SJung-uk Kim         /* Check for an ASCII character */
211*313a0c13SJung-uk Kim 
212*313a0c13SJung-uk Kim         if (!ACPI_IS_ASCII (Byte))
213*313a0c13SJung-uk Kim         {
214*313a0c13SJung-uk Kim             if ((BadBytes < 10) && (DisplayErrors))
215*313a0c13SJung-uk Kim             {
216*313a0c13SJung-uk Kim                 AcpiOsPrintf (
217*313a0c13SJung-uk Kim                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
218*313a0c13SJung-uk Kim                     Byte, Status.Line, Status.Offset);
219*313a0c13SJung-uk Kim             }
220*313a0c13SJung-uk Kim 
221*313a0c13SJung-uk Kim             BadBytes++;
222*313a0c13SJung-uk Kim         }
223*313a0c13SJung-uk Kim 
224*313a0c13SJung-uk Kim         /* Update line counter */
225*313a0c13SJung-uk Kim 
226*313a0c13SJung-uk Kim         else if (Byte == 0x0A)
227*313a0c13SJung-uk Kim         {
228*313a0c13SJung-uk Kim             Status.Line++;
229*313a0c13SJung-uk Kim         }
230*313a0c13SJung-uk Kim 
231*313a0c13SJung-uk Kim         Status.Offset++;
232*313a0c13SJung-uk Kim     }
233*313a0c13SJung-uk Kim 
234*313a0c13SJung-uk Kim     /* Seek back to the beginning of the source file */
235*313a0c13SJung-uk Kim 
236*313a0c13SJung-uk Kim     fseek (Handle, 0, SEEK_SET);
237*313a0c13SJung-uk Kim 
238*313a0c13SJung-uk Kim     /* Were there any non-ASCII characters in the file? */
239*313a0c13SJung-uk Kim 
240*313a0c13SJung-uk Kim     if (BadBytes)
241*313a0c13SJung-uk Kim     {
242*313a0c13SJung-uk Kim         if (DisplayErrors)
243*313a0c13SJung-uk Kim         {
244*313a0c13SJung-uk Kim             AcpiOsPrintf (
245*313a0c13SJung-uk Kim                 "%u non-ASCII characters found in input source text, could be a binary file\n",
246*313a0c13SJung-uk Kim                 BadBytes);
247*313a0c13SJung-uk Kim             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
248*313a0c13SJung-uk Kim         }
249*313a0c13SJung-uk Kim 
250*313a0c13SJung-uk Kim         return (AE_BAD_CHARACTER);
251*313a0c13SJung-uk Kim     }
252*313a0c13SJung-uk Kim 
253*313a0c13SJung-uk Kim     /* File is OK (100% ASCII) */
254*313a0c13SJung-uk Kim 
255*313a0c13SJung-uk Kim     return (AE_OK);
256*313a0c13SJung-uk Kim }
257*313a0c13SJung-uk Kim 
258*313a0c13SJung-uk Kim 
259*313a0c13SJung-uk Kim /*******************************************************************************
260*313a0c13SJung-uk Kim  *
261*313a0c13SJung-uk Kim  * FUNCTION:    FlConsumeAnsiComment
262*313a0c13SJung-uk Kim  *
263*313a0c13SJung-uk Kim  * PARAMETERS:  Handle              - Open input file
264*313a0c13SJung-uk Kim  *              Status              - File current status struct
265*313a0c13SJung-uk Kim  *
266*313a0c13SJung-uk Kim  * RETURN:      Number of lines consumed
267*313a0c13SJung-uk Kim  *
268*313a0c13SJung-uk Kim  * DESCRIPTION: Step over a normal slash-star type comment
269*313a0c13SJung-uk Kim  *
270*313a0c13SJung-uk Kim  ******************************************************************************/
271*313a0c13SJung-uk Kim 
272*313a0c13SJung-uk Kim static void
273*313a0c13SJung-uk Kim FlConsumeAnsiComment (
274*313a0c13SJung-uk Kim     FILE                    *Handle,
275*313a0c13SJung-uk Kim     ASL_FILE_STATUS         *Status)
276*313a0c13SJung-uk Kim {
277*313a0c13SJung-uk Kim     UINT8                   Byte;
278*313a0c13SJung-uk Kim     BOOLEAN                 ClosingComment = FALSE;
279*313a0c13SJung-uk Kim 
280*313a0c13SJung-uk Kim 
281*313a0c13SJung-uk Kim     while (fread (&Byte, 1, 1, Handle) == 1)
282*313a0c13SJung-uk Kim     {
283*313a0c13SJung-uk Kim         /* Scan until comment close is found */
284*313a0c13SJung-uk Kim 
285*313a0c13SJung-uk Kim         if (ClosingComment)
286*313a0c13SJung-uk Kim         {
287*313a0c13SJung-uk Kim             if (Byte == '/')
288*313a0c13SJung-uk Kim             {
289*313a0c13SJung-uk Kim                 return;
290*313a0c13SJung-uk Kim             }
291*313a0c13SJung-uk Kim 
292*313a0c13SJung-uk Kim             if (Byte != '*')
293*313a0c13SJung-uk Kim             {
294*313a0c13SJung-uk Kim                 /* Reset */
295*313a0c13SJung-uk Kim 
296*313a0c13SJung-uk Kim                 ClosingComment = FALSE;
297*313a0c13SJung-uk Kim             }
298*313a0c13SJung-uk Kim         }
299*313a0c13SJung-uk Kim         else if (Byte == '*')
300*313a0c13SJung-uk Kim         {
301*313a0c13SJung-uk Kim             ClosingComment = TRUE;
302*313a0c13SJung-uk Kim         }
303*313a0c13SJung-uk Kim 
304*313a0c13SJung-uk Kim         /* Maintain line count */
305*313a0c13SJung-uk Kim 
306*313a0c13SJung-uk Kim         if (Byte == 0x0A)
307*313a0c13SJung-uk Kim         {
308*313a0c13SJung-uk Kim             Status->Line++;
309*313a0c13SJung-uk Kim         }
310*313a0c13SJung-uk Kim 
311*313a0c13SJung-uk Kim         Status->Offset++;
312*313a0c13SJung-uk Kim     }
313*313a0c13SJung-uk Kim }
314*313a0c13SJung-uk Kim 
315*313a0c13SJung-uk Kim 
316*313a0c13SJung-uk Kim /*******************************************************************************
317*313a0c13SJung-uk Kim  *
318*313a0c13SJung-uk Kim  * FUNCTION:    FlConsumeNewComment
319*313a0c13SJung-uk Kim  *
320*313a0c13SJung-uk Kim  * PARAMETERS:  Handle              - Open input file
321*313a0c13SJung-uk Kim  *              Status              - File current status struct
322*313a0c13SJung-uk Kim  *
323*313a0c13SJung-uk Kim  * RETURN:      Number of lines consumed
324*313a0c13SJung-uk Kim  *
325*313a0c13SJung-uk Kim  * DESCRIPTION: Step over a slash-slash type of comment
326*313a0c13SJung-uk Kim  *
327*313a0c13SJung-uk Kim  ******************************************************************************/
328*313a0c13SJung-uk Kim 
329*313a0c13SJung-uk Kim static void
330*313a0c13SJung-uk Kim FlConsumeNewComment (
331*313a0c13SJung-uk Kim     FILE                    *Handle,
332*313a0c13SJung-uk Kim     ASL_FILE_STATUS         *Status)
333*313a0c13SJung-uk Kim {
334*313a0c13SJung-uk Kim     UINT8                   Byte;
335*313a0c13SJung-uk Kim 
336*313a0c13SJung-uk Kim 
337*313a0c13SJung-uk Kim     while (fread (&Byte, 1, 1, Handle) == 1)
338*313a0c13SJung-uk Kim     {
339*313a0c13SJung-uk Kim         Status->Offset++;
340*313a0c13SJung-uk Kim 
341*313a0c13SJung-uk Kim         /* Comment ends at newline */
342*313a0c13SJung-uk Kim 
343*313a0c13SJung-uk Kim         if (Byte == 0x0A)
344*313a0c13SJung-uk Kim         {
345*313a0c13SJung-uk Kim             Status->Line++;
346*313a0c13SJung-uk Kim             return;
347*313a0c13SJung-uk Kim         }
348*313a0c13SJung-uk Kim     }
349*313a0c13SJung-uk Kim }
350