1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBUNWINDSTACK_MEMORY_H 18 #define _LIBUNWINDSTACK_MEMORY_H 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 #include <unistd.h> 23 24 #include <atomic> 25 #include <map> 26 #include <memory> 27 #include <string> 28 #include <unordered_map> 29 #include <vector> 30 31 namespace unwindstack { 32 33 class Memory { 34 public: 35 Memory() = default; 36 virtual ~Memory() = default; 37 38 static std::shared_ptr<Memory> CreateProcessMemory(pid_t pid); 39 static std::shared_ptr<Memory> CreateProcessMemoryCached(pid_t pid); 40 41 virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX); 42 Clear()43 virtual void Clear() {} 44 45 virtual size_t Read(uint64_t addr, void* dst, size_t size) = 0; 46 47 bool ReadFully(uint64_t addr, void* dst, size_t size); 48 Read32(uint64_t addr,uint32_t * dst)49 inline bool Read32(uint64_t addr, uint32_t* dst) { 50 return ReadFully(addr, dst, sizeof(uint32_t)); 51 } 52 Read64(uint64_t addr,uint64_t * dst)53 inline bool Read64(uint64_t addr, uint64_t* dst) { 54 return ReadFully(addr, dst, sizeof(uint64_t)); 55 } 56 }; 57 58 class MemoryCache : public Memory { 59 public: MemoryCache(Memory * memory)60 MemoryCache(Memory* memory) : impl_(memory) {} 61 virtual ~MemoryCache() = default; 62 63 size_t Read(uint64_t addr, void* dst, size_t size) override; 64 Clear()65 void Clear() override { cache_.clear(); } 66 67 private: 68 constexpr static size_t kCacheBits = 12; 69 constexpr static size_t kCacheMask = (1 << kCacheBits) - 1; 70 constexpr static size_t kCacheSize = 1 << kCacheBits; 71 std::unordered_map<uint64_t, uint8_t[kCacheSize]> cache_; 72 73 std::unique_ptr<Memory> impl_; 74 }; 75 76 class MemoryBuffer : public Memory { 77 public: 78 MemoryBuffer() = default; 79 virtual ~MemoryBuffer() = default; 80 81 size_t Read(uint64_t addr, void* dst, size_t size) override; 82 83 uint8_t* GetPtr(size_t offset); 84 Resize(size_t size)85 void Resize(size_t size) { raw_.resize(size); } 86 Size()87 uint64_t Size() { return raw_.size(); } 88 89 private: 90 std::vector<uint8_t> raw_; 91 }; 92 93 class MemoryFileAtOffset : public Memory { 94 public: 95 MemoryFileAtOffset() = default; 96 virtual ~MemoryFileAtOffset(); 97 98 bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX); 99 100 size_t Read(uint64_t addr, void* dst, size_t size) override; 101 Size()102 size_t Size() { return size_; } 103 104 void Clear() override; 105 106 protected: 107 size_t size_ = 0; 108 size_t offset_ = 0; 109 uint8_t* data_ = nullptr; 110 }; 111 112 class MemoryRemote : public Memory { 113 public: MemoryRemote(pid_t pid)114 MemoryRemote(pid_t pid) : pid_(pid), read_redirect_func_(0) {} 115 virtual ~MemoryRemote() = default; 116 117 size_t Read(uint64_t addr, void* dst, size_t size) override; 118 pid()119 pid_t pid() { return pid_; } 120 121 private: 122 pid_t pid_; 123 std::atomic_uintptr_t read_redirect_func_; 124 }; 125 126 class MemoryLocal : public Memory { 127 public: 128 MemoryLocal() = default; 129 virtual ~MemoryLocal() = default; 130 131 size_t Read(uint64_t addr, void* dst, size_t size) override; 132 }; 133 134 // MemoryRange maps one address range onto another. 135 // The range [src_begin, src_begin + length) in the underlying Memory is mapped onto offset, 136 // such that range.read(offset) is equivalent to underlying.read(src_begin). 137 class MemoryRange : public Memory { 138 public: 139 MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t length, 140 uint64_t offset); 141 virtual ~MemoryRange() = default; 142 143 size_t Read(uint64_t addr, void* dst, size_t size) override; 144 offset()145 uint64_t offset() { return offset_; } length()146 uint64_t length() { return length_; } 147 148 private: 149 std::shared_ptr<Memory> memory_; 150 uint64_t begin_; 151 uint64_t length_; 152 uint64_t offset_; 153 }; 154 155 class MemoryRanges : public Memory { 156 public: 157 MemoryRanges() = default; 158 virtual ~MemoryRanges() = default; 159 160 void Insert(MemoryRange* memory); 161 162 size_t Read(uint64_t addr, void* dst, size_t size) override; 163 164 private: 165 std::map<uint64_t, std::unique_ptr<MemoryRange>> maps_; 166 }; 167 168 class MemoryOffline : public Memory { 169 public: 170 MemoryOffline() = default; 171 virtual ~MemoryOffline() = default; 172 173 bool Init(const std::string& file, uint64_t offset); 174 175 size_t Read(uint64_t addr, void* dst, size_t size) override; 176 177 private: 178 std::unique_ptr<MemoryRange> memory_; 179 }; 180 181 class MemoryOfflineBuffer : public Memory { 182 public: 183 MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end); 184 virtual ~MemoryOfflineBuffer() = default; 185 186 void Reset(const uint8_t* data, uint64_t start, uint64_t end); 187 188 size_t Read(uint64_t addr, void* dst, size_t size) override; 189 190 private: 191 const uint8_t* data_; 192 uint64_t start_; 193 uint64_t end_; 194 }; 195 196 class MemoryOfflineParts : public Memory { 197 public: 198 MemoryOfflineParts() = default; 199 virtual ~MemoryOfflineParts(); 200 Add(MemoryOffline * memory)201 void Add(MemoryOffline* memory) { memories_.push_back(memory); } 202 203 size_t Read(uint64_t addr, void* dst, size_t size) override; 204 205 private: 206 std::vector<MemoryOffline*> memories_; 207 }; 208 209 } // namespace unwindstack 210 211 #endif // _LIBUNWINDSTACK_MEMORY_H 212