Home | History | Annotate | Line # | Download | only in compiler
cvdisasm.c revision 1.1.1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: cvcompiler - ASL-/ASL+ converter functions
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "acparser.h"
     46 #include "amlcode.h"
     47 #include "acdebug.h"
     48 #include "acconvert.h"
     49 
     50 
     51 /* Local prototypes */
     52 
     53 static void
     54 CvPrintInclude(
     55     ACPI_FILE_NODE          *FNode,
     56     UINT32                  Level);
     57 
     58 static BOOLEAN
     59 CvListIsSingleton (
     60     ACPI_COMMENT_NODE       *CommentList);
     61 
     62 
     63 /*******************************************************************************
     64  *
     65  * FUNCTION:    CvPrintOneCommentList
     66  *
     67  * PARAMETERS:  CommentList
     68  *              Level
     69  *
     70  * RETURN:      None
     71  *
     72  * DESCRIPTION: Prints all comments within the given list.
     73  *              This is referred as ASL_CV_PRINT_ONE_COMMENT_LIST.
     74  *
     75  ******************************************************************************/
     76 
     77 void
     78 CvPrintOneCommentList (
     79     ACPI_COMMENT_NODE       *CommentList,
     80     UINT32                  Level)
     81 {
     82     ACPI_COMMENT_NODE       *Current = CommentList;
     83     ACPI_COMMENT_NODE       *Previous;
     84 
     85 
     86     while (Current)
     87     {
     88         Previous = Current;
     89         if (Current->Comment)
     90         {
     91             AcpiDmIndent(Level);
     92             AcpiOsPrintf("%s\n", Current->Comment);
     93             Current->Comment = NULL;
     94         }
     95 
     96         Current = Current->Next;
     97         AcpiOsReleaseObject(AcpiGbl_RegCommentCache, Previous);
     98     }
     99 }
    100 
    101 
    102 /*******************************************************************************
    103  *
    104  * FUNCTION:    CvListIsSingleton
    105  *
    106  * PARAMETERS:  CommentList     - check to see if this is a single item list.
    107  *
    108  * RETURN:      BOOLEAN
    109  *
    110  * DESCRIPTION: Returns TRUE if CommentList only contains 1 node.
    111  *
    112  ******************************************************************************/
    113 
    114 static BOOLEAN
    115 CvListIsSingleton (
    116     ACPI_COMMENT_NODE       *CommentList)
    117 
    118 {
    119 
    120     if (!CommentList)
    121     {
    122         return (FALSE);
    123     }
    124     else if (CommentList->Next)
    125     {
    126         return (FALSE);
    127     }
    128 
    129     return (TRUE);
    130 }
    131 
    132 
    133 /*******************************************************************************
    134  *
    135  * FUNCTION:    CvPrintOneCommentType
    136  *
    137  * PARAMETERS:  Op
    138  *              CommentType
    139  *              EndStr - String to print after printing the comment
    140  *              Level  - indentation level for comment lists.
    141  *
    142  * RETURN:      None
    143  *
    144  * DESCRIPTION: Prints all comments of CommentType within the given Op and
    145  *              clears the printed comment from the Op.
    146  *              This is referred as ASL_CV_PRINT_ONE_COMMENT.
    147  *
    148  ******************************************************************************/
    149 
    150 void
    151 CvPrintOneCommentType (
    152     ACPI_PARSE_OBJECT       *Op,
    153     UINT8                   CommentType,
    154     char*                   EndStr,
    155     UINT32                  Level)
    156 {
    157     BOOLEAN                 CommentExists = FALSE;
    158     char                    **CommentToPrint = NULL;
    159 
    160 
    161     switch (CommentType)
    162     {
    163     case AML_COMMENT_STANDARD:
    164 
    165         if (CvListIsSingleton (Op->Common.CommentList))
    166         {
    167             CvPrintOneCommentList (Op->Common.CommentList, Level);
    168             AcpiOsPrintf ("\n");
    169         }
    170         else
    171         {
    172             CvPrintOneCommentList (Op->Common.CommentList, Level);
    173         }
    174 
    175         Op->Common.CommentList = NULL;
    176         return;
    177 
    178     case AML_COMMENT_ENDBLK:
    179 
    180         if (Op->Common.EndBlkComment)
    181         {
    182             CvPrintOneCommentList (Op->Common.EndBlkComment, Level);
    183             Op->Common.EndBlkComment = NULL;
    184             AcpiDmIndent(Level);
    185         }
    186         return;
    187 
    188     case AMLCOMMENT_INLINE:
    189 
    190         CommentToPrint = &Op->Common.InlineComment;
    191         break;
    192 
    193     case AML_COMMENT_END_NODE:
    194 
    195         CommentToPrint = &Op->Common.EndNodeComment;
    196         break;
    197 
    198     case AML_NAMECOMMENT:
    199 
    200         CommentToPrint = &Op->Common.NameComment;
    201         break;
    202 
    203     case AML_COMMENT_CLOSE_BRACE:
    204 
    205         CommentToPrint = &Op->Common.CloseBraceComment;
    206         break;
    207 
    208     default:
    209         return;
    210     }
    211 
    212     if (*CommentToPrint)
    213     {
    214         CommentExists = TRUE;
    215         AcpiOsPrintf ("%s", *CommentToPrint);
    216         *CommentToPrint = NULL;
    217     }
    218 
    219     if (CommentExists && EndStr)
    220     {
    221         AcpiOsPrintf ("%s", EndStr);
    222     }
    223 }
    224 
    225 
    226 /*******************************************************************************
    227  *
    228  * FUNCTION:    CvCloseBraceWriteComment
    229  *
    230  * PARAMETERS:  Op
    231  *              Level
    232  *
    233  * RETURN:      None
    234  *
    235  * DESCRIPTION: Print a close brace } and any open brace comments associated
    236  *              with this parse object.
    237  *              This is referred as ASL_CV_CLOSE_BRACE.
    238  *
    239  ******************************************************************************/
    240 
    241 void
    242 CvCloseBraceWriteComment(
    243     ACPI_PARSE_OBJECT       *Op,
    244     UINT32                  Level)
    245 {
    246 
    247     if (!AcpiGbl_CaptureComments)
    248     {
    249         AcpiOsPrintf ("}");
    250         return;
    251     }
    252 
    253     CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
    254     AcpiOsPrintf ("}");
    255     CvPrintOneCommentType (Op, AML_COMMENT_CLOSE_BRACE, NULL, Level);
    256 }
    257 
    258 
    259 /*******************************************************************************
    260  *
    261  * FUNCTION:    CvCloseParenWriteComment
    262  *
    263  * PARAMETERS:  Op
    264  *              Level
    265  *
    266  * RETURN:      None
    267  *
    268  * DESCRIPTION: Print a closing paren ) and any end node comments associated
    269  *              with this parse object.
    270  *              This is referred as ASL_CV_CLOSE_PAREN.
    271  *
    272  ******************************************************************************/
    273 
    274 void
    275 CvCloseParenWriteComment(
    276     ACPI_PARSE_OBJECT       *Op,
    277     UINT32                  Level)
    278 {
    279 
    280     if (!AcpiGbl_CaptureComments)
    281     {
    282         AcpiOsPrintf (")");
    283         return;
    284     }
    285 
    286     /*
    287      * If this op has a BLOCK_BRACE, then output the comment when the
    288      * disassembler calls CvCloseBraceWriteComment
    289      */
    290     if (AcpiDmBlockType (Op) == BLOCK_PAREN)
    291     {
    292         CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
    293     }
    294 
    295     AcpiOsPrintf (")");
    296 
    297     if (Op->Common.EndNodeComment)
    298     {
    299         CvPrintOneCommentType (Op, AML_COMMENT_END_NODE, NULL, Level);
    300     }
    301     else if ((Op->Common.Parent->Common.AmlOpcode == AML_IF_OP) &&
    302          Op->Common.Parent->Common.EndNodeComment)
    303     {
    304         CvPrintOneCommentType (Op->Common.Parent,
    305             AML_COMMENT_END_NODE, NULL, Level);
    306     }
    307 }
    308 
    309 
    310 /*******************************************************************************
    311  *
    312  * FUNCTION:    CvFileHasSwitched
    313  *
    314  * PARAMETERS:  Op
    315  *
    316  * RETURN:      BOOLEAN
    317  *
    318  * DESCRIPTION: Determine whether if a file has switched.
    319  *              TRUE - file has switched.
    320  *              FALSE - file has not switched.
    321  *              This is referred as ASL_CV_FILE_HAS_SWITCHED.
    322  *
    323  ******************************************************************************/
    324 
    325 BOOLEAN
    326 CvFileHasSwitched(
    327     ACPI_PARSE_OBJECT       *Op)
    328 {
    329 
    330     if (Op->Common.CvFilename   &&
    331         AcpiGbl_CurrentFilename &&
    332         AcpiUtStricmp(Op->Common.CvFilename, AcpiGbl_CurrentFilename))
    333     {
    334         return (TRUE);
    335     }
    336 
    337     return (FALSE);
    338 }
    339 
    340 
    341 /*******************************************************************************
    342  *
    343  * FUNCTION:    CvPrintInclude
    344  *
    345  * PARAMETERS:  FNode - Write an Include statement for the file that is pointed
    346  *                      by FNode->File.
    347  *              Level - indentation level
    348  *
    349  * RETURN:      None
    350  *
    351  * DESCRIPTION: Write the ASL Include statement for FNode->File in the file
    352  *              indicated by FNode->Parent->File. Note this function emits
    353  *              actual ASL code rather than comments. This switches the output
    354  *              file to FNode->Parent->File.
    355  *
    356  ******************************************************************************/
    357 
    358 static void
    359 CvPrintInclude(
    360     ACPI_FILE_NODE          *FNode,
    361     UINT32                  Level)
    362 {
    363 
    364     if (!FNode || FNode->IncludeWritten)
    365     {
    366         return;
    367     }
    368 
    369     CvDbgPrint ("Writing include for %s within %s\n",
    370         FNode->Filename, FNode->Parent->Filename);
    371     AcpiOsRedirectOutput (FNode->Parent->File);
    372     CvPrintOneCommentList (FNode->IncludeComment, Level);
    373 
    374     AcpiDmIndent (Level);
    375     AcpiOsPrintf ("Include (\"%s\")\n", FNode->Filename);
    376     CvDbgPrint ("emitted the following: Include (\"%s\")\n",
    377         FNode->Filename);
    378     FNode->IncludeWritten = TRUE;
    379 }
    380 
    381 
    382 /*******************************************************************************
    383  *
    384  * FUNCTION:    CvSwitchFiles
    385  *
    386  * PARAMETERS:  Level                   - indentation level
    387  *              Op
    388  *
    389  * RETURN:      None
    390  *
    391  * DESCRIPTION: Switch the outputfile and write ASL Include statement. Note,
    392  *              this function emits actual ASL code rather than comments.
    393  *              This is referred as ASL_CV_SWITCH_FILES.
    394  *
    395  ******************************************************************************/
    396 
    397 void
    398 CvSwitchFiles(
    399     UINT32                  Level,
    400     ACPI_PARSE_OBJECT       *Op)
    401 {
    402     char                    *Filename = Op->Common.CvFilename;
    403     ACPI_FILE_NODE          *FNode;
    404     ACPI_FILE_NODE          *Current;
    405 
    406 
    407     CvDbgPrint ("Switching from %s to %s\n", AcpiGbl_CurrentFilename,
    408         Filename);
    409     FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
    410     if (!FNode)
    411     {
    412         /*
    413          * At this point, each Filename should exist in AcpiGbl_FileTreeRoot
    414          * if it does not exist, then abort.
    415          */
    416         FlDeleteFile (ASL_FILE_AML_OUTPUT);
    417         sprintf (MsgBuffer, "\"Cannot find %s\" - %s",
    418             Filename, strerror (errno));
    419         AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0,
    420             NULL, MsgBuffer);
    421         AslAbort ();
    422     }
    423 
    424     Current = FNode;
    425 
    426     /*
    427      * If the previous file is a descendent of the current file,
    428      * make sure that Include statements from the current file
    429      * to the previous have been emitted.
    430      */
    431     while (Current &&
    432            Current->Parent &&
    433            AcpiUtStricmp (Current->Filename, AcpiGbl_CurrentFilename))
    434     {
    435         CvPrintInclude (Current, Level);
    436         Current = Current->Parent;
    437     }
    438 
    439     /* Redirect output to Op->Common.CvFilename */
    440 
    441     AcpiOsRedirectOutput (FNode->File);
    442     AcpiGbl_CurrentFilename = FNode->Filename;
    443 }
    444