aboutsummaryrefslogtreecommitdiff
path: root/profiling/common/src/SwTrace.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'profiling/common/src/SwTrace.cpp')
-rw-r--r--profiling/common/src/SwTrace.cpp128
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