diff options
| author | Florian Mayer <fmayer@google.com> | 2025-10-22 10:55:10 -0700 |
|---|---|---|
| committer | Florian Mayer <fmayer@google.com> | 2025-10-22 10:55:10 -0700 |
| commit | a0abc0af0a0a90878822f8107d70dad6f7cdfc26 (patch) | |
| tree | 3317f49277cc325327cfe3d9a7be4b6e9bacd0f5 /lldb/source/Target/Process.cpp | |
| parent | e8230892228fd3b3e543c869f1238fa199d48bc1 (diff) | |
| parent | 735b1ad667ac7373c89ccc0f0e757ef418f8f790 (diff) | |
[𝘀𝗽𝗿] changes introduced through rebaseusers/fmayer/spr/main.wip-smartpointers
Created using spr 1.3.7
[skip ci]
Diffstat (limited to 'lldb/source/Target/Process.cpp')
| -rw-r--r-- | lldb/source/Target/Process.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 3176852f0b72..fb9e7eb5ed1b 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1971,6 +1971,49 @@ 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 a length of 0 for all + // ranges. + assert(buffer.size() >= total_ranges_len && "provided buffer is too short"); + if (buffer.size() < total_ranges_len) { + llvm::MutableArrayRef<uint8_t> empty; + return {ranges.size(), empty}; + } + + llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> results; + + // While `buffer` has space, take the next requested range and read + // memory into a `buffer` piece, then slice it to remove the used memory. + 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 length zero for this + // range. + results.emplace_back(); + continue; + } + + results.push_back(buffer.take_front(num_bytes_read)); + // Slice buffer to remove the used memory. + buffer = buffer.drop_front(num_bytes_read); + } + + 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, |
