[Lldb-commits] [lldb] r119680 - in /lldb/trunk: include/lldb/API/ include/lldb/Target/ lldb.xcodeproj/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Target/ tools/debugserver/debugserver.xcodeproj/ tools/debugserver/source/ tools/debugserver/source/MacOSX/ tools/debugserver/source/MacOSX/arm/ tools/debugserver/source/MacOSX/i386/ tools/debugserver/source/MacOSX/ppc/ tools/debugserver/source/MacOSX/x86_64/

Greg Clayton gclayton at apple.com
Wed Nov 17 21:57:03 PST 2010


Author: gclayton
Date: Wed Nov 17 23:57:03 2010
New Revision: 119680

URL: http://llvm.org/viewvc/llvm-project?rev=119680&view=rev
Log:
Fixed Process::Halt() as it was broken for "process halt" after recent changes
to the DoHalt down in ProcessGDBRemote. I also moved the functionality that
was in ProcessGDBRemote::DoHalt up into Process::Halt so not every class has
to implement a tricky halt/resume on the internal state thread. The 
functionality is the same as it was before with two changes:
- when we eat the event we now just reuse the event we consume when the private
  state thread is paused and set the interrupted bool on the event if needed
- we also properly update the Process::m_public_state with the state of the
  event we consume.
  
Prior to this, if you issued a "process halt" it would eat the event, not 
update the process state, and then produce a new event with the interrupted
bit set and send it. Anyone listening to the event would get the stopped event
with a process that whose state was set to "running".

Fixed debugserver to not have to be spawned with the architecture of the
inferior process. This worked fine for launching processes, but when attaching
to processes by name or pid without a file in lldb, it would fail.

Now debugserver can support multiple architectures for a native debug session
on the current host. This currently means i386 and x86_64 are supported in
the same binary and a x86_64 debugserver can attach to a i386 executable.
This change involved a lot of changes to make sure we dynamically detect the
correct registers for the inferior process.


Modified:
    lldb/trunk/include/lldb/API/SBThread.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
    lldb/trunk/tools/debugserver/source/DNB.cpp
    lldb/trunk/tools/debugserver/source/DNB.h
    lldb/trunk/tools/debugserver/source/DNBArch.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.h
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
    lldb/trunk/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h
    lldb/trunk/tools/debugserver/source/debugserver.cpp

Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Wed Nov 17 23:57:03 2010
@@ -35,6 +35,30 @@
 
     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);

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Wed Nov 17 23:57:03 2010
@@ -628,6 +628,12 @@
     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 @@
     //------------------------------------------------------------------
     /// 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 @@
     /// @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 @@
     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; 

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Nov 17 23:57:03 2010
@@ -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";
 			};

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Wed Nov 17 23:57:03 2010
@@ -59,8 +59,10 @@
     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 @@
 DynamicLoaderMacOSXDYLD::DidAttach ()
 {
     PrivateInitialize(m_process);
-    if (NeedToLocateDYLD ())
-        LocateDYLD ();
+    LocateDYLD ();
     SetNotificationBreakpoint ();
-    UpdateAllImageInfos();
 }
 
 //------------------------------------------------------------------
@@ -99,10 +99,8 @@
 DynamicLoaderMacOSXDYLD::DidLaunch ()
 {
     PrivateInitialize(m_process);
-    if (NeedToLocateDYLD ())
-        LocateDYLD ();
+    LocateDYLD ();
     SetNotificationBreakpoint ();
-    UpdateAllImageInfos();
 }
 
 
@@ -401,12 +399,23 @@
 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 @@
         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 @@
         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 @@
                     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 @@
     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 @@
 
         // 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 @@
             if (log)
                 PutToLog(log.get());
         }
