aslcompile.c revision 246849
1/******************************************************************************
2 *
3 * Module Name: aslcompile - top level compile module
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
45#include <contrib/dev/acpica/compiler/dtcompiler.h>
46
47#include <stdio.h>
48#include <time.h>
49#include <contrib/dev/acpica/include/acapps.h>
50
51#define _COMPONENT          ACPI_COMPILER
52        ACPI_MODULE_NAME    ("aslcompile")
53
54/*
55 * Main parser entry
56 * External is here in case the parser emits the same external in the
57 * generated header. (Newer versions of Bison)
58 */
59int
60AslCompilerparse(
61    void);
62
63/* Local prototypes */
64
65static void
66CmFlushSourceCode (
67    void);
68
69static void
70FlConsumeAnsiComment (
71    FILE                    *Handle,
72    ASL_FILE_STATUS         *Status);
73
74static void
75FlConsumeNewComment (
76    FILE                    *Handle,
77    ASL_FILE_STATUS         *Status);
78
79static void
80CmDumpAllEvents (
81    void);
82
83
84/*******************************************************************************
85 *
86 * FUNCTION:    AslCompilerSignon
87 *
88 * PARAMETERS:  FileId      - ID of the output file
89 *
90 * RETURN:      None
91 *
92 * DESCRIPTION: Display compiler signon
93 *
94 ******************************************************************************/
95
96void
97AslCompilerSignon (
98    UINT32                  FileId)
99{
100    char                    *Prefix = "";
101    char                    *UtilityName;
102
103
104    /* Set line prefix depending on the destination file type */
105
106    switch (FileId)
107    {
108    case ASL_FILE_ASM_SOURCE_OUTPUT:
109    case ASL_FILE_ASM_INCLUDE_OUTPUT:
110
111        Prefix = "; ";
112        break;
113
114    case ASL_FILE_HEX_OUTPUT:
115
116        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
117        {
118            Prefix = "; ";
119        }
120        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
121                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
122        {
123            FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
124            Prefix = " * ";
125        }
126        break;
127
128    case ASL_FILE_C_SOURCE_OUTPUT:
129    case ASL_FILE_C_INCLUDE_OUTPUT:
130
131        Prefix = " * ";
132        break;
133
134    default:
135        /* No other output types supported */
136        break;
137    }
138
139    /* Running compiler or disassembler? */
140
141    if (Gbl_DisasmFlag)
142    {
143        UtilityName = AML_DISASSEMBLER_NAME;
144    }
145    else
146    {
147        UtilityName = ASL_COMPILER_NAME;
148    }
149
150    /* Compiler signon with copyright */
151
152    FlPrintFile (FileId, "%s\n", Prefix);
153    FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
154}
155
156
157/*******************************************************************************
158 *
159 * FUNCTION:    AslCompilerFileHeader
160 *
161 * PARAMETERS:  FileId      - ID of the output file
162 *
163 * RETURN:      None
164 *
165 * DESCRIPTION: Header used at the beginning of output files
166 *
167 ******************************************************************************/
168
169void
170AslCompilerFileHeader (
171    UINT32                  FileId)
172{
173    struct tm               *NewTime;
174    time_t                  Aclock;
175    char                    *Prefix = "";
176
177
178    /* Set line prefix depending on the destination file type */
179
180    switch (FileId)
181    {
182    case ASL_FILE_ASM_SOURCE_OUTPUT:
183    case ASL_FILE_ASM_INCLUDE_OUTPUT:
184
185        Prefix = "; ";
186        break;
187
188    case ASL_FILE_HEX_OUTPUT:
189
190        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
191        {
192            Prefix = "; ";
193        }
194        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
195                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
196        {
197            Prefix = " * ";
198        }
199        break;
200
201    case ASL_FILE_C_SOURCE_OUTPUT:
202    case ASL_FILE_C_INCLUDE_OUTPUT:
203
204        Prefix = " * ";
205        break;
206
207    default:
208        /* No other output types supported */
209        break;
210    }
211
212    /* Compilation header with timestamp */
213
214    (void) time (&Aclock);
215    NewTime = localtime (&Aclock);
216
217    FlPrintFile (FileId,
218        "%sCompilation of \"%s\" - %s%s\n",
219        Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
220        Prefix);
221
222    switch (FileId)
223    {
224    case ASL_FILE_C_SOURCE_OUTPUT:
225    case ASL_FILE_C_INCLUDE_OUTPUT:
226        FlPrintFile (FileId, " */\n");
227        break;
228
229    default:
230        /* Nothing to do for other output types */
231        break;
232    }
233}
234
235
236/*******************************************************************************
237 *
238 * FUNCTION:    CmFlushSourceCode
239 *
240 * PARAMETERS:  None
241 *
242 * RETURN:      None
243 *
244 * DESCRIPTION: Read in any remaining source code after the parse tree
245 *              has been constructed.
246 *
247 ******************************************************************************/
248
249static void
250CmFlushSourceCode (
251    void)
252{
253    char                    Buffer;
254
255
256    while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
257    {
258        AslInsertLineBuffer ((int) Buffer);
259    }
260
261    AslResetCurrentLineBuffer ();
262}
263
264
265/*******************************************************************************
266 *
267 * FUNCTION:    FlConsume*
268 *
269 * PARAMETERS:  Handle              - Open input file
270 *              Status              - File current status struct
271 *
272 * RETURN:      Number of lines consumed
273 *
274 * DESCRIPTION: Step over both types of comment during check for ascii chars
275 *
276 ******************************************************************************/
277
278static void
279FlConsumeAnsiComment (
280    FILE                    *Handle,
281    ASL_FILE_STATUS         *Status)
282{
283    UINT8                   Byte;
284    BOOLEAN                 ClosingComment = FALSE;
285
286
287    while (fread (&Byte, 1, 1, Handle) == 1)
288    {
289        /* Scan until comment close is found */
290
291        if (ClosingComment)
292        {
293            if (Byte == '/')
294            {
295                return;
296            }
297
298            if (Byte != '*')
299            {
300                /* Reset */
301
302                ClosingComment = FALSE;
303            }
304        }
305        else if (Byte == '*')
306        {
307            ClosingComment = TRUE;
308        }
309
310        /* Maintain line count */
311
312        if (Byte == 0x0A)
313        {
314            Status->Line++;
315        }
316
317        Status->Offset++;
318    }
319}
320
321
322static void
323FlConsumeNewComment (
324    FILE                    *Handle,
325    ASL_FILE_STATUS         *Status)
326{
327    UINT8                   Byte;
328
329
330    while (fread (&Byte, 1, 1, Handle) == 1)
331    {
332        Status->Offset++;
333
334        /* Comment ends at newline */
335
336        if (Byte == 0x0A)
337        {
338            Status->Line++;
339            return;
340        }
341    }
342}
343
344
345/*******************************************************************************
346 *
347 * FUNCTION:    FlCheckForAcpiTable
348 *
349 * PARAMETERS:  Handle              - Open input file
350 *
351 * RETURN:      Status
352 *
353 * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
354 *              following checks on what would be the table header:
355 *              0) File must be at least as long as an ACPI_TABLE_HEADER
356 *              1) The header length field must match the file size
357 *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
358 *
359 ******************************************************************************/
360
361ACPI_STATUS
362FlCheckForAcpiTable (
363    FILE                    *Handle)
364{
365    ACPI_TABLE_HEADER       Table;
366    UINT32                  FileSize;
367    size_t                  Actual;
368    UINT32                  i;
369
370
371    /* Read a potential table header */
372
373    Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
374    fseek (Handle, 0, SEEK_SET);
375
376    if (Actual < sizeof (ACPI_TABLE_HEADER))
377    {
378        return (AE_ERROR);
379    }
380
381    /* Header length field must match the file size */
382
383    FileSize = DtGetFileSize (Handle);
384    if (Table.Length != FileSize)
385    {
386        return (AE_ERROR);
387    }
388
389    /*
390     * These fields must be ASCII:
391     * Signature, OemId, OemTableId, AslCompilerId.
392     * We allow a NULL terminator in OemId and OemTableId.
393     */
394    for (i = 0; i < ACPI_NAME_SIZE; i++)
395    {
396        if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
397        {
398            return (AE_ERROR);
399        }
400
401        if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
402        {
403            return (AE_ERROR);
404        }
405    }
406
407    for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
408    {
409        if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
410        {
411            return (AE_ERROR);
412        }
413    }
414
415    for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
416    {
417        if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
418        {
419            return (AE_ERROR);
420        }
421    }
422
423    printf ("Binary file appears to be a valid ACPI table, disassembling\n");
424    return (AE_OK);
425}
426
427
428/*******************************************************************************
429 *
430 * FUNCTION:    FlCheckForAscii
431 *
432 * PARAMETERS:  Handle              - Open input file
433 *              Filename            - Input filename
434 *              DisplayErrors       - TRUE if error messages desired
435 *
436 * RETURN:      Status
437 *
438 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
439 *              within comments. Note: does not handle nested comments and does
440 *              not handle comment delimiters within string literals. However,
441 *              on the rare chance this happens and an invalid character is
442 *              missed, the parser will catch the error by failing in some
443 *              spectactular manner.
444 *
445 ******************************************************************************/
446
447ACPI_STATUS
448FlCheckForAscii (
449    FILE                    *Handle,
450    char                    *Filename,
451    BOOLEAN                 DisplayErrors)
452{
453    UINT8                   Byte;
454    ACPI_SIZE               BadBytes = 0;
455    BOOLEAN                 OpeningComment = FALSE;
456    ASL_FILE_STATUS         Status;
457
458
459    Status.Line = 1;
460    Status.Offset = 0;
461
462    /* Read the entire file */
463
464    while (fread (&Byte, 1, 1, Handle) == 1)
465    {
466        /* Ignore comment fields (allow non-ascii within) */
467
468        if (OpeningComment)
469        {
470            /* Check for second comment open delimiter */
471
472            if (Byte == '*')
473            {
474                FlConsumeAnsiComment (Handle, &Status);
475            }
476
477            if (Byte == '/')
478            {
479                FlConsumeNewComment (Handle, &Status);
480            }
481
482            /* Reset */
483
484            OpeningComment = FALSE;
485        }
486        else if (Byte == '/')
487        {
488            OpeningComment = TRUE;
489        }
490
491        /* Check for an ASCII character */
492
493        if (!ACPI_IS_ASCII (Byte))
494        {
495            if ((BadBytes < 10) && (DisplayErrors))
496            {
497                AcpiOsPrintf (
498                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
499                    Byte, Status.Line, Status.Offset);
500            }
501
502            BadBytes++;
503        }
504
505        /* Update line counter */
506
507        else if (Byte == 0x0A)
508        {
509            Status.Line++;
510        }
511
512        Status.Offset++;
513    }
514
515    /* Seek back to the beginning of the source file */
516
517    fseek (Handle, 0, SEEK_SET);
518
519    /* Were there any non-ASCII characters in the file? */
520
521    if (BadBytes)
522    {
523        if (DisplayErrors)
524        {
525            AcpiOsPrintf (
526                "%u non-ASCII characters found in input source text, could be a binary file\n",
527                BadBytes);
528            AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
529        }
530
531        return (AE_BAD_CHARACTER);
532    }
533
534    /* File is OK (100% ASCII) */
535
536    return (AE_OK);
537}
538
539
540/*******************************************************************************
541 *
542 * FUNCTION:    CmDoCompile
543 *
544 * PARAMETERS:  None
545 *
546 * RETURN:      Status (0 = OK)
547 *
548 * DESCRIPTION: This procedure performs the entire compile
549 *
550 ******************************************************************************/
551
552int
553CmDoCompile (
554    void)
555{
556    ACPI_STATUS             Status;
557    UINT8                   FullCompile;
558    UINT8                   Event;
559
560
561    FullCompile = UtBeginEvent ("*** Total Compile time ***");
562    Event = UtBeginEvent ("Open input and output files");
563    UtEndEvent (Event);
564
565    Event = UtBeginEvent ("Preprocess input file");
566    if (Gbl_PreprocessFlag)
567    {
568        /* Preprocessor */
569
570        PrDoPreprocess ();
571        if (Gbl_PreprocessOnly)
572        {
573            UtEndEvent (Event);
574            CmCleanupAndExit ();
575            return (0);
576        }
577    }
578    UtEndEvent (Event);
579
580    /* Build the parse tree */
581
582    Event = UtBeginEvent ("Parse source code and build parse tree");
583    AslCompilerparse();
584    UtEndEvent (Event);
585
586    /* Flush out any remaining source after parse tree is complete */
587
588    Event = UtBeginEvent ("Flush source input");
589    CmFlushSourceCode ();
590
591    /* Did the parse tree get successfully constructed? */
592
593    if (!RootNode)
594    {
595        /*
596         * If there are no errors, then we have some sort of
597         * internal problem.
598         */
599        Status = AslCheckForErrorExit ();
600        if (Status == AE_OK)
601        {
602            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
603                NULL, "- Could not resolve parse tree root node");
604        }
605
606        goto ErrorExit;
607    }
608
609    /* Optional parse tree dump, compiler debug output only */
610
611    LsDumpParseTree ();
612
613    OpcGetIntegerWidth (RootNode);
614    UtEndEvent (Event);
615
616    /* Pre-process parse tree for any operator transforms */
617
618    Event = UtBeginEvent ("Parse tree transforms");
619    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
620    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
621        TrAmlTransformWalk, NULL, NULL);
622    UtEndEvent (Event);
623
624    /* Generate AML opcodes corresponding to the parse tokens */
625
626    Event = UtBeginEvent ("Generate AML opcodes");
627    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
628    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
629        OpcAmlOpcodeWalk, NULL);
630    UtEndEvent (Event);
631
632    /*
633     * Now that the input is parsed, we can open the AML output file.
634     * Note: by default, the name of this file comes from the table descriptor
635     * within the input file.
636     */
637    Event = UtBeginEvent ("Open AML output file");
638    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
639    UtEndEvent (Event);
640    if (ACPI_FAILURE (Status))
641    {
642        AePrintErrorLog (ASL_FILE_STDERR);
643        return (-1);
644    }
645
646    /* Interpret and generate all compile-time constants */
647
648    Event = UtBeginEvent ("Constant folding via AML interpreter");
649    DbgPrint (ASL_DEBUG_OUTPUT,
650        "\nInterpreting compile-time constant expressions\n\n");
651    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
652        OpcAmlConstantWalk, NULL, NULL);
653    UtEndEvent (Event);
654
655    /* Update AML opcodes if necessary, after constant folding */
656
657    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
658    DbgPrint (ASL_DEBUG_OUTPUT,
659        "\nUpdating AML opcodes after constant folding\n\n");
660    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
661        NULL, OpcAmlOpcodeUpdateWalk, NULL);
662    UtEndEvent (Event);
663
664    /* Calculate all AML package lengths */
665
666    Event = UtBeginEvent ("Generate AML package lengths");
667    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
668    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
669        LnPackageLengthWalk, NULL);
670    UtEndEvent (Event);
671
672    if (Gbl_ParseOnlyFlag)
673    {
674        AePrintErrorLog (ASL_FILE_STDERR);
675        UtDisplaySummary (ASL_FILE_STDERR);
676        if (Gbl_DebugFlag)
677        {
678            /* Print error summary to the stdout also */
679
680            AePrintErrorLog (ASL_FILE_STDOUT);
681            UtDisplaySummary (ASL_FILE_STDOUT);
682        }
683        UtEndEvent (FullCompile);
684        return (0);
685    }
686
687    /*
688     * Create an internal namespace and use it as a symbol table
689     */
690
691    /* Namespace loading */
692
693    Event = UtBeginEvent ("Create ACPI Namespace");
694    Status = LdLoadNamespace (RootNode);
695    UtEndEvent (Event);
696    if (ACPI_FAILURE (Status))
697    {
698        goto ErrorExit;
699    }
700
701    /* Namespace cross-reference */
702
703    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
704    Status = XfCrossReferenceNamespace ();
705    if (ACPI_FAILURE (Status))
706    {
707        goto ErrorExit;
708    }
709
710    /* Namespace - Check for non-referenced objects */
711
712    LkFindUnreferencedObjects ();
713    UtEndEvent (AslGbl_NamespaceEvent);
714
715    /*
716     * Semantic analysis. This can happen only after the
717     * namespace has been loaded and cross-referenced.
718     *
719     * part one - check control methods
720     */
721    Event = UtBeginEvent ("Analyze control method return types");
722    AnalysisWalkInfo.MethodStack = NULL;
723
724    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
725    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
726        MtMethodAnalysisWalkBegin,
727        MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
728    UtEndEvent (Event);
729
730    /* Semantic error checking part two - typing of method returns */
731
732    Event = UtBeginEvent ("Determine object types returned by methods");
733    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
734    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
735        NULL, AnMethodTypingWalkEnd, NULL);
736    UtEndEvent (Event);
737
738    /* Semantic error checking part three - operand type checking */
739
740    Event = UtBeginEvent ("Analyze AML operand types");
741    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
742    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
743        NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
744    UtEndEvent (Event);
745
746    /* Semantic error checking part four - other miscellaneous checks */
747
748    Event = UtBeginEvent ("Miscellaneous analysis");
749    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
750    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
751        AnOtherSemanticAnalysisWalkBegin,
752        NULL, &AnalysisWalkInfo);
753    UtEndEvent (Event);
754
755    /* Calculate all AML package lengths */
756
757    Event = UtBeginEvent ("Finish AML package length generation");
758    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
759    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
760        LnInitLengthsWalk, NULL);
761    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
762        LnPackageLengthWalk, NULL);
763    UtEndEvent (Event);
764
765    /* Code generation - emit the AML */
766
767    Event = UtBeginEvent ("Generate AML code and write output files");
768    CgGenerateAmlOutput ();
769    UtEndEvent (Event);
770
771    Event = UtBeginEvent ("Write optional output files");
772    CmDoOutputFiles ();
773    UtEndEvent (Event);
774
775    UtEndEvent (FullCompile);
776    CmCleanupAndExit ();
777    return (0);
778
779ErrorExit:
780    UtEndEvent (FullCompile);
781    CmCleanupAndExit ();
782    return (-1);
783}
784
785
786/*******************************************************************************
787 *
788 * FUNCTION:    CmDoOutputFiles
789 *
790 * PARAMETERS:  None
791 *
792 * RETURN:      None.
793 *
794 * DESCRIPTION: Create all "listing" type files
795 *
796 ******************************************************************************/
797
798void
799CmDoOutputFiles (
800    void)
801{
802
803    /* Create listings and hex files */
804
805    LsDoListings ();
806    HxDoHexOutput ();
807
808    /* Dump the namespace to the .nsp file if requested */
809
810    (void) NsDisplayNamespace ();
811}
812
813
814/*******************************************************************************
815 *
816 * FUNCTION:    CmDumpAllEvents
817 *
818 * PARAMETERS:  None
819 *
820 * RETURN:      None.
821 *
822 * DESCRIPTION: Dump all compiler events
823 *
824 ******************************************************************************/
825
826static void
827CmDumpAllEvents (
828    void)
829{
830    ASL_EVENT_INFO          *Event;
831    UINT32                  Delta;
832    UINT32                  USec;
833    UINT32                  MSec;
834    UINT32                  i;
835
836
837    Event = AslGbl_Events;
838
839    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
840    if (Gbl_CompileTimesFlag)
841    {
842        printf ("\nElapsed time for major events\n\n");
843    }
844
845    for (i = 0; i < AslGbl_NextEvent; i++)
846    {
847        if (Event->Valid)
848        {
849            /* Delta will be in 100-nanosecond units */
850
851            Delta = (UINT32) (Event->EndTime - Event->StartTime);
852
853            USec = Delta / ACPI_100NSEC_PER_USEC;
854            MSec = Delta / ACPI_100NSEC_PER_MSEC;
855
856            /* Round milliseconds up */
857
858            if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
859            {
860                MSec++;
861            }
862
863            DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
864                USec, MSec, Event->EventName);
865
866            if (Gbl_CompileTimesFlag)
867            {
868                printf ("%8u usec %8u msec - %s\n",
869                    USec, MSec, Event->EventName);
870            }
871        }
872
873        Event++;
874    }
875}
876
877
878/*******************************************************************************
879 *
880 * FUNCTION:    CmCleanupAndExit
881 *
882 * PARAMETERS:  None
883 *
884 * RETURN:      None.
885 *
886 * DESCRIPTION: Close all open files and exit the compiler
887 *
888 ******************************************************************************/
889
890void
891CmCleanupAndExit (
892    void)
893{
894    UINT32                  i;
895    BOOLEAN                 DeleteAmlFile = FALSE;
896
897
898    AePrintErrorLog (ASL_FILE_STDERR);
899    if (Gbl_DebugFlag)
900    {
901        /* Print error summary to stdout also */
902
903        AePrintErrorLog (ASL_FILE_STDOUT);
904    }
905
906    /* Emit compile times if enabled */
907
908    CmDumpAllEvents ();
909
910    if (Gbl_CompileTimesFlag)
911    {
912        printf ("\nMiscellaneous compile statistics\n\n");
913        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
914        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
915        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
916        printf ("%11u : %s\n", TotalMethods, "Control methods");
917        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
918        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
919        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
920        printf ("\n");
921    }
922
923    if (Gbl_NsLookupCount)
924    {
925        DbgPrint (ASL_DEBUG_OUTPUT,
926            "\n\nMiscellaneous compile statistics\n\n");
927
928        DbgPrint (ASL_DEBUG_OUTPUT,
929            "%32s : %u\n", "Total Namespace searches",
930            Gbl_NsLookupCount);
931
932        DbgPrint (ASL_DEBUG_OUTPUT,
933            "%32s : %u usec\n", "Time per search", ((UINT32)
934            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
935                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
936                Gbl_NsLookupCount);
937    }
938
939    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
940    {
941        printf ("\nMaximum error count (%u) exceeded\n",
942            ASL_MAX_ERROR_COUNT);
943    }
944
945    UtDisplaySummary (ASL_FILE_STDOUT);
946
947    /*
948     * We will delete the AML file if there are errors and the
949     * force AML output option has not been used.
950     */
951    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
952        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
953    {
954        DeleteAmlFile = TRUE;
955    }
956
957    /* Close all open files */
958
959    Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
960
961    for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
962    {
963        FlCloseFile (i);
964    }
965
966    /* Delete AML file if there are errors */
967
968    if (DeleteAmlFile)
969    {
970        FlDeleteFile (ASL_FILE_AML_OUTPUT);
971    }
972
973    /* Delete the preprocessor output file (.i) unless -li flag is set */
974
975    if (!Gbl_PreprocessorOutputFlag &&
976        Gbl_PreprocessFlag)
977    {
978        FlDeleteFile (ASL_FILE_PREPROCESSOR);
979    }
980
981    /*
982     * Delete intermediate ("combined") source file (if -ls flag not set)
983     * This file is created during normal ASL/AML compiles. It is not
984     * created by the data table compiler.
985     *
986     * If the -ls flag is set, then the .SRC file should not be deleted.
987     * In this case, Gbl_SourceOutputFlag is set to TRUE.
988     *
989     * Note: Handles are cleared by FlCloseFile above, so we look at the
990     * filename instead, to determine if the .SRC file was actually
991     * created.
992     *
993     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
994     */
995    if (!Gbl_SourceOutputFlag)
996    {
997        FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
998    }
999}
1000