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