blob: c25baadfec0119219c8481f722e65599b35cb125 [file] [log] [blame]
//
// 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)
{
if (packetBuffer == nullptr)
{
throw ProfilingException("SwTrace.cpp: Attempting to read a null buffer");
}
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