xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslutils.c (revision 63aea4bd5b445e491ff0389fe27ec78b3099dba3)
1 /******************************************************************************
2  *
3  * Module Name: aslutils -- compiler utilities
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, 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 
51 #define _COMPONENT          ACPI_COMPILER
52         ACPI_MODULE_NAME    ("aslutils")
53 
54 
55 /* Local prototypes */
56 
57 static void
58 UtPadNameWithUnderscores (
59     char                    *NameSeg,
60     char                    *PaddedNameSeg);
61 
62 static void
63 UtAttachNameseg (
64     ACPI_PARSE_OBJECT       *Op,
65     char                    *Name);
66 
67 
68 /*******************************************************************************
69  *
70  * FUNCTION:    UtDisplaySupportedTables
71  *
72  * PARAMETERS:  None
73  *
74  * RETURN:      None
75  *
76  * DESCRIPTION: Print all supported ACPI table names.
77  *
78  ******************************************************************************/
79 
80 void
81 UtDisplaySupportedTables (
82     void)
83 {
84     const AH_TABLE          *TableData;
85     UINT32                  i;
86 
87 
88     printf ("\nACPI tables supported by iASL version %8.8X:\n"
89         "  (Compiler, Disassembler, Template Generator)\n\n",
90         ACPI_CA_VERSION);
91 
92     /* All ACPI tables with the common table header */
93 
94     printf ("\n  Supported ACPI tables:\n");
95     for (TableData = AcpiSupportedTables, i = 1;
96          TableData->Signature; TableData++, i++)
97     {
98         printf ("%8u) %s    %s\n", i,
99             TableData->Signature, TableData->Description);
100     }
101 }
102 
103 
104 /*******************************************************************************
105  *
106  * FUNCTION:    UtDisplayConstantOpcodes
107  *
108  * PARAMETERS:  None
109  *
110  * RETURN:      None
111  *
112  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
113  *
114  ******************************************************************************/
115 
116 void
117 UtDisplayConstantOpcodes (
118     void)
119 {
120     UINT32                  i;
121 
122 
123     printf ("Constant expression opcode information\n\n");
124 
125     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
126     {
127         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
128         {
129             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
130         }
131     }
132 }
133 
134 
135 /*******************************************************************************
136  *
137  * FUNCTION:    UtLocalCalloc
138  *
139  * PARAMETERS:  Size                - Bytes to be allocated
140  *
141  * RETURN:      Pointer to the allocated memory. Guaranteed to be valid.
142  *
143  * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
144  *              allocation failure, on the assumption that nothing more can be
145  *              accomplished.
146  *
147  ******************************************************************************/
148 
149 void *
150 UtLocalCalloc (
151     UINT32                  Size)
152 {
153     void                    *Allocated;
154 
155 
156     Allocated = ACPI_ALLOCATE_ZEROED (Size);
157     if (!Allocated)
158     {
159         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
160             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
161             Gbl_InputByteCount, Gbl_CurrentColumn,
162             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
163 
164         CmCleanupAndExit ();
165         exit (1);
166     }
167 
168     TotalAllocations++;
169     TotalAllocated += Size;
170     return (Allocated);
171 }
172 
173 /*******************************************************************************
174  *
175  * FUNCTION:    UtLocalFree
176  *
177  * PARAMETERS:  Allocated           - Pointer to be released
178  * PARAMETERS:  Size                - Bytes to be released
179  *
180  * RETURN:      None
181  *
182  * DESCRIPTION: Free memory previously allocated
183  *
184  ******************************************************************************/
185 void
186 UtLocalFree (
187 	void *Allocated, UINT32 Size)
188 {
189     ACPI_FREE (Allocated);
190     TotalAllocations--;
191     TotalAllocated -= Size;
192 }
193 
194 /*******************************************************************************
195  *
196  * FUNCTION:    UtBeginEvent
197  *
198  * PARAMETERS:  Name                - Ascii name of this event
199  *
200  * RETURN:      Event number (integer index)
201  *
202  * DESCRIPTION: Saves the current time with this event
203  *
204  ******************************************************************************/
205 
206 UINT8
207 UtBeginEvent (
208     char                    *Name)
209 {
210 
211     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
212     {
213         AcpiOsPrintf ("Ran out of compiler event structs!\n");
214         return (AslGbl_NextEvent);
215     }
216 
217     /* Init event with current (start) time */
218 
219     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
220     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
221     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
222 
223     return (AslGbl_NextEvent++);
224 }
225 
226 
227 /*******************************************************************************
228  *
229  * FUNCTION:    UtEndEvent
230  *
231  * PARAMETERS:  Event               - Event number (integer index)
232  *
233  * RETURN:      None
234  *
235  * DESCRIPTION: Saves the current time (end time) with this event
236  *
237  ******************************************************************************/
238 
239 void
240 UtEndEvent (
241     UINT8                   Event)
242 {
243 
244     if (Event >= ASL_NUM_EVENTS)
245     {
246         return;
247     }
248 
249     /* Insert end time for event */
250 
251     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
252 }
253 
254 
255 /*******************************************************************************
256  *
257  * FUNCTION:    UtConvertByteToHex
258  *
259  * PARAMETERS:  RawByte             - Binary data
260  *              Buffer              - Pointer to where the hex bytes will be
261  *                                    stored
262  *
263  * RETURN:      Ascii hex byte is stored in Buffer.
264  *
265  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
266  *              with "0x"
267  *
268  ******************************************************************************/
269 
270 void
271 UtConvertByteToHex (
272     UINT8                   RawByte,
273     UINT8                   *Buffer)
274 {
275 
276     Buffer[0] = '0';
277     Buffer[1] = 'x';
278 
279     Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
280     Buffer[3] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
281 }
282 
283 
284 /*******************************************************************************
285  *
286  * FUNCTION:    UtConvertByteToAsmHex
287  *
288  * PARAMETERS:  RawByte             - Binary data
289  *              Buffer              - Pointer to where the hex bytes will be
290  *                                    stored
291  *
292  * RETURN:      Ascii hex byte is stored in Buffer.
293  *
294  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
295  *              with '0', and a trailing 'h' is added.
296  *
297  ******************************************************************************/
298 
299 void
300 UtConvertByteToAsmHex (
301     UINT8                   RawByte,
302     UINT8                   *Buffer)
303 {
304 
305     Buffer[0] = '0';
306     Buffer[1] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
307     Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
308     Buffer[3] = 'h';
309 }
310 
311 
312 /*******************************************************************************
313  *
314  * FUNCTION:    DbgPrint
315  *
316  * PARAMETERS:  Type                - Type of output
317  *              Fmt                 - Printf format string
318  *              ...                 - variable printf list
319  *
320  * RETURN:      None
321  *
322  * DESCRIPTION: Conditional print statement. Prints to stderr only if the
323  *              debug flag is set.
324  *
325  ******************************************************************************/
326 
327 void
328 DbgPrint (
329     UINT32                  Type,
330     char                    *Fmt,
331     ...)
332 {
333     va_list                 Args;
334 
335 
336     if (!Gbl_DebugFlag)
337     {
338         return;
339     }
340 
341     if ((Type == ASL_PARSE_OUTPUT) &&
342         (!(AslCompilerdebug)))
343     {
344         return;
345     }
346 
347     va_start (Args, Fmt);
348     (void) vfprintf (stderr, Fmt, Args);
349     va_end (Args);
350     return;
351 }
352 
353 
354 /*******************************************************************************
355  *
356  * FUNCTION:    UtPrintFormattedName
357  *
358  * PARAMETERS:  ParseOpcode         - Parser keyword ID
359  *              Level               - Indentation level
360  *
361  * RETURN:      None
362  *
363  * DESCRIPTION: Print the ascii name of the parse opcode.
364  *
365  ******************************************************************************/
366 
367 #define TEXT_OFFSET 10
368 
369 void
370 UtPrintFormattedName (
371     UINT16                  ParseOpcode,
372     UINT32                  Level)
373 {
374 
375     if (Level)
376     {
377         DbgPrint (ASL_TREE_OUTPUT,
378             "%*s", (3 * Level), " ");
379     }
380     DbgPrint (ASL_TREE_OUTPUT,
381         " %-20.20s", UtGetOpName (ParseOpcode));
382 
383     if (Level < TEXT_OFFSET)
384     {
385         DbgPrint (ASL_TREE_OUTPUT,
386             "%*s", (TEXT_OFFSET - Level) * 3, " ");
387     }
388 }
389 
390 
391 /*******************************************************************************
392  *
393  * FUNCTION:    UtSetParseOpName
394  *
395  * PARAMETERS:  Op                  - Parse op to be named.
396  *
397  * RETURN:      None
398  *
399  * DESCRIPTION: Insert the ascii name of the parse opcode
400  *
401  ******************************************************************************/
402 
403 void
404 UtSetParseOpName (
405     ACPI_PARSE_OBJECT       *Op)
406 {
407 
408     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
409         ACPI_MAX_PARSEOP_NAME);
410 }
411 
412 
413 /*******************************************************************************
414  *
415  * FUNCTION:    UtDisplaySummary
416  *
417  * PARAMETERS:  FileID              - ID of outpout file
418  *
419  * RETURN:      None
420  *
421  * DESCRIPTION: Display compilation statistics
422  *
423  ******************************************************************************/
424 
425 void
426 UtDisplaySummary (
427     UINT32                  FileId)
428 {
429     UINT32                  i;
430 
431 
432     if (FileId != ASL_FILE_STDOUT)
433     {
434         /* Compiler name and version number */
435 
436         FlPrintFile (FileId, "%s version %X%s [%s]\n\n",
437             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH, ACPI_DATE);
438     }
439 
440     /* Summary of main input and output files */
441 
442     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
443     {
444         FlPrintFile (FileId,
445             "%-14s %s - %u lines, %u bytes, %u fields\n",
446             "Table Input:",
447             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
448             Gbl_InputByteCount, Gbl_InputFieldCount);
449 
450         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
451         {
452             FlPrintFile (FileId,
453                 "%-14s %s - %u bytes\n",
454                 "Binary Output:",
455                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
456         }
457     }
458     else
459     {
460         FlPrintFile (FileId,
461             "%-14s %s - %u lines, %u bytes, %u keywords\n",
462             "ASL Input:",
463             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
464             Gbl_OriginalInputFileSize, TotalKeywords);
465 
466         /* AML summary */
467 
468         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
469         {
470             if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
471             {
472                 FlPrintFile (FileId,
473                     "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
474                     "AML Output:",
475                     Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
476                     TotalNamedObjects, TotalExecutableOpcodes);
477             }
478         }
479     }
480 
481     /* Display summary of any optional files */
482 
483     for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
484     {
485         if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
486         {
487             continue;
488         }
489 
490         /* .SRC is a temp file unless specifically requested */
491 
492         if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
493         {
494             continue;
495         }
496 
497         /* .PRE is the preprocessor intermediate file */
498 
499         if ((i == ASL_FILE_PREPROCESSOR)  && (!Gbl_KeepPreprocessorTempFile))
500         {
501             continue;
502         }
503 
504         FlPrintFile (FileId, "%14s %s - %u bytes\n",
505             Gbl_Files[i].ShortDescription,
506             Gbl_Files[i].Filename, FlGetFileSize (i));
507     }
508 
509     /* Error summary */
510 
511     FlPrintFile (FileId,
512         "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
513         Gbl_ExceptionCount[ASL_ERROR],
514         Gbl_ExceptionCount[ASL_WARNING] +
515             Gbl_ExceptionCount[ASL_WARNING2] +
516             Gbl_ExceptionCount[ASL_WARNING3],
517         Gbl_ExceptionCount[ASL_REMARK]);
518 
519     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
520     {
521         FlPrintFile (FileId, ", %u Optimizations",
522             Gbl_ExceptionCount[ASL_OPTIMIZATION]);
523 
524         if (TotalFolds)
525         {
526             FlPrintFile (FileId, ", %u Constants Folded", TotalFolds);
527         }
528     }
529 
530     FlPrintFile (FileId, "\n");
531 }
532 
533 
534 /*******************************************************************************
535  *
536  * FUNCTION:    UtCheckIntegerRange
537  *
538  * PARAMETERS:  Op                  - Integer parse node
539  *              LowValue            - Smallest allowed value
540  *              HighValue           - Largest allowed value
541  *
542  * RETURN:      Op if OK, otherwise NULL
543  *
544  * DESCRIPTION: Check integer for an allowable range
545  *
546  ******************************************************************************/
547 
548 ACPI_PARSE_OBJECT *
549 UtCheckIntegerRange (
550     ACPI_PARSE_OBJECT       *Op,
551     UINT32                  LowValue,
552     UINT32                  HighValue)
553 {
554 
555     if (!Op)
556     {
557         return (NULL);
558     }
559 
560     if ((Op->Asl.Value.Integer < LowValue) ||
561         (Op->Asl.Value.Integer > HighValue))
562     {
563         snprintf (MsgBuffer, sizeof(MsgBuffer), "0x%X, allowable: 0x%X-0x%X",
564             (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
565 
566         AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
567         return (NULL);
568     }
569 
570     return (Op);
571 }
572 
573 
574 /*******************************************************************************
575  *
576  * FUNCTION:    UtStringCacheCalloc
577  *
578  * PARAMETERS:  Length              - Size of buffer requested
579  *
580  * RETURN:      Pointer to the buffer. Aborts on allocation failure
581  *
582  * DESCRIPTION: Allocate a string buffer. Bypass the local
583  *              dynamic memory manager for performance reasons (This has a
584  *              major impact on the speed of the compiler.)
585  *
586  ******************************************************************************/
587 
588 char *
589 UtStringCacheCalloc (
590     UINT32                  Length)
591 {
592     char                    *Buffer;
593     ASL_CACHE_INFO          *Cache;
594     UINT32                  CacheSize = ASL_STRING_CACHE_SIZE;
595 
596 
597     if (Length > CacheSize)
598     {
599         CacheSize = Length;
600 
601         if (Gbl_StringCacheList)
602         {
603             Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
604 
605             /* Link new cache buffer just following head of list */
606 
607             Cache->Next = Gbl_StringCacheList->Next;
608             Gbl_StringCacheList->Next = Cache;
609 
610             /* Leave cache management pointers alone as they pertain to head */
611 
612             Gbl_StringCount++;
613             Gbl_StringSize += Length;
614 
615             return (Cache->Buffer);
616         }
617     }
618 
619     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
620     {
621         /* Allocate a new buffer */
622 
623         Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
624 
625         /* Link new cache buffer to head of list */
626 
627         Cache->Next = Gbl_StringCacheList;
628         Gbl_StringCacheList = Cache;
629 
630         /* Setup cache management pointers */
631 
632         Gbl_StringCacheNext = Cache->Buffer;
633         Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
634     }
635 
636     Gbl_StringCount++;
637     Gbl_StringSize += Length;
638 
639     Buffer = Gbl_StringCacheNext;
640     Gbl_StringCacheNext += Length;
641     return (Buffer);
642 }
643 
644 
645 /******************************************************************************
646  *
647  * FUNCTION:    UtExpandLineBuffers
648  *
649  * PARAMETERS:  None. Updates global line buffer pointers.
650  *
651  * RETURN:      None. Reallocates the global line buffers
652  *
653  * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
654  *              all global line buffers and updates Gbl_LineBufferSize. NOTE:
655  *              Also used for the initial allocation of the buffers, when
656  *              all of the buffer pointers are NULL. Initial allocations are
657  *              of size ASL_DEFAULT_LINE_BUFFER_SIZE
658  *
659  *****************************************************************************/
660 
661 void
662 UtExpandLineBuffers (
663     void)
664 {
665     UINT32                  NewSize;
666 
667 
668     /* Attempt to double the size of all line buffers */
669 
670     NewSize = Gbl_LineBufferSize * 2;
671     if (Gbl_CurrentLineBuffer)
672     {
673         DbgPrint (ASL_DEBUG_OUTPUT,
674             "Increasing line buffer size from %u to %u\n",
675             Gbl_LineBufferSize, NewSize);
676     }
677 
678     Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize);
679     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
680     if (!Gbl_CurrentLineBuffer)
681     {
682         goto ErrorExit;
683     }
684 
685     Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize);
686     if (!Gbl_MainTokenBuffer)
687     {
688         goto ErrorExit;
689     }
690 
691     Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize);
692     if (!Gbl_MacroTokenBuffer)
693     {
694         goto ErrorExit;
695     }
696 
697     Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize);
698     if (!Gbl_ExpressionTokenBuffer)
699     {
700         goto ErrorExit;
701     }
702 
703     Gbl_LineBufferSize = NewSize;
704     return;
705 
706 
707     /* On error above, simply issue error messages and abort, cannot continue */
708 
709 ErrorExit:
710     printf ("Could not increase line buffer size from %u to %u\n",
711         Gbl_LineBufferSize, Gbl_LineBufferSize * 2);
712 
713     AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION,
714         NULL, NULL);
715     AslAbort ();
716 }
717 
718 
719 /******************************************************************************
720  *
721  * FUNCTION:    UtFreeLineBuffers
722  *
723  * PARAMETERS:  None
724  *
725  * RETURN:      None
726  *
727  * DESCRIPTION: Free all line buffers
728  *
729  *****************************************************************************/
730 
731 void
732 UtFreeLineBuffers (
733     void)
734 {
735 
736     free (Gbl_CurrentLineBuffer);
737     free (Gbl_MainTokenBuffer);
738     free (Gbl_MacroTokenBuffer);
739     free (Gbl_ExpressionTokenBuffer);
740 }
741 
742 
743 /*******************************************************************************
744  *
745  * FUNCTION:    UtInternalizeName
746  *
747  * PARAMETERS:  ExternalName        - Name to convert
748  *              ConvertedName       - Where the converted name is returned
749  *
750  * RETURN:      Status
751  *
752  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
753  *
754  ******************************************************************************/
755 
756 ACPI_STATUS
757 UtInternalizeName (
758     char                    *ExternalName,
759     char                    **ConvertedName)
760 {
761     ACPI_NAMESTRING_INFO    Info;
762     ACPI_STATUS             Status;
763 
764 
765     if (!ExternalName)
766     {
767         return (AE_OK);
768     }
769 
770     /* Get the length of the new internal name */
771 
772     Info.ExternalName = ExternalName;
773     AcpiNsGetInternalNameLength (&Info);
774 
775     /* We need a segment to store the internal name */
776 
777     Info.InternalName = UtStringCacheCalloc (Info.Length);
778     if (!Info.InternalName)
779     {
780         return (AE_NO_MEMORY);
781     }
782 
783     /* Build the name */
784 
785     Status = AcpiNsBuildInternalName (&Info);
786     if (ACPI_FAILURE (Status))
787     {
788         return (Status);
789     }
790 
791     *ConvertedName = Info.InternalName;
792     return (AE_OK);
793 }
794 
795 
796 /*******************************************************************************
797  *
798  * FUNCTION:    UtPadNameWithUnderscores
799  *
800  * PARAMETERS:  NameSeg             - Input nameseg
801  *              PaddedNameSeg       - Output padded nameseg
802  *
803  * RETURN:      Padded nameseg.
804  *
805  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
806  *              ACPI_NAME.
807  *
808  ******************************************************************************/
809 
810 static void
811 UtPadNameWithUnderscores (
812     char                    *NameSeg,
813     char                    *PaddedNameSeg)
814 {
815     UINT32                  i;
816 
817 
818     for (i = 0; (i < ACPI_NAME_SIZE); i++)
819     {
820         if (*NameSeg)
821         {
822             *PaddedNameSeg = *NameSeg;
823             NameSeg++;
824         }
825         else
826         {
827             *PaddedNameSeg = '_';
828         }
829         PaddedNameSeg++;
830     }
831 }
832 
833 
834 /*******************************************************************************
835  *
836  * FUNCTION:    UtAttachNameseg
837  *
838  * PARAMETERS:  Op                  - Parent parse node
839  *              Name                - Full ExternalName
840  *
841  * RETURN:      None; Sets the NameSeg field in parent node
842  *
843  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
844  *              in the NameSeg field of the Op.
845  *
846  ******************************************************************************/
847 
848 static void
849 UtAttachNameseg (
850     ACPI_PARSE_OBJECT       *Op,
851     char                    *Name)
852 {
853     char                    *NameSeg;
854     char                    PaddedNameSeg[4];
855 
856 
857     if (!Name)
858     {
859         return;
860     }
861 
862     /* Look for the last dot in the namepath */
863 
864     NameSeg = strrchr (Name, '.');
865     if (NameSeg)
866     {
867         /* Found last dot, we have also found the final nameseg */
868 
869         NameSeg++;
870         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
871     }
872     else
873     {
874         /* No dots in the namepath, there is only a single nameseg. */
875         /* Handle prefixes */
876 
877         while (ACPI_IS_ROOT_PREFIX (*Name) ||
878                ACPI_IS_PARENT_PREFIX (*Name))
879         {
880             Name++;
881         }
882 
883         /* Remaining string should be one single nameseg */
884 
885         UtPadNameWithUnderscores (Name, PaddedNameSeg);
886     }
887 
888     ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg);
889 }
890 
891 
892 /*******************************************************************************
893  *
894  * FUNCTION:    UtAttachNamepathToOwner
895  *
896  * PARAMETERS:  Op                  - Parent parse node
897  *              NameOp              - Node that contains the name
898  *
899  * RETURN:      Sets the ExternalName and Namepath in the parent node
900  *
901  * DESCRIPTION: Store the name in two forms in the parent node: The original
902  *              (external) name, and the internalized name that is used within
903  *              the ACPI namespace manager.
904  *
905  ******************************************************************************/
906 
907 void
908 UtAttachNamepathToOwner (
909     ACPI_PARSE_OBJECT       *Op,
910     ACPI_PARSE_OBJECT       *NameOp)
911 {
912     ACPI_STATUS             Status;
913 
914 
915     /* Full external path */
916 
917     Op->Asl.ExternalName = NameOp->Asl.Value.String;
918 
919     /* Save the NameOp for possible error reporting later */
920 
921     Op->Asl.ParentMethod = (void *) NameOp;
922 
923     /* Last nameseg of the path */
924 
925     UtAttachNameseg (Op, Op->Asl.ExternalName);
926 
927     /* Create internalized path */
928 
929     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
930     if (ACPI_FAILURE (Status))
931     {
932         /* TBD: abort on no memory */
933     }
934 }
935 
936 
937 /*******************************************************************************
938  *
939  * FUNCTION:    UtDoConstant
940  *
941  * PARAMETERS:  String              - Hex, Octal, or Decimal string
942  *
943  * RETURN:      Converted Integer
944  *
945  * DESCRIPTION: Convert a string to an integer, with error checking.
946  *
947  ******************************************************************************/
948 
949 UINT64
950 UtDoConstant (
951     char                    *String)
952 {
953     ACPI_STATUS             Status;
954     UINT64                  Converted;
955     char                    ErrBuf[64];
956 
957 
958     Status = stroul64 (String, 0, &Converted);
959     if (ACPI_FAILURE (Status))
960     {
961         snprintf (ErrBuf, sizeof(ErrBuf), "%s %s\n", "Conversion error:",
962             AcpiFormatException (Status));
963         AslCompilererror (ErrBuf);
964     }
965 
966     return (Converted);
967 }
968 
969 
970 /* TBD: use version in ACPICA main code base? */
971 
972 /*******************************************************************************
973  *
974  * FUNCTION:    stroul64
975  *
976  * PARAMETERS:  String              - Null terminated string
977  *              Terminater          - Where a pointer to the terminating byte
978  *                                    is returned
979  *              Base                - Radix of the string
980  *
981  * RETURN:      Converted value
982  *
983  * DESCRIPTION: Convert a string into an unsigned value.
984  *
985  ******************************************************************************/
986 
987 ACPI_STATUS
988 stroul64 (
989     char                    *String,
990     UINT32                  Base,
991     UINT64                  *RetInteger)
992 {
993     UINT32                  Index;
994     UINT32                  Sign;
995     UINT64                  ReturnValue = 0;
996     ACPI_STATUS             Status = AE_OK;
997 
998 
999     *RetInteger = 0;
1000 
1001     switch (Base)
1002     {
1003     case 0:
1004     case 8:
1005     case 10:
1006     case 16:
1007 
1008         break;
1009 
1010     default:
1011         /*
1012          * The specified Base parameter is not in the domain of
1013          * this function:
1014          */
1015         return (AE_BAD_PARAMETER);
1016     }
1017 
1018     /* Skip over any white space in the buffer: */
1019 
1020     while (isspace ((int) *String) || *String == '\t')
1021     {
1022         ++String;
1023     }
1024 
1025     /*
1026      * The buffer may contain an optional plus or minus sign.
1027      * If it does, then skip over it but remember what is was:
1028      */
1029     if (*String == '-')
1030     {
1031         Sign = ACPI_SIGN_NEGATIVE;
1032         ++String;
1033     }
1034     else if (*String == '+')
1035     {
1036         ++String;
1037         Sign = ACPI_SIGN_POSITIVE;
1038     }
1039     else
1040     {
1041         Sign = ACPI_SIGN_POSITIVE;
1042     }
1043 
1044     /*
1045      * If the input parameter Base is zero, then we need to
1046      * determine if it is octal, decimal, or hexadecimal:
1047      */
1048     if (Base == 0)
1049     {
1050         if (*String == '0')
1051         {
1052             if (tolower ((int) *(++String)) == 'x')
1053             {
1054                 Base = 16;
1055                 ++String;
1056             }
1057             else
1058             {
1059                 Base = 8;
1060             }
1061         }
1062         else
1063         {
1064             Base = 10;
1065         }
1066     }
1067 
1068     /*
1069      * For octal and hexadecimal bases, skip over the leading
1070      * 0 or 0x, if they are present.
1071      */
1072     if (Base == 8 && *String == '0')
1073     {
1074         String++;
1075     }
1076 
1077     if (Base == 16 &&
1078         *String == '0' &&
1079         tolower ((int) *(++String)) == 'x')
1080     {
1081         String++;
1082     }
1083 
1084     /* Main loop: convert the string to an unsigned long */
1085 
1086     while (*String)
1087     {
1088         if (isdigit ((int) *String))
1089         {
1090             Index = ((UINT8) *String) - '0';
1091         }
1092         else
1093         {
1094             Index = (UINT8) toupper ((int) *String);
1095             if (isupper ((int) Index))
1096             {
1097                 Index = Index - 'A' + 10;
1098             }
1099             else
1100             {
1101                 goto ErrorExit;
1102             }
1103         }
1104 
1105         if (Index >= Base)
1106         {
1107             goto ErrorExit;
1108         }
1109 
1110         /* Check to see if value is out of range: */
1111 
1112         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
1113                             (UINT64) Base))
1114         {
1115             goto ErrorExit;
1116         }
1117         else
1118         {
1119             ReturnValue *= Base;
1120             ReturnValue += Index;
1121         }
1122 
1123         ++String;
1124     }
1125 
1126 
1127     /* If a minus sign was present, then "the conversion is negated": */
1128 
1129     if (Sign == ACPI_SIGN_NEGATIVE)
1130     {
1131         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
1132     }
1133 
1134     *RetInteger = ReturnValue;
1135     return (Status);
1136 
1137 
1138 ErrorExit:
1139     switch (Base)
1140     {
1141     case 8:
1142 
1143         Status = AE_BAD_OCTAL_CONSTANT;
1144         break;
1145 
1146     case 10:
1147 
1148         Status = AE_BAD_DECIMAL_CONSTANT;
1149         break;
1150 
1151     case 16:
1152 
1153         Status = AE_BAD_HEX_CONSTANT;
1154         break;
1155 
1156     default:
1157 
1158         /* Base validated above */
1159 
1160         break;
1161     }
1162 
1163     return (Status);
1164 }
1165