1 
2 /******************************************************************************
3  *
4  * Module Name: aslanalyze.c - check for semantic errors
5  *              $Revision: 1.96 $
6  *
7  *****************************************************************************/
8 
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2005, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
120 #include "aslcompiler.y.h"
121 #include <contrib/dev/acpica/acparser.h>
122 #include <contrib/dev/acpica/amlcode.h>
123 
124 #include <ctype.h>
125 
126 #define _COMPONENT          ACPI_COMPILER
127         ACPI_MODULE_NAME    ("aslanalyze")
128 
129 /* Local prototypes */
130 
131 static UINT32
132 AnMapArgTypeToBtype (
133     UINT32                  ArgType);
134 
135 static UINT32
136 AnMapEtypeToBtype (
137     UINT32                  Etype);
138 
139 static void
140 AnFormatBtype (
141     char                    *Buffer,
142     UINT32                  Btype);
143 
144 static UINT32
145 AnGetBtype (
146     ACPI_PARSE_OBJECT       *Op);
147 
148 static UINT32
149 AnCheckForReservedName (
150     ACPI_PARSE_OBJECT       *Op,
151     char                    *Name);
152 
153 static void
154 AnCheckForReservedMethod (
155     ACPI_PARSE_OBJECT       *Op,
156     ASL_METHOD_INFO         *MethodInfo);
157 
158 static UINT32
159 AnMapObjTypeToBtype (
160     ACPI_PARSE_OBJECT       *Op);
161 
162 static BOOLEAN
163 AnLastStatementIsReturn (
164     ACPI_PARSE_OBJECT       *Op);
165 
166 static void
167 AnCheckMethodReturnValue (
168     ACPI_PARSE_OBJECT       *Op,
169     const ACPI_OPCODE_INFO  *OpInfo,
170     ACPI_PARSE_OBJECT       *ArgOp,
171     UINT32                  RequiredBtypes,
172     UINT32                  ThisNodeBtype);
173 
174 
175 /*******************************************************************************
176  *
177  * FUNCTION:    AnMapArgTypeToBtype
178  *
179  * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
180  *                             from the opcode info table
181  *
182  * RETURN:      The corresponding Bit-encoded types
183  *
184  * DESCRIPTION: Convert an encoded ARGI required argument type code into a
185  *              bitfield type code.  Implements the implicit source conversion
186  *              rules.
187  *
188  ******************************************************************************/
189 
190 static UINT32
191 AnMapArgTypeToBtype (
192     UINT32                  ArgType)
193 {
194 
195     switch (ArgType)
196     {
197 
198     /* Simple types */
199 
200     case ARGI_ANYTYPE:
201         return (ACPI_BTYPE_OBJECTS_AND_REFS);
202 
203     case ARGI_PACKAGE:
204         return (ACPI_BTYPE_PACKAGE);
205 
206     case ARGI_EVENT:
207         return (ACPI_BTYPE_EVENT);
208 
209     case ARGI_MUTEX:
210         return (ACPI_BTYPE_MUTEX);
211 
212     case ARGI_DDBHANDLE:
213         return (ACPI_BTYPE_DDB_HANDLE);
214 
215     /* Interchangeable types */
216     /*
217      * Source conversion rules:
218      * Integer, String, and Buffer are all interchangeable
219      */
220     case ARGI_INTEGER:
221     case ARGI_STRING:
222     case ARGI_BUFFER:
223     case ARGI_BUFFER_OR_STRING:
224     case ARGI_COMPUTEDATA:
225         return (ACPI_BTYPE_COMPUTE_DATA);
226 
227     /* References */
228 
229     case ARGI_INTEGER_REF:
230         return (ACPI_BTYPE_INTEGER);
231 
232     case ARGI_OBJECT_REF:
233         return (ACPI_BTYPE_ALL_OBJECTS);
234 
235     case ARGI_DEVICE_REF:
236         return (ACPI_BTYPE_DEVICE_OBJECTS);
237 
238     case ARGI_REFERENCE:
239         return (ACPI_BTYPE_REFERENCE);
240 
241     case ARGI_TARGETREF:
242     case ARGI_FIXED_TARGET:
243     case ARGI_SIMPLE_TARGET:
244         return (ACPI_BTYPE_OBJECTS_AND_REFS);
245 
246     /* Complex types */
247 
248     case ARGI_DATAOBJECT:
249 
250         /*
251          * Buffer, string, package or reference to a Op -
252          * Used only by SizeOf operator
253          */
254         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
255             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
256 
257     case ARGI_COMPLEXOBJ:
258 
259         /* Buffer, String, or package */
260 
261         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
262 
263     case ARGI_REF_OR_STRING:
264         return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
265 
266     case ARGI_REGION_OR_FIELD:
267         return (ACPI_BTYPE_REGION | ACPI_BTYPE_FIELD_UNIT);
268 
269     case ARGI_DATAREFOBJ:
270         return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
271             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
272 
273     default:
274         break;
275     }
276 
277     return (ACPI_BTYPE_OBJECTS_AND_REFS);
278 }
279 
280 
281 /*******************************************************************************
282  *
283  * FUNCTION:    AnMapEtypeToBtype
284  *
285  * PARAMETERS:  Etype           - Encoded ACPI Type
286  *
287  * RETURN:      Btype corresponding to the Etype
288  *
289  * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
290  *              operand conversion rules.  In other words, returns the type(s)
291  *              this Etype is implicitly converted to during interpretation.
292  *
293  ******************************************************************************/
294 
295 static UINT32
296 AnMapEtypeToBtype (
297     UINT32                  Etype)
298 {
299 
300 
301     if (Etype == ACPI_TYPE_ANY)
302     {
303         return ACPI_BTYPE_OBJECTS_AND_REFS;
304     }
305 
306     /* Try the standard ACPI data types */
307 
308     if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
309     {
310         /*
311          * This switch statement implements the allowed operand conversion
312          * rules as per the "ASL Data Types" section of the ACPI
313          * specification.
314          */
315         switch (Etype)
316         {
317         case ACPI_TYPE_INTEGER:
318             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
319 
320         case ACPI_TYPE_STRING:
321         case ACPI_TYPE_BUFFER:
322             return (ACPI_BTYPE_COMPUTE_DATA);
323 
324         case ACPI_TYPE_PACKAGE:
325             return (ACPI_BTYPE_PACKAGE);
326 
327         case ACPI_TYPE_FIELD_UNIT:
328             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
329 
330         case ACPI_TYPE_BUFFER_FIELD:
331             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
332 
333         case ACPI_TYPE_DDB_HANDLE:
334             return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
335 
336         case ACPI_BTYPE_DEBUG_OBJECT:
337 
338             /* Cannot be used as a source operand */
339 
340             return (0);
341 
342         default:
343             return (1 << (Etype - 1));
344         }
345     }
346 
347     /* Try the internal data types */
348 
349     switch (Etype)
350     {
351     case ACPI_TYPE_LOCAL_REGION_FIELD:
352     case ACPI_TYPE_LOCAL_BANK_FIELD:
353     case ACPI_TYPE_LOCAL_INDEX_FIELD:
354 
355         /* Named fields can be either Integer/Buffer/String */
356 
357         return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
358 
359     case ACPI_TYPE_LOCAL_ALIAS:
360 
361         return (ACPI_BTYPE_INTEGER);
362 
363 
364     case ACPI_TYPE_LOCAL_RESOURCE:
365     case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
366 
367         return (ACPI_BTYPE_REFERENCE);
368 
369     default:
370         printf ("Unhandled encoded type: %X\n", Etype);
371         return (0);
372     }
373 }
374 
375 
376 /*******************************************************************************
377  *
378  * FUNCTION:    AnFormatBtype
379  *
380  * PARAMETERS:  Btype               - Bitfield of ACPI types
381  *              Buffer              - Where to put the ascii string
382  *
383  * RETURN:      None.
384  *
385  * DESCRIPTION: Convert a Btype to a string of ACPI types
386  *
387  ******************************************************************************/
388 
389 static void
390 AnFormatBtype (
391     char                    *Buffer,
392     UINT32                  Btype)
393 {
394     UINT32                  Type;
395     BOOLEAN                 First = TRUE;
396 
397 
398     *Buffer = 0;
399 
400     if (Btype == 0)
401     {
402         strcat (Buffer, "NoReturnValue");
403         return;
404     }
405 
406     for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
407     {
408         if (Btype & 0x00000001)
409         {
410             if (!First)
411             {
412                 strcat (Buffer, "|");
413             }
414             First = FALSE;
415             strcat (Buffer, AcpiUtGetTypeName (Type));
416         }
417         Btype >>= 1;
418     }
419 
420     if (Btype & 0x00000001)
421     {
422         if (!First)
423         {
424             strcat (Buffer, "|");
425         }
426         First = FALSE;
427         strcat (Buffer, "Reference");
428     }
429 
430     Btype >>= 1;
431     if (Btype & 0x00000001)
432     {
433         if (!First)
434         {
435             strcat (Buffer, "|");
436         }
437         First = FALSE;
438         strcat (Buffer, "Resource");
439     }
440 }
441 
442 
443 /*******************************************************************************
444  *
445  * FUNCTION:    AnGetBtype
446  *
447  * PARAMETERS:  Op          - Parse node whose type will be returned.
448  *
449  * RETURN:      The Btype associated with the Op.
450  *
451  * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
452  *              Handles the case where the node is a name or method call and
453  *              the actual type must be obtained from the namespace node.
454  *
455  ******************************************************************************/
456 
457 static UINT32
458 AnGetBtype (
459     ACPI_PARSE_OBJECT       *Op)
460 {
461     ACPI_NAMESPACE_NODE     *Node;
462     ACPI_PARSE_OBJECT       *ReferencedNode;
463     UINT32                  ThisNodeBtype = 0;
464 
465 
466     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||
467         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
468         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
469     {
470         Node = Op->Asl.Node;
471         if (!Node)
472         {
473             DbgPrint (ASL_DEBUG_OUTPUT,
474                 "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n",
475                 Op->Asl.ParseOpName, Op->Asl.LineNumber,
476                 Op->Asl.ExternalName);
477             return ACPI_UINT32_MAX;
478         }
479 
480         ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
481         if (!ThisNodeBtype)
482         {
483             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, NULL);
484         }
485 
486         /*
487          * Since it was a named reference, enable the
488          * reference bit also
489          */
490         ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
491 
492         if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
493         {
494             ReferencedNode = Node->Op;
495             if (!ReferencedNode)
496             {
497                printf ("No back ptr to Op: type %X\n", Node->Type);
498                return ACPI_UINT32_MAX;
499             }
500 
501             if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
502             {
503                 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
504             }
505             else
506             {
507                 return (ACPI_UINT32_MAX -1);
508             }
509         }
510     }
511     else
512     {
513         ThisNodeBtype = Op->Asl.AcpiBtype;
514     }
515 
516     return (ThisNodeBtype);
517 }
518 
519 
520 /*******************************************************************************
521  *
522  * FUNCTION:    AnCheckForReservedName
523  *
524  * PARAMETERS:  Op              - A parse node
525  *              Name            - NameSeg to check
526  *
527  * RETURN:      None
528  *
529  * DESCRIPTION: Check a NameSeg against the reserved list.
530  *
531  ******************************************************************************/
532 
533 static UINT32
534 AnCheckForReservedName (
535     ACPI_PARSE_OBJECT       *Op,
536     char                    *Name)
537 {
538     UINT32                  i;
539 
540 
541     if (Name[0] == 0)
542     {
543         AcpiOsPrintf ("Found a null name, external = %s\n",
544             Op->Asl.ExternalName);
545     }
546 
547     /* All reserved names are prefixed with a single underscore */
548 
549     if (Name[0] != '_')
550     {
551         return (ACPI_NOT_RESERVED_NAME);
552     }
553 
554     /* Check for a standard reserved method name */
555 
556     for (i = 0; ReservedMethods[i].Name; i++)
557     {
558         if (!ACPI_STRNCMP (Name, ReservedMethods[i].Name, ACPI_NAME_SIZE))
559         {
560             if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
561             {
562                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
563                     Op->Asl.ExternalName);
564                 return (ACPI_PREDEFINED_NAME);
565             }
566             else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
567             {
568                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
569                     Op->Asl.ExternalName);
570                 return (ACPI_PREDEFINED_NAME);
571             }
572 
573             /* Return index into reserved array */
574 
575             return i;
576         }
577     }
578 
579     /*
580      * Now check for the "special" reserved names --
581      * GPE:  _Lxx
582      * GPE:  _Exx
583      * EC:   _Qxx
584      */
585     if ((Name[1] == 'L') ||
586         (Name[1] == 'E') ||
587         (Name[1] == 'Q'))
588     {
589         /* The next two characters must be hex digits */
590 
591         if ((isxdigit (Name[2])) &&
592             (isxdigit (Name[3])))
593         {
594             return (ACPI_EVENT_RESERVED_NAME);
595         }
596     }
597 
598 
599     /* Check for the names reserved for the compiler itself: _T_x */
600 
601     else if ((Op->Asl.ExternalName[1] == 'T') &&
602              (Op->Asl.ExternalName[2] == '_'))
603     {
604         /* Ignore if actually emitted by the compiler */
605 
606         if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
607         {
608             return (ACPI_NOT_RESERVED_NAME);
609         }
610 
611         AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
612         return (ACPI_COMPILER_RESERVED_NAME);
613     }
614 
615     /*
616      * The name didn't match any of the known reserved names.  Flag it as a
617      * warning, since the entire namespace starting with an underscore is
618      * reserved by the ACPI spec.
619      */
620     AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
621         Op->Asl.ExternalName);
622 
623     return (ACPI_NOT_RESERVED_NAME);
624 }
625 
626 
627 /*******************************************************************************
628  *
629  * FUNCTION:    AnCheckForReservedMethod
630  *
631  * PARAMETERS:  Op              - A parse node of type "METHOD".
632  *              MethodInfo      - Saved info about this method
633  *
634  * RETURN:      None
635  *
636  * DESCRIPTION: If method is a reserved name, check that the number of arguments
637  *              and the return type (returns a value or not) is correct.
638  *
639  ******************************************************************************/
640 
641 static void
642 AnCheckForReservedMethod (
643     ACPI_PARSE_OBJECT       *Op,
644     ASL_METHOD_INFO         *MethodInfo)
645 {
646     UINT32                  Index;
647 
648 
649     /* Check for a match against the reserved name list */
650 
651     Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
652 
653     switch (Index)
654     {
655     case ACPI_NOT_RESERVED_NAME:
656     case ACPI_PREDEFINED_NAME:
657     case ACPI_COMPILER_RESERVED_NAME:
658 
659         /* Just return, nothing to do */
660         break;
661 
662 
663     case ACPI_EVENT_RESERVED_NAME:
664 
665         Gbl_ReservedMethods++;
666 
667         /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
668 
669         if (MethodInfo->NumArguments != 0)
670         {
671             sprintf (MsgBuffer, " %s requires %d",
672                         Op->Asl.ExternalName, 0);
673 
674             AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
675         }
676         break;
677 
678 
679     default:
680 
681         Gbl_ReservedMethods++;
682 
683         /* Matched a reserved method name */
684 
685         if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments)
686         {
687             sprintf (MsgBuffer, " %s requires %d",
688                         ReservedMethods[Index].Name,
689                         ReservedMethods[Index].NumArguments);
690 
691             if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments)
692             {
693                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
694                     MsgBuffer);
695             }
696             else
697             {
698                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
699                     MsgBuffer);
700             }
701         }
702 
703         if (MethodInfo->NumReturnNoValue &&
704             ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
705         {
706             sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
707 
708             AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
709         }
710         break;
711     }
712 }
713 
714 
715 /*******************************************************************************
716  *
717  * FUNCTION:    AnMapObjTypeToBtype
718  *
719  * PARAMETERS:  Op              - A parse node
720  *
721  * RETURN:      A Btype
722  *
723  * DESCRIPTION: Map object to the associated "Btype"
724  *
725  ******************************************************************************/
726 
727 static UINT32
728 AnMapObjTypeToBtype (
729     ACPI_PARSE_OBJECT       *Op)
730 {
731 
732     switch (Op->Asl.ParseOpcode)
733     {
734     case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
735         return (ACPI_BTYPE_BUFFER_FIELD);
736 
737     case PARSEOP_OBJECTTYPE_BUF:        /* "BuffObj" */
738         return (ACPI_BTYPE_BUFFER);
739 
740     case PARSEOP_OBJECTTYPE_DDB:        /* "DDBHandleObj" */
741         return (ACPI_BTYPE_DDB_HANDLE);
742 
743     case PARSEOP_OBJECTTYPE_DEV:        /* "DeviceObj" */
744         return (ACPI_BTYPE_DEVICE);
745 
746     case PARSEOP_OBJECTTYPE_EVT:        /* "EventObj" */
747         return (ACPI_BTYPE_EVENT);
748 
749     case PARSEOP_OBJECTTYPE_FLD:        /* "FieldUnitObj" */
750         return (ACPI_BTYPE_FIELD_UNIT);
751 
752     case PARSEOP_OBJECTTYPE_INT:        /* "IntObj" */
753         return (ACPI_BTYPE_INTEGER);
754 
755     case PARSEOP_OBJECTTYPE_MTH:        /* "MethodObj" */
756         return (ACPI_BTYPE_METHOD);
757 
758     case PARSEOP_OBJECTTYPE_MTX:        /* "MutexObj" */
759         return (ACPI_BTYPE_MUTEX);
760 
761     case PARSEOP_OBJECTTYPE_OPR:        /* "OpRegionObj" */
762         return (ACPI_BTYPE_REGION);
763 
764     case PARSEOP_OBJECTTYPE_PKG:        /* "PkgObj" */
765         return (ACPI_BTYPE_PACKAGE);
766 
767     case PARSEOP_OBJECTTYPE_POW:        /* "PowerResObj" */
768         return (ACPI_BTYPE_POWER);
769 
770     case PARSEOP_OBJECTTYPE_STR:        /* "StrObj" */
771         return (ACPI_BTYPE_STRING);
772 
773     case PARSEOP_OBJECTTYPE_THZ:        /* "ThermalZoneObj" */
774         return (ACPI_BTYPE_THERMAL);
775 
776     case PARSEOP_OBJECTTYPE_UNK:        /* "UnknownObj" */
777         return (ACPI_BTYPE_OBJECTS_AND_REFS);
778 
779     default:
780         return (0);
781     }
782 }
783 
784 
785 /*******************************************************************************
786  *
787  * FUNCTION:    AnMethodAnalysisWalkBegin
788  *
789  * PARAMETERS:  ASL_WALK_CALLBACK
790  *
791  * RETURN:      Status
792  *
793  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
794  *              1) Initialized local variables
795  *              2) Valid arguments
796  *              3) Return types
797  *
798  ******************************************************************************/
799 
800 ACPI_STATUS
801 AnMethodAnalysisWalkBegin (
802     ACPI_PARSE_OBJECT       *Op,
803     UINT32                  Level,
804     void                    *Context)
805 {
806     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
807     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
808     ACPI_PARSE_OBJECT       *Next;
809     UINT32                  RegisterNumber;
810     UINT32                  i;
811     char                    LocalName[] = "Local0";
812     char                    ArgName[] = "Arg0";
813     ACPI_PARSE_OBJECT       *ArgNode;
814     ACPI_PARSE_OBJECT       *NextType;
815     ACPI_PARSE_OBJECT       *NextParamType;
816     UINT8                   ActualArgs = 0;
817 
818 
819     ACPI_FUNCTION_NAME ("AnMethodAnalysisWalkBegin");
820 
821 
822     switch (Op->Asl.ParseOpcode)
823     {
824     case PARSEOP_METHOD:
825 
826         TotalMethods++;
827 
828         /* Create and init method info */
829 
830         MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
831         MethodInfo->Next = WalkInfo->MethodStack;
832         MethodInfo->Op = Op;
833 
834         WalkInfo->MethodStack = MethodInfo;
835 
836         /* Get the name node, ignored here */
837 
838         Next = Op->Asl.Child;
839 
840         /* Get the NumArguments node */
841 
842         Next = Next->Asl.Next;
843         MethodInfo->NumArguments = (UINT8)
844             (((UINT8) Next->Asl.Value.Integer) & 0x07);
845 
846         /* Get the SerializeRule and SyncLevel nodes, ignored here */
847 
848         Next = Next->Asl.Next;
849         Next = Next->Asl.Next;
850         ArgNode = Next;
851 
852         /* Get the ReturnType node */
853 
854         Next = Next->Asl.Next;
855 
856         NextType = Next->Asl.Child;
857         while (NextType)
858         {
859             /* Get and map each of the ReturnTypes */
860 
861             MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
862             NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
863             NextType = NextType->Asl.Next;
864         }
865 
866         /* Get the ParameterType node */
867 
868         Next = Next->Asl.Next;
869 
870         NextType = Next->Asl.Child;
871         while (NextType)
872         {
873             if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
874             {
875                 NextParamType = NextType->Asl.Child;
876                 while (NextParamType)
877                 {
878                     MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
879                     NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
880                     NextParamType = NextParamType->Asl.Next;
881                 }
882             }
883             else
884             {
885                 MethodInfo->ValidArgTypes[ActualArgs] =
886                     AnMapObjTypeToBtype (NextType);
887                 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
888             }
889 
890             ActualArgs++;
891             NextType = NextType->Asl.Next;
892         }
893 
894         if ((MethodInfo->NumArguments) &&
895             (MethodInfo->NumArguments != ActualArgs))
896         {
897             /* error: Param list did not match number of args */
898         }
899 
900         /* Allow numarguments == 0 for Function() */
901 
902         if ((!MethodInfo->NumArguments) && (ActualArgs))
903         {
904             MethodInfo->NumArguments = ActualArgs;
905             ArgNode->Asl.Value.Integer |= ActualArgs;
906         }
907 
908         /*
909          * Actual arguments are initialized at method entry.
910          * All other ArgX "registers" can be used as locals, so we
911          * track their initialization.
912          */
913         for (i = 0; i < MethodInfo->NumArguments; i++)
914         {
915             MethodInfo->ArgInitialized[i] = TRUE;
916         }
917         break;
918 
919 
920     case PARSEOP_METHODCALL:
921 
922         if (MethodInfo &&
923            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
924         {
925             AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
926         }
927         break;
928 
929 
930     case PARSEOP_LOCAL0:
931     case PARSEOP_LOCAL1:
932     case PARSEOP_LOCAL2:
933     case PARSEOP_LOCAL3:
934     case PARSEOP_LOCAL4:
935     case PARSEOP_LOCAL5:
936     case PARSEOP_LOCAL6:
937     case PARSEOP_LOCAL7:
938 
939         if (!MethodInfo)
940         {
941             /*
942              * Probably was an error in the method declaration,
943              * no additional error here
944              */
945             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
946             return (AE_ERROR);
947         }
948 
949         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
950 
951         /*
952          * If the local is being used as a target, mark the local
953          * initialized
954          */
955         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
956         {
957             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
958         }
959 
960         /*
961          * Otherwise, this is a reference, check if the local
962          * has been previously initialized.
963          *
964          * The only operator that accepts an uninitialized value is ObjectType()
965          */
966         else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
967                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
968         {
969             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
970             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
971         }
972         break;
973 
974 
975     case PARSEOP_ARG0:
976     case PARSEOP_ARG1:
977     case PARSEOP_ARG2:
978     case PARSEOP_ARG3:
979     case PARSEOP_ARG4:
980     case PARSEOP_ARG5:
981     case PARSEOP_ARG6:
982 
983         if (!MethodInfo)
984         {
985             /*
986              * Probably was an error in the method declaration,
987              * no additional error here
988              */
989             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
990             return (AE_ERROR);
991         }
992 
993         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
994         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
995 
996         /*
997          * If the Arg is being used as a target, mark the local
998          * initialized
999          */
1000         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
1001         {
1002             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
1003         }
1004 
1005         /*
1006          * Otherwise, this is a reference, check if the Arg
1007          * has been previously initialized.
1008          *
1009          * The only operator that accepts an uninitialized value is ObjectType()
1010          */
1011         else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
1012                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
1013         {
1014             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
1015         }
1016 
1017         /* Flag this arg if it is not a "real" argument to the method */
1018 
1019         if (RegisterNumber >= MethodInfo->NumArguments)
1020         {
1021             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
1022         }
1023         break;
1024 
1025 
1026     case PARSEOP_RETURN:
1027 
1028         if (!MethodInfo)
1029         {
1030             /*
1031              * Probably was an error in the method declaration,
1032              * no additional error here
1033              */
1034             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
1035             return (AE_ERROR);
1036         }
1037 
1038         /* Child indicates a return value */
1039 
1040         if ((Op->Asl.Child) &&
1041             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1042         {
1043             MethodInfo->NumReturnWithValue++;
1044         }
1045         else
1046         {
1047             MethodInfo->NumReturnNoValue++;
1048         }
1049         break;
1050 
1051 
1052     case PARSEOP_BREAK:
1053     case PARSEOP_CONTINUE:
1054 
1055         Next = Op->Asl.Parent;
1056         while (Next)
1057         {
1058             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
1059             {
1060                 break;
1061             }
1062             Next = Next->Asl.Parent;
1063         }
1064 
1065         if (!Next)
1066         {
1067             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
1068         }
1069         break;
1070 
1071 
1072     case PARSEOP_STALL:
1073 
1074         /* We can range check if the argument is an integer */
1075 
1076         if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1077             (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
1078         {
1079             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
1080         }
1081         break;
1082 
1083 
1084     case PARSEOP_DEVICE:
1085     case PARSEOP_EVENT:
1086     case PARSEOP_MUTEX:
1087     case PARSEOP_OPERATIONREGION:
1088     case PARSEOP_POWERRESOURCE:
1089     case PARSEOP_PROCESSOR:
1090     case PARSEOP_THERMALZONE:
1091 
1092         /*
1093          * The first operand is a name to be created in the namespace.
1094          * Check against the reserved list.
1095          */
1096         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1097         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1098         {
1099             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
1100         }
1101         break;
1102 
1103 
1104     case PARSEOP_NAME:
1105 
1106         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1107         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1108         {
1109             if (ReservedMethods[i].NumArguments > 0)
1110             {
1111                 /*
1112                  * This reserved name must be a control method because
1113                  * it must have arguments
1114                  */
1115                 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
1116                     "with arguments");
1117             }
1118 
1119             /* Typechecking for _HID */
1120 
1121             else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
1122             {
1123                 /* Examine the second operand to typecheck it */
1124 
1125                 Next = Op->Asl.Child->Asl.Next;
1126 
1127                 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
1128                     (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
1129                 {
1130                     /* _HID must be a string or an integer */
1131 
1132                     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next,
1133                         "String or Integer");
1134                 }
1135 
1136                 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
1137                 {
1138                     /*
1139                      * _HID is a string, all characters must be alphanumeric.
1140                      * One of the things we want to catch here is the use of
1141                      * a leading asterisk in the string.
1142                      */
1143                     for (i = 0; Next->Asl.Value.String[i]; i++)
1144                     {
1145                         if (!isalnum (Next->Asl.Value.String[i]))
1146                         {
1147                             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
1148                                 Next, Next->Asl.Value.String);
1149                             break;
1150                         }
1151                     }
1152                 }
1153             }
1154         }
1155 
1156         break;
1157 
1158 
1159     default:
1160         break;
1161     }
1162 
1163     return AE_OK;
1164 }
1165 
1166 
1167 /*******************************************************************************
1168  *
1169  * FUNCTION:    AnLastStatementIsReturn
1170  *
1171  * PARAMETERS:  Op            - A method parse node
1172  *
1173  * RETURN:      TRUE if last statement is an ASL RETURN.  False otherwise
1174  *
1175  * DESCRIPTION: Walk down the list of top level statements within a method
1176  *              to find the last one.  Check if that last statement is in
1177  *              fact a RETURN statement.
1178  *
1179  ******************************************************************************/
1180 
1181 static BOOLEAN
1182 AnLastStatementIsReturn (
1183     ACPI_PARSE_OBJECT       *Op)
1184 {
1185     ACPI_PARSE_OBJECT       *Next;
1186 
1187 
1188     /*
1189      * Check if last statement is a return
1190      */
1191     Next = ASL_GET_CHILD_NODE (Op);
1192     while (Next)
1193     {
1194         if ((!Next->Asl.Next) &&
1195             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1196         {
1197             return TRUE;
1198         }
1199 
1200         Next = ASL_GET_PEER_NODE (Next);
1201     }
1202 
1203     return FALSE;
1204 }
1205 
1206 
1207 /*******************************************************************************
1208  *
1209  * FUNCTION:    AnMethodAnalysisWalkEnd
1210  *
1211  * PARAMETERS:  ASL_WALK_CALLBACK
1212  *
1213  * RETURN:      Status
1214  *
1215  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1216  *              return analysis.
1217  *
1218  ******************************************************************************/
1219 
1220 ACPI_STATUS
1221 AnMethodAnalysisWalkEnd (
1222     ACPI_PARSE_OBJECT       *Op,
1223     UINT32                  Level,
1224     void                    *Context)
1225 {
1226     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1227     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1228 
1229 
1230     switch (Op->Asl.ParseOpcode)
1231     {
1232     case PARSEOP_METHOD:
1233     case PARSEOP_RETURN:
1234         if (!MethodInfo)
1235         {
1236             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1237             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
1238                 "No method info for this method");
1239             CmCleanupAndExit ();
1240             return (AE_AML_INTERNAL);
1241         }
1242         break;
1243 
1244     default:
1245         break;
1246     }
1247 
1248     switch (Op->Asl.ParseOpcode)
1249     {
1250     case PARSEOP_METHOD:
1251 
1252         WalkInfo->MethodStack = MethodInfo->Next;
1253 
1254         /*
1255          * Check if there is no return statement at the end of the
1256          * method AND we can actually get there -- i.e., the execution
1257          * of the method can possibly terminate without a return statement.
1258          */
1259         if ((!AnLastStatementIsReturn (Op)) &&
1260             (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1261         {
1262             /*
1263              * No return statement, and execution can possibly exit
1264              * via this path.  This is equivalent to Return ()
1265              */
1266             MethodInfo->NumReturnNoValue++;
1267         }
1268 
1269         /*
1270          * Check for case where some return statements have a return value
1271          * and some do not.  Exit without a return statement is a return with
1272          * no value
1273          */
1274         if (MethodInfo->NumReturnNoValue &&
1275             MethodInfo->NumReturnWithValue)
1276         {
1277             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
1278                 Op->Asl.ExternalName);
1279         }
1280 
1281         /*
1282          * If there are any RETURN() statements with no value, or there is a
1283          * control path that allows the method to exit without a return value,
1284          * we mark the method as a method that does not return a value.  This
1285          * knowledge can be used to check method invocations that expect a
1286          * returned value.
1287          */
1288         if (MethodInfo->NumReturnNoValue)
1289         {
1290             if (MethodInfo->NumReturnWithValue)
1291             {
1292                 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1293             }
1294             else
1295             {
1296                 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1297             }
1298         }
1299 
1300         /*
1301          * Check predefined method names for correct return behavior
1302          * and correct number of arguments
1303          */
1304         AnCheckForReservedMethod (Op, MethodInfo);
1305         ACPI_MEM_FREE (MethodInfo);
1306         break;
1307 
1308 
1309     case PARSEOP_RETURN:
1310 
1311         /*
1312          * The parent block does not "exit" and continue execution -- the
1313          * method is terminated here with the Return() statement.
1314          */
1315         Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1316 
1317         /* Used in the "typing" pass later */
1318 
1319         Op->Asl.ParentMethod = MethodInfo->Op;
1320 
1321         /*
1322          * If there is a peer node after the return statement, then this
1323          * node is unreachable code -- i.e., it won't be executed because of
1324          *  thepreceeding Return() statement.
1325          */
1326         if (Op->Asl.Next)
1327         {
1328             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1329         }
1330         break;
1331 
1332 
1333     case PARSEOP_IF:
1334 
1335         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1336             (Op->Asl.Next) &&
1337             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1338         {
1339             /*
1340              * This IF has a corresponding ELSE.  The IF block has no exit,
1341              * (it contains an unconditional Return)
1342              * mark the ELSE block to remember this fact.
1343              */
1344             Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1345         }
1346         break;
1347 
1348 
1349     case PARSEOP_ELSE:
1350 
1351         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1352             (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1353         {
1354             /*
1355              * This ELSE block has no exit and the corresponding IF block
1356              * has no exit either.  Therefore, the parent node has no exit.
1357              */
1358             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1359         }
1360         break;
1361 
1362 
1363     default:
1364 
1365         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1366             (Op->Asl.Parent))
1367         {
1368             /* If this node has no exit, then the parent has no exit either */
1369 
1370             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1371         }
1372         break;
1373     }
1374 
1375     return AE_OK;
1376 }
1377 
1378 
1379 /*******************************************************************************
1380  *
1381  * FUNCTION:    AnMethodTypingWalkBegin
1382  *
1383  * PARAMETERS:  ASL_WALK_CALLBACK
1384  *
1385  * RETURN:      Status
1386  *
1387  * DESCRIPTION: Descending callback for the typing walk.
1388  *
1389  ******************************************************************************/
1390 
1391 ACPI_STATUS
1392 AnMethodTypingWalkBegin (
1393     ACPI_PARSE_OBJECT       *Op,
1394     UINT32                  Level,
1395     void                    *Context)
1396 {
1397 
1398     return AE_OK;
1399 }
1400 
1401 
1402 /*******************************************************************************
1403  *
1404  * FUNCTION:    AnMethodTypingWalkEnd
1405  *
1406  * PARAMETERS:  ASL_WALK_CALLBACK
1407  *
1408  * RETURN:      Status
1409  *
1410  * DESCRIPTION: Ascending callback for typing walk.  Complete method
1411  *              return analysis.  Check methods for :
1412  *              1) Initialized local variables
1413  *              2) Valid arguments
1414  *              3) Return types
1415  *
1416  ******************************************************************************/
1417 
1418 ACPI_STATUS
1419 AnMethodTypingWalkEnd (
1420     ACPI_PARSE_OBJECT       *Op,
1421     UINT32                  Level,
1422     void                    *Context)
1423 {
1424     UINT32                  ThisNodeBtype;
1425 
1426 
1427     switch (Op->Asl.ParseOpcode)
1428     {
1429     case PARSEOP_METHOD:
1430 
1431         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1432         break;
1433 
1434     case PARSEOP_RETURN:
1435 
1436         if ((Op->Asl.Child) &&
1437             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1438         {
1439             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1440 
1441             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1442                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1443             {
1444                 /*
1445                  * The method is untyped at this time (typically a forward
1446                  *  reference). We must recursively type the method here
1447                  */
1448                 TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
1449                     ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1450                     AnMethodTypingWalkEnd, NULL);
1451 
1452                 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1453             }
1454 
1455             /* Returns a value, get it's type */
1456 
1457             if (Op->Asl.ParentMethod)
1458             {
1459                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1460             }
1461         }
1462         break;
1463 
1464     default:
1465         break;
1466     }
1467 
1468     return AE_OK;
1469 }
1470 
1471 
1472 /*******************************************************************************
1473  *
1474  * FUNCTION:    AnCheckMethodReturnValue
1475  *
1476  * PARAMETERS:  Op                  - Parent
1477  *              OpInfo              - Parent info
1478  *              ArgOp               - Method invocation op
1479  *              RequiredBtypes      - What caller requires
1480  *              ThisNodeBtype       - What this node returns (if anything)
1481  *
1482  * RETURN:      None
1483  *
1484  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1485  *              in fact return a value, 2) check the type of the return value.
1486  *
1487  ******************************************************************************/
1488 
1489 static void
1490 AnCheckMethodReturnValue (
1491     ACPI_PARSE_OBJECT       *Op,
1492     const ACPI_OPCODE_INFO  *OpInfo,
1493     ACPI_PARSE_OBJECT       *ArgOp,
1494     UINT32                  RequiredBtypes,
1495     UINT32                  ThisNodeBtype)
1496 {
1497     ACPI_PARSE_OBJECT       *OwningOp;
1498     ACPI_NAMESPACE_NODE     *Node;
1499 
1500 
1501     Node = ArgOp->Asl.Node;
1502 
1503 
1504     /* Examine the parent op of this method */
1505 
1506     OwningOp = Node->Op;
1507     if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1508     {
1509         /* Method NEVER returns a value */
1510 
1511         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1512     }
1513     else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1514     {
1515         /* Method SOMETIMES returns a value, SOMETIMES not */
1516 
1517         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1518     }
1519     else if (!(ThisNodeBtype & RequiredBtypes))
1520     {
1521         /* Method returns a value, but the type is wrong */
1522 
1523         AnFormatBtype (StringBuffer, ThisNodeBtype);
1524         AnFormatBtype (StringBuffer2, RequiredBtypes);
1525 
1526 
1527         /*
1528          * The case where the method does not return any value at all
1529          * was already handled in the namespace cross reference
1530          * -- Only issue an error if the method in fact returns a value,
1531          * but it is of the wrong type
1532          */
1533         if (ThisNodeBtype != 0)
1534         {
1535             sprintf (MsgBuffer,
1536                 "Method returns [%s], %s operator requires [%s]",
1537                 StringBuffer, OpInfo->Name, StringBuffer2);
1538 
1539             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1540         }
1541     }
1542 }
1543 
1544 
1545 /*******************************************************************************
1546  *
1547  * FUNCTION:    AnOperandTypecheckWalkBegin
1548  *
1549  * PARAMETERS:  ASL_WALK_CALLBACK
1550  *
1551  * RETURN:      Status
1552  *
1553  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for:
1554  *              1) Initialized local variables
1555  *              2) Valid arguments
1556  *              3) Return types
1557  *
1558  ******************************************************************************/
1559 
1560 ACPI_STATUS
1561 AnOperandTypecheckWalkBegin (
1562     ACPI_PARSE_OBJECT       *Op,
1563     UINT32                  Level,
1564     void                    *Context)
1565 {
1566 
1567     return AE_OK;
1568 }
1569 
1570 
1571 /*******************************************************************************
1572  *
1573  * FUNCTION:    AnOperandTypecheckWalkEnd
1574  *
1575  * PARAMETERS:  ASL_WALK_CALLBACK
1576  *
1577  * RETURN:      Status
1578  *
1579  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1580  *              return analysis.
1581  *
1582  ******************************************************************************/
1583 
1584 ACPI_STATUS
1585 AnOperandTypecheckWalkEnd (
1586     ACPI_PARSE_OBJECT       *Op,
1587     UINT32                  Level,
1588     void                    *Context)
1589 {
1590     const ACPI_OPCODE_INFO  *OpInfo;
1591     UINT32                  RuntimeArgTypes;
1592     UINT32                  RuntimeArgTypes2;
1593     UINT32                  RequiredBtypes;
1594     UINT32                  ThisNodeBtype;
1595     UINT32                  CommonBtypes;
1596     UINT32                  OpcodeClass;
1597     ACPI_PARSE_OBJECT       *ArgOp;
1598     UINT32                  ArgType;
1599 
1600 
1601     switch (Op->Asl.AmlOpcode)
1602     {
1603     case AML_RAW_DATA_BYTE:
1604     case AML_RAW_DATA_WORD:
1605     case AML_RAW_DATA_DWORD:
1606     case AML_RAW_DATA_QWORD:
1607     case AML_RAW_DATA_BUFFER:
1608     case AML_RAW_DATA_CHAIN:
1609     case AML_PACKAGE_LENGTH:
1610     case AML_UNASSIGNED_OPCODE:
1611     case AML_DEFAULT_ARG_OP:
1612 
1613         /* Ignore the internal (compiler-only) AML opcodes */
1614 
1615         return (AE_OK);
1616 
1617     default:
1618         break;
1619     }
1620 
1621     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1622     if (!OpInfo)
1623     {
1624         return (AE_OK);
1625     }
1626 
1627     ArgOp           = Op->Asl.Child;
1628     RuntimeArgTypes = OpInfo->RuntimeArgs;
1629     OpcodeClass     = OpInfo->Class;
1630 
1631 
1632     /*
1633      * Special case for control opcodes IF/RETURN/WHILE since they
1634      * have no runtime arg list (at this time)
1635      */
1636     switch (Op->Asl.AmlOpcode)
1637     {
1638     case AML_IF_OP:
1639     case AML_WHILE_OP:
1640     case AML_RETURN_OP:
1641 
1642         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1643         {
1644             if (!ACPI_STRCMP (ArgOp->Asl.ExternalName, "\\_OSI"))
1645             {
1646                 return (AE_OK);
1647             }
1648 
1649             /* The lone arg is a method call, check it */
1650 
1651             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1652             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1653             {
1654                 RequiredBtypes = 0xFFFFFFFF;
1655             }
1656 
1657             ThisNodeBtype = AnGetBtype (ArgOp);
1658             if (ThisNodeBtype == ACPI_UINT32_MAX)
1659             {
1660                 return (AE_OK);
1661             }
1662             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1663                 RequiredBtypes, ThisNodeBtype);
1664         }
1665         return (AE_OK);
1666 
1667     default:
1668         break;
1669     }
1670 
1671     /* Ignore the non-executable opcodes */
1672 
1673     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1674     {
1675         return (AE_OK);
1676     }
1677 
1678     switch (OpcodeClass)
1679     {
1680     case AML_CLASS_EXECUTE:
1681     case AML_CLASS_CREATE:
1682     case AML_CLASS_CONTROL:
1683     case AML_CLASS_RETURN_VALUE:
1684 
1685         /* TBD: Change class or fix typechecking for these */
1686 
1687         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1688             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1689             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1690         {
1691             break;
1692         }
1693 
1694         /* Reverse the runtime argument list */
1695 
1696         RuntimeArgTypes2 = 0;
1697         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1698         {
1699             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1700             RuntimeArgTypes2 |= ArgType;
1701             INCREMENT_ARG_LIST (RuntimeArgTypes);
1702         }
1703 
1704         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1705         {
1706             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1707 
1708             ThisNodeBtype = AnGetBtype (ArgOp);
1709             if (ThisNodeBtype == ACPI_UINT32_MAX)
1710             {
1711                 goto NextArgument;
1712             }
1713 
1714             /* Examine the arg based on the required type of the arg */
1715 
1716             switch (ArgType)
1717             {
1718             case ARGI_TARGETREF:
1719 
1720                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1721                 {
1722                     /* ZERO is the placeholder for "don't store result" */
1723 
1724                     ThisNodeBtype = RequiredBtypes;
1725                     break;
1726                 }
1727 
1728                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1729                 {
1730                     /*
1731                      * This is the case where an original reference to a resource
1732                      * descriptor field has been replaced by an (Integer) offset.
1733                      * These named fields are supported at compile-time only;
1734                      * the names are not passed to the interpreter (via the AML).
1735                      */
1736                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1737                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1738                     {
1739                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1740                     }
1741                     else
1742                     {
1743                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1744                     }
1745                     break;
1746                 }
1747 
1748                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1749                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1750                 {
1751                     break;
1752                 }
1753 
1754                 ThisNodeBtype = RequiredBtypes;
1755                 break;
1756 
1757 
1758             case ARGI_REFERENCE:            /* References */
1759             case ARGI_INTEGER_REF:
1760             case ARGI_OBJECT_REF:
1761             case ARGI_DEVICE_REF:
1762 
1763                 switch (ArgOp->Asl.ParseOpcode)
1764                 {
1765                 case PARSEOP_LOCAL0:
1766                 case PARSEOP_LOCAL1:
1767                 case PARSEOP_LOCAL2:
1768                 case PARSEOP_LOCAL3:
1769                 case PARSEOP_LOCAL4:
1770                 case PARSEOP_LOCAL5:
1771                 case PARSEOP_LOCAL6:
1772                 case PARSEOP_LOCAL7:
1773 
1774                     /* TBD: implement analysis of current value (type) of the local */
1775                     /* For now, just treat any local as a typematch */
1776 
1777                     /*ThisNodeBtype = RequiredBtypes;*/
1778                     break;
1779 
1780                 case PARSEOP_ARG0:
1781                 case PARSEOP_ARG1:
1782                 case PARSEOP_ARG2:
1783                 case PARSEOP_ARG3:
1784                 case PARSEOP_ARG4:
1785                 case PARSEOP_ARG5:
1786                 case PARSEOP_ARG6:
1787 
1788                     /* Hard to analyze argument types, sow we won't */
1789                     /* For now, just treat any arg as a typematch */
1790 
1791                     /* ThisNodeBtype = RequiredBtypes; */
1792                     break;
1793 
1794                 case PARSEOP_DEBUG:
1795                     break;
1796 
1797                 case PARSEOP_REFOF:
1798                 case PARSEOP_INDEX:
1799                 default:
1800                     break;
1801 
1802                 }
1803                 break;
1804 
1805             case ARGI_INTEGER:
1806             default:
1807                 break;
1808             }
1809 
1810 
1811             CommonBtypes = ThisNodeBtype & RequiredBtypes;
1812 
1813             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1814             {
1815                 /* Check a method call for a valid return value */
1816 
1817                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1818                     RequiredBtypes, ThisNodeBtype);
1819             }
1820 
1821             /*
1822              * Now check if the actual type(s) match at least one
1823              * bit to the required type
1824              */
1825             else if (!CommonBtypes)
1826             {
1827                 /* No match -- this is a type mismatch error */
1828 
1829                 AnFormatBtype (StringBuffer, ThisNodeBtype);
1830                 AnFormatBtype (StringBuffer2, RequiredBtypes);
1831 
1832                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1833                             StringBuffer, OpInfo->Name, StringBuffer2);
1834 
1835                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1836             }
1837 
1838         NextArgument:
1839             ArgOp = ArgOp->Asl.Next;
1840             INCREMENT_ARG_LIST (RuntimeArgTypes2);
1841         }
1842         break;
1843 
1844     default:
1845         break;
1846     }
1847 
1848     return (AE_OK);
1849 }
1850 
1851 
1852 /*******************************************************************************
1853  *
1854  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
1855  *
1856  * PARAMETERS:  ASL_WALK_CALLBACK
1857  *
1858  * RETURN:      Status
1859  *
1860  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1861  *              1) Initialized local variables
1862  *              2) Valid arguments
1863  *              3) Return types
1864  *
1865  ******************************************************************************/
1866 
1867 ACPI_STATUS
1868 AnOtherSemanticAnalysisWalkBegin (
1869     ACPI_PARSE_OBJECT       *Op,
1870     UINT32                  Level,
1871     void                    *Context)
1872 {
1873 
1874     return AE_OK;
1875 }
1876 
1877 
1878 /*******************************************************************************
1879  *
1880  * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
1881  *
1882  * PARAMETERS:  ASL_WALK_CALLBACK
1883  *
1884  * RETURN:      Status
1885  *
1886  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1887  *              return analysis.
1888  *
1889  ******************************************************************************/
1890 
1891 ACPI_STATUS
1892 AnOtherSemanticAnalysisWalkEnd (
1893     ACPI_PARSE_OBJECT       *Op,
1894     UINT32                  Level,
1895     void                    *Context)
1896 {
1897 
1898     return AE_OK;
1899 
1900 }
1901 
1902 
1903 #ifdef ACPI_OBSOLETE_FUNCTIONS
1904 /*******************************************************************************
1905  *
1906  * FUNCTION:    AnMapBtypeToEtype
1907  *
1908  * PARAMETERS:  Btype               - Bitfield of ACPI types
1909  *
1910  * RETURN:      The Etype corresponding the the Btype
1911  *
1912  * DESCRIPTION: Convert a bitfield type to an encoded type
1913  *
1914  ******************************************************************************/
1915 
1916 UINT32
1917 AnMapBtypeToEtype (
1918     UINT32              Btype)
1919 {
1920     UINT32              i;
1921     UINT32              Etype;
1922 
1923 
1924     if (Btype == 0)
1925     {
1926         return 0;
1927     }
1928 
1929     Etype = 1;
1930     for (i = 1; i < Btype; i *= 2)
1931     {
1932         Etype++;
1933     }
1934 
1935     return (Etype);
1936 }
1937 #endif
1938 
1939