1723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris/*
2723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Copyright (C) 2016 The Android Open Source Project
3723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris *
4723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License");
5723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * you may not use this file except in compliance with the License.
6723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * You may obtain a copy of the License at
7723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris *
8723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris *      http://www.apache.org/licenses/LICENSE-2.0
9723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris *
10723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Unless required by applicable law or agreed to in writing, software
11723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS,
12723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * See the License for the specific language governing permissions and
14723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * limitations under the License.
15723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris */
16723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
17723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#ifndef _LIBUNWINDSTACK_MEMORY_H
18723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#define _LIBUNWINDSTACK_MEMORY_H
19723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
20723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <stdint.h>
21723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <sys/types.h>
22723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <unistd.h>
23723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
24723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <string>
253958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris#include <vector>
26723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
27d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferrisnamespace unwindstack {
289416703f5b37cde61fe8f3e3572b84b21e06ea81Christopher Ferris
29723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass Memory {
30723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
31723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  Memory() = default;
32723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~Memory() = default;
33723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
34723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX);
35723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
36723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual bool Read(uint64_t addr, void* dst, size_t size) = 0;
37723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
38f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris  inline bool ReadField(uint64_t addr, void* start, void* field, size_t size) {
39f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    if (reinterpret_cast<uintptr_t>(field) < reinterpret_cast<uintptr_t>(start)) {
40f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris      return false;
41f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    }
42f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    uint64_t offset = reinterpret_cast<uintptr_t>(field) - reinterpret_cast<uintptr_t>(start);
43f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    if (__builtin_add_overflow(addr, offset, &offset)) {
44f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris      return false;
45f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    }
46f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    // The read will check if offset + size overflows.
47f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris    return Read(offset, field, size);
48723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  }
49723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
50d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris  inline bool Read32(uint64_t addr, uint32_t* dst) { return Read(addr, dst, sizeof(uint32_t)); }
51723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
52d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris  inline bool Read64(uint64_t addr, uint64_t* dst) { return Read(addr, dst, sizeof(uint64_t)); }
53723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
54723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
553958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferrisclass MemoryBuffer : public Memory {
563958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris public:
573958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  MemoryBuffer() = default;
583958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  virtual ~MemoryBuffer() = default;
593958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
603958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
613958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
623958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  uint8_t* GetPtr(size_t offset);
633958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
643958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  void Resize(size_t size) { raw_.resize(size); }
653958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
663958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  uint64_t Size() { return raw_.size(); }
673958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
683958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris private:
693958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  std::vector<uint8_t> raw_;
703958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris};
713958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
72723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass MemoryFileAtOffset : public Memory {
73723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
74723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  MemoryFileAtOffset() = default;
75723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~MemoryFileAtOffset();
76723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
773958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX);
78723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
79723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
80723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
813958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris  void Clear();
823958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris
83723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris protected:
84723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  size_t size_ = 0;
85723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  size_t offset_ = 0;
86723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  uint8_t* data_ = nullptr;
87723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
88723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
89723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass MemoryOffline : public MemoryFileAtOffset {
90723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
91723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  MemoryOffline() = default;
92723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~MemoryOffline() = default;
93723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
94723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  bool Init(const std::string& file, uint64_t offset);
95723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
96723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
97723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
98723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris private:
99723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  uint64_t start_;
100723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
101723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
102723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass MemoryRemote : public Memory {
103723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
104723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  MemoryRemote(pid_t pid) : pid_(pid) {}
105723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~MemoryRemote() = default;
106723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
107723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
108723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
109723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  pid_t pid() { return pid_; }
110723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
111f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris protected:
112f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris  virtual bool PtraceRead(uint64_t addr, long* value);
113f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris
114723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris private:
115723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  pid_t pid_;
116723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
117723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
118723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass MemoryLocal : public Memory {
119723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
120723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  MemoryLocal() = default;
121723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~MemoryLocal() = default;
122723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
123723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
124723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
125723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
126723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass MemoryRange : public Memory {
127723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public:
128d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris  MemoryRange(Memory* memory, uint64_t begin, uint64_t end);
129723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  virtual ~MemoryRange() { delete memory_; }
130723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
131f447c8eb205d899085968a0a8dfae861ef56a589Christopher Ferris  bool Read(uint64_t addr, void* dst, size_t size) override;
132723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
133723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris private:
134723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  Memory* memory_;
135723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  uint64_t begin_;
136723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris  uint64_t length_;
137723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris};
138723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris
139d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris}  // namespace unwindstack
140d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris
141723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#endif  // _LIBUNWINDSTACK_MEMORY_H
142