blob: e353cab2f49d556f00fc0672da73628a0b9f83ec [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
20#include <stdint.h>
21#include <sys/types.h>
22#include <unistd.h>
23
24#include <string>
Christopher Ferris3958f802017-02-01 15:44:40 -080025#include <vector>
Christopher Ferris723cf9b2017-01-19 20:08:48 -080026
Christopher Ferris94167032017-06-28 18:56:52 -070027#include "Check.h"
28
Christopher Ferris723cf9b2017-01-19 20:08:48 -080029class 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
Christopher Ferrisf447c8e2017-04-03 12:39:47 -070038 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);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080048 }
49
50 inline bool Read32(uint64_t addr, uint32_t* dst) {
51 return Read(addr, dst, sizeof(uint32_t));
52 }
53
54 inline bool Read64(uint64_t addr, uint64_t* dst) {
55 return Read(addr, dst, sizeof(uint64_t));
56 }
57};
58
Christopher Ferris3958f802017-02-01 15:44:40 -080059class MemoryBuffer : public Memory {
60 public:
61 MemoryBuffer() = default;
62 virtual ~MemoryBuffer() = default;
63
64 bool Read(uint64_t addr, void* dst, size_t size) override;
65
66 uint8_t* GetPtr(size_t offset);
67
68 void Resize(size_t size) { raw_.resize(size); }
69
70 uint64_t Size() { return raw_.size(); }
71
72 private:
73 std::vector<uint8_t> raw_;
74};
75
Christopher Ferris723cf9b2017-01-19 20:08:48 -080076class MemoryFileAtOffset : public Memory {
77 public:
78 MemoryFileAtOffset() = default;
79 virtual ~MemoryFileAtOffset();
80
Christopher Ferris3958f802017-02-01 15:44:40 -080081 bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080082
83 bool Read(uint64_t addr, void* dst, size_t size) override;
84
Christopher Ferris3958f802017-02-01 15:44:40 -080085 void Clear();
86
Christopher Ferris723cf9b2017-01-19 20:08:48 -080087 protected:
88 size_t size_ = 0;
89 size_t offset_ = 0;
90 uint8_t* data_ = nullptr;
91};
92
93class MemoryOffline : public MemoryFileAtOffset {
94 public:
95 MemoryOffline() = default;
96 virtual ~MemoryOffline() = default;
97
98 bool Init(const std::string& file, uint64_t offset);
99
100 bool Read(uint64_t addr, void* dst, size_t size) override;
101
102 private:
103 uint64_t start_;
104};
105
106class MemoryRemote : public Memory {
107 public:
108 MemoryRemote(pid_t pid) : pid_(pid) {}
109 virtual ~MemoryRemote() = default;
110
111 bool Read(uint64_t addr, void* dst, size_t size) override;
112
113 pid_t pid() { return pid_; }
114
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700115 protected:
116 virtual bool PtraceRead(uint64_t addr, long* value);
117
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800118 private:
119 pid_t pid_;
120};
121
122class MemoryLocal : public Memory {
123 public:
124 MemoryLocal() = default;
125 virtual ~MemoryLocal() = default;
126
127 bool Read(uint64_t addr, void* dst, size_t size) override;
128};
129
130class MemoryRange : public Memory {
131 public:
132 MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700133 : memory_(memory), begin_(begin), length_(end - begin) {
Christopher Ferris94167032017-06-28 18:56:52 -0700134 CHECK(end > begin);
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700135 }
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800136 virtual ~MemoryRange() { delete memory_; }
137
Christopher Ferrisf447c8e2017-04-03 12:39:47 -0700138 bool Read(uint64_t addr, void* dst, size_t size) override;
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800139
140 private:
141 Memory* memory_;
142 uint64_t begin_;
143 uint64_t length_;
144};
145
146#endif // _LIBUNWINDSTACK_MEMORY_H