blob: c25baadfec0119219c8481f722e65599b35cb125 [file] [log] [blame]
Jim Flynnbbfe6032020-07-20 16:57:44 +01001//
2// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include <common/include/CommonProfilingUtils.hpp>
7#include <common/include/NumericCast.hpp>
8#include <common/include/ProfilingException.hpp>
9#include <common/include/SwTrace.hpp>
10
11#include <sstream>
12
13namespace arm
14{
15
16namespace pipe
17{
18
19// Calculate the actual length an SwString will be including the terminating null character
20// padding to bring it to the next uint32_t boundary but minus the leading uint32_t encoding
21// the size to allow the offset to be correctly updated when decoding a binary packet.
22uint32_t CalculateSizeOfPaddedSwString(const std::string& str)
23{
24 std::vector<uint32_t> swTraceString;
25 StringToSwTraceString<SwTraceCharPolicy>(str, swTraceString);
26 unsigned int uint32_t_size = sizeof(uint32_t);
27 uint32_t size = (numeric_cast<uint32_t>(swTraceString.size()) - 1) * uint32_t_size;
28 return size;
29}
30
31// Read TimelineMessageDirectoryPacket from given IPacketBuffer and offset
32SwTraceMessage ReadSwTraceMessage(const unsigned char* packetBuffer,
33 unsigned int& offset,
34 const unsigned int& packetLength)
35{
David Monahan6a1d5062023-08-29 09:10:50 +010036 if (packetBuffer == nullptr)
37 {
38 throw ProfilingException("SwTrace.cpp: Attempting to read a null buffer");
39 }
Jim Flynnbbfe6032020-07-20 16:57:44 +010040
41 unsigned int uint32_t_size = sizeof(uint32_t);
42
43 SwTraceMessage swTraceMessage;
44
45 // Read the decl_id
46 uint32_t readDeclId = ReadUint32(packetBuffer, offset);
47 swTraceMessage.m_Id = readDeclId;
48
49 // SWTrace "namestring" format
50 // length of the string (first 4 bytes) + string + null terminator
51
52 // Check the decl_name
53 offset += uint32_t_size;
54 uint32_t swTraceDeclNameLength = ReadUint32(packetBuffer, offset);
55
56 if (swTraceDeclNameLength == 0 || swTraceDeclNameLength > packetLength)
57 {
58 throw arm::pipe::ProfilingException("Error swTraceDeclNameLength is an invalid size", LOCATION());
59 }
60
61 offset += uint32_t_size;
62 std::vector<unsigned char> swTraceStringBuffer(swTraceDeclNameLength - 1);
63 std::memcpy(swTraceStringBuffer.data(),
64 packetBuffer + offset, swTraceStringBuffer.size());
65
66 swTraceMessage.m_Name.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // name
67
68 // Check the ui_name
69 offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_Name);
70 uint32_t swTraceUINameLength = ReadUint32(packetBuffer, offset);
71
72 if (swTraceUINameLength == 0 || swTraceUINameLength > packetLength)
73 {
74 throw arm::pipe::ProfilingException("Error swTraceUINameLength is an invalid size", LOCATION());
75 }
76
77 offset += uint32_t_size;
78 swTraceStringBuffer.resize(swTraceUINameLength - 1);
79 std::memcpy(swTraceStringBuffer.data(),
80 packetBuffer + offset, swTraceStringBuffer.size());
81
82 swTraceMessage.m_UiName.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // ui_name
83
84 // Check arg_types
85 offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_UiName);
86 uint32_t swTraceArgTypesLength = ReadUint32(packetBuffer, offset);
87
88 if (swTraceArgTypesLength == 0 || swTraceArgTypesLength > packetLength)
89 {
90 throw arm::pipe::ProfilingException("Error swTraceArgTypesLength is an invalid size", LOCATION());
91 }
92
93 offset += uint32_t_size;
94 swTraceStringBuffer.resize(swTraceArgTypesLength - 1);
95 std::memcpy(swTraceStringBuffer.data(),
96 packetBuffer + offset, swTraceStringBuffer.size());
97
98 swTraceMessage.m_ArgTypes.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // arg_types
99
100 std::string swTraceString(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
101
102 // Check arg_names
103 offset += CalculateSizeOfPaddedSwString(swTraceString);
104 uint32_t swTraceArgNamesLength = ReadUint32(packetBuffer, offset);
105
106 if (swTraceArgNamesLength == 0 || swTraceArgNamesLength > packetLength)
107 {
108 throw arm::pipe::ProfilingException("Error swTraceArgNamesLength is an invalid size", LOCATION());
109 }
110
111 offset += uint32_t_size;
112 swTraceStringBuffer.resize(swTraceArgNamesLength - 1);
113 std::memcpy(swTraceStringBuffer.data(),
114 packetBuffer + offset, swTraceStringBuffer.size());
115
116 swTraceString.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
117 std::stringstream stringStream(swTraceString);
118 std::string argName;
119 while (std::getline(stringStream, argName, ','))
120 {
121 swTraceMessage.m_ArgNames.push_back(argName);
122 }
123
124 offset += CalculateSizeOfPaddedSwString(swTraceString);
125
126 return swTraceMessage;
127}
128
129} // namespace pipe
130
131} // namespace arm