• 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 class PerfFileSection {
113 public:
114     struct perf_file_section header;
115     const FEATURE featureId_;
116 
117     virtual bool GetBinary(char *buf, size_t size) = 0;
118     virtual size_t GetSize() = 0;
~PerfFileSection()119     virtual ~PerfFileSection() {}
PerfFileSection(const FEATURE featureId)120     explicit PerfFileSection(const FEATURE featureId) : featureId_(featureId)
121     {
122         header.size = 0;
123         header.offset = 0;
124     }
125     static std::string GetFeatureName(FEATURE featureId);
126 
127 protected:
128     const char *rBuffer_ = nullptr;
129     char *wBuffer_ = nullptr;
130     size_t maxSize_ = 0;
131     size_t offset_ = 0;
132 
133     // for read
134     void Init(const char *buffer, size_t maxSize);
135     // for write
136     void Init(char *buffer, size_t maxSize);
137     bool Write(uint32_t u32);
138     bool Write(uint64_t u64);
139     bool Write(const std::string &str);
140 
141     bool Write(const char *buf, size_t size);
142     bool Write(const char *buf, size_t size, size_t max);
143 
144     bool Read(uint32_t &value);
145     bool Read(uint64_t &value);
146     bool Read(std::string &value);
147     bool Read(char *buf, size_t size);
148     void Skip(size_t size);
149 
150     uint32_t SizeOf(std::string &string);
151 };
152 
153 class PerfFileSectionString : public PerfFileSection {
154     std::string stdString_;
155 
156 public:
157     // convert buff to PerfFileSectionString, used to read file
158     // if the data in buf is incorrect, ......
159     PerfFileSectionString(FEATURE id, const char *buf, size_t size);
160     PerfFileSectionString(FEATURE id, const std::string &charString);
161 
162     bool GetBinary(char *buf, size_t size);
163     size_t GetSize();
164     const std::string ToString() const;
165 };
166 
167 // ref struct
168 struct SymbolStruct {
169     uint64_t vaddr_ = 0;
170     uint32_t len_ = 0;
171     std::string symbolName_ = EMPTY_STRING;
SymbolStructSymbolStruct172     SymbolStruct() {}
SymbolStructSymbolStruct173     SymbolStruct(uint64_t vaddr, uint32_t len, const std::string &symbolName)
174         : vaddr_(vaddr), len_(len), symbolName_(symbolName)
175     {
176     }
177 };
178 
179 struct SymbolFileStruct {
180     std::string filePath_ = EMPTY_STRING;
181     uint32_t symbolType_;
182     uint64_t textExecVaddr_;
183     uint64_t textExecVaddrFileOffset_;
184     std::string buildId_;
185     std::vector<SymbolStruct> symbolStructs_;
186 };
187 
188 class PerfFileSectionSymbolsFiles : public PerfFileSection {
189 public:
190     std::vector<SymbolFileStruct> symbolFileStructs_;
191 
192     size_t GetSize();
PerfFileSectionSymbolsFiles(FEATURE id,const std::vector<SymbolFileStruct> & symbolFileStructs)193     PerfFileSectionSymbolsFiles(FEATURE id, const std::vector<SymbolFileStruct> &symbolFileStructs)
194         : PerfFileSection(id), symbolFileStructs_(symbolFileStructs)
195     {
196     }
197     // if the data in buf is incorrect, ......
198     PerfFileSectionSymbolsFiles(FEATURE id, const char *buf, size_t size);
199 
200     bool GetBinary(char *buf, size_t size);
201     void ReadSymbolFileStructs();
202 private:
203 };
204 
205 // NRCPUS: A structure defining the number of CPUs.
206 class PerfFileSectionNrCpus : public PerfFileSection {
207     uint32_t nrCpusAvailable_; /* CPUs not yet onlined */
208     uint32_t nrCpusOnline_;
209 
210 public:
211     PerfFileSectionNrCpus(FEATURE id, const char *buf, size_t size);
212     PerfFileSectionNrCpus(FEATURE id, uint32_t nrCpusAvailable, uint32_t nrCpusOnline);
213 
214     bool GetBinary(char *buf, size_t size);
215     size_t GetSize();
216     void GetValue(uint32_t &nrCpusAvailable, uint32_t &nrCpusOnline) const;
217 };
218 
219 class PerfFileSectionU64 : public PerfFileSection {
220     uint64_t value_;
221 
222 public:
223     PerfFileSectionU64(FEATURE id, const char *buf, size_t size);
224     PerfFileSectionU64(FEATURE id, uint64_t v);
225 
226     bool GetBinary(char *buf, size_t size);
227     size_t GetSize();
228     void GetValue(uint64_t &v) const;
229 };
230 
231 class PerfFileSectionUniStackTable : public PerfFileSection {
232 public:
233     std::vector<UniStackTableInfo> uniStackTableInfos_;
PerfFileSectionUniStackTable(FEATURE id,const ProcessStackMap * table)234     PerfFileSectionUniStackTable(FEATURE id,
235         const ProcessStackMap *table)
236         : PerfFileSection(id), processStackTable_(table) {}
237     PerfFileSectionUniStackTable(FEATURE id, const char *buf, size_t size);
238 private:
239     const ProcessStackMap *processStackTable_;
240     size_t GetSize();
241     bool GetBinary(char *buf, size_t size);
242 };
243 
244 struct AttrWithId;
245 class PerfFileSectionEventDesc : public PerfFileSection {
246 public:
247     std::vector<AttrWithId> eventDesces_;
248 
249     PerfFileSectionEventDesc(FEATURE id, const char *buf, size_t size);
250     PerfFileSectionEventDesc(FEATURE id, const std::vector<AttrWithId> &eventDesces);
251 
252     bool GetBinary(char *buf, size_t size);
253     size_t GetSize();
254     void GetValue(std::vector<AttrWithId> &eventDesces) const;
255 };
256 } // namespace HiPerf
257 } // namespace Developtools
258 } // namespace OHOS
259 #endif // HIPERF_PERF_FILE_FORMAT_H
260