Skip to content

Commit 02345ea

Browse files
author
Miro Bucko
committed
[lldb][API] Add Find(Ranges)InMemory() to Process SB API
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
1 parent 46080ab commit 02345ea

File tree

11 files changed

+590
-6
lines changed

11 files changed

+590
-6
lines changed

lldb/bindings/python/python-typemaps.swig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ AND call SWIG_fail at the same time, because it will result in a double free.
257257
}
258258
// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
259259
%typemap(in) (const void *buf, size_t size),
260-
(const void *data, size_t data_len) {
260+
(const void *data, size_t data_len),
261+
(const void *buf, uint64_t size) {
261262
if (PythonString::Check($input)) {
262263
PythonString str(PyRefType::Borrowed, $input);
263264
$1 = (void *)str.GetString().data();

lldb/include/lldb/API/SBProcess.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ class LLDB_API SBProcess {
209209

210210
lldb::addr_t ReadPointerFromMemory(addr_t addr, lldb::SBError &error);
211211

212+
lldb::SBAddressRangeList
213+
FindRangesInMemory(const void *buf, uint64_t size, SBAddressRangeList &ranges,
214+
uint32_t alignment, uint32_t max_matches, SBError &error);
215+
216+
lldb::addr_t FindInMemory(const void *buf, uint64_t size,
217+
SBAddressRange &range, uint32_t alignment,
218+
SBError &error);
219+
212220
// Events
213221
static lldb::StateType GetStateFromEvent(const lldb::SBEvent &event);
214222

lldb/include/lldb/Core/AddressRangeListImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace lldb {
1616
class SBBlock;
17+
class SBProcess;
1718
}
1819

1920
namespace lldb_private {
@@ -40,6 +41,7 @@ class AddressRangeListImpl {
4041

4142
private:
4243
friend class lldb::SBBlock;
44+
friend class lldb::SBProcess;
4345

4446
AddressRanges &ref();
4547

lldb/include/lldb/Target/Process.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,15 @@ void PruneThreadPlans();
26852685
lldb::addr_t FindInMemory(lldb::addr_t low, lldb::addr_t high,
26862686
const uint8_t *buf, size_t size);
26872687

2688+
AddressRanges FindRangesInMemory(const uint8_t *buf, uint64_t size,
2689+
const AddressRanges &ranges,
2690+
size_t alignment, size_t max_matches,
2691+
Status &error);
2692+
2693+
lldb::addr_t FindInMemory(const uint8_t *buf, uint64_t size,
2694+
const AddressRange &range, size_t alignment,
2695+
Status &error);
2696+
26882697
protected:
26892698
friend class Trace;
26902699

@@ -2800,6 +2809,10 @@ void PruneThreadPlans();
28002809
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
28012810
Status &error) = 0;
28022811

2812+
void DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
2813+
const uint8_t *buf, size_t size, AddressRanges &matches,
2814+
size_t alignment, size_t max_matches);
2815+
28032816
/// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has
28042817
/// removed non address bits from load_addr. Override this method in
28052818
/// subclasses of Process.

lldb/source/API/SBProcess.cpp

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "lldb/lldb-defines.h"
1515
#include "lldb/lldb-types.h"
1616

17+
#include "lldb/Core/AddressRangeListImpl.h"
1718
#include "lldb/Core/Debugger.h"
1819
#include "lldb/Core/Module.h"
1920
#include "lldb/Core/PluginManager.h"
@@ -26,6 +27,7 @@
2627
#include "lldb/Target/Target.h"
2728
#include "lldb/Target/Thread.h"
2829
#include "lldb/Utility/Args.h"
30+
#include "lldb/Utility/LLDBLog.h"
2931
#include "lldb/Utility/ProcessInfo.h"
3032
#include "lldb/Utility/State.h"
3133
#include "lldb/Utility/Stream.h"
@@ -320,8 +322,8 @@ void SBProcess::ReportEventState(const SBEvent &event, FileSP out) const {
320322
if (process_sp) {
321323
StreamFile stream(out);
322324
const StateType event_state = SBProcess::GetStateFromEvent(event);
323-
stream.Printf("Process %" PRIu64 " %s\n",
324-
process_sp->GetID(), SBDebugger::StateAsCString(event_state));
325+
stream.Printf("Process %" PRIu64 " %s\n", process_sp->GetID(),
326+
SBDebugger::StateAsCString(event_state));
325327
}
326328
}
327329

@@ -378,7 +380,6 @@ bool SBProcess::SetSelectedThreadByIndexID(uint32_t index_id) {
378380
ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID(index_id);
379381
}
380382

381-
382383
return ret_val;
383384
}
384385

@@ -546,7 +547,6 @@ ByteOrder SBProcess::GetByteOrder() const {
546547
if (process_sp)
547548
byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder();
548549

549-
550550
return byteOrder;
551551
}
552552

@@ -558,7 +558,6 @@ uint32_t SBProcess::GetAddressByteSize() const {
558558
if (process_sp)
559559
size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
560560

561-
562561
return size;
563562
}
564563

@@ -810,6 +809,61 @@ const char *SBProcess::GetBroadcasterClass() {
810809
return ConstString(Process::GetStaticBroadcasterClass()).AsCString();
811810
}
812811

812+
lldb::SBAddressRangeList
813+
SBProcess::FindRangesInMemory(const void *buf, uint64_t size,
814+
SBAddressRangeList &ranges, uint32_t alignment,
815+
uint32_t max_matches, SBError &error) {
816+
LLDB_INSTRUMENT_VA(this, buf, size, ranges, alignment, max_matches, error);
817+
818+
lldb::SBAddressRangeList matches;
819+
820+
ProcessSP process_sp(GetSP());
821+
if (!process_sp) {
822+
error.SetErrorString("SBProcess is invalid");
823+
return matches;
824+
}
825+
Process::StopLocker stop_locker;
826+
if (!stop_locker.TryLock(&process_sp->GetRunLock())) {
827+
error.SetErrorString("process is running");
828+
return matches;
829+
}
830+
std::lock_guard<std::recursive_mutex> guard(
831+
process_sp->GetTarget().GetAPIMutex());
832+
matches.m_opaque_up->ref() = process_sp->FindRangesInMemory(
833+
reinterpret_cast<const uint8_t *>(buf), size, ranges.m_opaque_up->ref(),
834+
alignment, max_matches, error.ref());
835+
return matches;
836+
}
837+
838+
lldb::addr_t SBProcess::FindInMemory(const void *buf, uint64_t size,
839+
SBAddressRange &range, uint32_t alignment,
840+
SBError &error) {
841+
LLDB_INSTRUMENT_VA(this, buf, size, range, alignment, error);
842+
843+
if (!range.IsValid()) {
844+
error.SetErrorString("range is invalid");
845+
return LLDB_INVALID_ADDRESS;
846+
}
847+
848+
ProcessSP process_sp(GetSP());
849+
850+
if (!process_sp) {
851+
error.SetErrorString("SBProcess is invalid");
852+
return LLDB_INVALID_ADDRESS;
853+
}
854+
855+
Process::StopLocker stop_locker;
856+
if (!stop_locker.TryLock(&process_sp->GetRunLock())) {
857+
error.SetErrorString("process is running");
858+
return LLDB_INVALID_ADDRESS;
859+
}
860+
861+
std::lock_guard<std::recursive_mutex> guard(
862+
process_sp->GetTarget().GetAPIMutex());
863+
return process_sp->FindInMemory(reinterpret_cast<const uint8_t *>(buf), size,
864+
*range.m_opaque_up, alignment, error.ref());
865+
}
866+
813867
size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len,
814868
SBError &sb_error) {
815869
LLDB_INSTRUMENT_VA(this, addr, dst, dst_len, sb_error);

lldb/source/Target/Process.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,123 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
20072007
}
20082008
}
20092009

2010+
void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
2011+
const uint8_t *buf, size_t size,
2012+
AddressRanges &matches, size_t alignment,
2013+
size_t max_matches) {
2014+
// Inputs are already validated in FindInMemory() functions.
2015+
assert(buf != nullptr);
2016+
assert(size > 0);
2017+
assert(alignment > 0);
2018+
assert(max_matches > 0);
2019+
assert(start_addr != LLDB_INVALID_ADDRESS);
2020+
assert(end_addr != LLDB_INVALID_ADDRESS);
2021+
assert(start_addr < end_addr);
2022+
2023+
lldb::addr_t start = start_addr;
2024+
while (matches.size() < max_matches && (start + size) < end_addr) {
2025+
const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
2026+
if (found_addr == LLDB_INVALID_ADDRESS)
2027+
break;
2028+
matches.emplace_back(found_addr, size);
2029+
start = found_addr + alignment;
2030+
}
2031+
}
2032+
2033+
AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
2034+
const AddressRanges &ranges,
2035+
size_t alignment, size_t max_matches,
2036+
Status &error) {
2037+
AddressRanges matches;
2038+
if (buf == nullptr) {
2039+
error.SetErrorString("buffer is null");
2040+
return matches;
2041+
}
2042+
if (size == 0) {
2043+
error.SetErrorString("buffer size is zero");
2044+
return matches;
2045+
}
2046+
if (ranges.empty()) {
2047+
error.SetErrorString("empty ranges");
2048+
return matches;
2049+
}
2050+
if (alignment == 0) {
2051+
error.SetErrorString("alignment must be greater than zero");
2052+
return matches;
2053+
}
2054+
if (max_matches == 0) {
2055+
error.SetErrorStringWithFormat("max_matches must be greater than zero");
2056+
return matches;
2057+
}
2058+
2059+
int resolved_ranges = 0;
2060+
Target &target = GetTarget();
2061+
for (size_t i = 0; i < ranges.size(); ++i) {
2062+
if (matches.size() >= max_matches) {
2063+
break;
2064+
}
2065+
const AddressRange &range = ranges[i];
2066+
if (range.IsValid() == false) {
2067+
continue;
2068+
}
2069+
2070+
const lldb::addr_t start_addr =
2071+
range.GetBaseAddress().GetLoadAddress(&target);
2072+
if (start_addr == LLDB_INVALID_ADDRESS) {
2073+
continue;
2074+
}
2075+
++resolved_ranges;
2076+
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
2077+
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment,
2078+
max_matches);
2079+
}
2080+
2081+
if (resolved_ranges > 0) {
2082+
error.Clear();
2083+
} else {
2084+
error.SetErrorString("unable to resolve any ranges");
2085+
}
2086+
return matches;
2087+
}
2088+
2089+
lldb::addr_t Process::FindInMemory(const uint8_t *buf, uint64_t size,
2090+
const AddressRange &range, size_t alignment,
2091+
Status &error) {
2092+
if (buf == nullptr) {
2093+
error.SetErrorString("buffer is null");
2094+
return LLDB_INVALID_ADDRESS;
2095+
}
2096+
if (size == 0) {
2097+
error.SetErrorString("buffer size is zero");
2098+
return LLDB_INVALID_ADDRESS;
2099+
}
2100+
if (!range.IsValid()) {
2101+
error.SetErrorString("range is invalid");
2102+
return LLDB_INVALID_ADDRESS;
2103+
}
2104+
if (alignment == 0) {
2105+
error.SetErrorString("alignment must be greater than zero");
2106+
return LLDB_INVALID_ADDRESS;
2107+
}
2108+
2109+
Target &target = GetTarget();
2110+
const lldb::addr_t start_addr =
2111+
range.GetBaseAddress().GetLoadAddress(&target);
2112+
if (start_addr == LLDB_INVALID_ADDRESS) {
2113+
error.SetErrorString("range load address is invalid");
2114+
return LLDB_INVALID_ADDRESS;
2115+
}
2116+
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
2117+
2118+
AddressRanges matches;
2119+
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, 1);
2120+
if (matches.empty())
2121+
return LLDB_INVALID_ADDRESS;
2122+
2123+
error.Clear();
2124+
return matches[0].GetBaseAddress().GetLoadAddress(&target);
2125+
}
2126+
20102127
size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str,
20112128
Status &error) {
20122129
char buf[256];
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules

0 commit comments

Comments
 (0)