Home | History | Annotate | Line # | Download | only in compiler
cvparser.c revision 1.1.1.9
      1 /******************************************************************************
      2  *
      3  * Module Name: cvparser - Converter functions that are called from the AML
      4  *                         parser.
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2021, 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
     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
    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
    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
    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*
    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 *
    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
    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
    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
    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
    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
    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
    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