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 ((int) 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 if (!Filename) 444 { 445 return (NULL); 446 } 447 448 while (Current) 449 { 450 if (!AcpiUtStricmp (Current->Filename, Filename)) 451 { 452 return (Current); 453 } 454 Current = Current->Next; 455 } 456 return (NULL); 457 } 458 459 460 /******************************************************************************* 461 * 462 * FUNCTION: CvFileAddressLookup 463 * 464 * PARAMETERS: Address - address to look up 465 * Head - file dependency tree 466 * 467 * RETURN: ACPI_FLE_NODE - pointer to a file node containing the address 468 * 469 * DESCRIPTION: Look for the given address in the file dependency tree. 470 * Returns the first file node where the given address is within 471 * the file node's starting and ending address. 472 * 473 ******************************************************************************/ 474 475 static ACPI_FILE_NODE* 476 CvFileAddressLookup( 477 char *Address, 478 ACPI_FILE_NODE *Head) 479 { 480 ACPI_FILE_NODE *Current = Head; 481 482 483 while (Current) 484 { 485 if ((Address >= Current->FileStart) && 486 (Address < Current->FileEnd || 487 !Current->FileEnd)) 488 { 489 return (Current); 490 } 491 Current = Current->Next; 492 } 493 494 return (NULL); 495 } 496 497 498 /******************************************************************************* 499 * 500 * FUNCTION: CvLabelFileNode 501 * 502 * PARAMETERS: Op 503 * 504 * RETURN: None 505 * 506 * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field 507 * within the file tree and fills in approperiate file information 508 * from a matching node within the tree. 509 * This is referred as ASL_CV_LABEL_FILENODE. 510 * 511 ******************************************************************************/ 512 513 void 514 CvLabelFileNode( 515 ACPI_PARSE_OBJECT *Op) 516 { 517 ACPI_FILE_NODE *Node; 518 519 520 if (!Op) 521 { 522 return; 523 } 524 525 Node = CvFileAddressLookup ((char *)Op->Common.Aml, AcpiGbl_FileTreeRoot); 526 if (!Node) 527 { 528 return; 529 } 530 531 Op->Common.CvFilename = Node->Filename; 532 if (Node->Parent) 533 { 534 Op->Common.CvParentFilename = Node->Parent->Filename; 535 } 536 else 537 { 538 Op->Common.CvParentFilename = Node->Filename; 539 } 540 } 541 542 543 /******************************************************************************* 544 * 545 * FUNCTION: CvAddToFileTree 546 * 547 * PARAMETERS: Filename - Address containing the name of the current 548 * filename 549 * PreviousFilename - Address containing the name of the previous 550 * filename 551 * 552 * RETURN: void 553 * 554 * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist. 555 * 556 ******************************************************************************/ 557 558 static void 559 CvAddToFileTree ( 560 char *Filename, 561 char *PreviousFilename) 562 { 563 ACPI_FILE_NODE *Node; 564 565 566 if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 567 PreviousFilename) 568 { 569 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 570 if (Node) 571 { 572 /* 573 * Set the end point of the PreviousFilename to the address 574 * of Filename. 575 */ 576 Node->FileEnd = Filename; 577 } 578 } 579 else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 580 !PreviousFilename) 581 { 582 return; 583 } 584 585 Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 586 if (Node && PreviousFilename) 587 { 588 /* 589 * Update the end of the previous file and all of their parents' ending 590 * Addresses. This is done to ensure that parent file ranges extend to 591 * the end of their childrens' files. 592 */ 593 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 594 if (Node && (Node->FileEnd < Filename)) 595 { 596 Node->FileEnd = Filename; 597 Node = Node->Parent; 598 while (Node) 599 { 600 if (Node->FileEnd < Filename) 601 { 602 Node->FileEnd = Filename; 603 } 604 Node = Node->Parent; 605 } 606 } 607 } 608 else 609 { 610 Node = AcpiGbl_FileTreeRoot; 611 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 612 AcpiGbl_FileTreeRoot->Next = Node; 613 AcpiGbl_FileTreeRoot->Parent = NULL; 614 AcpiGbl_FileTreeRoot->Filename = Filename; 615 AcpiGbl_FileTreeRoot->FileStart = Filename; 616 AcpiGbl_FileTreeRoot->IncludeWritten = FALSE; 617 AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+"); 618 619 /* 620 * If we can't open the file, we need to abort here before we 621 * accidentally write to a NULL file. 622 */ 623 if (!AcpiGbl_FileTreeRoot->File) 624 { 625 /* delete the .xxx file */ 626 627 FlDeleteFile (ASL_FILE_AML_OUTPUT); 628 sprintf (MsgBuffer, "\"%s\" - %s", Filename, strerror (errno)); 629 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, NULL, MsgBuffer); 630 AslAbort (); 631 } 632 } 633 } 634 635 636 /******************************************************************************* 637 * 638 * FUNCTION: CvSetFileParent 639 * 640 * PARAMETERS: ChildFile - contains the filename of the child file 641 * ParentFile - contains the filename of the parent file. 642 * 643 * RETURN: none 644 * 645 * DESCRIPTION: point the parent pointer of the Child to the node that 646 * corresponds with the parent file node. 647 * 648 ******************************************************************************/ 649 650 static void 651 CvSetFileParent ( 652 char *ChildFile, 653 char *ParentFile) 654 { 655 ACPI_FILE_NODE *Child; 656 ACPI_FILE_NODE *Parent; 657 658 659 Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot); 660 Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot); 661 if (Child && Parent) 662 { 663 Child->Parent = Parent; 664 665 while (Child->Parent) 666 { 667 if (Child->Parent->FileEnd < Child->FileStart) 668 { 669 Child->Parent->FileEnd = Child->FileStart; 670 } 671 Child = Child->Parent; 672 } 673 } 674 } 675 676 677 /******************************************************************************* 678 * 679 * FUNCTION: CvCaptureCommentsOnly 680 * 681 * PARAMETERS: ParserState - A parser state object 682 * 683 * RETURN: none 684 * 685 * DESCRIPTION: look at the aml that the parser state is pointing to, 686 * capture any AML_COMMENT_OP and it's arguments and increment the 687 * aml pointer past the comment. Comments are transferred to parse 688 * nodes through CvTransferComments() as well as 689 * AcpiPsBuildNamedOp(). 690 * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY. 691 * 692 ******************************************************************************/ 693 694 void 695 CvCaptureCommentsOnly ( 696 ACPI_PARSE_STATE *ParserState) 697 { 698 UINT8 *Aml = ParserState->Aml; 699 UINT16 Opcode = (UINT16) ACPI_GET8 (Aml); 700 UINT32 Length = 0; 701 UINT8 CommentOption = (UINT16) ACPI_GET8 (Aml+1); 702 BOOLEAN StdDefBlockFlag = FALSE; 703 ACPI_COMMENT_NODE *CommentNode; 704 ACPI_FILE_NODE *FileNode; 705 706 707 if (!Gbl_CaptureComments || 708 Opcode != AML_COMMENT_OP) 709 { 710 return; 711 } 712 713 while (Opcode == AML_COMMENT_OP) 714 { 715 CvDbgPrint ("comment aml address: %p\n", Aml); 716 717 if (CvCommentExists(ParserState->Aml)) 718 { 719 CvDbgPrint ("Avoiding capturing an existing comment.\n"); 720 } 721 else 722 { 723 CommentOption = *(Aml+1); 724 725 /* Increment past the comment option and point the approperiate char pointers.*/ 726 727 Aml += 2; 728 729 /* found a comment. Now, set pointers to these comments. */ 730 731 switch (CommentOption) 732 { 733 case STD_DEFBLK_COMMENT: 734 735 StdDefBlockFlag = TRUE; 736 737 /* add to a linked list of nodes. This list will be taken by the parse node created next. */ 738 739 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 740 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 741 CommentNode->Next = NULL; 742 743 if (!AcpiGbl_DefBlkCommentListHead) 744 { 745 AcpiGbl_DefBlkCommentListHead = CommentNode; 746 AcpiGbl_DefBlkCommentListTail = CommentNode; 747 } 748 else 749 { 750 AcpiGbl_DefBlkCommentListTail->Next = CommentNode; 751 AcpiGbl_DefBlkCommentListTail = AcpiGbl_DefBlkCommentListTail->Next; 752 } 753 break; 754 755 case STANDARD_COMMENT: 756 757 CvDbgPrint ("found regular comment.\n"); 758 759 /* add to a linked list of nodes. This list will be taken by the parse node created next. */ 760 761 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 762 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 763 CommentNode->Next = NULL; 764 765 if (!AcpiGbl_RegCommentListHead) 766 { 767 AcpiGbl_RegCommentListHead = CommentNode; 768 AcpiGbl_RegCommentListTail = CommentNode; 769 } 770 else 771 { 772 AcpiGbl_RegCommentListTail->Next = CommentNode; 773 AcpiGbl_RegCommentListTail = AcpiGbl_RegCommentListTail->Next; 774 } 775 break; 776 777 case ENDBLK_COMMENT: 778 779 CvDbgPrint ("found endblk comment.\n"); 780 781 /* add to a linked list of nodes. This will be taken by the next created parse node. */ 782 783 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 784 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 785 CommentNode->Next = NULL; 786 787 if (!AcpiGbl_EndBlkCommentListHead) 788 { 789 AcpiGbl_EndBlkCommentListHead = CommentNode; 790 AcpiGbl_EndBlkCommentListTail = CommentNode; 791 } 792 else 793 { 794 AcpiGbl_EndBlkCommentListTail->Next = CommentNode; 795 AcpiGbl_EndBlkCommentListTail = AcpiGbl_EndBlkCommentListTail->Next; 796 } 797 break; 798 799 case INLINE_COMMENT: 800 801 CvDbgPrint ("found inline comment.\n"); 802 AcpiGbl_CurrentInlineComment = ACPI_CAST_PTR (char, Aml); 803 break; 804 805 case ENDNODE_COMMENT: 806 807 CvDbgPrint ("found EndNode comment.\n"); 808 AcpiGbl_CurrentEndNodeComment = ACPI_CAST_PTR (char, Aml); 809 break; 810 811 case CLOSE_BRACE_COMMENT: 812 813 CvDbgPrint ("found close brace comment.\n"); 814 AcpiGbl_CurrentCloseBraceComment = ACPI_CAST_PTR (char, Aml); 815 break; 816 817 case END_DEFBLK_COMMENT: 818 819 CvDbgPrint ("Found comment that belongs after the } for a definition block.\n"); 820 AcpiGbl_CurrentScope->Common.CloseBraceComment = ACPI_CAST_PTR (char, Aml); 821 break; 822 823 case FILENAME_COMMENT: 824 825 CvDbgPrint ("Found a filename: %s\n", ACPI_CAST_PTR (char, Aml)); 826 FileNode = CvFilenameExists (ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot); 827 828 /* 829 * If there is an INCLUDE_COMMENT followed by a 830 * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment 831 * that is emitted before the #include for the file. 832 * We will save the IncludeComment within the FileNode 833 * associated with this FILENAME_COMMENT. 834 */ 835 if (FileNode && AcpiGbl_IncCommentListHead) 836 { 837 FileNode->IncludeComment = AcpiGbl_IncCommentListHead; 838 AcpiGbl_IncCommentListHead = NULL; 839 AcpiGbl_IncCommentListTail = NULL; 840 } 841 break; 842 843 case PARENTFILENAME_COMMENT: 844 CvDbgPrint (" Found a parent filename.\n"); 845 break; 846 847 case INCLUDE_COMMENT: 848 849 /* 850 * Add to a linked list. This list will be taken by the 851 * parse node created next. See the FILENAME_COMMENT case 852 * for more details 853 */ 854 CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 855 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 856 CommentNode->Next = NULL; 857 858 if (!AcpiGbl_IncCommentListHead) 859 { 860 AcpiGbl_IncCommentListHead = CommentNode; 861 AcpiGbl_IncCommentListTail = CommentNode; 862 } 863 else 864 { 865 AcpiGbl_IncCommentListTail->Next = CommentNode; 866 AcpiGbl_IncCommentListTail = AcpiGbl_IncCommentListTail->Next; 867 } 868 869 CvDbgPrint ("Found a include comment: %s\n", CommentNode->Comment); 870 break; 871 872 default: 873 874 /* Not a valid comment option. Revert the AML */ 875 876 Aml -= 2; 877 goto DefBlock; 878 break; 879 880 } /* end switch statement */ 881 882 } /* end else */ 883 884 /* determine the length and move forward that amount */ 885 886 Length = 0; 887 while (ParserState->Aml[Length]) 888 { 889 Length++; 890 } 891 892 ParserState->Aml += Length + 1; 893 894 895 /* Peek at the next Opcode. */ 896 897 Aml = ParserState->Aml; 898 Opcode = (UINT16) ACPI_GET8 (Aml); 899 900 } 901 902 DefBlock: 903 if (StdDefBlockFlag) 904 { 905 /* 906 * Give all of its comments to the current scope, which is known as 907 * the definition block, since STD_DEFBLK_COMMENT only appears after 908 * definition block headers. 909 */ 910 AcpiGbl_CurrentScope->Common.CommentList 911 = AcpiGbl_DefBlkCommentListHead; 912 AcpiGbl_DefBlkCommentListHead = NULL; 913 AcpiGbl_DefBlkCommentListTail = NULL; 914 } 915 } 916 917 918 /******************************************************************************* 919 * 920 * FUNCTION: CvCaptureComments 921 * 922 * PARAMETERS: ParserState - A parser state object 923 * 924 * RETURN: none 925 * 926 * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly 927 * This is referred as ASL_CV_CAPTURE_COMMENTS. 928 * 929 ******************************************************************************/ 930 931 void 932 CvCaptureComments ( 933 ACPI_WALK_STATE *WalkState) 934 { 935 UINT8 *Aml; 936 UINT16 Opcode; 937 const ACPI_OPCODE_INFO *OpInfo; 938 939 940 if (!Gbl_CaptureComments) 941 { 942 return; 943 } 944 945 /* 946 * Before parsing, check to see that comments that come directly after 947 * deferred opcodes aren't being processed. 948 */ 949 Aml = WalkState->ParserState.Aml; 950 Opcode = (UINT16) ACPI_GET8 (Aml); 951 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 952 953 if (!(OpInfo->Flags & AML_DEFER) || 954 ((OpInfo->Flags & AML_DEFER) && 955 (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1))) 956 { 957 CvCaptureCommentsOnly (&WalkState->ParserState); 958 WalkState->Aml = WalkState->ParserState.Aml; 959 } 960 961 } 962 963 964 /******************************************************************************* 965 * 966 * FUNCTION: CvTransferComments 967 * 968 * PARAMETERS: Op - Transfer comments to this Op 969 * 970 * RETURN: none 971 * 972 * DESCRIPTION: Transfer all of the commments stored in global containers to the 973 * given Op. This will be invoked shortly after the parser creates 974 * a ParseOp. 975 * This is referred as ASL_CV_TRANSFER_COMMENTS. 976 * 977 ******************************************************************************/ 978 979 void 980 CvTransferComments ( 981 ACPI_PARSE_OBJECT *Op) 982 { 983 Op->Common.InlineComment = AcpiGbl_CurrentInlineComment; 984 AcpiGbl_CurrentInlineComment = NULL; 985 986 Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment; 987 AcpiGbl_CurrentEndNodeComment = NULL; 988 989 Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment; 990 AcpiGbl_CurrentCloseBraceComment = NULL; 991 992 Op->Common.CommentList = AcpiGbl_RegCommentListHead; 993 AcpiGbl_RegCommentListHead = NULL; 994 AcpiGbl_RegCommentListTail = NULL; 995 996 Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead; 997 AcpiGbl_EndBlkCommentListHead = NULL; 998 AcpiGbl_EndBlkCommentListTail = NULL; 999 1000 } 1001