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