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