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 - 2009, 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 %d", 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 %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