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