1 /****************************************************************************** 2 * 3 * Module Name: aslerror - Error handling and statistics 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 "aslcompiler.h" 45 46 #define _COMPONENT ACPI_COMPILER 47 ACPI_MODULE_NAME ("aslerror") 48 49 /* Local prototypes */ 50 51 static void 52 AeAddToErrorLog ( 53 ASL_ERROR_MSG *Enode); 54 55 static BOOLEAN 56 AslIsExceptionExpected ( 57 UINT8 Level, 58 UINT16 MessageId); 59 60 static BOOLEAN 61 AslIsExceptionDisabled ( 62 UINT8 Level, 63 UINT16 MessageId); 64 65 static void AslInitEnode ( 66 ASL_ERROR_MSG **Enode, 67 UINT8 Level, 68 UINT16 MessageId, 69 UINT32 LineNumber, 70 UINT32 LogicalLineNumber, 71 UINT32 LogicalByteOffset, 72 UINT32 Column, 73 char *Filename, 74 char *Message, 75 char *SourceLine, 76 ASL_ERROR_MSG *SubError); 77 78 static void 79 AslLogNewError ( 80 UINT8 Level, 81 UINT16 MessageId, 82 UINT32 LineNumber, 83 UINT32 LogicalLineNumber, 84 UINT32 LogicalByteOffset, 85 UINT32 Column, 86 char *Filename, 87 char *Message, 88 char *SourceLine, 89 ASL_ERROR_MSG *SubError); 90 91 static void 92 AePrintSubError ( 93 FILE *OutputFile, 94 ASL_ERROR_MSG *Enode); 95 96 97 /******************************************************************************* 98 * 99 * FUNCTION: AslAbort 100 * 101 * PARAMETERS: None 102 * 103 * RETURN: None 104 * 105 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 106 * I/O errors. 107 * 108 ******************************************************************************/ 109 110 void 111 AslAbort ( 112 void) 113 { 114 115 AePrintErrorLog (ASL_FILE_STDERR); 116 if (Gbl_DebugFlag) 117 { 118 /* Print error summary to stdout also */ 119 120 AePrintErrorLog (ASL_FILE_STDOUT); 121 } 122 123 exit (1); 124 } 125 126 127 /******************************************************************************* 128 * 129 * FUNCTION: AeClearErrorLog 130 * 131 * PARAMETERS: None 132 * 133 * RETURN: None 134 * 135 * DESCRIPTION: Empty the error list 136 * 137 ******************************************************************************/ 138 139 void 140 AeClearErrorLog ( 141 void) 142 { 143 ASL_ERROR_MSG *Enode = Gbl_ErrorLog; 144 ASL_ERROR_MSG *Next; 145 146 147 /* Walk the error node list */ 148 149 while (Enode) 150 { 151 Next = Enode->Next; 152 ACPI_FREE (Enode); 153 Enode = Next; 154 } 155 156 Gbl_ErrorLog = NULL; 157 } 158 159 160 /******************************************************************************* 161 * 162 * FUNCTION: AeAddToErrorLog 163 * 164 * PARAMETERS: Enode - An error node to add to the log 165 * 166 * RETURN: None 167 * 168 * DESCRIPTION: Add a new error node to the error log. The error log is 169 * ordered by the "logical" line number (cumulative line number 170 * including all include files.) 171 * 172 ******************************************************************************/ 173 174 static void 175 AeAddToErrorLog ( 176 ASL_ERROR_MSG *Enode) 177 { 178 ASL_ERROR_MSG *Next; 179 ASL_ERROR_MSG *Prev; 180 181 182 /* If Gbl_ErrorLog is null, this is the first error node */ 183 184 if (!Gbl_ErrorLog) 185 { 186 Gbl_ErrorLog = Enode; 187 return; 188 } 189 190 /* 191 * Walk error list until we find a line number greater than ours. 192 * List is sorted according to line number. 193 */ 194 Prev = NULL; 195 Next = Gbl_ErrorLog; 196 197 while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber)) 198 { 199 Prev = Next; 200 Next = Next->Next; 201 } 202 203 /* Found our place in the list */ 204 205 Enode->Next = Next; 206 207 if (Prev) 208 { 209 Prev->Next = Enode; 210 } 211 else 212 { 213 Gbl_ErrorLog = Enode; 214 } 215 } 216 217 218 /******************************************************************************* 219 * 220 * FUNCTION: AeDecodeErrorMessageId 221 * 222 * PARAMETERS: OutputFile - Output file 223 * Enode - Error node to print 224 * PrematureEOF - True = PrematureEOF has been reached 225 * Total - Total legth of line 226 * 227 * RETURN: None 228 * 229 * DESCRIPTION: Print the source line of an error. 230 * 231 ******************************************************************************/ 232 233 static void 234 AeDecodeErrorMessageId ( 235 FILE *OutputFile, 236 ASL_ERROR_MSG *Enode, 237 BOOLEAN PrematureEOF, 238 UINT32 Total) 239 { 240 UINT32 MsgLength; 241 const char *MainMessage; 242 char *ExtraMessage; 243 UINT32 SourceColumn; 244 UINT32 ErrorColumn; 245 246 247 fprintf (OutputFile, "%s %4.4d -", 248 AeDecodeExceptionLevel (Enode->Level), 249 AeBuildFullExceptionCode (Enode->Level, Enode->MessageId)); 250 251 MainMessage = AeDecodeMessageId (Enode->MessageId); 252 ExtraMessage = Enode->Message; 253 254 /* If a NULL line number, just print the decoded message */ 255 256 if (!Enode->LineNumber) 257 { 258 fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage); 259 return; 260 } 261 262 MsgLength = strlen (MainMessage); 263 if (MsgLength == 0) 264 { 265 /* Use the secondary/extra message as main message */ 266 267 MainMessage = Enode->Message; 268 if (!MainMessage) 269 { 270 MainMessage = ""; 271 } 272 273 MsgLength = strlen (MainMessage); 274 ExtraMessage = NULL; 275 } 276 277 if (Gbl_VerboseErrors && !PrematureEOF) 278 { 279 if (Total >= 256) 280 { 281 fprintf (OutputFile, " %s", 282 MainMessage); 283 } 284 else 285 { 286 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2; 287 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1; 288 289 if ((MsgLength + ErrorColumn) < (SourceColumn - 1)) 290 { 291 fprintf (OutputFile, "%*s%s", 292 (int) ((SourceColumn - 1) - ErrorColumn), 293 MainMessage, " ^ "); 294 } 295 else 296 { 297 fprintf (OutputFile, "%*s %s", 298 (int) ((SourceColumn - ErrorColumn) + 1), "^", 299 MainMessage); 300 } 301 } 302 } 303 else 304 { 305 fprintf (OutputFile, " %s", MainMessage); 306 } 307 308 /* Print the extra info message if present */ 309 310 if (ExtraMessage) 311 { 312 fprintf (OutputFile, " (%s)", ExtraMessage); 313 } 314 315 if (PrematureEOF) 316 { 317 fprintf (OutputFile, " and premature End-Of-File"); 318 } 319 320 fprintf (OutputFile, "\n"); 321 if (Gbl_VerboseErrors && !Enode->SubError) 322 { 323 fprintf (OutputFile, "\n"); 324 } 325 } 326 327 328 /******************************************************************************* 329 * 330 * FUNCTION: AePrintErrorSourceLine 331 * 332 * PARAMETERS: OutputFile - Output file 333 * Enode - Error node to print 334 * PrematureEOF - True = PrematureEOF has been reached 335 * Total - amount of characters printed so far 336 * 337 * 338 * RETURN: Status 339 * 340 * DESCRIPTION: Print the source line of an error. 341 * 342 ******************************************************************************/ 343 344 static ACPI_STATUS 345 AePrintErrorSourceLine ( 346 FILE *OutputFile, 347 ASL_ERROR_MSG *Enode, 348 BOOLEAN *PrematureEOF, 349 UINT32 *Total) 350 { 351 UINT8 SourceByte; 352 int Actual; 353 size_t RActual; 354 FILE *SourceFile = NULL; 355 long FileSize; 356 357 358 if (!Enode->SourceLine) 359 { 360 /* 361 * Use the merged header/source file if present, otherwise 362 * use input file 363 */ 364 SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; 365 if (!SourceFile) 366 { 367 SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; 368 } 369 370 if (SourceFile) 371 { 372 /* Determine if the error occurred at source file EOF */ 373 374 fseek (SourceFile, 0, SEEK_END); 375 FileSize = ftell (SourceFile); 376 377 if ((long) Enode->LogicalByteOffset >= FileSize) 378 { 379 *PrematureEOF = TRUE; 380 } 381 } 382 else 383 { 384 fprintf (OutputFile, 385 "[*** iASL: Source File Does not exist ***]\n"); 386 return AE_IO_ERROR; 387 } 388 } 389 390 /* Print filename and line number if present and valid */ 391 392 if (Gbl_VerboseErrors) 393 { 394 fprintf (OutputFile, "%-8s", Enode->Filename); 395 396 if (Enode->SourceLine && Enode->LineNumber) 397 { 398 fprintf (OutputFile, " %6u: %s", 399 Enode->LineNumber, Enode->SourceLine); 400 } 401 else if (Enode->LineNumber) 402 { 403 fprintf (OutputFile, " %6u: ", Enode->LineNumber); 404 405 /* 406 * If not at EOF, get the corresponding source code line 407 * and display it. Don't attempt this if we have a 408 * premature EOF condition. 409 */ 410 if (*PrematureEOF) 411 { 412 fprintf (OutputFile, "\n"); 413 return AE_OK; 414 } 415 /* 416 * Seek to the offset in the combined source file, 417 * read the source line, and write it to the output. 418 */ 419 Actual = fseek (SourceFile, 420 (long) Enode->LogicalByteOffset, (int) SEEK_SET); 421 if (Actual) 422 { 423 fprintf (OutputFile, 424 "[*** iASL: Seek error on source code temp file %s ***]", 425 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); 426 427 fprintf (OutputFile, "\n"); 428 return AE_OK; 429 } 430 RActual = fread (&SourceByte, 1, 1, SourceFile); 431 if (RActual != 1) 432 { 433 fprintf (OutputFile, 434 "[*** iASL: Read error on source code temp file %s ***]", 435 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); 436 return AE_IO_ERROR; 437 } 438 /* Read/write the source line, up to the maximum line length */ 439 440 while (RActual && SourceByte && (SourceByte != '\n')) 441 { 442 if (*Total < 256) 443 { 444 /* After the max line length, we will just read the line, no write */ 445 446 if (fwrite (&SourceByte, 1, 1, OutputFile) != 1) 447 { 448 printf ("[*** iASL: Write error on output file ***]\n"); 449 return AE_IO_ERROR; 450 } 451 } 452 else if (*Total == 256) 453 { 454 fprintf (OutputFile, 455 "\n[*** iASL: Very long input line, message below refers to column %u ***]", 456 Enode->Column); 457 } 458 459 RActual = fread (&SourceByte, 1, 1, SourceFile); 460 if (RActual != 1) 461 { 462 fprintf (OutputFile, 463 "[*** iASL: Read error on source code temp file %s ***]", 464 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); 465 466 return AE_IO_ERROR; 467 } 468 *Total += 1; 469 } 470 471 fprintf (OutputFile, "\n"); 472 } 473 } 474 else 475 { 476 /* 477 * Less verbose version of the error message, enabled via the 478 * -vi switch. The format is compatible with MS Visual Studio. 479 */ 480 fprintf (OutputFile, "%s", Enode->Filename); 481 482 if (Enode->LineNumber) 483 { 484 fprintf (OutputFile, "(%u) : ", 485 Enode->LineNumber); 486 } 487 } 488 489 return AE_OK; 490 } 491 492 /******************************************************************************* 493 * 494 * FUNCTION: AePrintException 495 * 496 * PARAMETERS: FileId - ID of output file 497 * Enode - Error node to print 498 * Header - Additional text before each message 499 * 500 * RETURN: None 501 * 502 * DESCRIPTION: Print the contents of an error node. 503 * 504 * NOTE: We don't use the FlxxxFile I/O functions here because on error 505 * they abort the compiler and call this function! Since we 506 * are reporting errors here, we ignore most output errors and 507 * just try to get out as much as we can. 508 * 509 ******************************************************************************/ 510 511 void 512 AePrintException ( 513 UINT32 FileId, 514 ASL_ERROR_MSG *Enode, 515 char *Header) 516 { 517 FILE *OutputFile; 518 BOOLEAN PrematureEOF = FALSE; 519 UINT32 Total = 0; 520 ACPI_STATUS Status; 521 ASL_ERROR_MSG *Child = Enode->SubError; 522 523 524 if (Gbl_NoErrors) 525 { 526 return; 527 } 528 529 /* 530 * Only listing files have a header, and remarks/optimizations 531 * are always output 532 */ 533 if (!Header) 534 { 535 /* Ignore remarks if requested */ 536 537 switch (Enode->Level) 538 { 539 case ASL_WARNING: 540 case ASL_WARNING2: 541 case ASL_WARNING3: 542 543 if (!Gbl_DisplayWarnings) 544 { 545 return; 546 } 547 break; 548 549 case ASL_REMARK: 550 551 if (!Gbl_DisplayRemarks) 552 { 553 return; 554 } 555 break; 556 557 case ASL_OPTIMIZATION: 558 559 if (!Gbl_DisplayOptimizations) 560 { 561 return; 562 } 563 break; 564 565 default: 566 567 break; 568 } 569 } 570 571 /* Get the various required file handles */ 572 573 OutputFile = Gbl_Files[FileId].Handle; 574 575 if (Header) 576 { 577 fprintf (OutputFile, "%s", Header); 578 } 579 580 if (!Enode->Filename) 581 { 582 AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total); 583 return; 584 } 585 586 Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total); 587 if (ACPI_FAILURE (Status)) 588 { 589 return; 590 } 591 592 /* If a NULL message ID, just print the raw message */ 593 594 if (Enode->MessageId == 0) 595 { 596 fprintf (OutputFile, "%s\n", Enode->Message); 597 return; 598 } 599 600 AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total); 601 602 while (Child) 603 { 604 fprintf (OutputFile, "\n"); 605 AePrintSubError (OutputFile, Child); 606 Child = Child->SubError; 607 } 608 } 609 610 611 /******************************************************************************* 612 * 613 * FUNCTION: AePrintSubError 614 * 615 * PARAMETERS: OutputFile - Output file 616 * Enode - Error node to print 617 * 618 * RETURN: None 619 * 620 * DESCRIPTION: Print the contents of an error nodes. This function is tailored 621 * to print error nodes that are SubErrors within ASL_ERROR_MSG 622 * 623 ******************************************************************************/ 624 625 static void 626 AePrintSubError ( 627 FILE *OutputFile, 628 ASL_ERROR_MSG *Enode) 629 { 630 UINT32 Total = 0; 631 BOOLEAN PrematureEOF = FALSE; 632 const char *MainMessage; 633 634 635 MainMessage = AeDecodeMessageId (Enode->MessageId); 636 637 fprintf (OutputFile, " %s%s", MainMessage, "\n "); 638 (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total); 639 fprintf (OutputFile, "\n"); 640 } 641 642 643 /******************************************************************************* 644 * 645 * FUNCTION: AePrintErrorLog 646 * 647 * PARAMETERS: FileId - Where to output the error log 648 * 649 * RETURN: None 650 * 651 * DESCRIPTION: Print the entire contents of the error log 652 * 653 ******************************************************************************/ 654 655 void 656 AePrintErrorLog ( 657 UINT32 FileId) 658 { 659 ASL_ERROR_MSG *Enode = Gbl_ErrorLog; 660 661 662 /* Walk the error node list */ 663 664 while (Enode) 665 { 666 AePrintException (FileId, Enode, NULL); 667 Enode = Enode->Next; 668 } 669 } 670 671 672 /******************************************************************************* 673 * 674 * FUNCTION: AslInitEnode 675 * 676 * PARAMETERS: InputEnode - Input Error node to initialize 677 * Level - Seriousness (Warning/error, etc.) 678 * MessageId - Index into global message buffer 679 * CurrentLineNumber - Actual file line number 680 * LogicalLineNumber - Cumulative line number 681 * LogicalByteOffset - Byte offset in source file 682 * Column - Column in current line 683 * Filename - source filename 684 * ExtraMessage - additional error message 685 * SourceLine - Line of error source code 686 * SubError - SubError of this InputEnode 687 * 688 * RETURN: None 689 * 690 * DESCRIPTION: Initialize an Error node 691 * 692 ******************************************************************************/ 693 694 static void AslInitEnode ( 695 ASL_ERROR_MSG **InputEnode, 696 UINT8 Level, 697 UINT16 MessageId, 698 UINT32 LineNumber, 699 UINT32 LogicalLineNumber, 700 UINT32 LogicalByteOffset, 701 UINT32 Column, 702 char *Filename, 703 char *ExtraMessage, 704 char *SourceLine, 705 ASL_ERROR_MSG *SubError) 706 { 707 ASL_ERROR_MSG *Enode; 708 709 710 *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG)); 711 Enode = *InputEnode; 712 Enode->Level = Level; 713 Enode->MessageId = MessageId; 714 Enode->LineNumber = LineNumber; 715 Enode->LogicalLineNumber = LogicalLineNumber; 716 Enode->LogicalByteOffset = LogicalByteOffset; 717 Enode->Column = Column; 718 Enode->SubError = SubError; 719 Enode->Message = NULL; 720 Enode->SourceLine = NULL; 721 Enode->Filename = NULL; 722 723 if (ExtraMessage) 724 { 725 /* Allocate a buffer for the message and a new error node */ 726 727 Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1); 728 729 /* Keep a copy of the extra message */ 730 731 strcpy (Enode->Message, ExtraMessage); 732 } 733 734 if (SourceLine) 735 { 736 Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1); 737 strcpy (Enode->SourceLine, SourceLine); 738 } 739 740 741 if (Filename) 742 { 743 Enode->Filename = Filename; 744 Enode->FilenameLength = strlen (Filename); 745 if (Enode->FilenameLength < 6) 746 { 747 Enode->FilenameLength = 6; 748 } 749 } 750 } 751 752 753 /******************************************************************************* 754 * 755 * FUNCTION: AslCommonError2 756 * 757 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 758 * MessageId - Index into global message buffer 759 * LineNumber - Actual file line number 760 * Column - Column in current line 761 * SourceLine - Actual source code line 762 * Filename - source filename 763 * ExtraMessage - additional error message 764 * 765 * RETURN: None 766 * 767 * DESCRIPTION: Create a new error node and add it to the error log 768 * 769 ******************************************************************************/ 770 771 void 772 AslCommonError2 ( 773 UINT8 Level, 774 UINT16 MessageId, 775 UINT32 LineNumber, 776 UINT32 Column, 777 char *SourceLine, 778 char *Filename, 779 char *ExtraMessage) 780 { 781 AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column, 782 Filename, ExtraMessage, SourceLine, NULL); 783 } 784 785 786 /******************************************************************************* 787 * 788 * FUNCTION: AslCommonError 789 * 790 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 791 * MessageId - Index into global message buffer 792 * CurrentLineNumber - Actual file line number 793 * LogicalLineNumber - Cumulative line number 794 * LogicalByteOffset - Byte offset in source file 795 * Column - Column in current line 796 * Filename - source filename 797 * ExtraMessage - additional error message 798 * 799 * RETURN: None 800 * 801 * DESCRIPTION: Create a new error node and add it to the error log 802 * 803 ******************************************************************************/ 804 805 void 806 AslCommonError ( 807 UINT8 Level, 808 UINT16 MessageId, 809 UINT32 CurrentLineNumber, 810 UINT32 LogicalLineNumber, 811 UINT32 LogicalByteOffset, 812 UINT32 Column, 813 char *Filename, 814 char *ExtraMessage) 815 { 816 AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber, 817 LogicalByteOffset, Column, Filename, ExtraMessage, 818 NULL, NULL); 819 } 820 821 822 /******************************************************************************* 823 * 824 * FUNCTION: AslLogNewError 825 * 826 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 827 * MessageId - Index into global message buffer 828 * CurrentLineNumber - Actual file line number 829 * LogicalLineNumber - Cumulative line number 830 * LogicalByteOffset - Byte offset in source file 831 * Column - Column in current line 832 * Filename - source filename 833 * Message - additional error message 834 * SourceLine - Actual line of source code 835 * SubError - Sub-error associated with this error 836 * 837 * RETURN: None 838 * 839 * DESCRIPTION: Create a new error node and add it to the error log 840 * 841 ******************************************************************************/ 842 static void 843 AslLogNewError ( 844 UINT8 Level, 845 UINT16 MessageId, 846 UINT32 LineNumber, 847 UINT32 LogicalLineNumber, 848 UINT32 LogicalByteOffset, 849 UINT32 Column, 850 char *Filename, 851 char *Message, 852 char *SourceLine, 853 ASL_ERROR_MSG *SubError) 854 { 855 ASL_ERROR_MSG *Enode = NULL; 856 857 858 AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber, 859 LogicalByteOffset, Column, Filename, Message, SourceLine, 860 SubError); 861 862 /* Add the new node to the error node list */ 863 864 AeAddToErrorLog (Enode); 865 866 if (Gbl_DebugFlag) 867 { 868 /* stderr is a file, send error to it immediately */ 869 870 AePrintException (ASL_FILE_STDERR, Enode, NULL); 871 } 872 873 Gbl_ExceptionCount[Level]++; 874 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 875 { 876 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT); 877 878 Gbl_SourceLine = 0; 879 Gbl_NextError = Gbl_ErrorLog; 880 CmCleanupAndExit (); 881 exit(1); 882 } 883 884 return; 885 } 886 887 /******************************************************************************* 888 * 889 * FUNCTION: AslIsExceptionIgnored 890 * 891 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 892 * MessageId - Index into global message buffer 893 * 894 * RETURN: BOOLEAN 895 * 896 * DESCRIPTION: Check if a particular exception is ignored. In this case it 897 * means that the exception is (expected or disabled. 898 * 899 ******************************************************************************/ 900 901 BOOLEAN 902 AslIsExceptionIgnored ( 903 UINT8 Level, 904 UINT16 MessageId) 905 { 906 BOOLEAN ExceptionIgnored; 907 908 909 /* Note: this allows exception to be disabled and expected */ 910 911 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId); 912 ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId); 913 914 return (Gbl_AllExceptionsDisabled || ExceptionIgnored); 915 } 916 917 918 /******************************************************************************* 919 * 920 * FUNCTION: AslCheckExpectException 921 * 922 * PARAMETERS: none 923 * 924 * RETURN: none 925 * 926 * DESCRIPTION: Check the global expected messages table and raise an error 927 * for each message that has not been received. 928 * 929 ******************************************************************************/ 930 931 void 932 AslCheckExpectedExceptions ( 933 void) 934 { 935 UINT8 i; 936 937 938 for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i) 939 { 940 if (!Gbl_ExpectedMessages[i].MessageReceived) 941 { 942 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL, 943 Gbl_ExpectedMessages[i].MessageIdStr); 944 } 945 } 946 } 947 948 949 /******************************************************************************* 950 * 951 * FUNCTION: AslExpectException 952 * 953 * PARAMETERS: MessageIdString - ID of excepted exception during compile 954 * 955 * RETURN: Status 956 * 957 * DESCRIPTION: Enter a message ID into the global expected messages table 958 * If these messages are not raised during the compilation, throw 959 * an error. 960 * 961 ******************************************************************************/ 962 963 ACPI_STATUS 964 AslExpectException ( 965 char *MessageIdString) 966 { 967 UINT32 MessageId; 968 969 970 /* Convert argument to an integer and validate it */ 971 972 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 973 974 if (MessageId > 6999) 975 { 976 printf ("\"%s\" is not a valid warning/remark/erro ID\n", 977 MessageIdString); 978 return (AE_BAD_PARAMETER); 979 } 980 981 /* Insert value into the global expected message array */ 982 983 if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES) 984 { 985 printf ("Too many messages have been registered as expected (max %u)\n", 986 ASL_MAX_DISABLED_MESSAGES); 987 return (AE_LIMIT); 988 } 989 990 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId; 991 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString; 992 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE; 993 Gbl_ExpectedMessagesIndex++; 994 return (AE_OK); 995 } 996 997 998 /******************************************************************************* 999 * 1000 * FUNCTION: AslDisableException 1001 * 1002 * PARAMETERS: MessageIdString - ID to be disabled 1003 * 1004 * RETURN: Status 1005 * 1006 * DESCRIPTION: Enter a message ID into the global disabled messages table 1007 * 1008 ******************************************************************************/ 1009 1010 ACPI_STATUS 1011 AslDisableException ( 1012 char *MessageIdString) 1013 { 1014 UINT32 MessageId; 1015 1016 1017 /* Convert argument to an integer and validate it */ 1018 1019 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1020 1021 if ((MessageId < 2000) || (MessageId > 6999)) 1022 { 1023 printf ("\"%s\" is not a valid warning/remark/error ID\n", 1024 MessageIdString); 1025 return (AE_BAD_PARAMETER); 1026 } 1027 1028 /* Insert value into the global disabled message array */ 1029 1030 if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES) 1031 { 1032 printf ("Too many messages have been disabled (max %u)\n", 1033 ASL_MAX_DISABLED_MESSAGES); 1034 return (AE_LIMIT); 1035 } 1036 1037 Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId; 1038 Gbl_DisabledMessagesIndex++; 1039 return (AE_OK); 1040 } 1041 1042 1043 /******************************************************************************* 1044 * 1045 * FUNCTION: AslIsExceptionDisabled 1046 * 1047 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1048 * MessageId - Index into global message buffer 1049 * 1050 * RETURN: TRUE if exception/message should be ignored 1051 * 1052 * DESCRIPTION: Check if the user has specified options such that this 1053 * exception should be ignored 1054 * 1055 ******************************************************************************/ 1056 1057 static BOOLEAN 1058 AslIsExceptionExpected ( 1059 UINT8 Level, 1060 UINT16 MessageId) 1061 { 1062 UINT32 EncodedMessageId; 1063 UINT32 i; 1064 1065 1066 /* Mark this exception as received */ 1067 1068 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1069 for (i = 0; i < Gbl_ExpectedMessagesIndex; i++) 1070 { 1071 /* Simple implementation via fixed array */ 1072 1073 if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId) 1074 { 1075 return (Gbl_ExpectedMessages[i].MessageReceived = TRUE); 1076 } 1077 } 1078 1079 return (FALSE); 1080 } 1081 1082 1083 /******************************************************************************* 1084 * 1085 * FUNCTION: AslIsExceptionDisabled 1086 * 1087 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1088 * MessageId - Index into global message buffer 1089 * 1090 * RETURN: TRUE if exception/message should be ignored 1091 * 1092 * DESCRIPTION: Check if the user has specified options such that this 1093 * exception should be ignored 1094 * 1095 ******************************************************************************/ 1096 1097 static BOOLEAN 1098 AslIsExceptionDisabled ( 1099 UINT8 Level, 1100 UINT16 MessageId) 1101 { 1102 UINT32 EncodedMessageId; 1103 UINT32 i; 1104 1105 1106 switch (Level) 1107 { 1108 case ASL_WARNING2: 1109 case ASL_WARNING3: 1110 1111 /* Check for global disable via -w1/-w2/-w3 options */ 1112 1113 if (Level > Gbl_WarningLevel) 1114 { 1115 return (TRUE); 1116 } 1117 /* Fall through */ 1118 1119 case ASL_WARNING: 1120 case ASL_REMARK: 1121 case ASL_ERROR: 1122 /* 1123 * Ignore this error/warning/remark if it has been disabled by 1124 * the user (-vw option) 1125 */ 1126 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1127 for (i = 0; i < Gbl_DisabledMessagesIndex; i++) 1128 { 1129 /* Simple implementation via fixed array */ 1130 1131 if (EncodedMessageId == Gbl_DisabledMessages[i]) 1132 { 1133 return (TRUE); 1134 } 1135 } 1136 break; 1137 1138 default: 1139 break; 1140 } 1141 1142 return (FALSE); 1143 } 1144 1145 1146 /******************************************************************************* 1147 * 1148 * FUNCTION: AslDualParseOpError 1149 * 1150 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1151 * MainMsgId - Index into global message buffer 1152 * MainOp - Parse node where error happened 1153 * MainMsg - Message pertaining to the MainOp 1154 * SubMsgId - Index into global message buffer 1155 * SubOp - Additional parse node for better message 1156 * SubMsg - Message pertainint to SubOp 1157 * 1158 * 1159 * RETURN: None 1160 * 1161 * DESCRIPTION: Main error reporting routine for the ASL compiler for error 1162 * messages that point to multiple parse objects. 1163 * 1164 ******************************************************************************/ 1165 1166 void 1167 AslDualParseOpError ( 1168 UINT8 Level, 1169 UINT16 MainMsgId, 1170 ACPI_PARSE_OBJECT *MainOp, 1171 char *MainMsg, 1172 UINT16 SubMsgId, 1173 ACPI_PARSE_OBJECT *SubOp, 1174 char *SubMsg) 1175 { 1176 ASL_ERROR_MSG *SubEnode = NULL; 1177 1178 1179 /* Check if user wants to ignore this exception */ 1180 1181 if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp) 1182 { 1183 return; 1184 } 1185 1186 if (SubOp) 1187 { 1188 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber, 1189 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset, 1190 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg, 1191 NULL, NULL); 1192 } 1193 1194 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber, 1195 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset, 1196 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg, 1197 NULL, SubEnode); 1198 } 1199 1200 1201 /******************************************************************************* 1202 * 1203 * FUNCTION: AslError 1204 * 1205 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1206 * MessageId - Index into global message buffer 1207 * Op - Parse node where error happened 1208 * ExtraMessage - additional error message 1209 * 1210 * RETURN: None 1211 * 1212 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code 1213 * except the parser.) 1214 * 1215 ******************************************************************************/ 1216 1217 void 1218 AslError ( 1219 UINT8 Level, 1220 UINT16 MessageId, 1221 ACPI_PARSE_OBJECT *Op, 1222 char *ExtraMessage) 1223 { 1224 if (Op) 1225 { 1226 AslCommonError (Level, MessageId, Op->Asl.LineNumber, 1227 Op->Asl.LogicalLineNumber, 1228 Op->Asl.LogicalByteOffset, 1229 Op->Asl.Column, 1230 Op->Asl.Filename, ExtraMessage); 1231 } 1232 else 1233 { 1234 AslCommonError (Level, MessageId, 0, 1235 0, 0, 0, NULL, ExtraMessage); 1236 } 1237 } 1238 1239 1240 /******************************************************************************* 1241 * 1242 * FUNCTION: AslCoreSubsystemError 1243 * 1244 * PARAMETERS: Op - Parse node where error happened 1245 * Status - The ACPICA Exception 1246 * ExtraMessage - additional error message 1247 * Abort - TRUE -> Abort compilation 1248 * 1249 * RETURN: None 1250 * 1251 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA 1252 * core subsystem. 1253 * 1254 ******************************************************************************/ 1255 1256 void 1257 AslCoreSubsystemError ( 1258 ACPI_PARSE_OBJECT *Op, 1259 ACPI_STATUS Status, 1260 char *ExtraMessage, 1261 BOOLEAN Abort) 1262 { 1263 1264 snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage); 1265 1266 if (Op) 1267 { 1268 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1269 Op->Asl.LineNumber, 1270 Op->Asl.LogicalLineNumber, 1271 Op->Asl.LogicalByteOffset, 1272 Op->Asl.Column, 1273 Op->Asl.Filename, MsgBuffer); 1274 } 1275 else 1276 { 1277 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1278 0, 0, 0, 0, NULL, MsgBuffer); 1279 } 1280 1281 if (Abort) 1282 { 1283 AslAbort (); 1284 } 1285 } 1286 1287 1288 /******************************************************************************* 1289 * 1290 * FUNCTION: AslCompilererror 1291 * 1292 * PARAMETERS: CompilerMessage - Error message from the parser 1293 * 1294 * RETURN: Status (0 for now) 1295 * 1296 * DESCRIPTION: Report an error situation discovered in a production 1297 * NOTE: don't change the name of this function, it is called 1298 * from the auto-generated parser. 1299 * 1300 ******************************************************************************/ 1301 1302 int 1303 AslCompilererror ( 1304 const char *CompilerMessage) 1305 { 1306 1307 Gbl_SyntaxError++; 1308 1309 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber, 1310 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset, 1311 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename, 1312 ACPI_CAST_PTR (char, CompilerMessage)); 1313 1314 return (0); 1315 } 1316