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
AcpiUtCheckTextModeCorruption(UINT8 * Table,UINT32 TableLength,UINT32 FileLength)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
AcpiUtReadTable(FILE * fp,ACPI_TABLE_HEADER ** Table,UINT32 * TableLength)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
AcpiUtReadTableFromFile(char * Filename,ACPI_TABLE_HEADER ** Table)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