• 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 <memory>
26 #include <string>
27 #include <vector>
28 
29 namespace unwindstack {
30 
31 class Memory {
32  public:
33   Memory() = default;
34   virtual ~Memory() = default;
35 
36   static std::shared_ptr<Memory> CreateProcessMemory(pid_t pid);
37 
38   virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX);
39 
40   virtual size_t Read(uint64_t addr, void* dst, size_t size) = 0;
41 
42   bool ReadFully(uint64_t addr, void* dst, size_t size);
43 
ReadField(uint64_t addr,void * start,void * field,size_t size)44   inline bool ReadField(uint64_t addr, void* start, void* field, size_t size) {
45     if (reinterpret_cast<uintptr_t>(field) < reinterpret_cast<uintptr_t>(start)) {
46       return false;
47     }
48     uint64_t offset = reinterpret_cast<uintptr_t>(field) - reinterpret_cast<uintptr_t>(start);
49     if (__builtin_add_overflow(addr, offset, &offset)) {
50       return false;
51     }
52     // The read will check if offset + size overflows.
53     return ReadFully(offset, field, size);
54   }
55 
Read32(uint64_t addr,uint32_t * dst)56   inline bool Read32(uint64_t addr, uint32_t* dst) {
57     return ReadFully(addr, dst, sizeof(uint32_t));
58   }
59 
Read64(uint64_t addr,uint64_t * dst)60   inline bool Read64(uint64_t addr, uint64_t* dst) {
61     return ReadFully(addr, dst, sizeof(uint64_t));
62   }
63 };
64 
65 class MemoryBuffer : public Memory {
66  public:
67   MemoryBuffer() = default;
68   virtual ~MemoryBuffer() = default;
69 
70   size_t Read(uint64_t addr, void* dst, size_t size) override;
71 
72   uint8_t* GetPtr(size_t offset);
73 
Resize(size_t size)74   void Resize(size_t size) { raw_.resize(size); }
75 
Size()76   uint64_t Size() { return raw_.size(); }
77 
78  private:
79   std::vector<uint8_t> raw_;
80 };
81 
82 class MemoryFileAtOffset : public Memory {
83  public:
84   MemoryFileAtOffset() = default;
85   virtual ~MemoryFileAtOffset();
86 
87   bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX);
88 
89   size_t Read(uint64_t addr, void* dst, size_t size) override;
90 
Size()91   size_t Size() { return size_; }
92 
93   void Clear();
94 
95  protected:
96   size_t size_ = 0;
97   size_t offset_ = 0;
98   uint8_t* data_ = nullptr;
99 };
100 
101 class MemoryRemote : public Memory {
102  public:
MemoryRemote(pid_t pid)103   MemoryRemote(pid_t pid) : pid_(pid), read_redirect_func_(0) {}
104   virtual ~MemoryRemote() = default;
105 
106   size_t Read(uint64_t addr, void* dst, size_t size) override;
107 
pid()108   pid_t pid() { return pid_; }
109 
110  private:
111   pid_t pid_;
112   std::atomic_uintptr_t read_redirect_func_;
113 };
114 
115 class MemoryLocal : public Memory {
116  public:
117   MemoryLocal() = default;
118   virtual ~MemoryLocal() = default;
119 
120   size_t Read(uint64_t addr, void* dst, size_t size) override;
121 };
122 
123 // MemoryRange maps one address range onto another.
124 // The range [src_begin, src_begin + length) in the underlying Memory is mapped onto offset,
125 // such that range.read(offset) is equivalent to underlying.read(src_begin).
126 class MemoryRange : public Memory {
127  public:
128   MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t length,
129               uint64_t offset);
130   virtual ~MemoryRange() = default;
131 
132   size_t Read(uint64_t addr, void* dst, size_t size) override;
133 
134  private:
135   std::shared_ptr<Memory> memory_;
136   uint64_t begin_;
137   uint64_t length_;
138   uint64_t offset_;
139 };
140 
141 class MemoryOffline : public Memory {
142  public:
143   MemoryOffline() = default;
144   virtual ~MemoryOffline() = default;
145 
146   bool Init(const std::string& file, uint64_t offset);
147 
148   size_t Read(uint64_t addr, void* dst, size_t size) override;
149 
150  private:
151   std::unique_ptr<MemoryRange> memory_;
152 };
153 
154 class MemoryOfflineBuffer : public Memory {
155  public:
156   MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end);
157   virtual ~MemoryOfflineBuffer() = default;
158 
159   void Reset(const uint8_t* data, uint64_t start, uint64_t end);
160 
161   size_t Read(uint64_t addr, void* dst, size_t size) override;
162 
163  private:
164   const uint8_t* data_;
165   uint64_t start_;
166   uint64_t end_;
167 };
168 
169 class MemoryOfflineParts : public Memory {
170  public:
171   MemoryOfflineParts() = default;
172   virtual ~MemoryOfflineParts();
173 
Add(MemoryOffline * memory)174   void Add(MemoryOffline* memory) { memories_.push_back(memory); }
175 
176   size_t Read(uint64_t addr, void* dst, size_t size) override;
177 
178  private:
179   std::vector<MemoryOffline*> memories_;
180 };
181 
182 }  // namespace unwindstack
183 
184 #endif  // _LIBUNWINDSTACK_MEMORY_H
185