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