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
1648f512ceSopenharmony_ci#define HILOG_TAG "Symbols"
1748f512ceSopenharmony_ci
1848f512ceSopenharmony_ci#include "symbols_file.h"
1948f512ceSopenharmony_ci
2048f512ceSopenharmony_ci#include <algorithm>
2148f512ceSopenharmony_ci#include <chrono>
2248f512ceSopenharmony_ci#include <cxxabi.h>
2348f512ceSopenharmony_ci#include <cstdlib>
2448f512ceSopenharmony_ci#include <fcntl.h>
2548f512ceSopenharmony_ci#include <fstream>
2648f512ceSopenharmony_ci#include <string_view>
2748f512ceSopenharmony_ci#include <type_traits>
2848f512ceSopenharmony_ci
2948f512ceSopenharmony_ci#if defined(is_mingw) && is_mingw
3048f512ceSopenharmony_ci#include <memoryapi.h>
3148f512ceSopenharmony_ci#else
3248f512ceSopenharmony_ci#include <sys/mman.h>
3348f512ceSopenharmony_ci#include <sys/stat.h>
3448f512ceSopenharmony_ci#endif
3548f512ceSopenharmony_ci#include <unistd.h>
3648f512ceSopenharmony_ci
3748f512ceSopenharmony_ci#include "dfx_ark.h"
3848f512ceSopenharmony_ci#include "dfx_extractor_utils.h"
3948f512ceSopenharmony_ci#include "dfx_symbols.h"
4048f512ceSopenharmony_ci#include "dwarf_encoding.h"
4148f512ceSopenharmony_ci#include "hiperf_hilog.h"
4248f512ceSopenharmony_ci#include "unwinder_config.h"
4348f512ceSopenharmony_ci#include "utilities.h"
4448f512ceSopenharmony_ci
4548f512ceSopenharmony_ciusing namespace OHOS::HiviewDFX;
4648f512ceSopenharmony_ciusing namespace std::chrono;
4748f512ceSopenharmony_ci
4848f512ceSopenharmony_cinamespace OHOS {
4948f512ceSopenharmony_cinamespace Developtools {
5048f512ceSopenharmony_cinamespace HiPerf {
5148f512ceSopenharmony_cibool SymbolsFile::onRecording_ = true;
5248f512ceSopenharmony_cibool SymbolsFile::needParseJsFunc_ = false;
5348f512ceSopenharmony_ci
5448f512ceSopenharmony_ciconst std::string SymbolsFile::GetBuildId() const
5548f512ceSopenharmony_ci{
5648f512ceSopenharmony_ci    return buildId_;
5748f512ceSopenharmony_ci}
5848f512ceSopenharmony_ci
5948f512ceSopenharmony_cibool SymbolsFile::UpdateBuildIdIfMatch(std::string buildId)
6048f512ceSopenharmony_ci{
6148f512ceSopenharmony_ci    /*
6248f512ceSopenharmony_ci        here we have two case
6348f512ceSopenharmony_ci        1 buildId_ is empty
6448f512ceSopenharmony_ci            a) always return match
6548f512ceSopenharmony_ci        2 buildId_ is not empty
6648f512ceSopenharmony_ci            a) really check if the same one
6748f512ceSopenharmony_ci    */
6848f512ceSopenharmony_ci
6948f512ceSopenharmony_ci    if (buildId_.empty()) {
7048f512ceSopenharmony_ci        // we have new empty build
7148f512ceSopenharmony_ci        if (buildId.empty()) {
7248f512ceSopenharmony_ci            // both empty , no build id provided
7348f512ceSopenharmony_ci            HLOGD("build id is empty.");
7448f512ceSopenharmony_ci            return true;
7548f512ceSopenharmony_ci        } else {
7648f512ceSopenharmony_ci            buildId_ = buildId;
7748f512ceSopenharmony_ci            HLOGD("new buildId %s", buildId_.c_str());
7848f512ceSopenharmony_ci            return true;
7948f512ceSopenharmony_ci        }
8048f512ceSopenharmony_ci    } else {
8148f512ceSopenharmony_ci        // we already have a build id
8248f512ceSopenharmony_ci        // so this is not the first time load symbol
8348f512ceSopenharmony_ci        // we need check if it match
8448f512ceSopenharmony_ci        HLOGV("expected buildid: %s vs %s", buildId_.c_str(), buildId.c_str());
8548f512ceSopenharmony_ci
8648f512ceSopenharmony_ci        if (buildId_ != buildId) {
8748f512ceSopenharmony_ci            HLOGW("id not match");
8848f512ceSopenharmony_ci            return false;
8948f512ceSopenharmony_ci        } else {
9048f512ceSopenharmony_ci            HLOGD("id match");
9148f512ceSopenharmony_ci            return true;
9248f512ceSopenharmony_ci        }
9348f512ceSopenharmony_ci    }
9448f512ceSopenharmony_ci}
9548f512ceSopenharmony_ci
9648f512ceSopenharmony_cistd::string SymbolsFile::SearchReadableFile(const std::vector<std::string> &searchPaths,
9748f512ceSopenharmony_ci                                            const std::string &filePath) const
9848f512ceSopenharmony_ci{
9948f512ceSopenharmony_ci    if (filePath.empty()) {
10048f512ceSopenharmony_ci        HLOGW("nothing to found");
10148f512ceSopenharmony_ci        return filePath;
10248f512ceSopenharmony_ci    }
10348f512ceSopenharmony_ci    for (auto searchPath : searchPaths) {
10448f512ceSopenharmony_ci        if (searchPath.back() != PATH_SEPARATOR) {
10548f512ceSopenharmony_ci            searchPath += PATH_SEPARATOR;
10648f512ceSopenharmony_ci        }
10748f512ceSopenharmony_ci        std::string PossibleFilePath = searchPath + filePath;
10848f512ceSopenharmony_ci        if (CheckPathReadable(PossibleFilePath)) {
10948f512ceSopenharmony_ci            return PossibleFilePath;
11048f512ceSopenharmony_ci        }
11148f512ceSopenharmony_ci        HLOGW("have not found '%s' in search paths %s", filePath.c_str(), searchPath.c_str());
11248f512ceSopenharmony_ci    }
11348f512ceSopenharmony_ci    return EMPTY_STRING;
11448f512ceSopenharmony_ci}
11548f512ceSopenharmony_ci
11648f512ceSopenharmony_ciconst std::string SymbolsFile::FindSymbolFile(
11748f512ceSopenharmony_ci    const std::vector<std::string> &symbolsFileSearchPaths, std::string symboleFilePath) const
11848f512ceSopenharmony_ci{
11948f512ceSopenharmony_ci    /*
12048f512ceSopenharmony_ci        this function do 2 things:
12148f512ceSopenharmony_ci        find by name:
12248f512ceSopenharmony_ci            1 find dso path
12348f512ceSopenharmony_ci            2 find search path
12448f512ceSopenharmony_ci                a) search path + dso path
12548f512ceSopenharmony_ci                b) search path + dso name
12648f512ceSopenharmony_ci
12748f512ceSopenharmony_ci        show we should return filePath_ as default ?
12848f512ceSopenharmony_ci    */
12948f512ceSopenharmony_ci    if (symboleFilePath.empty()) {
13048f512ceSopenharmony_ci        symboleFilePath = filePath_;
13148f512ceSopenharmony_ci        HLOGD("use default filename: %s ", symboleFilePath.c_str());
13248f512ceSopenharmony_ci    }
13348f512ceSopenharmony_ci    symboleFilePath = PlatformPathConvert(symboleFilePath);
13448f512ceSopenharmony_ci    std::string foundPath;
13548f512ceSopenharmony_ci    // search first if we have path
13648f512ceSopenharmony_ci    if (symbolsFileSearchPaths.size() != 0) {
13748f512ceSopenharmony_ci        foundPath = SearchReadableFile(symbolsFileSearchPaths, symboleFilePath);
13848f512ceSopenharmony_ci        if (foundPath.empty()) {
13948f512ceSopenharmony_ci            HLOGV("try base name for: %s split with %s", symboleFilePath.c_str(),
14048f512ceSopenharmony_ci                  PATH_SEPARATOR_STR.c_str());
14148f512ceSopenharmony_ci            auto pathSplit = StringSplit(symboleFilePath, PATH_SEPARATOR_STR);
14248f512ceSopenharmony_ci            if (pathSplit.size() > 1) {
14348f512ceSopenharmony_ci                HLOGV("base name is: %s ", pathSplit.back().c_str());
14448f512ceSopenharmony_ci                // found it again with base name , split it and get last name
14548f512ceSopenharmony_ci                foundPath = SearchReadableFile(symbolsFileSearchPaths, pathSplit.back());
14648f512ceSopenharmony_ci            }
14748f512ceSopenharmony_ci        }
14848f512ceSopenharmony_ci    }
14948f512ceSopenharmony_ci
15048f512ceSopenharmony_ci    // only access the patch in onRecording_
15148f512ceSopenharmony_ci    // in report mode we don't load any thing in runtime path
15248f512ceSopenharmony_ci    if (foundPath.empty() and onRecording_) {
15348f512ceSopenharmony_ci        // try access direct at last
15448f512ceSopenharmony_ci        if (CheckPathReadable(symboleFilePath)) {
15548f512ceSopenharmony_ci            // found direct folder
15648f512ceSopenharmony_ci            HLOGD("find %s in current work dir", symboleFilePath.c_str());
15748f512ceSopenharmony_ci            return symboleFilePath;
15848f512ceSopenharmony_ci        }
15948f512ceSopenharmony_ci    }
16048f512ceSopenharmony_ci    return foundPath;
16148f512ceSopenharmony_ci}
16248f512ceSopenharmony_ci
16348f512ceSopenharmony_ciclass ElfFileSymbols : public SymbolsFile {
16448f512ceSopenharmony_cipublic:
16548f512ceSopenharmony_ci    explicit ElfFileSymbols(const std::string &symbolFilePath,
16648f512ceSopenharmony_ci                            const SymbolsFileType symbolsFileType = SYMBOL_ELF_FILE)
16748f512ceSopenharmony_ci        : SymbolsFile(symbolsFileType, symbolFilePath)
16848f512ceSopenharmony_ci    {
16948f512ceSopenharmony_ci    }
17048f512ceSopenharmony_ci
17148f512ceSopenharmony_ci    virtual ~ElfFileSymbols()
17248f512ceSopenharmony_ci    {
17348f512ceSopenharmony_ci    }
17448f512ceSopenharmony_ci
17548f512ceSopenharmony_ci    DfxSymbol GetSymbolWithPcAndMap(uint64_t pc, std::shared_ptr<DfxMap> map) override
17648f512ceSopenharmony_ci    {
17748f512ceSopenharmony_ci        const DfxSymbol symbol;
17848f512ceSopenharmony_ci        return symbol;
17948f512ceSopenharmony_ci    }
18048f512ceSopenharmony_ci
18148f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
18248f512ceSopenharmony_ci    {
18348f512ceSopenharmony_ci        symbolsLoaded_ = true;
18448f512ceSopenharmony_ci        std::string findPath = FindSymbolFile(symbolsFileSearchPaths_, symbolFilePath);
18548f512ceSopenharmony_ci        if (findPath.empty() && elfFile_ == nullptr) { // elf not compressed in hap has been initialized before
18648f512ceSopenharmony_ci            HLOGW("elf found failed (belong to %s)", filePath_.c_str());
18748f512ceSopenharmony_ci            return false;
18848f512ceSopenharmony_ci        }
18948f512ceSopenharmony_ci        if (LoadElfSymbols(map, findPath)) {
19048f512ceSopenharmony_ci            return true;
19148f512ceSopenharmony_ci        } else {
19248f512ceSopenharmony_ci            HLOGW("elf open failed with '%s'", findPath.c_str());
19348f512ceSopenharmony_ci            return false;
19448f512ceSopenharmony_ci        }
19548f512ceSopenharmony_ci        return false;
19648f512ceSopenharmony_ci    }
19748f512ceSopenharmony_ci
19848f512ceSopenharmony_ci    void EnableMiniDebugInfo() override
19948f512ceSopenharmony_ci    {
20048f512ceSopenharmony_ci        UnwinderConfig::SetEnableMiniDebugInfo(true);
20148f512ceSopenharmony_ci    }
20248f512ceSopenharmony_ci
20348f512ceSopenharmony_ci    std::shared_ptr<DfxElf> GetElfFile() override
20448f512ceSopenharmony_ci    {
20548f512ceSopenharmony_ci        return elfFile_;
20648f512ceSopenharmony_ci    }
20748f512ceSopenharmony_ci
20848f512ceSopenharmony_ci    const std::unordered_map<uint64_t, ElfLoadInfo> GetPtLoads() override
20948f512ceSopenharmony_ci    {
21048f512ceSopenharmony_ci        CHECK_TRUE(elfFile_ == nullptr, info_, 0, "");
21148f512ceSopenharmony_ci        return elfFile_->GetPtLoads();
21248f512ceSopenharmony_ci    }
21348f512ceSopenharmony_ci
21448f512ceSopenharmony_ciprotected:
21548f512ceSopenharmony_ci    bool LoadDebugInfo(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
21648f512ceSopenharmony_ci    {
21748f512ceSopenharmony_ci        std::lock_guard<std::mutex> lock(mutex_);
21848f512ceSopenharmony_ci        if (debugInfoLoadResult_) {
21948f512ceSopenharmony_ci            return true; // it must have been loaded
22048f512ceSopenharmony_ci        } else if (debugInfoLoaded_) {
22148f512ceSopenharmony_ci            return debugInfoLoadResult_; // return the result of loaded
22248f512ceSopenharmony_ci        } else {
22348f512ceSopenharmony_ci            debugInfoLoaded_ = true;
22448f512ceSopenharmony_ci        }
22548f512ceSopenharmony_ci        std::string elfPath = FindSymbolFile(symbolsFileSearchPaths_, symbolFilePath);
22648f512ceSopenharmony_ci        if (elfPath.empty()) {
22748f512ceSopenharmony_ci            HLOGW("elf found failed (belong to %s)", filePath_.c_str());
22848f512ceSopenharmony_ci            return false;
22948f512ceSopenharmony_ci        }
23048f512ceSopenharmony_ci
23148f512ceSopenharmony_ci        if (elfFile_ == nullptr) {
23248f512ceSopenharmony_ci            if (StringEndsWith(elfPath, ".hap")) {
23348f512ceSopenharmony_ci                CHECK_TRUE(map == nullptr, false, 1, "map should not be nullptr.");
23448f512ceSopenharmony_ci                elfFile_ = DfxElf::CreateFromHap(elfPath, map->prevMap, map->offset);
23548f512ceSopenharmony_ci                HLOGD("try create elf from hap");
23648f512ceSopenharmony_ci            } else {
23748f512ceSopenharmony_ci                elfFile_ = std::make_shared<DfxElf>(elfPath);
23848f512ceSopenharmony_ci            }
23948f512ceSopenharmony_ci        }
24048f512ceSopenharmony_ci
24148f512ceSopenharmony_ci        CHECK_TRUE(elfFile_ == nullptr, false, 1, "Failed to create elf file for %s.", elfPath.c_str());
24248f512ceSopenharmony_ci
24348f512ceSopenharmony_ci        CHECK_TRUE(!elfFile_->IsValid(), false, 1, "parser elf file failed.");
24448f512ceSopenharmony_ci
24548f512ceSopenharmony_ci        HLOGD("loaded elf %s", elfPath.c_str());
24648f512ceSopenharmony_ci        // update path for so in hap
24748f512ceSopenharmony_ci        if (StringEndsWith(elfPath, ".hap")) {
24848f512ceSopenharmony_ci            filePath_ = elfPath + "!" + elfFile_->GetElfName();
24948f512ceSopenharmony_ci            HLOGD("update path for so in hap %s.", filePath_.c_str());
25048f512ceSopenharmony_ci            if (map == nullptr) {
25148f512ceSopenharmony_ci                HLOGW("map should not be nullptr.");
25248f512ceSopenharmony_ci                return false;
25348f512ceSopenharmony_ci            }
25448f512ceSopenharmony_ci            map->name = filePath_;
25548f512ceSopenharmony_ci            map->elf = elfFile_;
25648f512ceSopenharmony_ci            map->prevMap->name = filePath_;
25748f512ceSopenharmony_ci            map->prevMap->elf = elfFile_;
25848f512ceSopenharmony_ci        }
25948f512ceSopenharmony_ci
26048f512ceSopenharmony_ci        textExecVaddr_ = elfFile_->GetStartVaddr();
26148f512ceSopenharmony_ci        textExecVaddrFileOffset_ = elfFile_->GetStartOffset();
26248f512ceSopenharmony_ci
26348f512ceSopenharmony_ci        HLOGD("textExecVaddr_ 0x%016" PRIx64 " file offset 0x%016" PRIx64 "", textExecVaddr_,
26448f512ceSopenharmony_ci              textExecVaddrFileOffset_);
26548f512ceSopenharmony_ci
26648f512ceSopenharmony_ci#ifndef __arm__
26748f512ceSopenharmony_ci        ShdrInfo shinfo;
26848f512ceSopenharmony_ci        if (elfFile_->GetSectionInfo(shinfo, ".eh_frame_hdr")) {
26948f512ceSopenharmony_ci            auto mmapPtr = elfFile_->GetMmapPtr();
27048f512ceSopenharmony_ci            CHECK_TRUE(mmapPtr == nullptr, false, 1, "mmapPtr should not be nullptr.");
27148f512ceSopenharmony_ci            LoadEhFrameHDR(mmapPtr + shinfo.offset, shinfo.size, shinfo.offset);
27248f512ceSopenharmony_ci        }
27348f512ceSopenharmony_ci#endif
27448f512ceSopenharmony_ci
27548f512ceSopenharmony_ci        HLOGD("LoadDebugInfo success!");
27648f512ceSopenharmony_ci        debugInfoLoadResult_ = true;
27748f512ceSopenharmony_ci        return true;
27848f512ceSopenharmony_ci    }
27948f512ceSopenharmony_ci
28048f512ceSopenharmony_ciprivate:
28148f512ceSopenharmony_ci    bool EhFrameHDRValid_ {false};
28248f512ceSopenharmony_ci    uint64_t ehFrameHDRElfOffset_ {0};
28348f512ceSopenharmony_ci    uint64_t ehFrameHDRFdeCount_ {0};
28448f512ceSopenharmony_ci    uint64_t ehFrameHDRFdeTableItemSize_ {0};
28548f512ceSopenharmony_ci    uint64_t ehFrameHDRFdeTableElfOffset_ {0};
28648f512ceSopenharmony_ci    std::shared_ptr<DfxElf> elfFile_;
28748f512ceSopenharmony_ci    std::unordered_map<uint64_t, ElfLoadInfo> info_;
28848f512ceSopenharmony_ci
28948f512ceSopenharmony_ci    bool GetSectionInfo(const std::string &name, uint64_t &sectionVaddr, uint64_t &sectionSize,
29048f512ceSopenharmony_ci                        uint64_t &sectionFileOffset) const override
29148f512ceSopenharmony_ci    {
29248f512ceSopenharmony_ci        struct ShdrInfo shdrInfo;
29348f512ceSopenharmony_ci        if (elfFile_->GetSectionInfo(shdrInfo, name)) {
29448f512ceSopenharmony_ci            sectionVaddr = shdrInfo.addr;
29548f512ceSopenharmony_ci            sectionSize = shdrInfo.size;
29648f512ceSopenharmony_ci            sectionFileOffset = shdrInfo.offset;
29748f512ceSopenharmony_ci            HLOGM("Get Section '%s' %" PRIx64 " - %" PRIx64 "", name.c_str(), sectionVaddr, sectionSize);
29848f512ceSopenharmony_ci            return true;
29948f512ceSopenharmony_ci        } else {
30048f512ceSopenharmony_ci            HLOGW("Section '%s' not found", name.c_str());
30148f512ceSopenharmony_ci            return false;
30248f512ceSopenharmony_ci        }
30348f512ceSopenharmony_ci    }
30448f512ceSopenharmony_ci
30548f512ceSopenharmony_ci#ifndef __arm__
30648f512ceSopenharmony_ci    bool GetHDRSectionInfo(uint64_t &ehFrameHdrElfOffset, uint64_t &fdeTableElfOffset,
30748f512ceSopenharmony_ci                           uint64_t &fdeTableSize) override
30848f512ceSopenharmony_ci    {
30948f512ceSopenharmony_ci        CHECK_TRUE(elfFile_ == nullptr, false, 0, "");
31048f512ceSopenharmony_ci        ShdrInfo shinfo;
31148f512ceSopenharmony_ci        if (!elfFile_->GetSectionInfo(shinfo, ".eh_frame_hdr")) {
31248f512ceSopenharmony_ci            return false;
31348f512ceSopenharmony_ci        }
31448f512ceSopenharmony_ci
31548f512ceSopenharmony_ci        ehFrameHDRElfOffset_ = shinfo.offset;
31648f512ceSopenharmony_ci        if (EhFrameHDRValid_) {
31748f512ceSopenharmony_ci            ehFrameHdrElfOffset = ehFrameHDRElfOffset_;
31848f512ceSopenharmony_ci            fdeTableElfOffset = ehFrameHDRFdeTableElfOffset_;
31948f512ceSopenharmony_ci            fdeTableSize = ehFrameHDRFdeCount_;
32048f512ceSopenharmony_ci            return true;
32148f512ceSopenharmony_ci        }
32248f512ceSopenharmony_ci        auto mmapPtr = elfFile_->GetMmapPtr();
32348f512ceSopenharmony_ci        if (mmapPtr == nullptr) {
32448f512ceSopenharmony_ci            HLOGE("mmapPtr should not be nullptr.");
32548f512ceSopenharmony_ci            return false;
32648f512ceSopenharmony_ci        }
32748f512ceSopenharmony_ci        if (!LoadEhFrameHDR(mmapPtr + shinfo.offset, elfFile_->GetMmapSize(), shinfo.offset)) {
32848f512ceSopenharmony_ci            HLOGW("Failed to load eh_frame_hdr");
32948f512ceSopenharmony_ci            return false;
33048f512ceSopenharmony_ci        }
33148f512ceSopenharmony_ci
33248f512ceSopenharmony_ci        ehFrameHdrElfOffset = ehFrameHDRElfOffset_;
33348f512ceSopenharmony_ci        fdeTableElfOffset = ehFrameHDRFdeTableElfOffset_;
33448f512ceSopenharmony_ci        fdeTableSize = ehFrameHDRFdeCount_;
33548f512ceSopenharmony_ci        return true;
33648f512ceSopenharmony_ci    }
33748f512ceSopenharmony_ci#endif
33848f512ceSopenharmony_ci
33948f512ceSopenharmony_ci    void DumpEhFrameHDR()
34048f512ceSopenharmony_ci    {
34148f512ceSopenharmony_ci        HLOGD("  ehFrameHDRElfOffset_:          0x%" PRIx64 "", ehFrameHDRElfOffset_);
34248f512ceSopenharmony_ci        HLOGD("  ehFrameHDRFdeCount_:           0x%" PRIx64 "", ehFrameHDRFdeCount_);
34348f512ceSopenharmony_ci        HLOGD("  ehFrameHDRFdeTableElfOffset_:  0x%" PRIx64 "", ehFrameHDRFdeTableElfOffset_);
34448f512ceSopenharmony_ci        HLOGD("  ehFrameHDRFdeTableItemSize_:   0x%" PRIx64 "", ehFrameHDRFdeTableItemSize_);
34548f512ceSopenharmony_ci    }
34648f512ceSopenharmony_ci
34748f512ceSopenharmony_ci    bool LoadEhFrameHDR(const unsigned char *buffer, size_t bufferSize, uint64_t shdrOffset)
34848f512ceSopenharmony_ci    {
34948f512ceSopenharmony_ci        const eh_frame_hdr *ehFrameHdr = reinterpret_cast<const eh_frame_hdr *>(buffer);
35048f512ceSopenharmony_ci        CHECK_TRUE(ehFrameHdr == nullptr, false, 0, "");
35148f512ceSopenharmony_ci        const uint8_t *dataPtr = ehFrameHdr->encode_data;
35248f512ceSopenharmony_ci        DwarfEncoding dwEhFramePtr(ehFrameHdr->eh_frame_ptr_enc, dataPtr);
35348f512ceSopenharmony_ci        DwarfEncoding dwFdeCount(ehFrameHdr->fde_count_enc, dataPtr);
35448f512ceSopenharmony_ci        DwarfEncoding dwTable(ehFrameHdr->table_enc, dataPtr);
35548f512ceSopenharmony_ci        DwarfEncoding dwTableValue(ehFrameHdr->table_enc, dataPtr);
35648f512ceSopenharmony_ci
35748f512ceSopenharmony_ci        HLOGD("eh_frame_hdr:");
35848f512ceSopenharmony_ci        HexDump(ehFrameHdr, BITS_OF_FOUR_BYTE, bufferSize);
35948f512ceSopenharmony_ci        unsigned char version = ehFrameHdr->version;
36048f512ceSopenharmony_ci        HLOGD("  version:             %02x:%s", version, (version == 1) ? "valid" : "invalid");
36148f512ceSopenharmony_ci        HLOGD("  eh_frame_ptr_enc:    %s", dwEhFramePtr.ToString().c_str());
36248f512ceSopenharmony_ci        HLOGD("  fde_count_enc:       %s", dwFdeCount.ToString().c_str());
36348f512ceSopenharmony_ci        HLOGD("  table_enc:           %s", dwTable.ToString().c_str());
36448f512ceSopenharmony_ci        HLOGD("  table_value_enc:     %s", dwTableValue.ToString().c_str());
36548f512ceSopenharmony_ci        HLOGD("  table_item_size:     %zd", dwTable.GetSize() + dwTableValue.GetSize());
36648f512ceSopenharmony_ci        HLOGD("  table_offset_in_hdr: %zu", dwTable.GetData() - buffer);
36748f512ceSopenharmony_ci
36848f512ceSopenharmony_ci        CHECK_TRUE(version != 1, false, 1, "eh_frame_hdr version is invalid");
36948f512ceSopenharmony_ci        EhFrameHDRValid_ = true;
37048f512ceSopenharmony_ci        ehFrameHDRElfOffset_ = shdrOffset;
37148f512ceSopenharmony_ci        ehFrameHDRFdeCount_ = dwFdeCount.GetAppliedValue();
37248f512ceSopenharmony_ci        ehFrameHDRFdeTableElfOffset_ = dwTable.GetData() - buffer + shdrOffset;
37348f512ceSopenharmony_ci        ehFrameHDRFdeTableItemSize_ = dwTable.GetSize() + dwTableValue.GetSize();
37448f512ceSopenharmony_ci        DumpEhFrameHDR();
37548f512ceSopenharmony_ci
37648f512ceSopenharmony_ci        if (!dwFdeCount.IsOmit() && dwFdeCount.GetValue() > 0) {
37748f512ceSopenharmony_ci            return true;
37848f512ceSopenharmony_ci        } else {
37948f512ceSopenharmony_ci            HLOGW("fde table not found.\n");
38048f512ceSopenharmony_ci        }
38148f512ceSopenharmony_ci        return false;
38248f512ceSopenharmony_ci    }
38348f512ceSopenharmony_ci
38448f512ceSopenharmony_ci    void UpdateSymbols(std::vector<DfxSymbol> &symbolsTable, const std::string &elfPath)
38548f512ceSopenharmony_ci    {
38648f512ceSopenharmony_ci        symbols_.clear();
38748f512ceSopenharmony_ci        HLOGD("%zu symbols loadded from symbolsTable.", symbolsTable.size());
38848f512ceSopenharmony_ci
38948f512ceSopenharmony_ci        symbols_.swap(symbolsTable);
39048f512ceSopenharmony_ci
39148f512ceSopenharmony_ci        AdjustSymbols();
39248f512ceSopenharmony_ci        HLOGD("%zu symbols loadded from elf '%s'.", symbols_.size(), elfPath.c_str());
39348f512ceSopenharmony_ci        for (auto& symbol: symbols_) {
39448f512ceSopenharmony_ci            HLOGD("symbol %s", symbol.ToDebugString().c_str());
39548f512ceSopenharmony_ci        }
39648f512ceSopenharmony_ci        if (buildId_.empty()) {
39748f512ceSopenharmony_ci            HLOGD("buildId not found from elf '%s'.", elfPath.c_str());
39848f512ceSopenharmony_ci            // don't failed. some time the lib have not got the build id
39948f512ceSopenharmony_ci            // buildId not found from elf '/system/bin/ld-musl-arm.so.1'.
40048f512ceSopenharmony_ci        }
40148f512ceSopenharmony_ci    }
40248f512ceSopenharmony_ci
40348f512ceSopenharmony_ci    void AddSymbols(std::vector<DfxSymbol>& symbolsTable, std::shared_ptr<DfxElf> elf, const std::string& filePath)
40448f512ceSopenharmony_ci    {
40548f512ceSopenharmony_ci        // use elfFile_ to get symbolsTable
40648f512ceSopenharmony_ci        DfxSymbols::ParseSymbols(symbolsTable, elf, filePath);
40748f512ceSopenharmony_ci        DfxSymbols::AddSymbolsByPlt(symbolsTable, elf, filePath);
40848f512ceSopenharmony_ci    }
40948f512ceSopenharmony_ci
41048f512ceSopenharmony_ci    bool LoadElfSymbols(std::shared_ptr<DfxMap> map, std::string elfPath)
41148f512ceSopenharmony_ci    {
41248f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
41348f512ceSopenharmony_ci        const auto startTime = steady_clock::now();
41448f512ceSopenharmony_ci#endif
41548f512ceSopenharmony_ci        if (elfFile_ == nullptr) {
41648f512ceSopenharmony_ci            if (StringEndsWith(elfPath, ".hap") && map != nullptr) {
41748f512ceSopenharmony_ci                elfFile_ = DfxElf::CreateFromHap(elfPath, map->prevMap, map->offset);
41848f512ceSopenharmony_ci                map->elf = elfFile_;
41948f512ceSopenharmony_ci            } else {
42048f512ceSopenharmony_ci                elfFile_ = std::make_shared<DfxElf>(elfPath);
42148f512ceSopenharmony_ci            }
42248f512ceSopenharmony_ci        }
42348f512ceSopenharmony_ci        CHECK_TRUE(elfFile_ == nullptr, false, 1, "Failed to create elf file for %s.", elfPath.c_str());
42448f512ceSopenharmony_ci        HLOGD("loaded elf %s", elfPath.c_str());
42548f512ceSopenharmony_ci        if (!elfFile_->IsValid()) {
42648f512ceSopenharmony_ci            HLOGD("parser elf file failed.");
42748f512ceSopenharmony_ci            return false;
42848f512ceSopenharmony_ci        }
42948f512ceSopenharmony_ci
43048f512ceSopenharmony_ci        textExecVaddr_ = elfFile_->GetStartVaddr();
43148f512ceSopenharmony_ci        textExecVaddrFileOffset_ = elfFile_->GetStartOffset();
43248f512ceSopenharmony_ci        HLOGD("textExecVaddr_ 0x%016" PRIx64 " file offset 0x%016" PRIx64 "", textExecVaddr_,
43348f512ceSopenharmony_ci              textExecVaddrFileOffset_);
43448f512ceSopenharmony_ci
43548f512ceSopenharmony_ci        // we prepare two table here
43648f512ceSopenharmony_ci        // only one we will push in to symbols_
43748f512ceSopenharmony_ci        // or both drop if build id is not same
43848f512ceSopenharmony_ci        std::string buildIdFound = elfFile_->GetBuildId();
43948f512ceSopenharmony_ci        std::vector<DfxSymbol> symbolsTable;
44048f512ceSopenharmony_ci        AddSymbols(symbolsTable, elfFile_, filePath_);
44148f512ceSopenharmony_ci        if (UpdateBuildIdIfMatch(buildIdFound)) {
44248f512ceSopenharmony_ci            UpdateSymbols(symbolsTable, elfPath);
44348f512ceSopenharmony_ci        } else {
44448f512ceSopenharmony_ci            HLOGW("symbols will not update for '%s' because buildId is not match.",
44548f512ceSopenharmony_ci                  elfPath.c_str());
44648f512ceSopenharmony_ci            // this mean failed . we don't goon for this.
44748f512ceSopenharmony_ci            return false;
44848f512ceSopenharmony_ci        }
44948f512ceSopenharmony_ci
45048f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
45148f512ceSopenharmony_ci        auto usedTime = duration_cast<microseconds>(steady_clock::now() - startTime);
45248f512ceSopenharmony_ci        if (usedTime.count() != 0) {
45348f512ceSopenharmony_ci            HLOGV("cost %0.3f ms to load symbols '%s'",
45448f512ceSopenharmony_ci                  usedTime.count() / static_cast<double>(milliseconds::duration::period::den),
45548f512ceSopenharmony_ci                  elfPath.c_str());
45648f512ceSopenharmony_ci        }
45748f512ceSopenharmony_ci#endif
45848f512ceSopenharmony_ci        return true;
45948f512ceSopenharmony_ci    }
46048f512ceSopenharmony_ci
46148f512ceSopenharmony_ci    uint64_t GetVaddrInSymbols(uint64_t ip, uint64_t mapStart,
46248f512ceSopenharmony_ci                               uint64_t mapPageOffset) const override
46348f512ceSopenharmony_ci    {
46448f512ceSopenharmony_ci        /*
46548f512ceSopenharmony_ci            00200000-002c5000 r--p 00000000 08:02 46400311
46648f512ceSopenharmony_ci            002c5000-00490000 r-xp 000c5000 08:02 4640031
46748f512ceSopenharmony_ci
46848f512ceSopenharmony_ci            [14] .text             PROGBITS         00000000002c5000  000c5000
46948f512ceSopenharmony_ci
47048f512ceSopenharmony_ci            if ip is 0x46e6ab
47148f512ceSopenharmony_ci            1. find the map range is 002c5000-00490000
47248f512ceSopenharmony_ci            2. ip - map start(002c5000) = map section offset
47348f512ceSopenharmony_ci            3. map section offset + map page offset(000c5000) = elf file offset
47448f512ceSopenharmony_ci            4. elf file offset - exec file offset(000c5000)
47548f512ceSopenharmony_ci                = ip offset (ip always in exec file offset)
47648f512ceSopenharmony_ci            5. ip offset + exec begin vaddr(2c5000) = virtual ip in elf
47748f512ceSopenharmony_ci        */
47848f512ceSopenharmony_ci        uint64_t vaddr = ip - mapStart + mapPageOffset - textExecVaddrFileOffset_ + textExecVaddr_;
47948f512ceSopenharmony_ci        HLOGM(" ip :0x%016" PRIx64 " -> elf offset :0x%016" PRIx64 " -> vaddr :0x%016" PRIx64 " ",
48048f512ceSopenharmony_ci              ip, ip - mapStart + mapPageOffset, vaddr);
48148f512ceSopenharmony_ci        HLOGM("(minExecAddrFileOffset_ is 0x%" PRIx64 " textExecVaddr_ is 0x%" PRIx64 ")",
48248f512ceSopenharmony_ci              textExecVaddrFileOffset_, textExecVaddr_);
48348f512ceSopenharmony_ci        return vaddr;
48448f512ceSopenharmony_ci    }
48548f512ceSopenharmony_ci};
48648f512ceSopenharmony_ci
48748f512ceSopenharmony_ciclass KernelSymbols : public ElfFileSymbols {
48848f512ceSopenharmony_cipublic:
48948f512ceSopenharmony_ci    explicit KernelSymbols(const std::string &symbolFilePath)
49048f512ceSopenharmony_ci        : ElfFileSymbols(symbolFilePath, SYMBOL_KERNEL_FILE)
49148f512ceSopenharmony_ci    {
49248f512ceSopenharmony_ci    }
49348f512ceSopenharmony_ci
49448f512ceSopenharmony_ci    KernelSymbols(const std::string &symbolFilePath,
49548f512ceSopenharmony_ci                  const SymbolsFileType symbolsFileType)
49648f512ceSopenharmony_ci        : ElfFileSymbols(symbolFilePath, symbolsFileType)
49748f512ceSopenharmony_ci    {
49848f512ceSopenharmony_ci    }
49948f512ceSopenharmony_ci
50048f512ceSopenharmony_ci    static constexpr const int KSYM_MIN_TOKENS = 3;
50148f512ceSopenharmony_ci    static constexpr const int KSYM_DEFAULT_LINE = 35000;
50248f512ceSopenharmony_ci    static constexpr const int KSYM_DEFAULT_SIZE = 1024 * 1024 * 1; // 1MB
50348f512ceSopenharmony_ci
50448f512ceSopenharmony_ci    bool ParseKallsymsLine(const std::string &kallsymsPath)
50548f512ceSopenharmony_ci    {
50648f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
50748f512ceSopenharmony_ci        const auto startTime = steady_clock::now();
50848f512ceSopenharmony_ci        std::chrono::microseconds parseLineTime = std::chrono::microseconds::zero();
50948f512ceSopenharmony_ci        std::chrono::microseconds sscanfTime = std::chrono::microseconds::zero();
51048f512ceSopenharmony_ci        std::chrono::microseconds newTime = std::chrono::microseconds::zero();
51148f512ceSopenharmony_ci        std::chrono::microseconds readFileTime = std::chrono::microseconds::zero();
51248f512ceSopenharmony_ci#endif
51348f512ceSopenharmony_ci        size_t lines = 0;
51448f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
51548f512ceSopenharmony_ci        const auto eachFileStartTime = steady_clock::now();
51648f512ceSopenharmony_ci#endif
51748f512ceSopenharmony_ci        std::string kallsym;
51848f512ceSopenharmony_ci        CHECK_TRUE(!ReadFileToString(kallsymsPath, kallsym, KSYM_DEFAULT_SIZE) || kallsym.empty(), false, 1,
51948f512ceSopenharmony_ci                   "%s load failed.", kallsymsPath.c_str());
52048f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
52148f512ceSopenharmony_ci        // any way we finish the line scan
52248f512ceSopenharmony_ci        readFileTime += duration_cast<milliseconds>(steady_clock::now() - eachFileStartTime);
52348f512ceSopenharmony_ci#endif
52448f512ceSopenharmony_ci        // reduce the mem alloc
52548f512ceSopenharmony_ci        symbols_.reserve(KSYM_DEFAULT_LINE);
52648f512ceSopenharmony_ci
52748f512ceSopenharmony_ci        char *lineBegin = kallsym.data();
52848f512ceSopenharmony_ci        char *dataEnd = lineBegin + kallsym.size();
52948f512ceSopenharmony_ci        while (lineBegin < dataEnd) {
53048f512ceSopenharmony_ci            char *lineEnd = strchr(lineBegin, '\n');
53148f512ceSopenharmony_ci            if (lineEnd != nullptr) {
53248f512ceSopenharmony_ci                *lineEnd = '\0';
53348f512ceSopenharmony_ci            } else {
53448f512ceSopenharmony_ci                lineEnd = dataEnd;
53548f512ceSopenharmony_ci            }
53648f512ceSopenharmony_ci            size_t lineSize = (lineEnd != nullptr) ? (lineEnd - lineBegin) : (dataEnd - lineBegin);
53748f512ceSopenharmony_ci
53848f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
53948f512ceSopenharmony_ci            const auto eachLineStartTime = steady_clock::now();
54048f512ceSopenharmony_ci#endif
54148f512ceSopenharmony_ci            lines++;
54248f512ceSopenharmony_ci            uint64_t addr = 0;
54348f512ceSopenharmony_ci            char type = '\0';
54448f512ceSopenharmony_ci
54548f512ceSopenharmony_ci            char nameRaw[lineSize];
54648f512ceSopenharmony_ci            char moduleRaw[lineSize];
54748f512ceSopenharmony_ci            int ret = sscanf_s(lineBegin, "%" PRIx64 " %c %s%s", &addr, &type, sizeof(type),
54848f512ceSopenharmony_ci                               nameRaw, sizeof(nameRaw), moduleRaw, sizeof(moduleRaw));
54948f512ceSopenharmony_ci
55048f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
55148f512ceSopenharmony_ci            // any way we finish the line scan
55248f512ceSopenharmony_ci            sscanfTime += duration_cast<milliseconds>(steady_clock::now() - eachLineStartTime);
55348f512ceSopenharmony_ci#endif
55448f512ceSopenharmony_ci            if (ret >= KSYM_MIN_TOKENS) {
55548f512ceSopenharmony_ci                if (ret == KSYM_MIN_TOKENS) {
55648f512ceSopenharmony_ci                    moduleRaw[0] = '\0';
55748f512ceSopenharmony_ci                }
55848f512ceSopenharmony_ci                HLOGM(" 0x%016" PRIx64 " %c '%s' '%s'", addr, type, nameRaw, moduleRaw);
55948f512ceSopenharmony_ci            } else {
56048f512ceSopenharmony_ci                HLOGW("unknown line %d: '%s'", ret, lineBegin);
56148f512ceSopenharmony_ci                lineBegin = lineEnd + 1;
56248f512ceSopenharmony_ci                continue;
56348f512ceSopenharmony_ci            }
56448f512ceSopenharmony_ci            lineBegin = lineEnd + 1;
56548f512ceSopenharmony_ci            std::string name = nameRaw;
56648f512ceSopenharmony_ci            std::string module = moduleRaw;
56748f512ceSopenharmony_ci
56848f512ceSopenharmony_ci            /*
56948f512ceSopenharmony_ci            T
57048f512ceSopenharmony_ci            The symbol is in the text (code) section.
57148f512ceSopenharmony_ci
57248f512ceSopenharmony_ci            W
57348f512ceSopenharmony_ci            The symbol is a weak symbol that has not been specifically
57448f512ceSopenharmony_ci            tagged as a weak object symbol. When a weak defined symbol is
57548f512ceSopenharmony_ci            linked with a normal defined symbol, the normal defined symbol
57648f512ceSopenharmony_ci            is used with no error. When a weak undefined symbol is linked
57748f512ceSopenharmony_ci            and the symbol is not defined, the value of the weak symbol
57848f512ceSopenharmony_ci            becomes zero with no error.
57948f512ceSopenharmony_ci            */
58048f512ceSopenharmony_ci            if (addr != 0 && strchr("TtWw", type)) {
58148f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
58248f512ceSopenharmony_ci                const auto eachNewSymbolTime = steady_clock::now();
58348f512ceSopenharmony_ci#endif
58448f512ceSopenharmony_ci                // we only need text symbols
58548f512ceSopenharmony_ci                symbols_.emplace_back(addr, name, module.empty() ? filePath_ : module);
58648f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
58748f512ceSopenharmony_ci                newTime += duration_cast<milliseconds>(steady_clock::now() - eachNewSymbolTime);
58848f512ceSopenharmony_ci#endif
58948f512ceSopenharmony_ci            }
59048f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
59148f512ceSopenharmony_ci            parseLineTime += duration_cast<milliseconds>(steady_clock::now() - eachLineStartTime);
59248f512ceSopenharmony_ci#endif
59348f512ceSopenharmony_ci        }
59448f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_SYMBOLS_TIME
59548f512ceSopenharmony_ci        std::chrono::microseconds usedTime =
59648f512ceSopenharmony_ci            duration_cast<milliseconds>(steady_clock::now() - startTime);
59748f512ceSopenharmony_ci        printf("parse kernel symbols use : %0.3f ms\n", usedTime.count() / MS_DURATION);
59848f512ceSopenharmony_ci        printf("parse line use : %0.3f ms\n", parseLineTime.count() / MS_DURATION);
59948f512ceSopenharmony_ci        printf("sscanf line use : %0.3f ms\n", sscanfTime.count() / MS_DURATION);
60048f512ceSopenharmony_ci        printf("new symbols use : %0.3f ms\n", newTime.count() / MS_DURATION);
60148f512ceSopenharmony_ci        printf("read file use : %0.3f ms\n", readFileTime.count() / MS_DURATION);
60248f512ceSopenharmony_ci#endif
60348f512ceSopenharmony_ci        HLOGD("load %s: %zu line processed(%zu symbols)", kallsymsPath.c_str(), lines, symbols_.size());
60448f512ceSopenharmony_ci        return true;
60548f512ceSopenharmony_ci    }
60648f512ceSopenharmony_ci
60748f512ceSopenharmony_ci    const std::string KPTR_RESTRICT = "/proc/sys/kernel/kptr_restrict";
60848f512ceSopenharmony_ci
60948f512ceSopenharmony_ci    bool LoadKernelSyms()
61048f512ceSopenharmony_ci    {
61148f512ceSopenharmony_ci        if (!IsRoot()) {
61248f512ceSopenharmony_ci            return false;
61348f512ceSopenharmony_ci        }
61448f512ceSopenharmony_ci        HLOGD("try read /proc/kallsyms");
61548f512ceSopenharmony_ci        if (access("/proc/kallsyms", R_OK) != 0) {
61648f512ceSopenharmony_ci            printf("No vmlinux path is given, and kallsyms cannot be opened\n");
61748f512ceSopenharmony_ci            return false;
61848f512ceSopenharmony_ci        }
61948f512ceSopenharmony_ci        bool hasChangeKptr = false;
62048f512ceSopenharmony_ci        std::string oldKptrRestrict = ReadFileToString(KPTR_RESTRICT);
62148f512ceSopenharmony_ci        if (oldKptrRestrict.front() != '0') {
62248f512ceSopenharmony_ci            printf("/proc/sys/kernel/kptr_restrict is NOT 0, will try set it to 0.\n");
62348f512ceSopenharmony_ci            hasChangeKptr = WriteStringToFile(KPTR_RESTRICT, "0");
62448f512ceSopenharmony_ci            if (!hasChangeKptr) {
62548f512ceSopenharmony_ci                printf("/proc/sys/kernel/kptr_restrict write failed and we can't not change it.\n");
62648f512ceSopenharmony_ci            }
62748f512ceSopenharmony_ci        }
62848f512ceSopenharmony_ci
62948f512ceSopenharmony_ci        // getline end
63048f512ceSopenharmony_ci        CHECK_TRUE(!ParseKallsymsLine("/proc/kallsyms"), false, 0, "");
63148f512ceSopenharmony_ci
63248f512ceSopenharmony_ci        if (hasChangeKptr) {
63348f512ceSopenharmony_ci            if (!WriteStringToFile(KPTR_RESTRICT, oldKptrRestrict)) {
63448f512ceSopenharmony_ci                printf("recover /proc/sys/kernel/kptr_restrict fail.\n");
63548f512ceSopenharmony_ci            }
63648f512ceSopenharmony_ci        }
63748f512ceSopenharmony_ci
63848f512ceSopenharmony_ci        if (symbols_.empty()) {
63948f512ceSopenharmony_ci            printf("The symbol table addresses in /proc/kallsyms are all 0.\n"
64048f512ceSopenharmony_ci                   "Please check the value of /proc/sys/kernel/kptr_restrict, it "
64148f512ceSopenharmony_ci                   "should be 0.\n"
64248f512ceSopenharmony_ci                   "Or provide a separate vmlinux path.\n");
64348f512ceSopenharmony_ci
64448f512ceSopenharmony_ci            if (buildId_.size() != 0) {
64548f512ceSopenharmony_ci                // but we got the buildid , so we make a dummpy symbols
64648f512ceSopenharmony_ci                HLOGD("kallsyms not found. but we have the buildid");
64748f512ceSopenharmony_ci                return true;
64848f512ceSopenharmony_ci            } else {
64948f512ceSopenharmony_ci                // we got nothing
65048f512ceSopenharmony_ci                return false;
65148f512ceSopenharmony_ci            }
65248f512ceSopenharmony_ci        } else {
65348f512ceSopenharmony_ci            AdjustSymbols();
65448f512ceSopenharmony_ci            HLOGV("%zu symbols_ loadded from kallsyms.\n", symbols_.size());
65548f512ceSopenharmony_ci            return true;
65648f512ceSopenharmony_ci        }
65748f512ceSopenharmony_ci    }
65848f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
65948f512ceSopenharmony_ci    {
66048f512ceSopenharmony_ci        symbolsLoaded_ = true;
66148f512ceSopenharmony_ci        HLOGV("KernelSymbols try read '%s' search paths size %zu, inDeviceRecord %d",
66248f512ceSopenharmony_ci              symbolFilePath.c_str(), symbolsFileSearchPaths_.size(), onRecording_);
66348f512ceSopenharmony_ci
66448f512ceSopenharmony_ci        if (onRecording_) {
66548f512ceSopenharmony_ci            const auto startTime = std::chrono::steady_clock::now();
66648f512ceSopenharmony_ci            if (!LoadKernelSyms()) {
66748f512ceSopenharmony_ci                if (IsRoot()) {
66848f512ceSopenharmony_ci                    printf("parse kalsyms failed.\n");
66948f512ceSopenharmony_ci                }
67048f512ceSopenharmony_ci                return false;
67148f512ceSopenharmony_ci            } else {
67248f512ceSopenharmony_ci                const auto thisTime = std::chrono::steady_clock::now();
67348f512ceSopenharmony_ci                const auto usedTimeMsTick =
67448f512ceSopenharmony_ci                    std::chrono::duration_cast<std::chrono::milliseconds>(thisTime - startTime);
67548f512ceSopenharmony_ci                HLOGV("Load kernel symbols (total %" PRId64 " ms)\n", (int64_t)usedTimeMsTick.count());
67648f512ceSopenharmony_ci                // load complete
67748f512ceSopenharmony_ci                return true;
67848f512ceSopenharmony_ci            }
67948f512ceSopenharmony_ci
68048f512ceSopenharmony_ci            // try read
68148f512ceSopenharmony_ci            HLOGD("try read /sys/kernel/notes");
68248f512ceSopenharmony_ci            std::string notes = ReadFileToString("/sys/kernel/notes");
68348f512ceSopenharmony_ci            if (notes.empty()) {
68448f512ceSopenharmony_ci                printf("notes cannot be opened, unable get buildid\n");
68548f512ceSopenharmony_ci                return false;
68648f512ceSopenharmony_ci            } else {
68748f512ceSopenharmony_ci                HLOGD("kernel notes size: %zu", notes.size());
68848f512ceSopenharmony_ci                buildId_ = DfxElf::GetBuildId((uint64_t)notes.data(), (uint64_t)notes.size());
68948f512ceSopenharmony_ci            }
69048f512ceSopenharmony_ci        } // no search path
69148f512ceSopenharmony_ci
69248f512ceSopenharmony_ci        // try vmlinux
69348f512ceSopenharmony_ci        return ElfFileSymbols::LoadSymbols(nullptr, KERNEL_ELF_NAME);
69448f512ceSopenharmony_ci    }
69548f512ceSopenharmony_ci    uint64_t GetVaddrInSymbols(uint64_t ip, uint64_t mapStart, uint64_t) const override
69648f512ceSopenharmony_ci    {
69748f512ceSopenharmony_ci        // ip is vaddr in /proc/kallsyms
69848f512ceSopenharmony_ci        return ip;
69948f512ceSopenharmony_ci    }
70048f512ceSopenharmony_ci    ~KernelSymbols() override {}
70148f512ceSopenharmony_ci};
70248f512ceSopenharmony_ci
70348f512ceSopenharmony_ciclass KernelThreadSymbols : public KernelSymbols {
70448f512ceSopenharmony_cipublic:
70548f512ceSopenharmony_ci    explicit KernelThreadSymbols(const std::string &symbolFilePath)
70648f512ceSopenharmony_ci        : KernelSymbols(symbolFilePath, SYMBOL_KERNEL_THREAD_FILE)
70748f512ceSopenharmony_ci    {
70848f512ceSopenharmony_ci    }
70948f512ceSopenharmony_ci
71048f512ceSopenharmony_ci    bool LoadKernelSyms()
71148f512ceSopenharmony_ci    {
71248f512ceSopenharmony_ci        if (!IsRoot()) {
71348f512ceSopenharmony_ci            return false;
71448f512ceSopenharmony_ci        }
71548f512ceSopenharmony_ci        // find real proc path by filePath_
71648f512ceSopenharmony_ci        std::string procPath;
71748f512ceSopenharmony_ci        if (filePath_ == SYSMGR_FILE_NAME) {
71848f512ceSopenharmony_ci            procPath = StringPrintf("/proc/%u/uallsyms", SYSMGR_PID);
71948f512ceSopenharmony_ci        } else if (filePath_ == DEVHOST_FILE_NAME) {
72048f512ceSopenharmony_ci            procPath = "/proc/devhost/root/kallsyms";
72148f512ceSopenharmony_ci        }
72248f512ceSopenharmony_ci        HLOGD("try read kernel thread symbol file %s in %s", filePath_.c_str(), procPath.c_str());
72348f512ceSopenharmony_ci        CHECK_TRUE(access(procPath.c_str(), R_OK) != 0, false, LOG_TYPE_PRINTF,
72448f512ceSopenharmony_ci                   "kernel thread symbol file %s cannot be opened\n", filePath_.c_str());
72548f512ceSopenharmony_ci        bool hasChangeKptr = false;
72648f512ceSopenharmony_ci        std::string oldKptrRestrict = ReadFileToString(KPTR_RESTRICT);
72748f512ceSopenharmony_ci        if (oldKptrRestrict.front() != '0') {
72848f512ceSopenharmony_ci            printf("/proc/sys/kernel/kptr_restrict is NOT 0, will try set it to 0.\n");
72948f512ceSopenharmony_ci            hasChangeKptr = WriteStringToFile(KPTR_RESTRICT, "0");
73048f512ceSopenharmony_ci            if (!hasChangeKptr) {
73148f512ceSopenharmony_ci                printf("/proc/sys/kernel/kptr_restrict write failed and we can't not change it.\n");
73248f512ceSopenharmony_ci            }
73348f512ceSopenharmony_ci        }
73448f512ceSopenharmony_ci
73548f512ceSopenharmony_ci        // getline end
73648f512ceSopenharmony_ci        CHECK_TRUE(!ParseKallsymsLine(procPath), false, 0, "");
73748f512ceSopenharmony_ci
73848f512ceSopenharmony_ci        if (hasChangeKptr) {
73948f512ceSopenharmony_ci            if (!WriteStringToFile(KPTR_RESTRICT, oldKptrRestrict)) {
74048f512ceSopenharmony_ci                printf("recover /proc/sys/kernel/kptr_restrict fail.\n");
74148f512ceSopenharmony_ci            }
74248f512ceSopenharmony_ci        }
74348f512ceSopenharmony_ci
74448f512ceSopenharmony_ci        if (symbols_.empty()) {
74548f512ceSopenharmony_ci            printf("The symbol table addresses in %s are all 0.\n"
74648f512ceSopenharmony_ci                   "Please check the value of /proc/sys/kernel/kptr_restrict, it "
74748f512ceSopenharmony_ci                   "should be 0.\n", filePath_.c_str());
74848f512ceSopenharmony_ci            return false;
74948f512ceSopenharmony_ci        } else {
75048f512ceSopenharmony_ci            AdjustSymbols();
75148f512ceSopenharmony_ci            HLOGV("%zu symbols_ loadded from %s.\n", symbols_.size(), procPath.c_str());
75248f512ceSopenharmony_ci            return true;
75348f512ceSopenharmony_ci        }
75448f512ceSopenharmony_ci    }
75548f512ceSopenharmony_ci
75648f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
75748f512ceSopenharmony_ci    {
75848f512ceSopenharmony_ci        symbolsLoaded_ = true;
75948f512ceSopenharmony_ci        HLOGV("KernelThreadSymbols try read '%s', inDeviceRecord %d",
76048f512ceSopenharmony_ci              filePath_.c_str(), onRecording_);
76148f512ceSopenharmony_ci
76248f512ceSopenharmony_ci        if (onRecording_) {
76348f512ceSopenharmony_ci            const auto startTime = std::chrono::steady_clock::now();
76448f512ceSopenharmony_ci            if (!LoadKernelSyms()) {
76548f512ceSopenharmony_ci                if (IsRoot()) {
76648f512ceSopenharmony_ci                    printf("parse %s failed.\n", filePath_.c_str());
76748f512ceSopenharmony_ci                }
76848f512ceSopenharmony_ci            } else {
76948f512ceSopenharmony_ci                const auto thisTime = std::chrono::steady_clock::now();
77048f512ceSopenharmony_ci                const auto usedTimeMsTick =
77148f512ceSopenharmony_ci                    std::chrono::duration_cast<std::chrono::milliseconds>(thisTime - startTime);
77248f512ceSopenharmony_ci                HLOGV("Load kernel thread symbols (total %" PRId64 " ms)\n", (int64_t)usedTimeMsTick.count());
77348f512ceSopenharmony_ci                // load complete
77448f512ceSopenharmony_ci                return true;
77548f512ceSopenharmony_ci            }
77648f512ceSopenharmony_ci        } // no search path
77748f512ceSopenharmony_ci
77848f512ceSopenharmony_ci        // try elf
77948f512ceSopenharmony_ci        return ElfFileSymbols::LoadSymbols(nullptr, filePath_);
78048f512ceSopenharmony_ci    }
78148f512ceSopenharmony_ci    ~KernelThreadSymbols() override {}
78248f512ceSopenharmony_ci};
78348f512ceSopenharmony_ci
78448f512ceSopenharmony_ciclass KernelModuleSymbols : public ElfFileSymbols {
78548f512ceSopenharmony_cipublic:
78648f512ceSopenharmony_ci    explicit KernelModuleSymbols(const std::string &symbolFilePath) : ElfFileSymbols(symbolFilePath)
78748f512ceSopenharmony_ci    {
78848f512ceSopenharmony_ci        HLOGV("create %s", symbolFilePath.c_str());
78948f512ceSopenharmony_ci        symbolFileType_ = SYMBOL_KERNEL_MODULE_FILE;
79048f512ceSopenharmony_ci        module_ = symbolFilePath;
79148f512ceSopenharmony_ci    }
79248f512ceSopenharmony_ci    ~KernelModuleSymbols() override {};
79348f512ceSopenharmony_ci
79448f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
79548f512ceSopenharmony_ci    {
79648f512ceSopenharmony_ci        symbolsLoaded_ = true;
79748f512ceSopenharmony_ci        if (module_ == filePath_ and onRecording_) {
79848f512ceSopenharmony_ci            // file name still not convert to ko file path
79948f512ceSopenharmony_ci            // this is in record mode
80048f512ceSopenharmony_ci            HLOGV("find ko name %s", module_.c_str());
80148f512ceSopenharmony_ci            for (const std::string &path : kernelModulePaths) {
80248f512ceSopenharmony_ci                if (access(path.c_str(), R_OK) == 0) {
80348f512ceSopenharmony_ci                    std::string koPath = path + module_ + KERNEL_MODULES_EXT_NAME;
80448f512ceSopenharmony_ci                    HLOGV("found ko in %s", koPath.c_str());
80548f512ceSopenharmony_ci                    if (access(koPath.c_str(), R_OK) == 0) {
80648f512ceSopenharmony_ci                        // create symbol
80748f512ceSopenharmony_ci                        filePath_ = koPath;
80848f512ceSopenharmony_ci                        break; // find next ko
80948f512ceSopenharmony_ci                    }
81048f512ceSopenharmony_ci                }
81148f512ceSopenharmony_ci            }
81248f512ceSopenharmony_ci            LoadBuildId();
81348f512ceSopenharmony_ci        } else {
81448f512ceSopenharmony_ci            HLOGV("we have file path, load with %s", filePath_.c_str());
81548f512ceSopenharmony_ci            return ElfFileSymbols::LoadSymbols(nullptr, filePath_);
81648f512ceSopenharmony_ci        }
81748f512ceSopenharmony_ci        return false;
81848f512ceSopenharmony_ci    }
81948f512ceSopenharmony_ci    uint64_t GetVaddrInSymbols(uint64_t ip, uint64_t mapStart, uint64_t) const override
82048f512ceSopenharmony_ci    {
82148f512ceSopenharmony_ci        return ip - mapStart;
82248f512ceSopenharmony_ci    }
82348f512ceSopenharmony_ci
82448f512ceSopenharmony_ciprivate:
82548f512ceSopenharmony_ci    bool LoadBuildId()
82648f512ceSopenharmony_ci    {
82748f512ceSopenharmony_ci        std::string sysFile = "/sys/module/" + module_ + "/notes/.note.gnu.build-id";
82848f512ceSopenharmony_ci        std::string buildIdRaw = ReadFileToString(sysFile);
82948f512ceSopenharmony_ci        if (!buildIdRaw.empty()) {
83048f512ceSopenharmony_ci            buildId_ = DfxElf::GetBuildId((uint64_t)buildIdRaw.data(), (uint64_t)buildIdRaw.size());
83148f512ceSopenharmony_ci            HLOGD("kerne module %s(%s) build id %s", module_.c_str(), filePath_.c_str(),
83248f512ceSopenharmony_ci                  buildId_.c_str());
83348f512ceSopenharmony_ci            return buildId_.empty() ? false : true;
83448f512ceSopenharmony_ci        }
83548f512ceSopenharmony_ci        return false;
83648f512ceSopenharmony_ci    }
83748f512ceSopenharmony_ci
83848f512ceSopenharmony_ci    const std::vector<std::string> kernelModulePaths = {"/vendor/modules/"};
83948f512ceSopenharmony_ci    std::string module_ = "";
84048f512ceSopenharmony_ci};
84148f512ceSopenharmony_ci
84248f512ceSopenharmony_ciclass JavaFileSymbols : public ElfFileSymbols {
84348f512ceSopenharmony_cipublic:
84448f512ceSopenharmony_ci    explicit JavaFileSymbols(const std::string &symbolFilePath) : ElfFileSymbols(symbolFilePath)
84548f512ceSopenharmony_ci    {
84648f512ceSopenharmony_ci        symbolFileType_ = SYMBOL_KERNEL_FILE;
84748f512ceSopenharmony_ci    }
84848f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
84948f512ceSopenharmony_ci    {
85048f512ceSopenharmony_ci        symbolsLoaded_ = true;
85148f512ceSopenharmony_ci        return false;
85248f512ceSopenharmony_ci    }
85348f512ceSopenharmony_ci    ~JavaFileSymbols() override {}
85448f512ceSopenharmony_ci
85548f512ceSopenharmony_ci    uint64_t GetVaddrInSymbols(uint64_t ip, uint64_t mapStart,
85648f512ceSopenharmony_ci                                       uint64_t mapPageOffset) const override
85748f512ceSopenharmony_ci    {
85848f512ceSopenharmony_ci        // this is different with elf
85948f512ceSopenharmony_ci        // elf use  ip - mapStart + mapPageOffset - minExecAddrFileOffset_ + textExecVaddr_
86048f512ceSopenharmony_ci        return ip - mapStart + mapPageOffset;
86148f512ceSopenharmony_ci    }
86248f512ceSopenharmony_ci};
86348f512ceSopenharmony_ci
86448f512ceSopenharmony_ciclass JSFileSymbols : public ElfFileSymbols {
86548f512ceSopenharmony_cipublic:
86648f512ceSopenharmony_ci    explicit JSFileSymbols(const std::string &symbolFilePath) : ElfFileSymbols(symbolFilePath)
86748f512ceSopenharmony_ci    {
86848f512ceSopenharmony_ci        symbolFileType_ = SYMBOL_KERNEL_FILE;
86948f512ceSopenharmony_ci    }
87048f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
87148f512ceSopenharmony_ci    {
87248f512ceSopenharmony_ci        symbolsLoaded_ = true;
87348f512ceSopenharmony_ci        return false;
87448f512ceSopenharmony_ci    }
87548f512ceSopenharmony_ci    ~JSFileSymbols() override {}
87648f512ceSopenharmony_ci};
87748f512ceSopenharmony_ci
87848f512ceSopenharmony_ciclass HapFileSymbols : public ElfFileSymbols {
87948f512ceSopenharmony_ciprivate:
88048f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
88148f512ceSopenharmony_ci    std::unique_ptr<DfxExtractor> dfxExtractor_;
88248f512ceSopenharmony_ci    bool hapExtracted_ = false;
88348f512ceSopenharmony_ci#endif
88448f512ceSopenharmony_ci    std::unique_ptr<uint8_t[]> abcDataPtr_ = nullptr;
88548f512ceSopenharmony_ci    [[maybe_unused]] uintptr_t loadOffSet_ = 0;
88648f512ceSopenharmony_ci    [[maybe_unused]] size_t abcDataSize_ = 0;
88748f512ceSopenharmony_ci    [[maybe_unused]] uintptr_t arkExtractorptr_ = 0;
88848f512ceSopenharmony_ci    bool isHapAbc_ = false;
88948f512ceSopenharmony_ci    pid_t pid_ = 0;
89048f512ceSopenharmony_cipublic:
89148f512ceSopenharmony_ci    explicit HapFileSymbols(const std::string &symbolFilePath, pid_t pid)
89248f512ceSopenharmony_ci        : ElfFileSymbols(symbolFilePath, SYMBOL_HAP_FILE)
89348f512ceSopenharmony_ci    {
89448f512ceSopenharmony_ci        pid_ = pid;
89548f512ceSopenharmony_ci    }
89648f512ceSopenharmony_ci
89748f512ceSopenharmony_ci    bool IsHapAbc()
89848f512ceSopenharmony_ci    {
89948f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
90048f512ceSopenharmony_ci        if (hapExtracted_) {
90148f512ceSopenharmony_ci            return isHapAbc_;
90248f512ceSopenharmony_ci        }
90348f512ceSopenharmony_ci        hapExtracted_ = true;
90448f512ceSopenharmony_ci        HLOGD("the symbol file is %s, pid is %d.", filePath_.c_str(), pid_);
90548f512ceSopenharmony_ci        if (IsRoot()) {
90648f512ceSopenharmony_ci            if (IsApplicationEncryped(pid_)) {
90748f512ceSopenharmony_ci                HLOGD("no need to parse js symbols");
90848f512ceSopenharmony_ci                return false;
90948f512ceSopenharmony_ci            }
91048f512ceSopenharmony_ci        }
91148f512ceSopenharmony_ci
91248f512ceSopenharmony_ci        CHECK_TRUE(StringEndsWith(filePath_, ".hap") && map_->IsMapExec(), false, 1,
91348f512ceSopenharmony_ci                   "map is exec not abc file , the symbol file is:%s", map_->name.c_str());
91448f512ceSopenharmony_ci
91548f512ceSopenharmony_ci        if (StringEndsWith(filePath_, ".hap") || StringEndsWith(filePath_, ".hsp") ||
91648f512ceSopenharmony_ci            StringEndsWith(filePath_, ".hqf")) {
91748f512ceSopenharmony_ci            dfxExtractor_ = std::make_unique<DfxExtractor>(filePath_);
91848f512ceSopenharmony_ci            CHECK_TRUE(!dfxExtractor_->GetHapAbcInfo(loadOffSet_, abcDataPtr_, abcDataSize_), false, 1,
91948f512ceSopenharmony_ci                       "failed to call GetHapAbcInfo, the symbol file is:%s", filePath_.c_str());
92048f512ceSopenharmony_ci            HLOGD("loadOffSet %u", (uint32_t)loadOffSet_);
92148f512ceSopenharmony_ci            if (abcDataPtr_ != nullptr) {
92248f512ceSopenharmony_ci                isHapAbc_ = true;
92348f512ceSopenharmony_ci                HLOGD("symbol file : %s, isAbc: %d", filePath_.c_str(), isHapAbc_);
92448f512ceSopenharmony_ci            }
92548f512ceSopenharmony_ci        } else {
92648f512ceSopenharmony_ci            loadOffSet_ = map_->offset;
92748f512ceSopenharmony_ci            abcDataSize_ = map_->end - map_->begin;
92848f512ceSopenharmony_ci            abcDataPtr_ = std::make_unique<uint8_t[]>(abcDataSize_);
92948f512ceSopenharmony_ci            auto size = DfxMemory::ReadProcMemByPid(pid_, map_->begin, abcDataPtr_.get(), map_->end - map_->begin);
93048f512ceSopenharmony_ci            if (size != abcDataSize_) {
93148f512ceSopenharmony_ci                HLOGD("return size is small abcDataPtr : %s, isAbc: %d", abcDataPtr_.get(), isHapAbc_);
93248f512ceSopenharmony_ci                return false;
93348f512ceSopenharmony_ci            }
93448f512ceSopenharmony_ci            isHapAbc_ = true;
93548f512ceSopenharmony_ci            HLOGD("symbol file name %s loadOffSet %u abcDataSize_ %u",
93648f512ceSopenharmony_ci                  filePath_.c_str(), (uint32_t)loadOffSet_, (uint32_t)abcDataSize_);
93748f512ceSopenharmony_ci        }
93848f512ceSopenharmony_ci        auto ret = DfxArk::ArkCreateJsSymbolExtractor(&arkExtractorptr_);
93948f512ceSopenharmony_ci        if (ret < 0) {
94048f512ceSopenharmony_ci            arkExtractorptr_ = 0;
94148f512ceSopenharmony_ci            HLOGE("failed to call ArkCreateJsSymbolExtractor, the symbol file is:%s", filePath_.c_str());
94248f512ceSopenharmony_ci        }
94348f512ceSopenharmony_ci#endif
94448f512ceSopenharmony_ci        return isHapAbc_;
94548f512ceSopenharmony_ci    }
94648f512ceSopenharmony_ci
94748f512ceSopenharmony_ci    bool IsAbc() override
94848f512ceSopenharmony_ci    {
94948f512ceSopenharmony_ci        return isHapAbc_ == true;
95048f512ceSopenharmony_ci    }
95148f512ceSopenharmony_ci
95248f512ceSopenharmony_ci    void SetBoolValue(bool value) override
95348f512ceSopenharmony_ci    {
95448f512ceSopenharmony_ci        isHapAbc_ = value;
95548f512ceSopenharmony_ci    }
95648f512ceSopenharmony_ci
95748f512ceSopenharmony_ci    bool LoadDebugInfo(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
95848f512ceSopenharmony_ci    {
95948f512ceSopenharmony_ci        HLOGD("map ptr:%p, map name:%s", map.get(), map->name.c_str());
96048f512ceSopenharmony_ci        if (debugInfoLoaded_) {
96148f512ceSopenharmony_ci            return true;
96248f512ceSopenharmony_ci        }
96348f512ceSopenharmony_ci        CHECK_TRUE(!onRecording_, true, 0, "");
96448f512ceSopenharmony_ci
96548f512ceSopenharmony_ci        if (!IsHapAbc()) {
96648f512ceSopenharmony_ci            ElfFileSymbols::LoadDebugInfo(map, "");
96748f512ceSopenharmony_ci        }
96848f512ceSopenharmony_ci        debugInfoLoaded_ = true;
96948f512ceSopenharmony_ci        debugInfoLoadResult_ = true;
97048f512ceSopenharmony_ci        return true;
97148f512ceSopenharmony_ci    }
97248f512ceSopenharmony_ci
97348f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
97448f512ceSopenharmony_ci    {
97548f512ceSopenharmony_ci        HLOGD("map ptr:%p, map name:%s", map.get(), map->name.c_str());
97648f512ceSopenharmony_ci        CHECK_TRUE(symbolsLoaded_ || !onRecording_, true, 0, "");
97748f512ceSopenharmony_ci        symbolsLoaded_ = true;
97848f512ceSopenharmony_ci        if (!IsHapAbc()) {
97948f512ceSopenharmony_ci            ElfFileSymbols::LoadSymbols(map, "");
98048f512ceSopenharmony_ci        }
98148f512ceSopenharmony_ci        return true;
98248f512ceSopenharmony_ci    }
98348f512ceSopenharmony_ci
98448f512ceSopenharmony_ci    DfxSymbol GetSymbolWithPcAndMap(uint64_t ip, std::shared_ptr<DfxMap> map) override
98548f512ceSopenharmony_ci    {
98648f512ceSopenharmony_ci        // get cache
98748f512ceSopenharmony_ci        auto iter = symbolsMap_.find(ip);
98848f512ceSopenharmony_ci        if (iter != symbolsMap_.end()) {
98948f512ceSopenharmony_ci            return iter->second;
99048f512ceSopenharmony_ci        }
99148f512ceSopenharmony_ci        if (map == nullptr) {
99248f512ceSopenharmony_ci            return DfxSymbol(ip, "");
99348f512ceSopenharmony_ci        }
99448f512ceSopenharmony_ci        HLOGD("map ptr:%p, map name:%s", map.get(), map->name.c_str());
99548f512ceSopenharmony_ci
99648f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
99748f512ceSopenharmony_ci        if (IsAbc() && needParseJsFunc_) {
99848f512ceSopenharmony_ci            JsFunction jsFunc;
99948f512ceSopenharmony_ci            std::string module = map->name;
100048f512ceSopenharmony_ci            HLOGD("map->name module:%s", module.c_str());
100148f512ceSopenharmony_ci            auto ret = DfxArk::ParseArkFrameInfo(static_cast<uintptr_t>(ip), static_cast<uintptr_t>(map->begin),
100248f512ceSopenharmony_ci                                                 loadOffSet_, abcDataPtr_.get(), abcDataSize_,
100348f512ceSopenharmony_ci                                                 arkExtractorptr_, &jsFunc);
100448f512ceSopenharmony_ci            if (ret == -1) {
100548f512ceSopenharmony_ci                HLOGD("failed to call ParseArkFrameInfo, the symbol file is : %s", map->name.c_str());
100648f512ceSopenharmony_ci                return DfxSymbol(ip, "");
100748f512ceSopenharmony_ci            }
100848f512ceSopenharmony_ci            this->symbolsMap_.insert(std::make_pair(ip,
100948f512ceSopenharmony_ci                                                    DfxSymbol(ip,
101048f512ceSopenharmony_ci                                                    jsFunc.codeBegin,
101148f512ceSopenharmony_ci                                                    jsFunc.functionName,
101248f512ceSopenharmony_ci                                                    jsFunc.ToString(),
101348f512ceSopenharmony_ci                                                    map->name)));
101448f512ceSopenharmony_ci
101548f512ceSopenharmony_ci            DfxSymbol &foundSymbol = symbolsMap_[ip];
101648f512ceSopenharmony_ci            if (!foundSymbol.matched_) {
101748f512ceSopenharmony_ci                foundSymbol.matched_ = true;
101848f512ceSopenharmony_ci                foundSymbol.symbolFileIndex_ = id_;
101948f512ceSopenharmony_ci                matchedSymbols_.push_back(&(symbolsMap_[ip]));
102048f512ceSopenharmony_ci            }
102148f512ceSopenharmony_ci
102248f512ceSopenharmony_ci            HLOGD("ip : 0x%" PRIx64 " the symbol file is : %s, function is %s demangle_ : %s", ip,
102348f512ceSopenharmony_ci                  symbolsMap_[ip].module_.data(), jsFunc.functionName, matchedSymbols_.back()->demangle_.data());
102448f512ceSopenharmony_ci            return symbolsMap_[ip];
102548f512ceSopenharmony_ci        }
102648f512ceSopenharmony_ci#endif
102748f512ceSopenharmony_ci        DfxSymbol symbol(ip, "");
102848f512ceSopenharmony_ci        return symbol;
102948f512ceSopenharmony_ci    }
103048f512ceSopenharmony_ci};
103148f512ceSopenharmony_ci
103248f512ceSopenharmony_ciclass UnknowFileSymbols : public SymbolsFile {
103348f512ceSopenharmony_cipublic:
103448f512ceSopenharmony_ci    explicit UnknowFileSymbols(const std::string &symbolFilePath)
103548f512ceSopenharmony_ci        : SymbolsFile(SYMBOL_UNKNOW_FILE, symbolFilePath)
103648f512ceSopenharmony_ci    {
103748f512ceSopenharmony_ci    }
103848f512ceSopenharmony_ci    bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
103948f512ceSopenharmony_ci    {
104048f512ceSopenharmony_ci        symbolsLoaded_ = true;
104148f512ceSopenharmony_ci        return false;
104248f512ceSopenharmony_ci    }
104348f512ceSopenharmony_ci    ~UnknowFileSymbols() override {}
104448f512ceSopenharmony_ci};
104548f512ceSopenharmony_ci
104648f512ceSopenharmony_ciSymbolsFile::~SymbolsFile() {}
104748f512ceSopenharmony_ci
104848f512ceSopenharmony_cistd::unique_ptr<SymbolsFile> SymbolsFile::CreateSymbolsFile(SymbolsFileType symbolType,
104948f512ceSopenharmony_ci                                                            const std::string symbolFilePath, pid_t pid)
105048f512ceSopenharmony_ci{
105148f512ceSopenharmony_ci    switch (symbolType) {
105248f512ceSopenharmony_ci        case SYMBOL_KERNEL_FILE:
105348f512ceSopenharmony_ci            return std::make_unique<KernelSymbols>(symbolFilePath.empty() ? KERNEL_MMAP_NAME
105448f512ceSopenharmony_ci                                                                          : symbolFilePath);
105548f512ceSopenharmony_ci        case SYMBOL_KERNEL_MODULE_FILE:
105648f512ceSopenharmony_ci            return std::make_unique<KernelModuleSymbols>(symbolFilePath);
105748f512ceSopenharmony_ci        case SYMBOL_KERNEL_THREAD_FILE:
105848f512ceSopenharmony_ci            return std::make_unique<KernelThreadSymbols>(symbolFilePath);
105948f512ceSopenharmony_ci        case SYMBOL_ELF_FILE:
106048f512ceSopenharmony_ci            return std::make_unique<ElfFileSymbols>(symbolFilePath);
106148f512ceSopenharmony_ci        case SYMBOL_JAVA_FILE:
106248f512ceSopenharmony_ci            return std::make_unique<JavaFileSymbols>(symbolFilePath);
106348f512ceSopenharmony_ci        case SYMBOL_JS_FILE:
106448f512ceSopenharmony_ci            return std::make_unique<JSFileSymbols>(symbolFilePath);
106548f512ceSopenharmony_ci        case SYMBOL_HAP_FILE:
106648f512ceSopenharmony_ci            return std::make_unique<HapFileSymbols>(symbolFilePath, pid);
106748f512ceSopenharmony_ci        default:
106848f512ceSopenharmony_ci            return std::make_unique<SymbolsFile>(SYMBOL_UNKNOW_FILE, symbolFilePath);
106948f512ceSopenharmony_ci    }
107048f512ceSopenharmony_ci}
107148f512ceSopenharmony_ci
107248f512ceSopenharmony_cistd::unique_ptr<SymbolsFile> SymbolsFile::CreateSymbolsFile(const std::string &symbolFilePath, pid_t pid)
107348f512ceSopenharmony_ci{
107448f512ceSopenharmony_ci    // we need check file name here
107548f512ceSopenharmony_ci    if (symbolFilePath == KERNEL_MMAP_NAME) {
107648f512ceSopenharmony_ci        return SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE, symbolFilePath);
107748f512ceSopenharmony_ci    } else if (symbolFilePath == SYSMGR_FILE_NAME ||
107848f512ceSopenharmony_ci               symbolFilePath == DEVHOST_LINUX_FILE_NAME ||
107948f512ceSopenharmony_ci               StringStartsWith(symbolFilePath, DEVHOST_LINUX_PREFIX)) {
108048f512ceSopenharmony_ci        return SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_THREAD_FILE, symbolFilePath);
108148f512ceSopenharmony_ci    } else if (StringEndsWith(symbolFilePath, KERNEL_MODULES_EXT_NAME)) {
108248f512ceSopenharmony_ci        return SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_MODULE_FILE, symbolFilePath);
108348f512ceSopenharmony_ci    } else if (IsArkJsFile(symbolFilePath)) {
108448f512ceSopenharmony_ci        return SymbolsFile::CreateSymbolsFile(SYMBOL_HAP_FILE, symbolFilePath, pid);
108548f512ceSopenharmony_ci    } else {
108648f512ceSopenharmony_ci        // default is elf, this may be problematic in the future.
108748f512ceSopenharmony_ci        return SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, symbolFilePath);
108848f512ceSopenharmony_ci    }
108948f512ceSopenharmony_ci}
109048f512ceSopenharmony_ci
109148f512ceSopenharmony_civoid SymbolsFile::AdjustSymbols()
109248f512ceSopenharmony_ci{
109348f512ceSopenharmony_ci    if (symbols_.size() <= 0) {
109448f512ceSopenharmony_ci        return;
109548f512ceSopenharmony_ci    }
109648f512ceSopenharmony_ci
109748f512ceSopenharmony_ci    // order
109848f512ceSopenharmony_ci    sort(symbols_.begin(), symbols_.end(), [](const DfxSymbol& a, const DfxSymbol& b) {
109948f512ceSopenharmony_ci        return a.funcVaddr_ < b.funcVaddr_;
110048f512ceSopenharmony_ci    });
110148f512ceSopenharmony_ci    HLOGV("sort completed");
110248f512ceSopenharmony_ci
110348f512ceSopenharmony_ci    size_t fullSize = symbols_.size();
110448f512ceSopenharmony_ci    size_t erased = 0;
110548f512ceSopenharmony_ci
110648f512ceSopenharmony_ci    // Check for duplicate vaddr
110748f512ceSopenharmony_ci    auto last = std::unique(symbols_.begin(), symbols_.end(), [](const DfxSymbol &a, const DfxSymbol &b) {
110848f512ceSopenharmony_ci        return (a.funcVaddr_ == b.funcVaddr_);
110948f512ceSopenharmony_ci    });
111048f512ceSopenharmony_ci    symbols_.erase(last, symbols_.end());
111148f512ceSopenharmony_ci    erased = fullSize - symbols_.size();
111248f512ceSopenharmony_ci    HLOGV("uniqued completed");
111348f512ceSopenharmony_ci    auto it = symbols_.begin();
111448f512ceSopenharmony_ci    while (it != symbols_.end()) {
111548f512ceSopenharmony_ci        it->index_ = it - symbols_.begin();
111648f512ceSopenharmony_ci        it++;
111748f512ceSopenharmony_ci    }
111848f512ceSopenharmony_ci    HLOGV("indexed completed");
111948f512ceSopenharmony_ci
112048f512ceSopenharmony_ci    HLOG_ASSERT(symbols_.size() != 0);
112148f512ceSopenharmony_ci
112248f512ceSopenharmony_ci    if (textExecVaddrRange_ == maxVaddr) {
112348f512ceSopenharmony_ci        textExecVaddrRange_ = symbols_.back().funcVaddr_ - symbols_.front().funcVaddr_;
112448f512ceSopenharmony_ci    }
112548f512ceSopenharmony_ci
112648f512ceSopenharmony_ci    HLOGDDD("%zu symbols after adjust (%zu erased) 0x%016" PRIx64 " - 0x%016" PRIx64
112748f512ceSopenharmony_ci            " @0x%016" PRIx64 " ",
112848f512ceSopenharmony_ci            symbols_.size(), erased, symbols_.front().funcVaddr_, symbols_.back().funcVaddr_,
112948f512ceSopenharmony_ci            textExecVaddrFileOffset_);
113048f512ceSopenharmony_ci}
113148f512ceSopenharmony_ci
113248f512ceSopenharmony_civoid SymbolsFile::SortMatchedSymbols()
113348f512ceSopenharmony_ci{
113448f512ceSopenharmony_ci    if (matchedSymbols_.size() <= 1u) {
113548f512ceSopenharmony_ci        return;
113648f512ceSopenharmony_ci    }
113748f512ceSopenharmony_ci    sort(matchedSymbols_.begin(), matchedSymbols_.end(), [](const DfxSymbol* a, const DfxSymbol* b) {
113848f512ceSopenharmony_ci        if (a == nullptr || b == nullptr) {
113948f512ceSopenharmony_ci            return true;
114048f512ceSopenharmony_ci        }
114148f512ceSopenharmony_ci        return a->funcVaddr_ < b->funcVaddr_;
114248f512ceSopenharmony_ci    });
114348f512ceSopenharmony_ci}
114448f512ceSopenharmony_ci
114548f512ceSopenharmony_ciconst std::vector<DfxSymbol> &SymbolsFile::GetSymbols()
114648f512ceSopenharmony_ci{
114748f512ceSopenharmony_ci    return symbols_;
114848f512ceSopenharmony_ci}
114948f512ceSopenharmony_ci
115048f512ceSopenharmony_ciconst std::vector<DfxSymbol *> &SymbolsFile::GetMatchedSymbols()
115148f512ceSopenharmony_ci{
115248f512ceSopenharmony_ci    return matchedSymbols_;
115348f512ceSopenharmony_ci}
115448f512ceSopenharmony_ci
115548f512ceSopenharmony_ciconst DfxSymbol SymbolsFile::GetSymbolWithVaddr(uint64_t vaddrInFile)
115648f512ceSopenharmony_ci{
115748f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
115848f512ceSopenharmony_ci    const auto startTime = steady_clock::now();
115948f512ceSopenharmony_ci#endif
116048f512ceSopenharmony_ci    DfxSymbol symbol;
116148f512ceSopenharmony_ci    // it should be already order from small to large
116248f512ceSopenharmony_ci    auto found =
116348f512ceSopenharmony_ci        std::upper_bound(symbols_.begin(), symbols_.end(), vaddrInFile, DfxSymbol::ValueLessThen);
116448f512ceSopenharmony_ci    /*
116548f512ceSopenharmony_ci    if data is { 1, 2, 4, 5, 5, 6 };
116648f512ceSopenharmony_ci    upper_bound for each val :
116748f512ceSopenharmony_ci        0 < 1 at index 0
116848f512ceSopenharmony_ci        1 < 2 at index 1
116948f512ceSopenharmony_ci        2 < 4 at index 2
117048f512ceSopenharmony_ci        3 < 4 at index 2
117148f512ceSopenharmony_ci        4 < 5 at index 3
117248f512ceSopenharmony_ci        5 < 6 at index 5
117348f512ceSopenharmony_ci        6 < not found
117448f512ceSopenharmony_ci    if key symbol vaddr is { 1, 2, 4, 5, 5, 6 };
117548f512ceSopenharmony_ci     check ip vaddr for each val :
117648f512ceSopenharmony_ci       ip   sym
117748f512ceSopenharmony_ci        0   not found
117848f512ceSopenharmony_ci        1   1
117948f512ceSopenharmony_ci        1   1
118048f512ceSopenharmony_ci        2   2
118148f512ceSopenharmony_ci        3   3
118248f512ceSopenharmony_ci        4   4
118348f512ceSopenharmony_ci        5   5
118448f512ceSopenharmony_ci        6   6
118548f512ceSopenharmony_ci        7   7
118648f512ceSopenharmony_ci    */
118748f512ceSopenharmony_ci    if (found != symbols_.begin()) {
118848f512ceSopenharmony_ci        found = std::prev(found);
118948f512ceSopenharmony_ci        if (found != symbols_.end()) {
119048f512ceSopenharmony_ci            if (found->Contain(vaddrInFile)) {
119148f512ceSopenharmony_ci                found->offsetToVaddr_ = vaddrInFile - found->funcVaddr_;
119248f512ceSopenharmony_ci                if (!found->matched_) {
119348f512ceSopenharmony_ci                    found->matched_ = true;
119448f512ceSopenharmony_ci                    matchedSymbols_.push_back(&(*found));
119548f512ceSopenharmony_ci                }
119648f512ceSopenharmony_ci                symbol = *found; // copy
119748f512ceSopenharmony_ci                HLOGV("found '%s' for vaddr 0x%016" PRIx64 "", symbol.ToString().c_str(), vaddrInFile);
119848f512ceSopenharmony_ci            }
119948f512ceSopenharmony_ci        }
120048f512ceSopenharmony_ci    }
120148f512ceSopenharmony_ci
120248f512ceSopenharmony_ci    if (!symbol.IsValid()) {
120348f512ceSopenharmony_ci        HLOGV("NOT found vaddr 0x%" PRIx64 " in symbole file %s(%zu)", vaddrInFile,
120448f512ceSopenharmony_ci              filePath_.c_str(), symbols_.size());
120548f512ceSopenharmony_ci    }
120648f512ceSopenharmony_ci    symbol.fileVaddr_ = vaddrInFile;
120748f512ceSopenharmony_ci    symbol.symbolFileIndex_ = id_;
120848f512ceSopenharmony_ci
120948f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
121048f512ceSopenharmony_ci    auto usedTime = duration_cast<milliseconds>(steady_clock::now() - startTime);
121148f512ceSopenharmony_ci    if (usedTime > 1ms) {
121248f512ceSopenharmony_ci        HLOGW("cost %" PRId64 "ms to search ", usedTime.count());
121348f512ceSopenharmony_ci    }
121448f512ceSopenharmony_ci#endif
121548f512ceSopenharmony_ci    return symbol;
121648f512ceSopenharmony_ci}
121748f512ceSopenharmony_ci
121848f512ceSopenharmony_cibool SymbolsFile::CheckPathReadable(const std::string &path) const
121948f512ceSopenharmony_ci{
122048f512ceSopenharmony_ci    if (access(path.c_str(), R_OK) == 0) {
122148f512ceSopenharmony_ci        return true;
122248f512ceSopenharmony_ci    } else {
122348f512ceSopenharmony_ci        HLOGM("'%s' is unable read", path.c_str());
122448f512ceSopenharmony_ci        return false;
122548f512ceSopenharmony_ci    }
122648f512ceSopenharmony_ci}
122748f512ceSopenharmony_ci
122848f512ceSopenharmony_cibool SymbolsFile::setSymbolsFilePath(const std::vector<std::string> &symbolsSearchPaths)
122948f512ceSopenharmony_ci{
123048f512ceSopenharmony_ci    symbolsFileSearchPaths_.clear();
123148f512ceSopenharmony_ci    for (auto &symbolsSearchPath : symbolsSearchPaths) {
123248f512ceSopenharmony_ci        if (CheckPathReadable(symbolsSearchPath)) {
123348f512ceSopenharmony_ci            symbolsFileSearchPaths_.emplace_back(symbolsSearchPath);
123448f512ceSopenharmony_ci            HLOGV("'%s' is add to symbolsSearchPath", symbolsSearchPath.c_str());
123548f512ceSopenharmony_ci        }
123648f512ceSopenharmony_ci    }
123748f512ceSopenharmony_ci    return (symbolsFileSearchPaths_.size() > 0);
123848f512ceSopenharmony_ci}
123948f512ceSopenharmony_ci
124048f512ceSopenharmony_cistd::unique_ptr<SymbolsFile> SymbolsFile::LoadSymbolsFromSaved(
124148f512ceSopenharmony_ci    const SymbolFileStruct &symbolFileStruct)
124248f512ceSopenharmony_ci{
124348f512ceSopenharmony_ci    bool isHapSymbolFile = static_cast<SymbolsFileType>(symbolFileStruct.symbolType_) == SYMBOL_HAP_FILE;
124448f512ceSopenharmony_ci    HLOGD("isHapSymbolFile : %d", isHapSymbolFile);
124548f512ceSopenharmony_ci    auto symbolsFile = CreateSymbolsFile(symbolFileStruct.filePath_);
124648f512ceSopenharmony_ci
124748f512ceSopenharmony_ci    // default create elf file. but hap file need special operation.
124848f512ceSopenharmony_ci    symbolsFile->filePath_ = symbolFileStruct.filePath_;
124948f512ceSopenharmony_ci    symbolsFile->symbolFileType_ = static_cast<SymbolsFileType>(symbolFileStruct.symbolType_);
125048f512ceSopenharmony_ci    symbolsFile->textExecVaddr_ = symbolFileStruct.textExecVaddr_;
125148f512ceSopenharmony_ci    symbolsFile->textExecVaddrFileOffset_ = symbolFileStruct.textExecVaddrFileOffset_;
125248f512ceSopenharmony_ci    symbolsFile->buildId_ = symbolFileStruct.buildId_;
125348f512ceSopenharmony_ci    for (auto &symbolStruct : symbolFileStruct.symbolStructs_) {
125448f512ceSopenharmony_ci        symbolsFile->symbols_.emplace_back(symbolStruct.vaddr_, symbolStruct.len_,
125548f512ceSopenharmony_ci                                           symbolStruct.symbolName_, symbolFileStruct.filePath_);
125648f512ceSopenharmony_ci    }
125748f512ceSopenharmony_ci    symbolsFile->AdjustSymbols(); // reorder
125848f512ceSopenharmony_ci    if (isHapSymbolFile) {
125948f512ceSopenharmony_ci        for (const auto& symbol : symbolsFile->symbols_) {
126048f512ceSopenharmony_ci            symbolsFile->symbolsMap_.emplace(symbol.funcVaddr_, symbol);
126148f512ceSopenharmony_ci        }
126248f512ceSopenharmony_ci        symbolsFile->SetBoolValue(true);
126348f512ceSopenharmony_ci    }
126448f512ceSopenharmony_ci    symbolsFile->debugInfoLoadResult_ = true;
126548f512ceSopenharmony_ci    symbolsFile->symbolsLoaded_ = true; // all ready LoadFrom perf.data
126648f512ceSopenharmony_ci    HLOGV("load %zu symbol from SymbolFileStruct for file '%s'", symbolsFile->symbols_.size(),
126748f512ceSopenharmony_ci          symbolsFile->filePath_.c_str());
126848f512ceSopenharmony_ci    return symbolsFile;
126948f512ceSopenharmony_ci}
127048f512ceSopenharmony_ci
127148f512ceSopenharmony_civoid SymbolsFile::SetBoolValue(bool value)
127248f512ceSopenharmony_ci{
127348f512ceSopenharmony_ci}
127448f512ceSopenharmony_ci
127548f512ceSopenharmony_civoid SymbolsFile::ExportSymbolToFileFormat(SymbolFileStruct &symbolFileStruct)
127648f512ceSopenharmony_ci{
127748f512ceSopenharmony_ci    symbolFileStruct.filePath_ = filePath_;
127848f512ceSopenharmony_ci    symbolFileStruct.symbolType_ = symbolFileType_;
127948f512ceSopenharmony_ci    symbolFileStruct.textExecVaddr_ = textExecVaddr_;
128048f512ceSopenharmony_ci    symbolFileStruct.textExecVaddrFileOffset_ = textExecVaddrFileOffset_;
128148f512ceSopenharmony_ci    symbolFileStruct.buildId_ = buildId_;
128248f512ceSopenharmony_ci
128348f512ceSopenharmony_ci    SortMatchedSymbols();
128448f512ceSopenharmony_ci    auto symbols = GetMatchedSymbols();
128548f512ceSopenharmony_ci    symbolFileStruct.symbolStructs_.reserve(symbols.size());
128648f512ceSopenharmony_ci    for (const auto symbol : symbols) {
128748f512ceSopenharmony_ci        auto &symbolStruct = symbolFileStruct.symbolStructs_.emplace_back();
128848f512ceSopenharmony_ci        symbolStruct.vaddr_ = symbol->funcVaddr_;
128948f512ceSopenharmony_ci        symbolStruct.len_ = symbol->size_;
129048f512ceSopenharmony_ci        symbolStruct.symbolName_ = symbol->GetName();
129148f512ceSopenharmony_ci    }
129248f512ceSopenharmony_ci
129348f512ceSopenharmony_ci    HLOGV("export %zu symbol to SymbolFileStruct from %s", symbolFileStruct.symbolStructs_.size(),
129448f512ceSopenharmony_ci          filePath_.c_str());
129548f512ceSopenharmony_ci}
129648f512ceSopenharmony_ci
129748f512ceSopenharmony_ciuint64_t SymbolsFile::GetVaddrInSymbols(uint64_t ip, uint64_t mapStart, uint64_t mapOffset) const
129848f512ceSopenharmony_ci{
129948f512ceSopenharmony_ci    // no convert
130048f512ceSopenharmony_ci    return ip;
130148f512ceSopenharmony_ci}
130248f512ceSopenharmony_ci
130348f512ceSopenharmony_civoid SymbolsFile::AddSymbol(DfxSymbol symbol)
130448f512ceSopenharmony_ci{
130548f512ceSopenharmony_ci    symbolsLoaded_ = true;
130648f512ceSopenharmony_ci    symbols_.emplace_back(symbol);
130748f512ceSopenharmony_ci}
130848f512ceSopenharmony_ci} // namespace HiPerf
130948f512ceSopenharmony_ci} // namespace Developtools
131048f512ceSopenharmony_ci} // namespace OHOS
1311