• 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_LAST_FEATURE = HIPERF_CPU_OFF,
63 
64     FEATURE_MAX_BITS = 256,
65 };
66 
67 const static std::vector<FEATURE> FeatureStrings = {
68     FEATURE::HOSTNAME,
69     FEATURE::OSRELEASE,
70     FEATURE::VERSION,
71     FEATURE::ARCH,
72     FEATURE::CPUDESC,
73     FEATURE::CPUID,
74     FEATURE::CMDLINE,
75 
76     FEATURE::HIPERF_WORKLOAD_CMD,
77     FEATURE::HIPERF_RECORD_TIME,
78 };
79 
80 struct perf_file_section {
81     uint64_t offset;
82     uint64_t size;
83 };
84 
85 struct perf_file_attr {
86     perf_event_attr attr;
87     perf_file_section ids;
88 };
89 
90 struct perf_header_string {
91     uint32_t len;
92     char string[0]; /* zero terminated */
93 };
94 
95 constexpr char PERF_MAGIC[] = "PERFILE2";
96 constexpr int BITS_IN_BYTE = 8;
97 constexpr int NUM_FEATURES_FILE_HEADER = 256;
98 
99 struct perf_file_header {
100     char magic[8] = {'P', 'E', 'R', 'F', 'I', 'L', 'E', '2'};
101     uint64_t size = sizeof(perf_file_header);
102     uint64_t attrSize = sizeof(perf_file_attr);
103     perf_file_section attrs;
104     perf_file_section data;
105     perf_file_section eventTypes;
106     uint8_t features[NUM_FEATURES_FILE_HEADER / BITS_IN_BYTE] = {0};
107 };
108 
109 static const std::vector<std::string> extFeatureNames = {
110     "hiperf_files_symbol",
111     "hiperf_workloader_cmd",
112     "hiperf_record_time",
113     "hiperf_cpu_off",
114 };
115 static const std::vector<std::string> featureNames = {
116     "unknown_feature", "tracing_data", "build_id",     "hostname",     "osrelease",
117     "version",         "arch",         "nrcpus",       "cpudesc",      "cpuid",
118     "total_mem",       "cmdline",      "event_desc",   "cpu_topology", "numa_topology",
119     "branch_stack",    "pmu_mappings", "group_desc",   "auxtrace",     "stat",
120     "cache",           "sample_time",  "mem_topology", "last_feature",
121 };
122 
123 class PerfFileSection {
124 public:
125     struct perf_file_section header;
126     const FEATURE featureId_;
127 
128     virtual bool GetBinary(char *buf, size_t size) = 0;
129     virtual size_t GetSize() = 0;
~PerfFileSection()130     virtual ~PerfFileSection() {};
PerfFileSection(const FEATURE featureId)131     explicit PerfFileSection(const FEATURE featureId) : featureId_(featureId)
132     {
133         header.size = 0;
134         header.offset = 0;
135     }
136     static std::string GetFeatureName(FEATURE featureId);
137 
138 protected:
139     const char *rBuffer_ = nullptr;
140     char *wBuffer_ = nullptr;
141     size_t maxSize_ = 0;
142     size_t offset_ = 0;
143 
144     // for read
145     void Init(const char *buffer, size_t maxSize);
146     // for write
147     void Init(char *buffer, size_t maxSize);
148     bool Write(uint32_t u32);
149     bool Write(uint64_t u64);
150     bool Write(const std::string &str);
151 
152     bool Write(const char *buf, size_t size);
153     bool Write(const char *buf, size_t size, size_t max);
154 
155     bool Read(uint32_t &value);
156     bool Read(uint64_t &value);
157     bool Read(std::string &value);
158     bool Read(char *buf, size_t size);
159     void Skip(size_t size);
160 
161     uint32_t SizeOf(std::string &string);
162 };
163 
164 class PerfFileSectionString : public PerfFileSection {
165     std::string stdString_;
166 
167 public:
168     // convert buff to PerfFileSectionString, used to read file
169     // if the data in buf is incorrect, ......
170     PerfFileSectionString(FEATURE id, const char *buf, size_t size);
171     PerfFileSectionString(FEATURE id, const std::string &charString);
172 
173     bool GetBinary(char *buf, size_t size);
174     size_t GetSize();
175     const std::string toString() const;
176 };
177 
178 // ref struct
179 struct SymbolStruct {
180     uint64_t vaddr_ = 0;
181     uint32_t len_ = 0;
182     std::string symbolName_ = EMPTY_STRING;
SymbolStructSymbolStruct183     SymbolStruct() {};
SymbolStructSymbolStruct184     SymbolStruct(uint64_t vaddr, uint32_t len, const std::string &symbolName)
185         : vaddr_(vaddr), len_(len), symbolName_(symbolName)
186     {
187     }
188 };
189 
190 struct SymbolFileStruct {
191     std::string filePath_ = EMPTY_STRING;
192     uint32_t symbolType_;
193     uint64_t textExecVaddr_;
194     uint64_t textExecVaddrFileOffset_;
195     std::string buildId_;
196     std::vector<SymbolStruct> symbolStructs_;
197 };
198 
199 class PerfFileSectionSymbolsFiles : public PerfFileSection {
200 public:
201     std::vector<SymbolFileStruct> symbolFileStructs_;
202 
203     size_t GetSize();
PerfFileSectionSymbolsFiles(FEATURE id,const std::vector<SymbolFileStruct> & symbolFileStructs)204     PerfFileSectionSymbolsFiles(FEATURE id, const std::vector<SymbolFileStruct> &symbolFileStructs)
205         : PerfFileSection(id), symbolFileStructs_(symbolFileStructs)
206     {
207     }
208     // if the data in buf is incorrect, ......
209     PerfFileSectionSymbolsFiles(FEATURE id, const char *buf, size_t size);
210 
211     bool GetBinary(char *buf, size_t size);
212 
213 private:
214     // issue from fuzz test
215     const size_t MAX_SYMBOLS_FILE_NUMBER = 300;
216     const size_t MAX_SYMBOLS_NUMBER = 3000;
217 };
218 
219 // NRCPUS: A structure defining the number of CPUs.
220 class PerfFileSectionNrCpus : public PerfFileSection {
221     uint32_t nrCpusAvailable_; /* CPUs not yet onlined */
222     uint32_t nrCpusOnline_;
223 
224 public:
225     PerfFileSectionNrCpus(FEATURE id, const char *buf, size_t size);
226     PerfFileSectionNrCpus(FEATURE id, uint32_t nrCpusAvailable, uint32_t nrCpusOnline);
227 
228     bool GetBinary(char *buf, size_t size);
229     size_t GetSize();
230     void GetValue(uint32_t &nrCpusAvailable, uint32_t &nrCpusOnline) const;
231 };
232 
233 class PerfFileSectionU64 : public PerfFileSection {
234     uint64_t value_;
235 
236 public:
237     PerfFileSectionU64(FEATURE id, const char *buf, size_t size);
238     PerfFileSectionU64(FEATURE id, uint64_t v);
239 
240     bool GetBinary(char *buf, size_t size);
241     size_t GetSize();
242     void GetValue(uint64_t &v) const;
243 };
244 
245 struct AttrWithId;
246 class PerfFileSectionEventDesc : public PerfFileSection {
247 public:
248     std::vector<AttrWithId> eventDesces_;
249 
250     PerfFileSectionEventDesc(FEATURE id, const char *buf, size_t size);
251     PerfFileSectionEventDesc(FEATURE id, const std::vector<AttrWithId> &eventDesces);
252 
253     bool GetBinary(char *buf, size_t size);
254     size_t GetSize();
255     void GetValue(std::vector<AttrWithId> &eventDesces) const;
256 };
257 } // namespace HiPerf
258 } // namespace Developtools
259 } // namespace OHOS
260 #endif