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