1 /****************************************************************************** 2 * 3 * Module Name: aslerror - Error handling and statistics 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 /* Check if user wants to ignore this exception */ 817 818 if (AslIsExceptionIgnored (Level, MessageId)) 819 { 820 return; 821 } 822 823 AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber, 824 LogicalByteOffset, Column, Filename, ExtraMessage, 825 NULL, NULL); 826 } 827 828 829 /******************************************************************************* 830 * 831 * FUNCTION: AslLogNewError 832 * 833 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 834 * MessageId - Index into global message buffer 835 * CurrentLineNumber - Actual file line number 836 * LogicalLineNumber - Cumulative line number 837 * LogicalByteOffset - Byte offset in source file 838 * Column - Column in current line 839 * Filename - source filename 840 * Message - additional error message 841 * SourceLine - Actual line of source code 842 * SubError - Sub-error associated with this error 843 * 844 * RETURN: None 845 * 846 * DESCRIPTION: Create a new error node and add it to the error log 847 * 848 ******************************************************************************/ 849 static void 850 AslLogNewError ( 851 UINT8 Level, 852 UINT16 MessageId, 853 UINT32 LineNumber, 854 UINT32 LogicalLineNumber, 855 UINT32 LogicalByteOffset, 856 UINT32 Column, 857 char *Filename, 858 char *Message, 859 char *SourceLine, 860 ASL_ERROR_MSG *SubError) 861 { 862 ASL_ERROR_MSG *Enode = NULL; 863 864 865 AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber, 866 LogicalByteOffset, Column, Filename, Message, SourceLine, 867 SubError); 868 869 /* Add the new node to the error node list */ 870 871 AeAddToErrorLog (Enode); 872 873 if (Gbl_DebugFlag) 874 { 875 /* stderr is a file, send error to it immediately */ 876 877 AePrintException (ASL_FILE_STDERR, Enode, NULL); 878 } 879 880 Gbl_ExceptionCount[Level]++; 881 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 882 { 883 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT); 884 885 Gbl_SourceLine = 0; 886 Gbl_NextError = Gbl_ErrorLog; 887 CmCleanupAndExit (); 888 exit(1); 889 } 890 891 return; 892 } 893 894 /******************************************************************************* 895 * 896 * FUNCTION: AslIsExceptionIgnored 897 * 898 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 899 * MessageId - Index into global message buffer 900 * 901 * RETURN: BOOLEAN 902 * 903 * DESCRIPTION: Check if a particular exception is ignored. In this case it 904 * means that the exception is (expected or disabled. 905 * 906 ******************************************************************************/ 907 908 BOOLEAN 909 AslIsExceptionIgnored ( 910 UINT8 Level, 911 UINT16 MessageId) 912 { 913 BOOLEAN ExceptionIgnored; 914 915 916 /* Note: this allows exception to be disabled and expected */ 917 918 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId); 919 ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId); 920 921 return (Gbl_AllExceptionsDisabled || ExceptionIgnored); 922 } 923 924 925 /******************************************************************************* 926 * 927 * FUNCTION: AslCheckExpectException 928 * 929 * PARAMETERS: none 930 * 931 * RETURN: none 932 * 933 * DESCRIPTION: Check the global expected messages table and raise an error 934 * for each message that has not been received. 935 * 936 ******************************************************************************/ 937 938 void 939 AslCheckExpectedExceptions ( 940 void) 941 { 942 UINT8 i; 943 944 945 for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i) 946 { 947 if (!Gbl_ExpectedMessages[i].MessageReceived) 948 { 949 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL, 950 Gbl_ExpectedMessages[i].MessageIdStr); 951 } 952 } 953 } 954 955 956 /******************************************************************************* 957 * 958 * FUNCTION: AslExpectException 959 * 960 * PARAMETERS: MessageIdString - ID of excepted exception during compile 961 * 962 * RETURN: Status 963 * 964 * DESCRIPTION: Enter a message ID into the global expected messages table 965 * If these messages are not raised during the compilation, throw 966 * an error. 967 * 968 ******************************************************************************/ 969 970 ACPI_STATUS 971 AslExpectException ( 972 char *MessageIdString) 973 { 974 UINT32 MessageId; 975 976 977 /* Convert argument to an integer and validate it */ 978 979 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 980 981 if (MessageId > 6999) 982 { 983 printf ("\"%s\" is not a valid warning/remark/erro ID\n", 984 MessageIdString); 985 return (AE_BAD_PARAMETER); 986 } 987 988 /* Insert value into the global expected message array */ 989 990 if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES) 991 { 992 printf ("Too many messages have been registered as expected (max %u)\n", 993 ASL_MAX_DISABLED_MESSAGES); 994 return (AE_LIMIT); 995 } 996 997 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId; 998 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString; 999 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE; 1000 Gbl_ExpectedMessagesIndex++; 1001 return (AE_OK); 1002 } 1003 1004 1005 /******************************************************************************* 1006 * 1007 * FUNCTION: AslDisableException 1008 * 1009 * PARAMETERS: MessageIdString - ID to be disabled 1010 * 1011 * RETURN: Status 1012 * 1013 * DESCRIPTION: Enter a message ID into the global disabled messages table 1014 * 1015 ******************************************************************************/ 1016 1017 ACPI_STATUS 1018 AslDisableException ( 1019 char *MessageIdString) 1020 { 1021 UINT32 MessageId; 1022 1023 1024 /* Convert argument to an integer and validate it */ 1025 1026 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1027 1028 if ((MessageId < 2000) || (MessageId > 6999)) 1029 { 1030 printf ("\"%s\" is not a valid warning/remark/error ID\n", 1031 MessageIdString); 1032 return (AE_BAD_PARAMETER); 1033 } 1034 1035 /* Insert value into the global disabled message array */ 1036 1037 if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES) 1038 { 1039 printf ("Too many messages have been disabled (max %u)\n", 1040 ASL_MAX_DISABLED_MESSAGES); 1041 return (AE_LIMIT); 1042 } 1043 1044 Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId; 1045 Gbl_DisabledMessagesIndex++; 1046 return (AE_OK); 1047 } 1048 1049 1050 /******************************************************************************* 1051 * 1052 * FUNCTION: AslIsExceptionDisabled 1053 * 1054 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1055 * MessageId - Index into global message buffer 1056 * 1057 * RETURN: TRUE if exception/message should be ignored 1058 * 1059 * DESCRIPTION: Check if the user has specified options such that this 1060 * exception should be ignored 1061 * 1062 ******************************************************************************/ 1063 1064 static BOOLEAN 1065 AslIsExceptionExpected ( 1066 UINT8 Level, 1067 UINT16 MessageId) 1068 { 1069 UINT32 EncodedMessageId; 1070 UINT32 i; 1071 1072 1073 /* Mark this exception as received */ 1074 1075 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1076 for (i = 0; i < Gbl_ExpectedMessagesIndex; i++) 1077 { 1078 /* Simple implementation via fixed array */ 1079 1080 if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId) 1081 { 1082 return (Gbl_ExpectedMessages[i].MessageReceived = TRUE); 1083 } 1084 } 1085 1086 return (FALSE); 1087 } 1088 1089 1090 /******************************************************************************* 1091 * 1092 * FUNCTION: AslIsExceptionDisabled 1093 * 1094 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1095 * MessageId - Index into global message buffer 1096 * 1097 * RETURN: TRUE if exception/message should be ignored 1098 * 1099 * DESCRIPTION: Check if the user has specified options such that this 1100 * exception should be ignored 1101 * 1102 ******************************************************************************/ 1103 1104 static BOOLEAN 1105 AslIsExceptionDisabled ( 1106 UINT8 Level, 1107 UINT16 MessageId) 1108 { 1109 UINT32 EncodedMessageId; 1110 UINT32 i; 1111 1112 1113 switch (Level) 1114 { 1115 case ASL_WARNING2: 1116 case ASL_WARNING3: 1117 1118 /* Check for global disable via -w1/-w2/-w3 options */ 1119 1120 if (Level > Gbl_WarningLevel) 1121 { 1122 return (TRUE); 1123 } 1124 /* Fall through */ 1125 1126 case ASL_WARNING: 1127 case ASL_REMARK: 1128 case ASL_ERROR: 1129 /* 1130 * Ignore this error/warning/remark if it has been disabled by 1131 * the user (-vw option) 1132 */ 1133 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1134 for (i = 0; i < Gbl_DisabledMessagesIndex; i++) 1135 { 1136 /* Simple implementation via fixed array */ 1137 1138 if (EncodedMessageId == Gbl_DisabledMessages[i]) 1139 { 1140 return (TRUE); 1141 } 1142 } 1143 break; 1144 1145 default: 1146 break; 1147 } 1148 1149 return (FALSE); 1150 } 1151 1152 1153 /******************************************************************************* 1154 * 1155 * FUNCTION: AslDualParseOpError 1156 * 1157 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1158 * MainMsgId - Index into global message buffer 1159 * MainOp - Parse node where error happened 1160 * MainMsg - Message pertaining to the MainOp 1161 * SubMsgId - Index into global message buffer 1162 * SubOp - Additional parse node for better message 1163 * SubMsg - Message pertainint to SubOp 1164 * 1165 * 1166 * RETURN: None 1167 * 1168 * DESCRIPTION: Main error reporting routine for the ASL compiler for error 1169 * messages that point to multiple parse objects. 1170 * 1171 ******************************************************************************/ 1172 1173 void 1174 AslDualParseOpError ( 1175 UINT8 Level, 1176 UINT16 MainMsgId, 1177 ACPI_PARSE_OBJECT *MainOp, 1178 char *MainMsg, 1179 UINT16 SubMsgId, 1180 ACPI_PARSE_OBJECT *SubOp, 1181 char *SubMsg) 1182 { 1183 ASL_ERROR_MSG *SubEnode = NULL; 1184 1185 1186 /* Check if user wants to ignore this exception */ 1187 1188 if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp) 1189 { 1190 return; 1191 } 1192 1193 if (SubOp) 1194 { 1195 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber, 1196 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset, 1197 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg, 1198 NULL, NULL); 1199 } 1200 1201 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber, 1202 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset, 1203 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg, 1204 NULL, SubEnode); 1205 } 1206 1207 1208 /******************************************************************************* 1209 * 1210 * FUNCTION: AslError 1211 * 1212 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1213 * MessageId - Index into global message buffer 1214 * Op - Parse node where error happened 1215 * ExtraMessage - additional error message 1216 * 1217 * RETURN: None 1218 * 1219 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code 1220 * except the parser.) 1221 * 1222 ******************************************************************************/ 1223 1224 void 1225 AslError ( 1226 UINT8 Level, 1227 UINT16 MessageId, 1228 ACPI_PARSE_OBJECT *Op, 1229 char *ExtraMessage) 1230 { 1231 if (Op) 1232 { 1233 AslCommonError (Level, MessageId, Op->Asl.LineNumber, 1234 Op->Asl.LogicalLineNumber, 1235 Op->Asl.LogicalByteOffset, 1236 Op->Asl.Column, 1237 Op->Asl.Filename, ExtraMessage); 1238 } 1239 else 1240 { 1241 AslCommonError (Level, MessageId, 0, 1242 0, 0, 0, NULL, ExtraMessage); 1243 } 1244 } 1245 1246 1247 /******************************************************************************* 1248 * 1249 * FUNCTION: AslCoreSubsystemError 1250 * 1251 * PARAMETERS: Op - Parse node where error happened 1252 * Status - The ACPICA Exception 1253 * ExtraMessage - additional error message 1254 * Abort - TRUE -> Abort compilation 1255 * 1256 * RETURN: None 1257 * 1258 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA 1259 * core subsystem. 1260 * 1261 ******************************************************************************/ 1262 1263 void 1264 AslCoreSubsystemError ( 1265 ACPI_PARSE_OBJECT *Op, 1266 ACPI_STATUS Status, 1267 char *ExtraMessage, 1268 BOOLEAN Abort) 1269 { 1270 1271 snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage); 1272 1273 if (Op) 1274 { 1275 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1276 Op->Asl.LineNumber, 1277 Op->Asl.LogicalLineNumber, 1278 Op->Asl.LogicalByteOffset, 1279 Op->Asl.Column, 1280 Op->Asl.Filename, MsgBuffer); 1281 } 1282 else 1283 { 1284 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1285 0, 0, 0, 0, NULL, MsgBuffer); 1286 } 1287 1288 if (Abort) 1289 { 1290 AslAbort (); 1291 } 1292 } 1293 1294 1295 /******************************************************************************* 1296 * 1297 * FUNCTION: AslCompilererror 1298 * 1299 * PARAMETERS: CompilerMessage - Error message from the parser 1300 * 1301 * RETURN: Status (0 for now) 1302 * 1303 * DESCRIPTION: Report an error situation discovered in a production 1304 * NOTE: don't change the name of this function, it is called 1305 * from the auto-generated parser. 1306 * 1307 ******************************************************************************/ 1308 1309 int 1310 AslCompilererror ( 1311 const char *CompilerMessage) 1312 { 1313 1314 Gbl_SyntaxError++; 1315 1316 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber, 1317 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset, 1318 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename, 1319 ACPI_CAST_PTR (char, CompilerMessage)); 1320 1321 return (0); 1322 } 1323