diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c index c6929695a1..869e700b9b 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c @@ -64,10 +64,17 @@ STATIC CONST ACPI_PARSER Dbg2Parser[] = { (VOID**)&NumberDbgDeviceInfo, NULL, NULL} }; +/// An ACPI_PARSER array describing the debug device information structure +/// header. +STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser[] = { + {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, (VOID**)&DbgDevInfoLen, NULL, NULL} +}; + /// An ACPI_PARSER array describing the debug device information. STATIC CONST ACPI_PARSER DbgDevInfoParser[] = { {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL}, - {L"Length", 2, 1, L"%d", NULL, (VOID**)&DbgDevInfoLen, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL}, {L"Generic Address Registers Count", 1, 3, L"0x%x", NULL, (VOID**)&GasCount, NULL, NULL}, @@ -93,76 +100,91 @@ STATIC CONST ACPI_PARSER DbgDevInfoParser[] = { /** This function parses the debug device information structure. - @param [in] Ptr Pointer to the start of the buffer. - @param [out] Length Pointer in which the length of the debug - device information is returned. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the debug device information structure. **/ STATIC VOID EFIAPI DumpDbgDeviceInfo ( - IN UINT8* Ptr, - OUT UINT32* Length + IN UINT8* Ptr, + IN UINT16 Length ) { UINT16 Index; - UINT8* DataPtr; - UINT32* AddrSize; - - // Parse the debug device info to get the Length - ParseAcpi ( - FALSE, - 0, - "Debug Device Info", - Ptr, - 3, // Length is 2 bytes starting at offset 1 - PARSER_PARAMS (DbgDevInfoParser) - ); + UINT16 Offset; ParseAcpi ( TRUE, 2, "Debug Device Info", Ptr, - *DbgDevInfoLen, + Length, PARSER_PARAMS (DbgDevInfoParser) ); - // GAS and Address Size + // GAS Index = 0; - DataPtr = Ptr + (*BaseAddrRegOffset); - AddrSize = (UINT32*)(Ptr + (*AddrSizeOffset)); - while (Index < (*GasCount)) { + Offset = *BaseAddrRegOffset; + while ((Index++ < *GasCount) && + (Offset < Length)) { PrintFieldName (4, L"BaseAddressRegister"); - DumpGasStruct (DataPtr, 4, GAS_LENGTH); + Offset += (UINT16)DumpGasStruct ( + Ptr + Offset, + 4, + Length - Offset + ); + } + + // Make sure the array of address sizes corresponding to each GAS fit in the + // Debug Device Information structure + if ((*AddrSizeOffset + (*GasCount * sizeof (UINT32))) > Length) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \ + L"Parsing of the Debug Device Information structure aborted.\n", + *GasCount, + Length - *AddrSizeOffset + ); + return; + } + + // Address Size + Index = 0; + Offset = *AddrSizeOffset; + while ((Index++ < *GasCount) && + (Offset < Length)) { PrintFieldName (4, L"Address Size"); - Print (L"0x%x\n", AddrSize[Index]); - DataPtr += GAS_LENGTH; - Index++; + Print (L"0x%x\n", *((UINT32*)(Ptr + Offset))); + Offset += sizeof (UINT32); } // NameSpace String Index = 0; - DataPtr = Ptr + (*NameSpaceStringOffset); + Offset = *NameSpaceStringOffset; PrintFieldName (4, L"NameSpace String"); - while (Index < (*NameSpaceStringLength)) { - Print (L"%c", DataPtr[Index++]); + while ((Index++ < *NameSpaceStringLength) && + (Offset < Length)) { + Print (L"%c", *(Ptr + Offset)); + Offset++; } Print (L"\n"); // OEM Data - Index = 0; - DataPtr = Ptr + (*OEMDataOffset); - PrintFieldName (4, L"OEM Data"); - while (Index < (*OEMDataLength)) { - Print (L"%x ", DataPtr[Index++]); - if ((Index & 7) == 0) { - Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L""); + if (*OEMDataOffset != 0) { + Index = 0; + Offset = *OEMDataOffset; + PrintFieldName (4, L"OEM Data"); + while ((Index++ < *OEMDataLength) && + (Offset < Length)) { + Print (L"%x ", *(Ptr + Offset)); + if ((Index & 7) == 0) { + Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L""); + } + Offset++; } + Print (L"\n"); } - Print (L"\n"); - - *Length = *DbgDevInfoLen; } /** @@ -187,8 +209,7 @@ ParseAcpiDbg2 ( ) { UINT32 Offset; - UINT32 DbgDeviceInfoLength; - UINT8* DevInfoPtr; + UINT32 Index; if (!Trace) { return; @@ -202,14 +223,36 @@ ParseAcpiDbg2 ( AcpiTableLength, PARSER_PARAMS (Dbg2Parser) ); - DevInfoPtr = Ptr + Offset; - while (Offset < AcpiTableLength) { - DumpDbgDeviceInfo ( - DevInfoPtr, - &DbgDeviceInfoLength + Offset = *OffsetDbgDeviceInfo; + Index = 0; + + while (Index++ < *NumberDbgDeviceInfo) { + + // Parse the Debug Device Information Structure header to obtain Length + ParseAcpi ( + FALSE, + 0, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (DbgDevInfoHeaderParser) ); - Offset += DbgDeviceInfoLength; - DevInfoPtr += DbgDeviceInfoLength; + + // Make sure the Debug Device Information structure lies inside the table. + if ((Offset + *DbgDevInfoLen) > AcpiTableLength) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Debug Device Information structure length. " \ + L"DbgDevInfoLen = %d. RemainingTableBufferLength = %d. " \ + L"DBG2 parsing aborted.\n", + *DbgDevInfoLen, + AcpiTableLength - Offset + ); + return; + } + + DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen)); + Offset += (*DbgDevInfoLen); } }