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