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