Home | History | Annotate | Line # | Download | only in compiler
asldebug.c revision 1.1.1.10
      1 /******************************************************************************
      2  *
      3  * Module Name: asldebug -- Debug output support
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 "aslcompiler.y.h"
     46 
     47 
     48 #define _COMPONENT          ACPI_COMPILER
     49         ACPI_MODULE_NAME    ("asldebug")
     50 
     51 
     52 /* Local prototypes */
     53 
     54 static void
     55 UtDumpParseOpName (
     56     ACPI_PARSE_OBJECT       *Op,
     57     UINT32                  Level,
     58     UINT32                  DataLength);
     59 
     60 static char *
     61 UtCreateEscapeSequences (
     62     char                    *InString);
     63 
     64 
     65 /*******************************************************************************
     66  *
     67  * FUNCTION:    CvDbgPrint
     68  *
     69  * PARAMETERS:  Type                - Type of output
     70  *              Fmt                 - Printf format string
     71  *              ...                 - variable printf list
     72  *
     73  * RETURN:      None
     74  *
     75  * DESCRIPTION: Print statement for debug messages within the converter.
     76  *
     77  ******************************************************************************/
     78 
     79 void
     80 CvDbgPrint (
     81     char                    *Fmt,
     82     ...)
     83 {
     84     va_list                 Args;
     85 
     86 
     87     if (!AcpiGbl_CaptureComments || !AcpiGbl_DebugAslConversion)
     88     {
     89         return;
     90     }
     91 
     92     va_start (Args, Fmt);
     93     (void) vfprintf (AcpiGbl_ConvDebugFile, Fmt, Args);
     94     va_end (Args);
     95     return;
     96 }
     97 
     98 
     99 /*******************************************************************************
    100  *
    101  * FUNCTION:    UtDumpIntegerOp
    102  *
    103  * PARAMETERS:  Op                  - Current parse op
    104  *              Level               - Current output indentation level
    105  *              IntegerLength       - Output length of the integer (2/4/8/16)
    106  *
    107  * RETURN:      None
    108  *
    109  * DESCRIPTION: Emit formatted debug output for "integer" ops.
    110  *              Note: IntegerLength must be one of 2,4,8,16.
    111  *
    112  ******************************************************************************/
    113 
    114 void
    115 UtDumpIntegerOp (
    116     ACPI_PARSE_OBJECT       *Op,
    117     UINT32                  Level,
    118     UINT32                  IntegerLength)
    119 {
    120 
    121     /* Emit the ParseOp name, leaving room for the integer */
    122 
    123     UtDumpParseOpName (Op, Level, IntegerLength);
    124 
    125     /* Emit the integer based upon length */
    126 
    127     switch (IntegerLength)
    128     {
    129     case 2: /* Byte */
    130     case 4: /* Word */
    131     case 8: /* Dword */
    132 
    133         DbgPrint (ASL_TREE_OUTPUT,
    134             "%*.*X", IntegerLength, IntegerLength, (UINT32) Op->Asl.Value.Integer);
    135         break;
    136 
    137     case 16: /* Qword and Integer */
    138 
    139         DbgPrint (ASL_TREE_OUTPUT,
    140             "%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
    141         break;
    142 
    143     default:
    144         break;
    145     }
    146 }
    147 
    148 
    149 /*******************************************************************************
    150  *
    151  * FUNCTION:    UtDumpStringOp
    152  *
    153  * PARAMETERS:  Op                  - Current parse op
    154  *              Level               - Current output indentation level
    155  *
    156  * RETURN:      None
    157  *
    158  * DESCRIPTION: Emit formatted debug output for String/Pathname ops.
    159  *
    160  ******************************************************************************/
    161 
    162 void
    163 UtDumpStringOp (
    164     ACPI_PARSE_OBJECT       *Op,
    165     UINT32                  Level)
    166 {
    167     char                    *String;
    168 
    169 
    170     String = Op->Asl.Value.String;
    171     if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
    172     {
    173         /*
    174          * For the "path" ops NAMEPATH, NAMESEG, METHODCALL -- if the
    175          * ExternalName is valid, it takes precedence. In these cases the
    176          * Value.String is the raw "internal" name from the AML code, which
    177          * we don't want to use, because it contains non-ascii characters.
    178          */
    179         if (Op->Asl.ExternalName)
    180         {
    181             String = Op->Asl.ExternalName;
    182         }
    183     }
    184 
    185     if (!String)
    186     {
    187         DbgPrint (ASL_TREE_OUTPUT,
    188             " ERROR: Could not find a valid String/Path pointer\n");
    189         return;
    190     }
    191 
    192     String = UtCreateEscapeSequences (String);
    193 
    194     /* Emit the ParseOp name, leaving room for the string */
    195 
    196     UtDumpParseOpName (Op, Level, strlen (String));
    197     DbgPrint (ASL_TREE_OUTPUT, "%s", String);
    198 }
    199 
    200 
    201 /*******************************************************************************
    202  *
    203  * FUNCTION:    UtCreateEscapeSequences
    204  *
    205  * PARAMETERS:  InString            - ASCII string to be expanded
    206  *
    207  * RETURN:      Expanded string
    208  *
    209  * DESCRIPTION: Expand all non-printable ASCII bytes (0-0x1F) to escape
    210  *              sequences. For example, hex 14 becomes \x14
    211  *
    212  * NOTE:        Since this function is used for debug output only, it does
    213  *              not attempt to translate into the "known" escape sequences
    214  *              such as \a, \f, \t, etc.
    215  *
    216  ******************************************************************************/
    217 
    218 static char *
    219 UtCreateEscapeSequences (
    220     char                    *InString)
    221 {
    222     char                    *String = InString;
    223     char                    *OutString;
    224     char                    *OutStringPtr;
    225     UINT32                  InStringLength = 0;
    226     UINT32                  EscapeCount = 0;
    227 
    228 
    229     /*
    230      * Determine up front how many escapes are within the string.
    231      * Obtain the input string length while doing so.
    232      */
    233     while (*String)
    234     {
    235         if ((*String <= 0x1F) || (*String >= 0x7F))
    236         {
    237             EscapeCount++;
    238         }
    239 
    240         InStringLength++;
    241         String++;
    242     }
    243 
    244     if (!EscapeCount)
    245     {
    246         return (InString); /* No escapes, nothing to do */
    247     }
    248 
    249     /* New string buffer, 3 extra chars per escape (4 total) */
    250 
    251     OutString = UtLocalCacheCalloc (InStringLength + (EscapeCount * 3));
    252     OutStringPtr = OutString;
    253 
    254     /* Convert non-ascii or non-printable chars to escape sequences */
    255 
    256     while (*InString)
    257     {
    258         if ((*InString <= 0x1F) || (*InString >= 0x7F))
    259         {
    260             /* Insert a \x hex escape sequence */
    261 
    262             OutStringPtr[0] = '\\';
    263             OutStringPtr[1] = 'x';
    264             OutStringPtr[2] = AcpiUtHexToAsciiChar (*InString, 4);
    265             OutStringPtr[3] = AcpiUtHexToAsciiChar (*InString, 0);
    266             OutStringPtr += 4;
    267         }
    268         else /* Normal ASCII character */
    269         {
    270             *OutStringPtr = *InString;
    271             OutStringPtr++;
    272         }
    273 
    274         InString++;
    275     }
    276 
    277     return (OutString);
    278 }
    279 
    280 
    281 /*******************************************************************************
    282  *
    283  * FUNCTION:    UtDumpBasicOp
    284  *
    285  * PARAMETERS:  Op                  - Current parse op
    286  *              Level               - Current output indentation level
    287  *
    288  * RETURN:      None
    289  *
    290  * DESCRIPTION: Generic formatted debug output for "basic" ops that have no
    291  *              associated strings or integer values.
    292  *
    293  ******************************************************************************/
    294 
    295 void
    296 UtDumpBasicOp (
    297     ACPI_PARSE_OBJECT       *Op,
    298     UINT32                  Level)
    299 {
    300 
    301     /* Just print out the ParseOp name, there is no extra data */
    302 
    303     UtDumpParseOpName (Op, Level, 0);
    304 }
    305 
    306 
    307 /*******************************************************************************
    308  *
    309  * FUNCTION:    UtDumpParseOpName
    310  *
    311  * PARAMETERS:  Op                  - Current parse op
    312  *              Level               - Current output indentation level
    313  *              DataLength          - Length of data to appear after the name
    314  *
    315  * RETURN:      None
    316  *
    317  * DESCRIPTION: Indent and emit the ascii ParseOp name for the op
    318  *
    319  ******************************************************************************/
    320 
    321 static void
    322 UtDumpParseOpName (
    323     ACPI_PARSE_OBJECT       *Op,
    324     UINT32                  Level,
    325     UINT32                  DataLength)
    326 {
    327     char                    *ParseOpName;
    328     UINT32                  IndentLength;
    329     UINT32                  NameLength;
    330     UINT32                  LineLength;
    331     UINT32                  PaddingLength;
    332 
    333 
    334     /* Emit the LineNumber/IndentLevel prefix on each output line */
    335 
    336     DbgPrint (ASL_TREE_OUTPUT,
    337         "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
    338 
    339     ParseOpName = UtGetOpName (Op->Asl.ParseOpcode);
    340 
    341     /* Calculate various lengths for output alignment */
    342 
    343     IndentLength = Level * DEBUG_SPACES_PER_INDENT;
    344     NameLength = strlen (ParseOpName);
    345     LineLength = IndentLength + 1 + NameLength + 1 + DataLength;
    346     PaddingLength = (DEBUG_MAX_LINE_LENGTH + 1) - LineLength;
    347 
    348     /* Parse tree indentation is based upon the nesting/indent level */
    349 
    350     if (Level)
    351     {
    352         DbgPrint (ASL_TREE_OUTPUT, "%*s", IndentLength, " ");
    353     }
    354 
    355     /* Emit the actual name here */
    356 
    357     DbgPrint (ASL_TREE_OUTPUT, " %s", ParseOpName);
    358 
    359     /* Emit extra padding blanks for alignment of later data items */
    360 
    361     if (LineLength > DEBUG_MAX_LINE_LENGTH)
    362     {
    363         /* Split a long line immediately after the ParseOpName string */
    364 
    365         DbgPrint (ASL_TREE_OUTPUT, "\n%*s",
    366             (DEBUG_FULL_LINE_LENGTH - DataLength), " ");
    367     }
    368     else
    369     {
    370         DbgPrint (ASL_TREE_OUTPUT, "%*s", PaddingLength, " ");
    371     }
    372 }
    373