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