1 /****************************************************************************** 2 * 3 * Module Name: aslutils -- compiler utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #include "acdisasm.h" 47 #include "acnamesp.h" 48 #include "amlcode.h" 49 #include "acapps.h" 50 #include <sys/stat.h> 51 52 53 #define _COMPONENT ACPI_COMPILER 54 ACPI_MODULE_NAME ("aslutils") 55 56 57 /* Local prototypes */ 58 59 static void 60 UtPadNameWithUnderscores ( 61 char *NameSeg, 62 char *PaddedNameSeg); 63 64 static void 65 UtAttachNameseg ( 66 ACPI_PARSE_OBJECT *Op, 67 char *Name); 68 69 70 /****************************************************************************** 71 * 72 * FUNCTION: UtQueryForOverwrite 73 * 74 * PARAMETERS: Pathname - Output filename 75 * 76 * RETURN: TRUE if file does not exist or overwrite is authorized 77 * 78 * DESCRIPTION: Query for file overwrite if it already exists. 79 * 80 ******************************************************************************/ 81 82 BOOLEAN 83 UtQueryForOverwrite ( 84 char *Pathname) 85 { 86 struct stat StatInfo; 87 88 89 if (!stat (Pathname, &StatInfo)) 90 { 91 fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ", 92 Pathname); 93 94 if (getchar () != 'y') 95 { 96 return (FALSE); 97 } 98 } 99 100 return (TRUE); 101 } 102 103 104 /******************************************************************************* 105 * 106 * FUNCTION: UtDisplaySupportedTables 107 * 108 * PARAMETERS: None 109 * 110 * RETURN: None 111 * 112 * DESCRIPTION: Print all supported ACPI table names. 113 * 114 ******************************************************************************/ 115 116 void 117 UtDisplaySupportedTables ( 118 void) 119 { 120 const AH_TABLE *TableData; 121 UINT32 i; 122 123 124 printf ("\nACPI tables supported by iASL version %8.8X:\n" 125 " (Compiler, Disassembler, Template Generator)\n\n", 126 ACPI_CA_VERSION); 127 128 /* All ACPI tables with the common table header */ 129 130 printf ("\n Supported ACPI tables:\n"); 131 for (TableData = AcpiSupportedTables, i = 1; 132 TableData->Signature; TableData++, i++) 133 { 134 printf ("%8u) %s %s\n", i, 135 TableData->Signature, TableData->Description); 136 } 137 } 138 139 140 /******************************************************************************* 141 * 142 * FUNCTION: UtDisplayConstantOpcodes 143 * 144 * PARAMETERS: None 145 * 146 * RETURN: None 147 * 148 * DESCRIPTION: Print AML opcodes that can be used in constant expressions. 149 * 150 ******************************************************************************/ 151 152 void 153 UtDisplayConstantOpcodes ( 154 void) 155 { 156 UINT32 i; 157 158 159 printf ("Constant expression opcode information\n\n"); 160 161 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++) 162 { 163 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT) 164 { 165 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name); 166 } 167 } 168 } 169 170 171 /******************************************************************************* 172 * 173 * FUNCTION: UtLocalCalloc 174 * 175 * PARAMETERS: Size - Bytes to be allocated 176 * 177 * RETURN: Pointer to the allocated memory. Guaranteed to be valid. 178 * 179 * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an 180 * allocation failure, on the assumption that nothing more can be 181 * accomplished. 182 * 183 ******************************************************************************/ 184 185 void * 186 UtLocalCalloc ( 187 UINT32 Size) 188 { 189 void *Allocated; 190 191 192 Allocated = ACPI_ALLOCATE_ZEROED (Size); 193 if (!Allocated) 194 { 195 AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, 196 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 197 Gbl_InputByteCount, Gbl_CurrentColumn, 198 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 199 200 CmCleanupAndExit (); 201 exit (1); 202 } 203 204 TotalAllocations++; 205 TotalAllocated += Size; 206 return (Allocated); 207 } 208 209 /******************************************************************************* 210 * 211 * FUNCTION: UtLocalFree 212 * 213 * PARAMETERS: Allocated - Pointer to be released 214 * PARAMETERS: Size - Bytes to be released 215 * 216 * RETURN: None 217 * 218 * DESCRIPTION: Free memory previously allocated 219 * 220 ******************************************************************************/ 221 void 222 UtLocalFree ( 223 void *Allocated, UINT32 Size) 224 { 225 ACPI_FREE (Allocated); 226 TotalAllocations--; 227 TotalAllocated -= Size; 228 } 229 230 /******************************************************************************* 231 * 232 * FUNCTION: UtBeginEvent 233 * 234 * PARAMETERS: Name - Ascii name of this event 235 * 236 * RETURN: Event number (integer index) 237 * 238 * DESCRIPTION: Saves the current time with this event 239 * 240 ******************************************************************************/ 241 242 UINT8 243 UtBeginEvent ( 244 char *Name) 245 { 246 247 if (AslGbl_NextEvent >= ASL_NUM_EVENTS) 248 { 249 AcpiOsPrintf ("Ran out of compiler event structs!\n"); 250 return (AslGbl_NextEvent); 251 } 252 253 /* Init event with current (start) time */ 254 255 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer (); 256 AslGbl_Events[AslGbl_NextEvent].EventName = Name; 257 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE; 258 return (AslGbl_NextEvent++); 259 } 260 261 262 /******************************************************************************* 263 * 264 * FUNCTION: UtEndEvent 265 * 266 * PARAMETERS: Event - Event number (integer index) 267 * 268 * RETURN: None 269 * 270 * DESCRIPTION: Saves the current time (end time) with this event 271 * 272 ******************************************************************************/ 273 274 void 275 UtEndEvent ( 276 UINT8 Event) 277 { 278 279 if (Event >= ASL_NUM_EVENTS) 280 { 281 return; 282 } 283 284 /* Insert end time for event */ 285 286 AslGbl_Events[Event].EndTime = AcpiOsGetTimer (); 287 } 288 289 290 /******************************************************************************* 291 * 292 * FUNCTION: UtConvertByteToHex 293 * 294 * PARAMETERS: RawByte - Binary data 295 * Buffer - Pointer to where the hex bytes will be 296 * stored 297 * 298 * RETURN: Ascii hex byte is stored in Buffer. 299 * 300 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 301 * with "0x" 302 * 303 ******************************************************************************/ 304 305 void 306 UtConvertByteToHex ( 307 UINT8 RawByte, 308 UINT8 *Buffer) 309 { 310 311 Buffer[0] = '0'; 312 Buffer[1] = 'x'; 313 314 Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4); 315 Buffer[3] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0); 316 } 317 318 319 /******************************************************************************* 320 * 321 * FUNCTION: UtConvertByteToAsmHex 322 * 323 * PARAMETERS: RawByte - Binary data 324 * Buffer - Pointer to where the hex bytes will be 325 * stored 326 * 327 * RETURN: Ascii hex byte is stored in Buffer. 328 * 329 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 330 * with '0', and a trailing 'h' is added. 331 * 332 ******************************************************************************/ 333 334 void 335 UtConvertByteToAsmHex ( 336 UINT8 RawByte, 337 UINT8 *Buffer) 338 { 339 340 Buffer[0] = '0'; 341 Buffer[1] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4); 342 Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0); 343 Buffer[3] = 'h'; 344 } 345 346 347 /******************************************************************************* 348 * 349 * FUNCTION: DbgPrint 350 * 351 * PARAMETERS: Type - Type of output 352 * Fmt - Printf format string 353 * ... - variable printf list 354 * 355 * RETURN: None 356 * 357 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 358 * debug flag is set. 359 * 360 ******************************************************************************/ 361 362 void 363 DbgPrint ( 364 UINT32 Type, 365 char *Fmt, 366 ...) 367 { 368 va_list Args; 369 370 371 if (!Gbl_DebugFlag) 372 { 373 return; 374 } 375 376 if ((Type == ASL_PARSE_OUTPUT) && 377 (!(AslCompilerdebug))) 378 { 379 return; 380 } 381 382 va_start (Args, Fmt); 383 (void) vfprintf (stderr, Fmt, Args); 384 va_end (Args); 385 return; 386 } 387 388 389 /******************************************************************************* 390 * 391 * FUNCTION: UtPrintFormattedName 392 * 393 * PARAMETERS: ParseOpcode - Parser keyword ID 394 * Level - Indentation level 395 * 396 * RETURN: None 397 * 398 * DESCRIPTION: Print the ascii name of the parse opcode. 399 * 400 ******************************************************************************/ 401 402 #define TEXT_OFFSET 10 403 404 void 405 UtPrintFormattedName ( 406 UINT16 ParseOpcode, 407 UINT32 Level) 408 { 409 410 if (Level) 411 { 412 DbgPrint (ASL_TREE_OUTPUT, 413 "%*s", (3 * Level), " "); 414 } 415 DbgPrint (ASL_TREE_OUTPUT, 416 " %-20.20s", UtGetOpName (ParseOpcode)); 417 418 if (Level < TEXT_OFFSET) 419 { 420 DbgPrint (ASL_TREE_OUTPUT, 421 "%*s", (TEXT_OFFSET - Level) * 3, " "); 422 } 423 } 424 425 426 /******************************************************************************* 427 * 428 * FUNCTION: UtSetParseOpName 429 * 430 * PARAMETERS: Op - Parse op to be named. 431 * 432 * RETURN: None 433 * 434 * DESCRIPTION: Insert the ascii name of the parse opcode 435 * 436 ******************************************************************************/ 437 438 void 439 UtSetParseOpName ( 440 ACPI_PARSE_OBJECT *Op) 441 { 442 443 strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 444 ACPI_MAX_PARSEOP_NAME); 445 } 446 447 448 /******************************************************************************* 449 * 450 * FUNCTION: UtDisplaySummary 451 * 452 * PARAMETERS: FileID - ID of outpout file 453 * 454 * RETURN: None 455 * 456 * DESCRIPTION: Display compilation statistics 457 * 458 ******************************************************************************/ 459 460 void 461 UtDisplaySummary ( 462 UINT32 FileId) 463 { 464 UINT32 i; 465 466 467 if (FileId != ASL_FILE_STDOUT) 468 { 469 /* Compiler name and version number */ 470 471 FlPrintFile (FileId, "%s version %X%s [%s]\n\n", 472 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH, ACPI_DATE); 473 } 474 475 /* Summary of main input and output files */ 476 477 if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 478 { 479 FlPrintFile (FileId, 480 "%-14s %s - %u lines, %u bytes, %u fields\n", 481 "Table Input:", 482 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 483 Gbl_InputByteCount, Gbl_InputFieldCount); 484 485 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 486 { 487 FlPrintFile (FileId, 488 "%-14s %s - %u bytes\n", 489 "Binary Output:", 490 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength); 491 } 492 } 493 else 494 { 495 FlPrintFile (FileId, 496 "%-14s %s - %u lines, %u bytes, %u keywords\n", 497 "ASL Input:", 498 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 499 Gbl_OriginalInputFileSize, TotalKeywords); 500 501 /* AML summary */ 502 503 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 504 { 505 if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 506 { 507 FlPrintFile (FileId, 508 "%-14s %s - %u bytes, %u named objects, " 509 "%u executable opcodes\n", 510 "AML Output:", 511 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, 512 FlGetFileSize (ASL_FILE_AML_OUTPUT), 513 TotalNamedObjects, TotalExecutableOpcodes); 514 } 515 } 516 } 517 518 /* Display summary of any optional files */ 519 520 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++) 521 { 522 if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle) 523 { 524 continue; 525 } 526 527 /* .SRC is a temp file unless specifically requested */ 528 529 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag)) 530 { 531 continue; 532 } 533 534 /* .PRE is the preprocessor intermediate file */ 535 536 if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_KeepPreprocessorTempFile)) 537 { 538 continue; 539 } 540 541 FlPrintFile (FileId, "%14s %s - %u bytes\n", 542 Gbl_Files[i].ShortDescription, 543 Gbl_Files[i].Filename, FlGetFileSize (i)); 544 } 545 546 /* Error summary */ 547 548 FlPrintFile (FileId, 549 "\nCompilation complete. %u Errors, %u Warnings, %u Remarks", 550 Gbl_ExceptionCount[ASL_ERROR], 551 Gbl_ExceptionCount[ASL_WARNING] + 552 Gbl_ExceptionCount[ASL_WARNING2] + 553 Gbl_ExceptionCount[ASL_WARNING3], 554 Gbl_ExceptionCount[ASL_REMARK]); 555 556 if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 557 { 558 FlPrintFile (FileId, ", %u Optimizations", 559 Gbl_ExceptionCount[ASL_OPTIMIZATION]); 560 561 if (TotalFolds) 562 { 563 FlPrintFile (FileId, ", %u Constants Folded", TotalFolds); 564 } 565 } 566 567 FlPrintFile (FileId, "\n"); 568 } 569 570 571 /******************************************************************************* 572 * 573 * FUNCTION: UtCheckIntegerRange 574 * 575 * PARAMETERS: Op - Integer parse node 576 * LowValue - Smallest allowed value 577 * HighValue - Largest allowed value 578 * 579 * RETURN: Op if OK, otherwise NULL 580 * 581 * DESCRIPTION: Check integer for an allowable range 582 * 583 ******************************************************************************/ 584 585 ACPI_PARSE_OBJECT * 586 UtCheckIntegerRange ( 587 ACPI_PARSE_OBJECT *Op, 588 UINT32 LowValue, 589 UINT32 HighValue) 590 { 591 592 if (!Op) 593 { 594 return (NULL); 595 } 596 597 if ((Op->Asl.Value.Integer < LowValue) || 598 (Op->Asl.Value.Integer > HighValue)) 599 { 600 snprintf (MsgBuffer, sizeof(MsgBuffer), "0x%X, allowable: 0x%X-0x%X", 601 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue); 602 603 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer); 604 return (NULL); 605 } 606 607 return (Op); 608 } 609 610 611 /******************************************************************************* 612 * 613 * FUNCTION: UtStringCacheCalloc 614 * 615 * PARAMETERS: Length - Size of buffer requested 616 * 617 * RETURN: Pointer to the buffer. Aborts on allocation failure 618 * 619 * DESCRIPTION: Allocate a string buffer. Bypass the local 620 * dynamic memory manager for performance reasons (This has a 621 * major impact on the speed of the compiler.) 622 * 623 ******************************************************************************/ 624 625 char * 626 UtStringCacheCalloc ( 627 UINT32 Length) 628 { 629 char *Buffer; 630 ASL_CACHE_INFO *Cache; 631 UINT32 CacheSize = ASL_STRING_CACHE_SIZE; 632 633 634 if (Length > CacheSize) 635 { 636 CacheSize = Length; 637 638 if (Gbl_StringCacheList) 639 { 640 Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); 641 642 /* Link new cache buffer just following head of list */ 643 644 Cache->Next = Gbl_StringCacheList->Next; 645 Gbl_StringCacheList->Next = Cache; 646 647 /* Leave cache management pointers alone as they pertain to head */ 648 649 Gbl_StringCount++; 650 Gbl_StringSize += Length; 651 652 return (Cache->Buffer); 653 } 654 } 655 656 if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) 657 { 658 /* Allocate a new buffer */ 659 660 Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); 661 662 /* Link new cache buffer to head of list */ 663 664 Cache->Next = Gbl_StringCacheList; 665 Gbl_StringCacheList = Cache; 666 667 /* Setup cache management pointers */ 668 669 Gbl_StringCacheNext = Cache->Buffer; 670 Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize; 671 } 672 673 Gbl_StringCount++; 674 Gbl_StringSize += Length; 675 676 Buffer = Gbl_StringCacheNext; 677 Gbl_StringCacheNext += Length; 678 return (Buffer); 679 } 680 681 682 /****************************************************************************** 683 * 684 * FUNCTION: UtExpandLineBuffers 685 * 686 * PARAMETERS: None. Updates global line buffer pointers. 687 * 688 * RETURN: None. Reallocates the global line buffers 689 * 690 * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates 691 * all global line buffers and updates Gbl_LineBufferSize. NOTE: 692 * Also used for the initial allocation of the buffers, when 693 * all of the buffer pointers are NULL. Initial allocations are 694 * of size ASL_DEFAULT_LINE_BUFFER_SIZE 695 * 696 *****************************************************************************/ 697 698 void 699 UtExpandLineBuffers ( 700 void) 701 { 702 UINT32 NewSize; 703 704 705 /* Attempt to double the size of all line buffers */ 706 707 NewSize = Gbl_LineBufferSize * 2; 708 if (Gbl_CurrentLineBuffer) 709 { 710 DbgPrint (ASL_DEBUG_OUTPUT, 711 "Increasing line buffer size from %u to %u\n", 712 Gbl_LineBufferSize, NewSize); 713 } 714 715 Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize); 716 Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 717 if (!Gbl_CurrentLineBuffer) 718 { 719 goto ErrorExit; 720 } 721 722 Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize); 723 if (!Gbl_MainTokenBuffer) 724 { 725 goto ErrorExit; 726 } 727 728 Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize); 729 if (!Gbl_MacroTokenBuffer) 730 { 731 goto ErrorExit; 732 } 733 734 Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize); 735 if (!Gbl_ExpressionTokenBuffer) 736 { 737 goto ErrorExit; 738 } 739 740 Gbl_LineBufferSize = NewSize; 741 return; 742 743 744 /* On error above, simply issue error messages and abort, cannot continue */ 745 746 ErrorExit: 747 printf ("Could not increase line buffer size from %u to %u\n", 748 Gbl_LineBufferSize, Gbl_LineBufferSize * 2); 749 750 AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, 751 NULL, NULL); 752 AslAbort (); 753 } 754 755 756 /****************************************************************************** 757 * 758 * FUNCTION: UtFreeLineBuffers 759 * 760 * PARAMETERS: None 761 * 762 * RETURN: None 763 * 764 * DESCRIPTION: Free all line buffers 765 * 766 *****************************************************************************/ 767 768 void 769 UtFreeLineBuffers ( 770 void) 771 { 772 773 free (Gbl_CurrentLineBuffer); 774 free (Gbl_MainTokenBuffer); 775 free (Gbl_MacroTokenBuffer); 776 free (Gbl_ExpressionTokenBuffer); 777 } 778 779 780 /******************************************************************************* 781 * 782 * FUNCTION: UtInternalizeName 783 * 784 * PARAMETERS: ExternalName - Name to convert 785 * ConvertedName - Where the converted name is returned 786 * 787 * RETURN: Status 788 * 789 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name 790 * 791 ******************************************************************************/ 792 793 ACPI_STATUS 794 UtInternalizeName ( 795 char *ExternalName, 796 char **ConvertedName) 797 { 798 ACPI_NAMESTRING_INFO Info; 799 ACPI_STATUS Status; 800 801 802 if (!ExternalName) 803 { 804 return (AE_OK); 805 } 806 807 /* Get the length of the new internal name */ 808 809 Info.ExternalName = ExternalName; 810 AcpiNsGetInternalNameLength (&Info); 811 812 /* We need a segment to store the internal name */ 813 814 Info.InternalName = UtStringCacheCalloc (Info.Length); 815 if (!Info.InternalName) 816 { 817 return (AE_NO_MEMORY); 818 } 819 820 /* Build the name */ 821 822 Status = AcpiNsBuildInternalName (&Info); 823 if (ACPI_FAILURE (Status)) 824 { 825 return (Status); 826 } 827 828 *ConvertedName = Info.InternalName; 829 return (AE_OK); 830 } 831 832 833 /******************************************************************************* 834 * 835 * FUNCTION: UtPadNameWithUnderscores 836 * 837 * PARAMETERS: NameSeg - Input nameseg 838 * PaddedNameSeg - Output padded nameseg 839 * 840 * RETURN: Padded nameseg. 841 * 842 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full 843 * ACPI_NAME. 844 * 845 ******************************************************************************/ 846 847 static void 848 UtPadNameWithUnderscores ( 849 char *NameSeg, 850 char *PaddedNameSeg) 851 { 852 UINT32 i; 853 854 855 for (i = 0; (i < ACPI_NAME_SIZE); i++) 856 { 857 if (*NameSeg) 858 { 859 *PaddedNameSeg = *NameSeg; 860 NameSeg++; 861 } 862 else 863 { 864 *PaddedNameSeg = '_'; 865 } 866 867 PaddedNameSeg++; 868 } 869 } 870 871 872 /******************************************************************************* 873 * 874 * FUNCTION: UtAttachNameseg 875 * 876 * PARAMETERS: Op - Parent parse node 877 * Name - Full ExternalName 878 * 879 * RETURN: None; Sets the NameSeg field in parent node 880 * 881 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it 882 * in the NameSeg field of the Op. 883 * 884 ******************************************************************************/ 885 886 static void 887 UtAttachNameseg ( 888 ACPI_PARSE_OBJECT *Op, 889 char *Name) 890 { 891 char *NameSeg; 892 char PaddedNameSeg[4]; 893 894 895 if (!Name) 896 { 897 return; 898 } 899 900 /* Look for the last dot in the namepath */ 901 902 NameSeg = strrchr (Name, '.'); 903 if (NameSeg) 904 { 905 /* Found last dot, we have also found the final nameseg */ 906 907 NameSeg++; 908 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg); 909 } 910 else 911 { 912 /* No dots in the namepath, there is only a single nameseg. */ 913 /* Handle prefixes */ 914 915 while (ACPI_IS_ROOT_PREFIX (*Name) || 916 ACPI_IS_PARENT_PREFIX (*Name)) 917 { 918 Name++; 919 } 920 921 /* Remaining string should be one single nameseg */ 922 923 UtPadNameWithUnderscores (Name, PaddedNameSeg); 924 } 925 926 ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg); 927 } 928 929 930 /******************************************************************************* 931 * 932 * FUNCTION: UtAttachNamepathToOwner 933 * 934 * PARAMETERS: Op - Parent parse node 935 * NameOp - Node that contains the name 936 * 937 * RETURN: Sets the ExternalName and Namepath in the parent node 938 * 939 * DESCRIPTION: Store the name in two forms in the parent node: The original 940 * (external) name, and the internalized name that is used within 941 * the ACPI namespace manager. 942 * 943 ******************************************************************************/ 944 945 void 946 UtAttachNamepathToOwner ( 947 ACPI_PARSE_OBJECT *Op, 948 ACPI_PARSE_OBJECT *NameOp) 949 { 950 ACPI_STATUS Status; 951 952 953 /* Full external path */ 954 955 Op->Asl.ExternalName = NameOp->Asl.Value.String; 956 957 /* Save the NameOp for possible error reporting later */ 958 959 Op->Asl.ParentMethod = (void *) NameOp; 960 961 /* Last nameseg of the path */ 962 963 UtAttachNameseg (Op, Op->Asl.ExternalName); 964 965 /* Create internalized path */ 966 967 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 968 if (ACPI_FAILURE (Status)) 969 { 970 /* TBD: abort on no memory */ 971 } 972 } 973 974 975 /******************************************************************************* 976 * 977 * FUNCTION: UtDoConstant 978 * 979 * PARAMETERS: String - Hex, Octal, or Decimal string 980 * 981 * RETURN: Converted Integer 982 * 983 * DESCRIPTION: Convert a string to an integer, with error checking. 984 * 985 ******************************************************************************/ 986 987 UINT64 988 UtDoConstant ( 989 char *String) 990 { 991 ACPI_STATUS Status; 992 UINT64 Converted; 993 char ErrBuf[64]; 994 995 996 Status = stroul64 (String, 0, &Converted); 997 if (ACPI_FAILURE (Status)) 998 { 999 snprintf (ErrBuf, sizeof(ErrBuf), "%s %s\n", "Conversion error:", 1000 AcpiFormatException (Status)); 1001 AslCompilererror (ErrBuf); 1002 } 1003 1004 return (Converted); 1005 } 1006 1007 1008 /* TBD: use version in ACPICA main code base? */ 1009 1010 /******************************************************************************* 1011 * 1012 * FUNCTION: stroul64 1013 * 1014 * PARAMETERS: String - Null terminated string 1015 * Terminater - Where a pointer to the terminating byte 1016 * is returned 1017 * Base - Radix of the string 1018 * 1019 * RETURN: Converted value 1020 * 1021 * DESCRIPTION: Convert a string into an unsigned value. 1022 * 1023 ******************************************************************************/ 1024 1025 ACPI_STATUS 1026 stroul64 ( 1027 char *String, 1028 UINT32 Base, 1029 UINT64 *RetInteger) 1030 { 1031 UINT32 Index; 1032 UINT32 Sign; 1033 UINT64 ReturnValue = 0; 1034 ACPI_STATUS Status = AE_OK; 1035 1036 1037 *RetInteger = 0; 1038 1039 switch (Base) 1040 { 1041 case 0: 1042 case 8: 1043 case 10: 1044 case 16: 1045 1046 break; 1047 1048 default: 1049 /* 1050 * The specified Base parameter is not in the domain of 1051 * this function: 1052 */ 1053 return (AE_BAD_PARAMETER); 1054 } 1055 1056 /* Skip over any white space in the buffer: */ 1057 1058 while (isspace ((int) *String) || *String == '\t') 1059 { 1060 ++String; 1061 } 1062 1063 /* 1064 * The buffer may contain an optional plus or minus sign. 1065 * If it does, then skip over it but remember what is was: 1066 */ 1067 if (*String == '-') 1068 { 1069 Sign = ACPI_SIGN_NEGATIVE; 1070 ++String; 1071 } 1072 else if (*String == '+') 1073 { 1074 ++String; 1075 Sign = ACPI_SIGN_POSITIVE; 1076 } 1077 else 1078 { 1079 Sign = ACPI_SIGN_POSITIVE; 1080 } 1081 1082 /* 1083 * If the input parameter Base is zero, then we need to 1084 * determine if it is octal, decimal, or hexadecimal: 1085 */ 1086 if (Base == 0) 1087 { 1088 if (*String == '0') 1089 { 1090 if (tolower ((int) *(++String)) == 'x') 1091 { 1092 Base = 16; 1093 ++String; 1094 } 1095 else 1096 { 1097 Base = 8; 1098 } 1099 } 1100 else 1101 { 1102 Base = 10; 1103 } 1104 } 1105 1106 /* 1107 * For octal and hexadecimal bases, skip over the leading 1108 * 0 or 0x, if they are present. 1109 */ 1110 if (Base == 8 && *String == '0') 1111 { 1112 String++; 1113 } 1114 1115 if (Base == 16 && 1116 *String == '0' && 1117 tolower ((int) *(++String)) == 'x') 1118 { 1119 String++; 1120 } 1121 1122 /* Main loop: convert the string to an unsigned long */ 1123 1124 while (*String) 1125 { 1126 if (isdigit ((int) *String)) 1127 { 1128 Index = ((UINT8) *String) - '0'; 1129 } 1130 else 1131 { 1132 Index = (UINT8) toupper ((int) *String); 1133 if (isupper ((int) Index)) 1134 { 1135 Index = Index - 'A' + 10; 1136 } 1137 else 1138 { 1139 goto ErrorExit; 1140 } 1141 } 1142 1143 if (Index >= Base) 1144 { 1145 goto ErrorExit; 1146 } 1147 1148 /* Check to see if value is out of range: */ 1149 1150 if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 1151 (UINT64) Base)) 1152 { 1153 goto ErrorExit; 1154 } 1155 else 1156 { 1157 ReturnValue *= Base; 1158 ReturnValue += Index; 1159 } 1160 1161 ++String; 1162 } 1163 1164 1165 /* If a minus sign was present, then "the conversion is negated": */ 1166 1167 if (Sign == ACPI_SIGN_NEGATIVE) 1168 { 1169 ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 1170 } 1171 1172 *RetInteger = ReturnValue; 1173 return (Status); 1174 1175 1176 ErrorExit: 1177 switch (Base) 1178 { 1179 case 8: 1180 1181 Status = AE_BAD_OCTAL_CONSTANT; 1182 break; 1183 1184 case 10: 1185 1186 Status = AE_BAD_DECIMAL_CONSTANT; 1187 break; 1188 1189 case 16: 1190 1191 Status = AE_BAD_HEX_CONSTANT; 1192 break; 1193 1194 default: 1195 1196 /* Base validated above */ 1197 1198 break; 1199 } 1200 1201 return (Status); 1202 } 1203