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