1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef HIPERF_VIRTUAL_THREAD_H
16#define HIPERF_VIRTUAL_THREAD_H
17
18#include <cinttypes>
19#include <functional>
20#include <unordered_set>
21#include <unordered_map>
22
23#include "debug_logger.h"
24#include "dfx_maps.h"
25#include "perf_event_record.h"
26#include "symbols_file.h"
27
28namespace OHOS {
29namespace Developtools {
30namespace HiPerf {
31/*
3203284000-03289000 r--p 00000000 b3:05 289        /system/bin/sh
33032b7000-032b9000 rw-p 00000000 00:00 0
34aff60000-aff96000 r--p 00000000 b3:05 923        /system/lib/libc++.so
35affeb000-affed000 rw-p 00000000 00:00 0
36b0023000-b0024000 r--p 00000000 b3:05 959        /system/lib/libdl.so
37*/
38const std::string MMAP_NAME_HEAP = "[heap]";
39const std::string MMAP_NAME_ANON = "[anon]";
40
41class VirtualThread {
42public:
43    VirtualThread(const VirtualThread &) = delete;
44    VirtualThread &operator=(const VirtualThread &) = delete;
45
46    VirtualThread(pid_t pid, const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
47        : pid_(pid),
48          tid_(pid),
49          symbolsFiles_(symbolsFiles),
50          processMemMaps_(),
51          memMaps_(processMemMaps_),
52          vaddr4kPageCache_(vaddr4kPageCacheOfProc_),
53          memMapsIndexs_(processMemMapsIndexs_),
54          parent_(*this) {}
55
56    VirtualThread(pid_t pid, pid_t tid, VirtualThread &thread,
57                  const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
58        : pid_(pid),
59          tid_(tid),
60          symbolsFiles_(symbolsFiles),
61          processMemMaps_(),
62          memMaps_(thread.processMemMaps_),
63          vaddr4kPageCache_(thread.vaddr4kPageCacheOfProc_),
64          memMapsIndexs_(thread.processMemMapsIndexs_),
65          parent_(thread)
66    {
67        HLOG_ASSERT(pid != tid);
68        HLOGV("%d %d map from parent size is %zu", pid, tid, memMaps_.size());
69    };
70
71    pid_t pid_;
72    pid_t tid_;
73    std::string name_;
74
75    const std::vector<std::shared_ptr<DfxMap>> &GetMaps() const
76    {
77        return memMaps_;
78    }
79    void ParseMap();
80    void FixHMBundleMap();
81    void ParseServiceMap(const std::string &filename);
82    void ParseDevhostMap(pid_t devhost);
83    std::shared_ptr<DfxMap> CreateMapItem(const std::string filename, uint64_t begin,
84                                          uint64_t len, uint64_t offset, uint32_t prot = 0);
85    std::shared_ptr<DfxMap> FindMapByAddr(uint64_t addr) const;
86    std::shared_ptr<DfxMap> FindMapByFileInfo(const std::string name, uint64_t offset) const;
87    int64_t FindMapIndexByAddr(uint64_t addr) const;
88    SymbolsFile *FindSymbolsFileByMap(std::shared_ptr<DfxMap> map) const;
89    bool ReadRoMemory(uint64_t vaddr, uint8_t *data, size_t size) const;
90#ifdef HIPERF_DEBUG
91    void ReportVaddrMapMiss(uint64_t vaddr) const;
92#endif
93
94private:
95    void SortMemMaps();
96#ifdef DEBUG_TIME
97    bool IsSorted() const;
98#endif
99    const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles_;
100
101    // proc/xx/map
102    // use to put the parent thread's map
103    // only process have memmap
104    std::vector<std::shared_ptr<DfxMap>> processMemMaps_;
105    std::unordered_map<uint64_t, uint64_t> vaddr4kPageCacheOfProc_;
106    // thread must use ref from process
107    std::vector<std::shared_ptr<DfxMap>> &memMaps_;
108    std::unordered_map<uint64_t, uint64_t> &vaddr4kPageCache_;
109    std::vector<int> processMemMapsIndexs_;
110    std::vector<int> &memMapsIndexs_;
111    VirtualThread &parent_;
112#ifdef HIPERF_DEBUG
113    mutable std::unordered_set<uint64_t> missedRuntimeVaddr_;
114#endif
115#ifdef DEBUG_MISS_SYMBOL
116    mutable std::vector<std::string> missedSymbolFile_;
117#endif
118    FRIEND_TEST(VirtualThreadTest, ReadRoMemory);
119};
120} // namespace HiPerf
121} // namespace Developtools
122} // namespace OHOS
123#endif // HIPERF_VIRTUAL_THREAD_H
124