1 2 /****************************************************************************** 3 * 4 * Module Name: aslutils -- compiler utilities 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2012, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 46 #include <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include "aslcompiler.y.h" 48 #include <contrib/dev/acpica/include/acdisasm.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 #include <contrib/dev/acpica/include/amlcode.h> 51 #include <contrib/dev/acpica/include/acapps.h> 52 53 #define _COMPONENT ACPI_COMPILER 54 ACPI_MODULE_NAME ("aslutils") 55 56 57 char AslHexLookup[] = 58 { 59 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' 60 }; 61 62 /* Table below must match ASL_FILE_TYPES in asltypes.h */ 63 64 static const char *AslFileTypeNames [ASL_NUM_FILES] = 65 { 66 "stdout: ", 67 "stderr: ", 68 "Table Input: ", 69 "Binary Output:", 70 "Source Output:", 71 "Preprocessor: ", 72 "Listing File: ", 73 "Hex Dump: ", 74 "Namespace: ", 75 "Debug File: ", 76 "ASM Source: ", 77 "C Source: ", 78 "ASM Include: ", 79 "C Include: " 80 }; 81 82 83 /* Local prototypes */ 84 85 static void 86 UtPadNameWithUnderscores ( 87 char *NameSeg, 88 char *PaddedNameSeg); 89 90 static void 91 UtAttachNameseg ( 92 ACPI_PARSE_OBJECT *Op, 93 char *Name); 94 95 96 /******************************************************************************* 97 * 98 * FUNCTION: UtDisplaySupportedTables 99 * 100 * PARAMETERS: None 101 * 102 * RETURN: None 103 * 104 * DESCRIPTION: Print all supported ACPI table names. 105 * 106 ******************************************************************************/ 107 108 #define ACPI_TABLE_HELP_FORMAT "%8u) %s %s\n" 109 110 void 111 UtDisplaySupportedTables ( 112 void) 113 { 114 ACPI_DMTABLE_DATA *TableData; 115 UINT32 i; 116 117 118 printf ("\nACPI tables supported by iASL version %8.8X:\n" 119 " (Compiler, Disassembler, Template Generator)\n\n", 120 ACPI_CA_VERSION); 121 122 /* Special tables */ 123 124 printf (" Special tables and AML tables:\n"); 125 printf (ACPI_TABLE_HELP_FORMAT, 1, ACPI_RSDP_NAME, "Root System Description Pointer"); 126 printf (ACPI_TABLE_HELP_FORMAT, 2, ACPI_SIG_FACS, "Firmware ACPI Control Structure"); 127 printf (ACPI_TABLE_HELP_FORMAT, 3, ACPI_SIG_DSDT, "Differentiated System Description Table"); 128 printf (ACPI_TABLE_HELP_FORMAT, 4, ACPI_SIG_SSDT, "Secondary System Description Table"); 129 130 /* All data tables with common table header */ 131 132 printf ("\n Standard ACPI data tables:\n"); 133 for (TableData = AcpiDmTableData, i = 5; TableData->Signature; TableData++, i++) 134 { 135 printf (ACPI_TABLE_HELP_FORMAT, i, TableData->Signature, TableData->Name); 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 * 212 * FUNCTION: UtBeginEvent 213 * 214 * PARAMETERS: Name - Ascii name of this event 215 * 216 * RETURN: Event number (integer index) 217 * 218 * DESCRIPTION: Saves the current time with this event 219 * 220 ******************************************************************************/ 221 222 UINT8 223 UtBeginEvent ( 224 char *Name) 225 { 226 227 if (AslGbl_NextEvent >= ASL_NUM_EVENTS) 228 { 229 AcpiOsPrintf ("Ran out of compiler event structs!\n"); 230 return (AslGbl_NextEvent); 231 } 232 233 /* Init event with current (start) time */ 234 235 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer (); 236 AslGbl_Events[AslGbl_NextEvent].EventName = Name; 237 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE; 238 239 return (AslGbl_NextEvent++); 240 } 241 242 243 /******************************************************************************* 244 * 245 * FUNCTION: UtEndEvent 246 * 247 * PARAMETERS: Event - Event number (integer index) 248 * 249 * RETURN: None 250 * 251 * DESCRIPTION: Saves the current time (end time) with this event 252 * 253 ******************************************************************************/ 254 255 void 256 UtEndEvent ( 257 UINT8 Event) 258 { 259 260 if (Event >= ASL_NUM_EVENTS) 261 { 262 return; 263 } 264 265 /* Insert end time for event */ 266 267 AslGbl_Events[Event].EndTime = AcpiOsGetTimer (); 268 } 269 270 271 /******************************************************************************* 272 * 273 * FUNCTION: UtHexCharToValue 274 * 275 * PARAMETERS: HexChar - Hex character in Ascii 276 * 277 * RETURN: The binary value of the hex character 278 * 279 * DESCRIPTION: Perform ascii-to-hex translation 280 * 281 ******************************************************************************/ 282 283 UINT8 284 UtHexCharToValue ( 285 int HexChar) 286 { 287 288 if (HexChar <= 0x39) 289 { 290 return ((UINT8) (HexChar - 0x30)); 291 } 292 293 if (HexChar <= 0x46) 294 { 295 return ((UINT8) (HexChar - 0x37)); 296 } 297 298 return ((UINT8) (HexChar - 0x57)); 299 } 300 301 302 /******************************************************************************* 303 * 304 * FUNCTION: UtConvertByteToHex 305 * 306 * PARAMETERS: RawByte - Binary data 307 * Buffer - Pointer to where the hex bytes will be 308 * stored 309 * 310 * RETURN: Ascii hex byte is stored in Buffer. 311 * 312 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 313 * with "0x" 314 * 315 ******************************************************************************/ 316 317 void 318 UtConvertByteToHex ( 319 UINT8 RawByte, 320 UINT8 *Buffer) 321 { 322 323 Buffer[0] = '0'; 324 Buffer[1] = 'x'; 325 326 Buffer[2] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 327 Buffer[3] = (UINT8) AslHexLookup[RawByte & 0xF]; 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: UtConvertByteToAsmHex 334 * 335 * PARAMETERS: RawByte - Binary data 336 * Buffer - Pointer to where the hex bytes will be 337 * stored 338 * 339 * RETURN: Ascii hex byte is stored in Buffer. 340 * 341 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 342 * with "0x" 343 * 344 ******************************************************************************/ 345 346 void 347 UtConvertByteToAsmHex ( 348 UINT8 RawByte, 349 UINT8 *Buffer) 350 { 351 352 Buffer[0] = '0'; 353 Buffer[1] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 354 Buffer[2] = (UINT8) AslHexLookup[RawByte & 0xF]; 355 Buffer[3] = 'h'; 356 } 357 358 359 /******************************************************************************* 360 * 361 * FUNCTION: DbgPrint 362 * 363 * PARAMETERS: Type - Type of output 364 * Fmt - Printf format string 365 * ... - variable printf list 366 * 367 * RETURN: None 368 * 369 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 370 * debug flag is set. 371 * 372 ******************************************************************************/ 373 374 void 375 DbgPrint ( 376 UINT32 Type, 377 char *Fmt, 378 ...) 379 { 380 va_list Args; 381 382 383 va_start (Args, Fmt); 384 385 if (!Gbl_DebugFlag) 386 { 387 return; 388 } 389 390 if ((Type == ASL_PARSE_OUTPUT) && 391 (!(AslCompilerdebug))) 392 { 393 return; 394 } 395 396 (void) vfprintf (stderr, Fmt, Args); 397 va_end (Args); 398 return; 399 } 400 401 402 /******************************************************************************* 403 * 404 * FUNCTION: UtPrintFormattedName 405 * 406 * PARAMETERS: ParseOpcode - Parser keyword ID 407 * Level - Indentation level 408 * 409 * RETURN: None 410 * 411 * DESCRIPTION: Print the ascii name of the parse opcode. 412 * 413 ******************************************************************************/ 414 415 #define TEXT_OFFSET 10 416 417 void 418 UtPrintFormattedName ( 419 UINT16 ParseOpcode, 420 UINT32 Level) 421 { 422 423 if (Level) 424 { 425 DbgPrint (ASL_TREE_OUTPUT, 426 "%*s", (3 * Level), " "); 427 } 428 DbgPrint (ASL_TREE_OUTPUT, 429 " %-20.20s", UtGetOpName (ParseOpcode)); 430 431 if (Level < TEXT_OFFSET) 432 { 433 DbgPrint (ASL_TREE_OUTPUT, 434 "%*s", (TEXT_OFFSET - Level) * 3, " "); 435 } 436 } 437 438 439 /******************************************************************************* 440 * 441 * FUNCTION: UtSetParseOpName 442 * 443 * PARAMETERS: Op - Parse op to be named. 444 * 445 * RETURN: None 446 * 447 * DESCRIPTION: Insert the ascii name of the parse opcode 448 * 449 ******************************************************************************/ 450 451 void 452 UtSetParseOpName ( 453 ACPI_PARSE_OBJECT *Op) 454 { 455 456 strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 457 ACPI_MAX_PARSEOP_NAME); 458 } 459 460 461 /******************************************************************************* 462 * 463 * FUNCTION: UtDisplaySummary 464 * 465 * PARAMETERS: FileID - ID of outpout file 466 * 467 * RETURN: None 468 * 469 * DESCRIPTION: Display compilation statistics 470 * 471 ******************************************************************************/ 472 473 void 474 UtDisplaySummary ( 475 UINT32 FileId) 476 { 477 UINT32 i; 478 479 480 if (FileId != ASL_FILE_STDOUT) 481 { 482 /* Compiler name and version number */ 483 484 FlPrintFile (FileId, "%s version %X%s\n\n", 485 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH); 486 } 487 488 /* Summary of main input and output files */ 489 490 if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 491 { 492 FlPrintFile (FileId, 493 "%-14s %s - %u lines, %u bytes, %u fields\n", 494 "Table Input:", 495 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 496 Gbl_InputByteCount, Gbl_InputFieldCount); 497 498 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 499 { 500 FlPrintFile (FileId, 501 "%-14s %s - %u bytes\n", 502 "Binary Output:", 503 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength); 504 } 505 } 506 else 507 { 508 FlPrintFile (FileId, 509 "%-14s %s - %u lines, %u bytes, %u keywords\n", 510 "ASL Input:", 511 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 512 Gbl_InputByteCount, TotalKeywords); 513 514 /* AML summary */ 515 516 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 517 { 518 FlPrintFile (FileId, 519 "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n", 520 "AML Output:", 521 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength, 522 TotalNamedObjects, TotalExecutableOpcodes); 523 } 524 } 525 526 /* Display summary of any optional files */ 527 528 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++) 529 { 530 if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle) 531 { 532 continue; 533 } 534 535 /* .SRC is a temp file unless specifically requested */ 536 537 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag)) 538 { 539 continue; 540 } 541 542 /* .I is a temp file unless specifically requested */ 543 544 if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag)) 545 { 546 continue; 547 } 548 549 FlPrintFile (FileId, "%14s %s - %u bytes\n", 550 AslFileTypeNames [i], 551 Gbl_Files[i].Filename, FlGetFileSize (i)); 552 } 553 554 /* Error summary */ 555 556 FlPrintFile (FileId, 557 "\nCompilation complete. %u Errors, %u Warnings, %u Remarks", 558 Gbl_ExceptionCount[ASL_ERROR], 559 Gbl_ExceptionCount[ASL_WARNING] + 560 Gbl_ExceptionCount[ASL_WARNING2] + 561 Gbl_ExceptionCount[ASL_WARNING3], 562 Gbl_ExceptionCount[ASL_REMARK]); 563 564 if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 565 { 566 FlPrintFile (FileId, 567 ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]); 568 } 569 570 FlPrintFile (FileId, "\n"); 571 } 572 573 574 /******************************************************************************* 575 * 576 * FUNCTION: UtCheckIntegerRange 577 * 578 * PARAMETERS: Op - Integer parse node 579 * LowValue - Smallest allowed value 580 * HighValue - Largest allowed value 581 * 582 * RETURN: Op if OK, otherwise NULL 583 * 584 * DESCRIPTION: Check integer for an allowable range 585 * 586 ******************************************************************************/ 587 588 ACPI_PARSE_OBJECT * 589 UtCheckIntegerRange ( 590 ACPI_PARSE_OBJECT *Op, 591 UINT32 LowValue, 592 UINT32 HighValue) 593 { 594 595 if (!Op) 596 { 597 return NULL; 598 } 599 600 if ((Op->Asl.Value.Integer < LowValue) || 601 (Op->Asl.Value.Integer > HighValue)) 602 { 603 sprintf (MsgBuffer, "0x%X, allowable: 0x%X-0x%X", 604 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue); 605 606 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer); 607 return (NULL); 608 } 609 610 return (Op); 611 } 612 613 614 /******************************************************************************* 615 * 616 * FUNCTION: UtGetStringBuffer 617 * 618 * PARAMETERS: Length - Size of buffer requested 619 * 620 * RETURN: Pointer to the buffer. Aborts on allocation failure 621 * 622 * DESCRIPTION: Allocate a string buffer. Bypass the local 623 * dynamic memory manager for performance reasons (This has a 624 * major impact on the speed of the compiler.) 625 * 626 ******************************************************************************/ 627 628 char * 629 UtGetStringBuffer ( 630 UINT32 Length) 631 { 632 char *Buffer; 633 634 635 if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) 636 { 637 Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length); 638 Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE + 639 Length; 640 } 641 642 Buffer = Gbl_StringCacheNext; 643 Gbl_StringCacheNext += Length; 644 645 return (Buffer); 646 } 647 648 649 /******************************************************************************* 650 * 651 * FUNCTION: UtInternalizeName 652 * 653 * PARAMETERS: ExternalName - Name to convert 654 * ConvertedName - Where the converted name is returned 655 * 656 * RETURN: Status 657 * 658 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name 659 * 660 ******************************************************************************/ 661 662 ACPI_STATUS 663 UtInternalizeName ( 664 char *ExternalName, 665 char **ConvertedName) 666 { 667 ACPI_NAMESTRING_INFO Info; 668 ACPI_STATUS Status; 669 670 671 if (!ExternalName) 672 { 673 return (AE_OK); 674 } 675 676 /* Get the length of the new internal name */ 677 678 Info.ExternalName = ExternalName; 679 AcpiNsGetInternalNameLength (&Info); 680 681 /* We need a segment to store the internal name */ 682 683 Info.InternalName = UtGetStringBuffer (Info.Length); 684 if (!Info.InternalName) 685 { 686 return (AE_NO_MEMORY); 687 } 688 689 /* Build the name */ 690 691 Status = AcpiNsBuildInternalName (&Info); 692 if (ACPI_FAILURE (Status)) 693 { 694 return (Status); 695 } 696 697 *ConvertedName = Info.InternalName; 698 return (AE_OK); 699 } 700 701 702 /******************************************************************************* 703 * 704 * FUNCTION: UtPadNameWithUnderscores 705 * 706 * PARAMETERS: NameSeg - Input nameseg 707 * PaddedNameSeg - Output padded nameseg 708 * 709 * RETURN: Padded nameseg. 710 * 711 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full 712 * ACPI_NAME. 713 * 714 ******************************************************************************/ 715 716 static void 717 UtPadNameWithUnderscores ( 718 char *NameSeg, 719 char *PaddedNameSeg) 720 { 721 UINT32 i; 722 723 724 for (i = 0; (i < ACPI_NAME_SIZE); i++) 725 { 726 if (*NameSeg) 727 { 728 *PaddedNameSeg = *NameSeg; 729 NameSeg++; 730 } 731 else 732 { 733 *PaddedNameSeg = '_'; 734 } 735 PaddedNameSeg++; 736 } 737 } 738 739 740 /******************************************************************************* 741 * 742 * FUNCTION: UtAttachNameseg 743 * 744 * PARAMETERS: Op - Parent parse node 745 * Name - Full ExternalName 746 * 747 * RETURN: None; Sets the NameSeg field in parent node 748 * 749 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it 750 * in the NameSeg field of the Op. 751 * 752 ******************************************************************************/ 753 754 static void 755 UtAttachNameseg ( 756 ACPI_PARSE_OBJECT *Op, 757 char *Name) 758 { 759 char *NameSeg; 760 char PaddedNameSeg[4]; 761 762 763 if (!Name) 764 { 765 return; 766 } 767 768 /* Look for the last dot in the namepath */ 769 770 NameSeg = strrchr (Name, '.'); 771 if (NameSeg) 772 { 773 /* Found last dot, we have also found the final nameseg */ 774 775 NameSeg++; 776 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg); 777 } 778 else 779 { 780 /* No dots in the namepath, there is only a single nameseg. */ 781 /* Handle prefixes */ 782 783 while ((*Name == '\\') || (*Name == '^')) 784 { 785 Name++; 786 } 787 788 /* Remaing string should be one single nameseg */ 789 790 UtPadNameWithUnderscores (Name, PaddedNameSeg); 791 } 792 793 strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4); 794 } 795 796 797 /******************************************************************************* 798 * 799 * FUNCTION: UtAttachNamepathToOwner 800 * 801 * PARAMETERS: Op - Parent parse node 802 * NameOp - Node that contains the name 803 * 804 * RETURN: Sets the ExternalName and Namepath in the parent node 805 * 806 * DESCRIPTION: Store the name in two forms in the parent node: The original 807 * (external) name, and the internalized name that is used within 808 * the ACPI namespace manager. 809 * 810 ******************************************************************************/ 811 812 void 813 UtAttachNamepathToOwner ( 814 ACPI_PARSE_OBJECT *Op, 815 ACPI_PARSE_OBJECT *NameOp) 816 { 817 ACPI_STATUS Status; 818 819 820 /* Full external path */ 821 822 Op->Asl.ExternalName = NameOp->Asl.Value.String; 823 824 /* Save the NameOp for possible error reporting later */ 825 826 Op->Asl.ParentMethod = (void *) NameOp; 827 828 /* Last nameseg of the path */ 829 830 UtAttachNameseg (Op, Op->Asl.ExternalName); 831 832 /* Create internalized path */ 833 834 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 835 if (ACPI_FAILURE (Status)) 836 { 837 /* TBD: abort on no memory */ 838 } 839 } 840 841 842 /******************************************************************************* 843 * 844 * FUNCTION: UtDoConstant 845 * 846 * PARAMETERS: String - Hex, Octal, or Decimal string 847 * 848 * RETURN: Converted Integer 849 * 850 * DESCRIPTION: Convert a string to an integer, with error checking. 851 * 852 ******************************************************************************/ 853 854 UINT64 855 UtDoConstant ( 856 char *String) 857 { 858 ACPI_STATUS Status; 859 UINT64 Converted; 860 char ErrBuf[64]; 861 862 863 Status = UtStrtoul64 (String, 0, &Converted); 864 if (ACPI_FAILURE (Status)) 865 { 866 sprintf (ErrBuf, "%s %s\n", "Conversion error:", 867 AcpiFormatException (Status)); 868 AslCompilererror (ErrBuf); 869 } 870 871 return (Converted); 872 } 873 874 875 /* TBD: use version in ACPI CA main code base? */ 876 877 /******************************************************************************* 878 * 879 * FUNCTION: UtStrtoul64 880 * 881 * PARAMETERS: String - Null terminated string 882 * Terminater - Where a pointer to the terminating byte 883 * is returned 884 * Base - Radix of the string 885 * 886 * RETURN: Converted value 887 * 888 * DESCRIPTION: Convert a string into an unsigned value. 889 * 890 ******************************************************************************/ 891 892 ACPI_STATUS 893 UtStrtoul64 ( 894 char *String, 895 UINT32 Base, 896 UINT64 *RetInteger) 897 { 898 UINT32 Index; 899 UINT32 Sign; 900 UINT64 ReturnValue = 0; 901 ACPI_STATUS Status = AE_OK; 902 903 904 *RetInteger = 0; 905 906 switch (Base) 907 { 908 case 0: 909 case 8: 910 case 10: 911 case 16: 912 break; 913 914 default: 915 /* 916 * The specified Base parameter is not in the domain of 917 * this function: 918 */ 919 return (AE_BAD_PARAMETER); 920 } 921 922 /* Skip over any white space in the buffer: */ 923 924 while (isspace ((int) *String) || *String == '\t') 925 { 926 ++String; 927 } 928 929 /* 930 * The buffer may contain an optional plus or minus sign. 931 * If it does, then skip over it but remember what is was: 932 */ 933 if (*String == '-') 934 { 935 Sign = NEGATIVE; 936 ++String; 937 } 938 else if (*String == '+') 939 { 940 ++String; 941 Sign = POSITIVE; 942 } 943 else 944 { 945 Sign = POSITIVE; 946 } 947 948 /* 949 * If the input parameter Base is zero, then we need to 950 * determine if it is octal, decimal, or hexadecimal: 951 */ 952 if (Base == 0) 953 { 954 if (*String == '0') 955 { 956 if (tolower ((int) *(++String)) == 'x') 957 { 958 Base = 16; 959 ++String; 960 } 961 else 962 { 963 Base = 8; 964 } 965 } 966 else 967 { 968 Base = 10; 969 } 970 } 971 972 /* 973 * For octal and hexadecimal bases, skip over the leading 974 * 0 or 0x, if they are present. 975 */ 976 if (Base == 8 && *String == '0') 977 { 978 String++; 979 } 980 981 if (Base == 16 && 982 *String == '0' && 983 tolower ((int) *(++String)) == 'x') 984 { 985 String++; 986 } 987 988 /* Main loop: convert the string to an unsigned long */ 989 990 while (*String) 991 { 992 if (isdigit ((int) *String)) 993 { 994 Index = ((UINT8) *String) - '0'; 995 } 996 else 997 { 998 Index = (UINT8) toupper ((int) *String); 999 if (isupper ((int) Index)) 1000 { 1001 Index = Index - 'A' + 10; 1002 } 1003 else 1004 { 1005 goto ErrorExit; 1006 } 1007 } 1008 1009 if (Index >= Base) 1010 { 1011 goto ErrorExit; 1012 } 1013 1014 /* Check to see if value is out of range: */ 1015 1016 if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 1017 (UINT64) Base)) 1018 { 1019 goto ErrorExit; 1020 } 1021 else 1022 { 1023 ReturnValue *= Base; 1024 ReturnValue += Index; 1025 } 1026 1027 ++String; 1028 } 1029 1030 1031 /* If a minus sign was present, then "the conversion is negated": */ 1032 1033 if (Sign == NEGATIVE) 1034 { 1035 ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 1036 } 1037 1038 *RetInteger = ReturnValue; 1039 return (Status); 1040 1041 1042 ErrorExit: 1043 switch (Base) 1044 { 1045 case 8: 1046 Status = AE_BAD_OCTAL_CONSTANT; 1047 break; 1048 1049 case 10: 1050 Status = AE_BAD_DECIMAL_CONSTANT; 1051 break; 1052 1053 case 16: 1054 Status = AE_BAD_HEX_CONSTANT; 1055 break; 1056 1057 default: 1058 /* Base validated above */ 1059 break; 1060 } 1061 1062 return (Status); 1063 } 1064