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 void 109 UtDisplaySupportedTables ( 110 void) 111 { 112 ACPI_DMTABLE_DATA *TableData; 113 UINT32 i = 6; 114 115 116 printf ("\nACPI tables supported by iASL subsystems in " 117 "version %8.8X:\n" 118 " ASL and Data Table compilers\n" 119 " AML and Data Table disassemblers\n" 120 " ACPI table template generator\n\n", ACPI_CA_VERSION); 121 122 /* Special tables */ 123 124 printf ("%8u) %s %s\n", 1, ACPI_SIG_DSDT, "Differentiated System Description Table"); 125 printf ("%8u) %s %s\n", 2, ACPI_SIG_SSDT, "Secondary System Description Table"); 126 printf ("%8u) %s %s\n", 3, ACPI_SIG_FADT, "Fixed ACPI Description Table (FADT)"); 127 printf ("%8u) %s %s\n", 4, ACPI_SIG_FACS, "Firmware ACPI Control Structure"); 128 printf ("%8u) %s %s\n", 5, ACPI_RSDP_NAME, "Root System Description Pointer"); 129 130 /* All data tables with common table header */ 131 132 for (TableData = AcpiDmTableData; TableData->Signature; TableData++) 133 { 134 printf ("%8u) %s %s\n", i, TableData->Signature, TableData->Name); 135 i++; 136 } 137 } 138 139 140 /******************************************************************************* 141 * 142 * FUNCTION: AcpiPsDisplayConstantOpcodes 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 - 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 stored 308 * 309 * RETURN: Ascii hex byte is stored in Buffer. 310 * 311 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 312 * with "0x" 313 * 314 ******************************************************************************/ 315 316 void 317 UtConvertByteToHex ( 318 UINT8 RawByte, 319 UINT8 *Buffer) 320 { 321 322 Buffer[0] = '0'; 323 Buffer[1] = 'x'; 324 325 Buffer[2] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 326 Buffer[3] = (UINT8) AslHexLookup[RawByte & 0xF]; 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: UtConvertByteToAsmHex 333 * 334 * PARAMETERS: RawByte - Binary data 335 * Buffer - Pointer to where the hex bytes will be stored 336 * 337 * RETURN: Ascii hex byte is stored in Buffer. 338 * 339 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 340 * with "0x" 341 * 342 ******************************************************************************/ 343 344 void 345 UtConvertByteToAsmHex ( 346 UINT8 RawByte, 347 UINT8 *Buffer) 348 { 349 350 Buffer[0] = '0'; 351 Buffer[1] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 352 Buffer[2] = (UINT8) AslHexLookup[RawByte & 0xF]; 353 Buffer[3] = 'h'; 354 } 355 356 357 /******************************************************************************* 358 * 359 * FUNCTION: DbgPrint 360 * 361 * PARAMETERS: Type - Type of output 362 * Fmt - Printf format string 363 * ... - variable printf list 364 * 365 * RETURN: None 366 * 367 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 368 * debug flag is set. 369 * 370 ******************************************************************************/ 371 372 void 373 DbgPrint ( 374 UINT32 Type, 375 char *Fmt, 376 ...) 377 { 378 va_list Args; 379 380 381 va_start (Args, Fmt); 382 383 if (!Gbl_DebugFlag) 384 { 385 return; 386 } 387 388 if ((Type == ASL_PARSE_OUTPUT) && 389 (!(AslCompilerdebug))) 390 { 391 return; 392 } 393 394 (void) vfprintf (stderr, Fmt, Args); 395 va_end (Args); 396 return; 397 } 398 399 400 /******************************************************************************* 401 * 402 * FUNCTION: UtPrintFormattedName 403 * 404 * PARAMETERS: ParseOpcode - Parser keyword ID 405 * Level - Indentation level 406 * 407 * RETURN: None 408 * 409 * DESCRIPTION: Print the ascii name of the parse opcode. 410 * 411 ******************************************************************************/ 412 413 #define TEXT_OFFSET 10 414 415 void 416 UtPrintFormattedName ( 417 UINT16 ParseOpcode, 418 UINT32 Level) 419 { 420 421 if (Level) 422 { 423 DbgPrint (ASL_TREE_OUTPUT, 424 "%*s", (3 * Level), " "); 425 } 426 DbgPrint (ASL_TREE_OUTPUT, 427 " %-20.20s", UtGetOpName (ParseOpcode)); 428 429 if (Level < TEXT_OFFSET) 430 { 431 DbgPrint (ASL_TREE_OUTPUT, 432 "%*s", (TEXT_OFFSET - Level) * 3, " "); 433 } 434 } 435 436 437 /******************************************************************************* 438 * 439 * FUNCTION: UtSetParseOpName 440 * 441 * PARAMETERS: Op 442 * 443 * RETURN: None 444 * 445 * DESCRIPTION: Insert the ascii name of the parse opcode 446 * 447 ******************************************************************************/ 448 449 void 450 UtSetParseOpName ( 451 ACPI_PARSE_OBJECT *Op) 452 { 453 454 strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 455 ACPI_MAX_PARSEOP_NAME); 456 } 457 458 459 /******************************************************************************* 460 * 461 * FUNCTION: UtDisplaySummary 462 * 463 * PARAMETERS: FileID - ID of outpout file 464 * 465 * RETURN: None 466 * 467 * DESCRIPTION: Display compilation statistics 468 * 469 ******************************************************************************/ 470 471 void 472 UtDisplaySummary ( 473 UINT32 FileId) 474 { 475 UINT32 i; 476 477 478 if (FileId != ASL_FILE_STDOUT) 479 { 480 /* Compiler name and version number */ 481 482 FlPrintFile (FileId, "%s version %X%s\n\n", 483 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH); 484 } 485 486 /* Summary of main input and output files */ 487 488 if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 489 { 490 FlPrintFile (FileId, 491 "%-14s %s - %u lines, %u bytes, %u fields\n", 492 "Table Input:", 493 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 494 Gbl_InputByteCount, Gbl_InputFieldCount); 495 496 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 497 { 498 FlPrintFile (FileId, 499 "%-14s %s - %u bytes\n", 500 "Binary Output:", 501 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength); 502 } 503 } 504 else 505 { 506 FlPrintFile (FileId, 507 "%-14s %s - %u lines, %u bytes, %u keywords\n", 508 "ASL Input:", 509 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 510 Gbl_InputByteCount, TotalKeywords); 511 512 /* AML summary */ 513 514 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 515 { 516 FlPrintFile (FileId, 517 "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n", 518 "AML Output:", 519 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength, 520 TotalNamedObjects, TotalExecutableOpcodes); 521 } 522 } 523 524 /* Display summary of any optional files */ 525 526 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++) 527 { 528 if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle) 529 { 530 continue; 531 } 532 533 /* .SRC is a temp file unless specifically requested */ 534 535 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag)) 536 { 537 continue; 538 } 539 540 /* .I is a temp file unless specifically requested */ 541 542 if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag)) 543 { 544 continue; 545 } 546 547 FlPrintFile (FileId, "%14s %s - %u bytes\n", 548 AslFileTypeNames [i], 549 Gbl_Files[i].Filename, FlGetFileSize (i)); 550 } 551 552 /* Error summary */ 553 554 FlPrintFile (FileId, 555 "\nCompilation complete. %u Errors, %u Warnings, %u Remarks", 556 Gbl_ExceptionCount[ASL_ERROR], 557 Gbl_ExceptionCount[ASL_WARNING] + 558 Gbl_ExceptionCount[ASL_WARNING2] + 559 Gbl_ExceptionCount[ASL_WARNING3], 560 Gbl_ExceptionCount[ASL_REMARK]); 561 562 if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 563 { 564 FlPrintFile (FileId, 565 ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]); 566 } 567 568 FlPrintFile (FileId, "\n"); 569 } 570 571 572 /******************************************************************************* 573 * 574 * FUNCTION: UtDisplaySummary 575 * 576 * PARAMETERS: Op - Integer parse node 577 * LowValue - Smallest allowed value 578 * HighValue - Largest allowed value 579 * 580 * RETURN: Op if OK, otherwise NULL 581 * 582 * DESCRIPTION: Check integer for an allowable range 583 * 584 ******************************************************************************/ 585 586 ACPI_PARSE_OBJECT * 587 UtCheckIntegerRange ( 588 ACPI_PARSE_OBJECT *Op, 589 UINT32 LowValue, 590 UINT32 HighValue) 591 { 592 char *ParseError = NULL; 593 char Buffer[64]; 594 595 596 if (!Op) 597 { 598 return NULL; 599 } 600 601 if (Op->Asl.Value.Integer < LowValue) 602 { 603 ParseError = "Value below valid range"; 604 Op->Asl.Value.Integer = LowValue; 605 } 606 607 if (Op->Asl.Value.Integer > HighValue) 608 { 609 ParseError = "Value above valid range"; 610 Op->Asl.Value.Integer = HighValue; 611 } 612 613 if (ParseError) 614 { 615 sprintf (Buffer, "%s 0x%X-0x%X", ParseError, LowValue, HighValue); 616 AslCompilererror (Buffer); 617 618 return NULL; 619 } 620 621 return Op; 622 } 623 624 625 /******************************************************************************* 626 * 627 * FUNCTION: UtGetStringBuffer 628 * 629 * PARAMETERS: Length - Size of buffer requested 630 * 631 * RETURN: Pointer to the buffer. Aborts on allocation failure 632 * 633 * DESCRIPTION: Allocate a string buffer. Bypass the local 634 * dynamic memory manager for performance reasons (This has a 635 * major impact on the speed of the compiler.) 636 * 637 ******************************************************************************/ 638 639 char * 640 UtGetStringBuffer ( 641 UINT32 Length) 642 { 643 char *Buffer; 644 645 646 if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) 647 { 648 Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length); 649 Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE + 650 Length; 651 } 652 653 Buffer = Gbl_StringCacheNext; 654 Gbl_StringCacheNext += Length; 655 656 return (Buffer); 657 } 658 659 660 /******************************************************************************* 661 * 662 * FUNCTION: UtInternalizeName 663 * 664 * PARAMETERS: ExternalName - Name to convert 665 * ConvertedName - Where the converted name is returned 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name 670 * 671 ******************************************************************************/ 672 673 ACPI_STATUS 674 UtInternalizeName ( 675 char *ExternalName, 676 char **ConvertedName) 677 { 678 ACPI_NAMESTRING_INFO Info; 679 ACPI_STATUS Status; 680 681 682 if (!ExternalName) 683 { 684 return (AE_OK); 685 } 686 687 /* Get the length of the new internal name */ 688 689 Info.ExternalName = ExternalName; 690 AcpiNsGetInternalNameLength (&Info); 691 692 /* We need a segment to store the internal name */ 693 694 Info.InternalName = UtGetStringBuffer (Info.Length); 695 if (!Info.InternalName) 696 { 697 return (AE_NO_MEMORY); 698 } 699 700 /* Build the name */ 701 702 Status = AcpiNsBuildInternalName (&Info); 703 if (ACPI_FAILURE (Status)) 704 { 705 return (Status); 706 } 707 708 *ConvertedName = Info.InternalName; 709 return (AE_OK); 710 } 711 712 713 /******************************************************************************* 714 * 715 * FUNCTION: UtPadNameWithUnderscores 716 * 717 * PARAMETERS: NameSeg - Input nameseg 718 * PaddedNameSeg - Output padded nameseg 719 * 720 * RETURN: Padded nameseg. 721 * 722 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full 723 * ACPI_NAME. 724 * 725 ******************************************************************************/ 726 727 static void 728 UtPadNameWithUnderscores ( 729 char *NameSeg, 730 char *PaddedNameSeg) 731 { 732 UINT32 i; 733 734 735 for (i = 0; (i < ACPI_NAME_SIZE); i++) 736 { 737 if (*NameSeg) 738 { 739 *PaddedNameSeg = *NameSeg; 740 NameSeg++; 741 } 742 else 743 { 744 *PaddedNameSeg = '_'; 745 } 746 PaddedNameSeg++; 747 } 748 } 749 750 751 /******************************************************************************* 752 * 753 * FUNCTION: UtAttachNameseg 754 * 755 * PARAMETERS: Op - Parent parse node 756 * Name - Full ExternalName 757 * 758 * RETURN: None; Sets the NameSeg field in parent node 759 * 760 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it 761 * in the NameSeg field of the Op. 762 * 763 ******************************************************************************/ 764 765 static void 766 UtAttachNameseg ( 767 ACPI_PARSE_OBJECT *Op, 768 char *Name) 769 { 770 char *NameSeg; 771 char PaddedNameSeg[4]; 772 773 774 if (!Name) 775 { 776 return; 777 } 778 779 /* Look for the last dot in the namepath */ 780 781 NameSeg = strrchr (Name, '.'); 782 if (NameSeg) 783 { 784 /* Found last dot, we have also found the final nameseg */ 785 786 NameSeg++; 787 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg); 788 } 789 else 790 { 791 /* No dots in the namepath, there is only a single nameseg. */ 792 /* Handle prefixes */ 793 794 while ((*Name == '\\') || (*Name == '^')) 795 { 796 Name++; 797 } 798 799 /* Remaing string should be one single nameseg */ 800 801 UtPadNameWithUnderscores (Name, PaddedNameSeg); 802 } 803 804 strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4); 805 } 806 807 808 /******************************************************************************* 809 * 810 * FUNCTION: UtAttachNamepathToOwner 811 * 812 * PARAMETERS: Op - Parent parse node 813 * NameOp - Node that contains the name 814 * 815 * RETURN: Sets the ExternalName and Namepath in the parent node 816 * 817 * DESCRIPTION: Store the name in two forms in the parent node: The original 818 * (external) name, and the internalized name that is used within 819 * the ACPI namespace manager. 820 * 821 ******************************************************************************/ 822 823 void 824 UtAttachNamepathToOwner ( 825 ACPI_PARSE_OBJECT *Op, 826 ACPI_PARSE_OBJECT *NameOp) 827 { 828 ACPI_STATUS Status; 829 830 831 /* Full external path */ 832 833 Op->Asl.ExternalName = NameOp->Asl.Value.String; 834 835 /* Save the NameOp for possible error reporting later */ 836 837 Op->Asl.ParentMethod = (void *) NameOp; 838 839 /* Last nameseg of the path */ 840 841 UtAttachNameseg (Op, Op->Asl.ExternalName); 842 843 /* Create internalized path */ 844 845 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 846 if (ACPI_FAILURE (Status)) 847 { 848 /* TBD: abort on no memory */ 849 } 850 } 851 852 853 /******************************************************************************* 854 * 855 * FUNCTION: UtDoConstant 856 * 857 * PARAMETERS: String - Hex, Octal, or Decimal string 858 * 859 * RETURN: Converted Integer 860 * 861 * DESCRIPTION: Convert a string to an integer. With error checking. 862 * 863 ******************************************************************************/ 864 865 UINT64 866 UtDoConstant ( 867 char *String) 868 { 869 ACPI_STATUS Status; 870 UINT64 Converted; 871 char ErrBuf[64]; 872 873 874 Status = UtStrtoul64 (String, 0, &Converted); 875 if (ACPI_FAILURE (Status)) 876 { 877 sprintf (ErrBuf, "%s %s\n", "Conversion error:", 878 AcpiFormatException (Status)); 879 AslCompilererror (ErrBuf); 880 } 881 882 return (Converted); 883 } 884 885 886 /* TBD: use version in ACPI CA main code base? */ 887 888 /******************************************************************************* 889 * 890 * FUNCTION: UtStrtoul64 891 * 892 * PARAMETERS: String - Null terminated string 893 * Terminater - Where a pointer to the terminating byte is 894 * returned 895 * Base - Radix of the string 896 * 897 * RETURN: Converted value 898 * 899 * DESCRIPTION: Convert a string into an unsigned value. 900 * 901 ******************************************************************************/ 902 903 ACPI_STATUS 904 UtStrtoul64 ( 905 char *String, 906 UINT32 Base, 907 UINT64 *RetInteger) 908 { 909 UINT32 Index; 910 UINT32 Sign; 911 UINT64 ReturnValue = 0; 912 ACPI_STATUS Status = AE_OK; 913 914 915 *RetInteger = 0; 916 917 switch (Base) 918 { 919 case 0: 920 case 8: 921 case 10: 922 case 16: 923 break; 924 925 default: 926 /* 927 * The specified Base parameter is not in the domain of 928 * this function: 929 */ 930 return (AE_BAD_PARAMETER); 931 } 932 933 /* Skip over any white space in the buffer: */ 934 935 while (isspace ((int) *String) || *String == '\t') 936 { 937 ++String; 938 } 939 940 /* 941 * The buffer may contain an optional plus or minus sign. 942 * If it does, then skip over it but remember what is was: 943 */ 944 if (*String == '-') 945 { 946 Sign = NEGATIVE; 947 ++String; 948 } 949 else if (*String == '+') 950 { 951 ++String; 952 Sign = POSITIVE; 953 } 954 else 955 { 956 Sign = POSITIVE; 957 } 958 959 /* 960 * If the input parameter Base is zero, then we need to 961 * determine if it is octal, decimal, or hexadecimal: 962 */ 963 if (Base == 0) 964 { 965 if (*String == '0') 966 { 967 if (tolower ((int) *(++String)) == 'x') 968 { 969 Base = 16; 970 ++String; 971 } 972 else 973 { 974 Base = 8; 975 } 976 } 977 else 978 { 979 Base = 10; 980 } 981 } 982 983 /* 984 * For octal and hexadecimal bases, skip over the leading 985 * 0 or 0x, if they are present. 986 */ 987 if (Base == 8 && *String == '0') 988 { 989 String++; 990 } 991 992 if (Base == 16 && 993 *String == '0' && 994 tolower ((int) *(++String)) == 'x') 995 { 996 String++; 997 } 998 999 /* Main loop: convert the string to an unsigned long */ 1000 1001 while (*String) 1002 { 1003 if (isdigit ((int) *String)) 1004 { 1005 Index = ((UINT8) *String) - '0'; 1006 } 1007 else 1008 { 1009 Index = (UINT8) toupper ((int) *String); 1010 if (isupper ((int) Index)) 1011 { 1012 Index = Index - 'A' + 10; 1013 } 1014 else 1015 { 1016 goto ErrorExit; 1017 } 1018 } 1019 1020 if (Index >= Base) 1021 { 1022 goto ErrorExit; 1023 } 1024 1025 /* Check to see if value is out of range: */ 1026 1027 if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 1028 (UINT64) Base)) 1029 { 1030 goto ErrorExit; 1031 } 1032 else 1033 { 1034 ReturnValue *= Base; 1035 ReturnValue += Index; 1036 } 1037 1038 ++String; 1039 } 1040 1041 1042 /* If a minus sign was present, then "the conversion is negated": */ 1043 1044 if (Sign == NEGATIVE) 1045 { 1046 ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 1047 } 1048 1049 *RetInteger = ReturnValue; 1050 return (Status); 1051 1052 1053 ErrorExit: 1054 switch (Base) 1055 { 1056 case 8: 1057 Status = AE_BAD_OCTAL_CONSTANT; 1058 break; 1059 1060 case 10: 1061 Status = AE_BAD_DECIMAL_CONSTANT; 1062 break; 1063 1064 case 16: 1065 Status = AE_BAD_HEX_CONSTANT; 1066 break; 1067 1068 default: 1069 /* Base validated above */ 1070 break; 1071 } 1072 1073 return (Status); 1074 } 1075 1076 1077