Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: util/mach/task_memory.cc

Issue 558313002: Add a MappedMemory interface to TaskMemory and use it in MachOImageSymbolTableReader (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Use vm_region_64() instead of mach_vm_region() Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mach/task_memory.h ('k') | util/mach/task_memory_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "util/mach/task_memory.h" 15 #include "util/mach/task_memory.h"
16 16
17 #include <mach/mach_vm.h> 17 #include <mach/mach_vm.h>
18 #include <string.h> 18 #include <string.h>
19 19
20 #include <algorithm> 20 #include <algorithm>
21 21
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/mac/mach_logging.h" 23 #include "base/mac/mach_logging.h"
24 #include "base/mac/scoped_mach_vm.h"
25 #include "base/strings/stringprintf.h" 24 #include "base/strings/stringprintf.h"
25 #include "util/stdlib/strnlen.h"
26 26
27 namespace crashpad { 27 namespace crashpad {
28 28
29 TaskMemory::MappedMemory::~MappedMemory() {
30 }
31
32 bool TaskMemory::MappedMemory::ReadCString(
33 size_t offset, std::string* string) const {
34 if (offset >= user_size_) {
35 LOG(WARNING) << "offset out of range";
36 return false;
37 }
38
39 const char* string_base = reinterpret_cast<const char*>(data_) + offset;
40 size_t max_length = user_size_ - offset;
41 size_t string_length = strnlen(string_base, max_length);
42 if (string_length == max_length) {
43 LOG(WARNING) << "unterminated string";
44 return false;
45 }
46
47 string->assign(string_base, string_length);
48 return true;
49 }
50
51 TaskMemory::MappedMemory::MappedMemory(vm_address_t vm_address,
52 size_t vm_size,
53 size_t user_offset,
54 size_t user_size)
55 : vm_(vm_address, vm_size),
56 data_(reinterpret_cast<const void*>(vm_address + user_offset)),
57 user_size_(user_size) {
58 vm_address_t vm_end = vm_address + vm_size;
59 vm_address_t user_address = reinterpret_cast<vm_address_t>(data_);
60 vm_address_t user_end = user_address + user_size;
61 DCHECK_GE(user_address, vm_address);
62 DCHECK_LE(user_address, vm_end);
63 DCHECK_GE(user_end, vm_address);
64 DCHECK_LE(user_end, vm_end);
65 }
66
29 TaskMemory::TaskMemory(mach_port_t task) : task_(task) { 67 TaskMemory::TaskMemory(mach_port_t task) : task_(task) {
30 } 68 }
31 69
32 bool TaskMemory::Read(mach_vm_address_t address, size_t size, void* buffer) { 70 bool TaskMemory::Read(mach_vm_address_t address, size_t size, void* buffer) {
71 scoped_ptr<MappedMemory> memory = ReadMapped(address, size);
72 if (!memory) {
73 return false;
74 }
75
76 memcpy(buffer, memory->data(), size);
77 return true;
78 }
79
80 scoped_ptr<TaskMemory::MappedMemory> TaskMemory::ReadMapped(
81 mach_vm_address_t address, size_t size) {
33 if (size == 0) { 82 if (size == 0) {
34 return true; 83 return scoped_ptr<MappedMemory>(new MappedMemory(0, 0, 0, 0));
35 } 84 }
36 85
37 mach_vm_address_t region_address = mach_vm_trunc_page(address); 86 mach_vm_address_t region_address = mach_vm_trunc_page(address);
38 mach_vm_size_t region_size = 87 mach_vm_size_t region_size =
39 mach_vm_round_page(address - region_address + size); 88 mach_vm_round_page(address - region_address + size);
40 89
41 vm_offset_t region; 90 vm_offset_t region;
42 mach_msg_type_number_t region_count; 91 mach_msg_type_number_t region_count;
43 kern_return_t kr = 92 kern_return_t kr =
44 mach_vm_read(task_, region_address, region_size, &region, &region_count); 93 mach_vm_read(task_, region_address, region_size, &region, &region_count);
45 if (kr != KERN_SUCCESS) { 94 if (kr != KERN_SUCCESS) {
46 MACH_LOG(WARNING, kr) << base::StringPrintf( 95 MACH_LOG(WARNING, kr) << base::StringPrintf(
47 "mach_vm_read(0x%llx, 0x%llx)", region_address, region_size); 96 "mach_vm_read(0x%llx, 0x%llx)", region_address, region_size);
48 return false; 97 return scoped_ptr<MappedMemory>();
49 } 98 }
50 99
51 DCHECK_EQ(region_count, region_size); 100 DCHECK_EQ(region_count, region_size);
52 base::mac::ScopedMachVM region_owner(region, region_count); 101 return scoped_ptr<MappedMemory>(
53 102 new MappedMemory(region, region_size, address - region_address, size));
54 const char* region_base = reinterpret_cast<const char*>(region);
55 memcpy(buffer, &region_base[address - region_address], size);
56
57 return true;
58 } 103 }
59 104
60 bool TaskMemory::ReadCString(mach_vm_address_t address, std::string* string) { 105 bool TaskMemory::ReadCString(mach_vm_address_t address, std::string* string) {
61 return ReadCStringInternal(address, false, 0, string); 106 return ReadCStringInternal(address, false, 0, string);
62 } 107 }
63 108
64 bool TaskMemory::ReadCStringSizeLimited(mach_vm_address_t address, 109 bool TaskMemory::ReadCStringSizeLimited(mach_vm_address_t address,
65 mach_vm_size_t size, 110 mach_vm_size_t size,
66 std::string* string) { 111 std::string* string) {
67 return ReadCStringInternal(address, true, size, string); 112 return ReadCStringInternal(address, true, size, string);
(...skipping 10 matching lines...) Expand all
78 } 123 }
79 } else { 124 } else {
80 size = PAGE_SIZE; 125 size = PAGE_SIZE;
81 } 126 }
82 127
83 std::string local_string; 128 std::string local_string;
84 mach_vm_address_t read_address = address; 129 mach_vm_address_t read_address = address;
85 do { 130 do {
86 mach_vm_size_t read_length = 131 mach_vm_size_t read_length =
87 std::min(size, PAGE_SIZE - (read_address % PAGE_SIZE)); 132 std::min(size, PAGE_SIZE - (read_address % PAGE_SIZE));
88 std::string read_string(read_length, '\0'); 133 scoped_ptr<MappedMemory> read_region =
89 if (!Read(read_address, read_length, &read_string[0])) { 134 ReadMapped(read_address, read_length);
135 if (!read_region) {
90 return false; 136 return false;
91 } 137 }
92 138
93 size_t terminator = read_string.find_first_of('\0'); 139 const char* read_region_data =
94 if (terminator == std::string::npos) { 140 reinterpret_cast<const char*>(read_region->data());
95 local_string.append(read_string); 141 size_t read_region_data_length = strnlen(read_region_data, read_length);
96 } else { 142 local_string.append(read_region_data, read_region_data_length);
97 local_string.append(read_string, 0, terminator); 143 if (read_region_data_length < read_length) {
98 string->swap(local_string); 144 string->swap(local_string);
99 return true; 145 return true;
100 } 146 }
101 147
102 if (has_size) { 148 if (has_size) {
103 size -= read_length; 149 size -= read_length;
104 } 150 }
105 read_address = mach_vm_trunc_page(read_address + read_length); 151 read_address = mach_vm_trunc_page(read_address + read_length);
106 } while ((!has_size || size > 0) && read_address > address); 152 } while ((!has_size || size > 0) && read_address > address);
107 153
108 LOG(WARNING) << base::StringPrintf("unterminated string at 0x%llx", address); 154 LOG(WARNING) << base::StringPrintf("unterminated string at 0x%llx", address);
109 return false; 155 return false;
110 } 156 }
111 157
112 } // namespace crashpad 158 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/mach/task_memory.h ('k') | util/mach/task_memory_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698