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