+        m_dyld_image_infos_stop_id = m_process->GetStopID();
     }
     else
     {

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Wed Nov 17 23:57:03 2010
@@ -266,6 +266,41 @@
             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 @@
     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;
 

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Wed Nov 17 23:57:03 2010
@@ -235,9 +235,7 @@
     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 @@
 Error
 ProcessMacOSX::DoHalt (bool &caused_stop)
 {
+    caused_stop = true;
     return Signal (SIGSTOP);
 }
 

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Wed Nov 17 23:57:03 2010
@@ -247,8 +247,6 @@
     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

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Nov 17 23:57:03 2010
@@ -105,7 +105,6 @@
     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 @@
 }
 
 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 @@
             if (response.IsOKPacket())
                 m_gdb_comm.SetAckMode (false);
         }
-
-        BuildDynamicRegisterInfo ();
     }
     return error;
 }
@@ -574,22 +571,23 @@
     {
         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 @@
 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 @@
 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 @@
     return error;
 }
 
-ByteOrder
-ProcessGDBRemote::GetByteOrder () const
-{
-    return m_byte_order;
-}
-
 //------------------------------------------------------------------
 // Process Queries
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Nov 17 23:57:03 2010
@@ -90,10 +90,10 @@
     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 @@
     virtual lldb_private::Error
     DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc);
 
-    virtual lldb::ByteOrder
-    GetByteOrder () const;
-
     virtual lldb_private::DynamicLoader *
     GetDynamicLoader ();
 
@@ -322,7 +319,6 @@
     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;

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Nov 17 23:57:03 2010
@@ -85,12 +85,19 @@
     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 @@
     
     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 @@
 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 @@
             // 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 @@
 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);

Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Wed Nov 17 23:57:03 2010
@@ -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;
 		};

Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Wed Nov 17 23:57:03 2010
@@ -265,10 +265,8 @@
             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 @@
     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 @@
 
                 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 @@
 }
 
 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 @@
 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 @@
     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()
+{
+}

Modified: lldb/trunk/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.h (original)
+++ lldb/trunk/tools/debugserver/source/DNB.h Wed Nov 17 23:57:03 2010
@@ -25,6 +25,9 @@
 
 typedef bool (*DNBShouldCancelCallback) (void *);
 
+void            DNBInitialize ();
+void            DNBTerminate ();
+
 //----------------------------------------------------------------------
 // Process control
 //----------------------------------------------------------------------

Modified: lldb/trunk/tools/debugserver/source/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.h Wed Nov 17 23:57:03 2010
@@ -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 @@
     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;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Wed Nov 17 23:57:03 2010
@@ -115,6 +115,7 @@
     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 @@
 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 @@
 
         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 @@
 
             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 @@
         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 @@
 MachProcess::PosixSpawnChildForPTraceDebugging
 (
     const char *path,
+    cpu_type_t cpu_type,
     char const *argv[],
     char const *envp[],
     const char *stdio_path,
@@ -1628,7 +1645,6 @@
     // 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))

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Wed Nov 17 23:57:03 2010
@@ -48,7 +48,7 @@
     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 @@
     DNBCallbackCopyExecutableImageInfos
                                 m_image_infos_callback;
     void *                      m_image_infos_baton;
+    DNBArchPluginInfo           m_arch_plugin_info;
 };
 
 

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Wed Nov 17 23:57:03 2010
@@ -31,14 +31,9 @@
     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 @@
 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 @@
         Resume();
         break;
     }
-    m_arch.ThreadWillResume();
+    m_arch_ap->ThreadWillResume();
     m_stop_exception.Clear();
 }
 
