// // Copyright © 2020 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include #include 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 swTraceString; StringToSwTraceString(str, swTraceString); unsigned int uint32_t_size = sizeof(uint32_t); uint32_t size = (numeric_cast(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 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