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