1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: aslutils -- compiler utilities
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45118611Snjl#include "aslcompiler.y.h"
46209746Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
47193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49213806Sjkim#include <contrib/dev/acpica/include/acapps.h>
50306536Sjkim#include <sys/stat.h>
51118611Snjl
52306536Sjkim
53118611Snjl#define _COMPONENT          ACPI_COMPILER
54118611Snjl        ACPI_MODULE_NAME    ("aslutils")
55118611Snjl
56228110Sjkim
57151937Sjkim/* Local prototypes */
58118611Snjl
59151937Sjkimstatic void
60151937SjkimUtPadNameWithUnderscores (
61151937Sjkim    char                    *NameSeg,
62151937Sjkim    char                    *PaddedNameSeg);
63118611Snjl
64151937Sjkimstatic void
65151937SjkimUtAttachNameseg (
66151937Sjkim    ACPI_PARSE_OBJECT       *Op,
67151937Sjkim    char                    *Name);
68151937Sjkim
69151937Sjkim
70118611Snjl/*******************************************************************************
71118611Snjl *
72306536Sjkim * FUNCTION:    UtIsBigEndianMachine
73306536Sjkim *
74306536Sjkim * PARAMETERS:  None
75306536Sjkim *
76306536Sjkim * RETURN:      TRUE if machine is big endian
77306536Sjkim *              FALSE if machine is little endian
78306536Sjkim *
79306536Sjkim * DESCRIPTION: Detect whether machine is little endian or big endian.
80306536Sjkim *
81306536Sjkim ******************************************************************************/
82306536Sjkim
83306536SjkimUINT8
84306536SjkimUtIsBigEndianMachine (
85306536Sjkim    void)
86306536Sjkim{
87306536Sjkim    union {
88306536Sjkim        UINT32              Integer;
89306536Sjkim        UINT8               Bytes[4];
90306536Sjkim    } Overlay =                 {0xFF000000};
91306536Sjkim
92306536Sjkim
93306536Sjkim    return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
94306536Sjkim}
95306536Sjkim
96306536Sjkim
97306536Sjkim/******************************************************************************
98306536Sjkim *
99306536Sjkim * FUNCTION:    UtQueryForOverwrite
100306536Sjkim *
101306536Sjkim * PARAMETERS:  Pathname            - Output filename
102306536Sjkim *
103306536Sjkim * RETURN:      TRUE if file does not exist or overwrite is authorized
104306536Sjkim *
105306536Sjkim * DESCRIPTION: Query for file overwrite if it already exists.
106306536Sjkim *
107306536Sjkim ******************************************************************************/
108306536Sjkim
109306536SjkimBOOLEAN
110306536SjkimUtQueryForOverwrite (
111306536Sjkim    char                    *Pathname)
112306536Sjkim{
113306536Sjkim    struct stat             StatInfo;
114306536Sjkim
115306536Sjkim
116306536Sjkim    if (!stat (Pathname, &StatInfo))
117306536Sjkim    {
118306536Sjkim        fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ",
119306536Sjkim            Pathname);
120306536Sjkim
121306536Sjkim        if (getchar () != 'y')
122306536Sjkim        {
123306536Sjkim            return (FALSE);
124306536Sjkim        }
125306536Sjkim    }
126306536Sjkim
127306536Sjkim    return (TRUE);
128306536Sjkim}
129306536Sjkim
130306536Sjkim
131306536Sjkim/*******************************************************************************
132306536Sjkim *
133209746Sjkim * FUNCTION:    UtDisplaySupportedTables
134209746Sjkim *
135209746Sjkim * PARAMETERS:  None
136209746Sjkim *
137209746Sjkim * RETURN:      None
138209746Sjkim *
139209746Sjkim * DESCRIPTION: Print all supported ACPI table names.
140209746Sjkim *
141209746Sjkim ******************************************************************************/
142209746Sjkim
143209746Sjkimvoid
144209746SjkimUtDisplaySupportedTables (
145209746Sjkim    void)
146209746Sjkim{
147284460Sjkim    const AH_TABLE          *TableData;
148239340Sjkim    UINT32                  i;
149209746Sjkim
150209746Sjkim
151239340Sjkim    printf ("\nACPI tables supported by iASL version %8.8X:\n"
152239340Sjkim        "  (Compiler, Disassembler, Template Generator)\n\n",
153239340Sjkim        ACPI_CA_VERSION);
154209746Sjkim
155284460Sjkim    /* All ACPI tables with the common table header */
156209746Sjkim
157284460Sjkim    printf ("\n  Supported ACPI tables:\n");
158284460Sjkim    for (TableData = AcpiSupportedTables, i = 1;
159284460Sjkim         TableData->Signature; TableData++, i++)
160209746Sjkim    {
161284460Sjkim        printf ("%8u) %s    %s\n", i,
162284460Sjkim            TableData->Signature, TableData->Description);
163209746Sjkim    }
164209746Sjkim}
165209746Sjkim
166209746Sjkim
167209746Sjkim/*******************************************************************************
168209746Sjkim *
169237412Sjkim * FUNCTION:    UtDisplayConstantOpcodes
170118611Snjl *
171118611Snjl * PARAMETERS:  None
172118611Snjl *
173118611Snjl * RETURN:      None
174118611Snjl *
175118611Snjl * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
176118611Snjl *
177118611Snjl ******************************************************************************/
178118611Snjl
179118611Snjlvoid
180118611SnjlUtDisplayConstantOpcodes (
181118611Snjl    void)
182118611Snjl{
183167802Sjkim    UINT32                  i;
184118611Snjl
185151937Sjkim
186118611Snjl    printf ("Constant expression opcode information\n\n");
187118611Snjl
188118611Snjl    for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
189118611Snjl    {
190118611Snjl        if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
191118611Snjl        {
192118611Snjl            printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
193118611Snjl        }
194118611Snjl    }
195118611Snjl}
196118611Snjl
197118611Snjl
198118611Snjl/*******************************************************************************
199118611Snjl *
200118611Snjl * FUNCTION:    UtLocalCalloc
201118611Snjl *
202237412Sjkim * PARAMETERS:  Size                - Bytes to be allocated
203118611Snjl *
204237412Sjkim * RETURN:      Pointer to the allocated memory. Guaranteed to be valid.
205118611Snjl *
206237412Sjkim * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
207118611Snjl *              allocation failure, on the assumption that nothing more can be
208118611Snjl *              accomplished.
209118611Snjl *
210118611Snjl ******************************************************************************/
211118611Snjl
212118611Snjlvoid *
213118611SnjlUtLocalCalloc (
214118611Snjl    UINT32                  Size)
215118611Snjl{
216118611Snjl    void                    *Allocated;
217118611Snjl
218118611Snjl
219167802Sjkim    Allocated = ACPI_ALLOCATE_ZEROED (Size);
220118611Snjl    if (!Allocated)
221118611Snjl    {
222118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
223118611Snjl            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
224118611Snjl            Gbl_InputByteCount, Gbl_CurrentColumn,
225118611Snjl            Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
226209746Sjkim
227209746Sjkim        CmCleanupAndExit ();
228118611Snjl        exit (1);
229118611Snjl    }
230118611Snjl
231118611Snjl    TotalAllocations++;
232118611Snjl    TotalAllocated += Size;
233167802Sjkim    return (Allocated);
234118611Snjl}
235118611Snjl
236118611Snjl
237118611Snjl/*******************************************************************************
238118611Snjl *
239118611Snjl * FUNCTION:    UtBeginEvent
240118611Snjl *
241237412Sjkim * PARAMETERS:  Name                - Ascii name of this event
242118611Snjl *
243237412Sjkim * RETURN:      Event number (integer index)
244118611Snjl *
245118611Snjl * DESCRIPTION: Saves the current time with this event
246118611Snjl *
247118611Snjl ******************************************************************************/
248118611Snjl
249151937SjkimUINT8
250118611SnjlUtBeginEvent (
251118611Snjl    char                    *Name)
252118611Snjl{
253118611Snjl
254151937Sjkim    if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
255151937Sjkim    {
256151937Sjkim        AcpiOsPrintf ("Ran out of compiler event structs!\n");
257151937Sjkim        return (AslGbl_NextEvent);
258151937Sjkim    }
259151937Sjkim
260151937Sjkim    /* Init event with current (start) time */
261151937Sjkim
262151937Sjkim    AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
263151937Sjkim    AslGbl_Events[AslGbl_NextEvent].EventName = Name;
264151937Sjkim    AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
265151937Sjkim    return (AslGbl_NextEvent++);
266118611Snjl}
267118611Snjl
268118611Snjl
269118611Snjl/*******************************************************************************
270118611Snjl *
271118611Snjl * FUNCTION:    UtEndEvent
272118611Snjl *
273237412Sjkim * PARAMETERS:  Event               - Event number (integer index)
274118611Snjl *
275118611Snjl * RETURN:      None
276118611Snjl *
277118611Snjl * DESCRIPTION: Saves the current time (end time) with this event
278118611Snjl *
279118611Snjl ******************************************************************************/
280118611Snjl
281118611Snjlvoid
282118611SnjlUtEndEvent (
283237412Sjkim    UINT8                   Event)
284118611Snjl{
285118611Snjl
286151937Sjkim    if (Event >= ASL_NUM_EVENTS)
287151937Sjkim    {
288151937Sjkim        return;
289151937Sjkim    }
290151937Sjkim
291151937Sjkim    /* Insert end time for event */
292151937Sjkim
293151937Sjkim    AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
294118611Snjl}
295118611Snjl
296118611Snjl
297118611Snjl/*******************************************************************************
298118611Snjl *
299118611Snjl * FUNCTION:    DbgPrint
300118611Snjl *
301237412Sjkim * PARAMETERS:  Type                - Type of output
302237412Sjkim *              Fmt                 - Printf format string
303237412Sjkim *              ...                 - variable printf list
304118611Snjl *
305118611Snjl * RETURN:      None
306118611Snjl *
307237412Sjkim * DESCRIPTION: Conditional print statement. Prints to stderr only if the
308118611Snjl *              debug flag is set.
309118611Snjl *
310118611Snjl ******************************************************************************/
311118611Snjl
312118611Snjlvoid
313118611SnjlDbgPrint (
314118611Snjl    UINT32                  Type,
315118611Snjl    char                    *Fmt,
316118611Snjl    ...)
317118611Snjl{
318118611Snjl    va_list                 Args;
319118611Snjl
320118611Snjl
321118611Snjl    if (!Gbl_DebugFlag)
322118611Snjl    {
323118611Snjl        return;
324118611Snjl    }
325118611Snjl
326118611Snjl    if ((Type == ASL_PARSE_OUTPUT) &&
327118611Snjl        (!(AslCompilerdebug)))
328118611Snjl    {
329118611Snjl        return;
330118611Snjl    }
331118611Snjl
332252279Sjkim    va_start (Args, Fmt);
333118611Snjl    (void) vfprintf (stderr, Fmt, Args);
334118611Snjl    va_end (Args);
335118611Snjl    return;
336118611Snjl}
337118611Snjl
338118611Snjl
339118611Snjl/*******************************************************************************
340118611Snjl *
341118611Snjl * FUNCTION:    UtSetParseOpName
342118611Snjl *
343237412Sjkim * PARAMETERS:  Op                  - Parse op to be named.
344118611Snjl *
345118611Snjl * RETURN:      None
346118611Snjl *
347118611Snjl * DESCRIPTION: Insert the ascii name of the parse opcode
348118611Snjl *
349118611Snjl ******************************************************************************/
350118611Snjl
351118611Snjlvoid
352118611SnjlUtSetParseOpName (
353118611Snjl    ACPI_PARSE_OBJECT       *Op)
354118611Snjl{
355151937Sjkim
356167802Sjkim    strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
357167802Sjkim        ACPI_MAX_PARSEOP_NAME);
358118611Snjl}
359118611Snjl
360118611Snjl
361118611Snjl/*******************************************************************************
362118611Snjl *
363118611Snjl * FUNCTION:    UtDisplaySummary
364118611Snjl *
365237412Sjkim * PARAMETERS:  FileID              - ID of outpout file
366118611Snjl *
367118611Snjl * RETURN:      None
368118611Snjl *
369118611Snjl * DESCRIPTION: Display compilation statistics
370118611Snjl *
371118611Snjl ******************************************************************************/
372118611Snjl
373118611Snjlvoid
374118611SnjlUtDisplaySummary (
375118611Snjl    UINT32                  FileId)
376118611Snjl{
377228110Sjkim    UINT32                  i;
378118611Snjl
379228110Sjkim
380118611Snjl    if (FileId != ASL_FILE_STDOUT)
381118611Snjl    {
382118611Snjl        /* Compiler name and version number */
383118611Snjl
384228110Sjkim        FlPrintFile (FileId, "%s version %X%s\n\n",
385213806Sjkim            ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH);
386118611Snjl    }
387118611Snjl
388228110Sjkim    /* Summary of main input and output files */
389228110Sjkim
390209746Sjkim    if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
391209746Sjkim    {
392209746Sjkim        FlPrintFile (FileId,
393228110Sjkim            "%-14s %s - %u lines, %u bytes, %u fields\n",
394228110Sjkim            "Table Input:",
395209746Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
396209746Sjkim            Gbl_InputByteCount, Gbl_InputFieldCount);
397118611Snjl
398209746Sjkim        if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
399209746Sjkim        {
400209746Sjkim            FlPrintFile (FileId,
401228110Sjkim                "%-14s %s - %u bytes\n",
402228110Sjkim                "Binary Output:",
403209746Sjkim                Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
404209746Sjkim        }
405209746Sjkim    }
406209746Sjkim    else
407209746Sjkim    {
408209746Sjkim        FlPrintFile (FileId,
409228110Sjkim            "%-14s %s - %u lines, %u bytes, %u keywords\n",
410228110Sjkim            "ASL Input:",
411209746Sjkim            Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
412306536Sjkim            Gbl_OriginalInputFileSize, TotalKeywords);
413118611Snjl
414209746Sjkim        /* AML summary */
415209746Sjkim
416209746Sjkim        if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
417209746Sjkim        {
418306536Sjkim            if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
419306536Sjkim            {
420306536Sjkim                FlPrintFile (FileId,
421306536Sjkim                    "%-14s %s - %u bytes, %u named objects, "
422306536Sjkim                    "%u executable opcodes\n",
423306536Sjkim                    "AML Output:",
424306536Sjkim                    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename,
425306536Sjkim                    FlGetFileSize (ASL_FILE_AML_OUTPUT),
426306536Sjkim                    TotalNamedObjects, TotalExecutableOpcodes);
427306536Sjkim            }
428209746Sjkim        }
429118611Snjl    }
430118611Snjl
431228110Sjkim    /* Display summary of any optional files */
432228110Sjkim
433228110Sjkim    for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
434228110Sjkim    {
435228110Sjkim        if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
436228110Sjkim        {
437228110Sjkim            continue;
438228110Sjkim        }
439228110Sjkim
440228110Sjkim        /* .SRC is a temp file unless specifically requested */
441228110Sjkim
442228110Sjkim        if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
443228110Sjkim        {
444228110Sjkim            continue;
445228110Sjkim        }
446228110Sjkim
447306536Sjkim        /* .PRE is the preprocessor intermediate file */
448233250Sjkim
449306536Sjkim        if ((i == ASL_FILE_PREPROCESSOR)  && (!Gbl_KeepPreprocessorTempFile))
450233250Sjkim        {
451233250Sjkim            continue;
452233250Sjkim        }
453233250Sjkim
454228110Sjkim        FlPrintFile (FileId, "%14s %s - %u bytes\n",
455240716Sjkim            Gbl_Files[i].ShortDescription,
456228110Sjkim            Gbl_Files[i].Filename, FlGetFileSize (i));
457228110Sjkim    }
458228110Sjkim
459118611Snjl    /* Error summary */
460118611Snjl
461118611Snjl    FlPrintFile (FileId,
462228110Sjkim        "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
463118611Snjl        Gbl_ExceptionCount[ASL_ERROR],
464167802Sjkim        Gbl_ExceptionCount[ASL_WARNING] +
465167802Sjkim            Gbl_ExceptionCount[ASL_WARNING2] +
466167802Sjkim            Gbl_ExceptionCount[ASL_WARNING3],
467209746Sjkim        Gbl_ExceptionCount[ASL_REMARK]);
468209746Sjkim
469209746Sjkim    if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
470209746Sjkim    {
471281687Sjkim        FlPrintFile (FileId, ", %u Optimizations",
472281687Sjkim            Gbl_ExceptionCount[ASL_OPTIMIZATION]);
473281687Sjkim
474281687Sjkim        if (TotalFolds)
475281687Sjkim        {
476281687Sjkim            FlPrintFile (FileId, ", %u Constants Folded", TotalFolds);
477281687Sjkim        }
478209746Sjkim    }
479209746Sjkim
480209746Sjkim    FlPrintFile (FileId, "\n");
481118611Snjl}
482118611Snjl
483118611Snjl
484118611Snjl/*******************************************************************************
485118611Snjl *
486237412Sjkim * FUNCTION:    UtCheckIntegerRange
487118611Snjl *
488237412Sjkim * PARAMETERS:  Op                  - Integer parse node
489237412Sjkim *              LowValue            - Smallest allowed value
490237412Sjkim *              HighValue           - Largest allowed value
491118611Snjl *
492118611Snjl * RETURN:      Op if OK, otherwise NULL
493118611Snjl *
494118611Snjl * DESCRIPTION: Check integer for an allowable range
495118611Snjl *
496118611Snjl ******************************************************************************/
497118611Snjl
498118611SnjlACPI_PARSE_OBJECT *
499118611SnjlUtCheckIntegerRange (
500118611Snjl    ACPI_PARSE_OBJECT       *Op,
501118611Snjl    UINT32                  LowValue,
502118611Snjl    UINT32                  HighValue)
503118611Snjl{
504118611Snjl
505118611Snjl    if (!Op)
506118611Snjl    {
507241973Sjkim        return (NULL);
508118611Snjl    }
509118611Snjl
510239340Sjkim    if ((Op->Asl.Value.Integer < LowValue) ||
511239340Sjkim        (Op->Asl.Value.Integer > HighValue))
512118611Snjl    {
513239340Sjkim        sprintf (MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
514239340Sjkim            (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
515118611Snjl
516239340Sjkim        AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
517239340Sjkim        return (NULL);
518118611Snjl    }
519118611Snjl
520239340Sjkim    return (Op);
521118611Snjl}
522118611Snjl
523118611Snjl
524118611Snjl/*******************************************************************************
525118611Snjl *
526281075Sdim * FUNCTION:    UtStringCacheCalloc
527118611Snjl *
528237412Sjkim * PARAMETERS:  Length              - Size of buffer requested
529118611Snjl *
530237412Sjkim * RETURN:      Pointer to the buffer. Aborts on allocation failure
531118611Snjl *
532237412Sjkim * DESCRIPTION: Allocate a string buffer. Bypass the local
533118611Snjl *              dynamic memory manager for performance reasons (This has a
534118611Snjl *              major impact on the speed of the compiler.)
535118611Snjl *
536118611Snjl ******************************************************************************/
537118611Snjl
538118611Snjlchar *
539281075SdimUtStringCacheCalloc (
540118611Snjl    UINT32                  Length)
541118611Snjl{
542118611Snjl    char                    *Buffer;
543281075Sdim    ASL_CACHE_INFO          *Cache;
544281075Sdim    UINT32                  CacheSize = ASL_STRING_CACHE_SIZE;
545118611Snjl
546118611Snjl
547281075Sdim    if (Length > CacheSize)
548281075Sdim    {
549281075Sdim        CacheSize = Length;
550281075Sdim
551281075Sdim        if (Gbl_StringCacheList)
552281075Sdim        {
553281075Sdim            Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
554281075Sdim
555281075Sdim            /* Link new cache buffer just following head of list */
556281075Sdim
557281075Sdim            Cache->Next = Gbl_StringCacheList->Next;
558281075Sdim            Gbl_StringCacheList->Next = Cache;
559281075Sdim
560281075Sdim            /* Leave cache management pointers alone as they pertain to head */
561281075Sdim
562281075Sdim            Gbl_StringCount++;
563281075Sdim            Gbl_StringSize += Length;
564281075Sdim
565281075Sdim            return (Cache->Buffer);
566281075Sdim        }
567281075Sdim    }
568281075Sdim
569118611Snjl    if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
570118611Snjl    {
571281075Sdim        /* Allocate a new buffer */
572281075Sdim
573281075Sdim        Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
574281075Sdim
575281075Sdim        /* Link new cache buffer to head of list */
576281075Sdim
577281075Sdim        Cache->Next = Gbl_StringCacheList;
578281075Sdim        Gbl_StringCacheList = Cache;
579281075Sdim
580281075Sdim        /* Setup cache management pointers */
581281075Sdim
582281075Sdim        Gbl_StringCacheNext = Cache->Buffer;
583281075Sdim        Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
584118611Snjl    }
585118611Snjl
586281075Sdim    Gbl_StringCount++;
587281075Sdim    Gbl_StringSize += Length;
588281075Sdim
589118611Snjl    Buffer = Gbl_StringCacheNext;
590118611Snjl    Gbl_StringCacheNext += Length;
591118611Snjl    return (Buffer);
592118611Snjl}
593118611Snjl
594118611Snjl
595240716Sjkim/******************************************************************************
596240716Sjkim *
597240716Sjkim * FUNCTION:    UtExpandLineBuffers
598240716Sjkim *
599240716Sjkim * PARAMETERS:  None. Updates global line buffer pointers.
600240716Sjkim *
601240716Sjkim * RETURN:      None. Reallocates the global line buffers
602240716Sjkim *
603240716Sjkim * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
604240716Sjkim *              all global line buffers and updates Gbl_LineBufferSize. NOTE:
605240716Sjkim *              Also used for the initial allocation of the buffers, when
606240716Sjkim *              all of the buffer pointers are NULL. Initial allocations are
607240716Sjkim *              of size ASL_DEFAULT_LINE_BUFFER_SIZE
608240716Sjkim *
609240716Sjkim *****************************************************************************/
610240716Sjkim
611240716Sjkimvoid
612240716SjkimUtExpandLineBuffers (
613240716Sjkim    void)
614240716Sjkim{
615240716Sjkim    UINT32                  NewSize;
616240716Sjkim
617240716Sjkim
618240716Sjkim    /* Attempt to double the size of all line buffers */
619240716Sjkim
620240716Sjkim    NewSize = Gbl_LineBufferSize * 2;
621240716Sjkim    if (Gbl_CurrentLineBuffer)
622240716Sjkim    {
623281075Sdim        DbgPrint (ASL_DEBUG_OUTPUT,
624281075Sdim            "Increasing line buffer size from %u to %u\n",
625240716Sjkim            Gbl_LineBufferSize, NewSize);
626240716Sjkim    }
627240716Sjkim
628240716Sjkim    Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize);
629240716Sjkim    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
630240716Sjkim    if (!Gbl_CurrentLineBuffer)
631240716Sjkim    {
632240716Sjkim        goto ErrorExit;
633240716Sjkim    }
634240716Sjkim
635240716Sjkim    Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize);
636240716Sjkim    if (!Gbl_MainTokenBuffer)
637240716Sjkim    {
638240716Sjkim        goto ErrorExit;
639240716Sjkim    }
640240716Sjkim
641240716Sjkim    Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize);
642240716Sjkim    if (!Gbl_MacroTokenBuffer)
643240716Sjkim    {
644240716Sjkim        goto ErrorExit;
645240716Sjkim    }
646240716Sjkim
647240716Sjkim    Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize);
648240716Sjkim    if (!Gbl_ExpressionTokenBuffer)
649240716Sjkim    {
650240716Sjkim        goto ErrorExit;
651240716Sjkim    }
652240716Sjkim
653240716Sjkim    Gbl_LineBufferSize = NewSize;
654240716Sjkim    return;
655240716Sjkim
656240716Sjkim
657240716Sjkim    /* On error above, simply issue error messages and abort, cannot continue */
658240716Sjkim
659240716SjkimErrorExit:
660240716Sjkim    printf ("Could not increase line buffer size from %u to %u\n",
661240716Sjkim        Gbl_LineBufferSize, Gbl_LineBufferSize * 2);
662240716Sjkim
663240716Sjkim    AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION,
664240716Sjkim        NULL, NULL);
665240716Sjkim    AslAbort ();
666240716Sjkim}
667240716Sjkim
668240716Sjkim
669281075Sdim/******************************************************************************
670281075Sdim *
671281075Sdim * FUNCTION:    UtFreeLineBuffers
672281075Sdim *
673281075Sdim * PARAMETERS:  None
674281075Sdim *
675281075Sdim * RETURN:      None
676281075Sdim *
677281075Sdim * DESCRIPTION: Free all line buffers
678281075Sdim *
679281075Sdim *****************************************************************************/
680281075Sdim
681281075Sdimvoid
682281075SdimUtFreeLineBuffers (
683281075Sdim    void)
684281075Sdim{
685281075Sdim
686281075Sdim    free (Gbl_CurrentLineBuffer);
687281075Sdim    free (Gbl_MainTokenBuffer);
688281075Sdim    free (Gbl_MacroTokenBuffer);
689281075Sdim    free (Gbl_ExpressionTokenBuffer);
690281075Sdim}
691281075Sdim
692281075Sdim
693118611Snjl/*******************************************************************************
694118611Snjl *
695118611Snjl * FUNCTION:    UtInternalizeName
696118611Snjl *
697237412Sjkim * PARAMETERS:  ExternalName        - Name to convert
698237412Sjkim *              ConvertedName       - Where the converted name is returned
699118611Snjl *
700118611Snjl * RETURN:      Status
701118611Snjl *
702118611Snjl * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
703118611Snjl *
704118611Snjl ******************************************************************************/
705118611Snjl
706118611SnjlACPI_STATUS
707118611SnjlUtInternalizeName (
708118611Snjl    char                    *ExternalName,
709118611Snjl    char                    **ConvertedName)
710118611Snjl{
711118611Snjl    ACPI_NAMESTRING_INFO    Info;
712118611Snjl    ACPI_STATUS             Status;
713118611Snjl
714118611Snjl
715118611Snjl    if (!ExternalName)
716118611Snjl    {
717118611Snjl        return (AE_OK);
718118611Snjl    }
719118611Snjl
720118611Snjl    /* Get the length of the new internal name */
721118611Snjl
722118611Snjl    Info.ExternalName = ExternalName;
723118611Snjl    AcpiNsGetInternalNameLength (&Info);
724118611Snjl
725281075Sdim    /* We need a segment to store the internal name */
726118611Snjl
727281075Sdim    Info.InternalName = UtStringCacheCalloc (Info.Length);
728118611Snjl    if (!Info.InternalName)
729118611Snjl    {
730118611Snjl        return (AE_NO_MEMORY);
731118611Snjl    }
732118611Snjl
733118611Snjl    /* Build the name */
734118611Snjl
735118611Snjl    Status = AcpiNsBuildInternalName (&Info);
736118611Snjl    if (ACPI_FAILURE (Status))
737118611Snjl    {
738118611Snjl        return (Status);
739118611Snjl    }
740118611Snjl
741118611Snjl    *ConvertedName = Info.InternalName;
742118611Snjl    return (AE_OK);
743118611Snjl}
744118611Snjl
745118611Snjl
746118611Snjl/*******************************************************************************
747118611Snjl *
748118611Snjl * FUNCTION:    UtPadNameWithUnderscores
749118611Snjl *
750237412Sjkim * PARAMETERS:  NameSeg             - Input nameseg
751237412Sjkim *              PaddedNameSeg       - Output padded nameseg
752118611Snjl *
753118611Snjl * RETURN:      Padded nameseg.
754118611Snjl *
755118611Snjl * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
756118611Snjl *              ACPI_NAME.
757118611Snjl *
758118611Snjl ******************************************************************************/
759118611Snjl
760151937Sjkimstatic void
761118611SnjlUtPadNameWithUnderscores (
762118611Snjl    char                    *NameSeg,
763118611Snjl    char                    *PaddedNameSeg)
764118611Snjl{
765118611Snjl    UINT32                  i;
766118611Snjl
767118611Snjl
768118611Snjl    for (i = 0; (i < ACPI_NAME_SIZE); i++)
769118611Snjl    {
770118611Snjl        if (*NameSeg)
771118611Snjl        {
772118611Snjl            *PaddedNameSeg = *NameSeg;
773118611Snjl            NameSeg++;
774118611Snjl        }
775118611Snjl        else
776118611Snjl        {
777118611Snjl            *PaddedNameSeg = '_';
778118611Snjl        }
779306536Sjkim
780118611Snjl        PaddedNameSeg++;
781118611Snjl    }
782118611Snjl}
783118611Snjl
784118611Snjl
785118611Snjl/*******************************************************************************
786118611Snjl *
787118611Snjl * FUNCTION:    UtAttachNameseg
788118611Snjl *
789237412Sjkim * PARAMETERS:  Op                  - Parent parse node
790237412Sjkim *              Name                - Full ExternalName
791118611Snjl *
792151937Sjkim * RETURN:      None; Sets the NameSeg field in parent node
793118611Snjl *
794118611Snjl * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
795118611Snjl *              in the NameSeg field of the Op.
796118611Snjl *
797118611Snjl ******************************************************************************/
798118611Snjl
799151937Sjkimstatic void
800118611SnjlUtAttachNameseg (
801118611Snjl    ACPI_PARSE_OBJECT       *Op,
802118611Snjl    char                    *Name)
803118611Snjl{
804118611Snjl    char                    *NameSeg;
805118611Snjl    char                    PaddedNameSeg[4];
806118611Snjl
807118611Snjl
808118611Snjl    if (!Name)
809118611Snjl    {
810118611Snjl        return;
811118611Snjl    }
812118611Snjl
813118611Snjl    /* Look for the last dot in the namepath */
814118611Snjl
815118611Snjl    NameSeg = strrchr (Name, '.');
816118611Snjl    if (NameSeg)
817118611Snjl    {
818118611Snjl        /* Found last dot, we have also found the final nameseg */
819118611Snjl
820118611Snjl        NameSeg++;
821118611Snjl        UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
822118611Snjl    }
823118611Snjl    else
824118611Snjl    {
825118611Snjl        /* No dots in the namepath, there is only a single nameseg. */
826118611Snjl        /* Handle prefixes */
827118611Snjl
828245582Sjkim        while (ACPI_IS_ROOT_PREFIX (*Name) ||
829245582Sjkim               ACPI_IS_PARENT_PREFIX (*Name))
830118611Snjl        {
831118611Snjl            Name++;
832118611Snjl        }
833118611Snjl
834241973Sjkim        /* Remaining string should be one single nameseg */
835118611Snjl
836118611Snjl        UtPadNameWithUnderscores (Name, PaddedNameSeg);
837118611Snjl    }
838118611Snjl
839241973Sjkim    ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg);
840118611Snjl}
841118611Snjl
842118611Snjl
843118611Snjl/*******************************************************************************
844118611Snjl *
845118611Snjl * FUNCTION:    UtAttachNamepathToOwner
846118611Snjl *
847237412Sjkim * PARAMETERS:  Op                  - Parent parse node
848237412Sjkim *              NameOp              - Node that contains the name
849118611Snjl *
850118611Snjl * RETURN:      Sets the ExternalName and Namepath in the parent node
851118611Snjl *
852237412Sjkim * DESCRIPTION: Store the name in two forms in the parent node: The original
853118611Snjl *              (external) name, and the internalized name that is used within
854118611Snjl *              the ACPI namespace manager.
855118611Snjl *
856118611Snjl ******************************************************************************/
857118611Snjl
858118611Snjlvoid
859118611SnjlUtAttachNamepathToOwner (
860118611Snjl    ACPI_PARSE_OBJECT       *Op,
861118611Snjl    ACPI_PARSE_OBJECT       *NameOp)
862118611Snjl{
863118611Snjl    ACPI_STATUS             Status;
864118611Snjl
865118611Snjl
866118611Snjl    /* Full external path */
867118611Snjl
868118611Snjl    Op->Asl.ExternalName = NameOp->Asl.Value.String;
869118611Snjl
870151937Sjkim    /* Save the NameOp for possible error reporting later */
871151937Sjkim
872151937Sjkim    Op->Asl.ParentMethod = (void *) NameOp;
873151937Sjkim
874118611Snjl    /* Last nameseg of the path */
875118611Snjl
876118611Snjl    UtAttachNameseg (Op, Op->Asl.ExternalName);
877118611Snjl
878118611Snjl    /* Create internalized path */
879118611Snjl
880118611Snjl    Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
881118611Snjl    if (ACPI_FAILURE (Status))
882118611Snjl    {
883118611Snjl        /* TBD: abort on no memory */
884118611Snjl    }
885118611Snjl}
886118611Snjl
887118611Snjl
888118611Snjl/*******************************************************************************
889118611Snjl *
890118611Snjl * FUNCTION:    UtDoConstant
891118611Snjl *
892237412Sjkim * PARAMETERS:  String              - Hex, Octal, or Decimal string
893118611Snjl *
894118611Snjl * RETURN:      Converted Integer
895118611Snjl *
896237412Sjkim * DESCRIPTION: Convert a string to an integer, with error checking.
897118611Snjl *
898118611Snjl ******************************************************************************/
899118611Snjl
900202771SjkimUINT64
901118611SnjlUtDoConstant (
902118611Snjl    char                    *String)
903118611Snjl{
904118611Snjl    ACPI_STATUS             Status;
905202771Sjkim    UINT64                  Converted;
906118611Snjl    char                    ErrBuf[64];
907118611Snjl
908118611Snjl
909306536Sjkim    Status = AcpiUtStrtoul64 (String, ACPI_ANY_BASE,
910306536Sjkim        ACPI_MAX64_BYTE_WIDTH, &Converted);
911306536Sjkim
912118611Snjl    if (ACPI_FAILURE (Status))
913118611Snjl    {
914151937Sjkim        sprintf (ErrBuf, "%s %s\n", "Conversion error:",
915151937Sjkim            AcpiFormatException (Status));
916118611Snjl        AslCompilererror (ErrBuf);
917118611Snjl    }
918118611Snjl
919118611Snjl    return (Converted);
920118611Snjl}
921118611Snjl
922118611Snjl
923306536Sjkim#ifdef _OBSOLETE_FUNCTIONS
924306536Sjkim/* Removed 01/2016 */
925151937Sjkim
926118611Snjl/*******************************************************************************
927118611Snjl *
928306536Sjkim * FUNCTION:    UtConvertByteToHex
929118611Snjl *
930306536Sjkim * PARAMETERS:  RawByte             - Binary data
931306536Sjkim *              Buffer              - Pointer to where the hex bytes will be
932306536Sjkim *                                    stored
933118611Snjl *
934306536Sjkim * RETURN:      Ascii hex byte is stored in Buffer.
935118611Snjl *
936306536Sjkim * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
937306536Sjkim *              with "0x"
938118611Snjl *
939118611Snjl ******************************************************************************/
940118611Snjl
941306536Sjkimvoid
942306536SjkimUtConvertByteToHex (
943306536Sjkim    UINT8                   RawByte,
944306536Sjkim    UINT8                   *Buffer)
945118611Snjl{
946118611Snjl
947306536Sjkim    Buffer[0] = '0';
948306536Sjkim    Buffer[1] = 'x';
949118611Snjl
950306536Sjkim    Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
951306536Sjkim    Buffer[3] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
952306536Sjkim}
953118611Snjl
954250838Sjkim
955306536Sjkim/*******************************************************************************
956306536Sjkim *
957306536Sjkim * FUNCTION:    UtConvertByteToAsmHex
958306536Sjkim *
959306536Sjkim * PARAMETERS:  RawByte             - Binary data
960306536Sjkim *              Buffer              - Pointer to where the hex bytes will be
961306536Sjkim *                                    stored
962306536Sjkim *
963306536Sjkim * RETURN:      Ascii hex byte is stored in Buffer.
964306536Sjkim *
965306536Sjkim * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
966306536Sjkim *              with '0', and a trailing 'h' is added.
967306536Sjkim *
968306536Sjkim ******************************************************************************/
969118611Snjl
970306536Sjkimvoid
971306536SjkimUtConvertByteToAsmHex (
972306536Sjkim    UINT8                   RawByte,
973306536Sjkim    UINT8                   *Buffer)
974306536Sjkim{
975118611Snjl
976306536Sjkim    Buffer[0] = '0';
977306536Sjkim    Buffer[1] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
978306536Sjkim    Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
979306536Sjkim    Buffer[3] = 'h';
980118611Snjl}
981306536Sjkim#endif /* OBSOLETE_FUNCTIONS */
982