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