1 /******************************************************************************* 2 * 3 * Module Name: utfileio - simple file I/O routines 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 "acpi.h" 45 #include "accommon.h" 46 #include "actables.h" 47 #include "acapps.h" 48 49 #ifdef ACPI_ASL_COMPILER 50 #include "aslcompiler.h" 51 #endif 52 53 54 #define _COMPONENT ACPI_CA_DEBUGGER 55 ACPI_MODULE_NAME ("utfileio") 56 57 58 #ifdef ACPI_APPLICATION 59 60 /* Local prototypes */ 61 62 static ACPI_STATUS 63 AcpiUtCheckTextModeCorruption ( 64 UINT8 *Table, 65 UINT32 TableLength, 66 UINT32 FileLength); 67 68 static ACPI_STATUS 69 AcpiUtReadTable ( 70 FILE *fp, 71 ACPI_TABLE_HEADER **Table, 72 UINT32 *TableLength); 73 74 75 /******************************************************************************* 76 * 77 * FUNCTION: AcpiUtCheckTextModeCorruption 78 * 79 * PARAMETERS: Table - Table buffer 80 * TableLength - Length of table from the table header 81 * FileLength - Length of the file that contains the table 82 * 83 * RETURN: Status 84 * 85 * DESCRIPTION: Check table for text mode file corruption where all linefeed 86 * characters (LF) have been replaced by carriage return linefeed 87 * pairs (CR/LF). 88 * 89 ******************************************************************************/ 90 91 static ACPI_STATUS 92 AcpiUtCheckTextModeCorruption ( 93 UINT8 *Table, 94 UINT32 TableLength, 95 UINT32 FileLength) 96 { 97 UINT32 i; 98 UINT32 Pairs = 0; 99 100 101 if (TableLength != FileLength) 102 { 103 ACPI_WARNING ((AE_INFO, 104 "File length (0x%X) is not the same as the table length (0x%X)", 105 FileLength, TableLength)); 106 } 107 108 /* Scan entire table to determine if each LF has been prefixed with a CR */ 109 110 for (i = 1; i < FileLength; i++) 111 { 112 if (Table[i] == 0x0A) 113 { 114 if (Table[i - 1] != 0x0D) 115 { 116 /* The LF does not have a preceding CR, table not corrupted */ 117 118 return (AE_OK); 119 } 120 else 121 { 122 /* Found a CR/LF pair */ 123 124 Pairs++; 125 } 126 i++; 127 } 128 } 129 130 if (!Pairs) 131 { 132 return (AE_OK); 133 } 134 135 /* 136 * Entire table scanned, each CR is part of a CR/LF pair -- 137 * meaning that the table was treated as a text file somewhere. 138 * 139 * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the 140 * original table are left untouched by the text conversion process -- 141 * meaning that we cannot simply replace CR/LF pairs with LFs. 142 */ 143 AcpiOsPrintf ("Table has been corrupted by text mode conversion\n"); 144 AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs); 145 AcpiOsPrintf ("Table cannot be repaired!\n"); 146 return (AE_BAD_VALUE); 147 } 148 149 150 /******************************************************************************* 151 * 152 * FUNCTION: AcpiUtReadTable 153 * 154 * PARAMETERS: fp - File that contains table 155 * Table - Return value, buffer with table 156 * TableLength - Return value, length of table 157 * 158 * RETURN: Status 159 * 160 * DESCRIPTION: Load the DSDT from the file pointer 161 * 162 ******************************************************************************/ 163 164 static ACPI_STATUS 165 AcpiUtReadTable ( 166 FILE *fp, 167 ACPI_TABLE_HEADER **Table, 168 UINT32 *TableLength) 169 { 170 ACPI_TABLE_HEADER TableHeader; 171 UINT32 Actual; 172 ACPI_STATUS Status; 173 UINT32 FileSize; 174 BOOLEAN StandardHeader = TRUE; 175 INT32 Count; 176 177 /* Get the file size */ 178 179 FileSize = CmGetFileSize (fp); 180 if (FileSize == ACPI_UINT32_MAX) 181 { 182 return (AE_ERROR); 183 } 184 185 if (FileSize < 4) 186 { 187 return (AE_BAD_HEADER); 188 } 189 190 /* Read the signature */ 191 192 fseek (fp, 0, SEEK_SET); 193 194 Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp); 195 if (Count != sizeof (ACPI_TABLE_HEADER)) 196 { 197 AcpiOsPrintf ("Could not read the table header\n"); 198 return (AE_BAD_HEADER); 199 } 200 201 /* The RSDP table does not have standard ACPI header */ 202 203 if (ACPI_VALIDATE_RSDP_SIG (TableHeader.Signature)) 204 { 205 *TableLength = FileSize; 206 StandardHeader = FALSE; 207 } 208 else 209 { 210 211 #if 0 212 /* Validate the table header/length */ 213 214 Status = AcpiTbValidateTableHeader (&TableHeader); 215 if (ACPI_FAILURE (Status)) 216 { 217 AcpiOsPrintf ("Table header is invalid!\n"); 218 return (Status); 219 } 220 #endif 221 222 /* File size must be at least as long as the Header-specified length */ 223 224 if (TableHeader.Length > FileSize) 225 { 226 AcpiOsPrintf ( 227 "TableHeader length [0x%X] greater than the input file size [0x%X]\n", 228 TableHeader.Length, FileSize); 229 230 #ifdef ACPI_ASL_COMPILER 231 Status = FlCheckForAscii (fp, NULL, FALSE); 232 if (ACPI_SUCCESS (Status)) 233 { 234 AcpiOsPrintf ("File appears to be ASCII only, must be binary\n"); 235 } 236 #endif 237 return (AE_BAD_HEADER); 238 } 239 240 #ifdef ACPI_OBSOLETE_CODE 241 /* We only support a limited number of table types */ 242 243 if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) && 244 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) && 245 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT)) 246 { 247 AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n", 248 (char *) TableHeader.Signature); 249 ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); 250 return (AE_ERROR); 251 } 252 #endif 253 254 *TableLength = TableHeader.Length; 255 } 256 257 /* Allocate a buffer for the table */ 258 259 *Table = AcpiOsAllocate ((size_t) FileSize); 260 if (!*Table) 261 { 262 AcpiOsPrintf ( 263 "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", 264 TableHeader.Signature, *TableLength); 265 return (AE_NO_MEMORY); 266 } 267 268 /* Get the rest of the table */ 269 270 fseek (fp, 0, SEEK_SET); 271 Actual = fread (*Table, 1, (size_t) FileSize, fp); 272 if (Actual == FileSize) 273 { 274 if (StandardHeader) 275 { 276 /* Now validate the checksum */ 277 278 Status = AcpiTbVerifyChecksum ((void *) *Table, 279 ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); 280 281 if (Status == AE_BAD_CHECKSUM) 282 { 283 Status = AcpiUtCheckTextModeCorruption ((UINT8 *) *Table, 284 FileSize, (*Table)->Length); 285 return (Status); 286 } 287 } 288 return (AE_OK); 289 } 290 291 if (Actual > 0) 292 { 293 AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", 294 FileSize, Actual); 295 return (AE_OK); 296 } 297 298 AcpiOsPrintf ("Error - could not read the table file\n"); 299 AcpiOsFree (*Table); 300 *Table = NULL; 301 *TableLength = 0; 302 return (AE_ERROR); 303 } 304 305 306 /******************************************************************************* 307 * 308 * FUNCTION: AcpiUtReadTableFromFile 309 * 310 * PARAMETERS: Filename - File where table is located 311 * Table - Where a pointer to the table is returned 312 * 313 * RETURN: Status 314 * 315 * DESCRIPTION: Get an ACPI table from a file 316 * 317 ******************************************************************************/ 318 319 ACPI_STATUS 320 AcpiUtReadTableFromFile ( 321 char *Filename, 322 ACPI_TABLE_HEADER **Table) 323 { 324 FILE *File; 325 UINT32 FileSize; 326 UINT32 TableLength; 327 ACPI_STATUS Status = AE_ERROR; 328 329 330 /* Open the file, get current size */ 331 332 File = fopen (Filename, "rb"); 333 if (!File) 334 { 335 perror ("Could not open input file"); 336 return (Status); 337 } 338 339 FileSize = CmGetFileSize (File); 340 if (FileSize == ACPI_UINT32_MAX) 341 { 342 goto Exit; 343 } 344 345 /* Get the entire file */ 346 347 fprintf (stderr, "Loading Acpi table from file %10s - Length %.8u (%06X)\n", 348 Filename, FileSize, FileSize); 349 350 Status = AcpiUtReadTable (File, Table, &TableLength); 351 if (ACPI_FAILURE (Status)) 352 { 353 AcpiOsPrintf ("Could not get table from the file\n"); 354 } 355 356 Exit: 357 fclose(File); 358 return (Status); 359 } 360 361 #endif 362