xref: /aosp_15_r20/external/armnn/profiling/common/src/SwTrace.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
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 
13 namespace arm
14 {
15 
16 namespace 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.
CalculateSizeOfPaddedSwString(const std::string & str)22 uint32_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
ReadSwTraceMessage(const unsigned char * packetBuffer,unsigned int & offset,const unsigned int & packetLength)32 SwTraceMessage 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
129