1 2 /****************************************************************************** 3 * 4 * Module Name: aslanalyze.c - check for semantic errors 5 * $Revision: 77 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 119 #include "aslcompiler.h" 120 #include "aslcompiler.y.h" 121 #include "acparser.h" 122 #include "amlcode.h" 123 124 #include <ctype.h> 125 126 #define _COMPONENT ACPI_COMPILER 127 ACPI_MODULE_NAME ("aslanalyze") 128 129 130 /******************************************************************************* 131 * 132 * FUNCTION: AnMapArgTypeToBtype 133 * 134 * PARAMETERS: ArgType - The ARGI required type(s) for this argument, 135 * from the opcode info table 136 * 137 * RETURN: The corresponding Bit-encoded types 138 * 139 * DESCRIPTION: Convert an encoded ARGI required argument type code into a 140 * bitfield type code. Implements the implicit source conversion 141 * rules. 142 * 143 ******************************************************************************/ 144 145 UINT32 146 AnMapArgTypeToBtype ( 147 UINT32 ArgType) 148 { 149 150 switch (ArgType) 151 { 152 153 /* Simple types */ 154 155 case ARGI_ANYTYPE: 156 return (ACPI_BTYPE_OBJECTS_AND_REFS); 157 158 case ARGI_PACKAGE: 159 return (ACPI_BTYPE_PACKAGE); 160 161 case ARGI_EVENT: 162 return (ACPI_BTYPE_EVENT); 163 164 case ARGI_MUTEX: 165 return (ACPI_BTYPE_MUTEX); 166 167 case ARGI_DDBHANDLE: 168 return (ACPI_BTYPE_DDB_HANDLE); 169 170 /* Interchangeable types */ 171 /* 172 * Source conversion rules: 173 * Integer, String, and Buffer are all interchangeable 174 */ 175 case ARGI_INTEGER: 176 case ARGI_STRING: 177 case ARGI_BUFFER: 178 case ARGI_BUFFER_OR_STRING: 179 case ARGI_COMPUTEDATA: 180 return (ACPI_BTYPE_COMPUTE_DATA); 181 182 /* References */ 183 184 case ARGI_INTEGER_REF: 185 return (ACPI_BTYPE_INTEGER); 186 187 case ARGI_OBJECT_REF: 188 return (ACPI_BTYPE_ALL_OBJECTS); 189 190 case ARGI_DEVICE_REF: 191 return (ACPI_BTYPE_DEVICE_OBJECTS); 192 193 case ARGI_REFERENCE: 194 return (ACPI_BTYPE_REFERENCE); 195 196 case ARGI_TARGETREF: 197 case ARGI_FIXED_TARGET: 198 case ARGI_SIMPLE_TARGET: 199 return (ACPI_BTYPE_OBJECTS_AND_REFS); 200 201 /* Complex types */ 202 203 case ARGI_DATAOBJECT: 204 205 /* Buffer, string, package or reference to a Op - Used only by SizeOf operator*/ 206 207 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE); 208 209 case ARGI_COMPLEXOBJ: 210 211 /* Buffer, String, or package */ 212 213 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE); 214 215 case ARGI_REF_OR_STRING: 216 return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE); 217 218 case ARGI_REGION_OR_FIELD: 219 return (ACPI_BTYPE_REGION | ACPI_BTYPE_FIELD_UNIT); 220 221 default: 222 break; 223 } 224 225 return (ACPI_BTYPE_OBJECTS_AND_REFS); 226 } 227 228 229 /******************************************************************************* 230 * 231 * FUNCTION: AnMapEtypeToBtype 232 * 233 * PARAMETERS: Etype - Encoded ACPI Type 234 * 235 * RETURN: Btype corresponding to the Etype 236 * 237 * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the 238 * operand conversion rules. In other words, returns the type(s) 239 * this Etype is implicitly converted to during interpretation. 240 * 241 ******************************************************************************/ 242 243 UINT32 244 AnMapEtypeToBtype ( 245 UINT32 Etype) 246 { 247 248 249 if (Etype == ACPI_TYPE_ANY) 250 { 251 return ACPI_BTYPE_OBJECTS_AND_REFS; 252 } 253 254 /* Try the standard ACPI data types */ 255 256 if (Etype <= ACPI_TYPE_EXTERNAL_MAX) 257 { 258 /* 259 * This switch statement implements the allowed operand conversion 260 * rules as per the "ASL Data Types" section of the ACPI 261 * specification. 262 */ 263 switch (Etype) 264 { 265 case ACPI_TYPE_INTEGER: 266 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE); 267 268 case ACPI_TYPE_STRING: 269 case ACPI_TYPE_BUFFER: 270 return (ACPI_BTYPE_COMPUTE_DATA); 271 272 case ACPI_TYPE_PACKAGE: 273 return (ACPI_BTYPE_PACKAGE); 274 275 case ACPI_TYPE_FIELD_UNIT: 276 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 277 278 case ACPI_TYPE_BUFFER_FIELD: 279 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD); 280 281 case ACPI_TYPE_DDB_HANDLE: 282 return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE); 283 284 case ACPI_BTYPE_DEBUG_OBJECT: 285 286 /* Cannot be used as a source operand */ 287 288 return (0); 289 290 default: 291 return (1 << (Etype - 1)); 292 } 293 } 294 295 /* Try the internal data types */ 296 297 switch (Etype) 298 { 299 case ACPI_TYPE_LOCAL_REGION_FIELD: 300 case ACPI_TYPE_LOCAL_BANK_FIELD: 301 case ACPI_TYPE_LOCAL_INDEX_FIELD: 302 303 /* Named fields can be either Integer/Buffer/String */ 304 305 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 306 307 case ACPI_TYPE_LOCAL_ALIAS: 308 309 return (ACPI_BTYPE_INTEGER); 310 311 312 case ACPI_TYPE_LOCAL_RESOURCE: 313 case ACPI_TYPE_LOCAL_RESOURCE_FIELD: 314 315 return (ACPI_BTYPE_REFERENCE); 316 317 default: 318 printf ("Unhandled encoded type: %X\n", Etype); 319 return (0); 320 } 321 } 322 323 324 /******************************************************************************* 325 * 326 * FUNCTION: AnMapBtypeToEtype 327 * 328 * PARAMETERS: Btype - Bitfield of ACPI types 329 * 330 * RETURN: The Etype corresponding the the Btype 331 * 332 * DESCRIPTION: Convert a bitfield type to an encoded type 333 * 334 ******************************************************************************/ 335 336 UINT32 337 AnMapBtypeToEtype ( 338 UINT32 Btype) 339 { 340 UINT32 i; 341 UINT32 Etype; 342 343 344 if (Btype == 0) 345 { 346 return 0; 347 } 348 349 Etype = 1; 350 for (i = 1; i < Btype; i *= 2) 351 { 352 Etype++; 353 } 354 355 return (Etype); 356 } 357 358 359 /******************************************************************************* 360 * 361 * FUNCTION: AnFormatBtype 362 * 363 * PARAMETERS: Btype - Bitfield of ACPI types 364 * Buffer - Where to put the ascii string 365 * 366 * RETURN: None. 367 * 368 * DESCRIPTION: Convert a Btype to a string of ACPI types 369 * 370 ******************************************************************************/ 371 372 void 373 AnFormatBtype ( 374 char *Buffer, 375 UINT32 Btype) 376 { 377 UINT32 Type; 378 BOOLEAN First = TRUE; 379 380 381 *Buffer = 0; 382 383 if (Btype == 0) 384 { 385 strcat (Buffer, "NoReturnValue"); 386 return; 387 } 388 389 for (Type = 1; Type < ACPI_TYPE_EXTERNAL_MAX; Type++) 390 { 391 if (Btype & 0x00000001) 392 { 393 if (!First) 394 { 395 strcat (Buffer, "|"); 396 } 397 First = FALSE; 398 strcat (Buffer, AcpiUtGetTypeName (Type)); 399 } 400 Btype >>= 1; 401 } 402 403 if (Btype & 0x00000001) 404 { 405 if (!First) 406 { 407 strcat (Buffer, "|"); 408 } 409 First = FALSE; 410 strcat (Buffer, "Reference"); 411 } 412 413 Btype >>= 1; 414 if (Btype & 0x00000001) 415 { 416 if (!First) 417 { 418 strcat (Buffer, "|"); 419 } 420 First = FALSE; 421 strcat (Buffer, "Resource"); 422 } 423 } 424 425 426 /******************************************************************************* 427 * 428 * FUNCTION: AnGetBtype 429 * 430 * PARAMETERS: Op - Parse node whose type will be returned. 431 * 432 * RETURN: The Btype associated with the Op. 433 * 434 * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node. 435 * Handles the case where the node is a name or method call and 436 * the actual type must be obtained from the namespace node. 437 * 438 ******************************************************************************/ 439 440 UINT32 441 AnGetBtype ( 442 ACPI_PARSE_OBJECT *Op) 443 { 444 ACPI_NAMESPACE_NODE *Node; 445 ACPI_PARSE_OBJECT *ReferencedNode; 446 UINT32 ThisNodeBtype = 0; 447 448 449 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 450 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 451 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 452 { 453 Node = Op->Asl.Node; 454 if (!Node) 455 { 456 DbgPrint (ASL_DEBUG_OUTPUT, 457 "Null attached Nsnode: [%s] at line %d\n", 458 Op->Asl.ParseOpName, Op->Asl.LineNumber); 459 return ACPI_UINT32_MAX; 460 } 461 462 ThisNodeBtype = AnMapEtypeToBtype (Node->Type); 463 464 /* 465 * Since it was a named reference, enable the 466 * reference bit also 467 */ 468 ThisNodeBtype |= ACPI_BTYPE_REFERENCE; 469 470 if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) 471 { 472 ReferencedNode = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object); 473 if (!ReferencedNode) 474 { 475 printf ("No back ptr to Op: type %X\n", Node->Type); 476 return ACPI_UINT32_MAX; 477 } 478 479 if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED) 480 { 481 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype; 482 } 483 else 484 { 485 return (ACPI_UINT32_MAX -1); 486 } 487 } 488 } 489 else 490 { 491 ThisNodeBtype = Op->Asl.AcpiBtype; 492 } 493 494 return (ThisNodeBtype); 495 } 496 497 498 /******************************************************************************* 499 * 500 * FUNCTION: AnCheckForReservedName 501 * 502 * PARAMETERS: Op - A parse node 503 * Name - NameSeg to check 504 * 505 * RETURN: None 506 * 507 * DESCRIPTION: Check a NameSeg against the reserved list. 508 * 509 ******************************************************************************/ 510 511 #define ACPI_VALID_RESERVED_NAME_MAX 0x80000000 512 #define ACPI_NOT_RESERVED_NAME ACPI_UINT32_MAX 513 #define ACPI_PREDEFINED_NAME (ACPI_UINT32_MAX - 1) 514 #define ACPI_EVENT_RESERVED_NAME (ACPI_UINT32_MAX - 2) 515 #define ACPI_COMPILER_RESERVED_NAME (ACPI_UINT32_MAX - 3) 516 517 UINT32 518 AnCheckForReservedName ( 519 ACPI_PARSE_OBJECT *Op, 520 char *Name) 521 { 522 UINT32 i; 523 524 525 if (Name[0] == 0) 526 { 527 AcpiOsPrintf ("Found a null name, external = %s\n", Op->Asl.ExternalName); 528 } 529 530 /* All reserved names are prefixed with a single underscore */ 531 532 if (Name[0] != '_') 533 { 534 return (ACPI_NOT_RESERVED_NAME); 535 } 536 537 /* Check for a standard reserved method name */ 538 539 for (i = 0; ReservedMethods[i].Name; i++) 540 { 541 if (!ACPI_STRNCMP (Name, ReservedMethods[i].Name, ACPI_NAME_SIZE)) 542 { 543 if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE) 544 { 545 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName); 546 return (ACPI_PREDEFINED_NAME); 547 } 548 else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME) 549 { 550 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName); 551 return (ACPI_PREDEFINED_NAME); 552 } 553 554 /* Return index into reserved array */ 555 556 return i; 557 } 558 } 559 560 /* 561 * Now check for the "special" reserved names -- 562 * GPE: _Lxx 563 * GPE: _Exx 564 * EC: _Qxx 565 */ 566 if ((Name[1] == 'L') || 567 (Name[1] == 'E') || 568 (Name[1] == 'Q')) 569 { 570 /* The next two characters must be hex digits */ 571 572 if ((isxdigit (Name[2])) && 573 (isxdigit (Name[3]))) 574 { 575 return (ACPI_EVENT_RESERVED_NAME); 576 } 577 } 578 579 580 /* Check for the names reserved for the compiler itself: _T_x */ 581 582 else if ((Op->Asl.ExternalName[1] == 'T') && 583 (Op->Asl.ExternalName[2] == '_')) 584 { 585 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName); 586 return (ACPI_COMPILER_RESERVED_NAME); 587 } 588 589 /* 590 * The name didn't match any of the known reserved names. Flag it as a 591 * warning, since the entire namespace starting with an underscore is 592 * reserved by the ACPI spec. 593 */ 594 AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, Op->Asl.ExternalName); 595 596 return (ACPI_NOT_RESERVED_NAME); 597 } 598 599 600 /******************************************************************************* 601 * 602 * FUNCTION: AnCheckForReservedMethod 603 * 604 * PARAMETERS: Op - A parse node of type "METHOD". 605 * MethodInfo - Saved info about this method 606 * 607 * RETURN: None 608 * 609 * DESCRIPTION: If method is a reserved name, check that the number of arguments 610 * and the return type (returns a value or not) is correct. 611 * 612 ******************************************************************************/ 613 614 void 615 AnCheckForReservedMethod ( 616 ACPI_PARSE_OBJECT *Op, 617 ASL_METHOD_INFO *MethodInfo) 618 { 619 UINT32 Index; 620 621 622 /* Check for a match against the reserved name list */ 623 624 Index = AnCheckForReservedName (Op, Op->Asl.NameSeg); 625 626 switch (Index) 627 { 628 case ACPI_NOT_RESERVED_NAME: 629 case ACPI_PREDEFINED_NAME: 630 case ACPI_COMPILER_RESERVED_NAME: 631 632 /* Just return, nothing to do */ 633 break; 634 635 636 case ACPI_EVENT_RESERVED_NAME: 637 638 Gbl_ReservedMethods++; 639 640 /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */ 641 642 if (MethodInfo->NumArguments != 0) 643 { 644 sprintf (MsgBuffer, " %s requires %d", 645 Op->Asl.ExternalName, 0); 646 647 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer); 648 } 649 break; 650 651 652 default: 653 654 Gbl_ReservedMethods++; 655 656 /* Matched a reserved method name */ 657 658 if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments) 659 { 660 sprintf (MsgBuffer, " %s requires %d", 661 ReservedMethods[Index].Name, 662 ReservedMethods[Index].NumArguments); 663 664 if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments) 665 { 666 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer); 667 } 668 else 669 { 670 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, MsgBuffer); 671 } 672 } 673 674 if (MethodInfo->NumReturnNoValue && 675 ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE) 676 { 677 sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name); 678 679 AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer); 680 } 681 break; 682 } 683 } 684 685 686 /******************************************************************************* 687 * 688 * FUNCTION: AnMethodAnalysisWalkBegin 689 * 690 * PARAMETERS: ASL_WALK_CALLBACK 691 * 692 * RETURN: Status 693 * 694 * DESCRIPTION: Descending callback for the analysis walk. Check methods for : 695 * 1) Initialized local variables 696 * 2) Valid arguments 697 * 3) Return types 698 * 699 ******************************************************************************/ 700 701 ACPI_STATUS 702 AnMethodAnalysisWalkBegin ( 703 ACPI_PARSE_OBJECT *Op, 704 UINT32 Level, 705 void *Context) 706 { 707 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 708 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 709 ACPI_PARSE_OBJECT *Next; 710 UINT32 RegisterNumber; 711 UINT32 i; 712 char LocalName[] = "Local0"; 713 char ArgName[] = "Arg0"; 714 715 716 ACPI_FUNCTION_NAME ("AnMethodAnalysisWalkBegin"); 717 718 719 switch (Op->Asl.ParseOpcode) 720 { 721 case PARSEOP_METHOD: 722 723 TotalMethods++; 724 725 /* 726 * Create and init method info 727 */ 728 MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 729 MethodInfo->Next = WalkInfo->MethodStack; 730 MethodInfo->Op = Op; 731 732 WalkInfo->MethodStack = MethodInfo; 733 734 /* Get the NumArguments node */ 735 736 Next = Op->Asl.Child; 737 Next = Next->Asl.Next; 738 MethodInfo->NumArguments = (UINT8) (((UINT8) Next->Asl.Value.Integer) & 0x07); 739 740 /* 741 * Actual arguments are initialized at method entry. 742 * All other ArgX "registers" can be used as locals, so we 743 * track their initialization. 744 */ 745 for (i = 0; i < MethodInfo->NumArguments; i++) 746 { 747 MethodInfo->ArgInitialized[i] = TRUE; 748 } 749 750 break; 751 752 753 case PARSEOP_METHODCALL: 754 755 if (MethodInfo && 756 (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 757 { 758 AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 759 } 760 break; 761 762 763 case PARSEOP_LOCAL0: 764 case PARSEOP_LOCAL1: 765 case PARSEOP_LOCAL2: 766 case PARSEOP_LOCAL3: 767 case PARSEOP_LOCAL4: 768 case PARSEOP_LOCAL5: 769 case PARSEOP_LOCAL6: 770 case PARSEOP_LOCAL7: 771 772 if (!MethodInfo) 773 { 774 /* Probably was an error in the method declaration, no additional error here */ 775 776 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op)); 777 return (AE_ERROR); 778 } 779 780 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F); 781 782 /* 783 * If the local is being used as a target, mark the local 784 * initialized 785 */ 786 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 787 { 788 MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 789 } 790 791 /* 792 * Otherwise, this is a reference, check if the local 793 * has been previously initialized. 794 */ 795 else if (!MethodInfo->LocalInitialized[RegisterNumber]) 796 { 797 LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 798 AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 799 } 800 break; 801 802 803 case PARSEOP_ARG0: 804 case PARSEOP_ARG1: 805 case PARSEOP_ARG2: 806 case PARSEOP_ARG3: 807 case PARSEOP_ARG4: 808 case PARSEOP_ARG5: 809 case PARSEOP_ARG6: 810 811 if (!MethodInfo) 812 { 813 /* Probably was an error in the method declaration, no additional error here */ 814 815 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op)); 816 return (AE_ERROR); 817 } 818 819 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 820 ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 821 822 /* 823 * If the Arg is being used as a target, mark the local 824 * initialized 825 */ 826 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 827 { 828 MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 829 } 830 831 /* 832 * Otherwise, this is a reference, check if the Arg 833 * has been previously initialized. 834 */ 835 else if (!MethodInfo->ArgInitialized[RegisterNumber]) 836 { 837 AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 838 } 839 840 /* Flag this arg if it is not a "real" argument to the method */ 841 842 if (RegisterNumber >= MethodInfo->NumArguments) 843 { 844 AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 845 } 846 break; 847 848 849 case PARSEOP_RETURN: 850 851 if (!MethodInfo) 852 { 853 /* Probably was an error in the method declaration, no additional error here */ 854 855 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op)); 856 return (AE_ERROR); 857 } 858 859 /* Child indicates a return value */ 860 861 if ((Op->Asl.Child) && 862 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 863 { 864 MethodInfo->NumReturnWithValue++; 865 } 866 else 867 { 868 MethodInfo->NumReturnNoValue++; 869 } 870 break; 871 872 873 case PARSEOP_BREAK: 874 case PARSEOP_CONTINUE: 875 876 Next = Op->Asl.Parent; 877 while (Next) 878 { 879 if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 880 { 881 break; 882 } 883 Next = Next->Asl.Parent; 884 } 885 886 if (!Next) 887 { 888 AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 889 } 890 break; 891 892 893 case PARSEOP_DEVICE: 894 case PARSEOP_EVENT: 895 case PARSEOP_MUTEX: 896 case PARSEOP_OPERATIONREGION: 897 case PARSEOP_POWERRESOURCE: 898 case PARSEOP_PROCESSOR: 899 case PARSEOP_THERMALZONE: 900 901 /* 902 * The first operand is a name to be created in the namespace. 903 * Check against the reserved list. 904 */ 905 i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 906 if (i < ACPI_VALID_RESERVED_NAME_MAX) 907 { 908 AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); 909 } 910 break; 911 912 913 case PARSEOP_NAME: 914 915 i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 916 if (i < ACPI_VALID_RESERVED_NAME_MAX) 917 { 918 if (ReservedMethods[i].NumArguments > 0) 919 { 920 /* 921 * This reserved name must be a control method because 922 * it must have arguments 923 */ 924 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments"); 925 } 926 927 /* 928 * Typechecking for _HID 929 */ 930 else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name)) 931 { 932 /* Examine the second operand to typecheck it */ 933 934 Next = Op->Asl.Child->Asl.Next; 935 936 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) && 937 (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)) 938 { 939 /* _HID must be a string or an integer */ 940 941 AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer"); 942 } 943 944 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 945 { 946 /* 947 * _HID is a string, all characters must be alphanumeric. 948 * One of the things we want to catch here is the use of 949 * a leading asterisk in the string. 950 */ 951 for (i = 0; Next->Asl.Value.String[i]; i++) 952 { 953 if (!isalnum (Next->Asl.Value.String[i])) 954 { 955 AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String); 956 break; 957 } 958 } 959 } 960 } 961 } 962 963 break; 964 965 966 default: 967 break; 968 } 969 970 return AE_OK; 971 } 972 973 974 /******************************************************************************* 975 * 976 * FUNCTION: AnLastStatementIsReturn 977 * 978 * PARAMETERS: Op - A method parse node 979 * 980 * RETURN: TRUE if last statement is an ASL RETURN. False otherwise 981 * 982 * DESCRIPTION: Walk down the list of top level statements within a method 983 * to find the last one. Check if that last statement is in 984 * fact a RETURN statement. 985 * 986 ******************************************************************************/ 987 988 BOOLEAN 989 AnLastStatementIsReturn ( 990 ACPI_PARSE_OBJECT *Op) 991 { 992 ACPI_PARSE_OBJECT *Next; 993 994 995 /* 996 * Check if last statement is a return 997 */ 998 Next = ASL_GET_CHILD_NODE (Op); 999 while (Next) 1000 { 1001 if ((!Next->Asl.Next) && 1002 (Next->Asl.ParseOpcode == PARSEOP_RETURN)) 1003 { 1004 return TRUE; 1005 } 1006 1007 Next = ASL_GET_PEER_NODE (Next); 1008 } 1009 1010 return FALSE; 1011 } 1012 1013 1014 /******************************************************************************* 1015 * 1016 * FUNCTION: AnMethodAnalysisWalkEnd 1017 * 1018 * PARAMETERS: ASL_WALK_CALLBACK 1019 * 1020 * RETURN: Status 1021 * 1022 * DESCRIPTION: Ascending callback for analysis walk. Complete method 1023 * return analysis. 1024 * 1025 ******************************************************************************/ 1026 1027 ACPI_STATUS 1028 AnMethodAnalysisWalkEnd ( 1029 ACPI_PARSE_OBJECT *Op, 1030 UINT32 Level, 1031 void *Context) 1032 { 1033 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 1034 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 1035 1036 1037 switch (Op->Asl.ParseOpcode) 1038 { 1039 case PARSEOP_METHOD: 1040 case PARSEOP_RETURN: 1041 if (!MethodInfo) 1042 { 1043 printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 1044 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method"); 1045 CmCleanupAndExit (); 1046 return (AE_AML_INTERNAL); 1047 } 1048 break; 1049 1050 default: 1051 break; 1052 } 1053 1054 switch (Op->Asl.ParseOpcode) 1055 { 1056 case PARSEOP_METHOD: 1057 1058 WalkInfo->MethodStack = MethodInfo->Next; 1059 1060 /* 1061 * Check if there is no return statement at the end of the 1062 * method AND we can actually get there -- i.e., the execution 1063 * of the method can possibly terminate without a return statement. 1064 */ 1065 if ((!AnLastStatementIsReturn (Op)) && 1066 (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 1067 { 1068 /* 1069 * No return statement, and execution can possibly exit 1070 * via this path. This is equivalent to Return () 1071 */ 1072 MethodInfo->NumReturnNoValue++; 1073 } 1074 1075 /* 1076 * Check for case where some return statements have a return value 1077 * and some do not. Exit without a return statement is a return with 1078 * no value 1079 */ 1080 if (MethodInfo->NumReturnNoValue && 1081 MethodInfo->NumReturnWithValue) 1082 { 1083 AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, Op->Asl.ExternalName); 1084 } 1085 1086 /* 1087 * If there are any RETURN() statements with no value, or there is a 1088 * control path that allows the method to exit without a return value, 1089 * we mark the method as a method that does not return a value. This 1090 * knowledge can be used to check method invocations that expect a 1091 * returned value. 1092 */ 1093 if (MethodInfo->NumReturnNoValue) 1094 { 1095 if (MethodInfo->NumReturnWithValue) 1096 { 1097 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 1098 } 1099 else 1100 { 1101 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 1102 } 1103 } 1104 1105 /* 1106 * Check predefined method names for correct return behavior 1107 * and correct number of arguments 1108 */ 1109 AnCheckForReservedMethod (Op, MethodInfo); 1110 ACPI_MEM_FREE (MethodInfo); 1111 break; 1112 1113 1114 case PARSEOP_RETURN: 1115 1116 /* 1117 * The parent block does not "exit" and continue execution -- the 1118 * method is terminated here with the Return() statement. 1119 */ 1120 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1121 Op->Asl.ParentMethod = MethodInfo->Op; /* Used in the "typing" pass later */ 1122 1123 /* 1124 * If there is a peer node after the return statement, then this 1125 * node is unreachable code -- i.e., it won't be executed because of the 1126 * preceeding Return() statement. 1127 */ 1128 if (Op->Asl.Next) 1129 { 1130 AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL); 1131 } 1132 break; 1133 1134 1135 case PARSEOP_IF: 1136 1137 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1138 (Op->Asl.Next) && 1139 (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 1140 { 1141 /* 1142 * This IF has a corresponding ELSE. The IF block has no exit, 1143 * (it contains an unconditional Return) 1144 * mark the ELSE block to remember this fact. 1145 */ 1146 Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 1147 } 1148 break; 1149 1150 1151 case PARSEOP_ELSE: 1152 1153 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1154 (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 1155 { 1156 /* 1157 * This ELSE block has no exit and the corresponding IF block 1158 * has no exit either. Therefore, the parent node has no exit. 1159 */ 1160 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1161 } 1162 break; 1163 1164 1165 default: 1166 1167 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1168 (Op->Asl.Parent)) 1169 { 1170 /* If this node has no exit, then the parent has no exit either */ 1171 1172 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1173 } 1174 break; 1175 } 1176 1177 return AE_OK; 1178 } 1179 1180 1181 /******************************************************************************* 1182 * 1183 * FUNCTION: AnMethodTypingWalkBegin 1184 * 1185 * PARAMETERS: ASL_WALK_CALLBACK 1186 * 1187 * RETURN: Status 1188 * 1189 * DESCRIPTION: Descending callback for the typing walk. 1190 * 1191 ******************************************************************************/ 1192 1193 ACPI_STATUS 1194 AnMethodTypingWalkBegin ( 1195 ACPI_PARSE_OBJECT *Op, 1196 UINT32 Level, 1197 void *Context) 1198 { 1199 1200 return AE_OK; 1201 } 1202 1203 1204 /******************************************************************************* 1205 * 1206 * FUNCTION: AnMethodTypingWalkEnd 1207 * 1208 * PARAMETERS: ASL_WALK_CALLBACK 1209 * 1210 * RETURN: Status 1211 * 1212 * DESCRIPTION: Ascending callback for typing walk. Complete method 1213 * return analysis. Check methods for : 1214 * 1) Initialized local variables 1215 * 2) Valid arguments 1216 * 3) Return types 1217 * 1218 ******************************************************************************/ 1219 1220 ACPI_STATUS 1221 AnMethodTypingWalkEnd ( 1222 ACPI_PARSE_OBJECT *Op, 1223 UINT32 Level, 1224 void *Context) 1225 { 1226 UINT32 ThisNodeBtype; 1227 1228 1229 switch (Op->Asl.ParseOpcode) 1230 { 1231 case PARSEOP_METHOD: 1232 1233 Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 1234 break; 1235 1236 case PARSEOP_RETURN: 1237 1238 if ((Op->Asl.Child) && 1239 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 1240 { 1241 ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1242 1243 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 1244 (ThisNodeBtype == (ACPI_UINT32_MAX -1))) 1245 { 1246 /* 1247 * The method is untyped at this time (typically a forward reference). 1248 * We must recursively type the method here 1249 */ 1250 TrWalkParseTree (ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Op->Asl.Child->Asl.Node->Object), 1251 ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin, 1252 AnMethodTypingWalkEnd, NULL); 1253 1254 ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1255 } 1256 1257 /* Returns a value, get it's type */ 1258 1259 if (Op->Asl.ParentMethod) 1260 { 1261 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype; 1262 } 1263 } 1264 break; 1265 1266 default: 1267 break; 1268 } 1269 1270 return AE_OK; 1271 } 1272 1273 1274 /******************************************************************************* 1275 * 1276 * FUNCTION: AnCheckMethodReturnValue 1277 * 1278 * PARAMETERS: Op - Parent 1279 * OpInfo - Parent info 1280 * ArgOp - Method invocation op 1281 * RequiredBtypes - What caller requires 1282 * ThisNodeBtype - What this node returns (if anything) 1283 * 1284 * RETURN: None 1285 * 1286 * DESCRIPTION: Check a method invocation for 1) A return value and if it does 1287 * in fact return a value, 2) check the type of the return value. 1288 * 1289 ******************************************************************************/ 1290 1291 void 1292 AnCheckMethodReturnValue ( 1293 ACPI_PARSE_OBJECT *Op, 1294 const ACPI_OPCODE_INFO *OpInfo, 1295 ACPI_PARSE_OBJECT *ArgOp, 1296 UINT32 RequiredBtypes, 1297 UINT32 ThisNodeBtype) 1298 { 1299 ACPI_PARSE_OBJECT *OwningOp; 1300 ACPI_NAMESPACE_NODE *Node; 1301 1302 1303 Node = ArgOp->Asl.Node; 1304 1305 1306 /* Examine the parent op of this method */ 1307 1308 OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object); 1309 if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL) 1310 { 1311 /* 1312 * Method NEVER returns a value 1313 */ 1314 AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName); 1315 } 1316 else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL) 1317 { 1318 /* 1319 * Method SOMETIMES returns a value, SOMETIMES not 1320 */ 1321 AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName); 1322 } 1323 else if (!(ThisNodeBtype & RequiredBtypes)) 1324 { 1325 /* 1326 * Method returns a value, but the type is wrong 1327 */ 1328 AnFormatBtype (StringBuffer, ThisNodeBtype); 1329 AnFormatBtype (StringBuffer2, RequiredBtypes); 1330 1331 1332 /* 1333 * The case where the method does not return any value at all 1334 * was already handled in the namespace cross reference 1335 * -- Only issue an error if the method in fact returns a value, 1336 * but it is of the wrong type 1337 */ 1338 if (ThisNodeBtype != 0) 1339 { 1340 sprintf (MsgBuffer, "Method returns [%s], %s operator requires [%s]", 1341 StringBuffer, OpInfo->Name, StringBuffer2); 1342 1343 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1344 } 1345 } 1346 } 1347 1348 1349 /******************************************************************************* 1350 * 1351 * FUNCTION: AnOperandTypecheckWalkBegin 1352 * 1353 * PARAMETERS: ASL_WALK_CALLBACK 1354 * 1355 * RETURN: Status 1356 * 1357 * DESCRIPTION: Descending callback for the analysis walk. Check methods for : 1358 * 1) Initialized local variables 1359 * 2) Valid arguments 1360 * 3) Return types 1361 * 1362 ******************************************************************************/ 1363 1364 ACPI_STATUS 1365 AnOperandTypecheckWalkBegin ( 1366 ACPI_PARSE_OBJECT *Op, 1367 UINT32 Level, 1368 void *Context) 1369 { 1370 1371 return AE_OK; 1372 } 1373 1374 1375 /******************************************************************************* 1376 * 1377 * FUNCTION: AnOperandTypecheckWalkEnd 1378 * 1379 * PARAMETERS: ASL_WALK_CALLBACK 1380 * 1381 * RETURN: Status 1382 * 1383 * DESCRIPTION: Ascending callback for analysis walk. Complete method 1384 * return analysis. 1385 * 1386 ******************************************************************************/ 1387 1388 ACPI_STATUS 1389 AnOperandTypecheckWalkEnd ( 1390 ACPI_PARSE_OBJECT *Op, 1391 UINT32 Level, 1392 void *Context) 1393 { 1394 const ACPI_OPCODE_INFO *OpInfo; 1395 UINT32 RuntimeArgTypes; 1396 UINT32 RuntimeArgTypes2; 1397 UINT32 RequiredBtypes; 1398 UINT32 ThisNodeBtype; 1399 UINT32 CommonBtypes; 1400 UINT32 OpcodeClass; 1401 ACPI_PARSE_OBJECT *ArgOp; 1402 UINT32 ArgType; 1403 1404 1405 switch (Op->Asl.AmlOpcode) 1406 { 1407 case AML_RAW_DATA_BYTE: 1408 case AML_RAW_DATA_WORD: 1409 case AML_RAW_DATA_DWORD: 1410 case AML_RAW_DATA_QWORD: 1411 case AML_RAW_DATA_BUFFER: 1412 case AML_RAW_DATA_CHAIN: 1413 case AML_PACKAGE_LENGTH: 1414 case AML_UNASSIGNED_OPCODE: 1415 case AML_DEFAULT_ARG_OP: 1416 1417 /* Ignore the internal (compiler-only) AML opcodes */ 1418 1419 return (AE_OK); 1420 1421 default: 1422 break; 1423 } 1424 1425 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1426 if (!OpInfo) 1427 { 1428 return (AE_OK); 1429 } 1430 1431 ArgOp = Op->Asl.Child; 1432 RuntimeArgTypes = OpInfo->RuntimeArgs; 1433 OpcodeClass = OpInfo->Class; 1434 1435 1436 /* 1437 * Special case for control opcodes IF/RETURN/WHILE since they 1438 * have no runtime arg list (at this time) 1439 */ 1440 switch (Op->Asl.AmlOpcode) 1441 { 1442 case AML_IF_OP: 1443 case AML_WHILE_OP: 1444 case AML_RETURN_OP: 1445 1446 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1447 { 1448 /* The lone arg is a method call, check it */ 1449 1450 RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 1451 if (Op->Asl.AmlOpcode == AML_RETURN_OP) 1452 { 1453 RequiredBtypes = 0xFFFFFFFF; 1454 } 1455 1456 ThisNodeBtype = AnGetBtype (ArgOp); 1457 if (ThisNodeBtype == ACPI_UINT32_MAX) 1458 { 1459 return (AE_OK); 1460 } 1461 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype); 1462 } 1463 return (AE_OK); 1464 1465 default: 1466 break; 1467 } 1468 1469 /* Ignore the non-executable opcodes */ 1470 1471 if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 1472 { 1473 return (AE_OK); 1474 } 1475 1476 switch (OpcodeClass) 1477 { 1478 case AML_CLASS_EXECUTE: 1479 case AML_CLASS_CREATE: 1480 case AML_CLASS_CONTROL: 1481 case AML_CLASS_RETURN_VALUE: 1482 1483 /* TBD: Change class or fix typechecking for these */ 1484 1485 if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) || 1486 (Op->Asl.AmlOpcode == AML_PACKAGE_OP) || 1487 (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)) 1488 { 1489 break; 1490 } 1491 1492 /* Reverse the runtime argument list */ 1493 1494 RuntimeArgTypes2 = 0; 1495 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 1496 { 1497 RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 1498 RuntimeArgTypes2 |= ArgType; 1499 INCREMENT_ARG_LIST (RuntimeArgTypes); 1500 } 1501 1502 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 1503 { 1504 RequiredBtypes = AnMapArgTypeToBtype (ArgType); 1505 1506 ThisNodeBtype = AnGetBtype (ArgOp); 1507 if (ThisNodeBtype == ACPI_UINT32_MAX) 1508 { 1509 goto NextArgument; 1510 } 1511 1512 /* Examine the arg based on the required type of the arg */ 1513 1514 switch (ArgType) 1515 { 1516 case ARGI_TARGETREF: 1517 1518 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 1519 { 1520 /* ZERO is the placeholder for "don't store result" */ 1521 1522 ThisNodeBtype = RequiredBtypes; 1523 break; 1524 } 1525 1526 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 1527 { 1528 /* 1529 * This is the case where an original reference to a resource 1530 * descriptor field has been replaced by an (Integer) offset. 1531 * These named fields are supported at compile-time only; 1532 * the names are not passed to the interpreter (via the AML). 1533 */ 1534 if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 1535 (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 1536 { 1537 AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); 1538 } 1539 else 1540 { 1541 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); 1542 } 1543 break; 1544 } 1545 1546 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) || 1547 (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF)) 1548 { 1549 break; 1550 } 1551 1552 ThisNodeBtype = RequiredBtypes; 1553 break; 1554 1555 1556 case ARGI_REFERENCE: /* References */ 1557 case ARGI_INTEGER_REF: 1558 case ARGI_OBJECT_REF: 1559 case ARGI_DEVICE_REF: 1560 1561 switch (ArgOp->Asl.ParseOpcode) 1562 { 1563 case PARSEOP_LOCAL0: 1564 case PARSEOP_LOCAL1: 1565 case PARSEOP_LOCAL2: 1566 case PARSEOP_LOCAL3: 1567 case PARSEOP_LOCAL4: 1568 case PARSEOP_LOCAL5: 1569 case PARSEOP_LOCAL6: 1570 case PARSEOP_LOCAL7: 1571 1572 /* TBD: implement analysis of current value (type) of the local */ 1573 /* For now, just treat any local as a typematch */ 1574 1575 /*ThisNodeBtype = RequiredBtypes;*/ 1576 break; 1577 1578 case PARSEOP_ARG0: 1579 case PARSEOP_ARG1: 1580 case PARSEOP_ARG2: 1581 case PARSEOP_ARG3: 1582 case PARSEOP_ARG4: 1583 case PARSEOP_ARG5: 1584 case PARSEOP_ARG6: 1585 1586 /* Hard to analyze argument types, sow we won't */ 1587 /* For now, just treat any arg as a typematch */ 1588 1589 /* ThisNodeBtype = RequiredBtypes; */ 1590 break; 1591 1592 case PARSEOP_DEBUG: 1593 break; 1594 1595 case PARSEOP_REFOF: 1596 case PARSEOP_INDEX: 1597 default: 1598 break; 1599 1600 } 1601 break; 1602 1603 case ARGI_INTEGER: 1604 default: 1605 break; 1606 } 1607 1608 1609 CommonBtypes = ThisNodeBtype & RequiredBtypes; 1610 1611 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1612 { 1613 /* Check a method call for a valid return value */ 1614 1615 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype); 1616 } 1617 1618 /* 1619 * Now check if the actual type(s) match at least one 1620 * bit to the required type 1621 */ 1622 else if (!CommonBtypes) 1623 { 1624 /* No match -- this is a type mismatch error */ 1625 1626 AnFormatBtype (StringBuffer, ThisNodeBtype); 1627 AnFormatBtype (StringBuffer2, RequiredBtypes); 1628 1629 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 1630 StringBuffer, OpInfo->Name, StringBuffer2); 1631 1632 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1633 } 1634 1635 NextArgument: 1636 ArgOp = ArgOp->Asl.Next; 1637 INCREMENT_ARG_LIST (RuntimeArgTypes2); 1638 } 1639 break; 1640 1641 default: 1642 break; 1643 } 1644 1645 return (AE_OK); 1646 } 1647 1648 1649 /******************************************************************************* 1650 * 1651 * FUNCTION: AnOtherSemanticAnalysisWalkBegin 1652 * 1653 * PARAMETERS: ASL_WALK_CALLBACK 1654 * 1655 * RETURN: Status 1656 * 1657 * DESCRIPTION: Descending callback for the analysis walk. Check methods for : 1658 * 1) Initialized local variables 1659 * 2) Valid arguments 1660 * 3) Return types 1661 * 1662 ******************************************************************************/ 1663 1664 ACPI_STATUS 1665 AnOtherSemanticAnalysisWalkBegin ( 1666 ACPI_PARSE_OBJECT *Op, 1667 UINT32 Level, 1668 void *Context) 1669 { 1670 1671 return AE_OK; 1672 } 1673 1674 1675 /******************************************************************************* 1676 * 1677 * FUNCTION: AnOtherSemanticAnalysisWalkEnd 1678 * 1679 * PARAMETERS: ASL_WALK_CALLBACK 1680 * 1681 * RETURN: Status 1682 * 1683 * DESCRIPTION: Ascending callback for analysis walk. Complete method 1684 * return analysis. 1685 * 1686 ******************************************************************************/ 1687 1688 ACPI_STATUS 1689 AnOtherSemanticAnalysisWalkEnd ( 1690 ACPI_PARSE_OBJECT *Op, 1691 UINT32 Level, 1692 void *Context) 1693 { 1694 1695 return AE_OK; 1696 1697 } 1698