summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/memory/find/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py59
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/memory/find/main.cpp17
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp87
4 files changed, 152 insertions, 16 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/Makefile
new file mode 100644
index 00000000000..314f1cb2f07
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py
new file mode 100644
index 00000000000..f7507c73c94
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py
@@ -0,0 +1,59 @@
+"""
+Test the 'memory find' command.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class MemoryFindTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// break here')
+
+ def test_memory_find(self):
+ """Test the 'memory find' command."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main() aftre the variables are assigned values.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # Test the memory find commands.
+
+ self.expect('memory find -s "in const" `stringdata` `stringdata+(int)strlen(stringdata)`',
+ substrs = ['data found at location: 0x', '69 6e 20 63', 'in const'])
+
+ self.expect('memory find -e "(uint8_t)0x22" `&bytedata[0]` `&bytedata[15]`',
+ substrs = ['data found at location: 0x', '22 33 44 55 66'])
+
+ self.expect('memory find -e "(uint8_t)0x22" `&bytedata[0]` `&bytedata[2]`',
+ substrs = ['data not found within the range.'])
+
+ self.expect('memory find -s "nothere" `stringdata` `stringdata+5`',
+ substrs = ['data not found within the range.'])
+
+ self.expect('memory find -s "nothere" `stringdata` `stringdata+10`',
+ substrs = ['data not found within the range.'])
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/main.cpp
new file mode 100644
index 00000000000..250f359c76e
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/memory/find/main.cpp
@@ -0,0 +1,17 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+int main (int argc, char const *argv[])
+{
+ const char* stringdata = "hello world; I like to write text in const char pointers";
+ uint8_t bytedata[] = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};
+ return 0; // break here
+}
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 20b15cfe26e..fa89da11904 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1088,6 +1088,45 @@ public:
}
protected:
+ class ProcessMemoryIterator
+ {
+ public:
+ ProcessMemoryIterator (ProcessSP process_sp,
+ lldb::addr_t base) :
+ m_process_sp(process_sp),
+ m_base_addr(base),
+ m_is_valid(true)
+ {
+ lldbassert(process_sp);
+ }
+
+ bool
+ IsValid ()
+ {
+ return m_is_valid;
+ }
+
+ uint8_t
+ operator [](lldb::addr_t offset)
+ {
+ if (!IsValid())
+ return 0;
+
+ uint8_t retval = 0;
+ Error error;
+ if (0 == m_process_sp->ReadMemory(m_base_addr+offset, &retval, 1, error))
+ {
+ m_is_valid = false;
+ return 0;
+ }
+
+ return retval;
+ }
+ private:
+ ProcessSP m_process_sp;
+ lldb::addr_t m_base_addr;
+ bool m_is_valid;
+ };
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
@@ -1185,7 +1224,7 @@ protected:
bool ever_found = false;
while (count)
{
- found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
+ found_location = FastSearch(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
if (found_location == LLDB_INVALID_ADDRESS)
{
if (!ever_found)
@@ -1218,24 +1257,40 @@ protected:
}
lldb::addr_t
- Search (lldb::addr_t low,
- lldb::addr_t high,
- uint8_t* buffer,
- size_t buffer_size)
+ FastSearch (lldb::addr_t low,
+ lldb::addr_t high,
+ uint8_t *buffer,
+ size_t buffer_size)
{
- Process *process = m_exe_ctx.GetProcessPtr();
- DataBufferHeap heap(buffer_size, 0);
- for (auto ptr = low;
- ptr < high;
- ptr++)
+ const size_t region_size = high-low;
+
+ if (region_size < buffer_size)
+ return LLDB_INVALID_ADDRESS;
+
+ std::vector<size_t> bad_char_heuristic(256, buffer_size);
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+ ProcessMemoryIterator iterator(process_sp, low);
+
+ for (size_t idx = 0;
+ idx < buffer_size-1;
+ idx++)
{
- Error error;
- process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
- if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0)
- return ptr;
+ decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
+ bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
+ }
+ for (size_t s = 0;
+ s <= (region_size - buffer_size);
+ )
+ {
+ int64_t j = buffer_size-1;
+ while (j >= 0 && buffer[j] == iterator[s + j])
+ j--;
+ if (j < 0)
+ return low+s;
+ else
+ s += bad_char_heuristic[iterator[s + buffer_size - 1]];
}
+
return LLDB_INVALID_ADDRESS;
}
OpenPOWER on IntegriCloud