summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBThread.h24
-rw-r--r--lldb/include/lldb/Target/Process.h31
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj3
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp55
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h37
-rw-r--r--lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp5
-rw-r--r--lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp74
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h8
-rw-r--r--lldb/source/Target/Process.cpp87
-rw-r--r--lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj4
-rw-r--r--lldb/tools/debugserver/source/DNB.cpp95
-rw-r--r--lldb/tools/debugserver/source/DNB.h3
-rw-r--r--lldb/tools/debugserver/source/DNBArch.h29
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp26
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h3
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.cpp67
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.h12
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp33
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThreadList.h2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp50
-rw-r--r--lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h23
-rw-r--r--lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp52
-rw-r--r--lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h23
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp304
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h18
-rw-r--r--lldb/tools/debugserver/source/debugserver.cpp35
29 files changed, 688 insertions, 419 deletions
diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h
index 86a19ae0568..a41a3588907 100644
--- a/lldb/include/lldb/API/SBThread.h
+++ b/lldb/include/lldb/API/SBThread.h
@@ -35,6 +35,30 @@ public:
lldb::StopReason
GetStopReason();
+//
+// // Get the number of words associated with the stop reason.
+// size_t
+// GetStopReasonDataCount();
+//
+// //--------------------------------------------------------------------------
+// // Get information associated with a stop reason.
+// //
+// // Breakpoint and watchpoint stop reasons will have data that consists of
+// // pairs of breakpoint/watchpoint IDs followed by the breakpoint/watchpoint
+// // location IDs (they always come in pairs).
+// //
+// // Stop Reason Count Data Type
+// // ======================== ===== ==========================================
+// // eStopReasonNone 0
+// // eStopReasonTrace 0
+// // eStopReasonBreakpoint N duple: {breakpoint id, location id}
+// // eStopReasonWatchpoint N duple: {watchpoint id, location id}
+// // eStopReasonSignal 1 unix signal number
+// // eStopReasonException N exception data
+// // eStopReasonPlanComplete 0
+// //--------------------------------------------------------------------------
+// uint64_t
+// GetStopReasonDataAtIndex(uint32_t idx);
size_t
GetStopDescription (char *dst, size_t dst_len);
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 07f4d3de8e0..5b3b56b798d 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -628,6 +628,12 @@ public:
uint32_t
GetAddressByteSize();
+ void
+ SetAddressByteSize (uint32_t addr_byte_size)
+ {
+ m_addr_byte_size = addr_byte_size;
+ }
+
//------------------------------------------------------------------
/// Get the image information address for the current process.
///
@@ -1007,12 +1013,12 @@ public:
//------------------------------------------------------------------
/// Halts a running process.
///
- /// DoHalt should consume any process events that were delivered in the
- /// process of implementing the halt.
+ /// DoHalt should consume any process events that were delivered in
+ /// the process of implementing the halt.
///
/// @param[out] caused_stop
- /// If true, then this Halt caused the stop, otherwise, the process was
- /// already stopped.
+ /// If true, then this Halt caused the stop, otherwise, the
+ /// process was already stopped.
///
/// @return
/// Returns \b true if the process successfully halts, \b false
@@ -1633,8 +1639,17 @@ public:
/// @return
/// A valid ByteOrder enumeration, or eByteOrderInvalid.
//------------------------------------------------------------------
- virtual lldb::ByteOrder
- GetByteOrder () const = 0;
+ lldb::ByteOrder
+ GetByteOrder () const
+ {
+ return m_byte_order;
+ }
+
+ void
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
const ConstString &
GetTargetTriple ()
@@ -1720,10 +1735,12 @@ protected:
std::auto_ptr<DynamicCheckerFunctions> m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
UnixSignals m_unix_signals; /// This is the current signal set for this process.
ConstString m_target_triple;
+ lldb::ByteOrder m_byte_order; /// The byte order of the process. Should be set in DidLaunch/DidAttach.
+ uint32_t m_addr_byte_size; /// The size in bytes of an address/pointer for the inferior process. Should be set in DidLaunch/DidAttach.
lldb::ABISP m_abi_sp;
lldb::InputReaderSP m_process_input_reader;
lldb_private::Communication m_stdio_communication;
- lldb_private::Mutex m_stdio_comm_mutex;
+ lldb_private::Mutex m_stdio_communication_mutex;
std::string m_stdout_data;
typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index ef4258c918c..2c13f0ca302 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -2452,6 +2452,7 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
@@ -2941,7 +2942,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- ONLY_ACTIVE_ARCH = YES;
+ ONLY_ACTIVE_ARCH = NO;
PREBINDING = NO;
VALID_ARCHS = "x86_64 i386";
};
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index bc268b8e905..227a981b809 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -59,8 +59,10 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
m_dyld(),
m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
m_dyld_all_image_infos(),
+ m_dyld_all_image_infos_stop_id (UINT32_MAX),
m_break_id(LLDB_INVALID_BREAK_ID),
m_dyld_image_infos(),
+ m_dyld_image_infos_stop_id (UINT32_MAX),
m_mutex(Mutex::eMutexTypeRecursive)
{
}
@@ -83,10 +85,8 @@ void
DynamicLoaderMacOSXDYLD::DidAttach ()
{
PrivateInitialize(m_process);
- if (NeedToLocateDYLD ())
- LocateDYLD ();
+ LocateDYLD ();
SetNotificationBreakpoint ();
- UpdateAllImageInfos();
}
//------------------------------------------------------------------
@@ -99,10 +99,8 @@ void
DynamicLoaderMacOSXDYLD::DidLaunch ()
{
PrivateInitialize(m_process);
- if (NeedToLocateDYLD ())
- LocateDYLD ();
+ LocateDYLD ();
SetNotificationBreakpoint ();
- UpdateAllImageInfos();
}
@@ -401,12 +399,23 @@ bool
DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
{
Mutex::Locker locker(m_mutex);
+
+ // the all image infos is already valid for this process stop ID
+ if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
+ return true;
+
m_dyld_all_image_infos.Clear();
if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
{
- const ByteOrder endian = m_process->GetByteOrder();
- const uint32_t addr_size = m_process->GetAddressByteSize();
+ ByteOrder byte_order = m_process->GetByteOrder();
+ uint32_t addr_size = 4;
+ if (m_dyld_all_image_infos_addr > UINT32_MAX)
+ addr_size = 8;
+
uint8_t buf[256];
+ DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
+ uint32_t offset = 0;
+
const size_t count_v2 = sizeof (uint32_t) + // version
sizeof (uint32_t) + // infoArrayCount
addr_size + // infoArray
@@ -434,9 +443,23 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
Error error;
if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
{
- DataExtractor data(buf, 4, endian, addr_size);
- uint32_t offset = 0;
m_dyld_all_image_infos.version = data.GetU32(&offset);
+ // If anything in the high byte is set, we probably got the byte
+ // order incorrect (the process might not have it set correctly
+ // yet due to attaching to a program without a specified file).
+ if (m_dyld_all_image_infos.version & 0xff000000)
+ {
+ // We have guessed the wrong byte order. Swap it and try
+ // reading the version again.
+ if (byte_order == eByteOrderLittle)
+ byte_order = eByteOrderBig;
+ else
+ byte_order = eByteOrderLittle;
+
+ data.SetByteOrder (byte_order);
+ offset = 0;
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ }
}
else
{
@@ -451,8 +474,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
if (bytes_read == count)
{
- DataExtractor data(buf, count, endian, addr_size);
- uint32_t offset = 0;
+ offset = 0;
m_dyld_all_image_infos.version = data.GetU32(&offset);
m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
@@ -486,6 +508,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
}
}
+ m_dyld_all_image_infos_stop_id = m_process->GetStopID();
return true;
}
}
@@ -504,6 +527,9 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
if (ReadAllImageInfosStructure ())
{
Mutex::Locker locker(m_mutex);
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ m_dyld_image_infos.size();
+
uint32_t idx;
uint32_t i = 0;
DYLDImageInfo::collection old_dyld_all_image_infos;
@@ -511,8 +537,8 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
// If we made it here, we are assuming that the all dylib info data should
// be valid, lets read the info array.
- const ByteOrder endian = m_process->GetByteOrder();
- const uint32_t addr_size = m_process->GetAddressByteSize();
+ const ByteOrder endian = m_dyld.GetByteOrder();
+ const uint32_t addr_size = m_dyld.GetAddressByteSize();
if (m_dyld_all_image_infos.dylib_info_count > 0)
{
@@ -605,6 +631,7 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
if (log)
PutToLog(log.get());
}
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
}
else
{
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 34ea8a46781..d8dbe711b3d 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -266,6 +266,41 @@ protected:
return uuid.IsValid();
}
+ uint32_t
+ GetAddressByteSize ()
+ {
+ if (header.cputype)
+ {
+ if (header.cputype & llvm::MachO::CPUArchABI64)
+ return 8;
+ else
+ return 4;
+ }
+ return 0;
+ }
+
+ lldb::ByteOrder
+ GetByteOrder()
+ {
+ switch (header.magic)
+ {
+ case llvm::MachO::HeaderMagic32: // MH_MAGIC
+ case llvm::MachO::HeaderMagic64: // MH_MAGIC_64
+ return lldb::eByteOrderHost;
+
+ case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM
+ case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64
+ if (lldb::eByteOrderHost == lldb::eByteOrderLittle)
+ return lldb::eByteOrderBig;
+ else
+ return lldb::eByteOrderLittle;
+ default:
+ assert (!"invalid header.magic value");
+ break;
+ }
+ return lldb::eByteOrderHost;
+ }
+
const Segment *
FindSegment (const lldb_private::ConstString &name) const;
@@ -348,8 +383,10 @@ protected:
DYLDImageInfo m_dyld; // Info about the curent dyld being used
lldb::addr_t m_dyld_all_image_infos_addr;
DYLDAllImageInfos m_dyld_all_image_infos;
+ uint32_t m_dyld_all_image_infos_stop_id;
lldb::user_id_t m_break_id;
DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information
+ uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
mutable lldb_private::Mutex m_mutex;
lldb_private::Process::Notifications m_notification_callbacks;
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
index 259c08072a1..b3933169841 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
@@ -235,9 +235,7 @@ ProcessMacOSX::ProcessMacOSX(Target& target, Listener &listener) :
m_exception_messages (),
m_exception_messages_mutex (Mutex::eMutexTypeRecursive),
m_arch_spec (),
- m_dynamic_loader_ap (),
-// m_wait_thread (LLDB_INVALID_HOST_THREAD),
- m_byte_order (eByteOrderHost)
+ m_dynamic_loader_ap ()
{
}
@@ -676,6 +674,7 @@ ProcessMacOSX::RefreshStateAfterStop ()
Error
ProcessMacOSX::DoHalt (bool &caused_stop)
{
+ caused_stop = true;
return Signal (SIGSTOP);
}
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
index 92d2c9c1653..4f8bdb930b7 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
@@ -247,8 +247,6 @@ protected:
lldb_private::Mutex m_exception_messages_mutex; // Multithreaded protection for m_exception_messages
lldb_private::ArchSpec m_arch_spec;
std::auto_ptr<lldb_private::DynamicLoader> m_dynamic_loader_ap;
-// lldb::thread_t m_wait_thread;
- lldb::ByteOrder m_byte_order;
//----------------------------------------------------------------------
// Child process control
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index fcbd523699f..5496a02343a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -105,7 +105,6 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
m_dynamic_loader_ap (),
m_flags (0),
m_stdio_mutex (Mutex::eMutexTypeRecursive),
- m_byte_order (eByteOrderHost),
m_gdb_comm(),
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
@@ -339,13 +338,13 @@ ProcessGDBRemote::WillLaunch (Module* module)
}
Error
-ProcessGDBRemote::WillAttach (lldb::pid_t pid)
+ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
{
return WillLaunchOrAttach ();
}
Error
-ProcessGDBRemote::WillAttach (const char *process_name, bool wait_for_launch)
+ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
{
return WillLaunchOrAttach ();
}
@@ -556,8 +555,6 @@ ProcessGDBRemote::ConnectToDebugserver (const char *host_port)
if (response.IsOKPacket())
m_gdb_comm.SetAckMode (false);
}
-
- BuildDynamicRegisterInfo ();
}
return error;
}
@@ -574,22 +571,23 @@ ProcessGDBRemote::DidLaunchOrAttach ()
{
m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;
- Module * exe_module = GetTarget().GetExecutableModule ().get();
+ BuildDynamicRegisterInfo ();
+
+ m_byte_order = m_gdb_comm.GetByteOrder();
+
+ Module * exe_module = GetTarget().GetExecutableModule().get();
assert(exe_module);
ObjectFile *exe_objfile = exe_module->GetObjectFile();
assert(exe_objfile);
- m_byte_order = exe_objfile->GetByteOrder();
- assert (m_byte_order != eByteOrderInvalid);
-
StreamString strm;
ArchSpec inferior_arch;
// See if the GDB server supports the qHostInfo information
const char *vendor = m_gdb_comm.GetVendorString().AsCString();
const char *os_type = m_gdb_comm.GetOSString().AsCString();
- ArchSpec arch_spec = GetTarget().GetArchitecture();
+ ArchSpec arch_spec (GetTarget().GetArchitecture());
if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm"))
{
@@ -858,25 +856,8 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait
void
ProcessGDBRemote::DidAttach ()
{
- // If we haven't got an executable module yet, then we should make a dynamic loader, and
- // see if it can find the executable module for us. If we do have an executable module,
- // make sure it matches the process we've just attached to.
-
- ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- if (!m_dynamic_loader_ap.get())
- {
- m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld"));
- }
-
if (m_dynamic_loader_ap.get())
m_dynamic_loader_ap->DidAttach();
-
- Module * new_exe_module = GetTarget().GetExecutableModule().get();
- if (new_exe_module == NULL)
- {
-
- }
-
DidLaunchOrAttach ();
}
@@ -1124,45 +1105,26 @@ Error
ProcessGDBRemote::DoHalt (bool &caused_stop)
{
Error error;
- caused_stop = false;
if (m_gdb_comm.IsRunning())
{
- PausePrivateStateThread();
+ caused_stop = true;
bool timed_out = false;
Mutex::Locker locker;
- if (m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
- {
- EventSP event_sp;
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
-
- StateType state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp);
-
- if (!StateIsStoppedState (state))
- {
- LogSP log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoHalt() failed to stop after sending interrupt");
- error.SetErrorString ("Did not get stopped event after interrupt succeeded.");
- }
- else
- caused_stop = true;
- }
- else
+ if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
{
if (timed_out)
error.SetErrorString("timed out sending interrupt packet");
else
error.SetErrorString("unknown error sending interrupt packet");
}
-
- // Resume the private state thread at this point.
- ResumePrivateStateThread();
-
}
+ else
+ {
+ caused_stop = false;
+ }
+
return error;
}
@@ -1265,12 +1227,6 @@ ProcessGDBRemote::DoDestroy ()
return error;
}
-ByteOrder
-ProcessGDBRemote::GetByteOrder () const
-{
- return m_byte_order;
-}
-
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 1e85e9918a7..546f1054536 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -90,10 +90,10 @@ public:
DidLaunch ();
virtual lldb_private::Error
- WillAttach (lldb::pid_t pid);
+ WillAttachToProcessWithID (lldb::pid_t pid);
virtual lldb_private::Error
- WillAttach (const char *process_name, bool wait_for_launch);
+ WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
lldb_private::Error
WillLaunchOrAttach ();
@@ -215,9 +215,6 @@ public:
virtual lldb_private::Error
DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc);
- virtual lldb::ByteOrder
- GetByteOrder () const;
-
virtual lldb_private::DynamicLoader *
GetDynamicLoader ();
@@ -322,7 +319,6 @@ protected:
std::auto_ptr<lldb_private::DynamicLoader> m_dynamic_loader_ap;
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio
- lldb::ByteOrder m_byte_order;
GDBRemoteCommunication m_gdb_comm;
lldb::pid_t m_debugserver_pid;
lldb::thread_t m_debugserver_thread;
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 749ae3ceb88..a86a4e10187 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -85,12 +85,19 @@ Process::Process(Target &target, Listener &listener) :
m_exit_string (),
m_thread_list (this),
m_notifications (),
- m_persistent_vars(),
- m_listener(listener),
+ m_image_tokens (),
+ m_listener (listener),
+ m_breakpoint_site_list (),
+ m_persistent_vars (),
+ m_dynamic_checkers_ap (),
m_unix_signals (),
+ m_target_triple (),
+ m_byte_order (eByteOrderHost),
+ m_addr_byte_size (0),
+ m_abi_sp (),
m_process_input_reader (),
m_stdio_communication ("lldb.process.stdio"),
- m_stdio_comm_mutex (Mutex::eMutexTypeRecursive),
+ m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
m_stdout_data ()
{
UpdateInstanceName();
@@ -1438,19 +1445,71 @@ Process::Halt ()
if (error.Success())
{
- bool caused_stop;
+
+ bool caused_stop = false;
+ EventSP event_sp;
+
+ // Pause our private state thread so we can ensure no one else eats
+ // the stop event out from under us.
+ PausePrivateStateThread();
+
+ // Ask the process subclass to actually halt our process
error = DoHalt(caused_stop);
if (error.Success())
{
- DidHalt();
+ // If "caused_stop" is true, then DoHalt stopped the process. If
+ // "caused_stop" is false, the process was already stopped.
+ // If the DoHalt caused the process to stop, then we want to catch
+ // this event and set the interrupted bool to true before we pass
+ // this along so clients know that the process was interrupted by
+ // a halt command.
if (caused_stop)
{
- ProcessEventData *new_data = new ProcessEventData (GetTarget().GetProcessSP(), eStateStopped);
- new_data->SetInterrupted(true);
- BroadcastEvent (eBroadcastBitStateChanged, new_data);
+ // Wait for 2 seconds for the process to stop.
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(2);
+ StateType state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp);
+
+ if (state == eStateInvalid)
+ {
+ // We timeout out and didn't get a stop event...
+ error.SetErrorString ("Halt timed out.");
+ }
+ else
+ {
+ // Since we are eating the event, we need to update our state
+ // otherwise the process state will not match reality...
+ SetPublicState(state);
+
+ if (StateIsStoppedState (state))
+ {
+ // We caused the process to interrupt itself, so mark this
+ // as such in the stop event so clients can tell an interrupted
+ // process from a natural stop
+ ProcessEventData::SetInterruptedInEvent (event_sp.get(), true);
+ }
+ else
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("Process::Halt() failed to stop, state is: %s", StateAsCString(state));
+ error.SetErrorString ("Did not get stopped event after halt.");
+ }
+ }
}
+ DidHalt();
+
}
-
+ // Resume our private state thread before we post the event (if any)
+ ResumePrivateStateThread();
+
+ // Post any event we might have consumed. If all goes well, we will have
+ // stopped the process, intercepted the event and set the interrupted
+ // bool in the event.
+ if (event_sp)
+ BroadcastEvent(event_sp);
+
}
return error;
}
@@ -1530,7 +1589,9 @@ Process::GetTarget () const
uint32_t
Process::GetAddressByteSize()
{
- return m_target.GetArchitecture().GetAddressByteSize();
+ if (m_addr_byte_size == 0)
+ return m_target.GetArchitecture().GetAddressByteSize();
+ return m_addr_byte_size;
}
bool
@@ -1603,8 +1664,8 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
// If no thread has an opinion, we don't report it.
if (ProcessEventData::GetInterruptedFromEvent (event_ptr))
{
- if (log)
- log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state));
+ if (log)
+ log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state));
return true;
}
else
@@ -2074,7 +2135,7 @@ Process::GetArchSpecForExistingProcess (const char *process_name)
void
Process::AppendSTDOUT (const char * s, size_t len)
{
- Mutex::Locker locker (m_stdio_comm_mutex);
+ Mutex::Locker locker (m_stdio_communication_mutex);
m_stdout_data.append (s, len);
BroadcastEventIfUnique (eBroadcastBitSTDOUT);
diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index db7ad2692bb..3e8a4f84947 100644
--- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2660D9CC1192280900958FBD /* StringExtractor.cpp */; };
26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; };
26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; };
@@ -48,6 +49,7 @@
260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = "<group>"; };
260FC7320E5B290400043FC9 /* debugnub-exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "debugnub-exports"; sourceTree = SOURCE_ROOT; };
26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = "<group>"; };
+ 264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = "<group>"; };
26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
2660D9CC1192280900958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = ../../source/Utility/StringExtractor.cpp; sourceTree = SOURCE_ROOT; };
2660D9CD1192280900958FBD /* StringExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = ../../source/Utility/StringExtractor.h; sourceTree = SOURCE_ROOT; };
@@ -190,6 +192,7 @@
26C637D70C71334A0024798E /* DNB.h */,
26C637D60C71334A0024798E /* DNB.cpp */,
26C637D80C71334A0024798E /* DNBArch.h */,
+ 264D5D571293835600ED4C01 /* DNBArch.cpp */,
26C637DA0C71334A0024798E /* DNBBreakpoint.h */,
26C637D90C71334A0024798E /* DNBBreakpoint.cpp */,
26C637DC0C71334A0024798E /* DNBDataRef.h */,
@@ -441,6 +444,7 @@
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */,
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
+ 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index 948125b9714..17a17d32f0d 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -265,10 +265,8 @@ DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_st
DNBLogError ("%6u - %s\n", matching_proc_infos[i].kp_proc.p_pid, matching_proc_infos[i].kp_proc.p_comm);
return INVALID_NUB_PROCESS;
}
- else
- {
- return DNBProcessAttach (matching_proc_infos[0].kp_proc.p_pid, timeout, err_str, err_len);
- }
+
+ return DNBProcessAttach (matching_proc_infos[0].kp_proc.p_pid, timeout, err_str, err_len);
}
nub_process_t
@@ -294,15 +292,20 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_
while (pid != INVALID_NUB_PROCESS)
{
// Wait for process to start up and hit entry point
- DNBLogThreadedIf (LOG_PROCESS, "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged "
- "| eEventProcessStoppedStateChanged, true, INFINITE)...",
- __FUNCTION__, pid);
+ DNBLogThreadedIf (LOG_PROCESS,
+ "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE)...",
+ __FUNCTION__,
+ pid);
nub_event_t set_events = DNBProcessWaitForEvents (pid,
- eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged,
- true, timeout);
- DNBLogThreadedIf (LOG_PROCESS, "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged "
- "| eEventProcessStoppedStateChanged, true, INFINITE) => 0x%8.8x",
- __FUNCTION__, pid, set_events);
+ eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged,
+ true,
+ timeout);
+
+ DNBLogThreadedIf (LOG_PROCESS,
+ "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE) => 0x%8.8x",
+ __FUNCTION__,
+ pid,
+ set_events);
if (set_events == 0)
{
@@ -320,29 +323,30 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_
switch (pid_state)
{
- default:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateAttaching:
- case eStateLaunching:
- case eStateSuspended:
- break; // Ignore
-
- case eStateRunning:
- case eStateStepping:
- // Still waiting to stop at entry point...
- break;
-
- case eStateStopped:
- case eStateCrashed:
- return pid;
- case eStateDetached:
- case eStateExited:
- if (err_str && err_len > 0)
- snprintf(err_str, err_len, "process exited");
- return INVALID_NUB_PROCESS;
- }
- }
+ default:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateSuspended:
+ break; // Ignore
+
+ case eStateRunning:
+ case eStateStepping:
+ // Still waiting to stop at entry point...
+ break;
+
+ case eStateStopped:
+ case eStateCrashed:
+ return pid;
+
+ case eStateDetached:
+ case eStateExited:
+ if (err_str && err_len > 0)
+ snprintf(err_str, err_len, "process exited");
+ return INVALID_NUB_PROCESS;
+ }
+ }
DNBProcessResetEvents(pid, set_events);
}
@@ -352,7 +356,7 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_
}
static size_t
-GetAllInfos(std::vector<struct kinfo_proc>& proc_infos)
+GetAllInfos (std::vector<struct kinfo_proc>& proc_infos)
{
size_t size;
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
@@ -1722,7 +1726,7 @@ DNBProcessGetSharedLibraryInfo (nub_process_t pid, nub_bool_t only_changed, stru
const DNBRegisterSetInfo *
DNBGetRegisterSetInfo (nub_size_t *num_reg_sets)
{
- return DNBArch::GetRegisterSetInfo (num_reg_sets);
+ return DNBArchProtocol::GetRegisterSetInfo (num_reg_sets);
}
@@ -1998,3 +2002,20 @@ DNBResolveExecutablePath (const char *path, char *resolved_path, size_t resolved
return false;
}
+
+void
+DNBInitialize()
+{
+ DNBLogThreadedIf (LOG_PROCESS, "DNBInitialize ()");
+#if defined (__i386__) || defined (__x86_64__)
+ DNBArchImplI386::Initialize();
+ DNBArchImplX86_64::Initialize();
+#elif defined (__arm__)
+ DNBArchMachARM::Initialize();
+#endif
+}
+
+void
+DNBTerminate()
+{
+}
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 4dadff2473b..921bbbfc23d 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -25,6 +25,9 @@ extern "C" {
typedef bool (*DNBShouldCancelCallback) (void *);
+void DNBInitialize ();
+void DNBTerminate ();
+
//----------------------------------------------------------------------
// Process control
//----------------------------------------------------------------------
diff --git a/lldb/tools/debugserver/source/DNBArch.h b/lldb/tools/debugserver/source/DNBArch.h
index 3eb2362aa0f..a0f18cd39c8 100644
--- a/lldb/tools/debugserver/source/DNBArch.h
+++ b/lldb/tools/debugserver/source/DNBArch.h
@@ -22,13 +22,39 @@
struct DNBRegisterValue;
struct DNBRegisterSetInfo;
+class DNBArchProtocol;
+class MachThread;
+
+typedef DNBArchProtocol * (* DNBArchCallbackCreate)(MachThread *thread);
+typedef const DNBRegisterSetInfo * (* DNBArchCallbackGetRegisterSetInfo)(nub_size_t *num_reg_sets);
+typedef const uint8_t * const (* DNBArchCallbackGetBreakpointOpcode)(nub_size_t byte_size);
+
+typedef struct DNBArchPluginInfoTag
+{
+ uint32_t cpu_type;
+ DNBArchCallbackCreate Create;
+ DNBArchCallbackGetRegisterSetInfo GetRegisterSetInfo;
+ DNBArchCallbackGetBreakpointOpcode GetBreakpointOpcode;
+} DNBArchPluginInfo;
class DNBArchProtocol
{
public:
- static const DNBRegisterSetInfo *
+ static DNBArchProtocol *
+ Create (MachThread *thread);
+
+ static const DNBRegisterSetInfo *
GetRegisterSetInfo (nub_size_t *num_reg_sets);
+ static const uint8_t * const
+ GetBreakpointOpcode (nub_size_t byte_size);
+
+ static void
+ RegisterArchPlugin (const DNBArchPluginInfo &arch_info);
+
+ static void
+ SetDefaultArchitecture (uint32_t cpu_type);
+
virtual bool GetRegisterValue (int set, int reg, DNBRegisterValue *value) = 0;
virtual bool SetRegisterValue (int set, int reg, const DNBRegisterValue *value) = 0;
virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len) = 0;
@@ -39,6 +65,7 @@ public:
virtual bool RegisterSetStateIsValid (int set) const = 0;
virtual uint64_t GetPC (uint64_t failValue) = 0; // Get program counter
+ virtual kern_return_t SetPC (uint64_t value) = 0;
virtual uint64_t GetSP (uint64_t failValue) = 0; // Get stack pointer
virtual void ThreadWillResume () = 0;
virtual bool ThreadDidStop () = 0;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index c5c1e7f6f0c..3ca7fe8abeb 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -115,6 +115,7 @@ MachProcess::MachProcess() :
m_image_infos_baton(NULL)
{
DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
+ bzero(&m_arch_plugin_info, sizeof(m_arch_plugin_info));
}
MachProcess::~MachProcess()
@@ -208,7 +209,15 @@ MachProcess::GetThreadInfo(nub_thread_t tid) const
const DNBRegisterSetInfo *
MachProcess::GetRegisterSetInfo(nub_thread_t tid, nub_size_t *num_reg_sets ) const
{
- return DNBArch::GetRegisterSetInfo (num_reg_sets);
+ MachThread *thread = m_thread_list.GetThreadByID (tid);
+ if (thread)
+ {
+ DNBArchProtocol *arch = thread->GetArchProtocol();
+ if (arch)
+ return arch->GetRegisterSetInfo (num_reg_sets);
+ }
+ *num_reg_sets = 0;
+ return NULL;
}
bool
@@ -766,7 +775,7 @@ MachProcess::DisableBreakpoint(nub_break_t breakID, bool remove)
const nub_size_t break_op_size = bp->ByteSize();
assert (break_op_size > 0);
- const uint8_t * const break_op = DNBArch::SoftwareBreakpointOpcode(bp->ByteSize());
+ const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (bp->ByteSize());
if (break_op_size > 0)
{
// Clear a software breakoint instruction
@@ -954,7 +963,7 @@ MachProcess::EnableBreakpoint(nub_break_t breakID)
const nub_size_t break_op_size = bp->ByteSize();
assert (break_op_size != 0);
- const uint8_t * const break_op = DNBArch::SoftwareBreakpointOpcode(break_op_size);
+ const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (break_op_size);
if (break_op_size > 0)
{
// Save the original opcode by reading it
@@ -1507,7 +1516,14 @@ MachProcess::LaunchForDebug
break;
case eLaunchFlavorPosixSpawn:
- m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, argv, envp, stdio_path, this, disable_aslr, launch_err);
+ m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path,
+ m_arch_plugin_info.cpu_type,
+ argv,
+ envp,
+ stdio_path,
+ this,
+ disable_aslr,
+ launch_err);
break;
#if defined (__arm__)
@@ -1590,6 +1606,7 @@ pid_t
MachProcess::PosixSpawnChildForPTraceDebugging
(
const char *path,
+ cpu_type_t cpu_type,
char const *argv[],
char const *envp[],
const char *stdio_path,
@@ -1628,7 +1645,6 @@ MachProcess::PosixSpawnChildForPTraceDebugging
// We don't need to do this for ARM, and we really shouldn't now that we
// have multiple CPU subtypes and no posix_spawnattr call that allows us
// to set which CPU subtype to launch...
- cpu_type_t cpu_type = DNBArch::GetCPUType();
size_t ocount = 0;
err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), DNBError::POSIX);
if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index fa0979d7e20..cff08bb4d68 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -48,7 +48,7 @@ public:
pid_t AttachForDebug (pid_t pid, char *err_str, size_t err_len);
pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err);
static pid_t ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err);
- static pid_t PosixSpawnChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, int disable_aslr, DNBError& err);
+ static pid_t PosixSpawnChildForPTraceDebugging (const char *path, cpu_type_t cpu_type, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, int disable_aslr, DNBError& err);
nub_addr_t GetDYLDAllImageInfosAddress ();
static const void * PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str);
static void CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str);
@@ -254,6 +254,7 @@ private:
DNBCallbackCopyExecutableImageInfos
m_image_infos_callback;
void * m_image_infos_baton;
+ DNBArchPluginInfo m_arch_plugin_info;
};
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
index ca2bf9b3b3a..ddd7746dad4 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
@@ -31,14 +31,9 @@ MachThread::MachThread (MachProcess *process, thread_t thread) :
m_state_mutex (PTHREAD_MUTEX_RECURSIVE),
m_breakID (INVALID_NUB_BREAK_ID),
m_suspendCount (0),
- m_arch (this),
- m_regSets ()
+ m_arch_ap (DNBArchProtocol::Create (this)),
+ m_reg_sets (m_arch_ap->GetRegisterSetInfo (&n_num_reg_sets))
{
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *regSetInfo = m_arch.GetRegisterSetInfo(&num_reg_sets);
- if (num_reg_sets > 0)
- m_regSets.assign(regSetInfo, regSetInfo + num_reg_sets);
-
// Get the thread state so we know if a thread is in a state where we can't
// muck with it and also so we get the suspend count correct in case it was
// already suspended
@@ -251,34 +246,34 @@ MachThread::ThreadIDIsValid(thread_t thread)
bool
MachThread::GetRegisterState(int flavor, bool force)
{
- return m_arch.GetRegisterState(flavor, force) == KERN_SUCCESS;
+ return m_arch_ap->GetRegisterState(flavor, force) == KERN_SUCCESS;
}
bool
MachThread::SetRegisterState(int flavor)
{
- return m_arch.SetRegisterState(flavor) == KERN_SUCCESS;
+ return m_arch_ap->SetRegisterState(flavor) == KERN_SUCCESS;
}
uint64_t
MachThread::GetPC(uint64_t failValue)
{
// Get program counter
- return m_arch.GetPC(failValue);
+ return m_arch_ap->GetPC(failValue);
}
bool
MachThread::SetPC(uint64_t value)
{
// Set program counter
- return m_arch.SetPC(value);
+ return m_arch_ap->SetPC(value);
}
uint64_t
MachThread::GetSP(uint64_t failValue)
{
// Get stack pointer
- return m_arch.GetSP(failValue);
+ return m_arch_ap->GetSP(failValue);
}
nub_process_t
@@ -342,7 +337,7 @@ MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action)
Resume();
break;
}
- m_arch.ThreadWillResume();
+ m_arch_ap->ThreadWillResume();
m_stop_exception.Clear();
}
@@ -372,7 +367,7 @@ MachThread::ShouldStop(bool &step_more)
}
else
{
- if (m_arch.StepNotComplete())
+ if (m_arch_ap->StepNotComplete())
{
step_more = true;
return false;
@@ -426,7 +421,7 @@ MachThread::ThreadDidStop()
// When this method gets called, the process state is still in the
// state it was in while running so we can act accordingly.
- m_arch.ThreadDidStop();
+ m_arch_ap->ThreadDidStop();
// We may have suspended this thread so the primary thread could step
@@ -499,7 +494,7 @@ MachThread::NotifyException(MachException::Data& exc)
{
m_stop_exception = exc;
}
- bool handled = m_arch.NotifyException(exc);
+ bool handled = m_arch_ap->NotifyException(exc);
if (!handled)
{
handled = true;
@@ -551,25 +546,25 @@ MachThread::SetState(nub_state_t state)
uint32_t
MachThread::GetNumRegistersInSet(int regSet) const
{
- if (regSet < m_regSets.size())
- return m_regSets[regSet].num_registers;
+ if (regSet < n_num_reg_sets)
+ return m_reg_sets[regSet].num_registers;
return 0;
}
const char *
MachThread::GetRegisterSetName(int regSet) const
{
- if (regSet < m_regSets.size())
- return m_regSets[regSet].name;
+ if (regSet < n_num_reg_sets)
+ return m_reg_sets[regSet].name;
return NULL;
}
const DNBRegisterInfo *
MachThread::GetRegisterInfo(int regSet, int regIndex) const
{
- if (regSet < m_regSets.size())
- if (regIndex < m_regSets[regSet].num_registers)
- return &m_regSets[regSet].registers[regIndex];
+ if (regSet < n_num_reg_sets)
+ if (regIndex < m_reg_sets[regSet].num_registers)
+ return &m_reg_sets[regSet].registers[regIndex];
return NULL;
}
void
@@ -577,19 +572,19 @@ MachThread::DumpRegisterState(int regSet)
{
if (regSet == REGISTER_SET_ALL)
{
- for (regSet = 1; regSet < m_regSets.size(); regSet++)
+ for (regSet = 1; regSet < n_num_reg_sets; regSet++)
DumpRegisterState(regSet);
}
else
{
- if (m_arch.RegisterSetStateIsValid(regSet))
+ if (m_arch_ap->RegisterSetStateIsValid(regSet))
{
const size_t numRegisters = GetNumRegistersInSet(regSet);
size_t regIndex = 0;
DNBRegisterValueClass reg;
for (regIndex = 0; regIndex < numRegisters; ++regIndex)
{
- if (m_arch.GetRegisterValue(regSet, regIndex, &reg))
+ if (m_arch_ap->GetRegisterValue(regSet, regIndex, &reg))
{
reg.Dump(NULL, NULL);
}
@@ -605,39 +600,39 @@ MachThread::DumpRegisterState(int regSet)
const DNBRegisterSetInfo *
MachThread::GetRegisterSetInfo(nub_size_t *num_reg_sets ) const
{
- *num_reg_sets = m_regSets.size();
- return &m_regSets[0];
+ *num_reg_sets = n_num_reg_sets;
+ return &m_reg_sets[0];
}
bool
MachThread::GetRegisterValue ( uint32_t set, uint32_t reg, DNBRegisterValue *value )
{
- return m_arch.GetRegisterValue(set, reg, value);
+ return m_arch_ap->GetRegisterValue(set, reg, value);
}
bool
MachThread::SetRegisterValue ( uint32_t set, uint32_t reg, const DNBRegisterValue *value )
{
- return m_arch.SetRegisterValue(set, reg, value);
+ return m_arch_ap->SetRegisterValue(set, reg, value);
}
nub_size_t
MachThread::GetRegisterContext (void *buf, nub_size_t buf_len)
{
- return m_arch.GetRegisterContext(buf, buf_len);
+ return m_arch_ap->GetRegisterContext(buf, buf_len);
}
nub_size_t
MachThread::SetRegisterContext (const void *buf, nub_size_t buf_len)
{
- return m_arch.SetRegisterContext(buf, buf_len);
+ return m_arch_ap->SetRegisterContext(buf, buf_len);
}
uint32_t
MachThread::EnableHardwareBreakpoint (const DNBBreakpoint *bp)
{
if (bp != NULL && bp->IsBreakpoint())
- return m_arch.EnableHardwareBreakpoint(bp->Address(), bp->ByteSize());
+ return m_arch_ap->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize());
return INVALID_NUB_HW_INDEX;
}
@@ -645,7 +640,7 @@ uint32_t
MachThread::EnableHardwareWatchpoint (const DNBBreakpoint *wp)
{
if (wp != NULL && wp->IsWatchpoint())
- return m_arch.EnableHardwareWatchpoint(wp->Address(), wp->ByteSize(), wp->WatchpointRead(), wp->WatchpointWrite());
+ return m_arch_ap->EnableHardwareWatchpoint(wp->Address(), wp->ByteSize(), wp->WatchpointRead(), wp->WatchpointWrite());
return INVALID_NUB_HW_INDEX;
}
@@ -653,7 +648,7 @@ bool
MachThread::DisableHardwareBreakpoint (const DNBBreakpoint *bp)
{
if (bp != NULL && bp->IsHardware())
- return m_arch.DisableHardwareBreakpoint(bp->GetHardwareIndex());
+ return m_arch_ap->DisableHardwareBreakpoint(bp->GetHardwareIndex());
return false;
}
@@ -661,7 +656,7 @@ bool
MachThread::DisableHardwareWatchpoint (const DNBBreakpoint *wp)
{
if (wp != NULL && wp->IsHardware())
- return m_arch.DisableHardwareWatchpoint(wp->GetHardwareIndex());
+ return m_arch_ap->DisableHardwareWatchpoint(wp->GetHardwareIndex());
return false;
}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.h b/lldb/tools/debugserver/source/MacOSX/MachThread.h
index f7f2ce8b1ab..0b2a8bf1ff9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.h
@@ -95,6 +95,13 @@ public:
GetBasicInfo ();
const char * GetBasicInfoAsString () const;
const char * GetName ();
+
+ DNBArchProtocol*
+ GetArchProtocol()
+ {
+ return m_arch_ap.get();
+ }
+
protected:
static bool GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
@@ -113,8 +120,9 @@ protected:
struct thread_basic_info m_basicInfo; // Basic information for a thread used to see if a thread is valid
uint32_t m_suspendCount; // The current suspend count
MachException::Data m_stop_exception; // The best exception that describes why this thread is stopped
- DNBArch m_arch; // Arch specific information for register state and more
- std::vector<DNBRegisterSetInfo> m_regSets; // Register set information for this thread
+ std::auto_ptr<DNBArchProtocol> m_arch_ap; // Arch specific information for register state and more
+ const DNBRegisterSetInfo *const m_reg_sets; // Register set information for this thread
+ nub_size_t n_num_reg_sets;
#ifdef THREAD_IDENTIFIER_INFO_COUNT
thread_identifier_info_data_t m_ident_info;
struct proc_threadinfo m_proc_threadinfo;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
index db2a00a304a..7a5e9bb8588 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
@@ -12,6 +12,9 @@
//===----------------------------------------------------------------------===//
#include "MachThreadList.h"
+
+#include <sys/sysctl.h>
+
#include "DNBLog.h"
#include "DNBThreadResumeActions.h"
#include "MachProcess.h"
@@ -104,6 +107,15 @@ MachThreadList::GetThreadInfo(nub_thread_t tid) const
return NULL;
}
+MachThread *
+MachThreadList::GetThreadByID (nub_thread_t tid) const
+{
+ uint32_t idx = GetThreadIndexByID(tid);
+ if (idx < m_threads.size())
+ return m_threads[idx].get();
+ return NULL;
+}
+
bool
MachThreadList::GetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const
{
@@ -202,9 +214,28 @@ uint32_t
MachThreadList::UpdateThreadList(MachProcess *process, bool update)
{
// locker will keep a mutex locked until it goes out of scope
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThreadList::UpdateThreadList (pid = %4.4x, update = %u )", process->ProcessID(), update);
+ DNBLogThreadedIf (LOG_THREAD, "MachThreadList::UpdateThreadList (pid = %4.4x, update = %u) process stop count = %u", process->ProcessID(), update, process->StopCount());
PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+#if defined (__i386__) || defined (__x86_64__)
+ if (process->StopCount() == 0)
+ {
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process->ProcessID() };
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ bool is_64_bit = false;
+ if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0)
+ {
+ if (processInfo.kp_proc.p_flag & P_LP64)
+ is_64_bit = true;
+ }
+ if (is_64_bit)
+ DNBArchProtocol::SetDefaultArchitecture(CPU_TYPE_X86_64);
+ else
+ DNBArchProtocol::SetDefaultArchitecture(CPU_TYPE_I386);
+ }
+#endif
+
if (m_threads.empty() || update)
{
thread_array_t thread_list = NULL;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThreadList.h b/lldb/tools/debugserver/source/MacOSX/MachThreadList.h
index 5c813886569..1a17618a7e3 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThreadList.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachThreadList.h
@@ -55,6 +55,8 @@ public:
bool DisableHardwareWatchpoint (const DNBBreakpoint *wp) const;
uint32_t GetThreadIndexForThreadStoppedWithSignal (const int signo) const;
+ MachThread * GetThreadByID (nub_thread_t tid) const;
+
protected:
typedef std::vector<MachThreadSP> collection;
typedef collection::iterator iterator;
diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
index f012caa1828..9aff44e5dbc 100644
--- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
+++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
@@ -235,6 +235,5 @@ protected:
};
-typedef DNBArchMachARM DNBArch;
#endif // #if defined (__arm__)
#endif // #ifndef __DebugNubArchMachARM_h__
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
index 0a0601f6378..1222b809904 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__i386__)
+#if defined (__i386__) || defined (__x86_64__)
#include <sys/cdefs.h>
@@ -20,8 +20,6 @@
#include "MachThread.h"
#include "MachProcess.h"
-static const uint8_t g_breakpoint_opcode[] = { 0xCC };
-
enum
{
gpr_eax = 0,
@@ -187,21 +185,6 @@ enum
gdb_mm7 = 48
};
-
-const uint8_t * const
-DNBArchImplI386::SoftwareBreakpointOpcode (nub_size_t byte_size)
-{
- if (byte_size == 1)
- return g_breakpoint_opcode;
- return NULL;
-}
-
-uint32_t
-DNBArchImplI386::GetCPUType()
-{
- return CPU_TYPE_I386;
-}
-
uint64_t
DNBArchImplI386::GetPC(uint64_t failValue)
{
@@ -589,6 +572,21 @@ DNBArchImplI386::g_reg_sets[] =
const size_t DNBArchImplI386::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
+DNBArchProtocol *
+DNBArchImplI386::Create (MachThread *thread)
+{
+ return new DNBArchImplI386 (thread);
+}
+
+const uint8_t * const
+DNBArchImplI386::SoftwareBreakpointOpcode (nub_size_t byte_size)
+{
+ static const uint8_t g_breakpoint_opcode[] = { 0xCC };
+ if (byte_size == 1)
+ return g_breakpoint_opcode;
+ return NULL;
+}
+
const DNBRegisterSetInfo *
DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
@@ -596,6 +594,22 @@ DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets)
return g_reg_sets;
}
+
+void
+DNBArchImplI386::Initialize()
+{
+ DNBArchPluginInfo arch_plugin_info =
+ {
+ CPU_TYPE_I386,
+ DNBArchImplI386::Create,
+ DNBArchImplI386::GetRegisterSetInfo,
+ DNBArchImplI386::SoftwareBreakpointOpcode
+ };
+
+ // Register this arch plug-in with the main protocol class
+ DNBArchProtocol::RegisterArchPlugin (arch_plugin_info);
+}
+
bool
DNBArchImplI386::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
{
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
index 2b47e09cdf3..e0fcc199b5e 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
@@ -14,7 +14,7 @@
#ifndef __DNBArchImplI386_h__
#define __DNBArchImplI386_h__
-#if defined (__i386__)
+#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
#include <mach/mach_types.h>
@@ -34,9 +34,8 @@ public:
virtual ~DNBArchImplI386()
{
}
-
- static const DNBRegisterSetInfo *
- GetRegisterSetInfo(nub_size_t *num_reg_sets);
+
+ static void Initialize();
virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value);
virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value);
@@ -53,9 +52,6 @@ public:
virtual bool ThreadDidStop();
virtual bool NotifyException(MachException::Data& exc);
- static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size);
- static uint32_t GetCPUType();
-
protected:
kern_return_t EnableHardwareSingleStep (bool enable);
@@ -186,11 +182,18 @@ protected:
kern_return_t SetFPUState ();
kern_return_t SetEXCState ();
+ static DNBArchProtocol *
+ Create (MachThread *thread);
+
+ static const uint8_t * const
+ SoftwareBreakpointOpcode (nub_size_t byte_size);
+
+ static const DNBRegisterSetInfo *
+ GetRegisterSetInfo(nub_size_t *num_reg_sets);
+
MachThread *m_thread;
State m_state;
};
-typedef DNBArchImplI386 DNBArch;
-
-#endif // #if defined (__i386__)
+#endif // #if defined (__i386__) || defined (__x86_64__)
#endif // #ifndef __DNBArchImplI386_h__
diff --git a/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h b/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
index 6263407460a..a787d14d8d4 100644
--- a/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
+++ b/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
@@ -175,6 +175,5 @@ protected:
State m_state;
};
-typedef DNBArchMachPPC DNBArch;
#endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
#endif // #ifndef __DebugNubArchMachPPC_h__
diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
index 1f18156650c..fde3be6ab5d 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__x86_64__)
+#if defined (__i386__) || defined (__x86_64__)
#include <sys/cdefs.h>
@@ -20,22 +20,6 @@
#include "MachThread.h"
#include "MachProcess.h"
-static const uint8_t g_breakpoint_opcode[] = { 0xCC };
-
-const uint8_t * const
-DNBArchImplX86_64::SoftwareBreakpointOpcode (nub_size_t byte_size)
-{
- if (byte_size == 1)
- return g_breakpoint_opcode;
- return NULL;
-}
-
-uint32_t
-DNBArchImplX86_64::GetCPUType()
-{
- return CPU_TYPE_X86_64;
-}
-
uint64_t
DNBArchImplX86_64::GetPC(uint64_t failValue)
{
@@ -718,13 +702,43 @@ DNBArchImplX86_64::g_reg_sets[] =
const size_t DNBArchImplX86_64::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
+DNBArchProtocol *
+DNBArchImplX86_64::Create (MachThread *thread)
+{
+ return new DNBArchImplX86_64 (thread);
+}
+
+const uint8_t * const
+DNBArchImplX86_64::SoftwareBreakpointOpcode (nub_size_t byte_size)
+{
+ static const uint8_t g_breakpoint_opcode[] = { 0xCC };
+ if (byte_size == 1)
+ return g_breakpoint_opcode;
+ return NULL;
+}
+
const DNBRegisterSetInfo *
-DNBArchImplX86_64::GetRegisterSetInfo (nub_size_t *num_reg_sets)
+DNBArchImplX86_64::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
*num_reg_sets = k_num_register_sets;
return g_reg_sets;
}
+void
+DNBArchImplX86_64::Initialize()
+{
+ DNBArchPluginInfo arch_plugin_info =
+ {
+ CPU_TYPE_X86_64,
+ DNBArchImplX86_64::Create,
+ DNBArchImplX86_64::GetRegisterSetInfo,
+ DNBArchImplX86_64::SoftwareBreakpointOpcode
+ };
+
+ // Register this arch plug-in with the main protocol class
+ DNBArchProtocol::RegisterArchPlugin (arch_plugin_info);
+}
+
bool
DNBArchImplX86_64::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
{
@@ -1032,4 +1046,4 @@ DNBArchImplX86_64::RegisterSetStateIsValid (int set) const
-#endif // #if defined (__i386__)
+#endif // #if defined (__i386__) || defined (__x86_64__)
diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
index def263fec5e..584943c85c7 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
@@ -14,8 +14,7 @@
#ifndef __DNBArchImplX86_64_h__
#define __DNBArchImplX86_64_h__
-//#if defined (__i386__)
-#if defined(__x86_64__)
+#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
#include <mach/mach_types.h>
#include <mach/thread_status.h>
@@ -35,9 +34,7 @@ public:
{
}
- static const DNBRegisterSetInfo *
- GetRegisterSetInfo(nub_size_t *num_reg_sets);
-
+ static void Initialize();
virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value);
virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value);
virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
@@ -54,9 +51,6 @@ public:
virtual bool ThreadDidStop();
virtual bool NotifyException(MachException::Data& exc);
- static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size);
- static uint32_t GetCPUType();
-
protected:
kern_return_t EnableHardwareSingleStep (bool enable);
@@ -189,11 +183,18 @@ protected:
kern_return_t SetFPUState ();
kern_return_t SetEXCState ();
+ static DNBArchProtocol *
+ Create (MachThread *thread);
+
+ static const uint8_t * const
+ SoftwareBreakpointOpcode (nub_size_t byte_size);
+
+ static const DNBRegisterSetInfo *
+ GetRegisterSetInfo(nub_size_t *num_reg_sets);
+
MachThread *m_thread;
State m_state;
};
-typedef DNBArchImplX86_64 DNBArch;
-
-#endif // #if defined (__x86_64__)
+#endif // #if defined (__i386__) || defined (__x86_64__)
#endif // #ifndef __DNBArchImplX86_64_h__
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 7b2ba3335be..bb8c59ea0eb 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -60,11 +60,10 @@
extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
-RNBRemote::RNBRemote (bool use_native_regs) :
- m_ctx(),
- m_comm(),
- m_extended_mode(false),
- m_noack_mode(false),
+RNBRemote::RNBRemote (bool use_native_regs, const char *arch) :
+ m_ctx (),
+ m_comm (),
+ m_arch (),
m_continue_thread(-1),
m_thread(-1),
m_mutex(),
@@ -75,10 +74,14 @@ RNBRemote::RNBRemote (bool use_native_regs) :
m_rx_pthread(0),
m_breakpoints(),
m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
+ m_extended_mode(false),
+ m_noack_mode(false),
m_use_native_regs (use_native_regs)
{
DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
CreatePacketTable ();
+ if (arch && arch[0])
+ m_arch.assign (arch);
}
@@ -803,12 +806,10 @@ RegisterEntryNotAvailable (register_map_entry_t *reg_entry)
reg_entry->nub_info.reg_gdb = INVALID_NUB_REGNUM;
}
-#if defined (__arm__)
//----------------------------------------------------------------------
// ARM regiseter sets as gdb knows them
//----------------------------------------------------------------------
-
register_map_entry_t
g_gdb_register_map_arm[] =
{
@@ -873,32 +874,6 @@ g_gdb_register_map_arm[] =
{ 58, 4, "fpscr", {0}, NULL, 0}
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_arm[i].gdb_name, &g_gdb_register_map_arm[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_arm[i]);
- assert (g_gdb_register_map_arm[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_arm;
- g_num_reg_entries = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
- }
-}
-
-
-#elif defined (__i386__)
-
register_map_entry_t
g_gdb_register_map_i386[] =
{
@@ -945,32 +920,6 @@ g_gdb_register_map_i386[] =
{ 40, 4, "mxcsr" , {0}, NULL, 0 },
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_i386[i].gdb_name, &g_gdb_register_map_i386[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_i386[i]);
- assert (g_gdb_register_map_i386[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_i386;
- g_num_reg_entries = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
- }
-}
-
-
-#elif defined (__x86_64__)
-
register_map_entry_t
g_gdb_register_map_x86_64[] =
{
@@ -1033,86 +982,113 @@ g_gdb_register_map_x86_64[] =
{ 56, 4, "mxcsr" , {0}, NULL, 0 }
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_x86_64[i].gdb_name, &g_gdb_register_map_x86_64[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_x86_64[i]);
- assert (g_gdb_register_map_x86_64[i].gdb_size < MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_x86_64;
- g_num_reg_entries = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
- }
-}
-
-
-#else
void
-RNBRemote::InitializeRegisters (int use_native_registers)
+RNBRemote::Initialize()
{
- // No choice, we don't have a GDB register definition for this arch.
- RNBRemote::InitializeNativeRegisters();
+ DNBInitialize();
}
-#endif
-
-void
-RNBRemote::InitializeNativeRegisters()
+bool
+RNBRemote::InitializeRegisters ()
{
- if (g_dynamic_register_map.empty())
- {
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
-
- assert (num_reg_sets > 0 && reg_sets != NULL);
+ pid_t pid = m_ctx.ProcessID();
+ if (pid == INVALID_NUB_PROCESS)
+ return false;
- uint32_t regnum = 0;
- for (nub_size_t set = 0; set < num_reg_sets; ++set)
+ if (m_use_native_regs)
+ {
+ DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface (%s)", __FUNCTION__, m_arch.c_str());
+ // Discover the registers by querying the DNB interface and letting it
+ // state the registers that it would like to export. This allows the
+ // registers to be discovered using multiple qRegisterInfo calls to get
+ // all register information after the architecture for the process is
+ // determined.
+ if (g_dynamic_register_map.empty())
{
- if (reg_sets[set].registers == NULL)
- continue;
+ nub_size_t num_reg_sets = 0;
+ const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
- for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
+ assert (num_reg_sets > 0 && reg_sets != NULL);
+
+ uint32_t regnum = 0;
+ for (nub_size_t set = 0; set < num_reg_sets; ++set)
{
- register_map_entry_t reg_entry = {
- regnum++, // register number starts at zero and goes up with no gaps
- reg_sets[set].registers[reg].size, // register size in bytes
- reg_sets[set].registers[reg].name, // register name
- reg_sets[set].registers[reg], // DNBRegisterInfo
- NULL, // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
- reg_sets[set].registers[reg].reg_generic != INVALID_NUB_REGNUM};
-
- g_dynamic_register_map.push_back (reg_entry);
+ if (reg_sets[set].registers == NULL)
+ continue;
+
+ for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
+ {
+ register_map_entry_t reg_entry = {
+ regnum++, // register number starts at zero and goes up with no gaps
+ reg_sets[set].registers[reg].size, // register size in bytes
+ reg_sets[set].registers[reg].name, // register name
+ reg_sets[set].registers[reg], // DNBRegisterInfo
+ NULL, // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
+ reg_sets[set].registers[reg].reg_generic != INVALID_NUB_REGNUM};
+
+ g_dynamic_register_map.push_back (reg_entry);
+ }
}
+ g_reg_entries = g_dynamic_register_map.data();
+ g_num_reg_entries = g_dynamic_register_map.size();
}
- g_reg_entries = g_dynamic_register_map.data();
- g_num_reg_entries = g_dynamic_register_map.size();
+ return true;
}
-}
-
-
-const register_map_entry_t *
-register_mapping_by_regname (const char *n)
-{
- for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
+ else
{
- if (strcmp (g_reg_entries[reg].gdb_name, n) == 0)
- return &g_reg_entries[reg];
+ DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting gdb registers (%s)", __FUNCTION__, m_arch.c_str());
+#if defined (__i386__) || defined (__x86_64__)
+ if (m_arch.compare("x86_64") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_x86_64[i].gdb_name, &g_gdb_register_map_x86_64[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_x86_64[i]);
+ assert (g_gdb_register_map_x86_64[i].gdb_size < MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_x86_64;
+ g_num_reg_entries = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
+ return true;
+ }
+ else if (m_arch.compare("i386") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_i386[i].gdb_name, &g_gdb_register_map_i386[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_i386[i]);
+ assert (g_gdb_register_map_i386[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_i386;
+ g_num_reg_entries = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
+ return true;
+ }
+#elif defined (__arm__)
+ if (m_arch.find ("arm") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_arm[i].gdb_name, &g_gdb_register_map_arm[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_arm[i]);
+ assert (g_gdb_register_map_arm[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_arm;
+ g_num_reg_entries = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
+ return true;
+ }
+#endif
}
- return NULL;
+ return false;
}
/* The inferior has stopped executing; send a packet
@@ -1121,7 +1097,7 @@ register_mapping_by_regname (const char *n)
void
RNBRemote::NotifyThatProcessStopped (void)
{
- RNBRemote::HandlePacket_last_signal ("");
+ RNBRemote::HandlePacket_last_signal (NULL);
return;
}
@@ -1396,6 +1372,9 @@ RNBRemote::HandlePacket_qC (const char *p)
rnb_err_t
RNBRemote::HandlePacket_qRegisterInfo (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
p += strlen ("qRegisterInfo");
nub_size_t num_reg_sets = 0;
@@ -1951,6 +1930,9 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
if (thread_ident_info.dispatch_qaddr != 0)
ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
}
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
DNBRegisterValue reg_value;
for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
{
@@ -2002,45 +1984,45 @@ RNBRemote::HandlePacket_last_signal (const char *unused)
case eStateSuspended:
case eStateStopped:
case eStateCrashed:
- {
- nub_thread_t tid = DNBProcessGetCurrentThread (pid);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThread (tid);
+ {
+ nub_thread_t tid = DNBProcessGetCurrentThread (pid);
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ SetCurrentThread (tid);
- SendStopReplyPacketForThread (tid);
- }
+ SendStopReplyPacketForThread (tid);
+ }
break;
case eStateInvalid:
case eStateUnloaded:
case eStateExited:
- {
- char pid_exited_packet[16] = "";
- int pid_status = 0;
- // Process exited with exit status
- if (!DNBProcessGetExitStatus(pid, &pid_status))
- pid_status = 0;
-
- if (pid_status)
{
- if (WIFEXITED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
- else if (WIFSIGNALED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
- else if (WIFSTOPPED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
- }
+ char pid_exited_packet[16] = "";
+ int pid_status = 0;
+ // Process exited with exit status
+ if (!DNBProcessGetExitStatus(pid, &pid_status))
+ pid_status = 0;
- // If we have an empty exit packet, lets fill one in to be safe.
- if (!pid_exited_packet[0])
- {
- strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
- pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
- }
+ if (pid_status)
+ {
+ if (WIFEXITED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
+ else if (WIFSIGNALED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
+ else if (WIFSTOPPED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
+ }
- return SendPacket (pid_exited_packet);
- }
+ // If we have an empty exit packet, lets fill one in to be safe.
+ if (!pid_exited_packet[0])
+ {
+ strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
+ pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
+ }
+
+ return SendPacket (pid_exited_packet);
+ }
break;
}
return rnb_success;
@@ -2244,6 +2226,10 @@ RNBRemote::HandlePacket_g (const char *p)
{
return SendPacket ("E11");
}
+
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
nub_process_t pid = m_ctx.ProcessID ();
nub_thread_t tid = GetCurrentThread();
@@ -2283,6 +2269,10 @@ RNBRemote::HandlePacket_G (const char *p)
{
return SendPacket ("E11");
}
+
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
StringExtractor packet(p);
packet.SetFilePos(1); // Skip the 'G'
@@ -2872,6 +2862,9 @@ RNBRemote::HandlePacket_z (const char *p)
rnb_err_t
RNBRemote::HandlePacket_p (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("No thread specified in p packet");
@@ -2931,6 +2924,9 @@ RNBRemote::HandlePacket_p (const char *p)
rnb_err_t
RNBRemote::HandlePacket_P (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("Empty P packet");
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 30ab7e67302..fab42bc9693 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -106,10 +106,12 @@ public:
typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
- RNBRemote(bool use_native_regs);
- ~RNBRemote();
+ RNBRemote (bool use_native_regs, const char *arch);
+ ~RNBRemote ();
- static void InitializeRegisters (int use_native);
+ void Initialize();
+
+ bool InitializeRegisters ();
rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);
rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);
@@ -194,9 +196,6 @@ private:
protected:
- static void
- InitializeNativeRegisters ();
-
rnb_err_t GetCommData ();
void CommDataReceived(const std::string& data);
struct Packet
@@ -273,8 +272,7 @@ protected:
typedef BreakpointMap::const_iterator BreakpointMapConstIter;
RNBContext m_ctx; // process context
RNBSocket m_comm; // communication port
- bool m_extended_mode; // are we in extended mode?
- bool m_noack_mode; // are we in no-ack mode?
+ std::string m_arch;
nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all
nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all
PThreadMutex m_mutex; // Mutex that protects
@@ -286,7 +284,9 @@ protected:
BreakpointMap m_breakpoints;
BreakpointMap m_watchpoints;
uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb
- bool m_use_native_regs;
+ bool m_extended_mode:1, // are we in extended mode?
+ m_noack_mode:1, // are we in no-ack mode?
+ m_use_native_regs:1; // Use native registers by querying DNB layer for register definitions?
};
/* We translate the /usr/include/mach/exception_types.h exception types
diff --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index a3cae284d4f..e8c28cc5eae 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -334,7 +334,6 @@ RNBRunLoopLaunchAttaching (RNBRemoteSP &remote, nub_process_t attach_pid, nub_pr
}
else
{
-
ctx.SetProcessID(pid);
return eRNBRunLoopModeInferiorExecuting;
}
@@ -644,6 +643,7 @@ show_usage_and_exit (int exit_code)
static struct option g_long_options[] =
{
{ "attach", required_argument, NULL, 'a' },
+ { "arch", required_argument, NULL, 'A' },
{ "debug", no_argument, NULL, 'g' },
{ "verbose", no_argument, NULL, 'v' },
{ "lockdown", no_argument, &g_lockdown_opt, 1 }, // short option "-k"
@@ -695,6 +695,7 @@ main (int argc, char *argv[])
std::string waitfor_pid_name; // Wait for a process that starts with this name
std::string attach_pid_name;
std::string stdio_path;
+ std::string arch_name;
useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
useconds_t waitfor_duration = 0; // Time in seconds to wait for a process by name, 0 means wait forever.
@@ -704,7 +705,7 @@ main (int argc, char *argv[])
RNBRunLoopMode start_mode = eRNBRunLoopModeExit;
- while ((ch = getopt_long(argc, argv, "a:d:gi:vktl:f:w:x:rs:", g_long_options, &long_option_index)) != -1)
+ while ((ch = getopt_long(argc, argv, "a:A:d:gi:vktl:f:w:x:rs:", g_long_options, &long_option_index)) != -1)
{
DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
ch, (uint8_t)ch,
@@ -716,6 +717,11 @@ main (int argc, char *argv[])
case 0: // Any optional that auto set themselves will return 0
break;
+ case 'A':
+ if (optarg && optarg[0])
+ arch_name.assign(optarg);
+ break;
+
case 'a':
if (optarg && optarg[0])
{
@@ -869,12 +875,28 @@ main (int argc, char *argv[])
break;
}
}
+
+ if (arch_name.empty())
+ {
+#if defined (__i386__)
+ arch_name.assign ("i386");
+#elif defined (__x86_64__)
+ arch_name.assign ("x86_64");
+#elif defined (__arm__)
+ arch_name.assign ("arm");
+#endif
+ }
+ if (arch_name.empty())
+ {
+ fprintf(stderr, "error: no architecture was specified\n");
+ exit (8);
+ }
// Skip any options we consumed with getopt_long
argc -= optind;
argv += optind;
- g_remoteSP.reset (new RNBRemote (use_native_registers));
+ g_remoteSP.reset (new RNBRemote (use_native_registers, arch_name.c_str()));
RNBRemote *remote = g_remoteSP.get();
if (remote == NULL)
@@ -883,6 +905,8 @@ main (int argc, char *argv[])
return -1;
}
+ g_remoteSP->Initialize();
+
RNBContext& ctx = remote->Context();
@@ -911,11 +935,6 @@ main (int argc, char *argv[])
DNBLogDebug("argv[%i] = %s", i, argv[i]);
}
- // Now that we have read in the options and enabled logging, initialize
- // the rest of RNBRemote
- RNBRemote::InitializeRegisters (use_native_registers);
-
-
// as long as we're dropping remotenub in as a replacement for gdbserver,
// explicitly note that this is not gdbserver.
OpenPOWER on IntegriCloud