1 /******************************************************************************
2  *
3  * Module Name: aslutils -- compiler utilities
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, 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 
70 /*******************************************************************************
71  *
72  * FUNCTION:    UtIsBigEndianMachine
73  *
74  * PARAMETERS:  None
75  *
76  * RETURN:      TRUE if machine is big endian
77  *              FALSE if machine is little endian
78  *
79  * DESCRIPTION: Detect whether machine is little endian or big endian.
80  *
81  ******************************************************************************/
82 
83 UINT8
84 UtIsBigEndianMachine (
85     void)
86 {
87     union {
88         UINT32              Integer;
89         UINT8               Bytes[4];
90     } Overlay =                 {0xFF000000};
91 
92 
93     return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
94 }
95 
96 
97 /******************************************************************************
98  *
99  * FUNCTION:    UtQueryForOverwrite
100  *
101  * PARAMETERS:  Pathname            - Output filename
102  *
103  * RETURN:      TRUE if file does not exist or overwrite is authorized
104  *
105  * DESCRIPTION: Query for file overwrite if it already exists.
106  *
107  ******************************************************************************/
108 
109 BOOLEAN
110 UtQueryForOverwrite (
111     char                    *Pathname)
112 {
113     struct stat             StatInfo;
114 
115 
116     if (!stat (Pathname, &StatInfo))
117     {
118         fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ",
119             Pathname);
120 
121         if (getchar () != 'y')
122         {
123             return (FALSE);
124         }
125     }
126 
127     return (TRUE);
128 }
129 
130 
131 /*******************************************************************************
132  *
133  * FUNCTION:    UtDisplaySupportedTables
134  *
135  * PARAMETERS:  None
136  *
137  * RETURN:      None
138  *
139  * DESCRIPTION: Print all supported ACPI table names.
140  *
141  ******************************************************************************/
142 
143 void
144 UtDisplaySupportedTables (
145     void)
146 {
147     const AH_TABLE          *TableData;
148     UINT32                  i;
149 
150 
151     printf ("\nACPI tables supported by iASL version %8.8X:\n"
152         "  (Compiler, Disassembler, Template Generator)\n\n",
153         ACPI_CA_VERSION);
154 
155     /* All ACPI tables with the common table header */
156 
157     printf ("\n  Supported ACPI tables:\n");
158     for (TableData = AcpiSupportedTables, i = 1;
159          TableData->Signature; TableData++, i++)
160     {
161         printf ("%8u) %s    %s\n", i,
162             TableData->Signature, TableData->Description);
163     }
164 }
165 
166 
167 /*******************************************************************************
168  *
169  * FUNCTION:    UtDisplayConstantOpcodes
170  *
171  * PARAMETERS:  None
172  *
173  * RETURN:      None
174  *
175  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
176  *
177  ******************************************************************************/
178 
179 void
180 UtDisplayConstantOpcodes (
181     void)
182 {
183     UINT32                  i;
184 
185 
186     printf ("Constant expression opcode information\n\n");
187 
188     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
189     {
190         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
191         {
192             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
193         }
194     }
195 }
196 
197 
198 /*******************************************************************************
199  *
200  * FUNCTION:    UtLocalCalloc
201  *
202  * PARAMETERS:  Size                - Bytes to be allocated
203  *
204  * RETURN:      Pointer to the allocated memory. Guaranteed to be valid.
205  *
206  * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
207  *              allocation failure, on the assumption that nothing more can be
208  *              accomplished.
209  *
210  ******************************************************************************/
211 
212 void *
213 UtLocalCalloc (
214     UINT32                  Size)
215 {
216     void                    *Allocated;
217 
218 
219     Allocated = ACPI_ALLOCATE_ZEROED (Size);
220     if (!Allocated)
221     {
222         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
223             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
224             Gbl_InputByteCount, Gbl_CurrentColumn,
225             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
226 
227         CmCleanupAndExit ();
228         exit (1);
229     }
230 
231     TotalAllocations++;
232     TotalAllocated += Size;
233     return (Allocated);
234 }
235 
236 
237 /*******************************************************************************
238  *
239  * FUNCTION:    UtBeginEvent
240  *
241  * PARAMETERS:  Name                - Ascii name of this event
242  *
243  * RETURN:      Event number (integer index)
244  *
245  * DESCRIPTION: Saves the current time with this event
246  *
247  ******************************************************************************/
248 
249 UINT8
250 UtBeginEvent (
251     char                    *Name)
252 {
253 
254     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
255     {
256         AcpiOsPrintf ("Ran out of compiler event structs!\n");
257         return (AslGbl_NextEvent);
258     }
259 
260     /* Init event with current (start) time */
261 
262     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
263     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
264     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
265     return (AslGbl_NextEvent++);
266 }
267 
268 
269 /*******************************************************************************
270  *
271  * FUNCTION:    UtEndEvent
272  *
273  * PARAMETERS:  Event               - Event number (integer index)
274  *
275  * RETURN:      None
276  *
277  * DESCRIPTION: Saves the current time (end time) with this event
278  *
279  ******************************************************************************/
280 
281 void
282 UtEndEvent (
283     UINT8                   Event)
284 {
285 
286     if (Event >= ASL_NUM_EVENTS)
287     {
288         return;
289     }
290 
291     /* Insert end time for event */
292 
293     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
294 }
295 
296 
297 /*******************************************************************************
298  *
299  * FUNCTION:    DbgPrint
300  *
301  * PARAMETERS:  Type                - Type of output
302  *              Fmt                 - Printf format string
303  *              ...                 - variable printf list
304  *
305  * RETURN:      None
306  *
307  * DESCRIPTION: Conditional print statement. Prints to stderr only if the
308  *              debug flag is set.
309  *
310  ******************************************************************************/
311 
312 void
313 DbgPrint (
314     UINT32                  Type,
315     char                    *Fmt,
316     ...)
317 {
318     va_list                 Args;
319 
320 
321     if (!Gbl_DebugFlag)
322     {
323         return;
324     }
325 
326     if ((Type == ASL_PARSE_OUTPUT) &&
327         (!(AslCompilerdebug)))
328     {
329         return;
330     }
331 
332     va_start (Args, Fmt);
333     (void) vfprintf (stderr, Fmt, Args);
334     va_end (Args);
335     return;
336 }
337 
338 
339 /*******************************************************************************
340  *
341  * FUNCTION:    UtSetParseOpName
342  *
343  * PARAMETERS:  Op                  - Parse op to be named.
344  *
345  * RETURN:      None
346  *
347  * DESCRIPTION: Insert the ascii name of the parse opcode
348  *
349  ******************************************************************************/
350 
351 void
352 UtSetParseOpName (
353     ACPI_PARSE_OBJECT       *Op)
354 {
355 
356     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
357         ACPI_MAX_PARSEOP_NAME);
358 }
359 
360 
361 /*******************************************************************************
362  *
363  * FUNCTION:    UtDisplaySummary
364  *
365  * PARAMETERS:  FileID              - ID of outpout file
366  *
367  * RETURN:      None
368  *
369  * DESCRIPTION: Display compilation statistics
370  *
371  ******************************************************************************/
372 
373 void
374 UtDisplaySummary (
375     UINT32                  FileId)
376 {
377     UINT32                  i;
378 
379 
380     if (FileId != ASL_FILE_STDOUT)
381     {
382         /* Compiler name and version number */
383 
384         FlPrintFile (FileId, "%s version %X%s [%s]\n\n",
385             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH, __DATE__);
386     }
387 
388     /* Summary of main input and output files */
389 
390     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
391     {
392         FlPrintFile (FileId,
393             "%-14s %s - %u lines, %u bytes, %u fields\n",
394             "Table Input:",
395             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
396             Gbl_InputByteCount, Gbl_InputFieldCount);
397 
398         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
399         {
400             FlPrintFile (FileId,
401                 "%-14s %s - %u bytes\n",
402                 "Binary Output:",
403                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
404         }
405     }
406     else
407     {
408         FlPrintFile (FileId,
409             "%-14s %s - %u lines, %u bytes, %u keywords\n",
410             "ASL Input:",
411             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
412             Gbl_OriginalInputFileSize, TotalKeywords);
413 
414         /* AML summary */
415 
416         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
417         {
418             if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
419             {
420                 FlPrintFile (FileId,
421                     "%-14s %s - %u bytes, %u named objects, "
422                     "%u executable opcodes\n",
423                     "AML Output:",
424                     Gbl_Files[ASL_FILE_AML_OUTPUT].Filename,
425                     FlGetFileSize (ASL_FILE_AML_OUTPUT),
426                     TotalNamedObjects, TotalExecutableOpcodes);
427             }
428         }
429     }
430 
431     /* Display summary of any optional files */
432 
433     for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
434     {
435         if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
436         {
437             continue;
438         }
439 
440         /* .SRC is a temp file unless specifically requested */
441 
442         if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
443         {
444             continue;
445         }
446 
447         /* .PRE is the preprocessor intermediate file */
448 
449         if ((i == ASL_FILE_PREPROCESSOR)  && (!Gbl_KeepPreprocessorTempFile))
450         {
451             continue;
452         }
453 
454         FlPrintFile (FileId, "%14s %s - %u bytes\n",
455             Gbl_Files[i].ShortDescription,
456             Gbl_Files[i].Filename, FlGetFileSize (i));
457     }
458 
459     /* Error summary */
460 
461     FlPrintFile (FileId,
462         "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
463         Gbl_ExceptionCount[ASL_ERROR],
464         Gbl_ExceptionCount[ASL_WARNING] +
465             Gbl_ExceptionCount[ASL_WARNING2] +
466             Gbl_ExceptionCount[ASL_WARNING3],
467         Gbl_ExceptionCount[ASL_REMARK]);
468 
469     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
470     {
471         FlPrintFile (FileId, ", %u Optimizations",
472             Gbl_ExceptionCount[ASL_OPTIMIZATION]);
473 
474         if (TotalFolds)
475         {
476             FlPrintFile (FileId, ", %u Constants Folded", TotalFolds);
477         }
478     }
479 
480     FlPrintFile (FileId, "\n");
481 }
482 
483 
484 /*******************************************************************************
485  *
486  * FUNCTION:    UtCheckIntegerRange
487  *
488  * PARAMETERS:  Op                  - Integer parse node
489  *              LowValue            - Smallest allowed value
490  *              HighValue           - Largest allowed value
491  *
492  * RETURN:      Op if OK, otherwise NULL
493  *
494  * DESCRIPTION: Check integer for an allowable range
495  *
496  ******************************************************************************/
497 
498 ACPI_PARSE_OBJECT *
499 UtCheckIntegerRange (
500     ACPI_PARSE_OBJECT       *Op,
501     UINT32                  LowValue,
502     UINT32                  HighValue)
503 {
504 
505     if (!Op)
506     {
507         return (NULL);
508     }
509 
510     if ((Op->Asl.Value.Integer < LowValue) ||
511         (Op->Asl.Value.Integer > HighValue))
512     {
513         sprintf (MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
514             (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
515 
516         AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
517         return (NULL);
518     }
519 
520     return (Op);
521 }
522 
523 
524 /*******************************************************************************
525  *
526  * FUNCTION:    UtStringCacheCalloc
527  *
528  * PARAMETERS:  Length              - Size of buffer requested
529  *
530  * RETURN:      Pointer to the buffer. Aborts on allocation failure
531  *
532  * DESCRIPTION: Allocate a string buffer. Bypass the local
533  *              dynamic memory manager for performance reasons (This has a
534  *              major impact on the speed of the compiler.)
535  *
536  ******************************************************************************/
537 
538 char *
539 UtStringCacheCalloc (
540     UINT32                  Length)
541 {
542     char                    *Buffer;
543     ASL_CACHE_INFO          *Cache;
544     UINT32                  CacheSize = ASL_STRING_CACHE_SIZE;
545 
546 
547     if (Length > CacheSize)
548     {
549         CacheSize = Length;
550 
551         if (Gbl_StringCacheList)
552         {
553             Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
554 
555             /* Link new cache buffer just following head of list */
556 
557             Cache->Next = Gbl_StringCacheList->Next;
558             Gbl_StringCacheList->Next = Cache;
559 
560             /* Leave cache management pointers alone as they pertain to head */
561 
562             Gbl_StringCount++;
563             Gbl_StringSize += Length;
564 
565             return (Cache->Buffer);
566         }
567     }
568 
569     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
570     {
571         /* Allocate a new buffer */
572 
573         Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
574 
575         /* Link new cache buffer to head of list */
576 
577         Cache->Next = Gbl_StringCacheList;
578         Gbl_StringCacheList = Cache;
579 
580         /* Setup cache management pointers */
581 
582         Gbl_StringCacheNext = Cache->Buffer;
583         Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
584     }
585 
586     Gbl_StringCount++;
587     Gbl_StringSize += Length;
588 
589     Buffer = Gbl_StringCacheNext;
590     Gbl_StringCacheNext += Length;
591     return (Buffer);
592 }
593 
594 
595 /******************************************************************************
596  *
597  * FUNCTION:    UtExpandLineBuffers
598  *
599  * PARAMETERS:  None. Updates global line buffer pointers.
600  *
601  * RETURN:      None. Reallocates the global line buffers
602  *
603  * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
604  *              all global line buffers and updates Gbl_LineBufferSize. NOTE:
605  *              Also used for the initial allocation of the buffers, when
606  *              all of the buffer pointers are NULL. Initial allocations are
607  *              of size ASL_DEFAULT_LINE_BUFFER_SIZE
608  *
609  *****************************************************************************/
610 
611 void
612 UtExpandLineBuffers (
613     void)
614 {
615     UINT32                  NewSize;
616 
617 
618     /* Attempt to double the size of all line buffers */
619 
620     NewSize = Gbl_LineBufferSize * 2;
621     if (Gbl_CurrentLineBuffer)
622     {
623         DbgPrint (ASL_DEBUG_OUTPUT,
624             "Increasing line buffer size from %u to %u\n",
625             Gbl_LineBufferSize, NewSize);
626     }
627 
628     Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize);
629     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
630     if (!Gbl_CurrentLineBuffer)
631     {
632         goto ErrorExit;
633     }
634 
635     Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize);
636     if (!Gbl_MainTokenBuffer)
637     {
638         goto ErrorExit;
639     }
640 
641     Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize);
642     if (!Gbl_MacroTokenBuffer)
643     {
644         goto ErrorExit;
645     }
646 
647     Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize);
648     if (!Gbl_ExpressionTokenBuffer)
649     {
650         goto ErrorExit;
651     }
652 
653     Gbl_LineBufferSize = NewSize;
654     return;
655 
656 
657     /* On error above, simply issue error messages and abort, cannot continue */
658 
659 ErrorExit:
660     printf ("Could not increase line buffer size from %u to %u\n",
661         Gbl_LineBufferSize, Gbl_LineBufferSize * 2);
662 
663     AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION,
664         NULL, NULL);
665     AslAbort ();
666 }
667 
668 
669 /******************************************************************************
670  *
671  * FUNCTION:    UtFreeLineBuffers
672  *
673  * PARAMETERS:  None
674  *
675  * RETURN:      None
676  *
677  * DESCRIPTION: Free all line buffers
678  *
679  *****************************************************************************/
680 
681 void
682 UtFreeLineBuffers (
683     void)
684 {
685 
686     free (Gbl_CurrentLineBuffer);
687     free (Gbl_MainTokenBuffer);
688     free (Gbl_MacroTokenBuffer);
689     free (Gbl_ExpressionTokenBuffer);
690 }
691 
692 
693 /*******************************************************************************
694  *
695  * FUNCTION:    UtInternalizeName
696  *
697  * PARAMETERS:  ExternalName        - Name to convert
698  *              ConvertedName       - Where the converted name is returned
699  *
700  * RETURN:      Status
701  *
702  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
703  *
704  ******************************************************************************/
705 
706 ACPI_STATUS
707 UtInternalizeName (
708     char                    *ExternalName,
709     char                    **ConvertedName)
710 {
711     ACPI_NAMESTRING_INFO    Info;
712     ACPI_STATUS             Status;
713 
714 
715     if (!ExternalName)
716     {
717         return (AE_OK);
718     }
719 
720     /* Get the length of the new internal name */
721 
722     Info.ExternalName = ExternalName;
723     AcpiNsGetInternalNameLength (&Info);
724 
725     /* We need a segment to store the internal name */
726 
727     Info.InternalName = UtStringCacheCalloc (Info.Length);
728     if (!Info.InternalName)
729     {
730         return (AE_NO_MEMORY);
731     }
732 
733     /* Build the name */
734 
735     Status = AcpiNsBuildInternalName (&Info);
736     if (ACPI_FAILURE (Status))
737     {
738         return (Status);
739     }
740 
741     *ConvertedName = Info.InternalName;
742     return (AE_OK);
743 }
744 
745 
746 /*******************************************************************************
747  *
748  * FUNCTION:    UtPadNameWithUnderscores
749  *
750  * PARAMETERS:  NameSeg             - Input nameseg
751  *              PaddedNameSeg       - Output padded nameseg
752  *
753  * RETURN:      Padded nameseg.
754  *
755  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
756  *              ACPI_NAME.
757  *
758  ******************************************************************************/
759 
760 static void
761 UtPadNameWithUnderscores (
762     char                    *NameSeg,
763     char                    *PaddedNameSeg)
764 {
765     UINT32                  i;
766 
767 
768     for (i = 0; (i < ACPI_NAME_SIZE); i++)
769     {
770         if (*NameSeg)
771         {
772             *PaddedNameSeg = *NameSeg;
773             NameSeg++;
774         }
775         else
776         {
777             *PaddedNameSeg = '_';
778         }
779 
780         PaddedNameSeg++;
781     }
782 }
783 
784 
785 /*******************************************************************************
786  *
787  * FUNCTION:    UtAttachNameseg
788  *
789  * PARAMETERS:  Op                  - Parent parse node
790  *              Name                - Full ExternalName
791  *
792  * RETURN:      None; Sets the NameSeg field in parent node
793  *
794  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
795  *              in the NameSeg field of the Op.
796  *
797  ******************************************************************************/
798 
799 static void
800 UtAttachNameseg (
801     ACPI_PARSE_OBJECT       *Op,
802     char                    *Name)
803 {
804     char                    *NameSeg;
805     char                    PaddedNameSeg[4];
806 
807 
808     if (!Name)
809     {
810         return;
811     }
812 
813     /* Look for the last dot in the namepath */
814 
815     NameSeg = strrchr (Name, '.');
816     if (NameSeg)
817     {
818         /* Found last dot, we have also found the final nameseg */
819 
820         NameSeg++;
821         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
822     }
823     else
824     {
825         /* No dots in the namepath, there is only a single nameseg. */
826         /* Handle prefixes */
827 
828         while (ACPI_IS_ROOT_PREFIX (*Name) ||
829                ACPI_IS_PARENT_PREFIX (*Name))
830         {
831             Name++;
832         }
833 
834         /* Remaining string should be one single nameseg */
835 
836         UtPadNameWithUnderscores (Name, PaddedNameSeg);
837     }
838 
839     ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg);
840 }
841 
842 
843 /*******************************************************************************
844  *
845  * FUNCTION:    UtAttachNamepathToOwner
846  *
847  * PARAMETERS:  Op                  - Parent parse node
848  *              NameOp              - Node that contains the name
849  *
850  * RETURN:      Sets the ExternalName and Namepath in the parent node
851  *
852  * DESCRIPTION: Store the name in two forms in the parent node: The original
853  *              (external) name, and the internalized name that is used within
854  *              the ACPI namespace manager.
855  *
856  ******************************************************************************/
857 
858 void
859 UtAttachNamepathToOwner (
860     ACPI_PARSE_OBJECT       *Op,
861     ACPI_PARSE_OBJECT       *NameOp)
862 {
863     ACPI_STATUS             Status;
864 
865 
866     /* Full external path */
867 
868     Op->Asl.ExternalName = NameOp->Asl.Value.String;
869 
870     /* Save the NameOp for possible error reporting later */
871 
872     Op->Asl.ParentMethod = (void *) NameOp;
873 
874     /* Last nameseg of the path */
875 
876     UtAttachNameseg (Op, Op->Asl.ExternalName);
877 
878     /* Create internalized path */
879 
880     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
881     if (ACPI_FAILURE (Status))
882     {
883         /* TBD: abort on no memory */
884     }
885 }
886 
887 
888 /*******************************************************************************
889  *
890  * FUNCTION:    UtDoConstant
891  *
892  * PARAMETERS:  String              - Hexadecimal or decimal string
893  *
894  * RETURN:      Converted Integer
895  *
896  * DESCRIPTION: Convert a string to an integer, with error checking.
897  *
898  ******************************************************************************/
899 
900 UINT64
901 UtDoConstant (
902     char                    *String)
903 {
904     ACPI_STATUS             Status;
905     UINT64                  Converted;
906     char                    ErrBuf[64];
907 
908 
909     Status = AcpiUtStrtoul64 (String, ACPI_STRTOUL_64BIT, &Converted);
910     if (ACPI_FAILURE (Status))
911     {
912         sprintf (ErrBuf, "%s %s\n", "Conversion error:",
913             AcpiFormatException (Status));
914         AslCompilererror (ErrBuf);
915     }
916 
917     return (Converted);
918 }
919