Home | History | Annotate | Line # | Download | only in compiler
aslerror.c revision 1.1.1.2.4.2
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: aslerror - Error handling and statistics
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #define ASL_EXCEPTIONS
     46 #include "aslcompiler.h"
     47 
     48 #define _COMPONENT          ACPI_COMPILER
     49         ACPI_MODULE_NAME    ("aslerror")
     50 
     51 /* Local prototypes */
     52 
     53 static void
     54 AeAddToErrorLog (
     55     ASL_ERROR_MSG           *Enode);
     56 
     57 
     58 void
     59 AeClearErrorLog (
     60     void)
     61 {
     62     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
     63     ASL_ERROR_MSG           *Next;
     64 
     65     /* Walk the error node list */
     66 
     67     while (Enode)
     68     {
     69         Next = Enode->Next;
     70         ACPI_FREE (Enode);
     71         Enode = Next;
     72     }
     73 
     74     Gbl_ErrorLog = NULL;
     75 }
     76 
     77 
     78 /*******************************************************************************
     79  *
     80  * FUNCTION:    AeAddToErrorLog
     81  *
     82  * PARAMETERS:  Enode       - An error node to add to the log
     83  *
     84  * RETURN:      None
     85  *
     86  * DESCRIPTION: Add a new error node to the error log.  The error log is
     87  *              ordered by the "logical" line number (cumulative line number
     88  *              including all include files.)
     89  *
     90  ******************************************************************************/
     91 
     92 static void
     93 AeAddToErrorLog (
     94     ASL_ERROR_MSG           *Enode)
     95 {
     96     ASL_ERROR_MSG           *Next;
     97     ASL_ERROR_MSG           *Prev;
     98 
     99 
    100     /* If Gbl_ErrorLog is null, this is the first error node */
    101 
    102     if (!Gbl_ErrorLog)
    103     {
    104         Gbl_ErrorLog = Enode;
    105         return;
    106     }
    107 
    108     /*
    109      * Walk error list until we find a line number greater than ours.
    110      * List is sorted according to line number.
    111      */
    112     Prev = NULL;
    113     Next = Gbl_ErrorLog;
    114 
    115     while ((Next) &&
    116            (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
    117     {
    118         Prev = Next;
    119         Next = Next->Next;
    120     }
    121 
    122     /* Found our place in the list */
    123 
    124     Enode->Next = Next;
    125 
    126     if (Prev)
    127     {
    128         Prev->Next = Enode;
    129     }
    130     else
    131     {
    132         Gbl_ErrorLog = Enode;
    133     }
    134 }
    135 
    136 
    137 /*******************************************************************************
    138  *
    139  * FUNCTION:    AePrintException
    140  *
    141  * PARAMETERS:  FileId          - ID of output file
    142  *              Enode           - Error node to print
    143  *              Header          - Additional text before each message
    144  *
    145  * RETURN:      None
    146  *
    147  * DESCRIPTION: Print the contents of an error node.
    148  *
    149  * NOTE:        We don't use the FlxxxFile I/O functions here because on error
    150  *              they abort the compiler and call this function!  Since we
    151  *              are reporting errors here, we ignore most output errors and
    152  *              just try to get out as much as we can.
    153  *
    154  ******************************************************************************/
    155 
    156 void
    157 AePrintException (
    158     UINT32                  FileId,
    159     ASL_ERROR_MSG           *Enode,
    160     char                    *Header)
    161 {
    162     UINT8                   SourceByte;
    163     int                     Actual;
    164     size_t                  RActual;
    165     UINT32                  MsgLength;
    166     char                    *MainMessage;
    167     char                    *ExtraMessage;
    168     UINT32                  SourceColumn;
    169     UINT32                  ErrorColumn;
    170     FILE                    *OutputFile;
    171     FILE                    *SourceFile;
    172     long                    FileSize;
    173     BOOLEAN                 PrematureEOF = FALSE;
    174 
    175 
    176     if (Gbl_NoErrors)
    177     {
    178         return;
    179     }
    180 
    181     /*
    182      * Only listing files have a header, and remarks/optimizations
    183      * are always output
    184      */
    185     if (!Header)
    186     {
    187         /* Ignore remarks if requested */
    188 
    189         switch (Enode->Level)
    190         {
    191         case ASL_REMARK:
    192             if (!Gbl_DisplayRemarks)
    193             {
    194                 return;
    195             }
    196             break;
    197 
    198         case ASL_OPTIMIZATION:
    199             if (!Gbl_DisplayOptimizations)
    200             {
    201                 return;
    202             }
    203             break;
    204 
    205         default:
    206             break;
    207         }
    208     }
    209 
    210     /* Get the file handles */
    211 
    212     OutputFile = Gbl_Files[FileId].Handle;
    213 
    214     /* Use the merged header/source file if present, otherwise use input file */
    215 
    216     SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
    217     if (!SourceFile)
    218     {
    219         SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
    220     }
    221 
    222     if (SourceFile)
    223     {
    224         /* Determine if the error occurred at source file EOF */
    225 
    226         fseek (SourceFile, 0, SEEK_END);
    227         FileSize = ftell (SourceFile);
    228 
    229         if ((long) Enode->LogicalByteOffset >= FileSize)
    230         {
    231             PrematureEOF = TRUE;
    232         }
    233     }
    234 
    235     if (Header)
    236     {
    237         fprintf (OutputFile, "%s", Header);
    238     }
    239 
    240     /* Print filename and line number if present and valid */
    241 
    242     if (Enode->Filename)
    243     {
    244         if (Gbl_VerboseErrors)
    245         {
    246             fprintf (OutputFile, "%6s", Enode->Filename);
    247 
    248             if (Enode->LineNumber)
    249             {
    250                 fprintf (OutputFile, " %6u: ", Enode->LineNumber);
    251 
    252                 /*
    253                  * If not at EOF, get the corresponding source code line and
    254                  * display it. Don't attempt this if we have a premature EOF
    255                  * condition.
    256                  */
    257                 if (!PrematureEOF)
    258                 {
    259                     /*
    260                      * Seek to the offset in the combined source file, read
    261                      * the source line, and write it to the output.
    262                      */
    263                     Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
    264                                 (int) SEEK_SET);
    265                     if (Actual)
    266                     {
    267                         fprintf (OutputFile,
    268                             "[*** iASL: Seek error on source code temp file %s ***]",
    269                             Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    270                     }
    271                     else
    272                     {
    273                         RActual = fread (&SourceByte, 1, 1, SourceFile);
    274                         if (!RActual)
    275                         {
    276                             fprintf (OutputFile,
    277                                 "[*** iASL: Read error on source code temp file %s ***]",
    278                                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    279                         }
    280 
    281                         else while (RActual && SourceByte && (SourceByte != '\n'))
    282                         {
    283                             fwrite (&SourceByte, 1, 1, OutputFile);
    284                             RActual = fread (&SourceByte, 1, 1, SourceFile);
    285                         }
    286                     }
    287                 }
    288 
    289                 fprintf (OutputFile, "\n");
    290             }
    291         }
    292         else
    293         {
    294             fprintf (OutputFile, "%s", Enode->Filename);
    295 
    296             if (Enode->LineNumber)
    297             {
    298                 fprintf (OutputFile, "(%u) : ", Enode->LineNumber);
    299             }
    300         }
    301     }
    302 
    303     /* NULL message ID, just print the raw message */
    304 
    305     if (Enode->MessageId == 0)
    306     {
    307         fprintf (OutputFile, "%s\n", Enode->Message);
    308     }
    309     else
    310     {
    311         /* Decode the message ID */
    312 
    313         fprintf (OutputFile, "%s %4.4d - ",
    314                     AslErrorLevel[Enode->Level],
    315                     Enode->MessageId + ((Enode->Level+1) * 1000));
    316 
    317         MainMessage = AslMessages[Enode->MessageId];
    318         ExtraMessage = Enode->Message;
    319 
    320         if (Enode->LineNumber)
    321         {
    322             MsgLength = strlen (MainMessage);
    323             if (MsgLength == 0)
    324             {
    325                 MainMessage = Enode->Message;
    326 
    327                 MsgLength = strlen (MainMessage);
    328                 ExtraMessage = NULL;
    329             }
    330 
    331             if (Gbl_VerboseErrors && !PrematureEOF)
    332             {
    333                 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
    334                 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
    335 
    336                 if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
    337                 {
    338                     fprintf (OutputFile, "%*s%s",
    339                         (int) ((SourceColumn - 1) - ErrorColumn),
    340                         MainMessage, " ^ ");
    341                 }
    342                 else
    343                 {
    344                     fprintf (OutputFile, "%*s %s",
    345                         (int) ((SourceColumn - ErrorColumn) + 1), "^",
    346                         MainMessage);
    347                 }
    348             }
    349             else
    350             {
    351                 fprintf (OutputFile, " %s", MainMessage);
    352             }
    353 
    354             /* Print the extra info message if present */
    355 
    356             if (ExtraMessage)
    357             {
    358                 fprintf (OutputFile, " (%s)", ExtraMessage);
    359             }
    360 
    361             if (PrematureEOF)
    362             {
    363                 fprintf (OutputFile, " and premature End-Of-File");
    364             }
    365 
    366             fprintf (OutputFile, "\n");
    367             if (Gbl_VerboseErrors)
    368             {
    369                 fprintf (OutputFile, "\n");
    370             }
    371         }
    372         else
    373         {
    374             fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
    375         }
    376     }
    377 }
    378 
    379 
    380 /*******************************************************************************
    381  *
    382  * FUNCTION:    AePrintErrorLog
    383  *
    384  * PARAMETERS:  FileId           - Where to output the error log
    385  *
    386  * RETURN:      None
    387  *
    388  * DESCRIPTION: Print the entire contents of the error log
    389  *
    390  ******************************************************************************/
    391 
    392 void
    393 AePrintErrorLog (
    394     UINT32                  FileId)
    395 {
    396     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
    397 
    398 
    399     /* Walk the error node list */
    400 
    401     while (Enode)
    402     {
    403         AePrintException (FileId, Enode, NULL);
    404         Enode = Enode->Next;
    405     }
    406 }
    407 
    408 
    409 /*******************************************************************************
    410  *
    411  * FUNCTION:    AslCommonError
    412  *
    413  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    414  *              MessageId           - Index into global message buffer
    415  *              CurrentLineNumber   - Actual file line number
    416  *              LogicalLineNumber   - Cumulative line number
    417  *              LogicalByteOffset   - Byte offset in source file
    418  *              Column              - Column in current line
    419  *              Filename            - source filename
    420  *              ExtraMessage        - additional error message
    421  *
    422  * RETURN:      None
    423  *
    424  * DESCRIPTION: Create a new error node and add it to the error log
    425  *
    426  ******************************************************************************/
    427 
    428 void
    429 AslCommonError (
    430     UINT8                   Level,
    431     UINT8                   MessageId,
    432     UINT32                  CurrentLineNumber,
    433     UINT32                  LogicalLineNumber,
    434     UINT32                  LogicalByteOffset,
    435     UINT32                  Column,
    436     char                    *Filename,
    437     char                    *ExtraMessage)
    438 {
    439     UINT32                  MessageSize;
    440     char                    *MessageBuffer = NULL;
    441     ASL_ERROR_MSG           *Enode;
    442 
    443 
    444     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
    445 
    446     if (ExtraMessage)
    447     {
    448         /* Allocate a buffer for the message and a new error node */
    449 
    450         MessageSize   = strlen (ExtraMessage) + 1;
    451         MessageBuffer = UtLocalCalloc (MessageSize);
    452 
    453         /* Keep a copy of the extra message */
    454 
    455         ACPI_STRCPY (MessageBuffer, ExtraMessage);
    456     }
    457 
    458     /* Initialize the error node */
    459 
    460     if (Filename)
    461     {
    462         Enode->Filename       = Filename;
    463         Enode->FilenameLength = strlen (Filename);
    464         if (Enode->FilenameLength < 6)
    465         {
    466             Enode->FilenameLength = 6;
    467         }
    468     }
    469 
    470     Enode->MessageId            = MessageId;
    471     Enode->Level                = Level;
    472     Enode->LineNumber           = CurrentLineNumber;
    473     Enode->LogicalLineNumber    = LogicalLineNumber;
    474     Enode->LogicalByteOffset    = LogicalByteOffset;
    475     Enode->Column               = Column;
    476     Enode->Message              = MessageBuffer;
    477 
    478     /* Add the new node to the error node list */
    479 
    480     AeAddToErrorLog (Enode);
    481 
    482     if (Gbl_DebugFlag)
    483     {
    484         /* stderr is a file, send error to it immediately */
    485 
    486         AePrintException (ASL_FILE_STDERR, Enode, NULL);
    487     }
    488 
    489     Gbl_ExceptionCount[Level]++;
    490     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    491     {
    492         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
    493 
    494         Gbl_SourceLine = 0;
    495         Gbl_NextError = Gbl_ErrorLog;
    496         CmDoOutputFiles ();
    497         CmCleanupAndExit ();
    498         exit(1);
    499     }
    500 
    501     return;
    502 }
    503 
    504 
    505 /*******************************************************************************
    506  *
    507  * FUNCTION:    AslError
    508  *
    509  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    510  *              MessageId           - Index into global message buffer
    511  *              Op                  - Parse node where error happened
    512  *              ExtraMessage        - additional error message
    513  *
    514  * RETURN:      None
    515  *
    516  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
    517  *              except the parser.)
    518  *
    519  ******************************************************************************/
    520 
    521 void
    522 AslError (
    523     UINT8                   Level,
    524     UINT8                   MessageId,
    525     ACPI_PARSE_OBJECT       *Op,
    526     char                    *ExtraMessage)
    527 {
    528 
    529     switch (Level)
    530     {
    531     case ASL_WARNING2:
    532     case ASL_WARNING3:
    533         if (Gbl_WarningLevel < Level)
    534         {
    535             return;
    536         }
    537         break;
    538 
    539     default:
    540         break;
    541     }
    542 
    543 
    544     if (Op)
    545     {
    546         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
    547                         Op->Asl.LogicalLineNumber,
    548                         Op->Asl.LogicalByteOffset,
    549                         Op->Asl.Column,
    550                         Op->Asl.Filename, ExtraMessage);
    551     }
    552     else
    553     {
    554         AslCommonError (Level, MessageId, 0,
    555                         0, 0, 0, NULL, ExtraMessage);
    556     }
    557 }
    558 
    559 
    560 /*******************************************************************************
    561  *
    562  * FUNCTION:    AslCoreSubsystemError
    563  *
    564  * PARAMETERS:  Op                  - Parse node where error happened
    565  *              Status              - The ACPI CA Exception
    566  *              ExtraMessage        - additional error message
    567  *              Abort               - TRUE -> Abort compilation
    568  *
    569  * RETURN:      None
    570  *
    571  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
    572  *              CA core subsystem.
    573  *
    574  ******************************************************************************/
    575 
    576 void
    577 AslCoreSubsystemError (
    578     ACPI_PARSE_OBJECT       *Op,
    579     ACPI_STATUS             Status,
    580     char                    *ExtraMessage,
    581     BOOLEAN                 Abort)
    582 {
    583 
    584     sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
    585 
    586     if (Op)
    587     {
    588         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
    589                         Op->Asl.LogicalLineNumber,
    590                         Op->Asl.LogicalByteOffset,
    591                         Op->Asl.Column,
    592                         Op->Asl.Filename, MsgBuffer);
    593     }
    594     else
    595     {
    596         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
    597                         0, 0, 0, NULL, MsgBuffer);
    598     }
    599 
    600     if (Abort)
    601     {
    602         AslAbort ();
    603     }
    604 }
    605 
    606 
    607 /*******************************************************************************
    608  *
    609  * FUNCTION:    AslCompilererror
    610  *
    611  * PARAMETERS:  CompilerMessage         - Error message from the parser
    612  *
    613  * RETURN:      Status (0 for now)
    614  *
    615  * DESCRIPTION: Report an error situation discovered in a production
    616  *              NOTE: don't change the name of this function, it is called
    617  *              from the auto-generated parser.
    618  *
    619  ******************************************************************************/
    620 
    621 int
    622 AslCompilererror (
    623     char                    *CompilerMessage)
    624 {
    625 
    626     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
    627                     Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
    628                     Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
    629                     CompilerMessage);
    630 
    631     return 0;
    632 }
    633 
    634 
    635