1 /****************************************************************************** 2 * 3 * Module Name: cvcompiler - ASL-/ASL+ converter functions 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 "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 (AslGbl_MsgBuffer, "\"Cannot find %s\" - %s", 418 Filename, strerror (errno)); 419 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, 420 NULL, AslGbl_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 if (FNode) 440 { 441 /* Redirect output to Op->Common.CvFilename */ 442 443 AcpiOsRedirectOutput (FNode->File); 444 AcpiGbl_CurrentFilename = FNode->Filename; 445 } 446 } 447