xref: /aosp_15_r20/external/armnn/profiling/common/include/SwTrace.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include "NumericCast.hpp"
9 
10 #include <algorithm>
11 #include <cstring>
12 #include <string>
13 #include <vector>
14 
15 namespace arm
16 {
17 
18 namespace pipe
19 {
20 
21 struct SwTraceHeader
22 {
23     uint8_t m_StreamVersion;
24     uint8_t m_PointerBytes;
25     uint8_t m_ThreadIdBytes;
26 };
27 
28 struct SwTraceMessage
29 {
30     uint32_t m_Id;
31     std::string m_Name;
32     std::string m_UiName;
33     std::vector<char> m_ArgTypes;
34     std::vector<std::string> m_ArgNames;
35 };
36 
37 struct SwTraceCharPolicy
38 {
IsValidChararm::pipe::SwTraceCharPolicy39     static bool IsValidChar(unsigned char c)
40     {
41         // Check that the given character has ASCII 7-bit encoding
42         return c < 128;
43     }
44 };
45 
46 struct SwTraceNameCharPolicy
47 {
IsValidChararm::pipe::SwTraceNameCharPolicy48     static bool IsValidChar(unsigned char c)
49     {
50         // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
51         return c < 128 && (std::isalnum(c) || c == '_');
52     }
53 };
54 
55 struct SwTraceTypeCharPolicy
56 {
IsValidChararm::pipe::SwTraceTypeCharPolicy57     static bool IsValidChar(unsigned char c)
58     {
59         // Check that the given character is among the allowed ones
60         switch (c)
61         {
62         case '@':
63         case 't':
64         case 'i':
65         case 'I':
66         case 'l':
67         case 'L':
68         case 'F':
69         case 'p':
70         case 's':
71             return true; // Valid char
72         default:
73             return false; // Invalid char
74         }
75     }
76 };
77 
78 template <typename SwTracePolicy>
IsValidSwTraceString(const std::string & s)79 bool IsValidSwTraceString(const std::string& s)
80 {
81     // Check that all the characters in the given string conform to the given policy
82     return std::all_of(s.begin(), s.end(), [](unsigned char c) { return SwTracePolicy::IsValidChar(c); });
83 }
84 
85 template <typename SwTracePolicy>
StringToSwTraceString(const std::string & s,std::vector<uint32_t> & outputBuffer)86 bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
87 {
88     // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
89     // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
90 
91     // Clear the output buffer
92     outputBuffer.clear();
93 
94     // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
95     if (!IsValidSwTraceString<SwTracePolicy>(s))
96     {
97         return false;
98     }
99 
100     // Prepare the output buffer
101     size_t s_size        = s.size() + 1;    // The size of the string (in chars) plus the null-terminator
102     size_t uint32_t_size = sizeof(uint32_t);
103     // Output buffer size = StringLength (32 bit) + amount of complete 32bit words that fit into the string
104     //                      + an additional 32bit word if there are remaining chars to complete the string
105     //                      (The rest of the 32bit word is then filled with the NULL terminator)
106     size_t outBufferSize = 1 + (s_size / uint32_t_size) + (s_size % uint32_t_size != 0 ? 1 : 0);
107     outputBuffer.resize(outBufferSize, '\0');
108 
109     // Write the SWTrace string to the output buffer
110     outputBuffer[0] = numeric_cast<uint32_t>(s_size);
111     std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
112 
113     return true;
114 }
115 
116 template <typename SwTracePolicy,
117           typename SwTraceBuffer = std::vector<uint32_t>>
ConvertDirectoryComponent(const std::string & directoryComponent,SwTraceBuffer & swTraceBuffer)118 bool ConvertDirectoryComponent(const std::string& directoryComponent, SwTraceBuffer& swTraceBuffer)
119 {
120     // Convert the directory component using the given policy
121     SwTraceBuffer tempSwTraceBuffer;
122     bool result = StringToSwTraceString<SwTracePolicy>(directoryComponent, tempSwTraceBuffer);
123     if (!result)
124     {
125         return false;
126     }
127 
128     swTraceBuffer.insert(swTraceBuffer.end(), tempSwTraceBuffer.begin(), tempSwTraceBuffer.end());
129 
130     return true;
131 }
132 
133 uint32_t CalculateSizeOfPaddedSwString(const std::string& str);
134 
135 SwTraceMessage ReadSwTraceMessage(const unsigned char*, unsigned int&, const unsigned int& packetLength);
136 
137 } // namespace pipe
138 
139 } // namespace arm
140