diff options
Diffstat (limited to 'profiling/common/src/SwTrace.cpp')
-rw-r--r-- | profiling/common/src/SwTrace.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/profiling/common/src/SwTrace.cpp b/profiling/common/src/SwTrace.cpp new file mode 100644 index 0000000000..5860d8cf06 --- /dev/null +++ b/profiling/common/src/SwTrace.cpp @@ -0,0 +1,128 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include <common/include/CommonProfilingUtils.hpp> +#include <common/include/NumericCast.hpp> +#include <common/include/ProfilingException.hpp> +#include <common/include/SwTrace.hpp> + +#include <sstream> + +namespace arm +{ + +namespace pipe +{ + +// Calculate the actual length an SwString will be including the terminating null character +// padding to bring it to the next uint32_t boundary but minus the leading uint32_t encoding +// the size to allow the offset to be correctly updated when decoding a binary packet. +uint32_t CalculateSizeOfPaddedSwString(const std::string& str) +{ + std::vector<uint32_t> swTraceString; + StringToSwTraceString<SwTraceCharPolicy>(str, swTraceString); + unsigned int uint32_t_size = sizeof(uint32_t); + uint32_t size = (numeric_cast<uint32_t>(swTraceString.size()) - 1) * uint32_t_size; + return size; +} + +// Read TimelineMessageDirectoryPacket from given IPacketBuffer and offset +SwTraceMessage ReadSwTraceMessage(const unsigned char* packetBuffer, + unsigned int& offset, + const unsigned int& packetLength) +{ + ARM_PIPE_ASSERT(packetBuffer); + + unsigned int uint32_t_size = sizeof(uint32_t); + + SwTraceMessage swTraceMessage; + + // Read the decl_id + uint32_t readDeclId = ReadUint32(packetBuffer, offset); + swTraceMessage.m_Id = readDeclId; + + // SWTrace "namestring" format + // length of the string (first 4 bytes) + string + null terminator + + // Check the decl_name + offset += uint32_t_size; + uint32_t swTraceDeclNameLength = ReadUint32(packetBuffer, offset); + + if (swTraceDeclNameLength == 0 || swTraceDeclNameLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceDeclNameLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + std::vector<unsigned char> swTraceStringBuffer(swTraceDeclNameLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_Name.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // name + + // Check the ui_name + offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_Name); + uint32_t swTraceUINameLength = ReadUint32(packetBuffer, offset); + + if (swTraceUINameLength == 0 || swTraceUINameLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceUINameLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceUINameLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_UiName.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // ui_name + + // Check arg_types + offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_UiName); + uint32_t swTraceArgTypesLength = ReadUint32(packetBuffer, offset); + + if (swTraceArgTypesLength == 0 || swTraceArgTypesLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceArgTypesLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceArgTypesLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_ArgTypes.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // arg_types + + std::string swTraceString(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); + + // Check arg_names + offset += CalculateSizeOfPaddedSwString(swTraceString); + uint32_t swTraceArgNamesLength = ReadUint32(packetBuffer, offset); + + if (swTraceArgNamesLength == 0 || swTraceArgNamesLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceArgNamesLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceArgNamesLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceString.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); + std::stringstream stringStream(swTraceString); + std::string argName; + while (std::getline(stringStream, argName, ',')) + { + swTraceMessage.m_ArgNames.push_back(argName); + } + + offset += CalculateSizeOfPaddedSwString(swTraceString); + + return swTraceMessage; +} + +} // namespace pipe + +} // namespace arm |