Skip to content

Commit db98a70

Browse files
committed
Change Target::ReadMemory to ensure the amount of memory read from the file-cache is the amount requested.
This change ensures that if for whatever reason we read less bytes than expected (for example, when trying to read memory that spans multiple sections), we try reading from the live process as well. Reviewed By: jasonmolenda Differential Revision: https://reviews.llvm.org/D101390 (cherry picked from commit 6c82b8a)
1 parent bd4d8be commit db98a70

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

lldb/source/Target/Target.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,19 +1758,30 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
17581758
if (!resolved_addr.IsValid())
17591759
resolved_addr = addr;
17601760

1761-
bool is_readonly = false;
1761+
// If we read from the file cache but can't get as many bytes as requested,
1762+
// we keep the result around in this buffer, in case this result is the
1763+
// best we can do.
1764+
std::unique_ptr<uint8_t[]> file_cache_read_buffer;
1765+
size_t file_cache_bytes_read = 0;
1766+
17621767
// Read from file cache if read-only section.
17631768
if (!force_live_memory && resolved_addr.IsSectionOffset()) {
17641769
SectionSP section_sp(resolved_addr.GetSection());
17651770
if (section_sp) {
17661771
auto permissions = Flags(section_sp->GetPermissions());
1767-
is_readonly = !permissions.Test(ePermissionsWritable) &&
1768-
permissions.Test(ePermissionsReadable);
1769-
}
1770-
if (is_readonly) {
1771-
bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1772-
if (bytes_read > 0)
1773-
return bytes_read;
1772+
bool is_readonly = !permissions.Test(ePermissionsWritable) &&
1773+
permissions.Test(ePermissionsReadable);
1774+
if (is_readonly) {
1775+
file_cache_bytes_read =
1776+
ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1777+
if (file_cache_bytes_read == dst_len)
1778+
return file_cache_bytes_read;
1779+
else if (file_cache_bytes_read > 0) {
1780+
file_cache_read_buffer =
1781+
std::make_unique<uint8_t[]>(file_cache_bytes_read);
1782+
std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read);
1783+
}
1784+
}
17741785
}
17751786
}
17761787

@@ -1809,7 +1820,14 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
18091820
}
18101821
}
18111822

1812-
if (!is_readonly && resolved_addr.IsSectionOffset()) {
1823+
if (file_cache_read_buffer && file_cache_bytes_read > 0) {
1824+
// Reading from the process failed. If we've previously succeeded in reading
1825+
// something from the file cache, then copy that over and return that.
1826+
std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read);
1827+
return file_cache_bytes_read;
1828+
}
1829+
1830+
if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) {
18131831
// If we didn't already try and read from the object file cache, then try
18141832
// it after failing to read from the process.
18151833
return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);

0 commit comments

Comments
 (0)