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