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 if (!Handle) 181 { 182 perror ("Could not open input file"); 183 return (AE_ERROR); 184 } 185 186 Status.Line = 1; 187 Status.Offset = 0; 188 189 /* Read the entire file */ 190 191 while (fread (&Byte, 1, 1, Handle) == 1) 192 { 193 /* Ignore comment fields (allow non-ascii within) */ 194 195 if (OpeningComment) 196 { 197 /* Check for second comment open delimiter */ 198 199 if (Byte == '*') 200 { 201 FlConsumeAnsiComment (Handle, &Status); 202 } 203 204 if (Byte == '/') 205 { 206 FlConsumeNewComment (Handle, &Status); 207 } 208 209 /* Reset */ 210 211 OpeningComment = FALSE; 212 } 213 else if (Byte == '/') 214 { 215 OpeningComment = TRUE; 216 } 217 218 /* Check for an ASCII character */ 219 220 if (!ACPI_IS_ASCII (Byte)) 221 { 222 if ((BadBytes < 10) && (DisplayErrors)) 223 { 224 AcpiOsPrintf ( 225 "Found non-ASCII character in source text: " 226 "0x%2.2X in line %u, file offset 0x%2.2X\n", 227 Byte, Status.Line, Status.Offset); 228 } 229 BadBytes++; 230 } 231 232 /* Ensure character is either printable or a "space" char */ 233 234 else if (!isprint (Byte) && !isspace (Byte)) 235 { 236 if ((BadBytes < 10) && (DisplayErrors)) 237 { 238 AcpiOsPrintf ( 239 "Found invalid character in source text: " 240 "0x%2.2X in line %u, file offset 0x%2.2X\n", 241 Byte, Status.Line, Status.Offset); 242 } 243 BadBytes++; 244 } 245 246 /* Update line counter as necessary */ 247 248 if (Byte == 0x0A) 249 { 250 Status.Line++; 251 } 252 253 Status.Offset++; 254 } 255 256 fclose (Handle); 257 258 /* Were there any non-ASCII characters in the file? */ 259 260 if (BadBytes) 261 { 262 if (DisplayErrors) 263 { 264 AcpiOsPrintf ( 265 "Total %u invalid characters found in input source text, " 266 "could be a binary file\n", BadBytes); 267 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 268 } 269 270 return (AE_BAD_CHARACTER); 271 } 272 273 /* File is OK (100% ASCII) */ 274 275 return (AE_OK); 276 } 277 278 279 /******************************************************************************* 280 * 281 * FUNCTION: FlConsumeAnsiComment 282 * 283 * PARAMETERS: Handle - Open input file 284 * Status - File current status struct 285 * 286 * RETURN: Number of lines consumed 287 * 288 * DESCRIPTION: Step over a normal slash-star type comment 289 * 290 ******************************************************************************/ 291 292 static void 293 FlConsumeAnsiComment ( 294 FILE *Handle, 295 ASL_FILE_STATUS *Status) 296 { 297 UINT8 Byte; 298 BOOLEAN ClosingComment = FALSE; 299 300 301 while (fread (&Byte, 1, 1, Handle) == 1) 302 { 303 /* Scan until comment close is found */ 304 305 if (ClosingComment) 306 { 307 if (Byte == '/') 308 { 309 Status->Offset++; 310 return; 311 } 312 313 if (Byte != '*') 314 { 315 /* Reset */ 316 317 ClosingComment = FALSE; 318 } 319 } 320 else if (Byte == '*') 321 { 322 ClosingComment = TRUE; 323 } 324 325 /* Maintain line count */ 326 327 if (Byte == 0x0A) 328 { 329 Status->Line++; 330 } 331 332 Status->Offset++; 333 } 334 } 335 336 337 /******************************************************************************* 338 * 339 * FUNCTION: FlConsumeNewComment 340 * 341 * PARAMETERS: Handle - Open input file 342 * Status - File current status struct 343 * 344 * RETURN: Number of lines consumed 345 * 346 * DESCRIPTION: Step over a slash-slash type of comment 347 * 348 ******************************************************************************/ 349 350 static void 351 FlConsumeNewComment ( 352 FILE *Handle, 353 ASL_FILE_STATUS *Status) 354 { 355 UINT8 Byte; 356 357 358 while (fread (&Byte, 1, 1, Handle) == 1) 359 { 360 Status->Offset++; 361 362 /* Comment ends at newline */ 363 364 if (Byte == 0x0A) 365 { 366 Status->Line++; 367 return; 368 } 369 } 370 } 371