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