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