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 <string>
25#include <vector>
26
27namespace unwindstack {
28
29class Memory {
30 public:
31  Memory() = default;
32  virtual ~Memory() = default;
33
34  virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX);
35
36  virtual bool Read(uint64_t addr, void* dst, size_t size) = 0;
37
38  inline bool ReadField(uint64_t addr, void* start, void* field, size_t size) {
39    if (reinterpret_cast<uintptr_t>(field) < reinterpret_cast<uintptr_t>(start)) {
40      return false;
41    }
42    uint64_t offset = reinterpret_cast<uintptr_t>(field) - reinterpret_cast<uintptr_t>(start);
43    if (__builtin_add_overflow(addr, offset, &offset)) {
44      return false;
45    }
46    // The read will check if offset + size overflows.
47    return Read(offset, field, size);
48  }
49
50  inline bool Read32(uint64_t addr, uint32_t* dst) { return Read(addr, dst, sizeof(uint32_t)); }
51
52  inline bool Read64(uint64_t addr, uint64_t* dst) { return Read(addr, dst, sizeof(uint64_t)); }
53};
54
55class MemoryBuffer : public Memory {
56 public:
57  MemoryBuffer() = default;
58  virtual ~MemoryBuffer() = default;
59
60  bool Read(uint64_t addr, void* dst, size_t size) override;
61
62  uint8_t* GetPtr(size_t offset);
63
64  void Resize(size_t size) { raw_.resize(size); }
65
66  uint64_t Size() { return raw_.size(); }
67
68 private:
69  std::vector<uint8_t> raw_;
70};
71
72class MemoryFileAtOffset : public Memory {
73 public:
74  MemoryFileAtOffset() = default;
75  virtual ~MemoryFileAtOffset();
76
77  bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX);
78
79  bool Read(uint64_t addr, void* dst, size_t size) override;
80
81  void Clear();
82
83 protected:
84  size_t size_ = 0;
85  size_t offset_ = 0;
86  uint8_t* data_ = nullptr;
87};
88
89class MemoryOffline : public MemoryFileAtOffset {
90 public:
91  MemoryOffline() = default;
92  virtual ~MemoryOffline() = default;
93
94  bool Init(const std::string& file, uint64_t offset);
95
96  bool Read(uint64_t addr, void* dst, size_t size) override;
97
98 private:
99  uint64_t start_;
100};
101
102class MemoryRemote : public Memory {
103 public:
104  MemoryRemote(pid_t pid) : pid_(pid) {}
105  virtual ~MemoryRemote() = default;
106
107  bool Read(uint64_t addr, void* dst, size_t size) override;
108
109  pid_t pid() { return pid_; }
110
111 protected:
112  virtual bool PtraceRead(uint64_t addr, long* value);
113
114 private:
115  pid_t pid_;
116};
117
118class MemoryLocal : public Memory {
119 public:
120  MemoryLocal() = default;
121  virtual ~MemoryLocal() = default;
122
123  bool Read(uint64_t addr, void* dst, size_t size) override;
124};
125
126class MemoryRange : public Memory {
127 public:
128  MemoryRange(Memory* memory, uint64_t begin, uint64_t end);
129  virtual ~MemoryRange() { delete memory_; }
130
131  bool Read(uint64_t addr, void* dst, size_t size) override;
132
133 private:
134  Memory* memory_;
135  uint64_t begin_;
136  uint64_t length_;
137};
138
139}  // namespace unwindstack
140
141#endif  // _LIBUNWINDSTACK_MEMORY_H
142