cvparser.c revision 1.1.1.3 1 1.1 christos /******************************************************************************
2 1.1 christos *
3 1.1 christos * Module Name: cvparser - Converter functions that are called from the AML
4 1.1 christos * parser.
5 1.1 christos *
6 1.1 christos *****************************************************************************/
7 1.1 christos
8 1.1 christos /*
9 1.1 christos * Copyright (C) 2000 - 2017, Intel Corp.
10 1.1 christos * All rights reserved.
11 1.1 christos *
12 1.1 christos * Redistribution and use in source and binary forms, with or without
13 1.1 christos * modification, are permitted provided that the following conditions
14 1.1 christos * are met:
15 1.1 christos * 1. Redistributions of source code must retain the above copyright
16 1.1 christos * notice, this list of conditions, and the following disclaimer,
17 1.1 christos * without modification.
18 1.1 christos * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 1.1 christos * substantially similar to the "NO WARRANTY" disclaimer below
20 1.1 christos * ("Disclaimer") and any redistribution must be conditioned upon
21 1.1 christos * including a substantially similar Disclaimer requirement for further
22 1.1 christos * binary redistribution.
23 1.1 christos * 3. Neither the names of the above-listed copyright holders nor the names
24 1.1 christos * of any contributors may be used to endorse or promote products derived
25 1.1 christos * from this software without specific prior written permission.
26 1.1 christos *
27 1.1 christos * Alternatively, this software may be distributed under the terms of the
28 1.1 christos * GNU General Public License ("GPL") version 2 as published by the Free
29 1.1 christos * Software Foundation.
30 1.1 christos *
31 1.1 christos * NO WARRANTY
32 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 1.1 christos * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 1.1 christos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 1.1 christos * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 1.1 christos * POSSIBILITY OF SUCH DAMAGES.
43 1.1 christos */
44 1.1 christos
45 1.1 christos #include "aslcompiler.h"
46 1.1 christos #include "acparser.h"
47 1.1 christos #include "acdispat.h"
48 1.1 christos #include "amlcode.h"
49 1.1 christos #include "acinterp.h"
50 1.1 christos #include "acdisasm.h"
51 1.1 christos #include "acconvert.h"
52 1.1 christos
53 1.1 christos
54 1.1 christos /* local prototypes */
55 1.1 christos
56 1.1 christos static BOOLEAN
57 1.1 christos CvCommentExists (
58 1.1 christos UINT8 *Address);
59 1.1 christos
60 1.1 christos static BOOLEAN
61 1.1 christos CvIsFilename (
62 1.1 christos char *Filename);
63 1.1 christos
64 1.1 christos static ACPI_FILE_NODE*
65 1.1 christos CvFileAddressLookup(
66 1.1 christos char *Address,
67 1.1 christos ACPI_FILE_NODE *Head);
68 1.1 christos
69 1.1 christos static void
70 1.1 christos CvAddToFileTree (
71 1.1 christos char *Filename,
72 1.1 christos char *PreviousFilename);
73 1.1 christos
74 1.1 christos static void
75 1.1 christos CvSetFileParent (
76 1.1 christos char *ChildFile,
77 1.1 christos char *ParentFile);
78 1.1 christos
79 1.1 christos
80 1.1 christos /*******************************************************************************
81 1.1 christos *
82 1.1 christos * FUNCTION: CvIsFilename
83 1.1 christos *
84 1.1 christos * PARAMETERS: filename - input filename
85 1.1 christos *
86 1.1 christos * RETURN: BOOLEAN - TRUE if all characters are between 0x20 and 0x7f
87 1.1 christos *
88 1.1 christos * DESCRIPTION: Take a given char * and see if it contains all printable
89 1.1 christos * characters. If all characters have hexvalues 20-7f and ends with
90 1.1 christos * .dsl, we will assume that it is a proper filename.
91 1.1 christos *
92 1.1 christos ******************************************************************************/
93 1.1 christos
94 1.1 christos static BOOLEAN
95 1.1 christos CvIsFilename (
96 1.1 christos char *Filename)
97 1.1 christos {
98 1.1 christos UINT64 Length = strlen(Filename);
99 1.1 christos char *FileExt = Filename + Length - 4;
100 1.1.1.2 christos UINT64 i;
101 1.1 christos
102 1.1 christos
103 1.1 christos if ((Length > 4) && AcpiUtStricmp (FileExt, ".dsl"))
104 1.1 christos {
105 1.1.1.2 christos return (FALSE);
106 1.1 christos }
107 1.1 christos
108 1.1 christos for(i = 0; i<Length; ++i)
109 1.1 christos {
110 1.1.1.2 christos if (!isprint ((int) Filename[i]))
111 1.1 christos {
112 1.1.1.2 christos return (FALSE);
113 1.1 christos }
114 1.1 christos }
115 1.1.1.2 christos
116 1.1.1.2 christos return (TRUE);
117 1.1 christos }
118 1.1 christos
119 1.1 christos
120 1.1 christos /*******************************************************************************
121 1.1 christos *
122 1.1 christos * FUNCTION: CvInitFileTree
123 1.1 christos *
124 1.1 christos * PARAMETERS: Table - input table
125 1.1 christos * AmlStart - Address of the starting point of the AML.
126 1.1 christos * AmlLength - Length of the AML file.
127 1.1 christos *
128 1.1.1.2 christos * RETURN: None
129 1.1 christos *
130 1.1 christos * DESCRIPTION: Initialize the file dependency tree by scanning the AML.
131 1.1 christos * This is referred as ASL_CV_INIT_FILETREE.
132 1.1 christos *
133 1.1 christos ******************************************************************************/
134 1.1 christos
135 1.1 christos void
136 1.1 christos CvInitFileTree (
137 1.1 christos ACPI_TABLE_HEADER *Table,
138 1.1 christos UINT8 *AmlStart,
139 1.1 christos UINT32 AmlLength)
140 1.1 christos {
141 1.1 christos UINT8 *TreeAml;
142 1.1 christos UINT8 *FileEnd;
143 1.1 christos char *Filename = NULL;
144 1.1 christos char *PreviousFilename = NULL;
145 1.1 christos char *ParentFilename = NULL;
146 1.1 christos char *ChildFilename = NULL;
147 1.1 christos
148 1.1 christos
149 1.1 christos if (!Gbl_CaptureComments)
150 1.1 christos {
151 1.1 christos return;
152 1.1 christos }
153 1.1 christos
154 1.1 christos CvDbgPrint ("AmlLength: %x\n", AmlLength);
155 1.1 christos CvDbgPrint ("AmlStart: %p\n", AmlStart);
156 1.1 christos CvDbgPrint ("AmlEnd?: %p\n", AmlStart+AmlLength);
157 1.1 christos
158 1.1 christos AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
159 1.1.1.2 christos
160 1.1 christos AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart);
161 1.1 christos AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length);
162 1.1 christos AcpiGbl_FileTreeRoot->Next = NULL;
163 1.1 christos AcpiGbl_FileTreeRoot->Parent = NULL;
164 1.1 christos AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2);
165 1.1 christos
166 1.1 christos /* Set the root file to the current open file */
167 1.1 christos
168 1.1 christos AcpiGbl_FileTreeRoot->File = AcpiGbl_OutputFile;
169 1.1 christos
170 1.1 christos /*
171 1.1 christos * Set this to true because we dont need to output
172 1.1 christos * an include statement for the topmost file
173 1.1 christos */
174 1.1 christos AcpiGbl_FileTreeRoot->IncludeWritten = TRUE;
175 1.1 christos Filename = NULL;
176 1.1 christos AcpiGbl_CurrentFilename = (char *)(AmlStart+2);
177 1.1 christos AcpiGbl_RootFilename = (char *)(AmlStart+2);
178 1.1 christos
179 1.1 christos TreeAml = AmlStart;
180 1.1 christos FileEnd = AmlStart + AmlLength;
181 1.1 christos
182 1.1 christos while (TreeAml <= FileEnd)
183 1.1 christos {
184 1.1 christos /*
185 1.1 christos * Make sure that this filename contains all printable characters
186 1.1 christos * and a .dsl extension at the end. If not, then it must be some
187 1.1 christos * raw data that doesn't outline a filename.
188 1.1 christos */
189 1.1 christos if ((*TreeAml == AML_COMMENT_OP) &&
190 1.1.1.2 christos (*(TreeAml +1) == FILENAME_COMMENT) &&
191 1.1.1.2 christos (CvIsFilename ((char *)(TreeAml +2))))
192 1.1 christos {
193 1.1 christos CvDbgPrint ("A9 and a 08 file\n");
194 1.1 christos PreviousFilename = Filename;
195 1.1.1.2 christos Filename = (char *) (TreeAml +2);
196 1.1.1.2 christos
197 1.1 christos CvAddToFileTree (Filename, PreviousFilename);
198 1.1 christos ChildFilename = Filename;
199 1.1 christos CvDbgPrint ("%s\n", Filename);
200 1.1 christos }
201 1.1 christos else if ((*TreeAml == AML_COMMENT_OP) &&
202 1.1.1.2 christos (*(TreeAml +1) == PARENTFILENAME_COMMENT) &&
203 1.1.1.2 christos (CvIsFilename ((char *)(TreeAml +2))))
204 1.1 christos {
205 1.1 christos CvDbgPrint ("A9 and a 09 file\n");
206 1.1.1.2 christos ParentFilename = (char *)(TreeAml +2);
207 1.1 christos CvSetFileParent (ChildFilename, ParentFilename);
208 1.1 christos CvDbgPrint ("%s\n", ParentFilename);
209 1.1 christos }
210 1.1.1.2 christos
211 1.1 christos ++TreeAml;
212 1.1 christos }
213 1.1 christos }
214 1.1 christos
215 1.1 christos
216 1.1 christos /*******************************************************************************
217 1.1 christos *
218 1.1 christos * FUNCTION: CvClearOpComments
219 1.1 christos *
220 1.1 christos * PARAMETERS: Op -- clear all comments within this Op
221 1.1 christos *
222 1.1.1.2 christos * RETURN: None
223 1.1 christos *
224 1.1 christos * DESCRIPTION: Clear all converter-related fields of the given Op.
225 1.1 christos * This is referred as ASL_CV_CLEAR_OP_COMMENTS.
226 1.1 christos *
227 1.1 christos ******************************************************************************/
228 1.1 christos
229 1.1 christos void
230 1.1 christos CvClearOpComments (
231 1.1 christos ACPI_PARSE_OBJECT *Op)
232 1.1 christos {
233 1.1.1.2 christos
234 1.1 christos Op->Common.InlineComment = NULL;
235 1.1 christos Op->Common.EndNodeComment = NULL;
236 1.1 christos Op->Common.NameComment = NULL;
237 1.1 christos Op->Common.CommentList = NULL;
238 1.1 christos Op->Common.EndBlkComment = NULL;
239 1.1 christos Op->Common.CloseBraceComment = NULL;
240 1.1 christos Op->Common.CvFilename = NULL;
241 1.1 christos Op->Common.CvParentFilename = NULL;
242 1.1 christos }
243 1.1 christos
244 1.1 christos
245 1.1 christos /*******************************************************************************
246 1.1 christos *
247 1.1 christos * FUNCTION: CvCommentExists
248 1.1 christos *
249 1.1.1.2 christos * PARAMETERS: Address - check if this address appears in the list
250 1.1 christos *
251 1.1 christos * RETURN: BOOLEAN - TRUE if the address exists.
252 1.1 christos *
253 1.1.1.2 christos * DESCRIPTION: Look at the pointer address and check if this appears in the
254 1.1.1.2 christos * list of all addresses. If it exists in the list, return TRUE
255 1.1 christos * if it exists. Otherwise add to the list and return FALSE.
256 1.1 christos *
257 1.1 christos ******************************************************************************/
258 1.1 christos
259 1.1 christos static BOOLEAN
260 1.1 christos CvCommentExists (
261 1.1 christos UINT8 *Address)
262 1.1 christos {
263 1.1 christos ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead;
264 1.1 christos UINT8 Option;
265 1.1 christos
266 1.1 christos
267 1.1 christos if (!Address)
268 1.1 christos {
269 1.1 christos return (FALSE);
270 1.1 christos }
271 1.1.1.2 christos
272 1.1 christos Option = *(Address + 1);
273 1.1 christos
274 1.1 christos /*
275 1.1.1.2 christos * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as
276 1.1.1.2 christos * comments. They serve as markers for where the file starts and ends.
277 1.1 christos */
278 1.1.1.2 christos if ((Option == FILENAME_COMMENT) ||
279 1.1.1.2 christos (Option == PARENTFILENAME_COMMENT))
280 1.1 christos {
281 1.1 christos return (FALSE);
282 1.1 christos }
283 1.1 christos
284 1.1 christos if (!Current)
285 1.1 christos {
286 1.1 christos AcpiGbl_CommentAddrListHead =
287 1.1 christos AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
288 1.1 christos AcpiGbl_CommentAddrListHead->Addr = Address;
289 1.1 christos AcpiGbl_CommentAddrListHead->Next = NULL;
290 1.1 christos return (FALSE);
291 1.1 christos }
292 1.1 christos else
293 1.1 christos {
294 1.1 christos while (Current)
295 1.1 christos {
296 1.1 christos if (Current->Addr != Address)
297 1.1 christos {
298 1.1 christos Current = Current->Next;
299 1.1 christos }
300 1.1 christos else
301 1.1 christos {
302 1.1 christos return (TRUE);
303 1.1 christos }
304 1.1 christos }
305 1.1 christos
306 1.1 christos /*
307 1.1.1.2 christos * If the execution gets to this point, it means that this
308 1.1.1.2 christos * address does not exists in the list. Add this address to the
309 1.1 christos * beginning of the list.
310 1.1 christos */
311 1.1 christos Current = AcpiGbl_CommentAddrListHead;
312 1.1 christos AcpiGbl_CommentAddrListHead =
313 1.1 christos AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
314 1.1.1.2 christos
315 1.1 christos AcpiGbl_CommentAddrListHead->Addr = Address;
316 1.1 christos AcpiGbl_CommentAddrListHead->Next = Current;
317 1.1 christos return (FALSE);
318 1.1 christos }
319 1.1 christos }
320 1.1 christos
321 1.1 christos
322 1.1 christos /*******************************************************************************
323 1.1 christos *
324 1.1 christos * FUNCTION: CvFilenameExists
325 1.1 christos *
326 1.1 christos * PARAMETERS: Filename - filename to search
327 1.1 christos *
328 1.1 christos * RETURN: ACPI_FILE_NODE - a pointer to a file node
329 1.1 christos *
330 1.1 christos * DESCRIPTION: Look for the given filename in the file dependency tree.
331 1.1 christos * Returns the file node if it exists, returns NULL if it does not.
332 1.1 christos *
333 1.1 christos ******************************************************************************/
334 1.1 christos
335 1.1 christos ACPI_FILE_NODE*
336 1.1 christos CvFilenameExists(
337 1.1 christos char *Filename,
338 1.1 christos ACPI_FILE_NODE *Head)
339 1.1 christos {
340 1.1 christos ACPI_FILE_NODE *Current = Head;
341 1.1 christos
342 1.1 christos
343 1.1.1.2 christos if (!Filename)
344 1.1.1.2 christos {
345 1.1.1.2 christos return (NULL);
346 1.1.1.2 christos }
347 1.1.1.2 christos
348 1.1 christos while (Current)
349 1.1 christos {
350 1.1 christos if (!AcpiUtStricmp (Current->Filename, Filename))
351 1.1 christos {
352 1.1 christos return (Current);
353 1.1 christos }
354 1.1.1.2 christos
355 1.1 christos Current = Current->Next;
356 1.1 christos }
357 1.1 christos return (NULL);
358 1.1 christos }
359 1.1 christos
360 1.1 christos
361 1.1 christos /*******************************************************************************
362 1.1 christos *
363 1.1 christos * FUNCTION: CvFileAddressLookup
364 1.1 christos *
365 1.1 christos * PARAMETERS: Address - address to look up
366 1.1 christos * Head - file dependency tree
367 1.1 christos *
368 1.1.1.2 christos * RETURN: ACPI_FILE_NODE - pointer to a file node containing the address
369 1.1 christos *
370 1.1 christos * DESCRIPTION: Look for the given address in the file dependency tree.
371 1.1 christos * Returns the first file node where the given address is within
372 1.1 christos * the file node's starting and ending address.
373 1.1 christos *
374 1.1 christos ******************************************************************************/
375 1.1 christos
376 1.1.1.2 christos static ACPI_FILE_NODE *
377 1.1 christos CvFileAddressLookup(
378 1.1 christos char *Address,
379 1.1 christos ACPI_FILE_NODE *Head)
380 1.1 christos {
381 1.1 christos ACPI_FILE_NODE *Current = Head;
382 1.1 christos
383 1.1 christos
384 1.1 christos while (Current)
385 1.1 christos {
386 1.1 christos if ((Address >= Current->FileStart) &&
387 1.1 christos (Address < Current->FileEnd ||
388 1.1 christos !Current->FileEnd))
389 1.1 christos {
390 1.1 christos return (Current);
391 1.1 christos }
392 1.1.1.2 christos
393 1.1 christos Current = Current->Next;
394 1.1 christos }
395 1.1 christos
396 1.1 christos return (NULL);
397 1.1 christos }
398 1.1 christos
399 1.1 christos
400 1.1 christos /*******************************************************************************
401 1.1 christos *
402 1.1 christos * FUNCTION: CvLabelFileNode
403 1.1 christos *
404 1.1 christos * PARAMETERS: Op
405 1.1 christos *
406 1.1 christos * RETURN: None
407 1.1 christos *
408 1.1 christos * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field
409 1.1 christos * within the file tree and fills in approperiate file information
410 1.1 christos * from a matching node within the tree.
411 1.1 christos * This is referred as ASL_CV_LABEL_FILENODE.
412 1.1 christos *
413 1.1 christos ******************************************************************************/
414 1.1 christos
415 1.1 christos void
416 1.1 christos CvLabelFileNode(
417 1.1 christos ACPI_PARSE_OBJECT *Op)
418 1.1 christos {
419 1.1 christos ACPI_FILE_NODE *Node;
420 1.1 christos
421 1.1 christos
422 1.1 christos if (!Op)
423 1.1 christos {
424 1.1 christos return;
425 1.1 christos }
426 1.1 christos
427 1.1.1.2 christos Node = CvFileAddressLookup ((char *)
428 1.1.1.2 christos Op->Common.Aml, AcpiGbl_FileTreeRoot);
429 1.1 christos if (!Node)
430 1.1 christos {
431 1.1 christos return;
432 1.1 christos }
433 1.1 christos
434 1.1 christos Op->Common.CvFilename = Node->Filename;
435 1.1 christos if (Node->Parent)
436 1.1 christos {
437 1.1 christos Op->Common.CvParentFilename = Node->Parent->Filename;
438 1.1 christos }
439 1.1 christos else
440 1.1 christos {
441 1.1 christos Op->Common.CvParentFilename = Node->Filename;
442 1.1 christos }
443 1.1 christos }
444 1.1 christos
445 1.1 christos
446 1.1 christos /*******************************************************************************
447 1.1 christos *
448 1.1 christos * FUNCTION: CvAddToFileTree
449 1.1 christos *
450 1.1 christos * PARAMETERS: Filename - Address containing the name of the current
451 1.1 christos * filename
452 1.1 christos * PreviousFilename - Address containing the name of the previous
453 1.1 christos * filename
454 1.1 christos *
455 1.1.1.2 christos * RETURN: None
456 1.1 christos *
457 1.1 christos * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist.
458 1.1 christos *
459 1.1 christos ******************************************************************************/
460 1.1 christos
461 1.1 christos static void
462 1.1 christos CvAddToFileTree (
463 1.1 christos char *Filename,
464 1.1 christos char *PreviousFilename)
465 1.1 christos {
466 1.1 christos ACPI_FILE_NODE *Node;
467 1.1 christos
468 1.1 christos
469 1.1 christos if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
470 1.1 christos PreviousFilename)
471 1.1 christos {
472 1.1 christos Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
473 1.1 christos if (Node)
474 1.1 christos {
475 1.1 christos /*
476 1.1 christos * Set the end point of the PreviousFilename to the address
477 1.1 christos * of Filename.
478 1.1 christos */
479 1.1 christos Node->FileEnd = Filename;
480 1.1 christos }
481 1.1 christos }
482 1.1 christos else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
483 1.1 christos !PreviousFilename)
484 1.1 christos {
485 1.1 christos return;
486 1.1 christos }
487 1.1 christos
488 1.1 christos Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
489 1.1 christos if (Node && PreviousFilename)
490 1.1 christos {
491 1.1 christos /*
492 1.1.1.2 christos * Update the end of the previous file and all of their parents'
493 1.1.1.2 christos * ending addresses. This is done to ensure that parent file
494 1.1.1.2 christos * ranges extend to the end of their childrens' files.
495 1.1 christos */
496 1.1 christos Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
497 1.1 christos if (Node && (Node->FileEnd < Filename))
498 1.1 christos {
499 1.1 christos Node->FileEnd = Filename;
500 1.1 christos Node = Node->Parent;
501 1.1 christos while (Node)
502 1.1 christos {
503 1.1 christos if (Node->FileEnd < Filename)
504 1.1 christos {
505 1.1 christos Node->FileEnd = Filename;
506 1.1 christos }
507 1.1.1.2 christos
508 1.1 christos Node = Node->Parent;
509 1.1 christos }
510 1.1 christos }
511 1.1 christos }
512 1.1 christos else
513 1.1 christos {
514 1.1 christos Node = AcpiGbl_FileTreeRoot;
515 1.1 christos AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
516 1.1.1.2 christos
517 1.1 christos AcpiGbl_FileTreeRoot->Next = Node;
518 1.1 christos AcpiGbl_FileTreeRoot->Parent = NULL;
519 1.1 christos AcpiGbl_FileTreeRoot->Filename = Filename;
520 1.1 christos AcpiGbl_FileTreeRoot->FileStart = Filename;
521 1.1 christos AcpiGbl_FileTreeRoot->IncludeWritten = FALSE;
522 1.1 christos AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+");
523 1.1 christos
524 1.1 christos /*
525 1.1 christos * If we can't open the file, we need to abort here before we
526 1.1 christos * accidentally write to a NULL file.
527 1.1 christos */
528 1.1 christos if (!AcpiGbl_FileTreeRoot->File)
529 1.1 christos {
530 1.1 christos /* delete the .xxx file */
531 1.1 christos
532 1.1 christos FlDeleteFile (ASL_FILE_AML_OUTPUT);
533 1.1 christos sprintf (MsgBuffer, "\"%s\" - %s", Filename, strerror (errno));
534 1.1.1.2 christos AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0,
535 1.1.1.2 christos NULL, MsgBuffer);
536 1.1 christos AslAbort ();
537 1.1 christos }
538 1.1 christos }
539 1.1 christos }
540 1.1 christos
541 1.1 christos
542 1.1 christos /*******************************************************************************
543 1.1 christos *
544 1.1 christos * FUNCTION: CvSetFileParent
545 1.1 christos *
546 1.1 christos * PARAMETERS: ChildFile - contains the filename of the child file
547 1.1 christos * ParentFile - contains the filename of the parent file.
548 1.1 christos *
549 1.1.1.2 christos * RETURN: None
550 1.1 christos *
551 1.1.1.2 christos * DESCRIPTION: Point the parent pointer of the Child to the node that
552 1.1 christos * corresponds with the parent file node.
553 1.1 christos *
554 1.1 christos ******************************************************************************/
555 1.1 christos
556 1.1 christos static void
557 1.1 christos CvSetFileParent (
558 1.1 christos char *ChildFile,
559 1.1 christos char *ParentFile)
560 1.1 christos {
561 1.1 christos ACPI_FILE_NODE *Child;
562 1.1 christos ACPI_FILE_NODE *Parent;
563 1.1 christos
564 1.1 christos
565 1.1 christos Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot);
566 1.1 christos Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot);
567 1.1.1.2 christos
568 1.1 christos if (Child && Parent)
569 1.1 christos {
570 1.1 christos Child->Parent = Parent;
571 1.1 christos
572 1.1 christos while (Child->Parent)
573 1.1 christos {
574 1.1 christos if (Child->Parent->FileEnd < Child->FileStart)
575 1.1 christos {
576 1.1 christos Child->Parent->FileEnd = Child->FileStart;
577 1.1 christos }
578 1.1.1.2 christos
579 1.1 christos Child = Child->Parent;
580 1.1 christos }
581 1.1 christos }
582 1.1 christos }
583 1.1 christos
584 1.1 christos
585 1.1 christos /*******************************************************************************
586 1.1 christos *
587 1.1 christos * FUNCTION: CvCaptureCommentsOnly
588 1.1 christos *
589 1.1 christos * PARAMETERS: ParserState - A parser state object
590 1.1 christos *
591 1.1.1.2 christos * RETURN: None
592 1.1 christos *
593 1.1.1.2 christos * DESCRIPTION: Look at the aml that the parser state is pointing to,
594 1.1 christos * capture any AML_COMMENT_OP and it's arguments and increment the
595 1.1 christos * aml pointer past the comment. Comments are transferred to parse
596 1.1 christos * nodes through CvTransferComments() as well as
597 1.1 christos * AcpiPsBuildNamedOp().
598 1.1 christos * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY.
599 1.1 christos *
600 1.1 christos ******************************************************************************/
601 1.1 christos
602 1.1 christos void
603 1.1 christos CvCaptureCommentsOnly (
604 1.1 christos ACPI_PARSE_STATE *ParserState)
605 1.1 christos {
606 1.1 christos UINT8 *Aml = ParserState->Aml;
607 1.1 christos UINT16 Opcode = (UINT16) ACPI_GET8 (Aml);
608 1.1 christos UINT32 Length = 0;
609 1.1.1.3 christos UINT8 CommentOption;
610 1.1 christos BOOLEAN StdDefBlockFlag = FALSE;
611 1.1 christos ACPI_COMMENT_NODE *CommentNode;
612 1.1 christos ACPI_FILE_NODE *FileNode;
613 1.1 christos
614 1.1 christos
615 1.1 christos if (!Gbl_CaptureComments ||
616 1.1 christos Opcode != AML_COMMENT_OP)
617 1.1 christos {
618 1.1 christos return;
619 1.1 christos }
620 1.1 christos
621 1.1 christos while (Opcode == AML_COMMENT_OP)
622 1.1 christos {
623 1.1 christos CvDbgPrint ("comment aml address: %p\n", Aml);
624 1.1 christos
625 1.1 christos if (CvCommentExists(ParserState->Aml))
626 1.1 christos {
627 1.1 christos CvDbgPrint ("Avoiding capturing an existing comment.\n");
628 1.1 christos }
629 1.1 christos else
630 1.1 christos {
631 1.1.1.2 christos CommentOption = *(Aml +1);
632 1.1 christos
633 1.1.1.2 christos /*
634 1.1.1.2 christos * Increment past the comment option and point the
635 1.1.1.2 christos * appropriate char pointers
636 1.1.1.2 christos */
637 1.1 christos Aml += 2;
638 1.1 christos
639 1.1.1.2 christos /* Found a comment. Now, set pointers to these comments. */
640 1.1 christos
641 1.1 christos switch (CommentOption)
642 1.1 christos {
643 1.1 christos case STD_DEFBLK_COMMENT:
644 1.1 christos
645 1.1 christos StdDefBlockFlag = TRUE;
646 1.1 christos
647 1.1.1.2 christos /*
648 1.1.1.2 christos * Add to a linked list of nodes. This list will be
649 1.1.1.2 christos * taken by the parse node created next.
650 1.1.1.2 christos */
651 1.1.1.2 christos CommentNode = AcpiOsAcquireObject (
652 1.1.1.2 christos AcpiGbl_RegCommentCache);
653 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
654 1.1 christos CommentNode->Next = NULL;
655 1.1 christos
656 1.1 christos if (!AcpiGbl_DefBlkCommentListHead)
657 1.1 christos {
658 1.1 christos AcpiGbl_DefBlkCommentListHead = CommentNode;
659 1.1 christos AcpiGbl_DefBlkCommentListTail = CommentNode;
660 1.1 christos }
661 1.1 christos else
662 1.1 christos {
663 1.1 christos AcpiGbl_DefBlkCommentListTail->Next = CommentNode;
664 1.1.1.2 christos AcpiGbl_DefBlkCommentListTail =
665 1.1.1.2 christos AcpiGbl_DefBlkCommentListTail->Next;
666 1.1 christos }
667 1.1 christos break;
668 1.1 christos
669 1.1 christos case STANDARD_COMMENT:
670 1.1 christos
671 1.1 christos CvDbgPrint ("found regular comment.\n");
672 1.1 christos
673 1.1.1.2 christos /*
674 1.1.1.2 christos * Add to a linked list of nodes. This list will be
675 1.1.1.2 christos * taken by the parse node created next.
676 1.1.1.2 christos */
677 1.1.1.2 christos CommentNode = AcpiOsAcquireObject (
678 1.1.1.2 christos AcpiGbl_RegCommentCache);
679 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
680 1.1 christos CommentNode->Next = NULL;
681 1.1 christos
682 1.1 christos if (!AcpiGbl_RegCommentListHead)
683 1.1 christos {
684 1.1 christos AcpiGbl_RegCommentListHead = CommentNode;
685 1.1 christos AcpiGbl_RegCommentListTail = CommentNode;
686 1.1 christos }
687 1.1 christos else
688 1.1 christos {
689 1.1 christos AcpiGbl_RegCommentListTail->Next = CommentNode;
690 1.1.1.2 christos AcpiGbl_RegCommentListTail =
691 1.1.1.2 christos AcpiGbl_RegCommentListTail->Next;
692 1.1 christos }
693 1.1 christos break;
694 1.1 christos
695 1.1 christos case ENDBLK_COMMENT:
696 1.1 christos
697 1.1 christos CvDbgPrint ("found endblk comment.\n");
698 1.1 christos
699 1.1.1.2 christos /* Add to a linked list of nodes. This will be
700 1.1.1.2 christos * taken by the next created parse node.
701 1.1.1.2 christos */
702 1.1.1.2 christos CommentNode = AcpiOsAcquireObject (
703 1.1.1.2 christos AcpiGbl_RegCommentCache);
704 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
705 1.1 christos CommentNode->Next = NULL;
706 1.1 christos
707 1.1 christos if (!AcpiGbl_EndBlkCommentListHead)
708 1.1 christos {
709 1.1 christos AcpiGbl_EndBlkCommentListHead = CommentNode;
710 1.1 christos AcpiGbl_EndBlkCommentListTail = CommentNode;
711 1.1 christos }
712 1.1 christos else
713 1.1 christos {
714 1.1 christos AcpiGbl_EndBlkCommentListTail->Next = CommentNode;
715 1.1.1.2 christos AcpiGbl_EndBlkCommentListTail =
716 1.1.1.2 christos AcpiGbl_EndBlkCommentListTail->Next;
717 1.1 christos }
718 1.1 christos break;
719 1.1 christos
720 1.1 christos case INLINE_COMMENT:
721 1.1 christos
722 1.1 christos CvDbgPrint ("found inline comment.\n");
723 1.1.1.2 christos AcpiGbl_CurrentInlineComment =
724 1.1.1.2 christos ACPI_CAST_PTR (char, Aml);
725 1.1 christos break;
726 1.1 christos
727 1.1 christos case ENDNODE_COMMENT:
728 1.1 christos
729 1.1 christos CvDbgPrint ("found EndNode comment.\n");
730 1.1.1.2 christos AcpiGbl_CurrentEndNodeComment =
731 1.1.1.2 christos ACPI_CAST_PTR (char, Aml);
732 1.1 christos break;
733 1.1 christos
734 1.1 christos case CLOSE_BRACE_COMMENT:
735 1.1 christos
736 1.1 christos CvDbgPrint ("found close brace comment.\n");
737 1.1.1.2 christos AcpiGbl_CurrentCloseBraceComment =
738 1.1.1.2 christos ACPI_CAST_PTR (char, Aml);
739 1.1 christos break;
740 1.1 christos
741 1.1 christos case END_DEFBLK_COMMENT:
742 1.1 christos
743 1.1.1.2 christos CvDbgPrint ("Found comment that belongs after"
744 1.1.1.2 christos " the } for a definition block.\n");
745 1.1.1.2 christos AcpiGbl_CurrentScope->Common.CloseBraceComment =
746 1.1.1.2 christos ACPI_CAST_PTR (char, Aml);
747 1.1 christos break;
748 1.1 christos
749 1.1 christos case FILENAME_COMMENT:
750 1.1 christos
751 1.1.1.2 christos CvDbgPrint ("Found a filename: %s\n",
752 1.1.1.2 christos ACPI_CAST_PTR (char, Aml));
753 1.1.1.2 christos FileNode = CvFilenameExists (
754 1.1.1.2 christos ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot);
755 1.1 christos
756 1.1 christos /*
757 1.1 christos * If there is an INCLUDE_COMMENT followed by a
758 1.1 christos * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment
759 1.1 christos * that is emitted before the #include for the file.
760 1.1 christos * We will save the IncludeComment within the FileNode
761 1.1 christos * associated with this FILENAME_COMMENT.
762 1.1 christos */
763 1.1 christos if (FileNode && AcpiGbl_IncCommentListHead)
764 1.1 christos {
765 1.1 christos FileNode->IncludeComment = AcpiGbl_IncCommentListHead;
766 1.1 christos AcpiGbl_IncCommentListHead = NULL;
767 1.1 christos AcpiGbl_IncCommentListTail = NULL;
768 1.1 christos }
769 1.1 christos break;
770 1.1 christos
771 1.1 christos case PARENTFILENAME_COMMENT:
772 1.1 christos CvDbgPrint (" Found a parent filename.\n");
773 1.1 christos break;
774 1.1 christos
775 1.1 christos case INCLUDE_COMMENT:
776 1.1 christos
777 1.1 christos /*
778 1.1 christos * Add to a linked list. This list will be taken by the
779 1.1 christos * parse node created next. See the FILENAME_COMMENT case
780 1.1 christos * for more details
781 1.1 christos */
782 1.1.1.2 christos CommentNode = AcpiOsAcquireObject (
783 1.1.1.2 christos AcpiGbl_RegCommentCache);
784 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
785 1.1 christos CommentNode->Next = NULL;
786 1.1 christos
787 1.1 christos if (!AcpiGbl_IncCommentListHead)
788 1.1 christos {
789 1.1 christos AcpiGbl_IncCommentListHead = CommentNode;
790 1.1 christos AcpiGbl_IncCommentListTail = CommentNode;
791 1.1 christos }
792 1.1 christos else
793 1.1 christos {
794 1.1 christos AcpiGbl_IncCommentListTail->Next = CommentNode;
795 1.1.1.2 christos AcpiGbl_IncCommentListTail =
796 1.1.1.2 christos AcpiGbl_IncCommentListTail->Next;
797 1.1 christos }
798 1.1 christos
799 1.1.1.2 christos CvDbgPrint ("Found a include comment: %s\n",
800 1.1.1.2 christos CommentNode->Comment);
801 1.1 christos break;
802 1.1 christos
803 1.1 christos default:
804 1.1 christos
805 1.1 christos /* Not a valid comment option. Revert the AML */
806 1.1 christos
807 1.1 christos Aml -= 2;
808 1.1 christos goto DefBlock;
809 1.1 christos
810 1.1.1.2 christos } /* End switch statement */
811 1.1 christos
812 1.1.1.2 christos } /* End else */
813 1.1 christos
814 1.1.1.2 christos /* Determine the length and move forward that amount */
815 1.1 christos
816 1.1 christos Length = 0;
817 1.1 christos while (ParserState->Aml[Length])
818 1.1 christos {
819 1.1 christos Length++;
820 1.1 christos }
821 1.1 christos
822 1.1 christos ParserState->Aml += Length + 1;
823 1.1 christos
824 1.1 christos /* Peek at the next Opcode. */
825 1.1 christos
826 1.1 christos Aml = ParserState->Aml;
827 1.1 christos Opcode = (UINT16) ACPI_GET8 (Aml);
828 1.1 christos }
829 1.1 christos
830 1.1 christos DefBlock:
831 1.1 christos if (StdDefBlockFlag)
832 1.1 christos {
833 1.1 christos /*
834 1.1 christos * Give all of its comments to the current scope, which is known as
835 1.1 christos * the definition block, since STD_DEFBLK_COMMENT only appears after
836 1.1 christos * definition block headers.
837 1.1 christos */
838 1.1 christos AcpiGbl_CurrentScope->Common.CommentList
839 1.1 christos = AcpiGbl_DefBlkCommentListHead;
840 1.1 christos AcpiGbl_DefBlkCommentListHead = NULL;
841 1.1 christos AcpiGbl_DefBlkCommentListTail = NULL;
842 1.1 christos }
843 1.1 christos }
844 1.1 christos
845 1.1 christos
846 1.1 christos /*******************************************************************************
847 1.1 christos *
848 1.1 christos * FUNCTION: CvCaptureComments
849 1.1 christos *
850 1.1 christos * PARAMETERS: ParserState - A parser state object
851 1.1 christos *
852 1.1.1.2 christos * RETURN: None
853 1.1 christos *
854 1.1 christos * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly
855 1.1 christos * This is referred as ASL_CV_CAPTURE_COMMENTS.
856 1.1 christos *
857 1.1 christos ******************************************************************************/
858 1.1 christos
859 1.1 christos void
860 1.1 christos CvCaptureComments (
861 1.1 christos ACPI_WALK_STATE *WalkState)
862 1.1 christos {
863 1.1 christos UINT8 *Aml;
864 1.1 christos UINT16 Opcode;
865 1.1 christos const ACPI_OPCODE_INFO *OpInfo;
866 1.1 christos
867 1.1 christos
868 1.1 christos if (!Gbl_CaptureComments)
869 1.1 christos {
870 1.1 christos return;
871 1.1 christos }
872 1.1 christos
873 1.1 christos /*
874 1.1.1.2 christos * Before parsing, check to see that comments that come directly
875 1.1.1.2 christos * after deferred opcodes aren't being processed.
876 1.1 christos */
877 1.1 christos Aml = WalkState->ParserState.Aml;
878 1.1 christos Opcode = (UINT16) ACPI_GET8 (Aml);
879 1.1 christos OpInfo = AcpiPsGetOpcodeInfo (Opcode);
880 1.1 christos
881 1.1 christos if (!(OpInfo->Flags & AML_DEFER) ||
882 1.1 christos ((OpInfo->Flags & AML_DEFER) &&
883 1.1 christos (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1)))
884 1.1 christos {
885 1.1 christos CvCaptureCommentsOnly (&WalkState->ParserState);
886 1.1 christos WalkState->Aml = WalkState->ParserState.Aml;
887 1.1 christos }
888 1.1 christos
889 1.1 christos }
890 1.1 christos
891 1.1 christos
892 1.1 christos /*******************************************************************************
893 1.1 christos *
894 1.1 christos * FUNCTION: CvTransferComments
895 1.1 christos *
896 1.1.1.2 christos * PARAMETERS: Op - Transfer comments to this Op
897 1.1 christos *
898 1.1.1.2 christos * RETURN: None
899 1.1 christos *
900 1.1 christos * DESCRIPTION: Transfer all of the commments stored in global containers to the
901 1.1 christos * given Op. This will be invoked shortly after the parser creates
902 1.1 christos * a ParseOp.
903 1.1 christos * This is referred as ASL_CV_TRANSFER_COMMENTS.
904 1.1 christos *
905 1.1 christos ******************************************************************************/
906 1.1 christos
907 1.1 christos void
908 1.1 christos CvTransferComments (
909 1.1 christos ACPI_PARSE_OBJECT *Op)
910 1.1 christos {
911 1.1.1.2 christos
912 1.1 christos Op->Common.InlineComment = AcpiGbl_CurrentInlineComment;
913 1.1 christos AcpiGbl_CurrentInlineComment = NULL;
914 1.1 christos
915 1.1 christos Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment;
916 1.1 christos AcpiGbl_CurrentEndNodeComment = NULL;
917 1.1 christos
918 1.1 christos Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment;
919 1.1 christos AcpiGbl_CurrentCloseBraceComment = NULL;
920 1.1 christos
921 1.1 christos Op->Common.CommentList = AcpiGbl_RegCommentListHead;
922 1.1 christos AcpiGbl_RegCommentListHead = NULL;
923 1.1 christos AcpiGbl_RegCommentListTail = NULL;
924 1.1 christos
925 1.1 christos Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead;
926 1.1 christos AcpiGbl_EndBlkCommentListHead = NULL;
927 1.1 christos AcpiGbl_EndBlkCommentListTail = NULL;
928 1.1 christos }
929