| 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 |