blob: 5860d8cf06655615626519c33151fcf05f474840 [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{
36 ARM_PIPE_ASSERT(packetBuffer);
37
38 unsigned int uint32_t_size = sizeof(uint32_t);
39
40 SwTraceMessage swTraceMessage;
41
42 // Read the decl_id
43 uint32_t readDeclId = ReadUint32(packetBuffer, offset);
44 swTraceMessage.m_Id = readDeclId;
45
46 // SWTrace "namestring" format
47 // length of the string (first 4 bytes) + string + null terminator
48
49 // Check the decl_name
50 offset += uint32_t_size;
51 uint32_t swTraceDeclNameLength = ReadUint32(packetBuffer, offset);
52
53 if (swTraceDeclNameLength == 0 || swTraceDeclNameLength > packetLength)
54 {
55 throw arm::pipe::ProfilingException("Error swTraceDeclNameLength is an invalid size", LOCATION());
56 }
57
58 offset += uint32_t_size;
59 std::vector<unsigned char> swTraceStringBuffer(swTraceDeclNameLength - 1);
60 std::memcpy(swTraceStringBuffer.data(),
61 packetBuffer + offset, swTraceStringBuffer.size());
62
63 swTraceMessage.m_Name.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // name
64
65 // Check the ui_name
66 offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_Name);
67 uint32_t swTraceUINameLength = ReadUint32(packetBuffer, offset);
68
69 if (swTraceUINameLength == 0 || swTraceUINameLength > packetLength)
70 {
71 throw arm::pipe::ProfilingException("Error swTraceUINameLength is an invalid size", LOCATION());
72 }
73
74 offset += uint32_t_size;
75 swTraceStringBuffer.resize(swTraceUINameLength - 1);
76 std::memcpy(swTraceStringBuffer.data(),
77 packetBuffer + offset, swTraceStringBuffer.size());
78
79 swTraceMessage.m_UiName.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // ui_name
80
81 // Check arg_types
82 offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_UiName);
83 uint32_t swTraceArgTypesLength = ReadUint32(packetBuffer, offset);
84
85 if (swTraceArgTypesLength == 0 || swTraceArgTypesLength > packetLength)
86 {
87 throw arm::pipe::ProfilingException("Error swTraceArgTypesLength is an invalid size", LOCATION());
88 }
89
90 offset += uint32_t_size;
91 swTraceStringBuffer.resize(swTraceArgTypesLength - 1);
92 std::memcpy(swTraceStringBuffer.data(),
93 packetBuffer + offset, swTraceStringBuffer.size());
94
95 swTraceMessage.m_ArgTypes.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // arg_types
96
97 std::string swTraceString(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
98
99 // Check arg_names
100 offset += CalculateSizeOfPaddedSwString(swTraceString);
101 uint32_t swTraceArgNamesLength = ReadUint32(packetBuffer, offset);
102
103 if (swTraceArgNamesLength == 0 || swTraceArgNamesLength > packetLength)
104 {
105 throw arm::pipe::ProfilingException("Error swTraceArgNamesLength is an invalid size", LOCATION());
106 }
107
108 offset += uint32_t_size;
109 swTraceStringBuffer.resize(swTraceArgNamesLength - 1);
110 std::memcpy(swTraceStringBuffer.data(),
111 packetBuffer + offset, swTraceStringBuffer.size());
112
113 swTraceString.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
114 std::stringstream stringStream(swTraceString);
115 std::string argName;
116 while (std::getline(stringStream, argName, ','))
117 {
118 swTraceMessage.m_ArgNames.push_back(argName);
119 }
120
121 offset += CalculateSizeOfPaddedSwString(swTraceString);
122
123 return swTraceMessage;
124}
125
126} // namespace pipe
127
128} // namespace arm