1 /****************************************************************************** 2 * 3 * Module Name: cvparser - Converter functions that are called from the AML 4 * parser. 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 ***************************************************************************** 116 * 117 * Alternatively, you may choose to be licensed under the terms of the 118 * following license: 119 * 120 * Redistribution and use in source and binary forms, with or without 121 * modification, are permitted provided that the following conditions 122 * are met: 123 * 1. Redistributions of source code must retain the above copyright 124 * notice, this list of conditions, and the following disclaimer, 125 * without modification. 126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 127 * substantially similar to the "NO WARRANTY" disclaimer below 128 * ("Disclaimer") and any redistribution must be conditioned upon 129 * including a substantially similar Disclaimer requirement for further 130 * binary redistribution. 131 * 3. Neither the names of the above-listed copyright holders nor the names 132 * of any contributors may be used to endorse or promote products derived 133 * from this software without specific prior written permission. 134 * 135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 146 * 147 * Alternatively, you may choose to be licensed under the terms of the 148 * GNU General Public License ("GPL") version 2 as published by the Free 149 * Software Foundation. 150 * 151 *****************************************************************************/ 152 153 #include <contrib/dev/acpica/compiler/aslcompiler.h> 154 #include <contrib/dev/acpica/include/acparser.h> 155 #include <contrib/dev/acpica/include/acdispat.h> 156 #include <contrib/dev/acpica/include/amlcode.h> 157 #include <contrib/dev/acpica/include/acinterp.h> 158 #include <contrib/dev/acpica/include/acdisasm.h> 159 #include <contrib/dev/acpica/include/acconvert.h> 160 161 162 /* local prototypes */ 163 164 static BOOLEAN 165 CvCommentExists ( 166 UINT8 *Address); 167 168 static BOOLEAN 169 CvIsFilename ( 170 char *Filename); 171 172 static ACPI_FILE_NODE* 173 CvFileAddressLookup( 174 char *Address, 175 ACPI_FILE_NODE *Head); 176 177 static void 178 CvAddToFileTree ( 179 char *Filename, 180 char *PreviousFilename); 181 182 static void 183 CvSetFileParent ( 184 char *ChildFile, 185 char *ParentFile); 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: CvIsFilename 191 * 192 * PARAMETERS: filename - input filename 193 * 194 * RETURN: BOOLEAN - TRUE if all characters are between 0x20 and 0x7f 195 * 196 * DESCRIPTION: Take a given char * and see if it contains all printable 197 * characters. If all characters have hexvalues 20-7f and ends with 198 * .dsl, we will assume that it is a proper filename. 199 * 200 ******************************************************************************/ 201 202 static BOOLEAN 203 CvIsFilename ( 204 char *Filename) 205 { 206 UINT64 Length = strlen(Filename); 207 UINT64 i; 208 char *FileExt = Filename + Length - 4; 209 210 211 if ((Length > 4) && AcpiUtStricmp (FileExt, ".dsl")) 212 { 213 return FALSE; 214 } 215 216 for(i = 0; i<Length; ++i) 217 { 218 if (!isprint (Filename[i])) 219 { 220 return FALSE; 221 } 222 } 223 return TRUE; 224 } 225 226 227 /******************************************************************************* 228 * 229 * FUNCTION: CvInitFileTree 230 * 231 * PARAMETERS: Table - input table 232 * AmlStart - Address of the starting point of the AML. 233 * AmlLength - Length of the AML file. 234 * 235 * RETURN: none 236 * 237 * DESCRIPTION: Initialize the file dependency tree by scanning the AML. 238 * This is referred as ASL_CV_INIT_FILETREE. 239 * 240 ******************************************************************************/ 241 242 void 243 CvInitFileTree ( 244 ACPI_TABLE_HEADER *Table, 245 UINT8 *AmlStart, 246 UINT32 AmlLength) 247 { 248 UINT8 *TreeAml; 249 UINT8 *FileEnd; 250 char *Filename = NULL; 251 char *PreviousFilename = NULL; 252 char *ParentFilename = NULL; 253 char *ChildFilename = NULL; 254 255 256 if (!Gbl_CaptureComments) 257 { 258 return; 259 } 260 261 CvDbgPrint ("AmlLength: %x\n", AmlLength); 262 CvDbgPrint ("AmlStart: %p\n", AmlStart); 263 CvDbgPrint ("AmlEnd?: %p\n", AmlStart+AmlLength); 264 265 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 266 AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart); 267 AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length); 268 AcpiGbl_FileTreeRoot->Next = NULL; 269 AcpiGbl_FileTreeRoot->Parent = NULL; 270 AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2); 271 272 /* Set the root file to the current open file */ 273 274 AcpiGbl_FileTreeRoot->File = AcpiGbl_OutputFile; 275 276 /* 277 * Set this to true because we dont need to output 278 * an include statement for the topmost file 279 */ 280 AcpiGbl_FileTreeRoot->IncludeWritten = TRUE; 281 Filename = NULL; 282 AcpiGbl_CurrentFilename = (char *)(AmlStart+2); 283 AcpiGbl_RootFilename = (char *)(AmlStart+2); 284 285 TreeAml = AmlStart; 286 FileEnd = AmlStart + AmlLength; 287 288 while (TreeAml <= FileEnd) 289 { 290 /* 291 * Make sure that this filename contains all printable characters 292 * and a .dsl extension at the end. If not, then it must be some 293 * raw data that doesn't outline a filename. 294 */ 295 if ((*TreeAml == AML_COMMENT_OP) && 296 (*(TreeAml+1) == FILENAME_COMMENT) && 297 (CvIsFilename ((char *)(TreeAml+2)))) 298 { 299 CvDbgPrint ("A9 and a 08 file\n"); 300 PreviousFilename = Filename; 301 Filename = (char *) (TreeAml+2); 302 CvAddToFileTree (Filename, PreviousFilename); 303 ChildFilename = Filename; 304 CvDbgPrint ("%s\n", Filename); 305 } 306 else if ((*TreeAml == AML_COMMENT_OP) && 307 (*(TreeAml+1) == PARENTFILENAME_COMMENT) && 308 (CvIsFilename ((char *)(TreeAml+2)))) 309 { 310 CvDbgPrint ("A9 and a 09 file\n"); 311 ParentFilename = (char *)(TreeAml+2); 312 CvSetFileParent (ChildFilename, ParentFilename); 313 CvDbgPrint ("%s\n", ParentFilename); 314 } 315 ++TreeAml; 316 } 317 } 318 319 320 /******************************************************************************* 321 * 322 * FUNCTION: CvClearOpComments 323 * 324 * PARAMETERS: Op -- clear all comments within this Op 325 * 326 * RETURN: none 327 * 328 * DESCRIPTION: Clear all converter-related fields of the given Op. 329 * This is referred as ASL_CV_CLEAR_OP_COMMENTS. 330 * 331 ******************************************************************************/ 332 333 void 334 CvClearOpComments ( 335 ACPI_PARSE_OBJECT *Op) 336 { 337 Op->Common.InlineComment = NULL; 338 Op->Common.EndNodeComment = NULL; 339 Op->Common.NameComment = NULL; 340 Op->Common.CommentList = NULL; 341 Op->Common.EndBlkComment = NULL; 342 Op->Common.CloseBraceComment = NULL; 343 Op->Common.CvFilename = NULL; 344 Op->Common.CvParentFilename = NULL; 345 } 346 347 348 /******************************************************************************* 349 * 350 * FUNCTION: CvCommentExists 351 * 352 * PARAMETERS: address - check if this address appears in the list 353 * 354 * RETURN: BOOLEAN - TRUE if the address exists. 355 * 356 * DESCRIPTION: look at the pointer address and check if this appears in the 357 * list of all addresses. If it exitsts in the list, return TRUE 358 * if it exists. Otherwise add to the list and return FALSE. 359 * 360 ******************************************************************************/ 361 362 static BOOLEAN 363 CvCommentExists ( 364 UINT8 *Address) 365 { 366 ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead; 367 UINT8 Option; 368 369 370 if (!Address) 371 { 372 return (FALSE); 373 } 374 Option = *(Address + 1); 375 376 /* 377 * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as comments. 378 * They serve as markers for where the file starts and ends. 379 */ 380 if ((Option == FILENAME_COMMENT) || (Option == PARENTFILENAME_COMMENT)) 381 { 382 return (FALSE); 383 } 384 385 if (!Current) 386 { 387 AcpiGbl_CommentAddrListHead = 388 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 389 AcpiGbl_CommentAddrListHead->Addr = Address; 390 AcpiGbl_CommentAddrListHead->Next = NULL; 391 return (FALSE); 392 } 393 else 394 { 395 while (Current) 396 { 397 if (Current->Addr != Address) 398 { 399 Current = Current->Next; 400 } 401 else 402 { 403 return (TRUE); 404 } 405 } 406 407 /* 408 * If the execution gets to this point, it means that this address 409 * does not exists in the list. Add this address to the 410 * beginning of the list. 411 */ 412 Current = AcpiGbl_CommentAddrListHead; 413 AcpiGbl_CommentAddrListHead = 414 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 415 AcpiGbl_CommentAddrListHead->Addr = Address; 416 AcpiGbl_CommentAddrListHead->Next = Current; 417 return (FALSE); 418 } 419 } 420 421 422 /******************************************************************************* 423 * 424 * FUNCTION: CvFilenameExists 425 * 426 * PARAMETERS: Filename - filename to search 427 * 428 * RETURN: ACPI_FILE_NODE - a pointer to a file node 429 * 430 * DESCRIPTION: Look for the given filename in the file dependency tree. 431 * Returns the file node if it exists, returns NULL if it does not. 432 * 433 ******************************************************************************/ 434 435 ACPI_FILE_NODE* 436 CvFilenameExists( 437 char *Filename, 438 ACPI_FILE_NODE *Head) 439 { 440 ACPI_FILE_NODE *Current = Head; 441 442 443 while (Current) 444 { 445 if (!AcpiUtStricmp (Current->Filename, Filename)) 446 { 447 return (Current); 448 } 449 Current = Current->Next; 450 } 451 return (NULL); 452 } 453 454 455 /******************************************************************************* 456 * 457 * FUNCTION: CvFileAddressLookup 458 * 459 * PARAMETERS: Address - address to look up 460 * Head - file dependency tree 461 * 462 * RETURN: ACPI_FLE_NODE - pointer to a file node containing the address 463 * 464 * DESCRIPTION: Look for the given address in the file dependency tree. 465 * Returns the first file node where the given address is within 466 * the file node's starting and ending address. 467 * 468 ******************************************************************************/ 469 470 static ACPI_FILE_NODE* 471 CvFileAddressLookup( 472 char *Address, 473 ACPI_FILE_NODE *Head) 474 { 475 ACPI_FILE_NODE *Current = Head; 476 477 478 while (Current) 479 { 480 if ((Address >= Current->FileStart) && 481 (Address < Current->FileEnd || 482 !Current->FileEnd)) 483 { 484 return (Current); 485 } 486 Current = Current->Next; 487 } 488 489 return (NULL); 490 } 491 492 493 /******************************************************************************* 494 * 495 * FUNCTION: CvLabelFileNode 496 * 497 * PARAMETERS: Op 498 * 499 * RETURN: None 500 * 501 * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field 502 * within the file tree and fills in approperiate file information 503 * from a matching node within the tree. 504 * This is referred as ASL_CV_LABEL_FILENODE. 505 * 506 ******************************************************************************/ 507 508 void 509 CvLabelFileNode( 510 ACPI_PARSE_OBJECT *Op) 511 { 512 ACPI_FILE_NODE *Node; 513 514 515 if (!Op) 516 { 517 return; 518 } 519 520 Node = CvFileAddressLookup ((char *)Op->Common.Aml, AcpiGbl_FileTreeRoot); 521 if (!Node) 522 { 523 return; 524 } 525 526 Op->Common.CvFilename = Node->Filename; 527 if (Node->Parent) 528 { 529 Op->Common.CvParentFilename = Node->Parent->Filename; 530 } 531 else 532 { 533 Op->Common.CvParentFilename = Node->Filename; 534 } 535 } 536 537 538 /******************************************************************************* 539 * 540 * FUNCTION: CvAddToFileTree 541 * 542 * PARAMETERS: Filename - Address containing the name of the current 543 * filename 544 * PreviousFilename - Address containing the name of the previous 545 * filename 546 * 547 * RETURN: void 548 * 549 * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist. 550 * 551 ******************************************************************************/ 552 553 static void 554 CvAddToFileTree ( 555 char *Filename, 556 char *PreviousFilename) 557 { 558 ACPI_FILE_NODE *Node; 559 560 561 if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 562 PreviousFilename) 563 { 564 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 565 if (Node) 566 { 567 /* 568 * Set the end point of the PreviousFilename to the address 569 * of Filename. 570 */ 571 Node->FileEnd = Filename; 572 } 573 } 574 else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 575 !PreviousFilename) 576 { 577 return; 578 } 579 580 Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 581 if (Node && PreviousFilename) 582 { 583 /* 584 * Update the end of the previous file and all of their parents' ending 585 * Addresses. This is done to ensure that parent file ranges extend to 586 * the end of their childrens' files. 587 */ 588 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 589 if (Node && (Node->FileEnd < Filename)) 590 { 591 Node->FileEnd = Filename; 592 Node = Node->Parent; 593 while (Node) 594 { 595 if (Node->FileEnd < Filename) 596 { 597 Node->FileEnd = Filename; 598 } 599 Node = Node->Parent; 600 } 601 } 602 } 603 else 604 { 605 Node = AcpiGbl_FileTreeRoot; 606 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 607 AcpiGbl_FileTreeRoot->Next = Node; 608 AcpiGbl_FileTreeRoot->Parent = NULL; 609 AcpiGbl_FileTreeRoot->Filename = Filename; 610 AcpiGbl_FileTreeRoot->FileStart = Filename; 611 AcpiGbl_FileTreeRoot->IncludeWritten = FALSE; 612 AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+"); 613 614 /* 615 * If we can't open the file, we need to abort here before we 616 * accidentally write to a NULL file. 617 */ 618 if (!AcpiGbl_FileTreeRoot->File) 619 { 620 /* delete the .xxx file */ 621 622 FlDeleteFile (ASL_FILE_AML_OUTPUT); 623 sprintf (MsgBuffer, "\"%s\" - %s", Filename, strerror (errno)); 624 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, NULL, MsgBuffer); 625 AslAbort (); 626 } 627 } 628 } 629 630 631 /******************************************************************************* 632 * 633 * FUNCTION: CvSetFileParent 634 * 635 * PARAMETERS: ChildFile - contains the filename of the child file 636 * ParentFile - contains the filename of the parent file. 637 * 638 * RETURN: none 639 * 640 * DESCRIPTION: point the parent pointer of the Child to the node that 641 * corresponds with the parent file node. 642 * 643 ******************************************************************************/ 644 645 static void 646 CvSetFileParent ( 647 char *ChildFile, 648 char *ParentFile) 649 { 650 ACPI_FILE_NODE *Child; 651 ACPI_FILE_NODE *Parent; 652 653 654 Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot); 655 Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot); 656 if (Child && Parent) 657 { 658 Child->Parent = Parent; 659 660 while (Child->Parent) 661 { 662 if (Child->Parent->FileEnd < Child->FileStart) 663 { 664 Child->Parent->FileEnd = Child->FileStart; 665 } 666 Child = Child->Parent; 667 } 668 } 669 } 670 671 672 /******************************************************************************* 673 * 674 * FUNCTION: CvCaptureCommentsOnly 675 * 676 * PARAMETERS: ParserState - A parser state object 677 * 678 * RETURN: none 679 * 680 * DESCRIPTION: look at the aml that the parser state is pointing to, 681 * capture any AML_COMMENT_OP and it's arguments and increment the 682 * aml pointer past the comment. Comments are transferred to parse 683 * nodes through CvTransferComments() as well as 684 * AcpiPsBuildNamedOp(). 685 * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY. 686 * 687 ******************************************************************************/ 688 689 void 690 CvCaptureCommentsOnly ( 691 ACPI_PARSE_STATE *ParserState) 692 { 693 UINT8 *Aml = ParserState->Aml; 694 UINT16 Opcode = (UINT16) ACPI_GET8 (Aml); 695 UINT32 Length = 0; 696 UINT8 CommentOption = (UINT16) ACPI_GET8 (Aml+1); 697 BOOLEAN StdDefBlockFlag = FALSE; 698 ACPI_COMMENT_NODE *CommentNode; 699 ACPI_FILE_NODE *FileNode; 700 701 702 if (!Gbl_CaptureComments || 703 Opcode != AML_COMMENT_OP) 704 { 705 return; 706 } 707 708 while (Opcode == AML_COMMENT_OP) 709 { 710 CvDbgPrint ("comment aml address: %p\n", Aml); 711 712 if (CvCommentExists(ParserState->Aml)) 713 { 714 CvDbgPrint ("Avoiding capturing an existing comment.\n"); 715 } 716 else 717 { 718 CommentOption = *(Aml+1); 719 720 /* Increment past the comment option and point the approperiate char pointers.*/ 721 722 Aml += 2; 723 724 /* found a comment. Now, set pointers to these comments. */ 725 726 switch (CommentOption) 727 { 728 case STD_DEFBLK_COMMENT: 729 730 StdDefBlockFlag = TRUE; 731 732 /* add to a linked list of nodes. This list will be taken by the parse node created next. */ 733 734 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 735 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 736 CommentNode->Next = NULL; 737 738 if (!AcpiGbl_DefBlkCommentListHead) 739 { 740 AcpiGbl_DefBlkCommentListHead = CommentNode; 741 AcpiGbl_DefBlkCommentListTail = CommentNode; 742 } 743 else 744 { 745 AcpiGbl_DefBlkCommentListTail->Next = CommentNode; 746 AcpiGbl_DefBlkCommentListTail = AcpiGbl_DefBlkCommentListTail->Next; 747 } 748 break; 749 750 case STANDARD_COMMENT: 751 752 CvDbgPrint ("found regular comment.\n"); 753 754 /* add to a linked list of nodes. This list will be taken by the parse node created next. */ 755 756 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 757 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 758 CommentNode->Next = NULL; 759 760 if (!AcpiGbl_RegCommentListHead) 761 { 762 AcpiGbl_RegCommentListHead = CommentNode; 763 AcpiGbl_RegCommentListTail = CommentNode; 764 } 765 else 766 { 767 AcpiGbl_RegCommentListTail->Next = CommentNode; 768 AcpiGbl_RegCommentListTail = AcpiGbl_RegCommentListTail->Next; 769 } 770 break; 771 772 case ENDBLK_COMMENT: 773 774 CvDbgPrint ("found endblk comment.\n"); 775 776 /* add to a linked list of nodes. This will be taken by the next created parse node. */ 777 778 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 779 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 780 CommentNode->Next = NULL; 781 782 if (!AcpiGbl_EndBlkCommentListHead) 783 { 784 AcpiGbl_EndBlkCommentListHead = CommentNode; 785 AcpiGbl_EndBlkCommentListTail = CommentNode; 786 } 787 else 788 { 789 AcpiGbl_EndBlkCommentListTail->Next = CommentNode; 790 AcpiGbl_EndBlkCommentListTail = AcpiGbl_EndBlkCommentListTail->Next; 791 } 792 break; 793 794 case INLINE_COMMENT: 795 796 CvDbgPrint ("found inline comment.\n"); 797 AcpiGbl_CurrentInlineComment = ACPI_CAST_PTR (char, Aml); 798 break; 799 800 case ENDNODE_COMMENT: 801 802 CvDbgPrint ("found EndNode comment.\n"); 803 AcpiGbl_CurrentEndNodeComment = ACPI_CAST_PTR (char, Aml); 804 break; 805 806 case CLOSE_BRACE_COMMENT: 807 808 CvDbgPrint ("found close brace comment.\n"); 809 AcpiGbl_CurrentCloseBraceComment = ACPI_CAST_PTR (char, Aml); 810 break; 811 812 case END_DEFBLK_COMMENT: 813 814 CvDbgPrint ("Found comment that belongs after the } for a definition block.\n"); 815 AcpiGbl_CurrentScope->Common.CloseBraceComment = ACPI_CAST_PTR (char, Aml); 816 break; 817 818 case FILENAME_COMMENT: 819 820 CvDbgPrint ("Found a filename: %s\n", ACPI_CAST_PTR (char, Aml)); 821 FileNode = CvFilenameExists (ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot); 822 823 /* 824 * If there is an INCLUDE_COMMENT followed by a 825 * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment 826 * that is emitted before the #include for the file. 827 * We will save the IncludeComment within the FileNode 828 * associated with this FILENAME_COMMENT. 829 */ 830 if (FileNode && AcpiGbl_IncCommentListHead) 831 { 832 FileNode->IncludeComment = AcpiGbl_IncCommentListHead; 833 AcpiGbl_IncCommentListHead = NULL; 834 AcpiGbl_IncCommentListTail = NULL; 835 } 836 break; 837 838 case PARENTFILENAME_COMMENT: 839 CvDbgPrint (" Found a parent filename.\n"); 840 break; 841 842 case INCLUDE_COMMENT: 843 844 /* 845 * Add to a linked list. This list will be taken by the 846 * parse node created next. See the FILENAME_COMMENT case 847 * for more details 848 */ 849 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 850 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 851 CommentNode->Next = NULL; 852 853 if (!AcpiGbl_IncCommentListHead) 854 { 855 AcpiGbl_IncCommentListHead = CommentNode; 856 AcpiGbl_IncCommentListTail = CommentNode; 857 } 858 else 859 { 860 AcpiGbl_IncCommentListTail->Next = CommentNode; 861 AcpiGbl_IncCommentListTail = AcpiGbl_IncCommentListTail->Next; 862 } 863 864 CvDbgPrint ("Found a include comment: %s\n", CommentNode->Comment); 865 break; 866 867 default: 868 869 /* Not a valid comment option. Revert the AML */ 870 871 Aml -= 2; 872 goto DefBlock; 873 break; 874 875 } /* end switch statement */ 876 877 } /* end else */ 878 879 /* determine the length and move forward that amount */ 880 881 Length = 0; 882 while (ParserState->Aml[Length]) 883 { 884 Length++; 885 } 886 887 ParserState->Aml += Length + 1; 888 889 890 /* Peek at the next Opcode. */ 891 892 Aml = ParserState->Aml; 893 Opcode = (UINT16) ACPI_GET8 (Aml); 894 895 } 896 897 DefBlock: 898 if (StdDefBlockFlag) 899 { 900 /* 901 * Give all of its comments to the current scope, which is known as 902 * the definition block, since STD_DEFBLK_COMMENT only appears after 903 * definition block headers. 904 */ 905 AcpiGbl_CurrentScope->Common.CommentList 906 = AcpiGbl_DefBlkCommentListHead; 907 AcpiGbl_DefBlkCommentListHead = NULL; 908 AcpiGbl_DefBlkCommentListTail = NULL; 909 } 910 } 911 912 913 /******************************************************************************* 914 * 915 * FUNCTION: CvCaptureComments 916 * 917 * PARAMETERS: ParserState - A parser state object 918 * 919 * RETURN: none 920 * 921 * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly 922 * This is referred as ASL_CV_CAPTURE_COMMENTS. 923 * 924 ******************************************************************************/ 925 926 void 927 CvCaptureComments ( 928 ACPI_WALK_STATE *WalkState) 929 { 930 UINT8 *Aml; 931 UINT16 Opcode; 932 const ACPI_OPCODE_INFO *OpInfo; 933 934 935 if (!Gbl_CaptureComments) 936 { 937 return; 938 } 939 940 /* 941 * Before parsing, check to see that comments that come directly after 942 * deferred opcodes aren't being processed. 943 */ 944 Aml = WalkState->ParserState.Aml; 945 Opcode = (UINT16) ACPI_GET8 (Aml); 946 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 947 948 if (!(OpInfo->Flags & AML_DEFER) || 949 ((OpInfo->Flags & AML_DEFER) && 950 (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1))) 951 { 952 CvCaptureCommentsOnly (&WalkState->ParserState); 953 WalkState->Aml = WalkState->ParserState.Aml; 954 } 955 956 } 957 958 959 /******************************************************************************* 960 * 961 * FUNCTION: CvTransferComments 962 * 963 * PARAMETERS: Op - Transfer comments to this Op 964 * 965 * RETURN: none 966 * 967 * DESCRIPTION: Transfer all of the commments stored in global containers to the 968 * given Op. This will be invoked shortly after the parser creates 969 * a ParseOp. 970 * This is referred as ASL_CV_TRANSFER_COMMENTS. 971 * 972 ******************************************************************************/ 973 974 void 975 CvTransferComments ( 976 ACPI_PARSE_OBJECT *Op) 977 { 978 Op->Common.InlineComment = AcpiGbl_CurrentInlineComment; 979 AcpiGbl_CurrentInlineComment = NULL; 980 981 Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment; 982 AcpiGbl_CurrentEndNodeComment = NULL; 983 984 Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment; 985 AcpiGbl_CurrentCloseBraceComment = NULL; 986 987 Op->Common.CommentList = AcpiGbl_RegCommentListHead; 988 AcpiGbl_RegCommentListHead = NULL; 989 AcpiGbl_RegCommentListTail = NULL; 990 991 Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead; 992 AcpiGbl_EndBlkCommentListHead = NULL; 993 AcpiGbl_EndBlkCommentListTail = NULL; 994 995 } 996