xref: /freebsd/sys/contrib/edk2/Include/Library/DebugLib.h (revision 580fcf642ea2d5a1e60f24947d1c2e97007e44e9)
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