1 /** @file 2 Provides services to print debug and assert messages to a debug output device. 3 4 The Debug library supports debug print and asserts based on a combination of macros and code. 5 The debug library can be turned on and off so that the debug code does not increase the size of an image. 6 7 Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention 8 of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is 9 defined, then debug and assert related macros wrapped by it are the NULL implementations. 10 11 The implementations of the macros used when MDEPKG_NDEBUG is defined rely on the fact that 12 directly unreachable code is pruned, even with compiler optimization disabled (which has 13 been confirmed by generated code size tests on supported compilers). The advantage of 14 implementations which consume their arguments within directly unreachable code is that 15 compilers understand this, and stop warning about variables which would become unused when 16 MDEPKG_NDEBUG is defined if the macros had completely empty definitions. 17 18 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR> 19 SPDX-License-Identifier: BSD-2-Clause-Patent 20 21 **/ 22 23 #ifndef __DEBUG_LIB_H__ 24 #define __DEBUG_LIB_H__ 25 26 // 27 // Declare bits for PcdDebugPropertyMask 28 // 29 #define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 0x01 30 #define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 0x02 31 #define DEBUG_PROPERTY_DEBUG_CODE_ENABLED 0x04 32 #define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED 0x08 33 #define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10 34 #define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20 35 36 // 37 // Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint() 38 // 39 #define DEBUG_INIT 0x00000001 // Initialization 40 #define DEBUG_WARN 0x00000002 // Warnings 41 #define DEBUG_LOAD 0x00000004 // Load events 42 #define DEBUG_FS 0x00000008 // EFI File system 43 #define DEBUG_POOL 0x00000010 // Alloc & Free (pool) 44 #define DEBUG_PAGE 0x00000020 // Alloc & Free (page) 45 #define DEBUG_INFO 0x00000040 // Informational debug messages 46 #define DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers 47 #define DEBUG_VARIABLE 0x00000100 // Variable 48 #define DEBUG_BM 0x00000400 // Boot Manager 49 #define DEBUG_BLKIO 0x00001000 // BlkIo Driver 50 #define DEBUG_NET 0x00004000 // Network Io Driver 51 #define DEBUG_UNDI 0x00010000 // UNDI Driver 52 #define DEBUG_LOADFILE 0x00020000 // LoadFile 53 #define DEBUG_EVENT 0x00080000 // Event messages 54 #define DEBUG_GCD 0x00100000 // Global Coherency Database changes 55 #define DEBUG_CACHE 0x00200000 // Memory range cachability changes 56 #define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may 57 // significantly impact boot performance 58 #define DEBUG_MANAGEABILITY 0x00800000 // Detailed debug and payload manageability messages 59 // related to modules such as Redfish, IPMI, MCTP etc. 60 #define DEBUG_ERROR 0x80000000 // Error 61 62 // 63 // Aliases of debug message mask bits 64 // 65 #define EFI_D_INIT DEBUG_INIT 66 #define EFI_D_WARN DEBUG_WARN 67 #define EFI_D_LOAD DEBUG_LOAD 68 #define EFI_D_FS DEBUG_FS 69 #define EFI_D_POOL DEBUG_POOL 70 #define EFI_D_PAGE DEBUG_PAGE 71 #define EFI_D_INFO DEBUG_INFO 72 #define EFI_D_DISPATCH DEBUG_DISPATCH 73 #define EFI_D_VARIABLE DEBUG_VARIABLE 74 #define EFI_D_BM DEBUG_BM 75 #define EFI_D_BLKIO DEBUG_BLKIO 76 #define EFI_D_NET DEBUG_NET 77 #define EFI_D_UNDI DEBUG_UNDI 78 #define EFI_D_LOADFILE DEBUG_LOADFILE 79 #define EFI_D_EVENT DEBUG_EVENT 80 #define EFI_D_VERBOSE DEBUG_VERBOSE 81 #define EFI_D_ERROR DEBUG_ERROR 82 83 // 84 // Source file line number. 85 // Default is use the to compiler provided __LINE__ macro value. The __LINE__ 86 // mapping can be overriden by predefining DEBUG_LINE_NUMBER 87 // 88 // Defining DEBUG_LINE_NUMBER to a fixed value is useful when comparing builds 89 // across source code formatting changes that may add/remove lines in a source 90 // file. 91 // 92 #ifdef DEBUG_LINE_NUMBER 93 #else 94 #define DEBUG_LINE_NUMBER __LINE__ 95 #endif 96 97 /** 98 Macro that converts a Boolean expression to a Null-terminated ASCII string. 99 100 The default is to use the C pre-processor stringizing operator '#' to add 101 quotes around the C expression. If DEBUG_EXPRESSION_STRING_VALUE is defined 102 then the C expression is converted to the fixed string value. 103 104 Defining DEBUG_EXPRESSION_STRING_VALUE to a fixed value is useful when 105 comparing builds across source code formatting changes that may make 106 changes to spaces or parenthesis in a Boolean expression. 107 108 @param Expression Boolean expression. 109 110 **/ 111 112 #ifdef DEBUG_EXPRESSION_STRING_VALUE 113 #define DEBUG_EXPRESSION_STRING(Expression) DEBUG_EXPRESSION_STRING_VALUE 114 #else 115 #define DEBUG_EXPRESSION_STRING(Expression) #Expression 116 #endif 117 118 /** 119 Prints a debug message to the debug output device if the specified error level is enabled. 120 121 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 122 GetDebugPrintErrorLevel (), then print the message specified by Format and the 123 associated variable argument list to the debug output device. 124 125 If Format is NULL, then ASSERT(). 126 127 @param ErrorLevel The error level of the debug message. 128 @param Format The format string for the debug message to print. 129 @param ... The variable argument list whose contents are accessed 130 based on the format string specified by Format. 131 132 **/ 133 VOID 134 EFIAPI 135 DebugPrint ( 136 IN UINTN ErrorLevel, 137 IN CONST CHAR8 *Format, 138 ... 139 ); 140 141 /** 142 Prints a debug message to the debug output device if the specified 143 error level is enabled. 144 145 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 146 GetDebugPrintErrorLevel (), then print the message specified by Format and 147 the associated variable argument list to the debug output device. 148 149 If Format is NULL, then ASSERT(). 150 151 @param ErrorLevel The error level of the debug message. 152 @param Format Format string for the debug message to print. 153 @param VaListMarker VA_LIST marker for the variable argument list. 154 155 **/ 156 VOID 157 EFIAPI 158 DebugVPrint ( 159 IN UINTN ErrorLevel, 160 IN CONST CHAR8 *Format, 161 IN VA_LIST VaListMarker 162 ); 163 164 /** 165 Prints a debug message to the debug output device if the specified 166 error level is enabled. 167 This function use BASE_LIST which would provide a more compatible 168 service than VA_LIST. 169 170 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 171 GetDebugPrintErrorLevel (), then print the message specified by Format and 172 the associated variable argument list to the debug output device. 173 174 If Format is NULL, then ASSERT(). 175 176 @param ErrorLevel The error level of the debug message. 177 @param Format Format string for the debug message to print. 178 @param BaseListMarker BASE_LIST marker for the variable argument list. 179 180 **/ 181 VOID 182 EFIAPI 183 DebugBPrint ( 184 IN UINTN ErrorLevel, 185 IN CONST CHAR8 *Format, 186 IN BASE_LIST BaseListMarker 187 ); 188 189 /** 190 Prints an assert message containing a filename, line number, and description. 191 This may be followed by a breakpoint or a dead loop. 192 193 Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n" 194 to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 195 PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 196 DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 197 CpuDeadLoop() is called. If neither of these bits are set, then this function 198 returns immediately after the message is printed to the debug output device. 199 DebugAssert() must actively prevent recursion. If DebugAssert() is called while 200 processing another DebugAssert(), then DebugAssert() must return immediately. 201 202 If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. 203 If Description is NULL, then a <Description> string of "(NULL) Description" is printed. 204 205 @param FileName The pointer to the name of the source file that generated the assert condition. 206 @param LineNumber The line number in the source file that generated the assert condition 207 @param Description The pointer to the description of the assert condition. 208 209 **/ 210 VOID 211 EFIAPI 212 DebugAssert ( 213 IN CONST CHAR8 *FileName, 214 IN UINTN LineNumber, 215 IN CONST CHAR8 *Description 216 ); 217 218 /** 219 Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. 220 221 This function fills Length bytes of Buffer with the value specified by 222 PcdDebugClearMemoryValue, and returns Buffer. 223 224 If Buffer is NULL, then ASSERT(). 225 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 226 227 @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. 228 @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 229 230 @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. 231 232 **/ 233 VOID * 234 EFIAPI 235 DebugClearMemory ( 236 OUT VOID *Buffer, 237 IN UINTN Length 238 ); 239 240 /** 241 Returns TRUE if ASSERT() macros are enabled. 242 243 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 244 PcdDebugProperyMask is set. Otherwise, FALSE is returned. 245 246 @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. 247 @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. 248 249 **/ 250 BOOLEAN 251 EFIAPI 252 DebugAssertEnabled ( 253 VOID 254 ); 255 256 /** 257 Returns TRUE if DEBUG() macros are enabled. 258 259 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 260 PcdDebugProperyMask is set. Otherwise, FALSE is returned. 261 262 @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. 263 @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. 264 265 **/ 266 BOOLEAN 267 EFIAPI 268 DebugPrintEnabled ( 269 VOID 270 ); 271 272 /** 273 Returns TRUE if DEBUG_CODE() macros are enabled. 274 275 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 276 PcdDebugProperyMask is set. Otherwise, FALSE is returned. 277 278 @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. 279 @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. 280 281 **/ 282 BOOLEAN 283 EFIAPI 284 DebugCodeEnabled ( 285 VOID 286 ); 287 288 /** 289 Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. 290 291 This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of 292 PcdDebugProperyMask is set. Otherwise, FALSE is returned. 293 294 @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. 295 @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. 296 297 **/ 298 BOOLEAN 299 EFIAPI 300 DebugClearMemoryEnabled ( 301 VOID 302 ); 303 304 /** 305 Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. 306 307 This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. 308 309 @retval TRUE Current ErrorLevel is supported. 310 @retval FALSE Current ErrorLevel is not supported. 311 312 **/ 313 BOOLEAN 314 EFIAPI 315 DebugPrintLevelEnabled ( 316 IN CONST UINTN ErrorLevel 317 ); 318 319 /** 320 Internal worker macro that calls DebugAssert(). 321 322 This macro calls DebugAssert(), passing in the filename, line number, and an 323 expression that evaluated to FALSE. 324 325 @param Expression Boolean expression that evaluated to FALSE 326 327 **/ 328 #if defined (EDKII_UNIT_TEST_FRAMEWORK_ENABLED) 329 330 /** 331 Unit test library replacement for DebugAssert() in DebugLib. 332 333 If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. 334 If Description is NULL, then a <Description> string of "(NULL) Description" is printed. 335 336 @param FileName The pointer to the name of the source file that generated the assert condition. 337 @param LineNumber The line number in the source file that generated the assert condition 338 @param Description The pointer to the description of the assert condition. 339 340 **/ 341 VOID 342 EFIAPI 343 UnitTestDebugAssert ( 344 IN CONST CHAR8 *FileName, 345 IN UINTN LineNumber, 346 IN CONST CHAR8 *Description 347 ); 348 349 #if defined (_ASSERT) 350 #undef _ASSERT 351 #endif 352 #if defined (__FILE_NAME__) 353 #define _ASSERT(Expression) UnitTestDebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 354 #else 355 #define _ASSERT(Expression) UnitTestDebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 356 #endif 357 #else 358 #if defined (__FILE_NAME__) 359 #define _ASSERT(Expression) DebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 360 #else 361 #define _ASSERT(Expression) DebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 362 #endif 363 #endif 364 365 /** 366 Internal worker macro that calls DebugPrint(). 367 368 This macro calls DebugPrint() passing in the debug error level, a format 369 string, and a variable argument list. 370 __VA_ARGS__ is not supported by EBC compiler, Microsoft Visual Studio .NET 2003 371 and Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830. 372 373 @param Expression Expression containing an error level, a format string, 374 and a variable argument list based on the format string. 375 376 **/ 377 378 #if !defined (MDE_CPU_EBC) && (!defined (_MSC_VER) || _MSC_VER > 1400) 379 #define _DEBUG_PRINT(PrintLevel, ...) \ 380 do { \ 381 if (DebugPrintLevelEnabled (PrintLevel)) { \ 382 DebugPrint (PrintLevel, ##__VA_ARGS__); \ 383 } \ 384 } while (FALSE) 385 #define _DEBUGLIB_DEBUG(Expression) _DEBUG_PRINT Expression 386 #else 387 #define _DEBUGLIB_DEBUG(Expression) DebugPrint Expression 388 #endif 389 390 /** 391 Macro that calls DebugAssert() if an expression evaluates to FALSE. 392 393 If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 394 bit of PcdDebugProperyMask is set, then this macro evaluates the Boolean 395 expression specified by Expression. If Expression evaluates to FALSE, then 396 DebugAssert() is called passing in the source filename, source line number, 397 and Expression. 398 399 @param Expression Boolean expression. 400 401 **/ 402 #if !defined (MDEPKG_NDEBUG) 403 #define ASSERT(Expression) \ 404 do { \ 405 if (DebugAssertEnabled ()) { \ 406 if (!(Expression)) { \ 407 _ASSERT (Expression); \ 408 ANALYZER_UNREACHABLE (); \ 409 } \ 410 } \ 411 } while (FALSE) 412 #else 413 #define ASSERT(Expression) \ 414 do { \ 415 if (FALSE) { \ 416 (VOID) (Expression); \ 417 } \ 418 } while (FALSE) 419 #endif 420 421 /** 422 Macro that calls DebugPrint(). 423 424 If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 425 bit of PcdDebugProperyMask is set, then this macro passes Expression to 426 DebugPrint(). 427 428 @param Expression Expression containing an error level, a format string, 429 and a variable argument list based on the format string. 430 431 432 **/ 433 #if !defined (MDEPKG_NDEBUG) 434 #define DEBUG(Expression) \ 435 do { \ 436 if (DebugPrintEnabled ()) { \ 437 _DEBUGLIB_DEBUG (Expression); \ 438 } \ 439 } while (FALSE) 440 #else 441 #define DEBUG(Expression) \ 442 do { \ 443 if (FALSE) { \ 444 _DEBUGLIB_DEBUG (Expression); \ 445 } \ 446 } while (FALSE) 447 #endif 448 449 /** 450 Macro that calls DebugAssert() if an EFI_STATUS evaluates to an error code. 451 452 If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 453 bit of PcdDebugProperyMask is set, then this macro evaluates the EFI_STATUS 454 value specified by StatusParameter. If StatusParameter is an error code, 455 then DebugAssert() is called passing in the source filename, source line 456 number, and StatusParameter. 457 458 @param StatusParameter EFI_STATUS value to evaluate. 459 460 **/ 461 #if !defined (MDEPKG_NDEBUG) 462 #define ASSERT_EFI_ERROR(StatusParameter) \ 463 do { \ 464 if (DebugAssertEnabled ()) { \ 465 if (EFI_ERROR (StatusParameter)) { \ 466 DEBUG ((DEBUG_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", StatusParameter)); \ 467 _ASSERT (!EFI_ERROR (StatusParameter)); \ 468 } \ 469 } \ 470 } while (FALSE) 471 #else 472 #define ASSERT_EFI_ERROR(StatusParameter) \ 473 do { \ 474 if (FALSE) { \ 475 (VOID) (StatusParameter); \ 476 } \ 477 } while (FALSE) 478 #endif 479 480 /** 481 Macro that calls DebugAssert() if a RETURN_STATUS evaluates to an error code. 482 483 If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 484 bit of PcdDebugProperyMask is set, then this macro evaluates the 485 RETURN_STATUS value specified by StatusParameter. If StatusParameter is an 486 error code, then DebugAssert() is called passing in the source filename, 487 source line number, and StatusParameter. 488 489 @param StatusParameter RETURN_STATUS value to evaluate. 490 491 **/ 492 #if !defined (MDEPKG_NDEBUG) 493 #define ASSERT_RETURN_ERROR(StatusParameter) \ 494 do { \ 495 if (DebugAssertEnabled ()) { \ 496 if (RETURN_ERROR (StatusParameter)) { \ 497 DEBUG ((DEBUG_ERROR, "\nASSERT_RETURN_ERROR (Status = %r)\n", \ 498 StatusParameter)); \ 499 _ASSERT (!RETURN_ERROR (StatusParameter)); \ 500 } \ 501 } \ 502 } while (FALSE) 503 #else 504 #define ASSERT_RETURN_ERROR(StatusParameter) \ 505 do { \ 506 if (FALSE) { \ 507 (VOID) (StatusParameter); \ 508 } \ 509 } while (FALSE) 510 #endif 511 512 /** 513 Macro that calls DebugAssert() if a protocol is already installed in the 514 handle database. 515 516 If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 517 of PcdDebugProperyMask is clear, then return. 518 519 If Handle is NULL, then a check is made to see if the protocol specified by Guid 520 is present on any handle in the handle database. If Handle is not NULL, then 521 a check is made to see if the protocol specified by Guid is present on the 522 handle specified by Handle. If the check finds the protocol, then DebugAssert() 523 is called passing in the source filename, source line number, and Guid. 524 525 If Guid is NULL, then ASSERT(). 526 527 @param Handle The handle to check for the protocol. This is an optional 528 parameter that may be NULL. If it is NULL, then the entire 529 handle database is searched. 530 531 @param Guid The pointer to a protocol GUID. 532 533 **/ 534 #if !defined (MDEPKG_NDEBUG) 535 #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid) \ 536 do { \ 537 if (DebugAssertEnabled ()) { \ 538 VOID *Instance; \ 539 ASSERT (Guid != NULL); \ 540 if (Handle == NULL) { \ 541 if (!EFI_ERROR (gBS->LocateProtocol ((EFI_GUID *)Guid, NULL, &Instance))) { \ 542 _ASSERT (Guid already installed in database); \ 543 } \ 544 } else { \ 545 if (!EFI_ERROR (gBS->HandleProtocol (Handle, (EFI_GUID *)Guid, &Instance))) { \ 546 _ASSERT (Guid already installed on Handle); \ 547 } \ 548 } \ 549 } \ 550 } while (FALSE) 551 #else 552 #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid) 553 #endif 554 555 /** 556 Macro that marks the beginning of debug source code. 557 558 If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 559 then this macro marks the beginning of source code that is included in a module. 560 Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 561 are not included in a module. 562 563 **/ 564 #define DEBUG_CODE_BEGIN() \ 565 do { \ 566 if (DebugCodeEnabled ()) { \ 567 do { } while (FALSE) 568 569 /** 570 The macro that marks the end of debug source code. 571 572 If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 573 then this macro marks the end of source code that is included in a module. 574 Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 575 are not included in a module. 576 577 **/ 578 #define DEBUG_CODE_END() \ 579 } \ 580 } while (FALSE) 581 582 /** 583 The macro that declares a section of debug source code. 584 585 If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 586 then the source code specified by Expression is included in a module. 587 Otherwise, the source specified by Expression is not included in a module. 588 589 **/ 590 #define DEBUG_CODE(Expression) \ 591 DEBUG_CODE_BEGIN (); \ 592 Expression \ 593 DEBUG_CODE_END () 594 595 /** 596 The macro that calls DebugClearMemory() to clear a buffer to a default value. 597 598 If the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set, 599 then this macro calls DebugClearMemory() passing in Address and Length. 600 601 @param Address The pointer to a buffer. 602 @param Length The number of bytes in the buffer to set. 603 604 **/ 605 #define DEBUG_CLEAR_MEMORY(Address, Length) \ 606 do { \ 607 if (DebugClearMemoryEnabled ()) { \ 608 DebugClearMemory (Address, Length); \ 609 } \ 610 } while (FALSE) 611 612 /** 613 Macro that calls DebugAssert() if the containing record does not have a 614 matching signature. If the signatures matches, then a pointer to the data 615 structure that contains a specified field of that data structure is returned. 616 This is a lightweight method hide information by placing a public data 617 structure inside a larger private data structure and using a pointer to the 618 public data structure to retrieve a pointer to the private data structure. 619 620 If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 621 of PcdDebugProperyMask is clear, then this macro computes the offset, in bytes, 622 of the field specified by Field from the beginning of the data structure specified 623 by TYPE. This offset is subtracted from Record, and is used to compute a pointer 624 to a data structure of the type specified by TYPE. The Signature field of the 625 data structure specified by TYPE is compared to TestSignature. If the signatures 626 match, then a pointer to the pointer to a data structure of the type specified by 627 TYPE is returned. If the signatures do not match, then NULL is returned to 628 signify that the passed in data structure is invalid. 629 630 If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 631 of PcdDebugProperyMask is set, then this macro computes the offset, in bytes, 632 of field specified by Field from the beginning of the data structure specified 633 by TYPE. This offset is subtracted from Record, and is used to compute a pointer 634 to a data structure of the type specified by TYPE. The Signature field of the 635 data structure specified by TYPE is compared to TestSignature. If the signatures 636 match, then a pointer to the pointer to a data structure of the type specified by 637 TYPE is returned. If the signatures do not match, then DebugAssert() is called 638 with a description of "CR has a bad signature" and Record is returned. 639 640 If the data type specified by TYPE does not contain the field specified by Field, 641 then the module will not compile. 642 643 If TYPE does not contain a field called Signature, then the module will not 644 compile. 645 646 @param Record The pointer to the field specified by Field within a data 647 structure of type TYPE. 648 649 @param TYPE The name of the data structure type to return This 650 data structure must contain the field specified by Field. 651 652 @param Field The name of the field in the data structure specified 653 by TYPE to which Record points. 654 655 @param TestSignature The 32-bit signature value to match. 656 657 **/ 658 #if !defined (MDEPKG_NDEBUG) 659 #define CR(Record, TYPE, Field, TestSignature) \ 660 (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ 661 (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ 662 (BASE_CR (Record, TYPE, Field)->Signature != TestSignature) ? \ 663 NULL : \ 664 BASE_CR (Record, TYPE, Field) 665 #else 666 #define CR(Record, TYPE, Field, TestSignature) \ 667 (BASE_CR (Record, TYPE, Field)->Signature != TestSignature) ? \ 668 NULL : \ 669 BASE_CR (Record, TYPE, Field) 670 #endif 671 672 #endif 673