Home | History | Annotate | Line # | Download | only in compiler
aslutils.c revision 1.28
      1 /******************************************************************************
      2  *
      3  * Module Name: aslutils -- compiler utilities
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "acdisasm.h"
     47 #include "acnamesp.h"
     48 #include "amlcode.h"
     49 #include "acapps.h"
     50 #include <sys/stat.h>
     51 
     52 
     53 #define _COMPONENT          ACPI_COMPILER
     54         ACPI_MODULE_NAME    ("aslutils")
     55 
     56 
     57 /* Local prototypes */
     58 
     59 static void
     60 UtPadNameWithUnderscores (
     61     char                    *NameSeg,
     62     char                    *PaddedNameSeg);
     63 
     64 static void
     65 UtAttachNameseg (
     66     ACPI_PARSE_OBJECT       *Op,
     67     char                    *Name);
     68 
     69 static void
     70 UtDisplayErrorSummary (
     71     UINT32                  FileId);
     72 
     73 
     74 /*******************************************************************************
     75  *
     76  * FUNCTION:    UtIsBigEndianMachine
     77  *
     78  * PARAMETERS:  None
     79  *
     80  * RETURN:      TRUE if machine is big endian
     81  *              FALSE if machine is little endian
     82  *
     83  * DESCRIPTION: Detect whether machine is little endian or big endian.
     84  *
     85  ******************************************************************************/
     86 
     87 UINT8
     88 UtIsBigEndianMachine (
     89     void)
     90 {
     91     union {
     92         UINT32              Integer;
     93         UINT8               Bytes[4];
     94     } Overlay =                 {0xFF000000};
     95 
     96 
     97     return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
     98 }
     99 
    100 
    101 /******************************************************************************
    102  *
    103  * FUNCTION:    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[128];
    970     const ACPI_EXCEPTION_INFO *ExceptionInfo;
    971 
    972 
    973     Status = AcpiUtStrtoul64 (String, &ConvertedInteger);
    974     if (ACPI_FAILURE (Status))
    975     {
    976         ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
    977         snprintf (ErrBuf, sizeof(ErrBuf), " %s while converting to 64-bit integer",
    978             ExceptionInfo->Description);
    979 
    980         AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
    981             AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
    982             AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf);
    983     }
    984 
    985     return (ConvertedInteger);
    986 }
    987 
    988 
    989 /******************************************************************************
    990  *
    991  * FUNCTION:    AcpiUtStrdup
    992  *
    993  * PARAMETERS:  String1             - string to duplicate
    994  *
    995  * RETURN:      int that signifies string relationship. Zero means strings
    996  *              are equal.
    997  *
    998  * DESCRIPTION: Duplicate the string using UtCacheAlloc to avoid manual memory
    999  *              reclamation.
   1000  *
   1001  ******************************************************************************/
   1002 
   1003 char *
   1004 AcpiUtStrdup (
   1005     char                    *String)
   1006 {
   1007     char                    *NewString = (char *) UtLocalCalloc (strlen (String) + 1);
   1008 
   1009 
   1010     strcpy (NewString, String);
   1011     return (NewString);
   1012 }
   1013 
   1014 
   1015 /******************************************************************************
   1016  *
   1017  * FUNCTION:    AcpiUtStrcat
   1018  *
   1019  * PARAMETERS:  String1
   1020  *              String2
   1021  *
   1022  * RETURN:      New string with String1 concatenated with String2
   1023  *
   1024  * DESCRIPTION: Concatenate string1 and string2
   1025  *
   1026  ******************************************************************************/
   1027 
   1028 char *
   1029 AcpiUtStrcat (
   1030     char                    *String1,
   1031     char                    *String2)
   1032 {
   1033     UINT32                  String1Length = strlen (String1);
   1034     char                    *NewString = (char *) UtLocalCalloc (strlen (String1) + strlen (String2) + 1);
   1035 
   1036     strcpy (NewString, String1);
   1037     strcpy (NewString + String1Length, String2);
   1038     return (NewString);
   1039 }
   1040