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