dmikulin updated this revision to Diff 79987.
dmikulin added a comment.
Addressed review comments.
Haven't had a chance to re-test it on an arm board.
Repository:
rL LLVM
https://reviews.llvm.org/D25756
Files:
source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
Index: source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
===
--- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -1141,11 +1141,17 @@
case SI_KERNEL:
case TRAP_BRKPT:
-if (log)
- log->Printf(
- "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
- __FUNCTION__, tid);
-message = ProcessMessage::Break(tid);
+if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) {
+ if (log)
+log->Printf ("ProcessMonitor::%s() received sw single step breakpoint "
+ "event, tid = %" PRIu64, __FUNCTION__, tid);
+ message = ProcessMessage::Trace(tid);
+} else {
+ if (log)
+log->Printf ("ProcessMonitor::%s() received breakpoint event, tid = %"
+ PRIu64, __FUNCTION__, tid);
+ message = ProcessMessage::Break(tid);
+}
break;
}
Index: source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
===
--- source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
@@ -171,7 +171,27 @@
virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
lldb::tid_t tid);
-protected:
+ static bool
+ SingleStepBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ lldb_private::Error SetupSoftwareSingleStepping(lldb::tid_t tid);
+
+ lldb_private::Error
+ SetSoftwareSingleStepBreakpoint (lldb::tid_t tid, lldb::addr_t addr);
+
+ bool IsSoftwareStepBreakpoint(lldb::tid_t tid);
+
+ bool SupportHardwareSingleStepping() const;
+
+ typedef std::vector tid_collection;
+ tid_collection &GetStepTids() { return m_step_tids; }
+
+ protected:
+ static const size_t MAX_TRAP_OPCODE_SIZE = 8;
+
/// Target byte order.
lldb::ByteOrder m_byte_order;
@@ -207,10 +227,10 @@
friend class FreeBSDThread;
- typedef std::vector tid_collection;
tid_collection m_suspend_tids;
tid_collection m_run_tids;
tid_collection m_step_tids;
+ std::map m_threads_stepping_with_breakpoint;
int m_resume_signo;
};
Index: source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
===
--- source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -13,6 +13,7 @@
// C++ Includes
#include
+#include
// Other libraries and framework includes
#include "lldb/Core/PluginManager.h"
@@ -122,6 +123,7 @@
std::lock_guard guard(m_thread_list.GetMutex());
bool do_step = false;
+ bool software_single_step = !SupportHardwareSingleStepping();
for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
t_end = m_run_tids.end();
@@ -133,6 +135,11 @@
t_pos != t_end; ++t_pos) {
m_monitor->ThreadSuspend(*t_pos, false);
do_step = true;
+if (software_single_step) {
+ Error error = SetupSoftwareSingleStepping(*t_pos);
+ if (error.Fail())
+return error;
+}
}
for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
t_end = m_suspend_tids.end();
@@ -145,7 +152,7 @@
if (log)
log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
do_step ? "step" : "continue");
- if (do_step)
+ if (do_step && !software_single_step)
m_monitor->SingleStep(GetID(), m_resume_signo);
else
m_monitor->Resume(GetID(), m_resume_signo);
@@ -913,3 +920,194 @@
"no platform or not the host - how did we get here with ProcessFreeBSD?");
return DataBufferSP();
}
+
+struct EmulatorBaton {
+ ProcessFreeBSD *m_process;
+ RegisterContext *m_reg_context;
+
+ // eRegisterKindDWARF -> RegisterValue
+ std::unordered_map m_register_values;
+
+ EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context)
+ : m_process(process), m_reg_context(reg_context) {}
+};
+
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ EmulatorBaton *emulator_baton = static_cast(baton);
+
+ Error error;
+ size_t bytes_read =
+ emulator_baton->m_process->DoReadMemory(addr, d