mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[lldb][API] Add Find(Ranges)InMemory() to Process SB API (#95007)
Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb
This commit is contained in:
@@ -2007,6 +2007,129 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
size_t max_matches) {
|
||||
// Inputs are already validated in FindInMemory() functions.
|
||||
assert(buf != nullptr);
|
||||
assert(size > 0);
|
||||
assert(alignment > 0);
|
||||
assert(max_matches > 0);
|
||||
assert(start_addr != LLDB_INVALID_ADDRESS);
|
||||
assert(end_addr != LLDB_INVALID_ADDRESS);
|
||||
assert(start_addr < end_addr);
|
||||
|
||||
lldb::addr_t start = llvm::alignTo(start_addr, alignment);
|
||||
while (matches.size() < max_matches && (start + size) < end_addr) {
|
||||
const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
|
||||
if (found_addr == LLDB_INVALID_ADDRESS)
|
||||
break;
|
||||
|
||||
if (found_addr % alignment) {
|
||||
// We need to check the alignment because the FindInMemory uses a special
|
||||
// algorithm to efficiently search mememory but doesn't support alignment.
|
||||
start = llvm::alignTo(start + 1, alignment);
|
||||
continue;
|
||||
}
|
||||
|
||||
matches.emplace_back(found_addr, size);
|
||||
start = found_addr + alignment;
|
||||
}
|
||||
}
|
||||
|
||||
AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
|
||||
const AddressRanges &ranges,
|
||||
size_t alignment, size_t max_matches,
|
||||
Status &error) {
|
||||
AddressRanges matches;
|
||||
if (buf == nullptr) {
|
||||
error.SetErrorString("buffer is null");
|
||||
return matches;
|
||||
}
|
||||
if (size == 0) {
|
||||
error.SetErrorString("buffer size is zero");
|
||||
return matches;
|
||||
}
|
||||
if (ranges.empty()) {
|
||||
error.SetErrorString("empty ranges");
|
||||
return matches;
|
||||
}
|
||||
if (alignment == 0) {
|
||||
error.SetErrorString("alignment must be greater than zero");
|
||||
return matches;
|
||||
}
|
||||
if (max_matches == 0) {
|
||||
error.SetErrorString("max_matches must be greater than zero");
|
||||
return matches;
|
||||
}
|
||||
|
||||
int resolved_ranges = 0;
|
||||
Target &target = GetTarget();
|
||||
for (size_t i = 0; i < ranges.size(); ++i) {
|
||||
if (matches.size() >= max_matches)
|
||||
break;
|
||||
const AddressRange &range = ranges[i];
|
||||
if (range.IsValid() == false)
|
||||
continue;
|
||||
|
||||
const lldb::addr_t start_addr =
|
||||
range.GetBaseAddress().GetLoadAddress(&target);
|
||||
if (start_addr == LLDB_INVALID_ADDRESS)
|
||||
continue;
|
||||
|
||||
++resolved_ranges;
|
||||
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
|
||||
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment,
|
||||
max_matches);
|
||||
}
|
||||
|
||||
if (resolved_ranges > 0)
|
||||
error.Clear();
|
||||
else
|
||||
error.SetErrorString("unable to resolve any ranges");
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
lldb::addr_t Process::FindInMemory(const uint8_t *buf, uint64_t size,
|
||||
const AddressRange &range, size_t alignment,
|
||||
Status &error) {
|
||||
if (buf == nullptr) {
|
||||
error.SetErrorString("buffer is null");
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
if (size == 0) {
|
||||
error.SetErrorString("buffer size is zero");
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
if (!range.IsValid()) {
|
||||
error.SetErrorString("range is invalid");
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
if (alignment == 0) {
|
||||
error.SetErrorString("alignment must be greater than zero");
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
Target &target = GetTarget();
|
||||
const lldb::addr_t start_addr =
|
||||
range.GetBaseAddress().GetLoadAddress(&target);
|
||||
if (start_addr == LLDB_INVALID_ADDRESS) {
|
||||
error.SetErrorString("range load address is invalid");
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
|
||||
|
||||
AddressRanges matches;
|
||||
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, 1);
|
||||
if (matches.empty())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
error.Clear();
|
||||
return matches[0].GetBaseAddress().GetLoadAddress(&target);
|
||||
}
|
||||
|
||||
size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str,
|
||||
Status &error) {
|
||||
char buf[256];
|
||||
|
||||
Reference in New Issue
Block a user