Skip to content

Commit 2655897

Browse files
authored
[nfc][lldb] Move FastSearch from CommandObjectMemoryFind to Process (#93688)
Moving CommandObjectMemoryFind::FastSearch() to Process::FindInMemory(). Plan to expose FindInMemory as public API in SBProcess.
1 parent 8c5a7a1 commit 2655897

File tree

3 files changed

+78
-59
lines changed

3 files changed

+78
-59
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,28 @@ void PruneThreadPlans();
26632663
return m_source_file_cache;
26642664
}
26652665

2666+
/// Find a pattern within a memory region.
2667+
///
2668+
/// This function searches for a pattern represented by the provided buffer
2669+
/// within the memory range specified by the low and high addresses. It uses
2670+
/// a bad character heuristic to optimize the search process.
2671+
///
2672+
/// \param[in] low The starting address of the memory region to be searched.
2673+
/// (inclusive)
2674+
///
2675+
/// \param[in] high The ending address of the memory region to be searched.
2676+
/// (exclusive)
2677+
///
2678+
/// \param[in] buf A pointer to the buffer containing the pattern to be
2679+
/// searched.
2680+
///
2681+
/// \param[in] buffer_size The size of the buffer in bytes.
2682+
///
2683+
/// \return The address where the pattern was found or LLDB_INVALID_ADDRESS if
2684+
/// not found.
2685+
lldb::addr_t FindInMemory(lldb::addr_t low, lldb::addr_t high,
2686+
const uint8_t *buf, size_t size);
2687+
26662688
protected:
26672689
friend class Trace;
26682690

lldb/source/Commands/CommandObjectMemory.cpp

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -977,35 +977,6 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
977977
Options *GetOptions() override { return &m_option_group; }
978978

979979
protected:
980-
class ProcessMemoryIterator {
981-
public:
982-
ProcessMemoryIterator(ProcessSP process_sp, lldb::addr_t base)
983-
: m_process_sp(process_sp), m_base_addr(base) {
984-
lldbassert(process_sp.get() != nullptr);
985-
}
986-
987-
bool IsValid() { return m_is_valid; }
988-
989-
uint8_t operator[](lldb::addr_t offset) {
990-
if (!IsValid())
991-
return 0;
992-
993-
uint8_t retval = 0;
994-
Status error;
995-
if (0 ==
996-
m_process_sp->ReadMemory(m_base_addr + offset, &retval, 1, error)) {
997-
m_is_valid = false;
998-
return 0;
999-
}
1000-
1001-
return retval;
1002-
}
1003-
1004-
private:
1005-
ProcessSP m_process_sp;
1006-
lldb::addr_t m_base_addr;
1007-
bool m_is_valid = true;
1008-
};
1009980
void DoExecute(Args &command, CommandReturnObject &result) override {
1010981
// No need to check "process" for validity as eCommandRequiresProcess
1011982
// ensures it is valid
@@ -1106,8 +1077,8 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
11061077
found_location = low_addr;
11071078
bool ever_found = false;
11081079
while (count) {
1109-
found_location = FastSearch(found_location, high_addr, buffer.GetBytes(),
1110-
buffer.GetByteSize());
1080+
found_location = process->FindInMemory(
1081+
found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
11111082
if (found_location == LLDB_INVALID_ADDRESS) {
11121083
if (!ever_found) {
11131084
result.AppendMessage("data not found within the range.\n");
@@ -1144,34 +1115,6 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
11441115
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
11451116
}
11461117

1147-
lldb::addr_t FastSearch(lldb::addr_t low, lldb::addr_t high, uint8_t *buffer,
1148-
size_t buffer_size) {
1149-
const size_t region_size = high - low;
1150-
1151-
if (region_size < buffer_size)
1152-
return LLDB_INVALID_ADDRESS;
1153-
1154-
std::vector<size_t> bad_char_heuristic(256, buffer_size);
1155-
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1156-
ProcessMemoryIterator iterator(process_sp, low);
1157-
1158-
for (size_t idx = 0; idx < buffer_size - 1; idx++) {
1159-
decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
1160-
bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
1161-
}
1162-
for (size_t s = 0; s <= (region_size - buffer_size);) {
1163-
int64_t j = buffer_size - 1;
1164-
while (j >= 0 && buffer[j] == iterator[s + j])
1165-
j--;
1166-
if (j < 0)
1167-
return low + s;
1168-
else
1169-
s += bad_char_heuristic[iterator[s + buffer_size - 1]];
1170-
}
1171-
1172-
return LLDB_INVALID_ADDRESS;
1173-
}
1174-
11751118
OptionGroupOptions m_option_group;
11761119
OptionGroupFindMemory m_memory_options;
11771120
OptionGroupMemoryTag m_memory_tag_options;

lldb/source/Target/Process.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,33 @@ class ProcessOptionValueProperties
112112
}
113113
};
114114

115+
class ProcessMemoryIterator {
116+
public:
117+
ProcessMemoryIterator(Process &process, lldb::addr_t base)
118+
: m_process(process), m_base_addr(base) {}
119+
120+
bool IsValid() { return m_is_valid; }
121+
122+
uint8_t operator[](lldb::addr_t offset) {
123+
if (!IsValid())
124+
return 0;
125+
126+
uint8_t retval = 0;
127+
Status error;
128+
if (0 == m_process.ReadMemory(m_base_addr + offset, &retval, 1, error)) {
129+
m_is_valid = false;
130+
return 0;
131+
}
132+
133+
return retval;
134+
}
135+
136+
private:
137+
Process &m_process;
138+
const lldb::addr_t m_base_addr;
139+
bool m_is_valid = true;
140+
};
141+
115142
static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = {
116143
{
117144
eFollowParent,
@@ -3191,6 +3218,33 @@ Status Process::Halt(bool clear_thread_plans, bool use_run_lock) {
31913218
return Status();
31923219
}
31933220

3221+
lldb::addr_t Process::FindInMemory(lldb::addr_t low, lldb::addr_t high,
3222+
const uint8_t *buf, size_t size) {
3223+
const size_t region_size = high - low;
3224+
3225+
if (region_size < size)
3226+
return LLDB_INVALID_ADDRESS;
3227+
3228+
std::vector<size_t> bad_char_heuristic(256, size);
3229+
ProcessMemoryIterator iterator(*this, low);
3230+
3231+
for (size_t idx = 0; idx < size - 1; idx++) {
3232+
decltype(bad_char_heuristic)::size_type bcu_idx = buf[idx];
3233+
bad_char_heuristic[bcu_idx] = size - idx - 1;
3234+
}
3235+
for (size_t s = 0; s <= (region_size - size);) {
3236+
int64_t j = size - 1;
3237+
while (j >= 0 && buf[j] == iterator[s + j])
3238+
j--;
3239+
if (j < 0)
3240+
return low + s;
3241+
else
3242+
s += bad_char_heuristic[iterator[s + size - 1]];
3243+
}
3244+
3245+
return LLDB_INVALID_ADDRESS;
3246+
}
3247+
31943248
Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
31953249
Status error;
31963250

0 commit comments

Comments
 (0)