1 /******************************************************************************
2 *
3 * Module Name: cvparser - Converter functions that are called from the AML
4 * parser.
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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
CvIsFilename(char * Filename)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 * RootFile - Output file that defines the DefinitionBlock
126 *
127 * RETURN: None
128 *
129 * DESCRIPTION: Initialize the file dependency tree by scanning the AML.
130 * This is referred as ASL_CV_INIT_FILETREE.
131 *
132 ******************************************************************************/
133
134 void
CvInitFileTree(ACPI_TABLE_HEADER * Table,FILE * RootFile)135 CvInitFileTree (
136 ACPI_TABLE_HEADER *Table,
137 FILE *RootFile)
138 {
139 UINT8 *TreeAml;
140 UINT8 *FileEnd;
141 char *Filename = NULL;
142 char *PreviousFilename = NULL;
143 char *ParentFilename = NULL;
144 char *ChildFilename = NULL;
145 UINT8 *AmlStart;
146 UINT32 AmlLength;
147
148
149 if (!AcpiGbl_CaptureComments)
150 {
151 return;
152 }
153
154
155 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
156 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
157
158 CvDbgPrint ("AmlLength: %x\n", AmlLength);
159 CvDbgPrint ("AmlStart: %p\n", AmlStart);
160 CvDbgPrint ("AmlEnd: %p\n", AmlStart+AmlLength);
161
162 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
163
164 AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart);
165 AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length);
166 AcpiGbl_FileTreeRoot->Next = NULL;
167 AcpiGbl_FileTreeRoot->Parent = NULL;
168 AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2);
169
170 /* Set the root file to the current open file */
171
172 AcpiGbl_FileTreeRoot->File = RootFile;
173
174 /*
175 * Set this to true because we don't need to output
176 * an include statement for the topmost file
177 */
178 AcpiGbl_FileTreeRoot->IncludeWritten = TRUE;
179 Filename = NULL;
180 AcpiGbl_CurrentFilename = (char *)(AmlStart+2);
181 AcpiGbl_RootFilename = (char *)(AmlStart+2);
182
183 TreeAml = AmlStart;
184 FileEnd = AmlStart + AmlLength;
185
186 while (TreeAml <= FileEnd)
187 {
188 /*
189 * Make sure that this filename contains all printable characters
190 * and a .dsl extension at the end. If not, then it must be some
191 * raw data that doesn't outline a filename.
192 */
193 if ((*TreeAml == AML_COMMENT_OP) &&
194 (*(TreeAml +1) == FILENAME_COMMENT) &&
195 (CvIsFilename ((char *)(TreeAml +2))))
196 {
197 CvDbgPrint ("A9 and a 08 file\n");
198 PreviousFilename = Filename;
199 Filename = (char *) (TreeAml +2);
200
201 CvAddToFileTree (Filename, PreviousFilename);
202 ChildFilename = Filename;
203 CvDbgPrint ("%s\n", Filename);
204 }
205 else if ((*TreeAml == AML_COMMENT_OP) &&
206 (*(TreeAml +1) == PARENTFILENAME_COMMENT) &&
207 (CvIsFilename ((char *)(TreeAml +2))))
208 {
209 CvDbgPrint ("A9 and a 09 file\n");
210 ParentFilename = (char *)(TreeAml +2);
211 CvSetFileParent (ChildFilename, ParentFilename);
212 CvDbgPrint ("%s\n", ParentFilename);
213 }
214
215 ++TreeAml;
216 }
217 }
218
219
220 /*******************************************************************************
221 *
222 * FUNCTION: CvClearOpComments
223 *
224 * PARAMETERS: Op -- clear all comments within this Op
225 *
226 * RETURN: None
227 *
228 * DESCRIPTION: Clear all converter-related fields of the given Op.
229 * This is referred as ASL_CV_CLEAR_OP_COMMENTS.
230 *
231 ******************************************************************************/
232
233 void
CvClearOpComments(ACPI_PARSE_OBJECT * Op)234 CvClearOpComments (
235 ACPI_PARSE_OBJECT *Op)
236 {
237
238 Op->Common.InlineComment = NULL;
239 Op->Common.EndNodeComment = NULL;
240 Op->Common.NameComment = NULL;
241 Op->Common.CommentList = NULL;
242 Op->Common.EndBlkComment = NULL;
243 Op->Common.CloseBraceComment = NULL;
244 Op->Common.CvFilename = NULL;
245 Op->Common.CvParentFilename = NULL;
246 }
247
248
249 /*******************************************************************************
250 *
251 * FUNCTION: CvCommentExists
252 *
253 * PARAMETERS: Address - check if this address appears in the list
254 *
255 * RETURN: BOOLEAN - TRUE if the address exists.
256 *
257 * DESCRIPTION: Look at the pointer address and check if this appears in the
258 * list of all addresses. If it exists in the list, return TRUE
259 * if it exists. Otherwise add to the list and return FALSE.
260 *
261 ******************************************************************************/
262
263 static BOOLEAN
CvCommentExists(UINT8 * Address)264 CvCommentExists (
265 UINT8 *Address)
266 {
267 ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead;
268 UINT8 Option;
269
270
271 if (!Address)
272 {
273 return (FALSE);
274 }
275
276 Option = *(Address + 1);
277
278 /*
279 * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as
280 * comments. They serve as markers for where the file starts and ends.
281 */
282 if ((Option == FILENAME_COMMENT) ||
283 (Option == PARENTFILENAME_COMMENT))
284 {
285 return (FALSE);
286 }
287
288 if (!Current)
289 {
290 AcpiGbl_CommentAddrListHead =
291 AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
292 AcpiGbl_CommentAddrListHead->Addr = Address;
293 AcpiGbl_CommentAddrListHead->Next = NULL;
294 return (FALSE);
295 }
296 else
297 {
298 while (Current)
299 {
300 if (Current->Addr != Address)
301 {
302 Current = Current->Next;
303 }
304 else
305 {
306 return (TRUE);
307 }
308 }
309
310 /*
311 * If the execution gets to this point, it means that this
312 * address does not exists in the list. Add this address to the
313 * beginning of the list.
314 */
315 Current = AcpiGbl_CommentAddrListHead;
316 AcpiGbl_CommentAddrListHead =
317 AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
318
319 AcpiGbl_CommentAddrListHead->Addr = Address;
320 AcpiGbl_CommentAddrListHead->Next = Current;
321 return (FALSE);
322 }
323 }
324
325
326 /*******************************************************************************
327 *
328 * FUNCTION: CvFilenameExists
329 *
330 * PARAMETERS: Filename - filename to search
331 *
332 * RETURN: ACPI_FILE_NODE - a pointer to a file node
333 *
334 * DESCRIPTION: Look for the given filename in the file dependency tree.
335 * Returns the file node if it exists, returns NULL if it does not.
336 *
337 ******************************************************************************/
338
339 ACPI_FILE_NODE*
CvFilenameExists(char * Filename,ACPI_FILE_NODE * Head)340 CvFilenameExists(
341 char *Filename,
342 ACPI_FILE_NODE *Head)
343 {
344 ACPI_FILE_NODE *Current = Head;
345
346
347 if (!Filename)
348 {
349 return (NULL);
350 }
351
352 while (Current)
353 {
354 if (!AcpiUtStricmp (Current->Filename, Filename))
355 {
356 return (Current);
357 }
358
359 Current = Current->Next;
360 }
361 return (NULL);
362 }
363
364
365 /*******************************************************************************
366 *
367 * FUNCTION: CvFileAddressLookup
368 *
369 * PARAMETERS: Address - address to look up
370 * Head - file dependency tree
371 *
372 * RETURN: ACPI_FILE_NODE - pointer to a file node containing the address
373 *
374 * DESCRIPTION: Look for the given address in the file dependency tree.
375 * Returns the first file node where the given address is within
376 * the file node's starting and ending address.
377 *
378 ******************************************************************************/
379
380 static ACPI_FILE_NODE *
CvFileAddressLookup(char * Address,ACPI_FILE_NODE * Head)381 CvFileAddressLookup(
382 char *Address,
383 ACPI_FILE_NODE *Head)
384 {
385 ACPI_FILE_NODE *Current = Head;
386
387
388 while (Current)
389 {
390 if ((Address >= Current->FileStart) &&
391 (Address < Current->FileEnd ||
392 !Current->FileEnd))
393 {
394 return (Current);
395 }
396
397 Current = Current->Next;
398 }
399
400 return (NULL);
401 }
402
403
404 /*******************************************************************************
405 *
406 * FUNCTION: CvLabelFileNode
407 *
408 * PARAMETERS: Op
409 *
410 * RETURN: None
411 *
412 * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field
413 * within the file tree and fills in appropriate file information
414 * from a matching node within the tree.
415 * This is referred as ASL_CV_LABEL_FILENODE.
416 *
417 ******************************************************************************/
418
419 void
CvLabelFileNode(ACPI_PARSE_OBJECT * Op)420 CvLabelFileNode(
421 ACPI_PARSE_OBJECT *Op)
422 {
423 ACPI_FILE_NODE *Node;
424
425
426 if (!Op)
427 {
428 return;
429 }
430
431 Node = CvFileAddressLookup ((char *)
432 Op->Common.Aml, AcpiGbl_FileTreeRoot);
433 if (!Node)
434 {
435 return;
436 }
437
438 Op->Common.CvFilename = Node->Filename;
439 if (Node->Parent)
440 {
441 Op->Common.CvParentFilename = Node->Parent->Filename;
442 }
443 else
444 {
445 Op->Common.CvParentFilename = Node->Filename;
446 }
447 }
448
449
450 /*******************************************************************************
451 *
452 * FUNCTION: CvAddToFileTree
453 *
454 * PARAMETERS: Filename - Address containing the name of the current
455 * filename
456 * PreviousFilename - Address containing the name of the previous
457 * filename
458 *
459 * RETURN: None
460 *
461 * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist.
462 *
463 ******************************************************************************/
464
465 static void
CvAddToFileTree(char * Filename,char * PreviousFilename)466 CvAddToFileTree (
467 char *Filename,
468 char *PreviousFilename)
469 {
470 ACPI_FILE_NODE *Node;
471
472
473 if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
474 PreviousFilename)
475 {
476 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
477 if (Node)
478 {
479 /*
480 * Set the end point of the PreviousFilename to the address
481 * of Filename.
482 */
483 Node->FileEnd = Filename;
484 }
485 }
486 else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
487 !PreviousFilename)
488 {
489 return;
490 }
491
492 Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
493 if (Node && PreviousFilename)
494 {
495 /*
496 * Update the end of the previous file and all of their parents'
497 * ending addresses. This is done to ensure that parent file
498 * ranges extend to the end of their childrens' files.
499 */
500 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
501 if (Node && (Node->FileEnd < Filename))
502 {
503 Node->FileEnd = Filename;
504 Node = Node->Parent;
505 while (Node)
506 {
507 if (Node->FileEnd < Filename)
508 {
509 Node->FileEnd = Filename;
510 }
511
512 Node = Node->Parent;
513 }
514 }
515 }
516 else
517 {
518 Node = AcpiGbl_FileTreeRoot;
519 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
520
521 AcpiGbl_FileTreeRoot->Next = Node;
522 AcpiGbl_FileTreeRoot->Parent = NULL;
523 AcpiGbl_FileTreeRoot->Filename = Filename;
524 AcpiGbl_FileTreeRoot->FileStart = Filename;
525 AcpiGbl_FileTreeRoot->IncludeWritten = FALSE;
526 AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+");
527
528 /*
529 * If we can't open the file, we need to abort here before we
530 * accidentally write to a NULL file.
531 */
532 if (!AcpiGbl_FileTreeRoot->File)
533 {
534 /* delete the .xxx file */
535
536 FlDeleteFile (ASL_FILE_AML_OUTPUT);
537 sprintf (AslGbl_MsgBuffer, "\"%s\" - %s", Filename, strerror (errno));
538 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0,
539 NULL, AslGbl_MsgBuffer);
540 AslAbort ();
541 }
542 }
543 }
544
545
546 /*******************************************************************************
547 *
548 * FUNCTION: CvSetFileParent
549 *
550 * PARAMETERS: ChildFile - contains the filename of the child file
551 * ParentFile - contains the filename of the parent file.
552 *
553 * RETURN: None
554 *
555 * DESCRIPTION: Point the parent pointer of the Child to the node that
556 * corresponds with the parent file node.
557 *
558 ******************************************************************************/
559
560 static void
CvSetFileParent(char * ChildFile,char * ParentFile)561 CvSetFileParent (
562 char *ChildFile,
563 char *ParentFile)
564 {
565 ACPI_FILE_NODE *Child;
566 ACPI_FILE_NODE *Parent;
567
568
569 Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot);
570 Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot);
571
572 if (Child && Parent)
573 {
574 Child->Parent = Parent;
575
576 while (Child->Parent)
577 {
578 if (Child->Parent->FileEnd < Child->FileStart)
579 {
580 Child->Parent->FileEnd = Child->FileStart;
581 }
582
583 Child = Child->Parent;
584 }
585 }
586 }
587
588
589 /*******************************************************************************
590 *
591 * FUNCTION: CvCaptureCommentsOnly
592 *
593 * PARAMETERS: ParserState - A parser state object
594 *
595 * RETURN: None
596 *
597 * DESCRIPTION: Look at the aml that the parser state is pointing to,
598 * capture any AML_COMMENT_OP and it's arguments and increment the
599 * aml pointer past the comment. Comments are transferred to parse
600 * nodes through CvTransferComments() as well as
601 * AcpiPsBuildNamedOp().
602 * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY.
603 *
604 ******************************************************************************/
605
606 void
CvCaptureCommentsOnly(ACPI_PARSE_STATE * ParserState)607 CvCaptureCommentsOnly (
608 ACPI_PARSE_STATE *ParserState)
609 {
610 UINT8 *Aml = ParserState->Aml;
611 UINT16 Opcode = (UINT16) ACPI_GET8 (Aml);
612 UINT32 Length = 0;
613 UINT8 CommentOption;
614 BOOLEAN StdDefBlockFlag = FALSE;
615 ACPI_COMMENT_NODE *CommentNode;
616 ACPI_FILE_NODE *FileNode;
617
618
619 if (!AcpiGbl_CaptureComments ||
620 Opcode != AML_COMMENT_OP)
621 {
622 return;
623 }
624
625 while (Opcode == AML_COMMENT_OP)
626 {
627 CvDbgPrint ("comment aml address: %p\n", Aml);
628
629 if (CvCommentExists(ParserState->Aml))
630 {
631 CvDbgPrint ("Avoiding capturing an existing comment.\n");
632 }
633 else
634 {
635 CommentOption = *(Aml +1);
636
637 /*
638 * Increment past the comment option and point the
639 * appropriate char pointers
640 */
641 Aml += 2;
642
643 /* Found a comment. Now, set pointers to these comments. */
644
645 switch (CommentOption)
646 {
647 case STD_DEFBLK_COMMENT:
648
649 StdDefBlockFlag = TRUE;
650
651 /*
652 * Add to a linked list of nodes. This list will be
653 * taken by the parse node created next.
654 */
655 CommentNode = AcpiOsAcquireObject (
656 AcpiGbl_RegCommentCache);
657 CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
658 CommentNode->Next = NULL;
659
660 if (!AcpiGbl_DefBlkCommentListHead)
661 {
662 AcpiGbl_DefBlkCommentListHead = CommentNode;
663 AcpiGbl_DefBlkCommentListTail = CommentNode;
664 }
665 else
666 {
667 AcpiGbl_DefBlkCommentListTail->Next = CommentNode;
668 AcpiGbl_DefBlkCommentListTail =
669 AcpiGbl_DefBlkCommentListTail->Next;
670 }
671 break;
672
673 case STANDARD_COMMENT:
674
675 CvDbgPrint ("found regular comment.\n");
676
677 /*
678 * Add to a linked list of nodes. This list will be
679 * taken by the parse node created next.
680 */
681 CommentNode = AcpiOsAcquireObject (
682 AcpiGbl_RegCommentCache);
683 CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
684 CommentNode->Next = NULL;
685
686 if (!AcpiGbl_RegCommentListHead)
687 {
688 AcpiGbl_RegCommentListHead = CommentNode;
689 AcpiGbl_RegCommentListTail = CommentNode;
690 }
691 else
692 {
693 AcpiGbl_RegCommentListTail->Next = CommentNode;
694 AcpiGbl_RegCommentListTail =
695 AcpiGbl_RegCommentListTail->Next;
696 }
697 break;
698
699 case ENDBLK_COMMENT:
700
701 CvDbgPrint ("found endblk comment.\n");
702
703 /* Add to a linked list of nodes. This will be
704 * taken by the next created parse node.
705 */
706 CommentNode = AcpiOsAcquireObject (
707 AcpiGbl_RegCommentCache);
708 CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
709 CommentNode->Next = NULL;
710
711 if (!AcpiGbl_EndBlkCommentListHead)
712 {
713 AcpiGbl_EndBlkCommentListHead = CommentNode;
714 AcpiGbl_EndBlkCommentListTail = CommentNode;
715 }
716 else
717 {
718 AcpiGbl_EndBlkCommentListTail->Next = CommentNode;
719 AcpiGbl_EndBlkCommentListTail =
720 AcpiGbl_EndBlkCommentListTail->Next;
721 }
722 break;
723
724 case INLINE_COMMENT:
725
726 CvDbgPrint ("found inline comment.\n");
727 AcpiGbl_CurrentInlineComment =
728 ACPI_CAST_PTR (char, Aml);
729 break;
730
731 case ENDNODE_COMMENT:
732
733 CvDbgPrint ("found EndNode comment.\n");
734 AcpiGbl_CurrentEndNodeComment =
735 ACPI_CAST_PTR (char, Aml);
736 break;
737
738 case CLOSE_BRACE_COMMENT:
739
740 CvDbgPrint ("found close brace comment.\n");
741 AcpiGbl_CurrentCloseBraceComment =
742 ACPI_CAST_PTR (char, Aml);
743 break;
744
745 case END_DEFBLK_COMMENT:
746
747 CvDbgPrint ("Found comment that belongs after"
748 " the } for a definition block.\n");
749 AcpiGbl_CurrentScope->Common.CloseBraceComment =
750 ACPI_CAST_PTR (char, Aml);
751 break;
752
753 case FILENAME_COMMENT:
754
755 CvDbgPrint ("Found a filename: %s\n",
756 ACPI_CAST_PTR (char, Aml));
757 FileNode = CvFilenameExists (
758 ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot);
759
760 /*
761 * If there is an INCLUDE_COMMENT followed by a
762 * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment
763 * that is emitted before the #include for the file.
764 * We will save the IncludeComment within the FileNode
765 * associated with this FILENAME_COMMENT.
766 */
767 if (FileNode && AcpiGbl_IncCommentListHead)
768 {
769 FileNode->IncludeComment = AcpiGbl_IncCommentListHead;
770 AcpiGbl_IncCommentListHead = NULL;
771 AcpiGbl_IncCommentListTail = NULL;
772 }
773 break;
774
775 case PARENTFILENAME_COMMENT:
776 CvDbgPrint (" Found a parent filename.\n");
777 break;
778
779 case INCLUDE_COMMENT:
780
781 /*
782 * Add to a linked list. This list will be taken by the
783 * parse node created next. See the FILENAME_COMMENT case
784 * for more details
785 */
786 CommentNode = AcpiOsAcquireObject (
787 AcpiGbl_RegCommentCache);
788 CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
789 CommentNode->Next = NULL;
790
791 if (!AcpiGbl_IncCommentListHead)
792 {
793 AcpiGbl_IncCommentListHead = CommentNode;
794 AcpiGbl_IncCommentListTail = CommentNode;
795 }
796 else
797 {
798 AcpiGbl_IncCommentListTail->Next = CommentNode;
799 AcpiGbl_IncCommentListTail =
800 AcpiGbl_IncCommentListTail->Next;
801 }
802
803 CvDbgPrint ("Found a include comment: %s\n",
804 CommentNode->Comment);
805 break;
806
807 default:
808
809 /* Not a valid comment option. Revert the AML */
810
811 goto DefBlock;
812
813 } /* End switch statement */
814
815 } /* End else */
816
817 /* Determine the length and move forward that amount */
818
819 Length = 0;
820 while (ParserState->Aml[Length])
821 {
822 Length++;
823 }
824
825 ParserState->Aml += Length + 1;
826
827 /* Peek at the next Opcode. */
828
829 Aml = ParserState->Aml;
830 Opcode = (UINT16) ACPI_GET8 (Aml);
831 }
832
833 DefBlock:
834 if (StdDefBlockFlag)
835 {
836 /*
837 * Give all of its comments to the current scope, which is known as
838 * the definition block, since STD_DEFBLK_COMMENT only appears after
839 * definition block headers.
840 */
841 AcpiGbl_CurrentScope->Common.CommentList
842 = AcpiGbl_DefBlkCommentListHead;
843 AcpiGbl_DefBlkCommentListHead = NULL;
844 AcpiGbl_DefBlkCommentListTail = NULL;
845 }
846 }
847
848
849 /*******************************************************************************
850 *
851 * FUNCTION: CvCaptureComments
852 *
853 * PARAMETERS: ParserState - A parser state object
854 *
855 * RETURN: None
856 *
857 * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly
858 * This is referred as ASL_CV_CAPTURE_COMMENTS.
859 *
860 ******************************************************************************/
861
862 void
CvCaptureComments(ACPI_WALK_STATE * WalkState)863 CvCaptureComments (
864 ACPI_WALK_STATE *WalkState)
865 {
866 UINT8 *Aml;
867 UINT16 Opcode;
868 const ACPI_OPCODE_INFO *OpInfo;
869
870
871 if (!AcpiGbl_CaptureComments)
872 {
873 return;
874 }
875
876 /*
877 * Before parsing, check to see that comments that come directly
878 * after deferred opcodes aren't being processed.
879 */
880 Aml = WalkState->ParserState.Aml;
881 Opcode = (UINT16) ACPI_GET8 (Aml);
882 OpInfo = AcpiPsGetOpcodeInfo (Opcode);
883
884 if (!(OpInfo->Flags & AML_DEFER) ||
885 ((OpInfo->Flags & AML_DEFER) &&
886 (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1)))
887 {
888 CvCaptureCommentsOnly (&WalkState->ParserState);
889 WalkState->Aml = WalkState->ParserState.Aml;
890 }
891
892 }
893
894
895 /*******************************************************************************
896 *
897 * FUNCTION: CvTransferComments
898 *
899 * PARAMETERS: Op - Transfer comments to this Op
900 *
901 * RETURN: None
902 *
903 * DESCRIPTION: Transfer all of the comments stored in global containers to the
904 * given Op. This will be invoked shortly after the parser creates
905 * a ParseOp.
906 * This is referred as ASL_CV_TRANSFER_COMMENTS.
907 *
908 ******************************************************************************/
909
910 void
CvTransferComments(ACPI_PARSE_OBJECT * Op)911 CvTransferComments (
912 ACPI_PARSE_OBJECT *Op)
913 {
914
915 Op->Common.InlineComment = AcpiGbl_CurrentInlineComment;
916 AcpiGbl_CurrentInlineComment = NULL;
917
918 Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment;
919 AcpiGbl_CurrentEndNodeComment = NULL;
920
921 Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment;
922 AcpiGbl_CurrentCloseBraceComment = NULL;
923
924 Op->Common.CommentList = AcpiGbl_RegCommentListHead;
925 AcpiGbl_RegCommentListHead = NULL;
926 AcpiGbl_RegCommentListTail = NULL;
927
928 Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead;
929 AcpiGbl_EndBlkCommentListHead = NULL;
930 AcpiGbl_EndBlkCommentListTail = NULL;
931 }
932