• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef HIPERF_PERF_FILE_FORMAT_H
16 #define HIPERF_PERF_FILE_FORMAT_H
17 
18 #include <string>
19 
20 #include "perf_event_record.h"
21 
22 namespace OHOS {
23 namespace Developtools {
24 namespace HiPerf {
25 enum class FEATURE {
26     RESERVED = 0, /* always cleared */
27     FIRST_FEATURE = 1,
28     TRACING_DATA = 1,
29     BUILD_ID, // build_id_event
30 
31     HOSTNAME,  // A perf_header_string with the hostname where the data was collected (uname -n)
32     OSRELEASE, // A perf_header_string with the os release where the data was collected (uname -r)
33     VERSION,   // A perf_header_string with the perf user tool version where the data was collected.
34                // This is the same as the version of the source tree the perf tool was built from.
35     ARCH,      // A perf_header_string with the CPU architecture (uname -m)
36     NRCPUS,    // A structure defining the number of CPUs.
37     CPUDESC,   // A perf_header_string with description of the CPU. On x86 this is the model name
38                // in /proc/cpuinfo
39     CPUID,     // A perf_header_string with the exact CPU type. On x86 this is
40                // vendor,family,model,stepping. For example: GenuineIntel,6,69,1
41     TOTAL_MEM, // An uint64_t with the total memory in kilobytes.
42     CMDLINE,   // A perf_header_string_list with the perf arg-vector used to collect the data.
43     EVENT_DESC,    // Another description of the perf_event_attrs
44     CPU_TOPOLOGY,  //
45     NUMA_TOPOLOGY, // A list of NUMA node descriptions
46     BRANCH_STACK,  // Not implemented in perf.
47     PMU_MAPPINGS,  // A list of PMU structures, defining the different PMUs supported by perf.
48     GROUP_DESC,    // Description of counter groups ({...} in perf syntax)
49     AUXTRACE,      // Define additional auxtrace areas in the perf.data. auxtrace is used to store
50                    // undecoded hardware tracing information, such as Intel Processor Trace data.
51     STAT,
52     CACHE,
53     SAMPLE_TIME,
54     MEM_TOPOLOGY,
55     LAST_FEATURE,
56 
57     HIPERF_FIRST_FEATURE = 192,
58     HIPERF_FILES_SYMBOL = HIPERF_FIRST_FEATURE,
59     HIPERF_WORKLOAD_CMD,
60     HIPERF_RECORD_TIME,
61     HIPERF_CPU_OFF,
62     HIPERF_HM_DEVHOST,
63     // HIPERF_LAST_FEATURE = HIPERF_HM_DEVHOST,
64     HIPERF_FILES_UNISTACK_TABLE,
65     HIPERF_LAST_FEATURE = HIPERF_FILES_UNISTACK_TABLE,
66     FEATURE_MAX_BITS = 256,
67 };
68 
69 const static std::vector<FEATURE> FeatureStrings = {
70     FEATURE::HOSTNAME,
71     FEATURE::OSRELEASE,
72     FEATURE::VERSION,
73     FEATURE::ARCH,
74     FEATURE::CPUDESC,
75     FEATURE::CPUID,
76     FEATURE::CMDLINE,
77 
78     FEATURE::HIPERF_WORKLOAD_CMD,
79     FEATURE::HIPERF_RECORD_TIME,
80     FEATURE::HIPERF_HM_DEVHOST,
81 };
82 
83 struct perf_file_section {
84     uint64_t offset;
85     uint64_t size;
86 };
87 
88 struct perf_file_attr {
89     perf_event_attr attr;
90     perf_file_section ids;
91 };
92 
93 struct perf_header_string {
94     uint32_t len;
95     char string[0]; /* zero terminated */
96 };
97 
98 constexpr char PERF_MAGIC[] = "PERFILE2";
99 constexpr int BITS_IN_BYTE = 8;
100 constexpr int NUM_FEATURES_FILE_HEADER = 256;
101 
102 struct perf_file_header {
103     char magic[8] = {'P', 'E', 'R', 'F', 'I', 'L', 'E', '2'};
104     uint64_t size = sizeof(perf_file_header);
105     uint64_t attrSize = sizeof(perf_file_attr);
106     perf_file_section attrs;
107     perf_file_section data;
108     perf_file_section eventTypes;
109     uint8_t features[NUM_FEATURES_FILE_HEADER / BITS_IN_BYTE] = {0};
110 };
111 
112 static const std::vector<std::string> extFeatureNames = {
113     "hiperf_files_symbol",
114     "hiperf_workloader_cmd",
115     "hiperf_record_time",
116     "hiperf_cpu_off",
117     "hiperf_hm_devhost",
118     "hiperf_stack_table",
119 };
120 static const std::vector<std::string> featureNames = {
121     "unknown_feature", "tracing_data", "build_id",     "hostname",     "osrelease",
122     "version",         "arch",         "nrcpus",       "cpudesc",      "cpuid",
123     "total_mem",       "cmdline",      "event_desc",   "cpu_topology", "numa_topology",
124     "branch_stack",    "pmu_mappings", "group_desc",   "auxtrace",     "stat",
125     "cache",           "sample_time",  "mem_topology", "last_feature",
126 };
127 
128 class PerfFileSection {
129 public:
130     struct perf_file_section header;
131     const FEATURE featureId_;
132 
133     virtual bool GetBinary(char *buf, size_t size) = 0;
134     virtual size_t GetSize() = 0;
~PerfFileSection()135     virtual ~PerfFileSection() {}
PerfFileSection(const FEATURE featureId)136     explicit PerfFileSection(const FEATURE featureId) : featureId_(featureId)
137     {
138         header.size = 0;
139         header.offset = 0;
140     }
141     static std::string GetFeatureName(FEATURE featureId);
142 
143 protected:
144     const char *rBuffer_ = nullptr;
145     char *wBuffer_ = nullptr;
146     size_t maxSize_ = 0;
147     size_t offset_ = 0;
148 
149     // for read
150     void Init(const char *buffer, size_t maxSize);
151     // for write
152     void Init(char *buffer, size_t maxSize);
153     bool Write(uint32_t u32);
154     bool Write(uint64_t u64);
155     bool Write(const std::string &str);
156 
157     bool Write(const char *buf, size_t size);
158     bool Write(const char *buf, size_t size, size_t max);
159 
160     bool Read(uint32_t &value);
161     bool Read(uint64_t &value);
162     bool Read(std::string &value);
163     bool Read(char *buf, size_t size);
164     void Skip(size_t size);
165 
166     uint32_t SizeOf(std::string &string);
167 };
168 
169 class PerfFileSectionString : public PerfFileSection {
170     std::string stdString_;
171 
172 public:
173     // convert buff to PerfFileSectionString, used to read file
174     // if the data in buf is incorrect, ......
175     PerfFileSectionString(FEATURE id, const char *buf, size_t size);
176     PerfFileSectionString(FEATURE id, const std::string &charString);
177 
178     bool GetBinary(char *buf, size_t size);
179     size_t GetSize();
180     const std::string toString() const;
181 };
182 
183 // ref struct
184 struct SymbolStruct {
185     uint64_t vaddr_ = 0;
186     uint32_t len_ = 0;
187     std::string symbolName_ = EMPTY_STRING;
SymbolStructSymbolStruct188     SymbolStruct() {}
SymbolStructSymbolStruct189     SymbolStruct(uint64_t vaddr, uint32_t len, const std::string &symbolName)
190         : vaddr_(vaddr), len_(len), symbolName_(symbolName)
191     {
192     }
193 };
194 
195 struct SymbolFileStruct {
196     std::string filePath_ = EMPTY_STRING;
197     uint32_t symbolType_;
198     uint64_t textExecVaddr_;
199     uint64_t textExecVaddrFileOffset_;
200     std::string buildId_;
201     std::vector<SymbolStruct> symbolStructs_;
202 };
203 
204 class PerfFileSectionSymbolsFiles : public PerfFileSection {
205 public:
206     std::vector<SymbolFileStruct> symbolFileStructs_;
207 
208     size_t GetSize();
PerfFileSectionSymbolsFiles(FEATURE id,const std::vector<SymbolFileStruct> & symbolFileStructs)209     PerfFileSectionSymbolsFiles(FEATURE id, const std::vector<SymbolFileStruct> &symbolFileStructs)
210         : PerfFileSection(id), symbolFileStructs_(symbolFileStructs)
211     {
212     }
213     // if the data in buf is incorrect, ......
214     PerfFileSectionSymbolsFiles(FEATURE id, const char *buf, size_t size);
215 
216     bool GetBinary(char *buf, size_t size);
217     void ReadSymbolFileStructs();
218 private:
219 #ifdef FUZZER_TEST
220     // issue from fuzz test and also will lead to PerfFileSectionSymbolsFiles uncompletely construct
221     const size_t MAX_SYMBOLS_FILE_NUMBER = 300;
222     const size_t MAX_SYMBOLS_NUMBER = 10000;
223 #endif
224 };
225 
226 // NRCPUS: A structure defining the number of CPUs.
227 class PerfFileSectionNrCpus : public PerfFileSection {
228     uint32_t nrCpusAvailable_; /* CPUs not yet onlined */
229     uint32_t nrCpusOnline_;
230 
231 public:
232     PerfFileSectionNrCpus(FEATURE id, const char *buf, size_t size);
233     PerfFileSectionNrCpus(FEATURE id, uint32_t nrCpusAvailable, uint32_t nrCpusOnline);
234 
235     bool GetBinary(char *buf, size_t size);
236     size_t GetSize();
237     void GetValue(uint32_t &nrCpusAvailable, uint32_t &nrCpusOnline) const;
238 };
239 
240 class PerfFileSectionU64 : public PerfFileSection {
241     uint64_t value_;
242 
243 public:
244     PerfFileSectionU64(FEATURE id, const char *buf, size_t size);
245     PerfFileSectionU64(FEATURE id, uint64_t v);
246 
247     bool GetBinary(char *buf, size_t size);
248     size_t GetSize();
249     void GetValue(uint64_t &v) const;
250 };
251 
252 class PerfFileSectionUniStackTable : public PerfFileSection {
253 public:
254     std::vector<UniStackTableInfo> uniStackTableInfos_;
PerfFileSectionUniStackTable(FEATURE id,const ProcessStackMap * table)255     PerfFileSectionUniStackTable(FEATURE id,
256         const ProcessStackMap *table)
257         : PerfFileSection(id), processStackTable_(table) {}
258     PerfFileSectionUniStackTable(FEATURE id, const char *buf, size_t size);
259 private:
260     const ProcessStackMap *processStackTable_;
261     size_t GetSize();
262     bool GetBinary(char *buf, size_t size);
263 };
264 
265 struct AttrWithId;
266 class PerfFileSectionEventDesc : public PerfFileSection {
267 public:
268     std::vector<AttrWithId> eventDesces_;
269 
270     PerfFileSectionEventDesc(FEATURE id, const char *buf, size_t size);
271     PerfFileSectionEventDesc(FEATURE id, const std::vector<AttrWithId> &eventDesces);
272 
273     bool GetBinary(char *buf, size_t size);
274     size_t GetSize();
275     void GetValue(std::vector<AttrWithId> &eventDesces) const;
276 };
277 } // namespace HiPerf
278 } // namespace Developtools
279 } // namespace OHOS
280 #endif // HIPERF_PERF_FILE_FORMAT_H
281