148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci#include "perf_file_format.h" 1648f512ceSopenharmony_ci 1748f512ceSopenharmony_ci#include "debug_logger.h" 1848f512ceSopenharmony_ci#include "hiperf_hilog.h" 1948f512ceSopenharmony_ci 2048f512ceSopenharmony_cinamespace OHOS { 2148f512ceSopenharmony_cinamespace Developtools { 2248f512ceSopenharmony_cinamespace HiPerf { 2348f512ceSopenharmony_cistatic const std::vector<std::string> EXT_FEATURE_NAMES = { 2448f512ceSopenharmony_ci "hiperf_files_symbol", 2548f512ceSopenharmony_ci "hiperf_workloader_cmd", 2648f512ceSopenharmony_ci "hiperf_record_time", 2748f512ceSopenharmony_ci "hiperf_cpu_off", 2848f512ceSopenharmony_ci "hiperf_hm_devhost", 2948f512ceSopenharmony_ci "hiperf_stack_table", 3048f512ceSopenharmony_ci}; 3148f512ceSopenharmony_cistatic const std::vector<std::string> FEATURE_NAMES = { 3248f512ceSopenharmony_ci "unknown_feature", "tracing_data", "build_id", "hostname", "osrelease", 3348f512ceSopenharmony_ci "version", "arch", "nrcpus", "cpudesc", "cpuid", 3448f512ceSopenharmony_ci "total_mem", "cmdline", "event_desc", "cpu_topology", "numa_topology", 3548f512ceSopenharmony_ci "branch_stack", "pmu_mappings", "group_desc", "auxtrace", "stat", 3648f512ceSopenharmony_ci "cache", "sample_time", "mem_topology", "last_feature", 3748f512ceSopenharmony_ci}; 3848f512ceSopenharmony_ci#ifdef FUZZER_TEST 3948f512ceSopenharmony_ci // issue from fuzz test and also will lead to PerfFileSectionSymbolsFiles uncompletely construct 4048f512ceSopenharmony_cistatic constexpr size_t MAX_SYMBOLS_FILE_NUMBER = 300; 4148f512ceSopenharmony_cistatic constexpr size_t MAX_SYMBOLS_NUMBER = 10000; 4248f512ceSopenharmony_ci#endif 4348f512ceSopenharmony_cistd::string PerfFileSection::GetFeatureName(FEATURE featureId) 4448f512ceSopenharmony_ci{ 4548f512ceSopenharmony_ci unsigned int index = static_cast<unsigned int>(featureId); 4648f512ceSopenharmony_ci if (featureId >= FEATURE::HIPERF_FIRST_FEATURE) { 4748f512ceSopenharmony_ci index -= static_cast<unsigned int>(FEATURE::HIPERF_FIRST_FEATURE); 4848f512ceSopenharmony_ci if (index >= EXT_FEATURE_NAMES.size()) { 4948f512ceSopenharmony_ci return FEATURE_NAMES[0]; 5048f512ceSopenharmony_ci } 5148f512ceSopenharmony_ci return EXT_FEATURE_NAMES[index]; 5248f512ceSopenharmony_ci } else { 5348f512ceSopenharmony_ci if (index >= FEATURE_NAMES.size()) { 5448f512ceSopenharmony_ci return FEATURE_NAMES[0]; 5548f512ceSopenharmony_ci } 5648f512ceSopenharmony_ci return FEATURE_NAMES[index]; 5748f512ceSopenharmony_ci } 5848f512ceSopenharmony_ci} 5948f512ceSopenharmony_ci 6048f512ceSopenharmony_ci// for read 6148f512ceSopenharmony_civoid PerfFileSection::Init(const char *buffer, size_t maxSize) 6248f512ceSopenharmony_ci{ 6348f512ceSopenharmony_ci rBuffer_ = buffer; 6448f512ceSopenharmony_ci maxSize_ = maxSize; 6548f512ceSopenharmony_ci offset_ = 0; 6648f512ceSopenharmony_ci} 6748f512ceSopenharmony_ci 6848f512ceSopenharmony_ci// for write 6948f512ceSopenharmony_civoid PerfFileSection::Init(char *buffer, size_t maxSize) 7048f512ceSopenharmony_ci{ 7148f512ceSopenharmony_ci wBuffer_ = buffer; 7248f512ceSopenharmony_ci maxSize_ = maxSize; 7348f512ceSopenharmony_ci offset_ = 0; 7448f512ceSopenharmony_ci} 7548f512ceSopenharmony_ci 7648f512ceSopenharmony_cibool PerfFileSection::Write(uint32_t u32) 7748f512ceSopenharmony_ci{ 7848f512ceSopenharmony_ci uint32_t value = u32; 7948f512ceSopenharmony_ci return Write((char *)&value, sizeof(uint32_t)); 8048f512ceSopenharmony_ci} 8148f512ceSopenharmony_ci 8248f512ceSopenharmony_cibool PerfFileSection::Write(uint64_t u64) 8348f512ceSopenharmony_ci{ 8448f512ceSopenharmony_ci uint64_t value = u64; 8548f512ceSopenharmony_ci return Write((char *)&value, sizeof(uint64_t)); 8648f512ceSopenharmony_ci} 8748f512ceSopenharmony_ci 8848f512ceSopenharmony_cibool PerfFileSection::Write(const std::string &str) 8948f512ceSopenharmony_ci{ 9048f512ceSopenharmony_ci if (Write((uint32_t)str.size() + 1)) { // include the ending \0 9148f512ceSopenharmony_ci return Write(str.c_str(), str.size(), str.size() + 1); 9248f512ceSopenharmony_ci } else { 9348f512ceSopenharmony_ci return false; 9448f512ceSopenharmony_ci } 9548f512ceSopenharmony_ci} 9648f512ceSopenharmony_ci 9748f512ceSopenharmony_cibool PerfFileSection::Write(const char *buf, size_t size) 9848f512ceSopenharmony_ci{ 9948f512ceSopenharmony_ci return Write(buf, size, size); 10048f512ceSopenharmony_ci} 10148f512ceSopenharmony_ci 10248f512ceSopenharmony_cibool PerfFileSection::Write(const char *buf, size_t size, size_t max) 10348f512ceSopenharmony_ci{ 10448f512ceSopenharmony_ci CHECK_TRUE(offset_ + size > maxSize_, false, 1, 10548f512ceSopenharmony_ci "write out of size!!! offset_ %zu size %zu max %zu", offset_, size, maxSize_); 10648f512ceSopenharmony_ci CHECK_TRUE(offset_ + max > maxSize_, false, 1, 10748f512ceSopenharmony_ci "write out of size!!! offset_ %zu size %zu max %zu", offset_, size, maxSize_); 10848f512ceSopenharmony_ci CHECK_TRUE(wBuffer_ == nullptr, false, 0, ""); 10948f512ceSopenharmony_ci std::copy(buf, buf + size, wBuffer_ + offset_); 11048f512ceSopenharmony_ci if (size >= max) { 11148f512ceSopenharmony_ci offset_ += size; 11248f512ceSopenharmony_ci } else { 11348f512ceSopenharmony_ci offset_ += max; 11448f512ceSopenharmony_ci } 11548f512ceSopenharmony_ci return true; 11648f512ceSopenharmony_ci} 11748f512ceSopenharmony_ci 11848f512ceSopenharmony_cibool PerfFileSection::Read(uint32_t &value) 11948f512ceSopenharmony_ci{ 12048f512ceSopenharmony_ci static_assert(sizeof(uint32_t) == 4); 12148f512ceSopenharmony_ci return Read((char *)&value, sizeof(uint32_t)); 12248f512ceSopenharmony_ci} 12348f512ceSopenharmony_ci 12448f512ceSopenharmony_cibool PerfFileSection::Read(uint64_t &value) 12548f512ceSopenharmony_ci{ 12648f512ceSopenharmony_ci static_assert(sizeof(uint64_t) == 8); 12748f512ceSopenharmony_ci 12848f512ceSopenharmony_ci return Read((char *)&value, sizeof(uint64_t)); 12948f512ceSopenharmony_ci} 13048f512ceSopenharmony_ci 13148f512ceSopenharmony_cibool PerfFileSection::Read(std::string &value) 13248f512ceSopenharmony_ci{ 13348f512ceSopenharmony_ci uint32_t size = 0; 13448f512ceSopenharmony_ci CHECK_TRUE(!Read(size), false, 0, ""); 13548f512ceSopenharmony_ci // if size large than buf size or 0 size ? 13648f512ceSopenharmony_ci // don't assert for fuzz test 13748f512ceSopenharmony_ci CHECK_TRUE(size == 0 or size > maxSize_, false, 0, ""); 13848f512ceSopenharmony_ci char buf[size]; 13948f512ceSopenharmony_ci CHECK_TRUE(!Read(buf, size), false, 0, ""); 14048f512ceSopenharmony_ci CHECK_TRUE(buf[size - 1] != 0, false, 0, ""); 14148f512ceSopenharmony_ci value = buf; 14248f512ceSopenharmony_ci HLOGDUMMY("Read String size %u buf : %s", size, value.c_str()); 14348f512ceSopenharmony_ci return true; 14448f512ceSopenharmony_ci} 14548f512ceSopenharmony_civoid PerfFileSection::Skip(size_t size) 14648f512ceSopenharmony_ci{ 14748f512ceSopenharmony_ci offset_ += size; 14848f512ceSopenharmony_ci} 14948f512ceSopenharmony_ci 15048f512ceSopenharmony_cibool PerfFileSection::Read(char *buf, size_t size) 15148f512ceSopenharmony_ci{ 15248f512ceSopenharmony_ci HLOG_ASSERT(buf != nullptr); 15348f512ceSopenharmony_ci if (size == 0) { 15448f512ceSopenharmony_ci HLOGE("read zero size!!! offset_ %zu size %zu max %zu", offset_, size, maxSize_); 15548f512ceSopenharmony_ci return false; 15648f512ceSopenharmony_ci } else if (offset_ + size > maxSize_) { 15748f512ceSopenharmony_ci HLOGE("read out of size!!! offset_ %zu size %zu max %zu", offset_, size, maxSize_); 15848f512ceSopenharmony_ci if (memset_s(buf, size, 0, size) != EOK) { // make sure the content return is 0 when failed 15948f512ceSopenharmony_ci HLOGE("memset_s failed in PerfFileSection::Read"); 16048f512ceSopenharmony_ci return false; 16148f512ceSopenharmony_ci } 16248f512ceSopenharmony_ci return false; 16348f512ceSopenharmony_ci } 16448f512ceSopenharmony_ci HLOGD("PerfFileSection::Read offset_ %zu size %zu maxSize_ %zu", offset_, size, maxSize_); 16548f512ceSopenharmony_ci std::copy((rBuffer_ + offset_), (rBuffer_ + offset_ + size), buf); 16648f512ceSopenharmony_ci offset_ += size; 16748f512ceSopenharmony_ci HLOGDUMMY("after read offset_ %zx size %zu buf %x", offset_, size, buf[0]); 16848f512ceSopenharmony_ci return true; 16948f512ceSopenharmony_ci} 17048f512ceSopenharmony_ci 17148f512ceSopenharmony_ciuint32_t PerfFileSection::SizeOf(std::string &string) 17248f512ceSopenharmony_ci{ 17348f512ceSopenharmony_ci return sizeof(uint32_t) + string.size() + 1; /* '\0' */ 17448f512ceSopenharmony_ci} 17548f512ceSopenharmony_ci 17648f512ceSopenharmony_ciPerfFileSectionString::PerfFileSectionString(FEATURE id, const char *buf, size_t size) 17748f512ceSopenharmony_ci : PerfFileSection(id) 17848f512ceSopenharmony_ci{ 17948f512ceSopenharmony_ci Init(buf, size); 18048f512ceSopenharmony_ci CHECK_TRUE(!Read(stdString_), NO_RETVAL, 0, ""); // or throw ... 18148f512ceSopenharmony_ci} 18248f512ceSopenharmony_ci 18348f512ceSopenharmony_ciPerfFileSectionString::PerfFileSectionString(FEATURE id, const std::string &charString) 18448f512ceSopenharmony_ci : PerfFileSection(id) 18548f512ceSopenharmony_ci{ 18648f512ceSopenharmony_ci stdString_ = charString; 18748f512ceSopenharmony_ci} 18848f512ceSopenharmony_ci 18948f512ceSopenharmony_cibool PerfFileSectionString::GetBinary(char *buf, size_t size) 19048f512ceSopenharmony_ci{ 19148f512ceSopenharmony_ci CHECK_TRUE(size < GetSize(), false, 0, ""); 19248f512ceSopenharmony_ci 19348f512ceSopenharmony_ci Init(buf, size); 19448f512ceSopenharmony_ci Write(stdString_); 19548f512ceSopenharmony_ci return true; 19648f512ceSopenharmony_ci} 19748f512ceSopenharmony_ci 19848f512ceSopenharmony_cisize_t PerfFileSectionString::GetSize() 19948f512ceSopenharmony_ci{ 20048f512ceSopenharmony_ci return SizeOf(stdString_); 20148f512ceSopenharmony_ci} 20248f512ceSopenharmony_ci 20348f512ceSopenharmony_ciconst std::string PerfFileSectionString::ToString() const 20448f512ceSopenharmony_ci{ 20548f512ceSopenharmony_ci return stdString_; 20648f512ceSopenharmony_ci} 20748f512ceSopenharmony_ci 20848f512ceSopenharmony_cisize_t PerfFileSectionSymbolsFiles::GetSize() 20948f512ceSopenharmony_ci{ 21048f512ceSopenharmony_ci size_t size = 0; 21148f512ceSopenharmony_ci 21248f512ceSopenharmony_ci size += sizeof(uint32_t); // how many SymbolFileStruct 21348f512ceSopenharmony_ci for (auto &symbolFileStruct : symbolFileStructs_) { 21448f512ceSopenharmony_ci size += SizeOf(symbolFileStruct.filePath_); 21548f512ceSopenharmony_ci size += sizeof(symbolFileStruct.symbolType_); 21648f512ceSopenharmony_ci size += sizeof(symbolFileStruct.textExecVaddr_); 21748f512ceSopenharmony_ci size += sizeof(symbolFileStruct.textExecVaddrFileOffset_); 21848f512ceSopenharmony_ci size += SizeOf(symbolFileStruct.buildId_); 21948f512ceSopenharmony_ci 22048f512ceSopenharmony_ci size += sizeof(uint32_t); // how many SymbolStruct 22148f512ceSopenharmony_ci for (auto &symbolStruct : symbolFileStruct.symbolStructs_) { 22248f512ceSopenharmony_ci size += sizeof(symbolStruct.vaddr_); 22348f512ceSopenharmony_ci size += sizeof(symbolStruct.len_); 22448f512ceSopenharmony_ci size += SizeOf(symbolStruct.symbolName_); 22548f512ceSopenharmony_ci } 22648f512ceSopenharmony_ci } 22748f512ceSopenharmony_ci return size; 22848f512ceSopenharmony_ci} 22948f512ceSopenharmony_ci 23048f512ceSopenharmony_civoid PerfFileSectionSymbolsFiles::ReadSymbolFileStructs() 23148f512ceSopenharmony_ci{ 23248f512ceSopenharmony_ci uint32_t symbolFileNumber = 0; 23348f512ceSopenharmony_ci if (!Read(symbolFileNumber)) { 23448f512ceSopenharmony_ci HLOGE(" symbolFileNumber read failed"); 23548f512ceSopenharmony_ci return; 23648f512ceSopenharmony_ci#ifdef FUZZER_TEST 23748f512ceSopenharmony_ci } else if (symbolFileNumber > MAX_SYMBOLS_FILE_NUMBER) { 23848f512ceSopenharmony_ci HLOGE(" symbolFileNumber %u too large", symbolFileNumber); 23948f512ceSopenharmony_ci return; 24048f512ceSopenharmony_ci#endif 24148f512ceSopenharmony_ci } else { 24248f512ceSopenharmony_ci HLOGV(" symbolFileNumber %u", symbolFileNumber); 24348f512ceSopenharmony_ci } 24448f512ceSopenharmony_ci 24548f512ceSopenharmony_ci for (uint32_t i = symbolFileNumber; i > 0; i--) { 24648f512ceSopenharmony_ci auto &symbolFileStruct = symbolFileStructs_.emplace_back(); 24748f512ceSopenharmony_ci 24848f512ceSopenharmony_ci Read(symbolFileStruct.filePath_); 24948f512ceSopenharmony_ci HLOGV(" symbolFileStruct.filePath_ %s", symbolFileStruct.filePath_.c_str()); 25048f512ceSopenharmony_ci 25148f512ceSopenharmony_ci Read(symbolFileStruct.symbolType_); 25248f512ceSopenharmony_ci Read(symbolFileStruct.textExecVaddr_); 25348f512ceSopenharmony_ci Read(symbolFileStruct.textExecVaddrFileOffset_); 25448f512ceSopenharmony_ci Read(symbolFileStruct.buildId_); 25548f512ceSopenharmony_ci 25648f512ceSopenharmony_ci uint32_t symbolsNumber = 0; 25748f512ceSopenharmony_ci if (!Read(symbolsNumber)) { 25848f512ceSopenharmony_ci HLOGE(" symbols read failed"); 25948f512ceSopenharmony_ci return; 26048f512ceSopenharmony_ci#ifdef FUZZER_TEST 26148f512ceSopenharmony_ci } else if (symbolsNumber > MAX_SYMBOLS_NUMBER) { 26248f512ceSopenharmony_ci HLOGE(" symbols %u too large", symbolsNumber); 26348f512ceSopenharmony_ci return; 26448f512ceSopenharmony_ci#endif 26548f512ceSopenharmony_ci } else { 26648f512ceSopenharmony_ci HLOGV(" symbols %u", symbolsNumber); 26748f512ceSopenharmony_ci } 26848f512ceSopenharmony_ci for (; symbolsNumber > 0; symbolsNumber--) { 26948f512ceSopenharmony_ci auto &symbolStruct = symbolFileStruct.symbolStructs_.emplace_back(); 27048f512ceSopenharmony_ci Read(symbolStruct.vaddr_); 27148f512ceSopenharmony_ci Read(symbolStruct.len_); 27248f512ceSopenharmony_ci Read(symbolStruct.symbolName_); 27348f512ceSopenharmony_ci } 27448f512ceSopenharmony_ci HLOGV(" %zu SymbolStruct read.", symbolFileStruct.symbolStructs_.size()); 27548f512ceSopenharmony_ci } 27648f512ceSopenharmony_ci} 27748f512ceSopenharmony_ci 27848f512ceSopenharmony_ciPerfFileSectionSymbolsFiles::PerfFileSectionSymbolsFiles(FEATURE id, const char *buf, size_t size) 27948f512ceSopenharmony_ci : PerfFileSection(id) 28048f512ceSopenharmony_ci{ 28148f512ceSopenharmony_ci Init(buf, size); 28248f512ceSopenharmony_ci ReadSymbolFileStructs(); 28348f512ceSopenharmony_ci HLOGV(" %zu SymbolFileStruct read.", symbolFileStructs_.size()); 28448f512ceSopenharmony_ci} 28548f512ceSopenharmony_ci 28648f512ceSopenharmony_cibool PerfFileSectionSymbolsFiles::GetBinary(char *buf, size_t size) 28748f512ceSopenharmony_ci{ 28848f512ceSopenharmony_ci HLOGV("PerfFileSectionSymbolsFiles get buffer size %zu.", size); 28948f512ceSopenharmony_ci HLOG_ASSERT(size >= GetSize()); 29048f512ceSopenharmony_ci 29148f512ceSopenharmony_ci Init(buf, size); 29248f512ceSopenharmony_ci CHECK_TRUE(!Write((uint32_t)symbolFileStructs_.size()), false, 1, 29348f512ceSopenharmony_ci "PerfFileSectionSymbolsFiles write failed with %zu.", symbolFileStructs_.size()); 29448f512ceSopenharmony_ci for (auto &symbolFileStruct : symbolFileStructs_) { 29548f512ceSopenharmony_ci Write(symbolFileStruct.filePath_); 29648f512ceSopenharmony_ci Write(symbolFileStruct.symbolType_); 29748f512ceSopenharmony_ci Write(symbolFileStruct.textExecVaddr_); 29848f512ceSopenharmony_ci Write(symbolFileStruct.textExecVaddrFileOffset_); 29948f512ceSopenharmony_ci Write(symbolFileStruct.buildId_); 30048f512ceSopenharmony_ci 30148f512ceSopenharmony_ci Write((uint32_t)symbolFileStruct.symbolStructs_.size()); 30248f512ceSopenharmony_ci for (auto &symbolStruct : symbolFileStruct.symbolStructs_) { 30348f512ceSopenharmony_ci Write(symbolStruct.vaddr_); 30448f512ceSopenharmony_ci Write(symbolStruct.len_); 30548f512ceSopenharmony_ci Write(symbolStruct.symbolName_); 30648f512ceSopenharmony_ci } 30748f512ceSopenharmony_ci HLOGV(" %zu SymbolStruct writed. for %s at 0x%016" PRIx64 "@0x%08" PRIx64 ": %s", 30848f512ceSopenharmony_ci symbolFileStruct.symbolStructs_.size(), symbolFileStruct.filePath_.c_str(), 30948f512ceSopenharmony_ci symbolFileStruct.textExecVaddr_, symbolFileStruct.textExecVaddrFileOffset_, 31048f512ceSopenharmony_ci symbolFileStruct.buildId_.c_str()); 31148f512ceSopenharmony_ci } 31248f512ceSopenharmony_ci HLOGV("%zu SymbolFileStruct writed.", symbolFileStructs_.size()); 31348f512ceSopenharmony_ci 31448f512ceSopenharmony_ci return true; 31548f512ceSopenharmony_ci} 31648f512ceSopenharmony_ci 31748f512ceSopenharmony_ciPerfFileSectionUniStackTable::PerfFileSectionUniStackTable(FEATURE id, const char *buf, size_t size) 31848f512ceSopenharmony_ci : PerfFileSection(id) 31948f512ceSopenharmony_ci{ 32048f512ceSopenharmony_ci uint32_t processTableCount; 32148f512ceSopenharmony_ci Init(buf, size); 32248f512ceSopenharmony_ci if (!Read(processTableCount)) { 32348f512ceSopenharmony_ci HLOGV("processTableCount read failed\n"); 32448f512ceSopenharmony_ci return; 32548f512ceSopenharmony_ci } else { 32648f512ceSopenharmony_ci HLOGV("processTableCount %" PRIu32 "\n", processTableCount); 32748f512ceSopenharmony_ci } 32848f512ceSopenharmony_ci for (uint32_t i = 0; i < processTableCount; ++i) { 32948f512ceSopenharmony_ci UniStackTableInfo& stackTable = uniStackTableInfos_.emplace_back(); 33048f512ceSopenharmony_ci Read(stackTable.pid); 33148f512ceSopenharmony_ci HLOGV("pid %" PRIu32 " ", stackTable.pid); 33248f512ceSopenharmony_ci Read(stackTable.tableSize); 33348f512ceSopenharmony_ci HLOGV("tableSize %" PRIu32 " ", stackTable.tableSize); 33448f512ceSopenharmony_ci Read(stackTable.numNodes); 33548f512ceSopenharmony_ci HLOGV("numNodes %" PRIu32 " ", stackTable.numNodes); 33648f512ceSopenharmony_ci for (size_t j = 0; j < stackTable.numNodes; j++) { 33748f512ceSopenharmony_ci UniStackNode& node = stackTable.nodes.emplace_back(); 33848f512ceSopenharmony_ci Read(node.index); 33948f512ceSopenharmony_ci Read(node.node.value); 34048f512ceSopenharmony_ci } 34148f512ceSopenharmony_ci } 34248f512ceSopenharmony_ci} 34348f512ceSopenharmony_ci 34448f512ceSopenharmony_cibool PerfFileSectionUniStackTable::GetBinary(char *buf, size_t size) 34548f512ceSopenharmony_ci{ 34648f512ceSopenharmony_ci HLOG_ASSERT(size >= GetSize()); 34748f512ceSopenharmony_ci Init(buf, size); 34848f512ceSopenharmony_ci Write(uint32_t(processStackTable_->size())); 34948f512ceSopenharmony_ci for (auto it = processStackTable_->begin(); it != processStackTable_->end(); ++it) { 35048f512ceSopenharmony_ci const auto &table = it->second; 35148f512ceSopenharmony_ci if (table == nullptr) { 35248f512ceSopenharmony_ci continue; 35348f512ceSopenharmony_ci } 35448f512ceSopenharmony_ci Write(table->GetPid()); 35548f512ceSopenharmony_ci Write(table->GetTabelSize()); 35648f512ceSopenharmony_ci const auto &idxs = table->GetUsedIndexes(); 35748f512ceSopenharmony_ci Write(uint32_t(idxs.size())); 35848f512ceSopenharmony_ci Node *head = table->GetHeadNode(); 35948f512ceSopenharmony_ci Node *node = nullptr; 36048f512ceSopenharmony_ci for (const auto idx : idxs) { 36148f512ceSopenharmony_ci node = head + idx; 36248f512ceSopenharmony_ci if (node == nullptr) { 36348f512ceSopenharmony_ci continue; 36448f512ceSopenharmony_ci } 36548f512ceSopenharmony_ci Write(idx); 36648f512ceSopenharmony_ci Write(node->value); 36748f512ceSopenharmony_ci } 36848f512ceSopenharmony_ci } 36948f512ceSopenharmony_ci return true; 37048f512ceSopenharmony_ci} 37148f512ceSopenharmony_ci 37248f512ceSopenharmony_cisize_t PerfFileSectionUniStackTable::GetSize() 37348f512ceSopenharmony_ci{ 37448f512ceSopenharmony_ci CHECK_TRUE(processStackTable_ == nullptr, 0, 0, ""); 37548f512ceSopenharmony_ci size_t size = 0; 37648f512ceSopenharmony_ci // section header info size 37748f512ceSopenharmony_ci size += sizeof(uint32_t); // how many tables/process 37848f512ceSopenharmony_ci for (auto it = processStackTable_->begin(); it != processStackTable_->end(); ++it) { 37948f512ceSopenharmony_ci size += it->second->GetWriteSize(); 38048f512ceSopenharmony_ci } 38148f512ceSopenharmony_ci return size; 38248f512ceSopenharmony_ci} 38348f512ceSopenharmony_ci 38448f512ceSopenharmony_ciPerfFileSectionNrCpus::PerfFileSectionNrCpus(FEATURE id, const char *buf, size_t size) 38548f512ceSopenharmony_ci : PerfFileSection(id) 38648f512ceSopenharmony_ci{ 38748f512ceSopenharmony_ci Init(buf, size); 38848f512ceSopenharmony_ci CHECK_TRUE(!Read(nrCpusAvailable_) || !Read(nrCpusOnline_), NO_RETVAL, 0, ""); 38948f512ceSopenharmony_ci} 39048f512ceSopenharmony_ci 39148f512ceSopenharmony_ciPerfFileSectionNrCpus::PerfFileSectionNrCpus(FEATURE id, uint32_t nrCpusAvailable, 39248f512ceSopenharmony_ci uint32_t nrCpusOnline) 39348f512ceSopenharmony_ci : PerfFileSection(id), nrCpusAvailable_(nrCpusAvailable), nrCpusOnline_(nrCpusOnline) 39448f512ceSopenharmony_ci{ 39548f512ceSopenharmony_ci} 39648f512ceSopenharmony_ci 39748f512ceSopenharmony_cibool PerfFileSectionNrCpus::GetBinary(char *buf, size_t size) 39848f512ceSopenharmony_ci{ 39948f512ceSopenharmony_ci CHECK_TRUE(size < GetSize(), false, 0, ""); 40048f512ceSopenharmony_ci 40148f512ceSopenharmony_ci Init(buf, size); 40248f512ceSopenharmony_ci Write(nrCpusAvailable_); 40348f512ceSopenharmony_ci Write(nrCpusOnline_); 40448f512ceSopenharmony_ci return true; 40548f512ceSopenharmony_ci} 40648f512ceSopenharmony_ci 40748f512ceSopenharmony_cisize_t PerfFileSectionNrCpus::GetSize() 40848f512ceSopenharmony_ci{ 40948f512ceSopenharmony_ci return (sizeof(nrCpusAvailable_) + sizeof(nrCpusOnline_)); 41048f512ceSopenharmony_ci} 41148f512ceSopenharmony_ci 41248f512ceSopenharmony_civoid PerfFileSectionNrCpus::GetValue(uint32_t &nrCpusAvailable, uint32_t &nrCpusOnline) const 41348f512ceSopenharmony_ci{ 41448f512ceSopenharmony_ci nrCpusAvailable = nrCpusAvailable_; 41548f512ceSopenharmony_ci nrCpusOnline = nrCpusOnline_; 41648f512ceSopenharmony_ci} 41748f512ceSopenharmony_ci 41848f512ceSopenharmony_ciPerfFileSectionU64::PerfFileSectionU64(FEATURE id, const char *buf, size_t size) 41948f512ceSopenharmony_ci : PerfFileSection(id) 42048f512ceSopenharmony_ci{ 42148f512ceSopenharmony_ci Init(buf, size); 42248f512ceSopenharmony_ci CHECK_TRUE(!Read(value_), NO_RETVAL, 0, ""); 42348f512ceSopenharmony_ci} 42448f512ceSopenharmony_ci 42548f512ceSopenharmony_ciPerfFileSectionU64::PerfFileSectionU64(FEATURE id, uint64_t v) : PerfFileSection(id) 42648f512ceSopenharmony_ci{ 42748f512ceSopenharmony_ci value_ = v; 42848f512ceSopenharmony_ci} 42948f512ceSopenharmony_ci 43048f512ceSopenharmony_cibool PerfFileSectionU64::GetBinary(char *buf, size_t size) 43148f512ceSopenharmony_ci{ 43248f512ceSopenharmony_ci CHECK_TRUE(size < GetSize(), false, 0, ""); 43348f512ceSopenharmony_ci 43448f512ceSopenharmony_ci Init(buf, size); 43548f512ceSopenharmony_ci Write(value_); 43648f512ceSopenharmony_ci return true; 43748f512ceSopenharmony_ci} 43848f512ceSopenharmony_ci 43948f512ceSopenharmony_cisize_t PerfFileSectionU64::GetSize() 44048f512ceSopenharmony_ci{ 44148f512ceSopenharmony_ci return sizeof(value_); 44248f512ceSopenharmony_ci} 44348f512ceSopenharmony_ci 44448f512ceSopenharmony_civoid PerfFileSectionU64::GetValue(uint64_t &v) const 44548f512ceSopenharmony_ci{ 44648f512ceSopenharmony_ci v = value_; 44748f512ceSopenharmony_ci} 44848f512ceSopenharmony_ci 44948f512ceSopenharmony_ciPerfFileSectionEventDesc::PerfFileSectionEventDesc(FEATURE id, 45048f512ceSopenharmony_ci const std::vector<AttrWithId> &eventDesces) 45148f512ceSopenharmony_ci : PerfFileSection(id) 45248f512ceSopenharmony_ci{ 45348f512ceSopenharmony_ci eventDesces_ = eventDesces; 45448f512ceSopenharmony_ci} 45548f512ceSopenharmony_ci 45648f512ceSopenharmony_ciPerfFileSectionEventDesc::PerfFileSectionEventDesc(FEATURE id, const char *buf, size_t size) 45748f512ceSopenharmony_ci : PerfFileSection(id) 45848f512ceSopenharmony_ci{ 45948f512ceSopenharmony_ci constexpr uint32_t maxIds = 600; 46048f512ceSopenharmony_ci Init(buf, size); 46148f512ceSopenharmony_ci uint32_t nr = 0; 46248f512ceSopenharmony_ci CHECK_TRUE(!Read(nr), NO_RETVAL, 0, ""); 46348f512ceSopenharmony_ci uint32_t attrSize = 0; 46448f512ceSopenharmony_ci CHECK_TRUE(!Read(attrSize), NO_RETVAL, 0, ""); 46548f512ceSopenharmony_ci if (attrSize != sizeof(perf_event_attr)) { // only for log or debug 46648f512ceSopenharmony_ci HLOGW("perf_event_attr version is different, attrSize %d vs %zu", attrSize, 46748f512ceSopenharmony_ci sizeof(perf_event_attr)); 46848f512ceSopenharmony_ci } 46948f512ceSopenharmony_ci 47048f512ceSopenharmony_ci for (; nr > 0; nr--) { 47148f512ceSopenharmony_ci AttrWithId eventDesc; 47248f512ceSopenharmony_ci // compatible with the different version of 'perf_event_attr' 47348f512ceSopenharmony_ci if (attrSize > sizeof(perf_event_attr)) { 47448f512ceSopenharmony_ci if (!Read(reinterpret_cast<char*>(&(eventDesc.attr)), sizeof(perf_event_attr))) { 47548f512ceSopenharmony_ci return; 47648f512ceSopenharmony_ci } 47748f512ceSopenharmony_ci // skip tail bytes 47848f512ceSopenharmony_ci HLOGW("skip %zu byte for diff attr size", attrSize - sizeof(perf_event_attr)); 47948f512ceSopenharmony_ci Skip(attrSize - sizeof(perf_event_attr)); 48048f512ceSopenharmony_ci } else if (!Read(reinterpret_cast<char*>(&(eventDesc.attr)), attrSize)) { 48148f512ceSopenharmony_ci return; 48248f512ceSopenharmony_ci } 48348f512ceSopenharmony_ci 48448f512ceSopenharmony_ci uint32_t nrIds = 0; 48548f512ceSopenharmony_ci if (!Read(nrIds)) { 48648f512ceSopenharmony_ci return; 48748f512ceSopenharmony_ci } else if (nrIds == 0) { 48848f512ceSopenharmony_ci HLOGW("nrIds is not correct ! %u", nrIds); 48948f512ceSopenharmony_ci return; 49048f512ceSopenharmony_ci } else if (nrIds > maxIds) { 49148f512ceSopenharmony_ci HLOGW("nrIds is too large ! %u", nrIds); 49248f512ceSopenharmony_ci } 49348f512ceSopenharmony_ci CHECK_TRUE(!Read(eventDesc.name), NO_RETVAL, 0, ""); 49448f512ceSopenharmony_ci eventDesc.ids.resize(nrIds, 0); 49548f512ceSopenharmony_ci CHECK_TRUE(!Read(reinterpret_cast<char*>(eventDesc.ids.data()), sizeof(uint64_t) * nrIds), NO_RETVAL, 0, ""); 49648f512ceSopenharmony_ci eventDesces_.emplace_back(std::move(eventDesc)); 49748f512ceSopenharmony_ci } 49848f512ceSopenharmony_ci HLOGV("read complete. %zu events", eventDesces_.size()); 49948f512ceSopenharmony_ci} 50048f512ceSopenharmony_ci 50148f512ceSopenharmony_cibool PerfFileSectionEventDesc::GetBinary(char *buf, size_t size) 50248f512ceSopenharmony_ci{ 50348f512ceSopenharmony_ci CHECK_TRUE(size < GetSize(), false, 0, ""); 50448f512ceSopenharmony_ci Init(buf, size); 50548f512ceSopenharmony_ci 50648f512ceSopenharmony_ci CHECK_TRUE(!Write(static_cast<uint32_t>(eventDesces_.size())), false, 0, ""); 50748f512ceSopenharmony_ci CHECK_TRUE(!Write(static_cast<uint32_t>(sizeof(perf_event_attr))), false, 0, ""); 50848f512ceSopenharmony_ci for (auto &eventDesc : eventDesces_) { 50948f512ceSopenharmony_ci CHECK_TRUE(!Write(reinterpret_cast<char*>(&(eventDesc.attr)), sizeof(perf_event_attr)), false, 0, ""); 51048f512ceSopenharmony_ci CHECK_TRUE(!Write(static_cast<uint32_t>(eventDesc.ids.size())), false, 0, ""); 51148f512ceSopenharmony_ci CHECK_TRUE(!Write(eventDesc.name), false, 0, ""); 51248f512ceSopenharmony_ci // clang-format off 51348f512ceSopenharmony_ci CHECK_TRUE(!Write(reinterpret_cast<char*>(eventDesc.ids.data()), sizeof(uint64_t) * eventDesc.ids.size()), 51448f512ceSopenharmony_ci false, 0, ""); // clang-format on 51548f512ceSopenharmony_ci } 51648f512ceSopenharmony_ci return true; 51748f512ceSopenharmony_ci} 51848f512ceSopenharmony_ci 51948f512ceSopenharmony_cisize_t PerfFileSectionEventDesc::GetSize() 52048f512ceSopenharmony_ci{ 52148f512ceSopenharmony_ci size_t size = sizeof(uint32_t); // nr 52248f512ceSopenharmony_ci size += sizeof(uint32_t); // attr_size 52348f512ceSopenharmony_ci 52448f512ceSopenharmony_ci size += (eventDesces_.size() * sizeof(perf_event_attr)); 52548f512ceSopenharmony_ci size += (eventDesces_.size() * sizeof(uint32_t)); // nr_ids 52648f512ceSopenharmony_ci for (auto &eventDesc : eventDesces_) { 52748f512ceSopenharmony_ci size += SizeOf(eventDesc.name); 52848f512ceSopenharmony_ci size += (sizeof(uint64_t) * eventDesc.ids.size()); 52948f512ceSopenharmony_ci } 53048f512ceSopenharmony_ci return size; 53148f512ceSopenharmony_ci} 53248f512ceSopenharmony_ci 53348f512ceSopenharmony_civoid PerfFileSectionEventDesc::GetValue(std::vector<AttrWithId> &eventDesces) const 53448f512ceSopenharmony_ci{ 53548f512ceSopenharmony_ci eventDesces = eventDesces_; 53648f512ceSopenharmony_ci} 53748f512ceSopenharmony_ci} // namespace HiPerf 53848f512ceSopenharmony_ci} // namespace Developtools 53948f512ceSopenharmony_ci} // namespace OHOS 540