Home | History | Annotate | Line # | Download | only in executer
exnames.c revision 1.1
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: exnames - interpreter/scanner name load/execute
      5  *
      6  *****************************************************************************/
      7 
      8 /******************************************************************************
      9  *
     10  * 1. Copyright Notice
     11  *
     12  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     13  * All rights reserved.
     14  *
     15  * 2. License
     16  *
     17  * 2.1. This is your license from Intel Corp. under its intellectual property
     18  * rights.  You may have additional license terms from the party that provided
     19  * you this software, covering your right to use that party's intellectual
     20  * property rights.
     21  *
     22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     23  * copy of the source code appearing in this file ("Covered Code") an
     24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     25  * base code distributed originally by Intel ("Original Intel Code") to copy,
     26  * make derivatives, distribute, use and display any portion of the Covered
     27  * Code in any form, with the right to sublicense such rights; and
     28  *
     29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     30  * license (with the right to sublicense), under only those claims of Intel
     31  * patents that are infringed by the Original Intel Code, to make, use, sell,
     32  * offer to sell, and import the Covered Code and derivative works thereof
     33  * solely to the minimum extent necessary to exercise the above copyright
     34  * license, and in no event shall the patent license extend to any additions
     35  * to or modifications of the Original Intel Code.  No other license or right
     36  * is granted directly or by implication, estoppel or otherwise;
     37  *
     38  * The above copyright and patent license is granted only if the following
     39  * conditions are met:
     40  *
     41  * 3. Conditions
     42  *
     43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     44  * Redistribution of source code of any substantial portion of the Covered
     45  * Code or modification with rights to further distribute source must include
     46  * the above Copyright Notice, the above License, this list of Conditions,
     47  * and the following Disclaimer and Export Compliance provision.  In addition,
     48  * Licensee must cause all Covered Code to which Licensee contributes to
     49  * contain a file documenting the changes Licensee made to create that Covered
     50  * Code and the date of any change.  Licensee must include in that file the
     51  * documentation of any changes made by any predecessor Licensee.  Licensee
     52  * must include a prominent statement that the modification is derived,
     53  * directly or indirectly, from Original Intel Code.
     54  *
     55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     56  * Redistribution of source code of any substantial portion of the Covered
     57  * Code or modification without rights to further distribute source must
     58  * include the following Disclaimer and Export Compliance provision in the
     59  * documentation and/or other materials provided with distribution.  In
     60  * addition, Licensee may not authorize further sublicense of source of any
     61  * portion of the Covered Code, and must include terms to the effect that the
     62  * license from Licensee to its licensee is limited to the intellectual
     63  * property embodied in the software Licensee provides to its licensee, and
     64  * not to intellectual property embodied in modifications its licensee may
     65  * make.
     66  *
     67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     68  * substantial portion of the Covered Code or modification must reproduce the
     69  * above Copyright Notice, and the following Disclaimer and Export Compliance
     70  * provision in the documentation and/or other materials provided with the
     71  * distribution.
     72  *
     73  * 3.4. Intel retains all right, title, and interest in and to the Original
     74  * Intel Code.
     75  *
     76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     77  * Intel shall be used in advertising or otherwise to promote the sale, use or
     78  * other dealings in products derived from or relating to the Covered Code
     79  * without prior written authorization from Intel.
     80  *
     81  * 4. Disclaimer and Export Compliance
     82  *
     83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government.  In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************/
    116 
    117 #define __EXNAMES_C__
    118 
    119 #include "acpi.h"
    120 #include "accommon.h"
    121 #include "acinterp.h"
    122 #include "amlcode.h"
    123 
    124 #define _COMPONENT          ACPI_EXECUTER
    125         ACPI_MODULE_NAME    ("exnames")
    126 
    127 /* Local prototypes */
    128 
    129 static char *
    130 AcpiExAllocateNameString (
    131     UINT32                  PrefixCount,
    132     UINT32                  NumNameSegs);
    133 
    134 static ACPI_STATUS
    135 AcpiExNameSegment (
    136     UINT8                   **InAmlAddress,
    137     char                    *NameString);
    138 
    139 
    140 /*******************************************************************************
    141  *
    142  * FUNCTION:    AcpiExAllocateNameString
    143  *
    144  * PARAMETERS:  PrefixCount         - Count of parent levels. Special cases:
    145  *                                    (-1)==root,  0==none
    146  *              NumNameSegs         - count of 4-character name segments
    147  *
    148  * RETURN:      A pointer to the allocated string segment.  This segment must
    149  *              be deleted by the caller.
    150  *
    151  * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
    152  *              string is long enough, and set up prefix if any.
    153  *
    154  ******************************************************************************/
    155 
    156 static char *
    157 AcpiExAllocateNameString (
    158     UINT32                  PrefixCount,
    159     UINT32                  NumNameSegs)
    160 {
    161     char                    *TempPtr;
    162     char                    *NameString;
    163     UINT32                   SizeNeeded;
    164 
    165     ACPI_FUNCTION_TRACE (ExAllocateNameString);
    166 
    167 
    168     /*
    169      * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix.
    170      * Also, one byte for the null terminator.
    171      * This may actually be somewhat longer than needed.
    172      */
    173     if (PrefixCount == ACPI_UINT32_MAX)
    174     {
    175         /* Special case for root */
    176 
    177         SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
    178     }
    179     else
    180     {
    181         SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
    182     }
    183 
    184     /*
    185      * Allocate a buffer for the name.
    186      * This buffer must be deleted by the caller!
    187      */
    188     NameString = ACPI_ALLOCATE (SizeNeeded);
    189     if (!NameString)
    190     {
    191         ACPI_ERROR ((AE_INFO,
    192             "Could not allocate size %u", SizeNeeded));
    193         return_PTR (NULL);
    194     }
    195 
    196     TempPtr = NameString;
    197 
    198     /* Set up Root or Parent prefixes if needed */
    199 
    200     if (PrefixCount == ACPI_UINT32_MAX)
    201     {
    202         *TempPtr++ = AML_ROOT_PREFIX;
    203     }
    204     else
    205     {
    206         while (PrefixCount--)
    207         {
    208             *TempPtr++ = AML_PARENT_PREFIX;
    209         }
    210     }
    211 
    212 
    213     /* Set up Dual or Multi prefixes if needed */
    214 
    215     if (NumNameSegs > 2)
    216     {
    217         /* Set up multi prefixes   */
    218 
    219         *TempPtr++ = AML_MULTI_NAME_PREFIX_OP;
    220         *TempPtr++ = (char) NumNameSegs;
    221     }
    222     else if (2 == NumNameSegs)
    223     {
    224         /* Set up dual prefixes */
    225 
    226         *TempPtr++ = AML_DUAL_NAME_PREFIX;
    227     }
    228 
    229     /*
    230      * Terminate string following prefixes. AcpiExNameSegment() will
    231      * append the segment(s)
    232      */
    233     *TempPtr = 0;
    234 
    235     return_PTR (NameString);
    236 }
    237 
    238 /*******************************************************************************
    239  *
    240  * FUNCTION:    AcpiExNameSegment
    241  *
    242  * PARAMETERS:  InAmlAddress    - Pointer to the name in the AML code
    243  *              NameString      - Where to return the name. The name is appended
    244  *                                to any existing string to form a namepath
    245  *
    246  * RETURN:      Status
    247  *
    248  * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
    249  *
    250  ******************************************************************************/
    251 
    252 static ACPI_STATUS
    253 AcpiExNameSegment (
    254     UINT8                   **InAmlAddress,
    255     char                    *NameString)
    256 {
    257     char                    *AmlAddress = (void *) *InAmlAddress;
    258     ACPI_STATUS             Status = AE_OK;
    259     UINT32                  Index;
    260     char                    CharBuf[5];
    261 
    262 
    263     ACPI_FUNCTION_TRACE (ExNameSegment);
    264 
    265 
    266     /*
    267      * If first character is a digit, then we know that we aren't looking at a
    268      * valid name segment
    269      */
    270     CharBuf[0] = *AmlAddress;
    271 
    272     if ('0' <= CharBuf[0] && CharBuf[0] <= '9')
    273     {
    274         ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0]));
    275         return_ACPI_STATUS (AE_CTRL_PENDING);
    276     }
    277 
    278     ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
    279 
    280     for (Index = 0;
    281         (Index < ACPI_NAME_SIZE) && (AcpiUtValidAcpiChar (*AmlAddress, 0));
    282         Index++)
    283     {
    284         CharBuf[Index] = *AmlAddress++;
    285         ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", CharBuf[Index]));
    286     }
    287 
    288 
    289     /* Valid name segment  */
    290 
    291     if (Index == 4)
    292     {
    293         /* Found 4 valid characters */
    294 
    295         CharBuf[4] = '\0';
    296 
    297         if (NameString)
    298         {
    299             ACPI_STRCAT (NameString, CharBuf);
    300             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
    301                 "Appended to - %s\n", NameString));
    302         }
    303         else
    304         {
    305             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
    306                 "No Name string - %s\n", CharBuf));
    307         }
    308     }
    309     else if (Index == 0)
    310     {
    311         /*
    312          * First character was not a valid name character,
    313          * so we are looking at something other than a name.
    314          */
    315         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    316             "Leading character is not alpha: %02Xh (not a name)\n",
    317             CharBuf[0]));
    318         Status = AE_CTRL_PENDING;
    319     }
    320     else
    321     {
    322         /*
    323          * Segment started with one or more valid characters, but fewer than
    324          * the required 4
    325          */
    326         Status = AE_AML_BAD_NAME;
    327         ACPI_ERROR ((AE_INFO,
    328             "Bad character 0x%02x in name, at %p",
    329             *AmlAddress, AmlAddress));
    330     }
    331 
    332     *InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress);
    333     return_ACPI_STATUS (Status);
    334 }
    335 
    336 
    337 /*******************************************************************************
    338  *
    339  * FUNCTION:    AcpiExGetNameString
    340  *
    341  * PARAMETERS:  DataType            - Object type to be associated with this
    342  *                                    name
    343  *              InAmlAddress        - Pointer to the namestring in the AML code
    344  *              OutNameString       - Where the namestring is returned
    345  *              OutNameLength       - Length of the returned string
    346  *
    347  * RETURN:      Status, namestring and length
    348  *
    349  * DESCRIPTION: Extract a full namepath from the AML byte stream,
    350  *              including any prefixes.
    351  *
    352  ******************************************************************************/
    353 
    354 ACPI_STATUS
    355 AcpiExGetNameString (
    356     ACPI_OBJECT_TYPE        DataType,
    357     UINT8                   *InAmlAddress,
    358     char                    **OutNameString,
    359     UINT32                  *OutNameLength)
    360 {
    361     ACPI_STATUS             Status = AE_OK;
    362     UINT8                   *AmlAddress = InAmlAddress;
    363     char                    *NameString = NULL;
    364     UINT32                  NumSegments;
    365     UINT32                  PrefixCount = 0;
    366     BOOLEAN                 HasPrefix = FALSE;
    367 
    368 
    369     ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress);
    370 
    371 
    372     if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType   ||
    373         ACPI_TYPE_LOCAL_BANK_FIELD == DataType     ||
    374         ACPI_TYPE_LOCAL_INDEX_FIELD == DataType)
    375     {
    376         /* Disallow prefixes for types associated with FieldUnit names */
    377 
    378         NameString = AcpiExAllocateNameString (0, 1);
    379         if (!NameString)
    380         {
    381             Status = AE_NO_MEMORY;
    382         }
    383         else
    384         {
    385             Status = AcpiExNameSegment (&AmlAddress, NameString);
    386         }
    387     }
    388     else
    389     {
    390         /*
    391          * DataType is not a field name.
    392          * Examine first character of name for root or parent prefix operators
    393          */
    394         switch (*AmlAddress)
    395         {
    396         case AML_ROOT_PREFIX:
    397 
    398             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n",
    399                 AmlAddress));
    400 
    401             /*
    402              * Remember that we have a RootPrefix --
    403              * see comment in AcpiExAllocateNameString()
    404              */
    405             AmlAddress++;
    406             PrefixCount = ACPI_UINT32_MAX;
    407             HasPrefix = TRUE;
    408             break;
    409 
    410 
    411         case AML_PARENT_PREFIX:
    412 
    413             /* Increment past possibly multiple parent prefixes */
    414 
    415             do
    416             {
    417                 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n",
    418                     AmlAddress));
    419 
    420                 AmlAddress++;
    421                 PrefixCount++;
    422 
    423             } while (*AmlAddress == AML_PARENT_PREFIX);
    424 
    425             HasPrefix = TRUE;
    426             break;
    427 
    428 
    429         default:
    430 
    431             /* Not a prefix character */
    432 
    433             break;
    434         }
    435 
    436         /* Examine first character of name for name segment prefix operator */
    437 
    438         switch (*AmlAddress)
    439         {
    440         case AML_DUAL_NAME_PREFIX:
    441 
    442             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n",
    443                 AmlAddress));
    444 
    445             AmlAddress++;
    446             NameString = AcpiExAllocateNameString (PrefixCount, 2);
    447             if (!NameString)
    448             {
    449                 Status = AE_NO_MEMORY;
    450                 break;
    451             }
    452 
    453             /* Indicate that we processed a prefix */
    454 
    455             HasPrefix = TRUE;
    456 
    457             Status = AcpiExNameSegment (&AmlAddress, NameString);
    458             if (ACPI_SUCCESS (Status))
    459             {
    460                 Status = AcpiExNameSegment (&AmlAddress, NameString);
    461             }
    462             break;
    463 
    464 
    465         case AML_MULTI_NAME_PREFIX_OP:
    466 
    467             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n",
    468                 AmlAddress));
    469 
    470             /* Fetch count of segments remaining in name path */
    471 
    472             AmlAddress++;
    473             NumSegments = *AmlAddress;
    474 
    475             NameString = AcpiExAllocateNameString (PrefixCount, NumSegments);
    476             if (!NameString)
    477             {
    478                 Status = AE_NO_MEMORY;
    479                 break;
    480             }
    481 
    482             /* Indicate that we processed a prefix */
    483 
    484             AmlAddress++;
    485             HasPrefix = TRUE;
    486 
    487             while (NumSegments &&
    488                     (Status = AcpiExNameSegment (&AmlAddress, NameString)) ==
    489                         AE_OK)
    490             {
    491                 NumSegments--;
    492             }
    493 
    494             break;
    495 
    496 
    497         case 0:
    498 
    499             /* NullName valid as of 8-12-98 ASL/AML Grammar Update */
    500 
    501             if (PrefixCount == ACPI_UINT32_MAX)
    502             {
    503                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    504                     "NameSeg is \"\\\" followed by NULL\n"));
    505             }
    506 
    507             /* Consume the NULL byte */
    508 
    509             AmlAddress++;
    510             NameString = AcpiExAllocateNameString (PrefixCount, 0);
    511             if (!NameString)
    512             {
    513                 Status = AE_NO_MEMORY;
    514                 break;
    515             }
    516 
    517             break;
    518 
    519 
    520         default:
    521 
    522             /* Name segment string */
    523 
    524             NameString = AcpiExAllocateNameString (PrefixCount, 1);
    525             if (!NameString)
    526             {
    527                 Status = AE_NO_MEMORY;
    528                 break;
    529             }
    530 
    531             Status = AcpiExNameSegment (&AmlAddress, NameString);
    532             break;
    533         }
    534     }
    535 
    536     if (AE_CTRL_PENDING == Status && HasPrefix)
    537     {
    538         /* Ran out of segments after processing a prefix */
    539 
    540         ACPI_ERROR ((AE_INFO,
    541             "Malformed Name at %p", NameString));
    542         Status = AE_AML_BAD_NAME;
    543     }
    544 
    545     if (ACPI_FAILURE (Status))
    546     {
    547         if (NameString)
    548         {
    549             ACPI_FREE (NameString);
    550         }
    551         return_ACPI_STATUS (Status);
    552     }
    553 
    554     *OutNameString = NameString;
    555     *OutNameLength = (UINT32) (AmlAddress - InAmlAddress);
    556 
    557     return_ACPI_STATUS (Status);
    558 }
    559 
    560 
    561