Skip to content

Commit bae5474

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 49ae2dc commit bae5474

File tree

15 files changed

+677
-7
lines changed

15 files changed

+677
-7
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/SBAddressRange.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class LLDB_API SBAddressRange {
5858
friend class SBFunction;
5959
friend class SBProcess;
6060

61+
lldb_private::AddressRange &ref() const;
62+
6163
AddressRangeUP m_opaque_up;
6264
};
6365

lldb/include/lldb/API/SBAddressRangeList.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class LLDB_API SBAddressRangeList {
4646
friend class SBBlock;
4747
friend class SBProcess;
4848

49+
lldb_private::AddressRanges &ref() const;
50+
4951
std::unique_ptr<lldb_private::AddressRangeListImpl> m_opaque_up;
5052
};
5153

lldb/include/lldb/API/SBProcess.h

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

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

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

lldb/include/lldb/Core/AddressRangeListImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
#include <cstddef>
1414

1515
namespace lldb {
16+
class SBAddressRangeList;
1617
class SBBlock;
18+
class SBProcess;
1719
}
1820

1921
namespace lldb_private {
@@ -39,7 +41,9 @@ class AddressRangeListImpl {
3941
lldb_private::AddressRange GetAddressRangeAtIndex(size_t index);
4042

4143
private:
44+
friend class lldb::SBAddressRangeList;
4245
friend class lldb::SBBlock;
46+
friend class lldb::SBProcess;
4347

4448
AddressRanges &ref();
4549

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/SBAddressRange.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ bool SBAddressRange::operator!=(const SBAddressRange &rhs) {
6464
void SBAddressRange::Clear() {
6565
LLDB_INSTRUMENT_VA(this);
6666

67-
m_opaque_up.reset();
67+
m_opaque_up->Clear();
6868
}
6969

7070
bool SBAddressRange::IsValid() const {
@@ -101,3 +101,5 @@ bool SBAddressRange::GetDescription(SBStream &description,
101101
m_opaque_up->GetDescription(&stream, target.GetSP().get());
102102
return true;
103103
}
104+
105+
lldb_private::AddressRange &SBAddressRange::ref() const { return *m_opaque_up; }

lldb/source/API/SBAddressRangeList.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,7 @@ bool SBAddressRangeList::GetDescription(SBStream &description,
9292
stream << "]";
9393
return true;
9494
}
95+
96+
lldb_private::AddressRanges &SBAddressRangeList::ref() const {
97+
return m_opaque_up->ref();
98+
}

lldb/source/API/SBProcess.cpp

Lines changed: 53 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,55 @@ const char *SBProcess::GetBroadcasterClass() {
810809
return ConstString(Process::GetStaticBroadcasterClass()).AsCString();
811810
}
812811

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

lldb/source/Target/Process.cpp

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,135 @@ 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+
if (alignment > 1) {
2025+
// Align to an address alignment boundary
2026+
const uint64_t align_offset = start % alignment;
2027+
if (align_offset > 0)
2028+
start += alignment - align_offset;
2029+
}
2030+
while (matches.size() < max_matches && (start + size) < end_addr) {
2031+
const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
2032+
if (found_addr == LLDB_INVALID_ADDRESS)
2033+
break;
2034+
2035+
if (found_addr % alignment) {
2036+
++start;
2037+
continue;
2038+
}
2039+
2040+
matches.emplace_back(found_addr, size);
2041+
start = found_addr + alignment;
2042+
}
2043+
}
2044+
2045+
AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
2046+
const AddressRanges &ranges,
2047+
size_t alignment, size_t max_matches,
2048+
Status &error) {
2049+
AddressRanges matches;
2050+
if (buf == nullptr) {
2051+
error.SetErrorString("buffer is null");
2052+
return matches;
2053+
}
2054+
if (size == 0) {
2055+
error.SetErrorString("buffer size is zero");
2056+
return matches;
2057+
}
2058+
if (ranges.empty()) {
2059+
error.SetErrorString("empty ranges");
2060+
return matches;
2061+
}
2062+
if (alignment == 0) {
2063+
error.SetErrorString("alignment must be greater than zero");
2064+
return matches;
2065+
}
2066+
if (max_matches == 0) {
2067+
error.SetErrorStringWithFormat("max_matches must be greater than zero");
2068+
return matches;
2069+
}
2070+
2071+
int resolved_ranges = 0;
2072+
Target &target = GetTarget();
2073+
for (size_t i = 0; i < ranges.size(); ++i) {
2074+
if (matches.size() >= max_matches) {
2075+
break;
2076+
}
2077+
const AddressRange &range = ranges[i];
2078+
if (range.IsValid() == false) {
2079+
continue;
2080+
}
2081+
2082+
const lldb::addr_t start_addr =
2083+
range.GetBaseAddress().GetLoadAddress(&target);
2084+
if (start_addr == LLDB_INVALID_ADDRESS) {
2085+
continue;
2086+
}
2087+
++resolved_ranges;
2088+
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
2089+
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment,
2090+
max_matches);
2091+
}
2092+
2093+
if (resolved_ranges > 0) {
2094+
error.Clear();
2095+
} else {
2096+
error.SetErrorString("unable to resolve any ranges");
2097+
}
2098+
return matches;
2099+
}
2100+
2101+
lldb::addr_t Process::FindInMemory(const uint8_t *buf, uint64_t size,
2102+
const AddressRange &range, size_t alignment,
2103+
Status &error) {
2104+
if (buf == nullptr) {
2105+
error.SetErrorString("buffer is null");
2106+
return LLDB_INVALID_ADDRESS;
2107+
}
2108+
if (size == 0) {
2109+
error.SetErrorString("buffer size is zero");
2110+
return LLDB_INVALID_ADDRESS;
2111+
}
2112+
if (!range.IsValid()) {
2113+
error.SetErrorString("range is invalid");
2114+
return LLDB_INVALID_ADDRESS;
2115+
}
2116+
if (alignment == 0) {
2117+
error.SetErrorString("alignment must be greater than zero");
2118+
return LLDB_INVALID_ADDRESS;
2119+
}
2120+
2121+
Target &target = GetTarget();
2122+
const lldb::addr_t start_addr =
2123+
range.GetBaseAddress().GetLoadAddress(&target);
2124+
if (start_addr == LLDB_INVALID_ADDRESS) {
2125+
error.SetErrorString("range load address is invalid");
2126+
return LLDB_INVALID_ADDRESS;
2127+
}
2128+
const lldb::addr_t end_addr = start_addr + range.GetByteSize();
2129+
2130+
AddressRanges matches;
2131+
DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, 1);
2132+
if (matches.empty())
2133+
return LLDB_INVALID_ADDRESS;
2134+
2135+
error.Clear();
2136+
return matches[0].GetBaseAddress().GetLoadAddress(&target);
2137+
}
2138+
20102139
size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str,
20112140
Status &error) {
20122141
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)