106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci#define HILOG_TAG "Runtime"
1606f6ba60Sopenharmony_ci
1706f6ba60Sopenharmony_ci#include "virtual_runtime.h"
1806f6ba60Sopenharmony_ci
1906f6ba60Sopenharmony_ci#include <cinttypes>
2006f6ba60Sopenharmony_ci#include <iostream>
2106f6ba60Sopenharmony_ci#include <sstream>
2206f6ba60Sopenharmony_ci#include <unistd.h>
2306f6ba60Sopenharmony_ci#if !is_mingw
2406f6ba60Sopenharmony_ci#include <sys/mman.h>
2506f6ba60Sopenharmony_ci#endif
2606f6ba60Sopenharmony_ci
2706f6ba60Sopenharmony_ci#include "dfx_maps.h"
2806f6ba60Sopenharmony_ci#include "register.h"
2906f6ba60Sopenharmony_ci#include "symbols_file.h"
3006f6ba60Sopenharmony_ci#include "utilities.h"
3106f6ba60Sopenharmony_ci
3206f6ba60Sopenharmony_ciusing namespace std::chrono;
3306f6ba60Sopenharmony_cinamespace OHOS {
3406f6ba60Sopenharmony_cinamespace Developtools {
3506f6ba60Sopenharmony_cinamespace NativeDaemon {
3606f6ba60Sopenharmony_cinamespace {
3706f6ba60Sopenharmony_cistd::atomic<uint64_t> callStackErrCnt = 0;
3806f6ba60Sopenharmony_ciconstexpr uint32_t CALL_STACK_ERROR_TIMES = 10;
3906f6ba60Sopenharmony_ciconstexpr uint32_t SYMBOL_FILES_SIZE = 512;
4006f6ba60Sopenharmony_ciconstexpr uint32_t SECOND_INDEX = 2;
4106f6ba60Sopenharmony_ciconstexpr uint32_t THIRD_INDEX = 3;
4206f6ba60Sopenharmony_ciconstexpr uint32_t INFO_SIZE = 4;
4306f6ba60Sopenharmony_ci}
4406f6ba60Sopenharmony_ci// we unable to access 'swapper' from /proc/0/
4506f6ba60Sopenharmony_civoid VirtualRuntime::ClearMaps()
4606f6ba60Sopenharmony_ci{
4706f6ba60Sopenharmony_ci    processMaps_.clear();
4806f6ba60Sopenharmony_ci}
4906f6ba60Sopenharmony_ci
5006f6ba60Sopenharmony_ciVirtualRuntime::VirtualRuntime(const NativeHookConfig& hookConfig): hookConfig_(hookConfig)
5106f6ba60Sopenharmony_ci{
5206f6ba60Sopenharmony_ci    symbolsFiles_.reserve(SYMBOL_FILES_SIZE);
5306f6ba60Sopenharmony_ci    if (!hookConfig_.offline_symbolization()) {
5406f6ba60Sopenharmony_ci        userSymbolCache_.reserve(USER_SYMBOL_CACHE_LIMIT);
5506f6ba60Sopenharmony_ci    }
5606f6ba60Sopenharmony_ci}
5706f6ba60Sopenharmony_ci
5806f6ba60Sopenharmony_ciVirtualRuntime::~VirtualRuntime()
5906f6ba60Sopenharmony_ci{
6006f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "%s:%d UserSymbolCache size = %zu", __func__, __LINE__, userSymbolCache_.size());
6106f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "Total number of call stack errors: %" PRIu64 "", callStackErrCnt.load());
6206f6ba60Sopenharmony_ci    ClearMaps();
6306f6ba60Sopenharmony_ci}
6406f6ba60Sopenharmony_ci
6506f6ba60Sopenharmony_cistd::string VirtualRuntime::ReadThreadName(pid_t tid)
6606f6ba60Sopenharmony_ci{
6706f6ba60Sopenharmony_ci    std::string comm = ReadFileToString(StringPrintf("/proc/%d/comm", tid)).c_str();
6806f6ba60Sopenharmony_ci    comm.erase(std::remove(comm.begin(), comm.end(), '\r'), comm.end());
6906f6ba60Sopenharmony_ci    comm.erase(std::remove(comm.begin(), comm.end(), '\n'), comm.end());
7006f6ba60Sopenharmony_ci    return comm;
7106f6ba60Sopenharmony_ci}
7206f6ba60Sopenharmony_ci
7306f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::UpdateThread(pid_t pid, pid_t tid, const std::string name)
7406f6ba60Sopenharmony_ci{
7506f6ba60Sopenharmony_ci    pid_ = pid;
7606f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
7706f6ba60Sopenharmony_ci    const auto startTime = steady_clock::now();
7806f6ba60Sopenharmony_ci#endif
7906f6ba60Sopenharmony_ci    VirtualThread &thread = GetThread(pid, tid);
8006f6ba60Sopenharmony_ci    if (!name.empty()) {
8106f6ba60Sopenharmony_ci        thread.name_ = name;
8206f6ba60Sopenharmony_ci    }
8306f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
8406f6ba60Sopenharmony_ci    updateThreadTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime);
8506f6ba60Sopenharmony_ci#endif
8606f6ba60Sopenharmony_ci    return thread;
8706f6ba60Sopenharmony_ci}
8806f6ba60Sopenharmony_ci
8906f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::CreateThread(pid_t pid, pid_t tid)
9006f6ba60Sopenharmony_ci{
9106f6ba60Sopenharmony_ci    // make a new one
9206f6ba60Sopenharmony_ci    userSpaceThreadMap_.emplace(std::piecewise_construct, std::forward_as_tuple(tid),
9306f6ba60Sopenharmony_ci                                std::forward_as_tuple(pid, tid, symbolsFiles_, this));
9406f6ba60Sopenharmony_ci    VirtualThread& thr = userSpaceThreadMap_.at(tid);
9506f6ba60Sopenharmony_ci    return thr;
9606f6ba60Sopenharmony_ci}
9706f6ba60Sopenharmony_ci
9806f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::GetThread(pid_t pid, pid_t tid)
9906f6ba60Sopenharmony_ci{
10006f6ba60Sopenharmony_ci    HLOGV("find thread %u:%u", pid, tid);
10106f6ba60Sopenharmony_ci    auto it = userSpaceThreadMap_.find(tid);
10206f6ba60Sopenharmony_ci    if (it == userSpaceThreadMap_.end()) {
10306f6ba60Sopenharmony_ci        // we also need thread
10406f6ba60Sopenharmony_ci        VirtualThread& thr = CreateThread(pid, tid);
10506f6ba60Sopenharmony_ci        return thr;
10606f6ba60Sopenharmony_ci    } else {
10706f6ba60Sopenharmony_ci        VirtualThread& thr = it->second;
10806f6ba60Sopenharmony_ci        return thr;
10906f6ba60Sopenharmony_ci    }
11006f6ba60Sopenharmony_ci}
11106f6ba60Sopenharmony_ci
11206f6ba60Sopenharmony_civoid VirtualRuntime::MakeCallFrame(DfxSymbol &symbol, CallFrame &callFrame)
11306f6ba60Sopenharmony_ci{
11406f6ba60Sopenharmony_ci    callFrame.vaddrInFile_ = symbol.funcVaddr_;
11506f6ba60Sopenharmony_ci    callFrame.symbolName_ = symbol.symbolName_;
11606f6ba60Sopenharmony_ci    callFrame.symbolIndex_ = symbol.index_;
11706f6ba60Sopenharmony_ci    callFrame.filePath_ = symbol.module_.empty() ? symbol.comm_ : symbol.module_;
11806f6ba60Sopenharmony_ci    callFrame.symbolOffset_ = symbol.offset_;
11906f6ba60Sopenharmony_ci    callFrame.callFrameId_ = symbol.symbolId_;
12006f6ba60Sopenharmony_ci    callFrame.symbolNameId_ = symbol.symbolNameId_;
12106f6ba60Sopenharmony_ci    callFrame.filePathId_ = symbol.filePathId_;
12206f6ba60Sopenharmony_ci    if (symbol.funcVaddr_ != 0) {
12306f6ba60Sopenharmony_ci        callFrame.offset_ = symbol.funcVaddr_;
12406f6ba60Sopenharmony_ci    } else {
12506f6ba60Sopenharmony_ci        callFrame.offset_ = callFrame.ip_;
12606f6ba60Sopenharmony_ci    }
12706f6ba60Sopenharmony_ci}
12806f6ba60Sopenharmony_ci
12906f6ba60Sopenharmony_cibool VirtualRuntime::GetSymbolName(pid_t pid, pid_t tid, std::vector<CallFrame>& callFrames, int offset, bool first,
13006f6ba60Sopenharmony_ci                                   bool onlyjs)
13106f6ba60Sopenharmony_ci{
13206f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
13306f6ba60Sopenharmony_ci    const auto startTime = steady_clock::now();
13406f6ba60Sopenharmony_ci#endif
13506f6ba60Sopenharmony_ci    // Symbolic the Call Stack
13606f6ba60Sopenharmony_ci    HLOGV("total %zu frames", callFrames.size());
13706f6ba60Sopenharmony_ci
13806f6ba60Sopenharmony_ci    perf_callchain_context perfCallchainContext = PERF_CONTEXT_MAX;
13906f6ba60Sopenharmony_ci    for (auto callFrameIt = callFrames.begin() + offset; callFrameIt != callFrames.end(); ++callFrameIt) {
14006f6ba60Sopenharmony_ci        auto &callFrame = callFrameIt.operator*();
14106f6ba60Sopenharmony_ci        if (onlyjs && !callFrame.isJsFrame_) {
14206f6ba60Sopenharmony_ci           // only symbolize arkts frame
14306f6ba60Sopenharmony_ci            continue;
14406f6ba60Sopenharmony_ci        }
14506f6ba60Sopenharmony_ci        if (callFrame.ip_ >= PERF_CONTEXT_MAX) {
14606f6ba60Sopenharmony_ci            // dont care, this is not issue.
14706f6ba60Sopenharmony_ci            HLOGV("%s", UpdatePerfContext(callFrame.ip_, perfCallchainContext).c_str());
14806f6ba60Sopenharmony_ci            continue;
14906f6ba60Sopenharmony_ci        }
15006f6ba60Sopenharmony_ci        auto symbol = GetSymbol(callFrame, pid, tid,
15106f6ba60Sopenharmony_ci            perfCallchainContext);
15206f6ba60Sopenharmony_ci        if (symbol.IsValid()) {
15306f6ba60Sopenharmony_ci            MakeCallFrame(symbol, callFrame);
15406f6ba60Sopenharmony_ci        } else {
15506f6ba60Sopenharmony_ci#ifdef TRY_UNWIND_TWICE
15606f6ba60Sopenharmony_ci            if (first) {
15706f6ba60Sopenharmony_ci                if (failedIPs_.find(callFrame.ip_) == failedIPs_.end()) {
15806f6ba60Sopenharmony_ci                    return false;
15906f6ba60Sopenharmony_ci                } else {
16006f6ba60Sopenharmony_ci                    callFrames.erase(callFrameIt, callFrames.end());
16106f6ba60Sopenharmony_ci                    return true;
16206f6ba60Sopenharmony_ci                }
16306f6ba60Sopenharmony_ci            } else {
16406f6ba60Sopenharmony_ci                failedIPs_.insert(callFrame.ip_);
16506f6ba60Sopenharmony_ci                callFrames.erase(callFrameIt, callFrames.end());
16606f6ba60Sopenharmony_ci                return true;
16706f6ba60Sopenharmony_ci            }
16806f6ba60Sopenharmony_ci#else
16906f6ba60Sopenharmony_ci            ++callStackErrCnt;
17006f6ba60Sopenharmony_ci            if (callStackErrCnt.load() % CALL_STACK_ERROR_TIMES == 0) {
17106f6ba60Sopenharmony_ci                PROFILER_LOG_DEBUG(LOG_CORE, "number of call stack errors: %" PRIu64 "", callStackErrCnt.load());
17206f6ba60Sopenharmony_ci            }
17306f6ba60Sopenharmony_ci            if (callFrames.back().isJsFrame_) { //The fp mode js call stack is behind the native
17406f6ba60Sopenharmony_ci            //call stack, so it can't be deleted entirely
17506f6ba60Sopenharmony_ci                callFrameIt = callFrames.erase(callFrameIt);
17606f6ba60Sopenharmony_ci                --callFrameIt;
17706f6ba60Sopenharmony_ci                continue;
17806f6ba60Sopenharmony_ci            }
17906f6ba60Sopenharmony_ci            callFrames.erase(callFrameIt, callFrames.end());
18006f6ba60Sopenharmony_ci            return true;
18106f6ba60Sopenharmony_ci#endif
18206f6ba60Sopenharmony_ci        }
18306f6ba60Sopenharmony_ci        int index = callFrameIt - callFrames.begin();
18406f6ba60Sopenharmony_ci        HLOGV(" (%u)unwind symbol: %*s%s", index, index, "", callFrame.ToSymbolString().c_str());
18506f6ba60Sopenharmony_ci    }
18606f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
18706f6ba60Sopenharmony_ci    auto usedTime = duration_cast<microseconds>(steady_clock::now() - startTime);
18806f6ba60Sopenharmony_ci    if (usedTime.count() != 0) {
18906f6ba60Sopenharmony_ci        HLOGV("cost %0.3f ms to symbolic ", usedTime.count() / MS_DUARTION);
19006f6ba60Sopenharmony_ci    }
19106f6ba60Sopenharmony_ci    symbolicRecordTimes_ += usedTime;
19206f6ba60Sopenharmony_ci#endif
19306f6ba60Sopenharmony_ci    return true;
19406f6ba60Sopenharmony_ci}
19506f6ba60Sopenharmony_ci
19606f6ba60Sopenharmony_civoid VirtualRuntime::UpdateMaps(pid_t pid, pid_t tid)
19706f6ba60Sopenharmony_ci{
19806f6ba60Sopenharmony_ci    auto &thread = UpdateThread(pid, tid);
19906f6ba60Sopenharmony_ci    if (thread.ParseMap(processMaps_, true)) {
20006f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "voluntarily update maps succeed");
20106f6ba60Sopenharmony_ci    } else {
20206f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "voluntarily update maps ignore");
20306f6ba60Sopenharmony_ci    }
20406f6ba60Sopenharmony_ci}
20506f6ba60Sopenharmony_ci
20606f6ba60Sopenharmony_cibool VirtualRuntime::UnwindStack(std::vector<u64>& regs,
20706f6ba60Sopenharmony_ci                                 const u8* stack_addr,
20806f6ba60Sopenharmony_ci                                 int stack_size,
20906f6ba60Sopenharmony_ci                                 pid_t pid,
21006f6ba60Sopenharmony_ci                                 pid_t tid,
21106f6ba60Sopenharmony_ci                                 std::vector<CallFrame>& callFrames,
21206f6ba60Sopenharmony_ci                                 size_t maxStackLevel)
21306f6ba60Sopenharmony_ci{
21406f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
21506f6ba60Sopenharmony_ci    const auto startTime = steady_clock::now();
21606f6ba60Sopenharmony_ci#endif
21706f6ba60Sopenharmony_ci    // if we have userstack ?
21806f6ba60Sopenharmony_ci    int offset = 0;
21906f6ba60Sopenharmony_ci    auto &thread = UpdateThread(pid, tid);
22006f6ba60Sopenharmony_ci    if (stack_size > 0) {
22106f6ba60Sopenharmony_ci        callstack_.UnwindCallStack(thread, &regs[0], regs.size(), stack_addr, stack_size, callFrames, maxStackLevel,
22206f6ba60Sopenharmony_ci            hookConfig_.js_stack_report() > 0 ? hookConfig_.max_js_stack_depth() : 0,
22306f6ba60Sopenharmony_ci            hookConfig_.js_stack_report() > 0);
22406f6ba60Sopenharmony_ci        if (callFrames.size() <= FILTER_STACK_DEPTH) {
22506f6ba60Sopenharmony_ci            callFrames.clear();
22606f6ba60Sopenharmony_ci            return false;
22706f6ba60Sopenharmony_ci        }
22806f6ba60Sopenharmony_ci        // Do not symbolize the first two frame, cause the two frame implement by tool itself
22906f6ba60Sopenharmony_ci        offset = FILTER_STACK_DEPTH;
23006f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
23106f6ba60Sopenharmony_ci        unwindCallStackTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime);
23206f6ba60Sopenharmony_ci#endif
23306f6ba60Sopenharmony_ci    }
23406f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
23506f6ba60Sopenharmony_ci    unwindFromRecordTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime);
23606f6ba60Sopenharmony_ci#endif
23706f6ba60Sopenharmony_ci    if (hookConfig_.offline_symbolization()) {
23806f6ba60Sopenharmony_ci        // only get js symbol if report js frame and offline symbolization for dwarf mode
23906f6ba60Sopenharmony_ci        if (hookConfig_.js_stack_report() > 0 && !hookConfig_.fp_unwind()) {
24006f6ba60Sopenharmony_ci            GetSymbolName(pid, tid, callFrames, offset, true, true);
24106f6ba60Sopenharmony_ci        }
24206f6ba60Sopenharmony_ci        return true;
24306f6ba60Sopenharmony_ci    }
24406f6ba60Sopenharmony_ci    if (!GetSymbolName(pid, tid, callFrames, offset, true)) {
24506f6ba60Sopenharmony_ci#ifdef TRY_UNWIND_TWICE
24606f6ba60Sopenharmony_ci        HLOGD("clear and unwind one more time");
24706f6ba60Sopenharmony_ci        if (!thread.ParseMap(processMaps_, true)) {
24806f6ba60Sopenharmony_ci            GetSymbolName(pid, tid, callFrames, offset, false);
24906f6ba60Sopenharmony_ci            return false;
25006f6ba60Sopenharmony_ci        }
25106f6ba60Sopenharmony_ci        if (stack_size > 0) {
25206f6ba60Sopenharmony_ci            callFrames.clear();
25306f6ba60Sopenharmony_ci            callstack_.UnwindCallStack(thread, &regs[0], regs.size(), stack_addr,
25406f6ba60Sopenharmony_ci                stack_size, callFrames, maxStackLevel, 0, hookConfig_.js_stack_report() > 0);
25506f6ba60Sopenharmony_ci        }
25606f6ba60Sopenharmony_ci        if (callFrames.size() <= FILTER_STACK_DEPTH) {
25706f6ba60Sopenharmony_ci            callFrames.clear();
25806f6ba60Sopenharmony_ci            return false;
25906f6ba60Sopenharmony_ci        }
26006f6ba60Sopenharmony_ci        if (!GetSymbolName(pid, tid, callFrames, offset, false)) {
26106f6ba60Sopenharmony_ci            return false;
26206f6ba60Sopenharmony_ci        }
26306f6ba60Sopenharmony_ci#endif
26406f6ba60Sopenharmony_ci    }
26506f6ba60Sopenharmony_ci    return true;
26606f6ba60Sopenharmony_ci}
26706f6ba60Sopenharmony_ci
26806f6ba60Sopenharmony_cibool VirtualRuntime::IsSymbolExist(const std::string& fileName)
26906f6ba60Sopenharmony_ci{
27006f6ba60Sopenharmony_ci    if (symbolsFiles_.find(fileName) != symbolsFiles_.end()) {
27106f6ba60Sopenharmony_ci        HLOGV("already have '%s'", fileName.c_str());
27206f6ba60Sopenharmony_ci        return true;
27306f6ba60Sopenharmony_ci    }
27406f6ba60Sopenharmony_ci    return false;
27506f6ba60Sopenharmony_ci}
27606f6ba60Sopenharmony_ci
27706f6ba60Sopenharmony_civoid VirtualRuntime::DelSymbolFile(const std::string& fileName)
27806f6ba60Sopenharmony_ci{
27906f6ba60Sopenharmony_ci    symbolsFiles_.erase(fileName);
28006f6ba60Sopenharmony_ci}
28106f6ba60Sopenharmony_ci
28206f6ba60Sopenharmony_civoid VirtualRuntime::UpdateSymbols(std::string fileName, std::shared_ptr<DfxMap> map)
28306f6ba60Sopenharmony_ci{
28406f6ba60Sopenharmony_ci    HLOGD("try to find symbols for file: %s", fileName.c_str());
28506f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
28606f6ba60Sopenharmony_ci    const auto startTime = steady_clock::now();
28706f6ba60Sopenharmony_ci#endif
28806f6ba60Sopenharmony_ci    if (symbolsFiles_.find(fileName) != symbolsFiles_.end()) {
28906f6ba60Sopenharmony_ci        HLOGV("already have '%s'", fileName.c_str());
29006f6ba60Sopenharmony_ci        return;
29106f6ba60Sopenharmony_ci    }
29206f6ba60Sopenharmony_ci
29306f6ba60Sopenharmony_ci    // found it by name
29406f6ba60Sopenharmony_ci    auto symbolsFile = SymbolsFile::CreateSymbolsFile(fileName, pid_);
29506f6ba60Sopenharmony_ci    symbolsFile->SetMapsInfo(map);
29606f6ba60Sopenharmony_ci    // set sybol path If it exists
29706f6ba60Sopenharmony_ci    if (symbolsPaths_.size() > 0) {
29806f6ba60Sopenharmony_ci        symbolsFile->setSymbolsFilePath(symbolsPaths_); // also load from search path
29906f6ba60Sopenharmony_ci    }
30006f6ba60Sopenharmony_ci    if (loadSymboleWhenNeeded_) {
30106f6ba60Sopenharmony_ci        // load it when we need it
30206f6ba60Sopenharmony_ci        symbolsFiles_[symbolsFile->filePath_] = std::move(symbolsFile);
30306f6ba60Sopenharmony_ci    } else if (symbolsFile->LoadSymbols()) {
30406f6ba60Sopenharmony_ci        symbolsFiles_[symbolsFile->filePath_] = std::move(symbolsFile);
30506f6ba60Sopenharmony_ci    } else {
30606f6ba60Sopenharmony_ci        HLOGW("symbols file for '%s' not found.", fileName.c_str());
30706f6ba60Sopenharmony_ci    }
30806f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME
30906f6ba60Sopenharmony_ci    auto usedTime = duration_cast<microseconds>(steady_clock::now() - startTime);
31006f6ba60Sopenharmony_ci    if (usedTime.count() != 0) {
31106f6ba60Sopenharmony_ci        HLOGV("cost %0.3f ms to load '%s'", usedTime.count() / MS_DUARTION, fileName.c_str());
31206f6ba60Sopenharmony_ci    }
31306f6ba60Sopenharmony_ci    updateSymbolsTimes_ += usedTime;
31406f6ba60Sopenharmony_ci#endif
31506f6ba60Sopenharmony_ci}
31606f6ba60Sopenharmony_ci
31706f6ba60Sopenharmony_cibool VirtualRuntime::UpdateHapSymbols(std::shared_ptr<DfxMap> map)
31806f6ba60Sopenharmony_ci{
31906f6ba60Sopenharmony_ci    auto symbolsFile = SymbolsFile::CreateSymbolsFile(map->name);
32006f6ba60Sopenharmony_ci    if (symbolsFile == nullptr) {
32106f6ba60Sopenharmony_ci        HLOGV("Failed to load CreateSymbolsFile for exec section in hap(%s)", map->name.c_str());
32206f6ba60Sopenharmony_ci        return false;
32306f6ba60Sopenharmony_ci    }
32406f6ba60Sopenharmony_ci    symbolsFile->SetMapsInfo(map);
32506f6ba60Sopenharmony_ci    // update maps name if load debuginfo successfully
32606f6ba60Sopenharmony_ci    if (!symbolsFile->LoadDebugInfo(map)) {
32706f6ba60Sopenharmony_ci        HLOGV("Failed to load debuginfo for exec section in hap(%s)", map->name.c_str());
32806f6ba60Sopenharmony_ci        return false;
32906f6ba60Sopenharmony_ci    }
33006f6ba60Sopenharmony_ci
33106f6ba60Sopenharmony_ci    if (!loadSymboleWhenNeeded_) {
33206f6ba60Sopenharmony_ci        symbolsFile->LoadSymbols(map);
33306f6ba60Sopenharmony_ci    }
33406f6ba60Sopenharmony_ci    symbolsFiles_[symbolsFile->filePath_] = (std::move(symbolsFile));
33506f6ba60Sopenharmony_ci    return true;
33606f6ba60Sopenharmony_ci}
33706f6ba60Sopenharmony_ci
33806f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetKernelSymbol(uint64_t ip, const std::vector<std::shared_ptr<DfxMap>> &maps,
33906f6ba60Sopenharmony_ci                                                const VirtualThread &thread)
34006f6ba60Sopenharmony_ci{
34106f6ba60Sopenharmony_ci    DfxSymbol vaddrSymbol(ip, thread.name_);
34206f6ba60Sopenharmony_ci    for (auto &map : maps) {
34306f6ba60Sopenharmony_ci        if (ip > map->begin && ip < map->end) {
34406f6ba60Sopenharmony_ci            HLOGM("found addr 0x%" PRIx64 " in kernel map 0x%" PRIx64 " - 0x%" PRIx64 " from %s",
34506f6ba60Sopenharmony_ci                  ip, map->begin, map->end, map->name.c_str());
34606f6ba60Sopenharmony_ci            vaddrSymbol.module_ = map->name;
34706f6ba60Sopenharmony_ci            // found symbols by file name
34806f6ba60Sopenharmony_ci            auto search = symbolsFiles_.find(map->name);
34906f6ba60Sopenharmony_ci            if (search != symbolsFiles_.end()) {
35006f6ba60Sopenharmony_ci                auto& symbolsFile = search->second;
35106f6ba60Sopenharmony_ci                vaddrSymbol.fileVaddr_ =
35206f6ba60Sopenharmony_ci                        symbolsFile->GetVaddrInSymbols(ip, map->begin, map->offset);
35306f6ba60Sopenharmony_ci                HLOGV("found symbol vaddr 0x%" PRIx64 " for runtime vaddr 0x%" PRIx64
35406f6ba60Sopenharmony_ci                        " at '%s'",
35506f6ba60Sopenharmony_ci                        vaddrSymbol.fileVaddr_, ip, map->name.c_str());
35606f6ba60Sopenharmony_ci                if (!symbolsFile->SymbolsLoaded()) {
35706f6ba60Sopenharmony_ci                    symbolsFile->LoadSymbols(map);
35806f6ba60Sopenharmony_ci                }
35906f6ba60Sopenharmony_ci                DfxSymbol foundSymbols = symbolsFile->GetSymbolWithVaddr(vaddrSymbol.fileVaddr_);
36006f6ba60Sopenharmony_ci                foundSymbols.taskVaddr_ = ip;
36106f6ba60Sopenharmony_ci                if (!foundSymbols.IsValid()) {
36206f6ba60Sopenharmony_ci                    HLOGW("addr 0x%" PRIx64 " vaddr  0x%" PRIx64 " NOT found in symbol file %s",
36306f6ba60Sopenharmony_ci                            ip, vaddrSymbol.fileVaddr_, map->name.c_str());
36406f6ba60Sopenharmony_ci                    return vaddrSymbol;
36506f6ba60Sopenharmony_ci                } else {
36606f6ba60Sopenharmony_ci                    return foundSymbols;
36706f6ba60Sopenharmony_ci                }
36806f6ba60Sopenharmony_ci            }
36906f6ba60Sopenharmony_ci            HLOGW("addr 0x%" PRIx64 " in map but NOT found the symbol file %s", ip,
37006f6ba60Sopenharmony_ci                  map->name.c_str());
37106f6ba60Sopenharmony_ci        } else {
37206f6ba60Sopenharmony_ci            HLOGM("addr 0x%" PRIx64 " not in map 0x%" PRIx64 " - 0x%" PRIx64 " from %s", ip,
37306f6ba60Sopenharmony_ci                  map->begin, map->end, map->name.c_str());
37406f6ba60Sopenharmony_ci        }
37506f6ba60Sopenharmony_ci    }
37606f6ba60Sopenharmony_ci    return vaddrSymbol;
37706f6ba60Sopenharmony_ci}
37806f6ba60Sopenharmony_ci
37906f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetUserSymbol(uint64_t ip, const VirtualThread &thread)
38006f6ba60Sopenharmony_ci{
38106f6ba60Sopenharmony_ci    DfxSymbol vaddrSymbol(ip, thread.name_);
38206f6ba60Sopenharmony_ci    auto [curMaps, itemIndex] = FindMap(ip);
38306f6ba60Sopenharmony_ci    if (curMaps != nullptr) {
38406f6ba60Sopenharmony_ci        auto symbolsFilesIter = symbolsFiles_.find((curMaps->GetMaps())[itemIndex]->name);
38506f6ba60Sopenharmony_ci        if (symbolsFilesIter != symbolsFiles_.end()) {
38606f6ba60Sopenharmony_ci            auto symbolsFile = symbolsFilesIter->second.get();
38706f6ba60Sopenharmony_ci            symbolsFile->LoadDebugInfo((curMaps->GetMaps())[itemIndex]);
38806f6ba60Sopenharmony_ci            vaddrSymbol.fileVaddr_ =
38906f6ba60Sopenharmony_ci                symbolsFile->GetVaddrInSymbols(ip, (curMaps->GetMaps())[itemIndex]->begin,
39006f6ba60Sopenharmony_ci                                               (curMaps->GetMaps())[itemIndex]->offset);
39106f6ba60Sopenharmony_ci            vaddrSymbol.module_ = (curMaps->GetMaps())[itemIndex]->name;
39206f6ba60Sopenharmony_ci            vaddrSymbol.symbolName_ = vaddrSymbol.GetName();
39306f6ba60Sopenharmony_ci            if (!symbolsFile->SymbolsLoaded()) {
39406f6ba60Sopenharmony_ci                symbolsFile->LoadSymbols((curMaps->GetMaps())[itemIndex]);
39506f6ba60Sopenharmony_ci            }
39606f6ba60Sopenharmony_ci
39706f6ba60Sopenharmony_ci            DfxSymbol foundSymbols;
39806f6ba60Sopenharmony_ci
39906f6ba60Sopenharmony_ci            if (!symbolsFile->IsAbc()) {
40006f6ba60Sopenharmony_ci                foundSymbols = symbolsFile->GetSymbolWithVaddr(vaddrSymbol.fileVaddr_);
40106f6ba60Sopenharmony_ci            } else {
40206f6ba60Sopenharmony_ci                HLOGD("symbolsFile:%s is ABC :%d", symbolsFile->filePath_.c_str(), symbolsFile->IsAbc());
40306f6ba60Sopenharmony_ci                foundSymbols = symbolsFile->GetSymbolWithPcAndMap(ip, curMaps->GetMaps()[itemIndex]);
40406f6ba60Sopenharmony_ci            }
40506f6ba60Sopenharmony_ci            foundSymbols.taskVaddr_ = ip;
40606f6ba60Sopenharmony_ci            foundSymbols.symbolName_ = foundSymbols.GetName();
40706f6ba60Sopenharmony_ci            if (!foundSymbols.IsValid()) {
40806f6ba60Sopenharmony_ci                vaddrSymbol.filePathId_ = curMaps->filePathId_;
40906f6ba60Sopenharmony_ci                return vaddrSymbol;
41006f6ba60Sopenharmony_ci            } else {
41106f6ba60Sopenharmony_ci                foundSymbols.filePathId_ = curMaps->filePathId_;
41206f6ba60Sopenharmony_ci                return foundSymbols;
41306f6ba60Sopenharmony_ci            }
41406f6ba60Sopenharmony_ci        } else {
41506f6ba60Sopenharmony_ci            HLOGW("addr 0x%" PRIx64 " in map but NOT found the symbol file %s", ip,
41606f6ba60Sopenharmony_ci                  curMaps->name_.c_str());
41706f6ba60Sopenharmony_ci        }
41806f6ba60Sopenharmony_ci    } else {
41906f6ba60Sopenharmony_ci        HLOGW("ReportVaddrMapMiss");
42006f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG
42106f6ba60Sopenharmony_ci        thread.ReportVaddrMapMiss(ip);
42206f6ba60Sopenharmony_ci#endif
42306f6ba60Sopenharmony_ci    }
42406f6ba60Sopenharmony_ci    return vaddrSymbol;
42506f6ba60Sopenharmony_ci}
42606f6ba60Sopenharmony_ci
42706f6ba60Sopenharmony_cibool VirtualRuntime::GetSymbolCache(uint64_t ip, DfxSymbol &symbol, const VirtualThread &thread)
42806f6ba60Sopenharmony_ci{
42906f6ba60Sopenharmony_ci    auto [curMaps, itemIndex] = FindMap(ip);
43006f6ba60Sopenharmony_ci    if (curMaps != nullptr) {
43106f6ba60Sopenharmony_ci        auto foundSymbolIter = userSymbolCache_.find(std::pair(ip, curMaps->filePathId_));
43206f6ba60Sopenharmony_ci        if (foundSymbolIter != userSymbolCache_.end()) {
43306f6ba60Sopenharmony_ci            symbol = foundSymbolIter->second;
43406f6ba60Sopenharmony_ci            return true;
43506f6ba60Sopenharmony_ci        }
43606f6ba60Sopenharmony_ci    }
43706f6ba60Sopenharmony_ci    return false;
43806f6ba60Sopenharmony_ci}
43906f6ba60Sopenharmony_ci
44006f6ba60Sopenharmony_civoid VirtualRuntime::UpdateSymbolCache(uint64_t ip, DfxSymbol &symbol,
44106f6ba60Sopenharmony_ci    HashList<uint64_t, DfxSymbol> &cache)
44206f6ba60Sopenharmony_ci{
44306f6ba60Sopenharmony_ci    // review change to LRU for memmory
44406f6ba60Sopenharmony_ci    HLOG_ASSERT_MESSAGE(cache.count(ip) == 0, "already have cached ip 0x%" PRIx64 "", ip);
44506f6ba60Sopenharmony_ci    cache[ip] = symbol;
44606f6ba60Sopenharmony_ci}
44706f6ba60Sopenharmony_ci
44806f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetSymbol(CallFrame& callFrame, pid_t pid, pid_t tid,
44906f6ba60Sopenharmony_ci                                          const perf_callchain_context &context)
45006f6ba60Sopenharmony_ci{
45106f6ba60Sopenharmony_ci    HLOGM("try find tid %u ip 0x%" PRIx64 " in %zu symbolsFiles ", tid, callFrame.ip_, symbolsFiles_.size());
45206f6ba60Sopenharmony_ci    DfxSymbol symbol;
45306f6ba60Sopenharmony_ci    if (hookConfig_.fp_unwind() && callFrame.isJsFrame_) {
45406f6ba60Sopenharmony_ci        if (ArktsGetSymbolCache(callFrame, symbol)) {
45506f6ba60Sopenharmony_ci            return symbol;
45606f6ba60Sopenharmony_ci        } else {
45706f6ba60Sopenharmony_ci            symbol.filePathId_ = FillArkTsFilePath(callFrame.filePath_);
45806f6ba60Sopenharmony_ci            symbol.module_ = callFrame.filePath_;
45906f6ba60Sopenharmony_ci            symbol.symbolName_ = callFrame.symbolName_;
46006f6ba60Sopenharmony_ci            symbol.symbolId_ = userSymbolCache_.size() + 1;
46106f6ba60Sopenharmony_ci            if (hookConfig_.string_compressed()) {
46206f6ba60Sopenharmony_ci                FillSymbolNameId(callFrame, symbol);
46306f6ba60Sopenharmony_ci                FillFileSet(callFrame, symbol);
46406f6ba60Sopenharmony_ci            }
46506f6ba60Sopenharmony_ci            callFrame.needReport_ |= CALL_FRAME_REPORT;
46606f6ba60Sopenharmony_ci            userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol;
46706f6ba60Sopenharmony_ci            return symbol;
46806f6ba60Sopenharmony_ci        }
46906f6ba60Sopenharmony_ci    } else if (GetSymbolCache(callFrame.ip_, symbol, GetThread(pid, tid))) {
47006f6ba60Sopenharmony_ci        return symbol;
47106f6ba60Sopenharmony_ci    }
47206f6ba60Sopenharmony_ci    if (context == PERF_CONTEXT_USER or (context == PERF_CONTEXT_MAX and !symbol.IsValid())) {
47306f6ba60Sopenharmony_ci        // check userspace memmap
47406f6ba60Sopenharmony_ci        symbol = GetUserSymbol(callFrame.ip_, GetThread(pid, tid));
47506f6ba60Sopenharmony_ci        if (symbol.IsValid()) {
47606f6ba60Sopenharmony_ci            HLOGM("GetUserSymbol valid tid = %d ip = 0x%" PRIx64 "", tid, callFrame.ip_);
47706f6ba60Sopenharmony_ci            symbol.symbolId_ = userSymbolCache_.size() + 1;
47806f6ba60Sopenharmony_ci            if (hookConfig_.string_compressed()) {
47906f6ba60Sopenharmony_ci                FillSymbolNameId(callFrame, symbol);
48006f6ba60Sopenharmony_ci                FillFileSet(callFrame, symbol);
48106f6ba60Sopenharmony_ci            }
48206f6ba60Sopenharmony_ci            callFrame.needReport_ |= CALL_FRAME_REPORT;
48306f6ba60Sopenharmony_ci            userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol;
48406f6ba60Sopenharmony_ci        } else {
48506f6ba60Sopenharmony_ci            HLOGM("GetUserSymbol invalid!");
48606f6ba60Sopenharmony_ci        }
48706f6ba60Sopenharmony_ci    }
48806f6ba60Sopenharmony_ci
48906f6ba60Sopenharmony_ci    return symbol;
49006f6ba60Sopenharmony_ci}
49106f6ba60Sopenharmony_ci
49206f6ba60Sopenharmony_cibool VirtualRuntime::SetSymbolsPaths(const std::vector<std::string> &symbolsPaths)
49306f6ba60Sopenharmony_ci{
49406f6ba60Sopenharmony_ci    std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
49506f6ba60Sopenharmony_ci    // we need check if the path is accessable
49606f6ba60Sopenharmony_ci    bool accessable = symbolsFile->setSymbolsFilePath(symbolsPaths);
49706f6ba60Sopenharmony_ci    if (accessable) {
49806f6ba60Sopenharmony_ci        symbolsPaths_ = symbolsPaths;
49906f6ba60Sopenharmony_ci    } else {
50006f6ba60Sopenharmony_ci        if (!symbolsPaths.empty()) {
50106f6ba60Sopenharmony_ci            printf("some symbols path unable access\n");
50206f6ba60Sopenharmony_ci        }
50306f6ba60Sopenharmony_ci    }
50406f6ba60Sopenharmony_ci    return accessable;
50506f6ba60Sopenharmony_ci}
50606f6ba60Sopenharmony_ci
50706f6ba60Sopenharmony_civoid VirtualRuntime::FillMapsCache(std::string& currentFileName, std::shared_ptr<DfxMap> mapItem)
50806f6ba60Sopenharmony_ci{
50906f6ba60Sopenharmony_ci    if (currentFileName.compare(mapItem->name) != 0) {
51006f6ba60Sopenharmony_ci        currentFileName = mapItem->name;
51106f6ba60Sopenharmony_ci        soBegin_ = mapItem->begin;
51206f6ba60Sopenharmony_ci        auto memMaps = std::make_shared<MemMaps>(++memMapFilePathId_);
51306f6ba60Sopenharmony_ci        memMaps->AddMap(mapItem, true);
51406f6ba60Sopenharmony_ci        mapsCache_[mapItem->begin] = memMaps;
51506f6ba60Sopenharmony_ci    } else {
51606f6ba60Sopenharmony_ci        if (auto curMapsIter = mapsCache_.find(soBegin_);
51706f6ba60Sopenharmony_ci                curMapsIter != mapsCache_.end()) {
51806f6ba60Sopenharmony_ci            auto& curMaps = curMapsIter->second;
51906f6ba60Sopenharmony_ci            curMaps->soEnd_ = mapItem->end;
52006f6ba60Sopenharmony_ci            curMaps->AddMap(mapItem, false);
52106f6ba60Sopenharmony_ci            if (mapItem->prots & PROT_EXEC) {
52206f6ba60Sopenharmony_ci                offlineMapAddr_.push_back(soBegin_);
52306f6ba60Sopenharmony_ci            }
52406f6ba60Sopenharmony_ci        }
52506f6ba60Sopenharmony_ci    }
52606f6ba60Sopenharmony_ci}
52706f6ba60Sopenharmony_ci
52806f6ba60Sopenharmony_civoid VirtualRuntime::FillSymbolNameId(CallFrame& callFrame, DfxSymbol& symbol)
52906f6ba60Sopenharmony_ci{
53006f6ba60Sopenharmony_ci    auto itFuntion = functionMap_.find(std::string(symbol.symbolName_));
53106f6ba60Sopenharmony_ci    if (itFuntion != functionMap_.end()) {
53206f6ba60Sopenharmony_ci        symbol.symbolNameId_ = itFuntion->second;
53306f6ba60Sopenharmony_ci    } else {
53406f6ba60Sopenharmony_ci        symbol.symbolNameId_ = functionMap_.size() + 1;
53506f6ba60Sopenharmony_ci        functionMap_[std::string(symbol.symbolName_)] = symbol.symbolNameId_;
53606f6ba60Sopenharmony_ci        callFrame.needReport_ |= SYMBOL_NAME_ID_REPORT;
53706f6ba60Sopenharmony_ci    }
53806f6ba60Sopenharmony_ci}
53906f6ba60Sopenharmony_ci
54006f6ba60Sopenharmony_civoid VirtualRuntime::FillFileSet(CallFrame& callFrame, const DfxSymbol& symbol)
54106f6ba60Sopenharmony_ci{
54206f6ba60Sopenharmony_ci    auto itFile = fileSet_.find(symbol.filePathId_);
54306f6ba60Sopenharmony_ci    if (itFile == fileSet_.end()) {
54406f6ba60Sopenharmony_ci        callFrame.needReport_ |= FILE_PATH_ID_REPORT;
54506f6ba60Sopenharmony_ci        fileSet_.insert(symbol.filePathId_);
54606f6ba60Sopenharmony_ci    }
54706f6ba60Sopenharmony_ci}
54806f6ba60Sopenharmony_ci
54906f6ba60Sopenharmony_civoid VirtualRuntime::HandleMapInfo(std::vector<uint64_t> info, const std::string& filePath, pid_t pid, pid_t tid)
55006f6ba60Sopenharmony_ci{
55106f6ba60Sopenharmony_ci    if (info.size() != INFO_SIZE) {
55206f6ba60Sopenharmony_ci        return;
55306f6ba60Sopenharmony_ci    }
55406f6ba60Sopenharmony_ci    uint64_t begin = info[0];
55506f6ba60Sopenharmony_ci    uint64_t length = info[1];
55606f6ba60Sopenharmony_ci    uint64_t flags = info[SECOND_INDEX];
55706f6ba60Sopenharmony_ci    uint64_t offset = info[THIRD_INDEX];
55806f6ba60Sopenharmony_ci    if (!(flags & MAP_FIXED)) {
55906f6ba60Sopenharmony_ci        return;
56006f6ba60Sopenharmony_ci    }
56106f6ba60Sopenharmony_ci    if (offset == 0 && mapsCache_.find(begin) == mapsCache_.end()) {
56206f6ba60Sopenharmony_ci        soBegin_ = begin;
56306f6ba60Sopenharmony_ci        std::shared_ptr<DfxMap> mapItem = std::make_shared<DfxMap>(begin, begin + length, offset, flags, filePath);
56406f6ba60Sopenharmony_ci        auto memMaps = std::make_shared<MemMaps>(++memMapFilePathId_);
56506f6ba60Sopenharmony_ci        memMaps->AddMap(mapItem, true);
56606f6ba60Sopenharmony_ci        mapsCache_[begin] = memMaps;
56706f6ba60Sopenharmony_ci        UpdateSymbols(filePath, mapItem);
56806f6ba60Sopenharmony_ci        if ((!hookConfig_.fp_unwind())) {
56906f6ba60Sopenharmony_ci            auto &thread = UpdateThread(pid, tid);
57006f6ba60Sopenharmony_ci            thread.ParseMap(processMaps_, false);
57106f6ba60Sopenharmony_ci        }
57206f6ba60Sopenharmony_ci    } else {
57306f6ba60Sopenharmony_ci        auto curMapsIter = mapsCache_.find(soBegin_);
57406f6ba60Sopenharmony_ci        if (curMapsIter != mapsCache_.end()) {
57506f6ba60Sopenharmony_ci            auto& curMaps = curMapsIter->second;
57606f6ba60Sopenharmony_ci            curMaps->soEnd_ = begin + length;
57706f6ba60Sopenharmony_ci            std::shared_ptr<DfxMap> mapItem = std::make_shared<DfxMap>(begin, begin + length,
57806f6ba60Sopenharmony_ci                                                                       offset, flags, curMaps->name_);
57906f6ba60Sopenharmony_ci            if (mapItem->name.find(".hap") != std::string::npos && (mapItem->prots & PROT_EXEC)) {
58006f6ba60Sopenharmony_ci                mapItem->prevMap = curMaps->GetMaps().back();
58106f6ba60Sopenharmony_ci                HLOGD("update hap(%s) symbols", mapItem->name.c_str());
58206f6ba60Sopenharmony_ci                UpdateHapSymbols(mapItem);
58306f6ba60Sopenharmony_ci            }
58406f6ba60Sopenharmony_ci            curMaps->AddMap(mapItem, false);
58506f6ba60Sopenharmony_ci        }
58606f6ba60Sopenharmony_ci    }
58706f6ba60Sopenharmony_ci    if (flags & PROT_EXEC) {
58806f6ba60Sopenharmony_ci        offlineMapAddr_.push_back(soBegin_);
58906f6ba60Sopenharmony_ci    }
59006f6ba60Sopenharmony_ci}
59106f6ba60Sopenharmony_ci
59206f6ba60Sopenharmony_civoid VirtualRuntime::RemoveMaps(uint64_t addr)
59306f6ba60Sopenharmony_ci{
59406f6ba60Sopenharmony_ci    mapsCache_.erase(addr);
59506f6ba60Sopenharmony_ci}
59606f6ba60Sopenharmony_ci
59706f6ba60Sopenharmony_cistd::pair<std::shared_ptr<MemMaps>, uint32_t> VirtualRuntime::FindMap(uint64_t addr)
59806f6ba60Sopenharmony_ci{
59906f6ba60Sopenharmony_ci    auto iter = mapsCache_.upper_bound(addr);
60006f6ba60Sopenharmony_ci    if (iter == mapsCache_.begin()) {
60106f6ba60Sopenharmony_ci        // have map 2 3 4 5
60206f6ba60Sopenharmony_ci        // find 1 , will return 2 (index 0, begin elem)
60306f6ba60Sopenharmony_ci        // this same as not found any thins
60406f6ba60Sopenharmony_ci        return {nullptr, 0};
60506f6ba60Sopenharmony_ci    }
60606f6ba60Sopenharmony_ci
60706f6ba60Sopenharmony_ci    std::shared_ptr<MemMaps> curMaps = (--iter)->second;
60806f6ba60Sopenharmony_ci    if (addr >= curMaps->soBegin_ && addr < curMaps->soEnd_) {
60906f6ba60Sopenharmony_ci        std::vector<std::shared_ptr<DfxMap>> mapVec = curMaps->GetMaps();
61006f6ba60Sopenharmony_ci        for (auto curMapItem = mapVec.begin();
61106f6ba60Sopenharmony_ci            curMapItem != mapVec.end(); ++curMapItem) {
61206f6ba60Sopenharmony_ci            if (addr >= (*curMapItem)->begin && addr < (*curMapItem)->end) {
61306f6ba60Sopenharmony_ci                return {curMaps, curMapItem - mapVec.begin()};
61406f6ba60Sopenharmony_ci            }
61506f6ba60Sopenharmony_ci        }
61606f6ba60Sopenharmony_ci    }
61706f6ba60Sopenharmony_ci    return {nullptr, 0};
61806f6ba60Sopenharmony_ci}
61906f6ba60Sopenharmony_ci
62006f6ba60Sopenharmony_cibool VirtualRuntime::ArktsGetSymbolCache(CallFrame& callFrame, DfxSymbol &symbol)
62106f6ba60Sopenharmony_ci{
62206f6ba60Sopenharmony_ci    uint32_t jsfilePathId = FindArkTsFilePath(callFrame.filePath_);
62306f6ba60Sopenharmony_ci    if (jsfilePathId != 0) {
62406f6ba60Sopenharmony_ci        auto foundSymbolIter = userSymbolCache_.find(std::pair(callFrame.ip_, jsfilePathId));
62506f6ba60Sopenharmony_ci        if (foundSymbolIter != userSymbolCache_.end()) {
62606f6ba60Sopenharmony_ci            symbol = foundSymbolIter->second;
62706f6ba60Sopenharmony_ci            return true;
62806f6ba60Sopenharmony_ci        }
62906f6ba60Sopenharmony_ci    }
63006f6ba60Sopenharmony_ci    return false;
63106f6ba60Sopenharmony_ci}
63206f6ba60Sopenharmony_ci
63306f6ba60Sopenharmony_ciuint32_t VirtualRuntime::FindArkTsFilePath(std::string_view& jstr)
63406f6ba60Sopenharmony_ci{
63506f6ba60Sopenharmony_ci    auto iter = jsUrlMap_.find(jstr);
63606f6ba60Sopenharmony_ci    if (iter == jsUrlMap_.end()) {
63706f6ba60Sopenharmony_ci        return 0;
63806f6ba60Sopenharmony_ci    } else {
63906f6ba60Sopenharmony_ci        return iter->second;
64006f6ba60Sopenharmony_ci    }
64106f6ba60Sopenharmony_ci}
64206f6ba60Sopenharmony_ci
64306f6ba60Sopenharmony_ciuint32_t VirtualRuntime::FillArkTsFilePath(std::string_view& jstr)
64406f6ba60Sopenharmony_ci{
64506f6ba60Sopenharmony_ci    auto iter = jsUrlMap_.find(jstr);
64606f6ba60Sopenharmony_ci    if (iter == jsUrlMap_.end()) {
64706f6ba60Sopenharmony_ci        jsUrlMap_[jstr] = ++memMapFilePathId_;
64806f6ba60Sopenharmony_ci    }
64906f6ba60Sopenharmony_ci    return jsUrlMap_[jstr];
65006f6ba60Sopenharmony_ci}
65106f6ba60Sopenharmony_ci
65206f6ba60Sopenharmony_civoid VirtualRuntime::FillJsSymbolCache(CallFrame& callFrame, const DfxSymbol& symbol)
65306f6ba60Sopenharmony_ci{
65406f6ba60Sopenharmony_ci    userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol;
65506f6ba60Sopenharmony_ci}
65606f6ba60Sopenharmony_ci
65706f6ba60Sopenharmony_ciuint32_t VirtualRuntime::GetJsSymbolCacheSize()
65806f6ba60Sopenharmony_ci{
65906f6ba60Sopenharmony_ci    return userSymbolCache_.size() + 1;
66006f6ba60Sopenharmony_ci}
66106f6ba60Sopenharmony_ci
66206f6ba60Sopenharmony_ci} // namespace NativeDaemon
66306f6ba60Sopenharmony_ci} // namespace Developtools
66406f6ba60Sopenharmony_ci} // namespace OHOS
665