From ca9938b842347769618f84a2d53af63d6edf48e6 Mon Sep 17 00:00:00 2001 From: mdkinney Date: Sat, 30 May 2009 23:53:35 +0000 Subject: [PATCH] This checkin addresses the compatibility issue of passing arguments of type VA_LIST between components. The type VA_LIST is mapped onto the compiler specific implementation of varargs. As a result, modules build with different compilers may not use the same VA_LIST structure. The solution to this issue is to define a new type called BASE_LIST that is a compiler independent method of passing varargs between modules. 1) Update all implementations of ReportStatusCodeExtractDebugInfo() to use an argument of type BASE_LIST instead of VA_LIST. 2) Update the implementation of DebugPrint() in PeiDxeDebugLibReportStatusCode to convert a VA_LIST to a BASE_LIST before passing the data to report status code. 3) Update status code listeners to use the BASE_LIST based APIs in the PrintLib instead of the VA_LIST based APIs, since ReportStatusCodeExtractDebugInfo() was updated to return a parameter of type BASE_LIST. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8406 6f19259b-4bc3-4df7-8a09-765794883524 --- .../ReportStatusCodeLib.c | 4 +- .../PeiDxeDebugLibReportStatusCode/DebugLib.c | 136 ++++++++++++++++-- .../ReportStatusCodeLib.c | 4 +- .../ReportStatusCodeLib.c | 8 +- .../StatusCode/Pei/SerialStatusCodeWorker.c | 4 +- .../RuntimeDxe/DataHubStatusCodeWorker.c | 4 +- .../RuntimeDxe/SerialStatusCodeWorker.c | 4 +- 7 files changed, 139 insertions(+), 25 deletions(-) diff --git a/IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/ReportStatusCodeLib.c b/IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/ReportStatusCodeLib.c index 9e35cdda90..0dd2990e75 100644 --- a/IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/ReportStatusCodeLib.c +++ b/IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/ReportStatusCodeLib.c @@ -248,7 +248,7 @@ EFIAPI ReportStatusCodeExtractDebugInfo ( IN CONST EFI_STATUS_CODE_DATA *Data, OUT UINT32 *ErrorLevel, - OUT VA_LIST *Marker, + OUT BASE_LIST *Marker, OUT CHAR8 **Format ) { @@ -277,7 +277,7 @@ ReportStatusCodeExtractDebugInfo ( // The first 12 * UINTN bytes of the string are really an // argument stack to support varargs on the Format string. // - *Marker = (VA_LIST) (DebugInfo + 1); + *Marker = (BASE_LIST) (DebugInfo + 1); *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); return TRUE; diff --git a/IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/DebugLib.c b/IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/DebugLib.c index 4c62def93a..79a33dc04e 100644 --- a/IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/DebugLib.c +++ b/IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/DebugLib.c @@ -53,9 +53,11 @@ DebugPrint ( UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)]; EFI_DEBUG_INFO *DebugInfo; UINTN TotalSize; - UINTN Index; - VA_LIST Marker; - UINT64 *ArgumentPointer; + VA_LIST VaListMarker; + BASE_LIST BaseListMarker; + CHAR8 *FormatString; + BOOLEAN Long; + BOOLEAN Done; // // If Format is NULL, then ASSERT(). @@ -69,27 +71,140 @@ DebugPrint ( return; } + // + // Compute the total size of the record + // TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrLen (Format) + 1; + + // + // If the TotalSize is larger than the maximum record size, then ASSERT() + // + ASSERT (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE); + + // + // If the TotalSize is larger than the maximum record size, then return + // if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) { return; } // - // Then EFI_DEBUG_INFO + // Fill in EFI_DEBUG_INFO // - DebugInfo = (EFI_DEBUG_INFO *)Buffer; + DebugInfo = (EFI_DEBUG_INFO *)Buffer; DebugInfo->ErrorLevel = (UINT32)ErrorLevel; + BaseListMarker = (BASE_LIST)(DebugInfo + 1); + FormatString = (UINT8 *)((UINT64 *)(DebugInfo + 1) + 12); + + // + // Copy the Format string into the record + // + AsciiStrCpy (FormatString, Format); // // 256 byte mini Var Arg stack. That is followed by the format string. // - VA_START (Marker, Format); - for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) { - WriteUnaligned64(ArgumentPointer, VA_ARG (Marker, UINT64)); + VA_START (VaListMarker, Format); + for (; *Format != '\0'; Format++) { + if (*Format != '%') { + continue; + } + Long = FALSE; + // + // Parse Flags and Width + // + for (Done = FALSE; !Done; ) { + Format++; + switch (*Format) { + case '.': + case '-': + case '+': + case ' ': + case ',': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + case 'L': + case 'l': + Long = TRUE; + break; + case '*': + BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN); + break; + case '\0': + // + // Make no output if Format string terminates unexpectedly when + // looking up for flag, width, precision and type. + // + Format--; + // + // break skipped on purpose. + // + default: + Done = TRUE; + break; + } + } + + // + // Handle each argument type + // + switch (*Format) { + case 'p': + if (sizeof (VOID *) > 4) { + Long = TRUE; + } + case 'X': + case 'x': + case 'd': + if (Long) { + BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64); + } else { + BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int); + } + break; + case 's': + case 'S': + case 'a': + case 'g': + case 't': + BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *); + break; + case 'c': + BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN); + break; + case 'r': + BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS); + break; + } + + // + // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then ASSERT() + // This indicates that the DEBUG() macro is passing in more argument than can be handled by + // the EFI_DEBUG_INFO record + // + ASSERT ((UINT8 *)BaseListMarker <= FormatString); + + // + // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then return + // + if ((UINT8 *)BaseListMarker > FormatString) { + return; + } } - VA_END (Marker); - AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format); + VA_END (VaListMarker); + // + // Send the DebugInfo record + // REPORT_STATUS_CODE_EX ( EFI_DEBUG_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED), @@ -101,7 +216,6 @@ DebugPrint ( ); } - /** Prints an assert message containing a filename, line number, and description. diff --git a/IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c b/IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c index 3099c4785c..9bd3109121 100644 --- a/IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c +++ b/IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c @@ -235,7 +235,7 @@ EFIAPI ReportStatusCodeExtractDebugInfo ( IN CONST EFI_STATUS_CODE_DATA *Data, OUT UINT32 *ErrorLevel, - OUT VA_LIST *Marker, + OUT BASE_LIST *Marker, OUT CHAR8 **Format ) { @@ -264,7 +264,7 @@ ReportStatusCodeExtractDebugInfo ( // The first 12 * UINTN bytes of the string are really an // argument stack to support varargs on the Format string. // - *Marker = (VA_LIST) (DebugInfo + 1); + *Marker = (BASE_LIST) (DebugInfo + 1); *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); return TRUE; diff --git a/IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/ReportStatusCodeLib.c b/IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/ReportStatusCodeLib.c index f377481858..b4d677ef41 100644 --- a/IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/ReportStatusCodeLib.c +++ b/IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/ReportStatusCodeLib.c @@ -244,14 +244,14 @@ EFIAPI ReportStatusCodeExtractDebugInfo ( IN CONST EFI_STATUS_CODE_DATA *Data, OUT UINT32 *ErrorLevel, - OUT VA_LIST *Marker, + OUT BASE_LIST *Marker, OUT CHAR8 **Format ) { EFI_DEBUG_INFO *DebugInfo; - ASSERT (Data != NULL); - ASSERT (ErrorLevel != NULL); + ASSERT (Data != NULL); + ASSERT (ErrorLevel != NULL); ASSERT (Marker != NULL); ASSERT (Format != NULL); @@ -273,7 +273,7 @@ ReportStatusCodeExtractDebugInfo ( // The first 12 * UINTN bytes of the string are really an // argument stack to support varargs on the Format string. // - *Marker = (VA_LIST) (DebugInfo + 1); + *Marker = (BASE_LIST) (DebugInfo + 1); *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); return TRUE; diff --git a/IntelFrameworkModulePkg/Universal/StatusCode/Pei/SerialStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCode/Pei/SerialStatusCodeWorker.c index 1784f4ebc5..00aa41cb21 100644 --- a/IntelFrameworkModulePkg/Universal/StatusCode/Pei/SerialStatusCodeWorker.c +++ b/IntelFrameworkModulePkg/Universal/StatusCode/Pei/SerialStatusCodeWorker.c @@ -51,7 +51,7 @@ SerialStatusCodeReportWorker ( UINT32 ErrorLevel; UINT32 LineNumber; UINTN CharCount; - VA_LIST Marker; + BASE_LIST Marker; Buffer[0] = '\0'; @@ -73,7 +73,7 @@ SerialStatusCodeReportWorker ( // // Print DEBUG() information into output buffer. // - CharCount = AsciiVSPrint ( + CharCount = AsciiBSPrint ( Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, diff --git a/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/DataHubStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/DataHubStatusCodeWorker.c index 743f6185a2..6b765ccf16 100644 --- a/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/DataHubStatusCodeWorker.c +++ b/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/DataHubStatusCodeWorker.c @@ -186,7 +186,7 @@ DataHubStatusCodeReportWorker ( { DATA_HUB_STATUS_CODE_DATA_RECORD *Record; UINT32 ErrorLevel; - VA_LIST Marker; + BASE_LIST Marker; CHAR8 *Format; UINTN CharCount; @@ -226,7 +226,7 @@ DataHubStatusCodeReportWorker ( if (Data != NULL) { if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) { - CharCount = UnicodeVSPrintAsciiFormat ( + CharCount = UnicodeBSPrintAsciiFormat ( (CHAR16 *) (Record + 1), EFI_STATUS_CODE_DATA_MAX_SIZE, Format, diff --git a/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/SerialStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/SerialStatusCodeWorker.c index 710a808ada..cf5d48d665 100644 --- a/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/SerialStatusCodeWorker.c +++ b/IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/SerialStatusCodeWorker.c @@ -76,7 +76,7 @@ SerialStatusCodeReportWorker ( UINT32 ErrorLevel; UINT32 LineNumber; UINTN CharCount; - VA_LIST Marker; + BASE_LIST Marker; if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) { if (EfiAtRuntime ()) { @@ -107,7 +107,7 @@ SerialStatusCodeReportWorker ( // // Print DEBUG() information into output buffer. // - CharCount = AsciiVSPrint ( + CharCount = AsciiBSPrint ( Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, -- 2.39.2