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