1 /****************************************************************************** 2 * 3 * Module Name: aslascii - ASCII detection and support routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 #include <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/include/acapps.h> 46 47 #define _COMPONENT ACPI_COMPILER 48 ACPI_MODULE_NAME ("aslascii") 49 50 51 /* Local prototypes */ 52 53 static void 54 FlConsumeAnsiComment ( 55 FILE *Handle, 56 ASL_FILE_STATUS *Status); 57 58 static void 59 FlConsumeNewComment ( 60 FILE *Handle, 61 ASL_FILE_STATUS *Status); 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: FlCheckForAcpiTable 67 * 68 * PARAMETERS: Handle - Open input file 69 * 70 * RETURN: Status 71 * 72 * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the 73 * following checks on what would be the table header: 74 * 0) File must be at least as long as an ACPI_TABLE_HEADER 75 * 1) The header length field must match the file size 76 * 2) Signature, OemId, OemTableId, AslCompilerId must be ASCII 77 * 78 ******************************************************************************/ 79 80 ACPI_STATUS 81 FlCheckForAcpiTable ( 82 FILE *Handle) 83 { 84 ACPI_TABLE_HEADER Table; 85 UINT32 FileSize; 86 size_t Actual; 87 UINT32 i; 88 89 90 /* Read a potential table header */ 91 92 Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle); 93 fseek (Handle, 0, SEEK_SET); 94 95 if (Actual < sizeof (ACPI_TABLE_HEADER)) 96 { 97 return (AE_ERROR); 98 } 99 100 /* Header length field must match the file size */ 101 102 FileSize = CmGetFileSize (Handle); 103 if (Table.Length != FileSize) 104 { 105 return (AE_ERROR); 106 } 107 108 /* 109 * These fields must be ASCII: 110 * Signature, OemId, OemTableId, AslCompilerId. 111 * We allow a NULL terminator in OemId and OemTableId. 112 */ 113 for (i = 0; i < ACPI_NAME_SIZE; i++) 114 { 115 if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i])) 116 { 117 return (AE_ERROR); 118 } 119 120 if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i])) 121 { 122 return (AE_ERROR); 123 } 124 } 125 126 for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++) 127 { 128 if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i])) 129 { 130 return (AE_ERROR); 131 } 132 } 133 134 for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++) 135 { 136 if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i])) 137 { 138 return (AE_ERROR); 139 } 140 } 141 142 printf ("Binary file appears to be a valid ACPI table, disassembling\n"); 143 return (AE_OK); 144 } 145 146 147 /******************************************************************************* 148 * 149 * FUNCTION: FlCheckForAscii 150 * 151 * PARAMETERS: Filename - Full input filename 152 * DisplayErrors - TRUE if error messages desired 153 * 154 * RETURN: Status 155 * 156 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 157 * within comments. Note: does not handle nested comments and does 158 * not handle comment delimiters within string literals. However, 159 * on the rare chance this happens and an invalid character is 160 * missed, the parser will catch the error by failing in some 161 * spectactular manner. 162 * 163 ******************************************************************************/ 164 165 ACPI_STATUS 166 FlCheckForAscii ( 167 char *Filename, 168 BOOLEAN DisplayErrors) 169 { 170 UINT8 Byte; 171 ACPI_SIZE BadBytes = 0; 172 BOOLEAN OpeningComment = FALSE; 173 ASL_FILE_STATUS Status; 174 FILE *Handle; 175 176 177 /* Open file in text mode so file offset is always accurate */ 178 179 Handle = fopen (Filename, "rb"); 180 181 Status.Line = 1; 182 Status.Offset = 0; 183 184 /* Read the entire file */ 185 186 while (fread (&Byte, 1, 1, Handle) == 1) 187 { 188 /* Ignore comment fields (allow non-ascii within) */ 189 190 if (OpeningComment) 191 { 192 /* Check for second comment open delimiter */ 193 194 if (Byte == '*') 195 { 196 FlConsumeAnsiComment (Handle, &Status); 197 } 198 199 if (Byte == '/') 200 { 201 FlConsumeNewComment (Handle, &Status); 202 } 203 204 /* Reset */ 205 206 OpeningComment = FALSE; 207 } 208 else if (Byte == '/') 209 { 210 OpeningComment = TRUE; 211 } 212 213 /* Check for an ASCII character */ 214 215 if (!ACPI_IS_ASCII (Byte)) 216 { 217 if ((BadBytes < 10) && (DisplayErrors)) 218 { 219 AcpiOsPrintf ( 220 "Found non-ASCII character in source text: " 221 "0x%2.2X in line %u, file offset 0x%2.2X\n", 222 Byte, Status.Line, Status.Offset); 223 } 224 BadBytes++; 225 } 226 227 /* Ensure character is either printable or a "space" char */ 228 229 else if (!isprint (Byte) && !isspace (Byte)) 230 { 231 if ((BadBytes < 10) && (DisplayErrors)) 232 { 233 AcpiOsPrintf ( 234 "Found invalid character in source text: " 235 "0x%2.2X in line %u, file offset 0x%2.2X\n", 236 Byte, Status.Line, Status.Offset); 237 } 238 BadBytes++; 239 } 240 241 /* Update line counter as necessary */ 242 243 if (Byte == 0x0A) 244 { 245 Status.Line++; 246 } 247 248 Status.Offset++; 249 } 250 251 fclose (Handle); 252 253 /* Were there any non-ASCII characters in the file? */ 254 255 if (BadBytes) 256 { 257 if (DisplayErrors) 258 { 259 AcpiOsPrintf ( 260 "Total %u invalid characters found in input source text, " 261 "could be a binary file\n", BadBytes); 262 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 263 } 264 265 return (AE_BAD_CHARACTER); 266 } 267 268 /* File is OK (100% ASCII) */ 269 270 return (AE_OK); 271 } 272 273 274 /******************************************************************************* 275 * 276 * FUNCTION: FlConsumeAnsiComment 277 * 278 * PARAMETERS: Handle - Open input file 279 * Status - File current status struct 280 * 281 * RETURN: Number of lines consumed 282 * 283 * DESCRIPTION: Step over a normal slash-star type comment 284 * 285 ******************************************************************************/ 286 287 static void 288 FlConsumeAnsiComment ( 289 FILE *Handle, 290 ASL_FILE_STATUS *Status) 291 { 292 UINT8 Byte; 293 BOOLEAN ClosingComment = FALSE; 294 295 296 while (fread (&Byte, 1, 1, Handle) == 1) 297 { 298 /* Scan until comment close is found */ 299 300 if (ClosingComment) 301 { 302 if (Byte == '/') 303 { 304 Status->Offset++; 305 return; 306 } 307 308 if (Byte != '*') 309 { 310 /* Reset */ 311 312 ClosingComment = FALSE; 313 } 314 } 315 else if (Byte == '*') 316 { 317 ClosingComment = TRUE; 318 } 319 320 /* Maintain line count */ 321 322 if (Byte == 0x0A) 323 { 324 Status->Line++; 325 } 326 327 Status->Offset++; 328 } 329 } 330 331 332 /******************************************************************************* 333 * 334 * FUNCTION: FlConsumeNewComment 335 * 336 * PARAMETERS: Handle - Open input file 337 * Status - File current status struct 338 * 339 * RETURN: Number of lines consumed 340 * 341 * DESCRIPTION: Step over a slash-slash type of comment 342 * 343 ******************************************************************************/ 344 345 static void 346 FlConsumeNewComment ( 347 FILE *Handle, 348 ASL_FILE_STATUS *Status) 349 { 350 UINT8 Byte; 351 352 353 while (fread (&Byte, 1, 1, Handle) == 1) 354 { 355 Status->Offset++; 356 357 /* Comment ends at newline */ 358 359 if (Byte == 0x0A) 360 { 361 Status->Line++; 362 return; 363 } 364 } 365 } 366