• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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