OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #ifndef CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ | 15 #ifndef CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ |
16 #define CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ | 16 #define CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ |
17 | 17 |
18 #include <mach/mach.h> | 18 #include <mach/mach.h> |
19 | 19 |
20 #include <string> | 20 #include <string> |
21 | 21 |
22 #include "base/basictypes.h" | 22 #include "base/basictypes.h" |
| 23 #include "base/mac/scoped_mach_vm.h" |
| 24 #include "base/memory/scoped_ptr.h" |
23 | 25 |
24 namespace crashpad { | 26 namespace crashpad { |
25 | 27 |
26 //! \brief Accesses the memory of another Mach task. | 28 //! \brief Accesses the memory of another Mach task. |
27 class TaskMemory { | 29 class TaskMemory { |
28 public: | 30 public: |
| 31 //! \brief A memory region mapped from another Mach task. |
| 32 //! |
| 33 //! The mapping is maintained until this object is destroyed. |
| 34 class MappedMemory { |
| 35 public: |
| 36 ~MappedMemory(); |
| 37 |
| 38 //! \brief Returns a pointer to the data requested by the user. |
| 39 //! |
| 40 //! This is the value of the \a vm_address + \a user_offset parameters |
| 41 //! passed to the constructor, casted to `const void*`. |
| 42 const void* data() const { return data_; } |
| 43 |
| 44 //! \brief Reads a `NUL`-terminated C string from the mapped region. |
| 45 //! |
| 46 //! This method will read contiguous memory until a `NUL` terminator is |
| 47 //! found. |
| 48 //! |
| 49 //! \param[in] offset The offset into data() of the string to be read. |
| 50 //! \param[out] string The string, whose contents begin at data() and |
| 51 //! continue up to a `NUL` terminator. |
| 52 //! |
| 53 //! \return `true` on success, with \a string set appropriately. If \a |
| 54 //! offset is greater than or equal to the \a user_size constructor |
| 55 //! parameter, or if no `NUL` terminator was found in data() after \a |
| 56 //! offset, returns `false` with an appropriate warning logged. |
| 57 bool ReadCString(size_t offset, std::string* string) const; |
| 58 |
| 59 private: |
| 60 //! \brief Creates an object that owns a memory region mapped from another |
| 61 //! Mach task. |
| 62 //! |
| 63 //! \param[in] vm_address The address in this process’ address space where |
| 64 //! the mapping begins. This must be page-aligned. |
| 65 //! \param[in] vm_size The total size of the mapping that begins at \a |
| 66 //! vm_address. This must be page-aligned. |
| 67 //! \param[in] user_offset The offset into the mapped region where the data |
| 68 //! requested by the user begins. This accounts for the fact that a |
| 69 //! mapping must be page-aligned but the user data may not be. This |
| 70 //! parameter must be equal to or less than \a vm_size. |
| 71 //! \param[in] user_size The size of the data requested by the user. This |
| 72 //! parameter can be used to compute the end address of user data, which |
| 73 //! must be within the mapped region. |
| 74 MappedMemory(vm_address_t vm_address, |
| 75 size_t vm_size, |
| 76 size_t user_offset, |
| 77 size_t user_size); |
| 78 |
| 79 base::mac::ScopedMachVM vm_; |
| 80 const void* data_; |
| 81 size_t user_size_; |
| 82 |
| 83 // The outer class needs to be able to call this class’ private constructor. |
| 84 friend class TaskMemory; |
| 85 |
| 86 DISALLOW_COPY_AND_ASSIGN(MappedMemory); |
| 87 }; |
| 88 |
29 //! \param[in] task A send right to the target task’s task port. This object | 89 //! \param[in] task A send right to the target task’s task port. This object |
30 //! does not take ownership of the send right. | 90 //! does not take ownership of the send right. |
31 explicit TaskMemory(mach_port_t task); | 91 explicit TaskMemory(mach_port_t task); |
32 | 92 |
33 ~TaskMemory() {} | 93 ~TaskMemory() {} |
34 | 94 |
35 //! \brief Copies memory from the target task into a user-provided buffer in | 95 //! \brief Copies memory from the target task into a caller-provided buffer in |
36 //! the current task. | 96 //! the current task. |
37 //! | 97 //! |
38 //! \param[in] address The address, in the target task’s address space, of the | 98 //! \param[in] address The address, in the target task’s address space, of the |
39 //! memory region to copy. | 99 //! memory region to copy. |
40 //! \param[in] size The size, in bytes, of the memory region to copy. \a | 100 //! \param[in] size The size, in bytes, of the memory region to copy. \a |
41 //! buffer must be at least this size. | 101 //! buffer must be at least this size. |
42 //! \param[out] buffer The buffer into which the contents of the other task’s | 102 //! \param[out] buffer The buffer into which the contents of the other task’s |
43 //! memory will be copied. | 103 //! memory will be copied. |
44 //! | 104 //! |
45 //! \return `true` on success, with \a buffer filled appropriately. `false` on | 105 //! \return `true` on success, with \a buffer filled appropriately. `false` on |
46 //! failure, with a warning logged. Failures can occur, for example, when | 106 //! failure, with a warning logged. Failures can occur, for example, when |
47 //! encountering unmapped or unreadable pages. | 107 //! encountering unmapped or unreadable pages. |
| 108 //! |
| 109 //! \sa ReadMapped() |
48 bool Read(mach_vm_address_t address, size_t size, void* buffer); | 110 bool Read(mach_vm_address_t address, size_t size, void* buffer); |
49 | 111 |
| 112 //! \brief Maps memory from the target task into the current task. |
| 113 //! |
| 114 //! This interface is an alternative to Read() that does not require the |
| 115 //! caller to provide a buffer to fill. This avoids copying memory, which can |
| 116 //! offer a performance improvement. |
| 117 //! |
| 118 //! \param[in] address The address, in the target task’s address space, of the |
| 119 //! memory region to map. |
| 120 //! \param[in] size The size, in bytes, of the memory region to map. |
| 121 //! |
| 122 //! \return On success, a MappedMemory object that provides access to the data |
| 123 //! requested. On faliure, `NULL`, with a warning logged. Failures can |
| 124 //! occur, for example, when encountering unmapped or unreadable pages. |
| 125 scoped_ptr<MappedMemory> ReadMapped(mach_vm_address_t address, size_t size); |
| 126 |
50 //! \brief Reads a `NUL`-terminated C string from the target task into a | 127 //! \brief Reads a `NUL`-terminated C string from the target task into a |
51 //! string in the current task. | 128 //! string in the current task. |
52 //! | 129 //! |
53 //! The length of the string need not be known ahead of time. This method will | 130 //! The length of the string need not be known ahead of time. This method will |
54 //! read contiguous memory until a `NUL` terminator is found. | 131 //! read contiguous memory until a `NUL` terminator is found. |
55 //! | 132 //! |
56 //! \param[in] address The address, in the target task’s address space, of the | 133 //! \param[in] address The address, in the target task’s address space, of the |
57 //! string to copy. | 134 //! string to copy. |
58 //! \param[out] string The string read from the other task. | 135 //! \param[out] string The string read from the other task. |
59 //! | 136 //! |
60 //! \return `true` on success, with \a string set appropriately. `false` on | 137 //! \return `true` on success, with \a string set appropriately. `false` on |
61 //! failure, with a warning logged. Failures can occur, for example, when | 138 //! failure, with a warning logged. Failures can occur, for example, when |
62 //! encountering unmapped or unreadable pages. | 139 //! encountering unmapped or unreadable pages. |
| 140 //! |
| 141 //! \sa MappedMemory::ReadCString() |
63 bool ReadCString(mach_vm_address_t address, std::string* string); | 142 bool ReadCString(mach_vm_address_t address, std::string* string); |
64 | 143 |
65 //! \brief Reads a `NUL`-terminated C string from the target task into a | 144 //! \brief Reads a `NUL`-terminated C string from the target task into a |
66 //! string in the current task. | 145 //! string in the current task. |
67 //! | 146 //! |
68 //! \param[in] address The address, in the target task’s address space, of the | 147 //! \param[in] address The address, in the target task’s address space, of the |
69 //! string to copy. | 148 //! string to copy. |
70 //! \param[in] size The maximum number of bytes to read. The string is | 149 //! \param[in] size The maximum number of bytes to read. The string is |
71 //! required to be `NUL`-terminated within this many bytes. | 150 //! required to be `NUL`-terminated within this many bytes. |
72 //! \param[out] string The string read from the other task. | 151 //! \param[out] string The string read from the other task. |
73 //! | 152 //! |
74 //! \return `true` on success, with \a string set appropriately. `false` on | 153 //! \return `true` on success, with \a string set appropriately. `false` on |
75 //! failure, with a warning logged. Failures can occur, for example, when | 154 //! failure, with a warning logged. Failures can occur, for example, when |
76 //! a `NUL` terminator is not found within \a size bytes, or when | 155 //! a `NUL` terminator is not found within \a size bytes, or when |
77 //! encountering unmapped or unreadable pages. | 156 //! encountering unmapped or unreadable pages. |
| 157 //! |
| 158 //! \sa MappedMemory::ReadCString() |
78 bool ReadCStringSizeLimited(mach_vm_address_t address, | 159 bool ReadCStringSizeLimited(mach_vm_address_t address, |
79 mach_vm_size_t size, | 160 mach_vm_size_t size, |
80 std::string* string); | 161 std::string* string); |
81 | 162 |
82 private: | 163 private: |
83 // The common internal implementation shared by the ReadCString*() methods. | 164 // The common internal implementation shared by the ReadCString*() methods. |
84 bool ReadCStringInternal(mach_vm_address_t address, | 165 bool ReadCStringInternal(mach_vm_address_t address, |
85 bool has_size, | 166 bool has_size, |
86 mach_vm_size_t size, | 167 mach_vm_size_t size, |
87 std::string* string); | 168 std::string* string); |
88 | 169 |
89 mach_port_t task_; // weak | 170 mach_port_t task_; // weak |
90 | 171 |
91 DISALLOW_COPY_AND_ASSIGN(TaskMemory); | 172 DISALLOW_COPY_AND_ASSIGN(TaskMemory); |
92 }; | 173 }; |
93 | 174 |
94 } // namespace crashpad | 175 } // namespace crashpad |
95 | 176 |
96 #endif // CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ | 177 #endif // CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ |
OLD | NEW |