blob: f9f6d5662db074966c6d18a49a4569482b1ceaf5 [file] [log] [blame]
Christopher Ferris723cf9b2017-01-19 20:08:48 -08001/*
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
Christopher Ferrisf447c8e2017-04-03 12:39:47 -070020#include <assert.h>
Christopher Ferris723cf9b2017-01-19 20:08:48 -080021#include <stdint.h>
22#include <sys/types.h>
23#include <unistd.h>
24
25#include <string>
Christopher Ferris3958f802017-02-01 15:44:40 -080026#include <vector>
Christopher Ferris723cf9b2017-01-19 20:08:48 -080027
28class Memory {
29 public:
30 Memory() = default;
31 virtual ~Memory() = default;
32
33 virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX);
34
35 virtual bool Read(uint64_t addr, void* dst, size_t size) = 0;
36
Christopher Ferrisf447c8e2017-04-03 12:39:47 -070037 inline bool ReadField(uint64_t addr, void* start, void* field, size_t size) {
38 if (reinterpret_cast<uintptr_t>(field) < reinterpret_cast<uintptr_t>(start)) {
39 return false;
40 }
41 uint64_t offset = reinterpret_cast<uintptr_t>(field) - reinterpret_cast<uintptr_t>(start);
42 if (__builtin_add_overflow(addr, offset, &offset)) {
43 return false;
44 }
45 // The read will check if offset + size overflows.
46 return Read(offset, field, size);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080047 }
48
49 inline bool Read32(uint64_t addr, uint32_t* dst) {
50 return Read(addr, dst, sizeof(uint32_t));
51 }
52
53 inline bool Read64(uint64_t addr, uint64_t* dst) {
54 return Read(addr, dst, sizeof(uint64_t));
55 }
56};
57
Christopher Ferris3958f802017-02-01 15:44:40 -080058class MemoryBuffer : public Memory {
59 public:
60 MemoryBuffer() = default;
61 virtual ~MemoryBuffer() = default;
62
63 bool Read(uint64_t addr, void* dst, size_t size) override;
64
65 uint8_t* GetPtr(size_t offset);
66
67 void Resize(size_t size) { raw_.resize(size); }
68
69 uint64_t Size() { return raw_.size(); }
70
71 private:
72 std::vector<uint8_t> raw_;
73};
74
Christopher Ferris723cf9b2017-01-19 20:08:48 -080075class MemoryFileAtOffset : public Memory {
76 public:
77 MemoryFileAtOffset() = default;
78 virtual ~MemoryFileAtOffset();
79
Christopher Ferris3958f802017-02-01 15:44:40 -080080 bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080081
82 bool Read(uint64_t addr, void* dst, size_t size) override;
83
Christopher Ferris3958f802017-02-01 15:44:40 -080084 void Clear();
85
Christopher Ferris723cf9b2017-01-19 20:08:48 -080086 protected:
87 size_t size_ = 0;
88 size_t offset_ = 0;
89 uint8_t* data_ = nullptr;
90};
91
92class MemoryOffline : public MemoryFileAtOffset {
93 public:
94 MemoryOffline() = default;
95 virtual ~MemoryOffline() = default;
96
97 bool Init(const std::string& file, uint64_t offset);
98
99 bool Read(uint64_t addr, void* dst, size_t size) override;
100
101 private:
102 uint64_t start_;
103};
104
105class MemoryRemote : public Memory {
106 public:
107 MemoryRemote(pid_t pid) : pid_(pid) {}
108 virtual ~MemoryRemote() = default;
109
110 bool Read(uint64_t addr, void* dst, size_t size) override;
111
112 pid_t pid() { return pid_; }
113
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700114 protected:
115 virtual bool PtraceRead(uint64_t addr, long* value);
116
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800117 private:
118 pid_t pid_;
119};
120
121class MemoryLocal : public Memory {
122 public:
123 MemoryLocal() = default;
124 virtual ~MemoryLocal() = default;
125
126 bool Read(uint64_t addr, void* dst, size_t size) override;
127};
128
129class MemoryRange : public Memory {
130 public:
131 MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700132 : memory_(memory), begin_(begin), length_(end - begin) {
133 assert(end > begin);
134 }
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800135 virtual ~MemoryRange() { delete memory_; }
136
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700137 bool Read(uint64_t addr, void* dst, size_t size) override;
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800138
139 private:
140 Memory* memory_;
141 uint64_t begin_;
142 uint64_t length_;
143};
144
145#endif // _LIBUNWINDSTACK_MEMORY_H