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