1 /****************************************************************************** 2 * 3 * Module Name: aslerror - Error handling and statistics 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 (aslerror.c)\n", ASL_MAX_ERROR_COUNT); 921 922 AslGbl_SourceLine = 0; 923 AslGbl_NextError = AslGbl_ErrorLog; 924 CmCleanupAndExit (); 925 exit(1); 926 } 927 928 AslGbl_ExceptionCount[ASL_ERROR] = 0; 929 return; 930 } 931 932 933 /******************************************************************************* 934 * 935 * FUNCTION: GetModifiedLevel 936 * 937 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 938 * MessageId - Index into global message buffer 939 * 940 * RETURN: UINT8 - Modified level 941 * 942 * DESCRIPTION: Get the modified level of exception codes that are reported as 943 * errors from the -ww option. 944 * 945 ******************************************************************************/ 946 947 static UINT8 948 GetModifiedLevel ( 949 UINT8 Level, 950 UINT16 MessageId) 951 { 952 UINT32 i; 953 UINT16 ExceptionCode; 954 955 956 ExceptionCode = AeBuildFullExceptionCode (Level, MessageId); 957 958 for (i = 0; i < AslGbl_ElevatedMessagesIndex; i++) 959 { 960 if (ExceptionCode == AslGbl_ElevatedMessages[i]) 961 { 962 return (ASL_ERROR); 963 } 964 } 965 966 return (Level); 967 } 968 969 970 /******************************************************************************* 971 * 972 * FUNCTION: AslIsExceptionIgnored 973 * 974 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 975 * MessageId - Index into global message buffer 976 * 977 * RETURN: BOOLEAN 978 * 979 * DESCRIPTION: Check if a particular exception is ignored. In this case it 980 * means that the exception is (expected or disabled. 981 * 982 ******************************************************************************/ 983 984 BOOLEAN 985 AslIsExceptionIgnored ( 986 char *Filename, 987 UINT32 LineNumber, 988 UINT8 Level, 989 UINT16 MessageId) 990 { 991 BOOLEAN ExceptionIgnored; 992 993 994 /* Note: this allows exception to be disabled and expected */ 995 996 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId); 997 ExceptionIgnored |= 998 AslIsExceptionExpected (Filename, LineNumber, Level, MessageId); 999 1000 return (AslGbl_AllExceptionsDisabled || ExceptionIgnored); 1001 } 1002 1003 1004 /******************************************************************************* 1005 * 1006 * FUNCTION: AslCheckExpectedException 1007 * 1008 * PARAMETERS: none 1009 * 1010 * RETURN: none 1011 * 1012 * DESCRIPTION: Check the global expected messages table and raise an error 1013 * for each message that has not been received. 1014 * 1015 ******************************************************************************/ 1016 1017 void 1018 AslCheckExpectedExceptions ( 1019 void) 1020 { 1021 UINT32 i; 1022 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList; 1023 ASL_LOCATION_NODE *LocationNode; 1024 1025 1026 for (i = 0; i < AslGbl_ExpectedMessagesIndex; ++i) 1027 { 1028 if (!AslGbl_ExpectedMessages[i].MessageReceived) 1029 { 1030 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL, 1031 AslGbl_ExpectedMessages[i].MessageIdStr); 1032 } 1033 } 1034 1035 while (Current) 1036 { 1037 LocationNode = Current->LocationList; 1038 1039 while (LocationNode) 1040 { 1041 if (!LocationNode->MessageReceived) 1042 { 1043 AslCommonError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, 1044 LocationNode->LineNumber, LocationNode->LineNumber, 1045 LocationNode->LogicalByteOffset, LocationNode->Column, 1046 LocationNode->Filename, Current->MessageIdStr); 1047 } 1048 1049 LocationNode = LocationNode->Next; 1050 } 1051 1052 Current = Current->Next; 1053 } 1054 } 1055 1056 1057 /******************************************************************************* 1058 * 1059 * FUNCTION: AslLogExpectedException 1060 * 1061 * PARAMETERS: MessageIdString - ID of excepted exception during compile 1062 * 1063 * RETURN: Status 1064 * 1065 * DESCRIPTION: Enter a message ID into the global expected messages table 1066 * If these messages are not raised during the compilation, throw 1067 * an error. 1068 * 1069 ******************************************************************************/ 1070 1071 ACPI_STATUS 1072 AslLogExpectedException ( 1073 char *MessageIdString) 1074 { 1075 UINT32 MessageId; 1076 1077 1078 /* Convert argument to an integer and validate it */ 1079 1080 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1081 1082 if (MessageId > 6999) 1083 { 1084 printf ("\"%s\" is not a valid warning/remark/error ID\n", 1085 MessageIdString); 1086 return (AE_BAD_PARAMETER); 1087 } 1088 1089 /* Insert value into the global expected message array */ 1090 1091 if (AslGbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES) 1092 { 1093 printf ("Too many messages have been registered as expected (max %d)\n", 1094 ASL_MAX_DISABLED_MESSAGES); 1095 return (AE_LIMIT); 1096 } 1097 1098 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageId = MessageId; 1099 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString; 1100 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageReceived = FALSE; 1101 AslGbl_ExpectedMessagesIndex++; 1102 return (AE_OK); 1103 } 1104 1105 1106 /******************************************************************************* 1107 * 1108 * FUNCTION: AslLogExpectedExceptionByLine 1109 * 1110 * PARAMETERS: MessageIdString - ID of excepted exception during compile 1111 * 1112 * RETURN: Status 1113 * 1114 * DESCRIPTION: Enter a message ID into the global expected messages table 1115 * based on file and line number. If these messages are not raised 1116 * during the compilation, throw an error. 1117 * 1118 ******************************************************************************/ 1119 1120 void 1121 AslLogExpectedExceptionByLine ( 1122 char *MessageIdString) 1123 { 1124 ASL_LOCATION_NODE *NewErrorLocationNode; 1125 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList; 1126 UINT32 MessageId; 1127 1128 1129 NewErrorLocationNode = UtLocalCalloc (sizeof (ASL_LOCATION_NODE)); 1130 1131 NewErrorLocationNode->LineNumber = AslGbl_CurrentLineNumber; 1132 NewErrorLocationNode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename; 1133 NewErrorLocationNode->LogicalByteOffset = AslGbl_CurrentLineOffset; 1134 NewErrorLocationNode->Column = AslGbl_CurrentColumn; 1135 1136 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1137 1138 /* search the existing list for a matching message ID */ 1139 1140 while (Current && Current->MessageId != MessageId ) 1141 { 1142 Current = Current->Next; 1143 } 1144 if (!Current) 1145 { 1146 /* ID was not found, create a new node for this message ID */ 1147 1148 Current = UtLocalCalloc (sizeof (ASL_EXPECTED_MSG_NODE)); 1149 1150 Current->Next = AslGbl_ExpectedErrorCodeList; 1151 Current->MessageIdStr = MessageIdString; 1152 Current->MessageId = MessageId; 1153 AslGbl_ExpectedErrorCodeList = Current; 1154 } 1155 1156 NewErrorLocationNode->Next = Current->LocationList; 1157 Current->LocationList = NewErrorLocationNode; 1158 } 1159 1160 1161 /******************************************************************************* 1162 * 1163 * FUNCTION: AslDisableException 1164 * 1165 * PARAMETERS: MessageIdString - ID to be disabled 1166 * 1167 * RETURN: Status 1168 * 1169 * DESCRIPTION: Enter a message ID into the global disabled messages table 1170 * 1171 ******************************************************************************/ 1172 1173 ACPI_STATUS 1174 AslDisableException ( 1175 char *MessageIdString) 1176 { 1177 UINT32 MessageId; 1178 1179 1180 /* Convert argument to an integer and validate it */ 1181 1182 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1183 1184 if ((MessageId < 2000) || (MessageId > 6999)) 1185 { 1186 printf ("\"%s\" is not a valid warning/remark/error ID\n", 1187 MessageIdString); 1188 return (AE_BAD_PARAMETER); 1189 } 1190 1191 /* Insert value into the global disabled message array */ 1192 1193 if (AslGbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES) 1194 { 1195 printf ("Too many messages have been disabled (max %d)\n", 1196 ASL_MAX_DISABLED_MESSAGES); 1197 return (AE_LIMIT); 1198 } 1199 1200 AslGbl_DisabledMessages[AslGbl_DisabledMessagesIndex] = MessageId; 1201 AslGbl_DisabledMessagesIndex++; 1202 return (AE_OK); 1203 } 1204 1205 1206 /******************************************************************************* 1207 * 1208 * FUNCTION: AslElevateException 1209 * 1210 * PARAMETERS: MessageIdString - ID of excepted exception during compile 1211 * 1212 * RETURN: Status 1213 * 1214 * DESCRIPTION: Enter a message ID into the global elevated exceptions table. 1215 * These messages will be considered as compilation errors. 1216 * 1217 ******************************************************************************/ 1218 1219 ACPI_STATUS 1220 AslElevateException ( 1221 char *MessageIdString) 1222 { 1223 UINT32 MessageId; 1224 1225 1226 /* Convert argument to an integer and validate it */ 1227 1228 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0); 1229 1230 if (MessageId > 6999) 1231 { 1232 printf ("\"%s\" is not a valid warning/remark/error ID\n", 1233 MessageIdString); 1234 return (AE_BAD_PARAMETER); 1235 } 1236 1237 /* Insert value into the global expected message array */ 1238 1239 if (AslGbl_ElevatedMessagesIndex >= ASL_MAX_ELEVATED_MESSAGES) 1240 { 1241 printf ("Too many messages have been registered as elevated (max %d)\n", 1242 ASL_MAX_DISABLED_MESSAGES); 1243 return (AE_LIMIT); 1244 } 1245 1246 AslGbl_ElevatedMessages[AslGbl_ElevatedMessagesIndex] = MessageId; 1247 AslGbl_ElevatedMessagesIndex++; 1248 return (AE_OK); 1249 } 1250 1251 1252 /******************************************************************************* 1253 * 1254 * FUNCTION: AslIsExceptionDisabled 1255 * 1256 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1257 * MessageId - Index into global message buffer 1258 * 1259 * RETURN: TRUE if exception/message should be ignored 1260 * 1261 * DESCRIPTION: Check if the user has specified options such that this 1262 * exception should be ignored 1263 * 1264 ******************************************************************************/ 1265 1266 static BOOLEAN 1267 AslIsExceptionExpected ( 1268 char *Filename, 1269 UINT32 LineNumber, 1270 UINT8 Level, 1271 UINT16 MessageId) 1272 { 1273 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList; 1274 ASL_LOCATION_NODE *CurrentErrorLocation; 1275 UINT32 EncodedMessageId; 1276 UINT32 i; 1277 1278 1279 /* Mark this exception as received */ 1280 1281 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1282 for (i = 0; i < AslGbl_ExpectedMessagesIndex; i++) 1283 { 1284 /* Simple implementation via fixed array */ 1285 1286 if (EncodedMessageId == AslGbl_ExpectedMessages[i].MessageId) 1287 { 1288 return (AslGbl_ExpectedMessages[i].MessageReceived = TRUE); 1289 } 1290 } 1291 1292 while (Current && Current->MessageId != EncodedMessageId) 1293 { 1294 Current = Current->Next; 1295 } 1296 if (!Current) 1297 { 1298 return (FALSE); 1299 } 1300 1301 CurrentErrorLocation = Current->LocationList; 1302 1303 while (CurrentErrorLocation) 1304 { 1305 if (!strcmp (CurrentErrorLocation->Filename, Filename) && 1306 CurrentErrorLocation->LineNumber == LineNumber) 1307 { 1308 return (CurrentErrorLocation->MessageReceived = TRUE); 1309 } 1310 1311 CurrentErrorLocation = CurrentErrorLocation->Next; 1312 } 1313 1314 return (FALSE); 1315 } 1316 1317 1318 /******************************************************************************* 1319 * 1320 * FUNCTION: AslIsExceptionDisabled 1321 * 1322 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1323 * MessageId - Index into global message buffer 1324 * 1325 * RETURN: TRUE if exception/message should be ignored 1326 * 1327 * DESCRIPTION: Check if the user has specified options such that this 1328 * exception should be ignored 1329 * 1330 ******************************************************************************/ 1331 1332 static BOOLEAN 1333 AslIsExceptionDisabled ( 1334 UINT8 Level, 1335 UINT16 MessageId) 1336 { 1337 UINT32 EncodedMessageId; 1338 UINT32 i; 1339 1340 1341 switch (Level) 1342 { 1343 case ASL_WARNING2: 1344 case ASL_WARNING3: 1345 1346 /* Check for global disable via -w1/-w2/-w3 options */ 1347 1348 if (Level > AslGbl_WarningLevel) 1349 { 1350 return (TRUE); 1351 } 1352 ACPI_FALLTHROUGH; 1353 1354 case ASL_WARNING: 1355 case ASL_REMARK: 1356 case ASL_ERROR: 1357 /* 1358 * Ignore this error/warning/remark if it has been disabled by 1359 * the user (-vw option) 1360 */ 1361 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); 1362 for (i = 0; i < AslGbl_DisabledMessagesIndex; i++) 1363 { 1364 /* Simple implementation via fixed array */ 1365 1366 if (EncodedMessageId == AslGbl_DisabledMessages[i]) 1367 { 1368 return (TRUE); 1369 } 1370 } 1371 break; 1372 1373 default: 1374 break; 1375 } 1376 1377 return (FALSE); 1378 } 1379 1380 1381 /******************************************************************************* 1382 * 1383 * FUNCTION: AslDualParseOpError 1384 * 1385 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1386 * MainMsgId - Index into global message buffer 1387 * MainOp - Parse node where error happened 1388 * MainMsg - Message pertaining to the MainOp 1389 * SubMsgId - Index into global message buffer 1390 * SubOp - Additional parse node for better message 1391 * SubMsg - Message pertaining to SubOp 1392 * 1393 * 1394 * RETURN: None 1395 * 1396 * DESCRIPTION: Main error reporting routine for the ASL compiler for error 1397 * messages that point to multiple parse objects. 1398 * 1399 ******************************************************************************/ 1400 1401 void 1402 AslDualParseOpError ( 1403 UINT8 Level, 1404 UINT16 MainMsgId, 1405 ACPI_PARSE_OBJECT *MainOp, 1406 char *MainMsg, 1407 UINT16 SubMsgId, 1408 ACPI_PARSE_OBJECT *SubOp, 1409 char *SubMsg) 1410 { 1411 ASL_ERROR_MSG *SubEnode = NULL; 1412 1413 1414 /* Check if user wants to ignore this exception */ 1415 1416 if (!MainOp || AslIsExceptionIgnored (MainOp->Asl.Filename, 1417 MainOp->Asl.LogicalLineNumber, Level, MainMsgId)) 1418 { 1419 return; 1420 } 1421 1422 if (SubOp) 1423 { 1424 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber, 1425 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset, 1426 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg, 1427 NULL, NULL); 1428 } 1429 1430 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber, 1431 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset, 1432 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg, 1433 NULL, SubEnode); 1434 } 1435 1436 1437 /******************************************************************************* 1438 * 1439 * FUNCTION: AslError 1440 * 1441 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 1442 * MessageId - Index into global message buffer 1443 * Op - Parse node where error happened 1444 * ExtraMessage - Additional error message 1445 * 1446 * RETURN: None 1447 * 1448 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code 1449 * except the parser.) 1450 * 1451 ******************************************************************************/ 1452 1453 void 1454 AslError ( 1455 UINT8 Level, 1456 UINT16 MessageId, 1457 ACPI_PARSE_OBJECT *Op, 1458 char *ExtraMessage) 1459 { 1460 if (Op) 1461 { 1462 AslCommonError (Level, MessageId, Op->Asl.LineNumber, 1463 Op->Asl.LogicalLineNumber, 1464 Op->Asl.LogicalByteOffset, 1465 Op->Asl.Column, 1466 Op->Asl.Filename, ExtraMessage); 1467 } 1468 else 1469 { 1470 AslCommonError (Level, MessageId, 0, 1471 0, 0, 0, NULL, ExtraMessage); 1472 } 1473 } 1474 1475 1476 /******************************************************************************* 1477 * 1478 * FUNCTION: AslCoreSubsystemError 1479 * 1480 * PARAMETERS: Op - Parse node where error happened 1481 * Status - The ACPICA Exception 1482 * ExtraMessage - Additional error message 1483 * Abort - TRUE -> Abort compilation 1484 * 1485 * RETURN: None 1486 * 1487 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA 1488 * core subsystem. 1489 * 1490 ******************************************************************************/ 1491 1492 void 1493 AslCoreSubsystemError ( 1494 ACPI_PARSE_OBJECT *Op, 1495 ACPI_STATUS Status, 1496 char *ExtraMessage, 1497 BOOLEAN Abort) 1498 { 1499 1500 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage); 1501 1502 if (Op) 1503 { 1504 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1505 Op->Asl.LineNumber, 1506 Op->Asl.LogicalLineNumber, 1507 Op->Asl.LogicalByteOffset, 1508 Op->Asl.Column, 1509 Op->Asl.Filename, AslGbl_MsgBuffer); 1510 } 1511 else 1512 { 1513 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 1514 0, 0, 0, 0, NULL, AslGbl_MsgBuffer); 1515 } 1516 1517 if (Abort) 1518 { 1519 AslAbort (); 1520 } 1521 } 1522 1523 1524 /******************************************************************************* 1525 * 1526 * FUNCTION: AslCompilererror 1527 * 1528 * PARAMETERS: CompilerMessage - Error message from the parser 1529 * 1530 * RETURN: Status (0 for now) 1531 * 1532 * DESCRIPTION: Report an error situation discovered in a production 1533 * NOTE: don't change the name of this function, it is called 1534 * from the auto-generated parser. 1535 * 1536 ******************************************************************************/ 1537 1538 int 1539 AslCompilererror ( 1540 const char *CompilerMessage) 1541 { 1542 1543 AslGbl_SyntaxError++; 1544 1545 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber, 1546 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset, 1547 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, 1548 ACPI_CAST_PTR (char, CompilerMessage)); 1549 1550 return (0); 1551 } 1552