-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[lldb] Implement Process::ReadMemoryRanges #163651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
5b143dd
58d7eda
1bcac34
52aae17
d498717
1b470fb
c1434e4
6e13b80
f5e4358
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1971,6 +1971,45 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { | |
| } | ||
| } | ||
|
|
||
| llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> | ||
| Process::ReadMemoryRanges(llvm::ArrayRef<Range<lldb::addr_t, size_t>> ranges, | ||
| llvm::MutableArrayRef<uint8_t> buffer) { | ||
| auto total_ranges_len = llvm::sum_of( | ||
| llvm::map_range(ranges, [](auto range) { return range.size; })); | ||
| // If the buffer is not large enough, this is a programmer error. | ||
| // In production builds, gracefully fail by returning empty chunks. | ||
| assert(buffer.size() >= total_ranges_len); | ||
| if (buffer.size() < total_ranges_len) | ||
| return llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>(ranges.size()); | ||
|
||
|
|
||
| llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> results; | ||
|
|
||
| // While `buffer` has space, take the next requested range and read | ||
| // memory into a `buffer` chunk, then slice it to remove the used chunk. | ||
| for (auto [addr, range_len] : ranges) { | ||
| Status status; | ||
| size_t num_bytes_read = | ||
| ReadMemoryFromInferior(addr, buffer.data(), range_len, status); | ||
| // FIXME: ReadMemoryFromInferior promises to return 0 in case of errors, but | ||
| // it doesn't; it never checks for errors. | ||
| if (status.Fail()) | ||
| num_bytes_read = 0; | ||
|
|
||
| assert(num_bytes_read <= range_len && "read more than requested bytes"); | ||
| if (num_bytes_read > range_len) { | ||
| // In production builds, gracefully fail by returning an empty chunk. | ||
| results.emplace_back(); | ||
DavidSpickett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| continue; | ||
| } | ||
|
|
||
| results.push_back(buffer.take_front(num_bytes_read)); | ||
| // Slice buffer to remove the used chunk. | ||
| buffer = buffer.drop_front(num_bytes_read); | ||
DavidSpickett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| return results; | ||
| } | ||
|
|
||
| void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, | ||
| const uint8_t *buf, size_t size, | ||
| AddressRanges &matches, size_t alignment, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.