1 /****************************************************************************** 2 * 3 * Module Name: cvcompiler - ASL-/ASL+ converter functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 static void 52 CvPrintInclude( 53 ACPI_FILE_NODE *FNode, 54 UINT32 Level); 55 56 static BOOLEAN 57 CvListIsSingleton ( 58 ACPI_COMMENT_NODE *CommentList); 59 60 61 /******************************************************************************* 62 * 63 * FUNCTION: CvPrintOneCommentList 64 * 65 * PARAMETERS: CommentList 66 * Level 67 * 68 * RETURN: None 69 * 70 * DESCRIPTION: Prints all comments within the given list. 71 * This is referred as ASL_CV_PRINT_ONE_COMMENT_LIST. 72 * 73 ******************************************************************************/ 74 75 void 76 CvPrintOneCommentList ( 77 ACPI_COMMENT_NODE *CommentList, 78 UINT32 Level) 79 { 80 ACPI_COMMENT_NODE *Current = CommentList; 81 ACPI_COMMENT_NODE *Previous; 82 83 84 while (Current) 85 { 86 Previous = Current; 87 if (Current->Comment) 88 { 89 AcpiDmIndent(Level); 90 AcpiOsPrintf("%s\n", Current->Comment); 91 Current->Comment = NULL; 92 } 93 Current = Current->Next; 94 AcpiOsReleaseObject(AcpiGbl_RegCommentCache, Previous); 95 } 96 } 97 98 99 /******************************************************************************* 100 * 101 * FUNCTION: CvListIsSingleton 102 * 103 * PARAMETERS: CommentList -- check to see if this is a single item list. 104 * 105 * RETURN: BOOLEAN 106 * 107 * DESCRIPTION: Returns TRUE if CommentList only contains 1 node. 108 * 109 ******************************************************************************/ 110 111 static BOOLEAN 112 CvListIsSingleton ( 113 ACPI_COMMENT_NODE *CommentList) 114 115 { 116 if (!CommentList) 117 { 118 return FALSE; 119 } 120 else if (CommentList->Next) 121 { 122 return FALSE; 123 } 124 125 return TRUE; 126 } 127 128 129 /******************************************************************************* 130 * 131 * FUNCTION: CvPrintOneCommentType 132 * 133 * PARAMETERS: Op 134 * CommentType 135 * EndStr - String to print after printing the comment 136 * Level - indentation level for comment lists. 137 * 138 * RETURN: None 139 * 140 * DESCRIPTION: Prints all comments of CommentType within the given Op and 141 * clears the printed comment from the Op. 142 * This is referred as ASL_CV_PRINT_ONE_COMMENT. 143 * 144 ******************************************************************************/ 145 146 void 147 CvPrintOneCommentType ( 148 ACPI_PARSE_OBJECT *Op, 149 UINT8 CommentType, 150 char* EndStr, 151 UINT32 Level) 152 { 153 BOOLEAN CommentExists = FALSE; 154 char **CommentToPrint = NULL; 155 156 157 switch (CommentType) 158 { 159 case AML_COMMENT_STANDARD: 160 161 if (CvListIsSingleton (Op->Common.CommentList)) 162 { 163 CvPrintOneCommentList (Op->Common.CommentList, Level); 164 AcpiOsPrintf ("\n"); 165 } 166 else 167 { 168 CvPrintOneCommentList (Op->Common.CommentList, Level); 169 } 170 Op->Common.CommentList = NULL; 171 return; 172 173 case AML_COMMENT_ENDBLK: 174 175 if (Op->Common.EndBlkComment) 176 { 177 CvPrintOneCommentList (Op->Common.EndBlkComment, Level); 178 Op->Common.EndBlkComment = NULL; 179 AcpiDmIndent(Level); 180 } 181 return; 182 183 case AMLCOMMENT_INLINE: 184 185 CommentToPrint = &Op->Common.InlineComment; 186 break; 187 188 case AML_COMMENT_END_NODE: 189 190 CommentToPrint = &Op->Common.EndNodeComment; 191 break; 192 193 case AML_NAMECOMMENT: 194 195 CommentToPrint = &Op->Common.NameComment; 196 break; 197 198 case AML_COMMENT_CLOSE_BRACE: 199 200 CommentToPrint = &Op->Common.CloseBraceComment; 201 break; 202 203 default: 204 return; 205 } 206 207 if (*CommentToPrint) 208 { 209 AcpiOsPrintf ("%s", *CommentToPrint); 210 *CommentToPrint = NULL; 211 } 212 213 if (CommentExists && EndStr) 214 { 215 AcpiOsPrintf ("%s", EndStr); 216 } 217 } 218 219 220 /******************************************************************************* 221 * 222 * FUNCTION: CvCloseBraceWriteComment 223 * 224 * PARAMETERS: Op 225 * Level 226 * 227 * RETURN: none 228 * 229 * DESCRIPTION: Print a close brace } and any open brace comments associated 230 * with this parse object. 231 * This is referred as ASL_CV_CLOSE_BRACE. 232 * 233 ******************************************************************************/ 234 235 void 236 CvCloseBraceWriteComment( 237 ACPI_PARSE_OBJECT *Op, 238 UINT32 Level) 239 { 240 if (!Gbl_CaptureComments) 241 { 242 AcpiOsPrintf ("}"); 243 return; 244 } 245 246 CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level); 247 AcpiOsPrintf ("}"); 248 CvPrintOneCommentType (Op, AML_COMMENT_CLOSE_BRACE, NULL, Level); 249 } 250 251 252 /******************************************************************************* 253 * 254 * FUNCTION: CvCloseParenWriteComment 255 * 256 * PARAMETERS: Op 257 * Level 258 * 259 * RETURN: none 260 * 261 * DESCRIPTION: Print a closing paren ) and any end node comments associated 262 * with this parse object. 263 * This is referred as ASL_CV_CLOSE_PAREN. 264 * 265 ******************************************************************************/ 266 267 void 268 CvCloseParenWriteComment( 269 ACPI_PARSE_OBJECT *Op, 270 UINT32 Level) 271 { 272 if (!Gbl_CaptureComments) 273 { 274 AcpiOsPrintf (")"); 275 return; 276 } 277 278 /* 279 * If this op has a BLOCK_BRACE, then output the comment when the 280 * disassembler calls CvCloseBraceWriteComment 281 */ 282 if (AcpiDmBlockType (Op) == BLOCK_PAREN) 283 { 284 CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level); 285 } 286 287 AcpiOsPrintf (")"); 288 289 if (Op->Common.EndNodeComment) 290 { 291 CvPrintOneCommentType (Op, AML_COMMENT_END_NODE, NULL, Level); 292 } 293 else if ((Op->Common.Parent->Common.AmlOpcode == AML_IF_OP) && 294 Op->Common.Parent->Common.EndNodeComment) 295 { 296 CvPrintOneCommentType (Op->Common.Parent, 297 AML_COMMENT_END_NODE, NULL, Level); 298 } 299 } 300 301 302 /******************************************************************************* 303 * 304 * FUNCTION: CvFileHasSwitched 305 * 306 * PARAMETERS: Op 307 * 308 * RETURN: BOOLEAN 309 * 310 * DESCRIPTION: Determine whether if a file has switched. 311 * TRUE - file has switched. 312 * FALSE - file has not switched. 313 * This is referred as ASL_CV_FILE_HAS_SWITCHED. 314 * 315 ******************************************************************************/ 316 317 BOOLEAN 318 CvFileHasSwitched( 319 ACPI_PARSE_OBJECT *Op) 320 { 321 if (Op->Common.CvFilename && 322 AcpiGbl_CurrentFilename && 323 AcpiUtStricmp(Op->Common.CvFilename, AcpiGbl_CurrentFilename)) 324 { 325 return TRUE; 326 } 327 return FALSE; 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: CvPrintInclude 334 * 335 * PARAMETERS: FNode - Write an Include statement for the file that is pointed 336 * by FNode->File. 337 * Level - indentation level 338 * 339 * RETURN: None 340 * 341 * DESCRIPTION: Write the ASL Include statement for FNode->File in the file 342 * indicated by FNode->Parent->File. Note this function emits 343 * actual ASL code rather than comments. This switches the output 344 * file to FNode->Parent->File. 345 * 346 ******************************************************************************/ 347 348 static void 349 CvPrintInclude( 350 ACPI_FILE_NODE *FNode, 351 UINT32 Level) 352 { 353 if (!FNode || FNode->IncludeWritten) 354 { 355 return; 356 } 357 358 CvDbgPrint ("Writing include for %s within %s\n", FNode->Filename, FNode->Parent->Filename); 359 AcpiOsRedirectOutput (FNode->Parent->File); 360 CvPrintOneCommentList (FNode->IncludeComment, Level); 361 AcpiDmIndent (Level); 362 AcpiOsPrintf ("Include (\"%s\")\n", FNode->Filename); 363 CvDbgPrint ("emitted the following: Include (\"%s\")\n", FNode->Filename); 364 FNode->IncludeWritten = TRUE; 365 } 366 367 368 /******************************************************************************* 369 * 370 * FUNCTION: CvSwitchFiles 371 * 372 * PARAMETERS: Level - indentation level 373 * Op 374 * 375 * RETURN: None 376 * 377 * DESCRIPTION: Switch the outputfile and write ASL Include statement. Note, 378 * this function emits actual ASL code rather than comments. 379 * This is referred as ASL_CV_SWITCH_FILES. 380 * 381 ******************************************************************************/ 382 383 void 384 CvSwitchFiles( 385 UINT32 Level, 386 ACPI_PARSE_OBJECT *Op) 387 { 388 char *Filename = Op->Common.CvFilename; 389 ACPI_FILE_NODE *FNode; 390 391 CvDbgPrint ("Switching from %s to %s\n", AcpiGbl_CurrentFilename, Filename); 392 FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 393 if (!FNode) 394 { 395 /* 396 * At this point, each Filename should exist in AcpiGbl_FileTreeRoot 397 * if it does not exist, then abort. 398 */ 399 FlDeleteFile (ASL_FILE_AML_OUTPUT); 400 sprintf (MsgBuffer, "\"Cannot find %s\" - %s", Filename, strerror (errno)); 401 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, NULL, MsgBuffer); 402 AslAbort (); 403 } 404 405 /* 406 * If the previous file is a descendent of the current file, 407 * make sure that Include statements from the current file 408 * to the previous have been emitted. 409 */ 410 while (FNode && 411 FNode->Parent && 412 AcpiUtStricmp (FNode->Filename, AcpiGbl_CurrentFilename)) 413 { 414 CvPrintInclude (FNode, Level); 415 FNode = FNode->Parent; 416 } 417 418 /* Redirect output to the Op->Common.CvFilename */ 419 420 FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 421 AcpiOsRedirectOutput (FNode->File); 422 AcpiGbl_CurrentFilename = FNode->Filename; 423 } 424