1 /******************************************************************************
2 *
3 * Module Name: aslutils -- compiler utilities
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/include/acdisasm.h>
155 #include <contrib/dev/acpica/include/acnamesp.h>
156 #include <contrib/dev/acpica/include/amlcode.h>
157 #include <contrib/dev/acpica/include/acapps.h>
158 #include <sys/stat.h>
159
160
161 #define _COMPONENT ACPI_COMPILER
162 ACPI_MODULE_NAME ("aslutils")
163
164
165 /* Local prototypes */
166
167 static void
168 UtPadNameWithUnderscores (
169 char *NameSeg,
170 char *PaddedNameSeg);
171
172 static void
173 UtAttachNameseg (
174 ACPI_PARSE_OBJECT *Op,
175 char *Name);
176
177 static void
178 UtDisplayErrorSummary (
179 UINT32 FileId);
180
181
182 /*******************************************************************************
183 *
184 * FUNCTION: UtIsBigEndianMachine
185 *
186 * PARAMETERS: None
187 *
188 * RETURN: TRUE if machine is big endian
189 * FALSE if machine is little endian
190 *
191 * DESCRIPTION: Detect whether machine is little endian or big endian.
192 *
193 ******************************************************************************/
194
195 UINT8
UtIsBigEndianMachine(void)196 UtIsBigEndianMachine (
197 void)
198 {
199 union {
200 UINT32 Integer;
201 UINT8 Bytes[4];
202 } Overlay = {0xFF000000};
203
204
205 return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
206 }
207
208
209 /*******************************************************************************
210 *
211 * FUNCTION: UtIsIdInteger
212 *
213 * PARAMETERS: Pointer to an ACPI ID (HID, CID) string
214 *
215 * RETURN: TRUE if string is an integer
216 * FALSE if string is not an integer
217 *
218 * DESCRIPTION: Determine whether the input ACPI ID string can be converted to
219 * an integer value.
220 *
221 ******************************************************************************/
222
223 BOOLEAN
UtIsIdInteger(UINT8 * Target)224 UtIsIdInteger (
225 UINT8 *Target)
226 {
227 UINT32 i;
228
229
230 /* The first three characters of the string must be alphabetic */
231
232 for (i = 0; i < 3; i++)
233 {
234 if (!isalpha ((int) Target[i]))
235 {
236 break;
237 }
238 }
239
240 if (i < 3)
241 {
242 return (TRUE);
243 }
244
245 return (FALSE);
246 }
247
248
249 /******************************************************************************
250 *
251 * FUNCTION: UtQueryForOverwrite
252 *
253 * PARAMETERS: Pathname - Output filename
254 *
255 * RETURN: TRUE if file does not exist or overwrite is authorized
256 *
257 * DESCRIPTION: Query for file overwrite if it already exists.
258 *
259 ******************************************************************************/
260
261 BOOLEAN
UtQueryForOverwrite(char * Pathname)262 UtQueryForOverwrite (
263 char *Pathname)
264 {
265 struct stat StatInfo;
266 int InChar;
267
268
269 if (!stat (Pathname, &StatInfo))
270 {
271 fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ",
272 Pathname);
273
274 InChar = fgetc (stdin);
275 if (InChar == '\n')
276 {
277 InChar = fgetc (stdin);
278 }
279
280 if ((InChar != 'y') && (InChar != 'Y'))
281 {
282 return (FALSE);
283 }
284 }
285
286 return (TRUE);
287 }
288
289
290 /*******************************************************************************
291 *
292 * FUNCTION: UtNodeIsDescendantOf
293 *
294 * PARAMETERS: Node1 - Child node
295 * Node2 - Possible parent node
296 *
297 * RETURN: Boolean
298 *
299 * DESCRIPTION: Returns TRUE if Node1 is a descendant of Node2. Otherwise,
300 * return FALSE. Note, we assume a NULL Node2 element to be the
301 * topmost (root) scope. All nodes are descendants of the root.
302 * Note: Nodes at the same level (siblings) are not considered
303 * descendants.
304 *
305 ******************************************************************************/
306
307 BOOLEAN
UtNodeIsDescendantOf(ACPI_NAMESPACE_NODE * Node1,ACPI_NAMESPACE_NODE * Node2)308 UtNodeIsDescendantOf (
309 ACPI_NAMESPACE_NODE *Node1,
310 ACPI_NAMESPACE_NODE *Node2)
311 {
312
313 if (Node1 == Node2)
314 {
315 return (FALSE);
316 }
317
318 if (!Node2)
319 {
320 return (TRUE); /* All nodes descend from the root */
321 }
322
323 /* Walk upward until the root is reached or parent is found */
324
325 while (Node1)
326 {
327 if (Node1 == Node2)
328 {
329 return (TRUE);
330 }
331
332 Node1 = Node1->Parent;
333 }
334
335 return (FALSE);
336 }
337
338
339 /*******************************************************************************
340 *
341 * FUNCTION: UtGetParentMethodNode
342 *
343 * PARAMETERS: Node - Namespace node for any object
344 *
345 * RETURN: Namespace node for the parent method
346 * NULL - object is not within a method
347 *
348 * DESCRIPTION: Find the parent (owning) method node for a namespace object
349 *
350 ******************************************************************************/
351
352 ACPI_NAMESPACE_NODE *
UtGetParentMethodNode(ACPI_NAMESPACE_NODE * Node)353 UtGetParentMethodNode (
354 ACPI_NAMESPACE_NODE *Node)
355 {
356 ACPI_NAMESPACE_NODE *ParentNode;
357
358
359 if (!Node)
360 {
361 return (NULL);
362 }
363
364 /* Walk upward until a method is found, or the root is reached */
365
366 ParentNode = Node->Parent;
367 while (ParentNode)
368 {
369 if (ParentNode->Type == ACPI_TYPE_METHOD)
370 {
371 return (ParentNode);
372 }
373
374 ParentNode = ParentNode->Parent;
375 }
376
377 return (NULL); /* Object is not within a control method */
378 }
379
380
381 /*******************************************************************************
382 *
383 * FUNCTION: UtGetParentMethodOp
384 *
385 * PARAMETERS: Op - Parse Op to be checked
386 *
387 * RETURN: Control method Op if found. NULL otherwise
388 *
389 * DESCRIPTION: Find the control method parent of a parse op. Returns NULL if
390 * the input Op is not within a control method.
391 *
392 ******************************************************************************/
393
394 ACPI_PARSE_OBJECT *
UtGetParentMethodOp(ACPI_PARSE_OBJECT * Op)395 UtGetParentMethodOp (
396 ACPI_PARSE_OBJECT *Op)
397 {
398 ACPI_PARSE_OBJECT *NextOp;
399
400
401 NextOp = Op->Asl.Parent;
402 while (NextOp)
403 {
404 if (NextOp->Asl.AmlOpcode == AML_METHOD_OP)
405 {
406 return (NextOp);
407 }
408
409 NextOp = NextOp->Asl.Parent;
410 }
411
412 return (NULL); /* No parent method found */
413 }
414
415
416 /*******************************************************************************
417 *
418 * FUNCTION: UtDisplaySupportedTables
419 *
420 * PARAMETERS: None
421 *
422 * RETURN: None
423 *
424 * DESCRIPTION: Print all supported ACPI table names.
425 *
426 ******************************************************************************/
427
428 void
UtDisplaySupportedTables(void)429 UtDisplaySupportedTables (
430 void)
431 {
432 const AH_TABLE *TableData;
433 UINT32 i;
434
435
436 printf ("\nACPI tables supported by iASL version %8.8X:\n"
437 " (Compiler, Disassembler, Template Generator)\n",
438 ACPI_CA_VERSION);
439
440 /* All ACPI tables with the common table header */
441
442 printf ("\nKnown/Supported ACPI tables:\n");
443 for (TableData = AcpiGbl_SupportedTables, i = 1;
444 TableData->Signature; TableData++, i++)
445 {
446 printf ("%8u) %s %s\n", i,
447 TableData->Signature, TableData->Description);
448 }
449
450 printf ("\nTotal %u ACPI tables\n\n", i-1);
451 }
452
453
454 /*******************************************************************************
455 *
456 * FUNCTION: UtDisplayConstantOpcodes
457 *
458 * PARAMETERS: None
459 *
460 * RETURN: None
461 *
462 * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
463 *
464 ******************************************************************************/
465
466 void
UtDisplayConstantOpcodes(void)467 UtDisplayConstantOpcodes (
468 void)
469 {
470 UINT32 i;
471
472
473 printf ("Constant expression opcode information\n\n");
474
475 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
476 {
477 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
478 {
479 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
480 }
481 }
482 }
483
484
485 /*******************************************************************************
486 *
487 * FUNCTION: UtBeginEvent
488 *
489 * PARAMETERS: Name - Ascii name of this event
490 *
491 * RETURN: Event number (integer index)
492 *
493 * DESCRIPTION: Saves the current time with this event
494 *
495 ******************************************************************************/
496
497 UINT8
UtBeginEvent(char * Name)498 UtBeginEvent (
499 char *Name)
500 {
501
502 if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
503 {
504 AcpiOsPrintf ("Ran out of compiler event structs!\n");
505 return (AslGbl_NextEvent);
506 }
507
508 /* Init event with current (start) time */
509
510 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
511 AslGbl_Events[AslGbl_NextEvent].EventName = Name;
512 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
513 return (AslGbl_NextEvent++);
514 }
515
516
517 /*******************************************************************************
518 *
519 * FUNCTION: UtEndEvent
520 *
521 * PARAMETERS: Event - Event number (integer index)
522 *
523 * RETURN: None
524 *
525 * DESCRIPTION: Saves the current time (end time) with this event
526 *
527 ******************************************************************************/
528
529 void
UtEndEvent(UINT8 Event)530 UtEndEvent (
531 UINT8 Event)
532 {
533
534 if (Event >= ASL_NUM_EVENTS)
535 {
536 return;
537 }
538
539 /* Insert end time for event */
540
541 AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
542 }
543
544
545 /*******************************************************************************
546 *
547 * FUNCTION: DbgPrint
548 *
549 * PARAMETERS: Type - Type of output
550 * Fmt - Printf format string
551 * ... - variable printf list
552 *
553 * RETURN: None
554 *
555 * DESCRIPTION: Conditional print statement. Prints to stderr only if the
556 * debug flag is set.
557 *
558 ******************************************************************************/
559
560 void
DbgPrint(UINT32 Type,char * Fmt,...)561 DbgPrint (
562 UINT32 Type,
563 char *Fmt,
564 ...)
565 {
566 va_list Args;
567
568
569 if (!AslGbl_DebugFlag)
570 {
571 return;
572 }
573
574 if ((Type == ASL_PARSE_OUTPUT) &&
575 (!(AslCompilerdebug)))
576 {
577 return;
578 }
579
580 va_start (Args, Fmt);
581 (void) vfprintf (stderr, Fmt, Args);
582 va_end (Args);
583 return;
584 }
585
586
587 /*******************************************************************************
588 *
589 * FUNCTION: UtSetParseOpName
590 *
591 * PARAMETERS: Op - Parse op to be named.
592 *
593 * RETURN: None
594 *
595 * DESCRIPTION: Insert the ascii name of the parse opcode
596 *
597 ******************************************************************************/
598
599 void
UtSetParseOpName(ACPI_PARSE_OBJECT * Op)600 UtSetParseOpName (
601 ACPI_PARSE_OBJECT *Op)
602 {
603
604 AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
605 ACPI_MAX_PARSEOP_NAME);
606 }
607
608
609 /*******************************************************************************
610 *
611 * FUNCTION: UtDisplayOneSummary
612 *
613 * PARAMETERS: FileID - ID of output file
614 *
615 * RETURN: None
616 *
617 * DESCRIPTION: Display compilation statistics for one input file
618 *
619 ******************************************************************************/
620
621 void
UtDisplayOneSummary(UINT32 FileId,BOOLEAN DisplayErrorSummary)622 UtDisplayOneSummary (
623 UINT32 FileId,
624 BOOLEAN DisplayErrorSummary)
625 {
626 UINT32 i;
627 ASL_GLOBAL_FILE_NODE *FileNode;
628 BOOLEAN DisplayAMLSummary;
629
630
631 DisplayAMLSummary =
632 !AslGbl_PreprocessOnly && !AslGbl_ParserErrorDetected &&
633 ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || AslGbl_IgnoreErrors) &&
634 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle;
635
636 if (FileId != ASL_FILE_STDOUT)
637 {
638 /* Compiler name and version number */
639
640 FlPrintFile (FileId, "%s version %X\n\n",
641 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION);
642 }
643
644 /* Summary of main input and output files */
645
646 FileNode = FlGetCurrentFileNode ();
647
648 if (FileNode->ParserErrorDetected)
649 {
650 FlPrintFile (FileId,
651 "%-14s %s - Compilation aborted due to parser-detected syntax error(s)\n",
652 "Input file:", AslGbl_Files[ASL_FILE_INPUT].Filename);
653 }
654 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_DATA)
655 {
656 FlPrintFile (FileId,
657 "%-14s %s - %7u bytes %6u fields %8u source lines\n",
658 "Table Input:",
659 AslGbl_Files[ASL_FILE_INPUT].Filename,
660 FileNode->OriginalInputFileSize, FileNode->TotalFields,
661 FileNode->TotalLineCount);
662
663 FlPrintFile (FileId,
664 "%-14s %s - %7u bytes\n",
665 "Binary Output:",
666 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, FileNode->OutputByteLength);
667 }
668 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_ASL)
669 {
670 FlPrintFile (FileId,
671 "%-14s %s - %7u bytes %6u keywords %6u source lines\n",
672 "ASL Input:",
673 AslGbl_Files[ASL_FILE_INPUT].Filename,
674 FileNode->OriginalInputFileSize,
675 FileNode->TotalKeywords,
676 FileNode->TotalLineCount);
677
678 /* AML summary */
679
680 if (DisplayAMLSummary)
681 {
682 FlPrintFile (FileId,
683 "%-14s %s - %7u bytes %6u opcodes %6u named objects\n",
684 "AML Output:",
685 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename,
686 FlGetFileSize (ASL_FILE_AML_OUTPUT),
687 FileNode->TotalExecutableOpcodes,
688 FileNode->TotalNamedObjects);
689 }
690 }
691
692 /* Display summary of any optional files */
693
694 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
695 {
696 if (!AslGbl_Files[i].Filename || !AslGbl_Files[i].Handle)
697 {
698 continue;
699 }
700
701 /* .SRC is a temp file unless specifically requested */
702
703 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!AslGbl_SourceOutputFlag))
704 {
705 continue;
706 }
707
708 /* .PRE is the preprocessor intermediate file */
709
710 if ((i == ASL_FILE_PREPROCESSOR) && (!AslGbl_KeepPreprocessorTempFile))
711 {
712 continue;
713 }
714
715 FlPrintFile (FileId, "%-14s %s - %7u bytes\n",
716 AslGbl_FileDescs[i].ShortDescription,
717 AslGbl_Files[i].Filename, FlGetFileSize (i));
718 }
719
720
721 /*
722 * Optionally emit an error summary for a file. This is used to enhance the
723 * appearance of listing files.
724 */
725 if (DisplayErrorSummary)
726 {
727 UtDisplayErrorSummary (FileId);
728 }
729 }
730
731
732 /*******************************************************************************
733 *
734 * FUNCTION: UtDisplayErrorSummary
735 *
736 * PARAMETERS: FileID - ID of output file
737 *
738 * RETURN: None
739 *
740 * DESCRIPTION: Display compilation statistics for all input files
741 *
742 ******************************************************************************/
743
744 static void
UtDisplayErrorSummary(UINT32 FileId)745 UtDisplayErrorSummary (
746 UINT32 FileId)
747 {
748 BOOLEAN ErrorDetected;
749
750
751 ErrorDetected = AslGbl_ParserErrorDetected ||
752 ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && !AslGbl_IgnoreErrors);
753
754 if (ErrorDetected)
755 {
756 FlPrintFile (FileId, "\nCompilation failed. ");
757 }
758 else
759 {
760 FlPrintFile (FileId, "\nCompilation successful. ");
761 }
762
763 FlPrintFile (FileId,
764 "%u Errors, %u Warnings, %u Remarks",
765 AslGbl_ExceptionCount[ASL_ERROR],
766 AslGbl_ExceptionCount[ASL_WARNING] +
767 AslGbl_ExceptionCount[ASL_WARNING2] +
768 AslGbl_ExceptionCount[ASL_WARNING3],
769 AslGbl_ExceptionCount[ASL_REMARK]);
770
771 if (AslGbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
772 {
773 if (AslGbl_ParserErrorDetected)
774 {
775 FlPrintFile (FileId,
776 "\nNo AML files were generated due to syntax error(s)\n");
777 return;
778 }
779 else if (ErrorDetected)
780 {
781 FlPrintFile (FileId,
782 "\nNo AML files were generated due to compiler error(s)\n");
783 return;
784 }
785
786 FlPrintFile (FileId, ", %u Optimizations",
787 AslGbl_ExceptionCount[ASL_OPTIMIZATION]);
788
789 if (AslGbl_TotalFolds)
790 {
791 FlPrintFile (FileId, ", %u Constants Folded", AslGbl_TotalFolds);
792 }
793 }
794
795 FlPrintFile (FileId, "\n");
796 }
797
798
799 /*******************************************************************************
800 *
801 * FUNCTION: UtDisplaySummary
802 *
803 * PARAMETERS: FileID - ID of output file
804 *
805 * RETURN: None
806 *
807 * DESCRIPTION: Display compilation statistics for all input files
808 *
809 ******************************************************************************/
810
811 void
UtDisplaySummary(UINT32 FileId)812 UtDisplaySummary (
813 UINT32 FileId)
814 {
815 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
816
817
818 while (Current)
819 {
820 switch (FlSwitchFileSet(Current->Files[ASL_FILE_INPUT].Filename))
821 {
822 case SWITCH_TO_SAME_FILE:
823 case SWITCH_TO_DIFFERENT_FILE:
824
825 UtDisplayOneSummary (FileId, FALSE);
826 Current = Current->Next;
827 break;
828
829 case FILE_NOT_FOUND:
830 default:
831
832 Current = NULL;
833 break;
834 }
835 }
836 UtDisplayErrorSummary (FileId);
837 }
838
839 /*******************************************************************************
840 *
841 * FUNCTION: UtCheckIntegerRange
842 *
843 * PARAMETERS: Op - Integer parse node
844 * LowValue - Smallest allowed value
845 * HighValue - Largest allowed value
846 *
847 * RETURN: Op if OK, otherwise NULL
848 *
849 * DESCRIPTION: Check integer for an allowable range
850 *
851 ******************************************************************************/
852
853 ACPI_PARSE_OBJECT *
UtCheckIntegerRange(ACPI_PARSE_OBJECT * Op,UINT32 LowValue,UINT32 HighValue)854 UtCheckIntegerRange (
855 ACPI_PARSE_OBJECT *Op,
856 UINT32 LowValue,
857 UINT32 HighValue)
858 {
859
860 if (!Op)
861 {
862 return (NULL);
863 }
864
865 if ((Op->Asl.Value.Integer < LowValue) ||
866 (Op->Asl.Value.Integer > HighValue))
867 {
868 sprintf (AslGbl_MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
869 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
870
871 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, AslGbl_MsgBuffer);
872 return (NULL);
873 }
874
875 return (Op);
876 }
877
878
879 /*******************************************************************************
880 *
881 * FUNCTION: UtInternalizeName
882 *
883 * PARAMETERS: ExternalName - Name to convert
884 * ConvertedName - Where the converted name is returned
885 *
886 * RETURN: Status
887 *
888 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
889 *
890 ******************************************************************************/
891
892 ACPI_STATUS
UtInternalizeName(char * ExternalName,char ** ConvertedName)893 UtInternalizeName (
894 char *ExternalName,
895 char **ConvertedName)
896 {
897 ACPI_NAMESTRING_INFO Info;
898 ACPI_STATUS Status;
899
900
901 if (!ExternalName)
902 {
903 return (AE_OK);
904 }
905
906 /* Get the length of the new internal name */
907
908 Info.ExternalName = ExternalName;
909 AcpiNsGetInternalNameLength (&Info);
910
911 /* We need a segment to store the internal name */
912
913 Info.InternalName = UtLocalCacheCalloc (Info.Length);
914
915 /* Build the name */
916
917 Status = AcpiNsBuildInternalName (&Info);
918 if (ACPI_FAILURE (Status))
919 {
920 return (Status);
921 }
922
923 *ConvertedName = Info.InternalName;
924 return (AE_OK);
925 }
926
927
928 /*******************************************************************************
929 *
930 * FUNCTION: UtPadNameWithUnderscores
931 *
932 * PARAMETERS: NameSeg - Input nameseg
933 * PaddedNameSeg - Output padded nameseg
934 *
935 * RETURN: Padded nameseg.
936 *
937 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
938 * ACPI_NAME.
939 *
940 ******************************************************************************/
941
942 static void
UtPadNameWithUnderscores(char * NameSeg,char * PaddedNameSeg)943 UtPadNameWithUnderscores (
944 char *NameSeg,
945 char *PaddedNameSeg)
946 {
947 UINT32 i;
948
949
950 for (i = 0; (i < ACPI_NAMESEG_SIZE); i++)
951 {
952 if (*NameSeg)
953 {
954 *PaddedNameSeg = *NameSeg;
955 NameSeg++;
956 }
957 else
958 {
959 *PaddedNameSeg = '_';
960 }
961
962 PaddedNameSeg++;
963 }
964 }
965
966
967 /*******************************************************************************
968 *
969 * FUNCTION: UtAttachNameseg
970 *
971 * PARAMETERS: Op - Parent parse node
972 * Name - Full ExternalName
973 *
974 * RETURN: None; Sets the NameSeg field in parent node
975 *
976 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
977 * in the NameSeg field of the Op.
978 *
979 ******************************************************************************/
980
981 static void
UtAttachNameseg(ACPI_PARSE_OBJECT * Op,char * Name)982 UtAttachNameseg (
983 ACPI_PARSE_OBJECT *Op,
984 char *Name)
985 {
986 char *NameSeg;
987 char PaddedNameSeg[4];
988
989
990 if (!Name)
991 {
992 return;
993 }
994
995 /* Look for the last dot in the namepath */
996
997 NameSeg = strrchr (Name, '.');
998 if (NameSeg)
999 {
1000 /* Found last dot, we have also found the final nameseg */
1001
1002 NameSeg++;
1003 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
1004 }
1005 else
1006 {
1007 /* No dots in the namepath, there is only a single nameseg. */
1008 /* Handle prefixes */
1009
1010 while (ACPI_IS_ROOT_PREFIX (*Name) ||
1011 ACPI_IS_PARENT_PREFIX (*Name))
1012 {
1013 Name++;
1014 }
1015
1016 /* Remaining string should be one single nameseg */
1017
1018 UtPadNameWithUnderscores (Name, PaddedNameSeg);
1019 }
1020
1021 ACPI_COPY_NAMESEG (Op->Asl.NameSeg, PaddedNameSeg);
1022 }
1023
1024
1025 /*******************************************************************************
1026 *
1027 * FUNCTION: UtAttachNamepathToOwner
1028 *
1029 * PARAMETERS: Op - Parent parse node
1030 * NameOp - Node that contains the name
1031 *
1032 * RETURN: Sets the ExternalName and Namepath in the parent node
1033 *
1034 * DESCRIPTION: Store the name in two forms in the parent node: The original
1035 * (external) name, and the internalized name that is used within
1036 * the ACPI namespace manager.
1037 *
1038 ******************************************************************************/
1039
1040 void
UtAttachNamepathToOwner(ACPI_PARSE_OBJECT * Op,ACPI_PARSE_OBJECT * NameOp)1041 UtAttachNamepathToOwner (
1042 ACPI_PARSE_OBJECT *Op,
1043 ACPI_PARSE_OBJECT *NameOp)
1044 {
1045 ACPI_STATUS Status;
1046
1047
1048 /* Full external path */
1049
1050 Op->Asl.ExternalName = NameOp->Asl.Value.String;
1051
1052 /* Save the NameOp for possible error reporting later */
1053
1054 Op->Asl.ParentMethod = (void *) NameOp;
1055
1056 /* Last nameseg of the path */
1057
1058 UtAttachNameseg (Op, Op->Asl.ExternalName);
1059
1060 /* Create internalized path */
1061
1062 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
1063 if (ACPI_FAILURE (Status))
1064 {
1065 /* TBD: abort on no memory */
1066 }
1067 }
1068
1069
1070 /*******************************************************************************
1071 *
1072 * FUNCTION: UtNameContainsAllPrefix
1073 *
1074 * PARAMETERS: Op - Op containing NameString
1075 *
1076 * RETURN: NameString consists of all ^ characters
1077 *
1078 * DESCRIPTION: Determine if this Op contains a name segment that consists of
1079 * all '^' characters.
1080 *
1081 ******************************************************************************/
1082
1083 BOOLEAN
UtNameContainsAllPrefix(ACPI_PARSE_OBJECT * Op)1084 UtNameContainsAllPrefix (
1085 ACPI_PARSE_OBJECT *Op)
1086 {
1087 UINT32 Length = Op->Asl.AmlLength;
1088 UINT32 i;
1089
1090 for (i = 0; i < Length; i++)
1091 {
1092 if (Op->Asl.Value.String[i] != '^')
1093 {
1094 return (FALSE);
1095 }
1096 }
1097
1098 return (TRUE);
1099 }
1100
1101 /*******************************************************************************
1102 *
1103 * FUNCTION: UtDoConstant
1104 *
1105 * PARAMETERS: String - Hex/Decimal/Octal
1106 *
1107 * RETURN: Converted Integer
1108 *
1109 * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
1110 *
1111 ******************************************************************************/
1112
1113 UINT64
UtDoConstant(char * String)1114 UtDoConstant (
1115 char *String)
1116 {
1117 ACPI_STATUS Status;
1118 UINT64 ConvertedInteger;
1119 char ErrBuf[128];
1120 const ACPI_EXCEPTION_INFO *ExceptionInfo;
1121
1122
1123 Status = AcpiUtStrtoul64 (String, &ConvertedInteger);
1124 if (ACPI_FAILURE (Status))
1125 {
1126 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
1127 sprintf (ErrBuf, " %s while converting to 64-bit integer",
1128 ExceptionInfo->Description);
1129
1130 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
1131 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
1132 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf);
1133 }
1134
1135 return (ConvertedInteger);
1136 }
1137
1138
1139 /******************************************************************************
1140 *
1141 * FUNCTION: AcpiUtStrdup
1142 *
1143 * PARAMETERS: String1 - string to duplicate
1144 *
1145 * RETURN: int that signifies string relationship. Zero means strings
1146 * are equal.
1147 *
1148 * DESCRIPTION: Duplicate the string using UtCacheAlloc to avoid manual memory
1149 * reclamation.
1150 *
1151 ******************************************************************************/
1152
1153 char *
AcpiUtStrdup(char * String)1154 AcpiUtStrdup (
1155 char *String)
1156 {
1157 char *NewString = (char *) UtLocalCalloc (strlen (String) + 1);
1158
1159
1160 strcpy (NewString, String);
1161 return (NewString);
1162 }
1163
1164
1165 /******************************************************************************
1166 *
1167 * FUNCTION: AcpiUtStrcat
1168 *
1169 * PARAMETERS: String1
1170 * String2
1171 *
1172 * RETURN: New string with String1 concatenated with String2
1173 *
1174 * DESCRIPTION: Concatenate string1 and string2
1175 *
1176 ******************************************************************************/
1177
1178 char *
AcpiUtStrcat(char * String1,char * String2)1179 AcpiUtStrcat (
1180 char *String1,
1181 char *String2)
1182 {
1183 UINT32 String1Length = strlen (String1);
1184 char *NewString = (char *) UtLocalCalloc (strlen (String1) + strlen (String2) + 1);
1185
1186 strcpy (NewString, String1);
1187 strcpy (NewString + String1Length, String2);
1188 return (NewString);
1189 }
1190