@@ -372,7 +367,7 @@
     }
     else
     {
-        if (m_arch.StepNotComplete())
+        if (m_arch_ap->StepNotComplete())
         {
             step_more = true;
             return false;
@@ -426,7 +421,7 @@
 
     // 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 @@
     {
         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 @@
 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 @@
 {
     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 @@
 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 @@
 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 @@
 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 @@
 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;
 }
 

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h Wed Nov 17 23:57:03 2010
@@ -95,6 +95,13 @@
                     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 @@
     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;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Wed Nov 17 23:57:03 2010
@@ -12,6 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "MachThreadList.h"
+
+#include <sys/sysctl.h>
+
 #include "DNBLog.h"
 #include "DNBThreadResumeActions.h"
 #include "MachProcess.h"
@@ -104,6 +107,15 @@
     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 @@
 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;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.h Wed Nov 17 23:57:03 2010
@@ -55,6 +55,8 @@
     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;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h Wed Nov 17 23:57:03 2010
@@ -235,6 +235,5 @@
 
 };
 
-typedef DNBArchMachARM    DNBArch;
 #endif    // #if defined (__arm__)
 #endif    // #ifndef __DebugNubArchMachARM_h__

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Wed Nov 17 23:57:03 2010
@@ -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 @@
     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 @@
 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 @@
     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)
 {

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Wed Nov 17 23:57:03 2010
@@ -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 @@
     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 @@
     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 @@
     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__

Modified: lldb/trunk/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h Wed Nov 17 23:57:03 2010
@@ -175,6 +175,5 @@
     State            m_state;
 };
 
-typedef DNBArchMachPPC    DNBArch;
 #endif    // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
 #endif    // #ifndef __DebugNubArchMachPPC_h__

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Wed Nov 17 23:57:03 2010
@@ -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 @@
 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 @@
 
 
 
-#endif    // #if defined (__i386__)
+#endif    // #if defined (__i386__) || defined (__x86_64__)

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Wed Nov 17 23:57:03 2010
@@ -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 @@
     {
     }
 
-    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 @@
     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 @@
     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__

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Wed Nov 17 23:57:03 2010
@@ -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 @@
     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 @@
     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 @@
     { 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 @@
     { 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 @@
     { 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);
+    pid_t pid = m_ctx.ProcessID();
+    if (pid == INVALID_NUB_PROCESS)
+        return false;
 
-        assert (num_reg_sets > 0 && reg_sets != NULL);
+    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())
+        {
+            nub_size_t num_reg_sets = 0;
+            const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
 
-        uint32_t regnum = 0;
-        for (nub_size_t set = 0; set < num_reg_sets; ++set)
-        {
-            if (reg_sets[set].registers == NULL)
-                continue;
+            assert (num_reg_sets > 0 && reg_sets != NULL);
 
-            for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
+            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};
+                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_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 @@
 void
 RNBRemote::NotifyThatProcessStopped (void)
 {
-    RNBRemote::HandlePacket_last_signal ("");
+    RNBRemote::HandlePacket_last_signal (NULL);
     return;
 }
 
@@ -1396,6 +1372,9 @@
 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 @@
             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 @@
         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 @@
     {
         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 @@
     {
         return SendPacket ("E11");
     }
+
+    if (g_num_reg_entries == 0)
+        InitializeRegisters ();
+
     StringExtractor packet(p);
     packet.SetFilePos(1); // Skip the 'G'
     
@@ -2872,6 +2862,9 @@
 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 @@
 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");

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Wed Nov 17 23:57:03 2010
@@ -106,10 +106,12 @@
 
     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 @@
 
 protected:
 
-    static void
-    InitializeNativeRegisters ();
-
     rnb_err_t GetCommData ();
     void CommDataReceived(const std::string& data);
     struct Packet
@@ -273,8 +272,7 @@
     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 @@
     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

Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=119680&r1=119679&r2=119680&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/trunk/tools/debugserver/source/debugserver.cpp Wed Nov 17 23:57:03 2010
@@ -334,7 +334,6 @@
     }
     else
     {
-
         ctx.SetProcessID(pid);
         return eRNBRunLoopModeInferiorExecuting;
     }
@@ -644,6 +643,7 @@
 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 @@
     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 @@
 
     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 @@
             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 @@
                 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 @@
         return -1;
     }
 
+    g_remoteSP->Initialize();
+
     RNBContext& ctx = remote->Context();
 
 
@@ -911,11 +935,6 @@
             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.
 





More information about the lldb-commits mailing list