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