1 /****************************************************************************** 2 * 3 * Module Name: aslutils -- compiler utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, 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 = 0x34; 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: UtGetParentMethod 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 void * 205 UtGetParentMethod ( 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: UtDisplaySupportedTables 236 * 237 * PARAMETERS: None 238 * 239 * RETURN: None 240 * 241 * DESCRIPTION: Print all supported ACPI table names. 242 * 243 ******************************************************************************/ 244 245 void 246 UtDisplaySupportedTables ( 247 void) 248 { 249 const AH_TABLE *TableData; 250 UINT32 i; 251 252 253 printf ("\nACPI tables supported by iASL version %8.8X:\n" 254 " (Compiler, Disassembler, Template Generator)\n\n", 255 ACPI_CA_VERSION); 256 257 /* All ACPI tables with the common table header */ 258 259 printf ("\n Supported ACPI tables:\n"); 260 for (TableData = AcpiGbl_SupportedTables, i = 1; 261 TableData->Signature; TableData++, i++) 262 { 263 printf ("%8u) %s %s\n", i, 264 TableData->Signature, TableData->Description); 265 } 266 } 267 268 269 /******************************************************************************* 270 * 271 * FUNCTION: UtDisplayConstantOpcodes 272 * 273 * PARAMETERS: None 274 * 275 * RETURN: None 276 * 277 * DESCRIPTION: Print AML opcodes that can be used in constant expressions. 278 * 279 ******************************************************************************/ 280 281 void 282 UtDisplayConstantOpcodes ( 283 void) 284 { 285 UINT32 i; 286 287 288 printf ("Constant expression opcode information\n\n"); 289 290 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++) 291 { 292 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT) 293 { 294 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name); 295 } 296 } 297 } 298 299 300 /******************************************************************************* 301 * 302 * FUNCTION: UtBeginEvent 303 * 304 * PARAMETERS: Name - Ascii name of this event 305 * 306 * RETURN: Event number (integer index) 307 * 308 * DESCRIPTION: Saves the current time with this event 309 * 310 ******************************************************************************/ 311 312 UINT8 313 UtBeginEvent ( 314 char *Name) 315 { 316 317 if (AslGbl_NextEvent >= ASL_NUM_EVENTS) 318 { 319 AcpiOsPrintf ("Ran out of compiler event structs!\n"); 320 return (AslGbl_NextEvent); 321 } 322 323 /* Init event with current (start) time */ 324 325 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer (); 326 AslGbl_Events[AslGbl_NextEvent].EventName = Name; 327 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE; 328 return (AslGbl_NextEvent++); 329 } 330 331 332 /******************************************************************************* 333 * 334 * FUNCTION: UtEndEvent 335 * 336 * PARAMETERS: Event - Event number (integer index) 337 * 338 * RETURN: None 339 * 340 * DESCRIPTION: Saves the current time (end time) with this event 341 * 342 ******************************************************************************/ 343 344 void 345 UtEndEvent ( 346 UINT8 Event) 347 { 348 349 if (Event >= ASL_NUM_EVENTS) 350 { 351 return; 352 } 353 354 /* Insert end time for event */ 355 356 AslGbl_Events[Event].EndTime = AcpiOsGetTimer (); 357 } 358 359 360 /******************************************************************************* 361 * 362 * FUNCTION: DbgPrint 363 * 364 * PARAMETERS: Type - Type of output 365 * Fmt - Printf format string 366 * ... - variable printf list 367 * 368 * RETURN: None 369 * 370 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 371 * debug flag is set. 372 * 373 ******************************************************************************/ 374 375 void 376 DbgPrint ( 377 UINT32 Type, 378 char *Fmt, 379 ...) 380 { 381 va_list Args; 382 383 384 if (!AslGbl_DebugFlag) 385 { 386 return; 387 } 388 389 if ((Type == ASL_PARSE_OUTPUT) && 390 (!(AslCompilerdebug))) 391 { 392 return; 393 } 394 395 va_start (Args, Fmt); 396 (void) vfprintf (stderr, Fmt, Args); 397 va_end (Args); 398 return; 399 } 400 401 402 /******************************************************************************* 403 * 404 * FUNCTION: UtSetParseOpName 405 * 406 * PARAMETERS: Op - Parse op to be named. 407 * 408 * RETURN: None 409 * 410 * DESCRIPTION: Insert the ascii name of the parse opcode 411 * 412 ******************************************************************************/ 413 414 void 415 UtSetParseOpName ( 416 ACPI_PARSE_OBJECT *Op) 417 { 418 419 AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 420 ACPI_MAX_PARSEOP_NAME); 421 } 422 423 424 /******************************************************************************* 425 * 426 * FUNCTION: UtDisplayOneSummary 427 * 428 * PARAMETERS: FileID - ID of outpout file 429 * 430 * RETURN: None 431 * 432 * DESCRIPTION: Display compilation statistics for one input file 433 * 434 ******************************************************************************/ 435 436 void 437 UtDisplayOneSummary ( 438 UINT32 FileId, 439 BOOLEAN DisplayErrorSummary) 440 { 441 UINT32 i; 442 ASL_GLOBAL_FILE_NODE *FileNode; 443 BOOLEAN DisplayAMLSummary; 444 445 446 DisplayAMLSummary = 447 !AslGbl_PreprocessOnly && !AslGbl_ParserErrorDetected && 448 ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || AslGbl_IgnoreErrors) && 449 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle; 450 451 if (FileId != ASL_FILE_STDOUT) 452 { 453 /* Compiler name and version number */ 454 455 FlPrintFile (FileId, "%s version %X [%s]\n\n", 456 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, "2017-01-19"); 457 } 458 459 /* Summary of main input and output files */ 460 461 FileNode = FlGetCurrentFileNode (); 462 if (!FileNode) 463 { 464 fprintf (stderr, "Summary could not be generated"); 465 return; 466 } 467 468 if (FileNode->ParserErrorDetected) 469 { 470 FlPrintFile (FileId, 471 "%-14s %s - Compilation aborted due to parser-detected syntax error(s)\n", 472 "Input file:", AslGbl_Files[ASL_FILE_INPUT].Filename); 473 } 474 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_DATA) 475 { 476 FlPrintFile (FileId, 477 "%-14s %s - %7u bytes %6u fields %8u source lines\n", 478 "Table Input:", 479 AslGbl_Files[ASL_FILE_INPUT].Filename, 480 FileNode->OriginalInputFileSize, FileNode->TotalFields, 481 FileNode->TotalLineCount); 482 483 FlPrintFile (FileId, 484 "%-14s %s - %7u bytes\n", 485 "Binary Output:", 486 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, FileNode->OutputByteLength); 487 } 488 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_ASL) 489 { 490 FlPrintFile (FileId, 491 "%-14s %s - %7u bytes %6u keywords %6u source lines\n", 492 "ASL Input:", 493 AslGbl_Files[ASL_FILE_INPUT].Filename, 494 FileNode->OriginalInputFileSize, 495 FileNode->TotalKeywords, 496 FileNode->TotalLineCount); 497 498 /* AML summary */ 499 500 if (DisplayAMLSummary) 501 { 502 FlPrintFile (FileId, 503 "%-14s %s - %7u bytes %6u opcodes %6u named objects\n", 504 "AML Output:", 505 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, 506 FlGetFileSize (ASL_FILE_AML_OUTPUT), 507 FileNode->TotalExecutableOpcodes, 508 FileNode->TotalNamedObjects); 509 } 510 } 511 512 /* Display summary of any optional files */ 513 514 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++) 515 { 516 if (!AslGbl_Files[i].Filename || !AslGbl_Files[i].Handle) 517 { 518 continue; 519 } 520 521 /* .SRC is a temp file unless specifically requested */ 522 523 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!AslGbl_SourceOutputFlag)) 524 { 525 continue; 526 } 527 528 /* .PRE is the preprocessor intermediate file */ 529 530 if ((i == ASL_FILE_PREPROCESSOR) && (!AslGbl_KeepPreprocessorTempFile)) 531 { 532 continue; 533 } 534 535 FlPrintFile (FileId, "%-14s %s - %7u bytes\n", 536 AslGbl_FileDescs[i].ShortDescription, 537 AslGbl_Files[i].Filename, FlGetFileSize (i)); 538 } 539 540 541 /* 542 * Optionally emit an error summary for a file. This is used to enhance the 543 * appearance of listing files. 544 */ 545 if (DisplayErrorSummary) 546 { 547 UtDisplayErrorSummary (FileId); 548 } 549 } 550 551 552 /******************************************************************************* 553 * 554 * FUNCTION: UtDisplayErrorSummary 555 * 556 * PARAMETERS: FileID - ID of outpout file 557 * 558 * RETURN: None 559 * 560 * DESCRIPTION: Display compilation statistics for all input files 561 * 562 ******************************************************************************/ 563 564 static void 565 UtDisplayErrorSummary ( 566 UINT32 FileId) 567 { 568 BOOLEAN ErrorDetected; 569 570 571 ErrorDetected = AslGbl_ParserErrorDetected || 572 ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && !AslGbl_IgnoreErrors); 573 574 if (ErrorDetected) 575 { 576 FlPrintFile (FileId, "\nCompilation failed. "); 577 } 578 else 579 { 580 FlPrintFile (FileId, "\nCompilation successful. "); 581 } 582 583 FlPrintFile (FileId, 584 "%u Errors, %u Warnings, %u Remarks", 585 AslGbl_ExceptionCount[ASL_ERROR], 586 AslGbl_ExceptionCount[ASL_WARNING] + 587 AslGbl_ExceptionCount[ASL_WARNING2] + 588 AslGbl_ExceptionCount[ASL_WARNING3], 589 AslGbl_ExceptionCount[ASL_REMARK]); 590 591 if (AslGbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 592 { 593 if (AslGbl_ParserErrorDetected) 594 { 595 FlPrintFile (FileId, 596 "\nNo AML files were generated due to syntax error(s)\n"); 597 return; 598 } 599 else if (ErrorDetected) 600 { 601 FlPrintFile (FileId, 602 "\nNo AML files were generated due to compiler error(s)\n"); 603 return; 604 } 605 606 FlPrintFile (FileId, ", %u Optimizations", 607 AslGbl_ExceptionCount[ASL_OPTIMIZATION]); 608 609 if (AslGbl_TotalFolds) 610 { 611 FlPrintFile (FileId, ", %u Constants Folded", AslGbl_TotalFolds); 612 } 613 } 614 615 FlPrintFile (FileId, "\n"); 616 } 617 618 619 /******************************************************************************* 620 * 621 * FUNCTION: UtDisplaySummary 622 * 623 * PARAMETERS: FileID - ID of outpout file 624 * 625 * RETURN: None 626 * 627 * DESCRIPTION: Display compilation statistics for all input files 628 * 629 ******************************************************************************/ 630 631 void 632 UtDisplaySummary ( 633 UINT32 FileId) 634 { 635 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 636 637 638 while (Current) 639 { 640 switch (FlSwitchFileSet(Current->Files[ASL_FILE_INPUT].Filename)) 641 { 642 case SWITCH_TO_SAME_FILE: 643 case SWITCH_TO_DIFFERENT_FILE: 644 645 UtDisplayOneSummary (FileId, FALSE); 646 Current = Current->Next; 647 break; 648 649 case FILE_NOT_FOUND: 650 default: 651 652 Current = NULL; 653 break; 654 } 655 } 656 UtDisplayErrorSummary (FileId); 657 } 658 659 /******************************************************************************* 660 * 661 * FUNCTION: UtCheckIntegerRange 662 * 663 * PARAMETERS: Op - Integer parse node 664 * LowValue - Smallest allowed value 665 * HighValue - Largest allowed value 666 * 667 * RETURN: Op if OK, otherwise NULL 668 * 669 * DESCRIPTION: Check integer for an allowable range 670 * 671 ******************************************************************************/ 672 673 ACPI_PARSE_OBJECT * 674 UtCheckIntegerRange ( 675 ACPI_PARSE_OBJECT *Op, 676 UINT32 LowValue, 677 UINT32 HighValue) 678 { 679 680 if (!Op) 681 { 682 return (NULL); 683 } 684 685 if ((Op->Asl.Value.Integer < LowValue) || 686 (Op->Asl.Value.Integer > HighValue)) 687 { 688 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "0x%X, allowable: 0x%X-0x%X", 689 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue); 690 691 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, AslGbl_MsgBuffer); 692 return (NULL); 693 } 694 695 return (Op); 696 } 697 698 699 /******************************************************************************* 700 * 701 * FUNCTION: UtInternalizeName 702 * 703 * PARAMETERS: ExternalName - Name to convert 704 * ConvertedName - Where the converted name is returned 705 * 706 * RETURN: Status 707 * 708 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name 709 * 710 ******************************************************************************/ 711 712 ACPI_STATUS 713 UtInternalizeName ( 714 char *ExternalName, 715 char **ConvertedName) 716 { 717 ACPI_NAMESTRING_INFO Info; 718 ACPI_STATUS Status; 719 720 721 if (!ExternalName) 722 { 723 return (AE_OK); 724 } 725 726 /* Get the length of the new internal name */ 727 728 Info.ExternalName = ExternalName; 729 AcpiNsGetInternalNameLength (&Info); 730 731 /* We need a segment to store the internal name */ 732 733 Info.InternalName = UtLocalCacheCalloc (Info.Length); 734 735 /* Build the name */ 736 737 Status = AcpiNsBuildInternalName (&Info); 738 if (ACPI_FAILURE (Status)) 739 { 740 return (Status); 741 } 742 743 *ConvertedName = Info.InternalName; 744 return (AE_OK); 745 } 746 747 748 /******************************************************************************* 749 * 750 * FUNCTION: UtPadNameWithUnderscores 751 * 752 * PARAMETERS: NameSeg - Input nameseg 753 * PaddedNameSeg - Output padded nameseg 754 * 755 * RETURN: Padded nameseg. 756 * 757 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full 758 * ACPI_NAME. 759 * 760 ******************************************************************************/ 761 762 static void 763 UtPadNameWithUnderscores ( 764 char *NameSeg, 765 char *PaddedNameSeg) 766 { 767 UINT32 i; 768 769 770 for (i = 0; (i < ACPI_NAMESEG_SIZE); i++) 771 { 772 if (*NameSeg) 773 { 774 *PaddedNameSeg = *NameSeg; 775 NameSeg++; 776 } 777 else 778 { 779 *PaddedNameSeg = '_'; 780 } 781 782 PaddedNameSeg++; 783 } 784 } 785 786 787 /******************************************************************************* 788 * 789 * FUNCTION: UtAttachNameseg 790 * 791 * PARAMETERS: Op - Parent parse node 792 * Name - Full ExternalName 793 * 794 * RETURN: None; Sets the NameSeg field in parent node 795 * 796 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it 797 * in the NameSeg field of the Op. 798 * 799 ******************************************************************************/ 800 801 static void 802 UtAttachNameseg ( 803 ACPI_PARSE_OBJECT *Op, 804 char *Name) 805 { 806 char *NameSeg; 807 char PaddedNameSeg[4]; 808 809 810 if (!Name) 811 { 812 return; 813 } 814 815 /* Look for the last dot in the namepath */ 816 817 NameSeg = strrchr (Name, '.'); 818 if (NameSeg) 819 { 820 /* Found last dot, we have also found the final nameseg */ 821 822 NameSeg++; 823 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg); 824 } 825 else 826 { 827 /* No dots in the namepath, there is only a single nameseg. */ 828 /* Handle prefixes */ 829 830 while (ACPI_IS_ROOT_PREFIX (*Name) || 831 ACPI_IS_PARENT_PREFIX (*Name)) 832 { 833 Name++; 834 } 835 836 /* Remaining string should be one single nameseg */ 837 838 UtPadNameWithUnderscores (Name, PaddedNameSeg); 839 } 840 841 ACPI_COPY_NAMESEG (Op->Asl.NameSeg, PaddedNameSeg); 842 } 843 844 845 /******************************************************************************* 846 * 847 * FUNCTION: UtAttachNamepathToOwner 848 * 849 * PARAMETERS: Op - Parent parse node 850 * NameOp - Node that contains the name 851 * 852 * RETURN: Sets the ExternalName and Namepath in the parent node 853 * 854 * DESCRIPTION: Store the name in two forms in the parent node: The original 855 * (external) name, and the internalized name that is used within 856 * the ACPI namespace manager. 857 * 858 ******************************************************************************/ 859 860 void 861 UtAttachNamepathToOwner ( 862 ACPI_PARSE_OBJECT *Op, 863 ACPI_PARSE_OBJECT *NameOp) 864 { 865 ACPI_STATUS Status; 866 867 868 /* Full external path */ 869 870 Op->Asl.ExternalName = NameOp->Asl.Value.String; 871 872 /* Save the NameOp for possible error reporting later */ 873 874 Op->Asl.ParentMethod = (void *) NameOp; 875 876 /* Last nameseg of the path */ 877 878 UtAttachNameseg (Op, Op->Asl.ExternalName); 879 880 /* Create internalized path */ 881 882 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 883 if (ACPI_FAILURE (Status)) 884 { 885 /* TBD: abort on no memory */ 886 } 887 } 888 889 890 /******************************************************************************* 891 * 892 * FUNCTION: UtNameContainsAllPrefix 893 * 894 * PARAMETERS: Op - Op containing NameString 895 * 896 * RETURN: NameString consists of all ^ characters 897 * 898 * DESCRIPTION: Determine if this Op contains a name segment that consists of 899 * all '^' characters. 900 * 901 ******************************************************************************/ 902 903 BOOLEAN 904 UtNameContainsAllPrefix ( 905 ACPI_PARSE_OBJECT *Op) 906 { 907 UINT32 Length = Op->Asl.AmlLength; 908 UINT32 i; 909 910 for (i = 0; i < Length; i++) 911 { 912 if (Op->Asl.Value.String[i] != '^') 913 { 914 return (FALSE); 915 } 916 } 917 918 return (TRUE); 919 } 920 921 /******************************************************************************* 922 * 923 * FUNCTION: UtDoConstant 924 * 925 * PARAMETERS: String - Hex/Decimal/Octal 926 * 927 * RETURN: Converted Integer 928 * 929 * DESCRIPTION: Convert a string to an integer, with overflow/error checking. 930 * 931 ******************************************************************************/ 932 933 UINT64 934 UtDoConstant ( 935 char *String) 936 { 937 ACPI_STATUS Status; 938 UINT64 ConvertedInteger; 939 char ErrBuf[64]; 940 941 942 Status = AcpiUtStrtoul64 (String, &ConvertedInteger); 943 if (ACPI_FAILURE (Status)) 944 { 945 snprintf (ErrBuf, sizeof(ErrBuf), "While creating 64-bit constant: %s\n", 946 AcpiFormatException (Status)); 947 948 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber, 949 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset, 950 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf); 951 } 952 953 return (ConvertedInteger); 954 } 955 956 957 /****************************************************************************** 958 * 959 * FUNCTION: AcpiUtStrdup 960 * 961 * PARAMETERS: String1 - string to duplicate 962 * 963 * RETURN: int that signifies string relationship. Zero means strings 964 * are equal. 965 * 966 * DESCRIPTION: Duplicate the string using UtCacheAlloc to avoid manual memory 967 * reclamation. 968 * 969 ******************************************************************************/ 970 971 char * 972 AcpiUtStrdup ( 973 char *String) 974 { 975 char *NewString = (char *) UtLocalCalloc (strlen (String) + 1); 976 977 978 strcpy (NewString, String); 979 return (NewString); 980 } 981 982 983 /****************************************************************************** 984 * 985 * FUNCTION: AcpiUtStrcat 986 * 987 * PARAMETERS: String1 988 * String2 989 * 990 * RETURN: New string with String1 concatenated with String2 991 * 992 * DESCRIPTION: Concatenate string1 and string2 993 * 994 ******************************************************************************/ 995 996 char * 997 AcpiUtStrcat ( 998 char *String1, 999 char *String2) 1000 { 1001 UINT32 String1Length = strlen (String1); 1002 char *NewString = (char *) UtLocalCalloc (strlen (String1) + strlen (String2) + 1); 1003 1004 strcpy (NewString, String1); 1005 strcpy (NewString + String1Length, String2); 1006 return (NewString); 1007 } 1008