Path: blob/main/sys/contrib/dev/acpica/components/executer/exnames.c
48521 views
/******************************************************************************1*2* Module Name: exnames - interpreter/scanner name load/execute3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acinterp.h>154#include <contrib/dev/acpica/include/amlcode.h>155156#define _COMPONENT ACPI_EXECUTER157ACPI_MODULE_NAME ("exnames")158159/* Local prototypes */160161static char *162AcpiExAllocateNameString (163UINT32 PrefixCount,164UINT32 NumNameSegs);165166static ACPI_STATUS167AcpiExNameSegment (168UINT8 **InAmlAddress,169char *NameString);170171172/*******************************************************************************173*174* FUNCTION: AcpiExAllocateNameString175*176* PARAMETERS: PrefixCount - Count of parent levels. Special cases:177* (-1)==root, 0==none178* NumNameSegs - count of 4-character name segments179*180* RETURN: A pointer to the allocated string segment. This segment must181* be deleted by the caller.182*183* DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name184* string is long enough, and set up prefix if any.185*186******************************************************************************/187188static char *189AcpiExAllocateNameString (190UINT32 PrefixCount,191UINT32 NumNameSegs)192{193char *TempPtr;194char *NameString;195UINT32 SizeNeeded;196197ACPI_FUNCTION_TRACE (ExAllocateNameString);198199200/*201* Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix.202* Also, one byte for the null terminator.203* This may actually be somewhat longer than needed.204*/205if (PrefixCount == ACPI_UINT32_MAX)206{207/* Special case for root */208209SizeNeeded = 1 + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1;210}211else212{213SizeNeeded = PrefixCount + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1;214}215216/*217* Allocate a buffer for the name.218* This buffer must be deleted by the caller!219*/220NameString = ACPI_ALLOCATE (SizeNeeded);221if (!NameString)222{223ACPI_ERROR ((AE_INFO,224"Could not allocate size %u", SizeNeeded));225return_PTR (NULL);226}227228TempPtr = NameString;229230/* Set up Root or Parent prefixes if needed */231232if (PrefixCount == ACPI_UINT32_MAX)233{234*TempPtr++ = AML_ROOT_PREFIX;235}236else237{238while (PrefixCount--)239{240*TempPtr++ = AML_PARENT_PREFIX;241}242}243244245/* Set up Dual or Multi prefixes if needed */246247if (NumNameSegs > 2)248{249/* Set up multi prefixes */250251*TempPtr++ = AML_MULTI_NAME_PREFIX;252*TempPtr++ = (char) NumNameSegs;253}254else if (2 == NumNameSegs)255{256/* Set up dual prefixes */257258*TempPtr++ = AML_DUAL_NAME_PREFIX;259}260261/*262* Terminate string following prefixes. AcpiExNameSegment() will263* append the segment(s)264*/265*TempPtr = 0;266267return_PTR (NameString);268}269270271/*******************************************************************************272*273* FUNCTION: AcpiExNameSegment274*275* PARAMETERS: InAmlAddress - Pointer to the name in the AML code276* NameString - Where to return the name. The name is appended277* to any existing string to form a namepath278*279* RETURN: Status280*281* DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream282*283******************************************************************************/284285static ACPI_STATUS286AcpiExNameSegment (287UINT8 **InAmlAddress,288char *NameString)289{290char *AmlAddress = (void *) *InAmlAddress;291ACPI_STATUS Status = AE_OK;292UINT32 Index;293char CharBuf[5];294295296ACPI_FUNCTION_TRACE (ExNameSegment);297298299/*300* If first character is a digit, then we know that we aren't looking301* at a valid name segment302*/303CharBuf[0] = *AmlAddress;304305if ('0' <= CharBuf[0] && CharBuf[0] <= '9')306{307ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0]));308return_ACPI_STATUS (AE_CTRL_PENDING);309}310311for (Index = 0;312(Index < ACPI_NAMESEG_SIZE) && (AcpiUtValidNameChar (*AmlAddress, 0));313Index++)314{315CharBuf[Index] = *AmlAddress++;316}317318319/* Valid name segment */320321if (Index == 4)322{323/* Found 4 valid characters */324325CharBuf[4] = '\0';326327if (NameString)328{329ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,330"Appending NameSeg %s\n", CharBuf));331strcat (NameString, CharBuf);332}333else334{335ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,336"No Name string - %s\n", CharBuf));337}338}339else if (Index == 0)340{341/*342* First character was not a valid name character,343* so we are looking at something other than a name.344*/345ACPI_DEBUG_PRINT ((ACPI_DB_INFO,346"Leading character is not alpha: %02Xh (not a name)\n",347CharBuf[0]));348Status = AE_CTRL_PENDING;349}350else351{352/*353* Segment started with one or more valid characters, but fewer than354* the required 4355*/356Status = AE_AML_BAD_NAME;357ACPI_ERROR ((AE_INFO,358"Bad character 0x%02x in name, at %p",359*AmlAddress, AmlAddress));360}361362*InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress);363return_ACPI_STATUS (Status);364}365366367/*******************************************************************************368*369* FUNCTION: AcpiExGetNameString370*371* PARAMETERS: DataType - Object type to be associated with this372* name373* InAmlAddress - Pointer to the namestring in the AML code374* OutNameString - Where the namestring is returned375* OutNameLength - Length of the returned string376*377* RETURN: Status, namestring and length378*379* DESCRIPTION: Extract a full namepath from the AML byte stream,380* including any prefixes.381*382******************************************************************************/383384ACPI_STATUS385AcpiExGetNameString (386ACPI_OBJECT_TYPE DataType,387UINT8 *InAmlAddress,388char **OutNameString,389UINT32 *OutNameLength)390{391ACPI_STATUS Status = AE_OK;392UINT8 *AmlAddress = InAmlAddress;393char *NameString = NULL;394UINT32 NumSegments;395UINT32 PrefixCount = 0;396BOOLEAN HasPrefix = FALSE;397398399ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress);400401402if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType ||403ACPI_TYPE_LOCAL_BANK_FIELD == DataType ||404ACPI_TYPE_LOCAL_INDEX_FIELD == DataType)405{406/* Disallow prefixes for types associated with FieldUnit names */407408NameString = AcpiExAllocateNameString (0, 1);409if (!NameString)410{411Status = AE_NO_MEMORY;412}413else414{415Status = AcpiExNameSegment (&AmlAddress, NameString);416}417}418else419{420/*421* DataType is not a field name.422* Examine first character of name for root or parent prefix operators423*/424switch (*AmlAddress)425{426case AML_ROOT_PREFIX:427428ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n",429AmlAddress));430431/*432* Remember that we have a RootPrefix --433* see comment in AcpiExAllocateNameString()434*/435AmlAddress++;436PrefixCount = ACPI_UINT32_MAX;437HasPrefix = TRUE;438break;439440case AML_PARENT_PREFIX:441442/* Increment past possibly multiple parent prefixes */443444do445{446ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n",447AmlAddress));448449AmlAddress++;450PrefixCount++;451452} while (*AmlAddress == AML_PARENT_PREFIX);453454HasPrefix = TRUE;455break;456457default:458459/* Not a prefix character */460461break;462}463464/* Examine first character of name for name segment prefix operator */465466switch (*AmlAddress)467{468case AML_DUAL_NAME_PREFIX:469470ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n",471AmlAddress));472473AmlAddress++;474NameString = AcpiExAllocateNameString (PrefixCount, 2);475if (!NameString)476{477Status = AE_NO_MEMORY;478break;479}480481/* Indicate that we processed a prefix */482483HasPrefix = TRUE;484485Status = AcpiExNameSegment (&AmlAddress, NameString);486if (ACPI_SUCCESS (Status))487{488Status = AcpiExNameSegment (&AmlAddress, NameString);489}490break;491492case AML_MULTI_NAME_PREFIX:493494ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n",495AmlAddress));496497/* Fetch count of segments remaining in name path */498499AmlAddress++;500NumSegments = *AmlAddress;501502NameString = AcpiExAllocateNameString (503PrefixCount, NumSegments);504if (!NameString)505{506Status = AE_NO_MEMORY;507break;508}509510/* Indicate that we processed a prefix */511512AmlAddress++;513HasPrefix = TRUE;514515while (NumSegments &&516(Status = AcpiExNameSegment (&AmlAddress, NameString)) ==517AE_OK)518{519NumSegments--;520}521522break;523524case 0:525526/* NullName valid as of 8-12-98 ASL/AML Grammar Update */527528if (PrefixCount == ACPI_UINT32_MAX)529{530ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,531"NameSeg is \"\\\" followed by NULL\n"));532}533534/* Consume the NULL byte */535536AmlAddress++;537NameString = AcpiExAllocateNameString (PrefixCount, 0);538if (!NameString)539{540Status = AE_NO_MEMORY;541break;542}543544break;545546default:547548/* Name segment string */549550NameString = AcpiExAllocateNameString (PrefixCount, 1);551if (!NameString)552{553Status = AE_NO_MEMORY;554break;555}556557Status = AcpiExNameSegment (&AmlAddress, NameString);558break;559}560}561562if (AE_CTRL_PENDING == Status && HasPrefix)563{564/* Ran out of segments after processing a prefix */565566ACPI_ERROR ((AE_INFO,567"Malformed Name at %p", NameString));568Status = AE_AML_BAD_NAME;569}570571if (ACPI_FAILURE (Status))572{573if (NameString)574{575ACPI_FREE (NameString);576}577return_ACPI_STATUS (Status);578}579580*OutNameString = NameString;581*OutNameLength = (UINT32) (AmlAddress - InAmlAddress);582583return_ACPI_STATUS (Status);584}585586587