1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
|