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