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 //! \brief Creates an object that owns a memory region mapped from another | |
37 //! Mach task. | |
38 //! | |
39 //! \param[in] vm_address The address in this process’ address space where | |
40 //! the mapping begins. This must be page-aligned. | |
41 //! \param[in] vm_size The total size of the mapping that begins at \a | |
42 //! vm_address. This must be page-aligned. | |
43 //! \param[in] user_offset The offset into the mapped region where the data | |
Robert Sesek
2014/09/10 21:37:40
Can you just accept the user variants and do the p
Mark Mentovai
2014/09/10 22:16:56
rsesek wrote:
| |
44 //! requested by the user begins. This accounts for the fact that a | |
45 //! mapping must be page-aligned but the user data may not be. This | |
46 //! parameter must be equal to or less than \a vm_size. | |
47 //! \param[in] user_size The size of the data requested by the user. This | |
48 //! parameter can be used to compute the end address of user data, which | |
49 //! must be within the mapped region. | |
50 MappedMemory(vm_address_t vm_address, | |
Robert Sesek
2014/09/10 21:37:40
Can callers meaningfully call this ctor outside of
| |
51 size_t vm_size, | |
52 size_t user_offset, | |
53 size_t user_size); | |
54 ~MappedMemory(); | |
55 | |
56 //! \brief Returns a pointer to the data requested by the user. | |
57 //! | |
58 //! This is the value of the \a vm_address + \a user_offset parameters | |
59 //! passed to the constructor, casted to `const void*`. | |
60 const void* data() const { return data_; } | |
61 | |
62 //! \brief Reads a `NUL`-terminated C string from the mapped region. | |
63 //! | |
64 //! This method will read contiguous memory until a `NUL` terminator is | |
Robert Sesek
2014/09/10 21:37:41
Your test demonstrates that this will also read un
Mark Mentovai
2014/09/10 22:16:56
rsesek wrote:
Robert Sesek
2014/09/11 18:42:35
Sorry, forgot that the C string literal will end i
| |
65 //! found. | |
66 //! | |
67 //! \param[in] offset The offset into data() of the string to be read. | |
68 //! \param[out] string The string, whose contents begin at data() and | |
69 //! continue up to a `NUL` terminator. | |
70 //! | |
71 //! \return `true` on success, with \a string set appropriately. If \a | |
72 //! offset is greater than or equal to the \a user_size constructor | |
73 //! parameter, or if no `NUL` terminator was found in data() after \a | |
74 //! offset, returns `false` with an appropriate warning logged. | |
75 bool ReadCString(size_t offset, std::string* string) const; | |
76 | |
77 private: | |
78 base::mac::ScopedMachVM vm_; | |
79 const void* data_; | |
80 size_t user_size_; | |
81 | |
82 DISALLOW_COPY_AND_ASSIGN(MappedMemory); | |
83 }; | |
84 | |
29 //! \param[in] task A send right to the target task’s task port. This object | 85 //! \param[in] task A send right to the target task’s task port. This object |
30 //! does not take ownership of the send right. | 86 //! does not take ownership of the send right. |
31 explicit TaskMemory(mach_port_t task); | 87 explicit TaskMemory(mach_port_t task); |
32 | 88 |
33 ~TaskMemory() {} | 89 ~TaskMemory() {} |
34 | 90 |
35 //! \brief Copies memory from the target task into a user-provided buffer in | 91 //! \brief Copies memory from the target task into a caller-provided buffer in |
36 //! the current task. | 92 //! the current task. |
37 //! | 93 //! |
38 //! \param[in] address The address, in the target task’s address space, of the | 94 //! \param[in] address The address, in the target task’s address space, of the |
39 //! memory region to copy. | 95 //! memory region to copy. |
40 //! \param[in] size The size, in bytes, of the memory region to copy. \a | 96 //! \param[in] size The size, in bytes, of the memory region to copy. \a |
41 //! buffer must be at least this size. | 97 //! buffer must be at least this size. |
42 //! \param[out] buffer The buffer into which the contents of the other task’s | 98 //! \param[out] buffer The buffer into which the contents of the other task’s |
43 //! memory will be copied. | 99 //! memory will be copied. |
44 //! | 100 //! |
45 //! \return `true` on success, with \a buffer filled appropriately. `false` on | 101 //! \return `true` on success, with \a buffer filled appropriately. `false` on |
46 //! failure, with a warning logged. Failures can occur, for example, when | 102 //! failure, with a warning logged. Failures can occur, for example, when |
47 //! encountering unmapped or unreadable pages. | 103 //! encountering unmapped or unreadable pages. |
104 //! | |
105 //! \sa ReadMapped() | |
48 bool Read(mach_vm_address_t address, size_t size, void* buffer); | 106 bool Read(mach_vm_address_t address, size_t size, void* buffer); |
49 | 107 |
108 //! \brief Maps memory from the target task into the current task. | |
109 //! | |
110 //! This interface is an alternative to Read() that does not require the | |
111 //! caller to provide a buffer to fill. This avoids copying memory, which can | |
112 //! offer a performance improvement. | |
113 //! | |
114 //! \param[in] address The address, in the target task’s address space, of the | |
115 //! memory region to map. | |
116 //! \param[in] size The size, in bytes, of the memory region to map. | |
117 //! | |
118 //! \return On success, a MappedMemory object that provides access to the data | |
119 //! requested. On faliure, `NULL`, with a warning logged. Failures can | |
120 //! occur, for example, when encountering unmapped or unreadable pages. | |
121 scoped_ptr<MappedMemory> ReadMapped(mach_vm_address_t address, size_t size); | |
122 | |
50 //! \brief Reads a `NUL`-terminated C string from the target task into a | 123 //! \brief Reads a `NUL`-terminated C string from the target task into a |
51 //! string in the current task. | 124 //! string in the current task. |
52 //! | 125 //! |
53 //! The length of the string need not be known ahead of time. This method will | 126 //! 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. | 127 //! read contiguous memory until a `NUL` terminator is found. |
55 //! | 128 //! |
56 //! \param[in] address The address, in the target task’s address space, of the | 129 //! \param[in] address The address, in the target task’s address space, of the |
57 //! string to copy. | 130 //! string to copy. |
58 //! \param[out] string The string read from the other task. | 131 //! \param[out] string The string read from the other task. |
59 //! | 132 //! |
60 //! \return `true` on success, with \a string set appropriately. `false` on | 133 //! \return `true` on success, with \a string set appropriately. `false` on |
61 //! failure, with a warning logged. Failures can occur, for example, when | 134 //! failure, with a warning logged. Failures can occur, for example, when |
62 //! encountering unmapped or unreadable pages. | 135 //! encountering unmapped or unreadable pages. |
136 //! | |
137 //! \sa MappedMemory::ReadCString() | |
63 bool ReadCString(mach_vm_address_t address, std::string* string); | 138 bool ReadCString(mach_vm_address_t address, std::string* string); |
64 | 139 |
65 //! \brief Reads a `NUL`-terminated C string from the target task into a | 140 //! \brief Reads a `NUL`-terminated C string from the target task into a |
66 //! string in the current task. | 141 //! string in the current task. |
67 //! | 142 //! |
68 //! \param[in] address The address, in the target task’s address space, of the | 143 //! \param[in] address The address, in the target task’s address space, of the |
69 //! string to copy. | 144 //! string to copy. |
70 //! \param[in] size The maximum number of bytes to read. The string is | 145 //! \param[in] size The maximum number of bytes to read. The string is |
71 //! required to be `NUL`-terminated within this many bytes. | 146 //! required to be `NUL`-terminated within this many bytes. |
72 //! \param[out] string The string read from the other task. | 147 //! \param[out] string The string read from the other task. |
73 //! | 148 //! |
74 //! \return `true` on success, with \a string set appropriately. `false` on | 149 //! \return `true` on success, with \a string set appropriately. `false` on |
75 //! failure, with a warning logged. Failures can occur, for example, when | 150 //! failure, with a warning logged. Failures can occur, for example, when |
76 //! a `NUL` terminator is not found within \a size bytes, or when | 151 //! a `NUL` terminator is not found within \a size bytes, or when |
77 //! encountering unmapped or unreadable pages. | 152 //! encountering unmapped or unreadable pages. |
153 //! | |
154 //! \sa MappedMemory::ReadCString() | |
78 bool ReadCStringSizeLimited(mach_vm_address_t address, | 155 bool ReadCStringSizeLimited(mach_vm_address_t address, |
79 mach_vm_size_t size, | 156 mach_vm_size_t size, |
80 std::string* string); | 157 std::string* string); |
81 | 158 |
82 private: | 159 private: |
83 // The common internal implementation shared by the ReadCString*() methods. | 160 // The common internal implementation shared by the ReadCString*() methods. |
84 bool ReadCStringInternal(mach_vm_address_t address, | 161 bool ReadCStringInternal(mach_vm_address_t address, |
85 bool has_size, | 162 bool has_size, |
86 mach_vm_size_t size, | 163 mach_vm_size_t size, |
87 std::string* string); | 164 std::string* string); |
88 | 165 |
89 mach_port_t task_; // weak | 166 mach_port_t task_; // weak |
90 | 167 |
91 DISALLOW_COPY_AND_ASSIGN(TaskMemory); | 168 DISALLOW_COPY_AND_ASSIGN(TaskMemory); |
92 }; | 169 }; |
93 | 170 |
94 } // namespace crashpad | 171 } // namespace crashpad |
95 | 172 |
96 #endif // CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ | 173 #endif // CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ |
OLD | NEW |