summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Target.cpp
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2013-01-21 19:20:50 +0000
committerEnrico Granata <egranata@apple.com>2013-01-21 19:20:50 +0000
commit6b4ddc655a3dafc53e98efd9560ee8185ae717fc (patch)
tree754719972dbd38cab3e3dec13af9478ade7e9561 /lldb/source/Target/Target.cpp
parent2cec01916c47a097f8777c85c22e66a88b684949 (diff)
downloadbcm5719-llvm-6b4ddc655a3dafc53e98efd9560ee8185ae717fc.tar.gz
bcm5719-llvm-6b4ddc655a3dafc53e98efd9560ee8185ae717fc.zip
<rdar://problem/12437929>
Providing a special mode of operator for "memory read -f c-str" which actually works in most common cases Where the old behavior would provide: (lldb) mem read --format s `foo` 0x100000f5d: NULL Now we do: (lldb) mem read --format s `foo` 0x100000f5d: "hello world" You can also specify a count and that many strings will be showed starting at the initial address: (lldb) mem read -c 2 -f c-str `foo` 0x100000f1d: "hello world" 0x100000f29: "short" llvm-svn: 173076
Diffstat (limited to 'lldb/source/Target/Target.cpp')
-rw-r--r--lldb/source/Target/Target.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 6238d2e337f..435081c8bba 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1327,6 +1327,82 @@ Target::ReadMemory (const Address& addr,
}
size_t
+Target::ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error)
+{
+ char buf[256];
+ out_str.clear();
+ addr_t curr_addr = addr.GetLoadAddress(this);
+ Address address(addr);
+ while (1)
+ {
+ size_t length = ReadCStringFromMemory (address, buf, sizeof(buf), error);
+ if (length == 0)
+ break;
+ out_str.append(buf, length);
+ // If we got "length - 1" bytes, we didn't get the whole C string, we
+ // need to read some more characters
+ if (length == sizeof(buf) - 1)
+ curr_addr += length;
+ else
+ break;
+ address = Address(curr_addr);
+ }
+ return out_str.size();
+}
+
+
+size_t
+Target::ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error)
+{
+ size_t total_cstr_len = 0;
+ if (dst && dst_max_len)
+ {
+ result_error.Clear();
+ // NULL out everything just to be safe
+ memset (dst, 0, dst_max_len);
+ Error error;
+ addr_t curr_addr = addr.GetLoadAddress(this);
+ Address address(addr);
+ const size_t cache_line_size = 512;
+ size_t bytes_left = dst_max_len - 1;
+ char *curr_dst = dst;
+
+ while (bytes_left > 0)
+ {
+ addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+ addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+ size_t bytes_read = ReadMemory (address, false, curr_dst, bytes_to_read, error);
+
+ if (bytes_read == 0)
+ {
+ result_error = error;
+ dst[total_cstr_len] = '\0';
+ break;
+ }
+ const size_t len = strlen(curr_dst);
+
+ total_cstr_len += len;
+
+ if (len < bytes_to_read)
+ break;
+
+ curr_dst += bytes_read;
+ curr_addr += bytes_read;
+ bytes_left -= bytes_read;
+ address = Address(curr_addr);
+ }
+ }
+ else
+ {
+ if (dst == NULL)
+ result_error.SetErrorString("invalid arguments");
+ else
+ result_error.Clear();
+ }
+ return total_cstr_len;
+}
+
+size_t
Target::ReadScalarIntegerFromMemory (const Address& addr,
bool prefer_file_cache,
uint32_t byte_size,
OpenPOWER on IntegriCloud