1 /****************************************************************************** 2 * 3 * Module Name: aslutils -- compiler utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #include "acdisasm.h" 47 #include "acnamesp.h" 48 #include "amlcode.h" 49 #include "acapps.h" 50 #include <sys/stat.h> 51 52 53 #define _COMPONENT ACPI_COMPILER 54 ACPI_MODULE_NAME ("aslutils") 55 56 57 /* Local prototypes */ 58 59 static void 60 UtPadNameWithUnderscores ( 61 char *NameSeg, 62 char *PaddedNameSeg); 63 64 static void 65 UtAttachNameseg ( 66 ACPI_PARSE_OBJECT *Op, 67 char *Name); 68 69 static void 70 UtDisplayErrorSummary ( 71 UINT32 FileId); 72 73 74 /******************************************************************************* 75 * 76 * FUNCTION: UtIsBigEndianMachine 77 * 78 * PARAMETERS: None 79 * 80 * RETURN: TRUE if machine is big endian 81 * FALSE if machine is little endian 82 * 83 * DESCRIPTION: Detect whether machine is little endian or big endian. 84 * 85 ******************************************************************************/ 86 87 UINT8 88 UtIsBigEndianMachine ( 89 void) 90 { 91 union { 92 UINT32 Integer; 93 UINT8 Bytes[4]; 94 } Overlay = {0xFF000000}; 95 96 97 return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */ 98 } 99 100 101 /****************************************************************************** 102 * 103 * FUNCTION: UtQueryForOverwrite 104 * 105 * PARAMETERS: Pathname - Output filename 106 * 107 * RETURN: TRUE if file does not exist or overwrite is authorized 108 * 109 * DESCRIPTION: Query for file overwrite if it already exists. 110 * 111 ******************************************************************************/ 112 113 BOOLEAN 114 UtQueryForOverwrite ( 115 char *Pathname) 116 { 117 struct stat StatInfo; 118 int InChar; 119 120 121 if (!stat (Pathname, &StatInfo)) 122 { 123 fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ", 124 Pathname); 125 126 InChar = fgetc (stdin); 127 if (InChar == '\n') 128 { 129 InChar = fgetc (stdin); 130 } 131 132 if ((InChar != 'y') && (InChar != 'Y')) 133 { 134 return (FALSE); 135 } 136 } 137 138 return (TRUE); 139 } 140 141 142 /******************************************************************************* 143 * 144 * FUNCTION: UtNodeIsDescendantOf 145 * 146 * PARAMETERS: Node1 - Child node 147 * Node2 - Possible parent node 148 * 149 * RETURN: Boolean 150 * 151 * DESCRIPTION: Returns TRUE if Node1 is a descendant of Node2. Otherwise, 152 * return FALSE. Note, we assume a NULL Node2 element to be the 153 * topmost (root) scope. All nodes are descendants of the root. 154 * Note: Nodes at the same level (siblings) are not considered 155 * descendants. 156 * 157 ******************************************************************************/ 158 159 BOOLEAN 160 UtNodeIsDescendantOf ( 161 ACPI_NAMESPACE_NODE *Node1, 162 ACPI_NAMESPACE_NODE *Node2) 163 { 164 165 if (Node1 == Node2) 166 { 167 return (FALSE); 168 } 169 170 if (!Node2) 171 { 172 return (TRUE); /* All nodes descend from the root */ 173 } 174 175 /* Walk upward until the root is reached or parent is found */ 176 177 while (Node1) 178 { 179 if (Node1 == Node2) 180 { 181 return (TRUE); 182 } 183 184 Node1 = Node1->Parent; 185 } 186 187 return (FALSE); 188 } 189 190 191 /******************************************************************************* 192 * 193 * FUNCTION: UtGetParentMethodNode 194 * 195 * PARAMETERS: Node - Namespace node for any object 196 * 197 * RETURN: Namespace node for the parent method 198 * NULL - object is not within a method 199 * 200 * DESCRIPTION: Find the parent (owning) method node for a namespace object 201 * 202 ******************************************************************************/ 203 204 ACPI_NAMESPACE_NODE * 205 UtGetParentMethodNode ( 206 ACPI_NAMESPACE_NODE *Node) 207 { 208 ACPI_NAMESPACE_NODE *ParentNode; 209 210 211 if (!Node) 212 { 213 return (NULL); 214 } 215 216 /* Walk upward until a method is found, or the root is reached */ 217 218 ParentNode = Node->Parent; 219 while (ParentNode) 220 { 221 if (ParentNode->Type == ACPI_TYPE_METHOD) 222 { 223 return (ParentNode); 224 } 225 226 ParentNode = ParentNode->Parent; 227 } 228 229 return (NULL); /* Object is not within a control method */ 230 } 231 232 233 /******************************************************************************* 234 * 235 * FUNCTION: UtGetParentMethodOp 236 * 237 * PARAMETERS: Op - Parse Op to be checked 238 * 239 * RETURN: Control method Op if found. NULL otherwise 240 * 241 * DESCRIPTION: Find the control method parent of a parse op. Returns NULL if 242 * the input Op is not within a control method. 243 * 244 ******************************************************************************/ 245 246 ACPI_PARSE_OBJECT * 247 UtGetParentMethodOp ( 248 ACPI_PARSE_OBJECT *Op) 249 { 250 ACPI_PARSE_OBJECT *NextOp; 251 252 253 NextOp = Op->Asl.Parent; 254 while (NextOp) 255 { 256 if (NextOp->Asl.AmlOpcode == AML_METHOD_OP) 257 { 258 return (NextOp); 259 } 260 261 NextOp = NextOp->Asl.Parent; 262 } 263 264 return (NULL); /* No parent method found */ 265 } 266 267 268 /******************************************************************************* 269 * 270 * FUNCTION: UtDisplaySupportedTables 271 * 272 * PARAMETERS: None 273 * 274 * RETURN: None 275 * 276 * DESCRIPTION: Print all supported ACPI table names. 277 * 278 ******************************************************************************/ 279 280 void 281 UtDisplaySupportedTables ( 282 void) 283 { 284 const AH_TABLE *TableData; 285 UINT32 i; 286 287 288 printf ("\nACPI tables supported by iASL version %8.8X:\n" 289 " (Compiler, Disassembler, Template Generator)\n\n", 290 ACPI_CA_VERSION); 291 292 /* All ACPI tables with the common table header */ 293 294 printf ("\n Supported ACPI tables:\n"); 295 for (TableData = AcpiGbl_SupportedTables, i = 1; 296 TableData->Signature; TableData++, i++) 297 { 298 printf ("%8u) %s %s\n", i, 299 TableData->Signature, TableData->Description); 300 } 301 } 302 303 304 /******************************************************************************* 305 * 306 * FUNCTION: UtDisplayConstantOpcodes 307 * 308 * PARAMETERS: None 309 * 310 * RETURN: None 311 * 312 * DESCRIPTION: Print AML opcodes that can be used in constant expressions. 313 * 314 ******************************************************************************/ 315 316 void 317 UtDisplayConstantOpcodes ( 318 void) 319 { 320 UINT32 i; 321 322 323 printf ("Constant expression opcode information\n\n"); 324 325 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++) 326 { 327 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT) 328 { 329 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name); 330 } 331 } 332 } 333 334 335 /******************************************************************************* 336 * 337 * FUNCTION: UtBeginEvent 338 * 339 * PARAMETERS: Name - Ascii name of this event 340 * 341 * RETURN: Event number (integer index) 342 * 343 * DESCRIPTION: Saves the current time with this event 344 * 345 ******************************************************************************/ 346 347 UINT8 348 UtBeginEvent ( 349 char *Name) 350 { 351 352 if (AslGbl_NextEvent >= ASL_NUM_EVENTS) 353 { 354 AcpiOsPrintf ("Ran out of compiler event structs!\n"); 355 return (AslGbl_NextEvent); 356 } 357 358 /* Init event with current (start) time */ 359 360 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer (); 361 AslGbl_Events[AslGbl_NextEvent].EventName = Name; 362 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE; 363 return (AslGbl_NextEvent++); 364 } 365 366 367 /******************************************************************************* 368 * 369 * FUNCTION: UtEndEvent 370 * 371 * PARAMETERS: Event - Event number (integer index) 372 * 373 * RETURN: None 374 * 375 * DESCRIPTION: Saves the current time (end time) with this event 376 * 377 ******************************************************************************/ 378 379 void 380 UtEndEvent ( 381 UINT8 Event) 382 { 383 384 if (Event >= ASL_NUM_EVENTS) 385 { 386 return; 387 } 388 389 /* Insert end time for event */ 390 391 AslGbl_Events[Event].EndTime = AcpiOsGetTimer (); 392 } 393 394 395 /******************************************************************************* 396 * 397 * FUNCTION: DbgPrint 398 * 399 * PARAMETERS: Type - Type of output 400 * Fmt - Printf format string 401 * ... - variable printf list 402 * 403 * RETURN: None 404 * 405 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 406 * debug flag is set. 407 * 408 ******************************************************************************/ 409 410 void 411 DbgPrint ( 412 UINT32 Type, 413 char *Fmt, 414 ...) 415 { 416 va_list Args; 417 418 419 if (!AslGbl_DebugFlag) 420 { 421 return; 422 } 423 424 if ((Type == ASL_PARSE_OUTPUT) && 425 (!(AslCompilerdebug))) 426 { 427 return; 428 } 429 430 va_start (Args, Fmt); 431 (void) vfprintf (stderr, Fmt, Args); 432 va_end (Args); 433 return; 434 } 435 436 437 /******************************************************************************* 438 * 439 * FUNCTION: UtSetParseOpName 440 * 441 * PARAMETERS: Op - Parse op to be named. 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 AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 455 ACPI_MAX_PARSEOP_NAME); 456 } 457 458 459 /******************************************************************************* 460 * 461 * FUNCTION: UtDisplayOneSummary 462 * 463 * PARAMETERS: FileID - ID of outpout file 464 * 465 * RETURN: None 466 * 467 * DESCRIPTION: Display compilation statistics for one input file 468 * 469 ******************************************************************************/ 470 471 void 472 UtDisplayOneSummary ( 473 UINT32 FileId, 474 BOOLEAN DisplayErrorSummary) 475 { 476 UINT32 i; 477 ASL_GLOBAL_FILE_NODE *FileNode; 478 BOOLEAN DisplayAMLSummary; 479 480 481 DisplayAMLSummary = 482 !AslGbl_PreprocessOnly && !AslGbl_ParserErrorDetected && 483 ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || AslGbl_IgnoreErrors) && 484 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle; 485 486 if (FileId != ASL_FILE_STDOUT) 487 { 488 /* Compiler name and version number */ 489 490 FlPrintFile (FileId, "%s version %X [%s]\n\n", 491 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, "2017-01-19"); 492 } 493 494 /* Summary of main input and output files */ 495 496 FileNode = FlGetCurrentFileNode (); 497 498 if (FileNode->ParserErrorDetected) 499 { 500 FlPrintFile (FileId, 501 "%-14s %s - Compilation aborted due to parser-detected syntax error(s)\n", 502 "Input file:", AslGbl_Files[ASL_FILE_INPUT].Filename); 503 } 504 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_DATA) 505 { 506 FlPrintFile (FileId, 507 "%-14s %s - %7u bytes %6u fields %8u source lines\n", 508 "Table Input:", 509 AslGbl_Files[ASL_FILE_INPUT].Filename, 510 FileNode->OriginalInputFileSize, FileNode->TotalFields, 511 FileNode->TotalLineCount); 512 513 FlPrintFile (FileId, 514 "%-14s %s - %7u bytes\n", 515 "Binary Output:", 516 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, FileNode->OutputByteLength); 517 } 518 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_ASL) 519 { 520 FlPrintFile (FileId, 521 "%-14s %s - %7u bytes %6u keywords %6u source lines\n", 522 "ASL Input:", 523 AslGbl_Files[ASL_FILE_INPUT].Filename, 524 FileNode->OriginalInputFileSize, 525 FileNode->TotalKeywords, 526 FileNode->TotalLineCount); 527 528 /* AML summary */ 529 530 if (DisplayAMLSummary) 531 { 532 FlPrintFile (FileId, 533 "%-14s %s - %7u bytes %6u opcodes %6u named objects\n", 534 "AML Output:", 535 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, 536 FlGetFileSize (ASL_FILE_AML_OUTPUT), 537 FileNode->TotalExecutableOpcodes, 538 FileNode->TotalNamedObjects); 539 } 540 } 541 542 /* Display summary of any optional files */ 543 544 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++) 545 { 546 if (!AslGbl_Files[i].Filename || !AslGbl_Files[i].Handle) 547 { 548 continue; 549 } 550 551 /* .SRC is a temp file unless specifically requested */ 552 553 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!AslGbl_SourceOutputFlag)) 554 { 555 continue; 556 } 557 558 /* .PRE is the preprocessor intermediate file */ 559 560 if ((i == ASL_FILE_PREPROCESSOR) && (!AslGbl_KeepPreprocessorTempFile)) 561 { 562 continue; 563 } 564 565 FlPrintFile (FileId, "%-14s %s - %7u bytes\n", 566 AslGbl_FileDescs[i].ShortDescription, 567 AslGbl_Files[i].Filename, FlGetFileSize (i)); 568 } 569 570 571 /* 572 * Optionally emit an error summary for a file. This is used to enhance the 573 * appearance of listing files. 574 */ 575 if (DisplayErrorSummary) 576 { 577 UtDisplayErrorSummary (FileId); 578 } 579 } 580 581 582 /******************************************************************************* 583 * 584 * FUNCTION: UtDisplayErrorSummary 585 * 586 * PARAMETERS: FileID - ID of outpout file 587 * 588 * RETURN: None 589 * 590 * DESCRIPTION: Display compilation statistics for all input files 591 * 592 ******************************************************************************/ 593 594 static void 595 UtDisplayErrorSummary ( 596 UINT32 FileId) 597 { 598 BOOLEAN ErrorDetected; 599 600 601 ErrorDetected = AslGbl_ParserErrorDetected || 602 ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && !AslGbl_IgnoreErrors); 603 604 if (ErrorDetected) 605 { 606 FlPrintFile (FileId, "\nCompilation failed. "); 607 } 608 else 609 { 610 FlPrintFile (FileId, "\nCompilation successful. "); 611 } 612 613 FlPrintFile (FileId, 614 "%u Errors, %u Warnings, %u Remarks", 615 AslGbl_ExceptionCount[ASL_ERROR], 616 AslGbl_ExceptionCount[ASL_WARNING] + 617 AslGbl_ExceptionCount[ASL_WARNING2] + 618 AslGbl_ExceptionCount[ASL_WARNING3], 619 AslGbl_ExceptionCount[ASL_REMARK]); 620 621 if (AslGbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 622 { 623 if (AslGbl_ParserErrorDetected) 624 { 625 FlPrintFile (FileId, 626 "\nNo AML files were generated due to syntax error(s)\n"); 627 return; 628 } 629 else if (ErrorDetected) 630 { 631 FlPrintFile (FileId, 632 "\nNo AML files were generated due to compiler error(s)\n"); 633 return; 634 } 635 636 FlPrintFile (FileId, ", %u Optimizations", 637 AslGbl_ExceptionCount[ASL_OPTIMIZATION]); 638 639 if (AslGbl_TotalFolds) 640 { 641 FlPrintFile (FileId, ", %u Constants Folded", AslGbl_TotalFolds); 642 } 643 } 644 645 FlPrintFile (FileId, "\n"); 646 } 647 648 649 /******************************************************************************* 650 * 651 * FUNCTION: UtDisplaySummary 652 * 653 * PARAMETERS: FileID - ID of outpout file 654 * 655 * RETURN: None 656 * 657 * DESCRIPTION: Display compilation statistics for all input files 658 * 659 ******************************************************************************/ 660 661 void 662 UtDisplaySummary ( 663 UINT32 FileId) 664 { 665 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 666 667 668 while (Current) 669 { 670 switch (FlSwitchFileSet(Current->Files[ASL_FILE_INPUT].Filename)) 671 { 672 case SWITCH_TO_SAME_FILE: 673 case SWITCH_TO_DIFFERENT_FILE: 674 675 UtDisplayOneSummary (FileId, FALSE); 676 Current = Current->Next; 677 break; 678 679 case FILE_NOT_FOUND: 680 default: 681 682 Current = NULL; 683 break; 684 } 685 } 686 UtDisplayErrorSummary (FileId); 687 } 688 689 /******************************************************************************* 690 * 691 * FUNCTION: UtCheckIntegerRange 692 * 693 * PARAMETERS: Op - Integer parse node 694 * LowValue - Smallest allowed value 695 * HighValue - Largest allowed value 696 * 697 * RETURN: Op if OK, otherwise NULL 698 * 699 * DESCRIPTION: Check integer for an allowable range 700 * 701 ******************************************************************************/ 702 703 ACPI_PARSE_OBJECT * 704 UtCheckIntegerRange ( 705 ACPI_PARSE_OBJECT *Op, 706 UINT32 LowValue, 707 UINT32 HighValue) 708 { 709 710 if (!Op) 711 { 712 return (NULL); 713 } 714 715 if ((Op->Asl.Value.Integer < LowValue) || 716 (Op->Asl.Value.Integer > HighValue)) 717 { 718 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "0x%X, allowable: 0x%X-0x%X", 719 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue); 720 721 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, AslGbl_MsgBuffer); 722 return (NULL); 723 } 724 725 return (Op); 726 } 727 728 729 /******************************************************************************* 730 * 731 * FUNCTION: UtInternalizeName 732 * 733 * PARAMETERS: ExternalName - Name to convert 734 * ConvertedName - Where the converted name is returned 735 * 736 * RETURN: Status 737 * 738 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name 739 * 740 ******************************************************************************/ 741 742 ACPI_STATUS 743 UtInternalizeName ( 744 char *ExternalName, 745 char **ConvertedName) 746 { 747 ACPI_NAMESTRING_INFO Info; 748 ACPI_STATUS Status; 749 750 751 if (!ExternalName) 752 { 753 return (AE_OK); 754 } 755 756 /* Get the length of the new internal name */ 757 758 Info.ExternalName = ExternalName; 759 AcpiNsGetInternalNameLength (&Info); 760 761 /* We need a segment to store the internal name */ 762 763 Info.InternalName = UtLocalCacheCalloc (Info.Length); 764 765 /* Build the name */ 766 767 Status = AcpiNsBuildInternalName (&Info); 768 if (ACPI_FAILURE (Status)) 769 { 770 return (Status); 771 } 772 773 *ConvertedName = Info.InternalName; 774 return (AE_OK); 775 } 776 777 778 /******************************************************************************* 779 * 780 * FUNCTION: UtPadNameWithUnderscores 781 * 782 * PARAMETERS: NameSeg - Input nameseg 783 * PaddedNameSeg - Output padded nameseg 784 * 785 * RETURN: Padded nameseg. 786 * 787 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full 788 * ACPI_NAME. 789 * 790 ******************************************************************************/ 791 792 static void 793 UtPadNameWithUnderscores ( 794 char *NameSeg, 795 char *PaddedNameSeg) 796 { 797 UINT32 i; 798 799 800 for (i = 0; (i < ACPI_NAMESEG_SIZE); i++) 801 { 802 if (*NameSeg) 803 { 804 *PaddedNameSeg = *NameSeg; 805 NameSeg++; 806 } 807 else 808 { 809 *PaddedNameSeg = '_'; 810 } 811 812 PaddedNameSeg++; 813 } 814 } 815 816 817 /******************************************************************************* 818 * 819 * FUNCTION: UtAttachNameseg 820 * 821 * PARAMETERS: Op - Parent parse node 822 * Name - Full ExternalName 823 * 824 * RETURN: None; Sets the NameSeg field in parent node 825 * 826 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it 827 * in the NameSeg field of the Op. 828 * 829 ******************************************************************************/ 830 831 static void 832 UtAttachNameseg ( 833 ACPI_PARSE_OBJECT *Op, 834 char *Name) 835 { 836 char *NameSeg; 837 char PaddedNameSeg[4]; 838 839 840 if (!Name) 841 { 842 return; 843 } 844 845 /* Look for the last dot in the namepath */ 846 847 NameSeg = strrchr (Name, '.'); 848 if (NameSeg) 849 { 850 /* Found last dot, we have also found the final nameseg */ 851 852 NameSeg++; 853 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg); 854 } 855 else 856 { 857 /* No dots in the namepath, there is only a single nameseg. */ 858 /* Handle prefixes */ 859 860 while (ACPI_IS_ROOT_PREFIX (*Name) || 861 ACPI_IS_PARENT_PREFIX (*Name)) 862 { 863 Name++; 864 } 865 866 /* Remaining string should be one single nameseg */ 867 868 UtPadNameWithUnderscores (Name, PaddedNameSeg); 869 } 870 871 ACPI_COPY_NAMESEG (Op->Asl.NameSeg, PaddedNameSeg); 872 } 873 874 875 /******************************************************************************* 876 * 877 * FUNCTION: UtAttachNamepathToOwner 878 * 879 * PARAMETERS: Op - Parent parse node 880 * NameOp - Node that contains the name 881 * 882 * RETURN: Sets the ExternalName and Namepath in the parent node 883 * 884 * DESCRIPTION: Store the name in two forms in the parent node: The original 885 * (external) name, and the internalized name that is used within 886 * the ACPI namespace manager. 887 * 888 ******************************************************************************/ 889 890 void 891 UtAttachNamepathToOwner ( 892 ACPI_PARSE_OBJECT *Op, 893 ACPI_PARSE_OBJECT *NameOp) 894 { 895 ACPI_STATUS Status; 896 897 898 /* Full external path */ 899 900 Op->Asl.ExternalName = NameOp->Asl.Value.String; 901 902 /* Save the NameOp for possible error reporting later */ 903 904 Op->Asl.ParentMethod = (void *) NameOp; 905 906 /* Last nameseg of the path */ 907 908 UtAttachNameseg (Op, Op->Asl.ExternalName); 909 910 /* Create internalized path */ 911 912 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 913 if (ACPI_FAILURE (Status)) 914 { 915 /* TBD: abort on no memory */ 916 } 917 } 918 919 920 /******************************************************************************* 921 * 922 * FUNCTION: UtNameContainsAllPrefix 923 * 924 * PARAMETERS: Op - Op containing NameString 925 * 926 * RETURN: NameString consists of all ^ characters 927 * 928 * DESCRIPTION: Determine if this Op contains a name segment that consists of 929 * all '^' characters. 930 * 931 ******************************************************************************/ 932 933 BOOLEAN 934 UtNameContainsAllPrefix ( 935 ACPI_PARSE_OBJECT *Op) 936 { 937 UINT32 Length = Op->Asl.AmlLength; 938 UINT32 i; 939 940 for (i = 0; i < Length; i++) 941 { 942 if (Op->Asl.Value.String[i] != '^') 943 { 944 return (FALSE); 945 } 946 } 947 948 return (TRUE); 949 } 950 951 /******************************************************************************* 952 * 953 * FUNCTION: UtDoConstant 954 * 955 * PARAMETERS: String - Hex/Decimal/Octal 956 * 957 * RETURN: Converted Integer 958 * 959 * DESCRIPTION: Convert a string to an integer, with overflow/error checking. 960 * 961 ******************************************************************************/ 962 963 UINT64 964 UtDoConstant ( 965 char *String) 966 { 967 ACPI_STATUS Status; 968 UINT64 ConvertedInteger; 969 char ErrBuf[64]; 970 971 972 Status = AcpiUtStrtoul64 (String, &ConvertedInteger); 973 if (ACPI_FAILURE (Status)) 974 { 975 snprintf (ErrBuf, sizeof(ErrBuf), "While creating 64-bit constant: %s\n", 976 AcpiFormatException (Status)); 977 978 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber, 979 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset, 980 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf); 981 } 982 983 return (ConvertedInteger); 984 } 985 986 987 /****************************************************************************** 988 * 989 * FUNCTION: AcpiUtStrdup 990 * 991 * PARAMETERS: String1 - string to duplicate 992 * 993 * RETURN: int that signifies string relationship. Zero means strings 994 * are equal. 995 * 996 * DESCRIPTION: Duplicate the string using UtCacheAlloc to avoid manual memory 997 * reclamation. 998 * 999 ******************************************************************************/ 1000 1001 char * 1002 AcpiUtStrdup ( 1003 char *String) 1004 { 1005 char *NewString = (char *) UtLocalCalloc (strlen (String) + 1); 1006 1007 1008 strcpy (NewString, String); 1009 return (NewString); 1010 } 1011 1012 1013 /****************************************************************************** 1014 * 1015 * FUNCTION: AcpiUtStrcat 1016 * 1017 * PARAMETERS: String1 1018 * String2 1019 * 1020 * RETURN: New string with String1 concatenated with String2 1021 * 1022 * DESCRIPTION: Concatenate string1 and string2 1023 * 1024 ******************************************************************************/ 1025 1026 char * 1027 AcpiUtStrcat ( 1028 char *String1, 1029 char *String2) 1030 { 1031 UINT32 String1Length = strlen (String1); 1032 char *NewString = (char *) UtLocalCalloc (strlen (String1) + strlen (String2) + 1); 1033 1034 strcpy (NewString, String1); 1035 strcpy (NewString + String1Length, String2); 1036 return (NewString); 1037 } 1038