148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 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#ifndef HIPERF_VIRTUAL_THREAD_H
1648f512ceSopenharmony_ci#define HIPERF_VIRTUAL_THREAD_H
1748f512ceSopenharmony_ci
1848f512ceSopenharmony_ci#include <cinttypes>
1948f512ceSopenharmony_ci#include <functional>
2048f512ceSopenharmony_ci#include <unordered_set>
2148f512ceSopenharmony_ci#include <unordered_map>
2248f512ceSopenharmony_ci
2348f512ceSopenharmony_ci#include "debug_logger.h"
2448f512ceSopenharmony_ci#include "dfx_maps.h"
2548f512ceSopenharmony_ci#include "perf_event_record.h"
2648f512ceSopenharmony_ci#include "symbols_file.h"
2748f512ceSopenharmony_ci
2848f512ceSopenharmony_cinamespace OHOS {
2948f512ceSopenharmony_cinamespace Developtools {
3048f512ceSopenharmony_cinamespace HiPerf {
3148f512ceSopenharmony_ci/*
3248f512ceSopenharmony_ci03284000-03289000 r--p 00000000 b3:05 289        /system/bin/sh
3348f512ceSopenharmony_ci032b7000-032b9000 rw-p 00000000 00:00 0
3448f512ceSopenharmony_ciaff60000-aff96000 r--p 00000000 b3:05 923        /system/lib/libc++.so
3548f512ceSopenharmony_ciaffeb000-affed000 rw-p 00000000 00:00 0
3648f512ceSopenharmony_cib0023000-b0024000 r--p 00000000 b3:05 959        /system/lib/libdl.so
3748f512ceSopenharmony_ci*/
3848f512ceSopenharmony_ciconst std::string MMAP_NAME_HEAP = "[heap]";
3948f512ceSopenharmony_ciconst std::string MMAP_NAME_ANON = "[anon]";
4048f512ceSopenharmony_ci
4148f512ceSopenharmony_ciclass VirtualThread {
4248f512ceSopenharmony_cipublic:
4348f512ceSopenharmony_ci    VirtualThread(const VirtualThread &) = delete;
4448f512ceSopenharmony_ci    VirtualThread &operator=(const VirtualThread &) = delete;
4548f512ceSopenharmony_ci
4648f512ceSopenharmony_ci    VirtualThread(pid_t pid, const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
4748f512ceSopenharmony_ci        : pid_(pid),
4848f512ceSopenharmony_ci          tid_(pid),
4948f512ceSopenharmony_ci          symbolsFiles_(symbolsFiles),
5048f512ceSopenharmony_ci          processMemMaps_(),
5148f512ceSopenharmony_ci          memMaps_(processMemMaps_),
5248f512ceSopenharmony_ci          vaddr4kPageCache_(vaddr4kPageCacheOfProc_),
5348f512ceSopenharmony_ci          memMapsIndexs_(processMemMapsIndexs_),
5448f512ceSopenharmony_ci          parent_(*this) {}
5548f512ceSopenharmony_ci
5648f512ceSopenharmony_ci    VirtualThread(pid_t pid, pid_t tid, VirtualThread &thread,
5748f512ceSopenharmony_ci                  const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
5848f512ceSopenharmony_ci        : pid_(pid),
5948f512ceSopenharmony_ci          tid_(tid),
6048f512ceSopenharmony_ci          symbolsFiles_(symbolsFiles),
6148f512ceSopenharmony_ci          processMemMaps_(),
6248f512ceSopenharmony_ci          memMaps_(thread.processMemMaps_),
6348f512ceSopenharmony_ci          vaddr4kPageCache_(thread.vaddr4kPageCacheOfProc_),
6448f512ceSopenharmony_ci          memMapsIndexs_(thread.processMemMapsIndexs_),
6548f512ceSopenharmony_ci          parent_(thread)
6648f512ceSopenharmony_ci    {
6748f512ceSopenharmony_ci        HLOG_ASSERT(pid != tid);
6848f512ceSopenharmony_ci        HLOGV("%d %d map from parent size is %zu", pid, tid, memMaps_.size());
6948f512ceSopenharmony_ci    };
7048f512ceSopenharmony_ci
7148f512ceSopenharmony_ci    pid_t pid_;
7248f512ceSopenharmony_ci    pid_t tid_;
7348f512ceSopenharmony_ci    std::string name_;
7448f512ceSopenharmony_ci
7548f512ceSopenharmony_ci    const std::vector<std::shared_ptr<DfxMap>> &GetMaps() const
7648f512ceSopenharmony_ci    {
7748f512ceSopenharmony_ci        return memMaps_;
7848f512ceSopenharmony_ci    }
7948f512ceSopenharmony_ci    void ParseMap();
8048f512ceSopenharmony_ci    void FixHMBundleMap();
8148f512ceSopenharmony_ci    void ParseServiceMap(const std::string &filename);
8248f512ceSopenharmony_ci    void ParseDevhostMap(pid_t devhost);
8348f512ceSopenharmony_ci    std::shared_ptr<DfxMap> CreateMapItem(const std::string filename, uint64_t begin,
8448f512ceSopenharmony_ci                                          uint64_t len, uint64_t offset, uint32_t prot = 0);
8548f512ceSopenharmony_ci    std::shared_ptr<DfxMap> FindMapByAddr(uint64_t addr) const;
8648f512ceSopenharmony_ci    std::shared_ptr<DfxMap> FindMapByFileInfo(const std::string name, uint64_t offset) const;
8748f512ceSopenharmony_ci    int64_t FindMapIndexByAddr(uint64_t addr) const;
8848f512ceSopenharmony_ci    SymbolsFile *FindSymbolsFileByMap(std::shared_ptr<DfxMap> map) const;
8948f512ceSopenharmony_ci    bool ReadRoMemory(uint64_t vaddr, uint8_t *data, size_t size) const;
9048f512ceSopenharmony_ci#ifdef HIPERF_DEBUG
9148f512ceSopenharmony_ci    void ReportVaddrMapMiss(uint64_t vaddr) const;
9248f512ceSopenharmony_ci#endif
9348f512ceSopenharmony_ci
9448f512ceSopenharmony_ciprivate:
9548f512ceSopenharmony_ci    void SortMemMaps();
9648f512ceSopenharmony_ci#ifdef DEBUG_TIME
9748f512ceSopenharmony_ci    bool IsSorted() const;
9848f512ceSopenharmony_ci#endif
9948f512ceSopenharmony_ci    const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles_;
10048f512ceSopenharmony_ci
10148f512ceSopenharmony_ci    // proc/xx/map
10248f512ceSopenharmony_ci    // use to put the parent thread's map
10348f512ceSopenharmony_ci    // only process have memmap
10448f512ceSopenharmony_ci    std::vector<std::shared_ptr<DfxMap>> processMemMaps_;
10548f512ceSopenharmony_ci    std::unordered_map<uint64_t, uint64_t> vaddr4kPageCacheOfProc_;
10648f512ceSopenharmony_ci    // thread must use ref from process
10748f512ceSopenharmony_ci    std::vector<std::shared_ptr<DfxMap>> &memMaps_;
10848f512ceSopenharmony_ci    std::unordered_map<uint64_t, uint64_t> &vaddr4kPageCache_;
10948f512ceSopenharmony_ci    std::vector<int> processMemMapsIndexs_;
11048f512ceSopenharmony_ci    std::vector<int> &memMapsIndexs_;
11148f512ceSopenharmony_ci    VirtualThread &parent_;
11248f512ceSopenharmony_ci#ifdef HIPERF_DEBUG
11348f512ceSopenharmony_ci    mutable std::unordered_set<uint64_t> missedRuntimeVaddr_;
11448f512ceSopenharmony_ci#endif
11548f512ceSopenharmony_ci#ifdef DEBUG_MISS_SYMBOL
11648f512ceSopenharmony_ci    mutable std::vector<std::string> missedSymbolFile_;
11748f512ceSopenharmony_ci#endif
11848f512ceSopenharmony_ci    FRIEND_TEST(VirtualThreadTest, ReadRoMemory);
11948f512ceSopenharmony_ci};
12048f512ceSopenharmony_ci} // namespace HiPerf
12148f512ceSopenharmony_ci} // namespace Developtools
12248f512ceSopenharmony_ci} // namespace OHOS
12348f512ceSopenharmony_ci#endif // HIPERF_VIRTUAL_THREAD_H
124