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