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