[Lldb-commits] [lldb] r129351 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Host/ include/lldb/Interpreter/ include/lldb/Target/ lldb.xcodeproj/ source/API/ source/Commands/ source/Core/ source/Host/common/ source/Host/macosx/ source/Host/macosx/cfcpp/ source/Interpreter/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/Platform/MacOSX/ source/Plugins/Platform/gdb-server/ source/Plugins/Process/gdb-remote/ source/Symbol/ source/Target/ source/Utility/ test/ test/abbreviation_tests/ test/founda...

Greg Clayton gclayton at apple.com
Mon Apr 11 22:54:46 PDT 2011


Author: gclayton
Date: Tue Apr 12 00:54:46 2011
New Revision: 129351

URL: http://llvm.org/viewvc/llvm-project?rev=129351&view=rev
Log:
Moved the execution context that was in the Debugger into
the CommandInterpreter where it was always being used.

Make sure that Modules can track their object file offsets correctly to
allow opening of sub object files (like the "__commpage" on darwin).

Modified the Platforms to be able to launch processes. The first part of this
move is the platform soon will become the entity that launches your program
and when it does, it uses a new ProcessLaunchInfo class which encapsulates
all process launching settings. This simplifies the internal APIs needed for
launching. I want to slowly phase out process launching from the process
classes, so for now we can still launch just as we used to, but eventually
the platform is the object that should do the launching.

Modified the Host::LaunchProcess in the MacOSX Host.mm to correctly be able
to launch processes with all of the new eLaunchFlag settings. Modified any
code that was manually launching processes to use the Host::LaunchProcess
functions.

Fixed an issue where lldb_private::Args had implicitly defined copy 
constructors that could do the wrong thing. This has now been fixed by adding
an appropriate copy constructor and assignment operator.

Make sure we don't add empty ModuleSP entries to a module list.

Fixed the commpage module creation on MacOSX, but we still need to train
the MacOSX dynamic loader to not get rid of it when it doesn't have an entry
in the all image infos.

Abstracted many more calls from in ProcessGDBRemote down into the 
GDBRemoteCommunicationClient subclass to make the classes cleaner and more
efficient.

Fixed the default iOS ARM register context to be correct and also added support
for targets that don't support the qThreadStopInfo packet by selecting the
current thread (only if needed) and then sending a stop reply packet.

Debugserver can now start up with a --unix-socket (-u for short) and can 
then bind to port zero and send the port it bound to to a listening process
on the other end. This allows the GDB remote platform to spawn new GDB server
instances (debugserver) to allow platform debugging.






Modified:
    lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
    lldb/trunk/include/lldb/Core/ConnectionMachPort.h
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Core/Module.h
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/include/lldb/Interpreter/Args.h
    lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Commands/CommandObjectArgs.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectFile.cpp
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectImage.cpp
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Commands/CommandObjectPlatform.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Commands/CommandObjectRegister.cpp
    lldb/trunk/source/Commands/CommandObjectSource.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Core/ModuleList.cpp
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Host/macosx/Symbols.cpp
    lldb/trunk/source/Host/macosx/cfcpp/CFCString.h
    lldb/trunk/source/Interpreter/Args.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/CommandObject.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/source/Symbol/ObjectFile.cpp
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.h
    lldb/trunk/test/abbreviation_tests/TestAbbreviations.py
    lldb/trunk/test/dotest.py
    lldb/trunk/test/foundation/TestFoundationDisassembly.py
    lldb/trunk/test/foundation/TestObjCMethods.py
    lldb/trunk/tools/darwin-debug/darwin-debug.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/CFString.h
    lldb/trunk/tools/debugserver/source/RNBSocket.cpp
    lldb/trunk/tools/debugserver/source/RNBSocket.h
    lldb/trunk/tools/debugserver/source/debugserver.cpp
    lldb/trunk/tools/lldb-platform/lldb-platform.cpp

Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Tue Apr 12 00:54:46 2011
@@ -59,6 +59,9 @@
     NamedSocketAccept (const char *socket_name, Error *error_ptr);
 
     lldb::ConnectionStatus
+    NamedSocketConnect (const char *socket_name, Error *error_ptr);
+    
+    lldb::ConnectionStatus
     Close (int& fd, Error *error);
 
     int m_fd;    // Socket we use to communicate once conn established

Modified: lldb/trunk/include/lldb/Core/ConnectionMachPort.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionMachPort.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionMachPort.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionMachPort.h Tue Apr 12 00:54:46 2011
@@ -88,4 +88,4 @@
 
 #endif  // liblldb_ConnectionMachPort_h_
 
-#endif // #if defined(__APPLE__)
\ No newline at end of file
+#endif // #if defined(__APPLE__)

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Tue Apr 12 00:54:46 2011
@@ -388,15 +388,6 @@
     bool
     PopInputReader (const lldb::InputReaderSP& reader_sp);
 
-    ExecutionContext &
-    GetExecutionContext()
-    {
-        return m_exe_ctx;
-    }
-
-    void
-    UpdateExecutionContext (ExecutionContext *override_context);
-
     static lldb::DebuggerSP
     FindDebuggerWithID (lldb::user_id_t id);
     
@@ -447,7 +438,6 @@
     Listener m_listener;
     SourceManager m_source_manager;
     std::auto_ptr<CommandInterpreter> m_command_interpreter_ap;
-    ExecutionContext m_exe_ctx;
 
     std::stack<lldb::InputReaderSP> m_input_readers;
     std::string m_input_reader_data;

Modified: lldb/trunk/include/lldb/Core/Module.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Module.h (original)
+++ lldb/trunk/include/lldb/Core/Module.h Tue Apr 12 00:54:46 2011
@@ -391,8 +391,11 @@
     const ConstString &
     GetObjectName() const;
 
-    off_t
-    GetObjectOffset() const;
+    uint64_t
+    GetObjectOffset() const
+    {
+        return m_object_offset;
+    }
 
     //------------------------------------------------------------------
     /// Get the object file representation for the current architecture.
@@ -598,6 +601,7 @@
     FileSpec                    m_file;         ///< The file representation on disk for this module (if there is one).
     FileSpec                    m_platform_file;///< The path to the module on the platform on which it is being debugged
     ConstString                 m_object_name;  ///< The name an object within this module that is selected, or empty of the module is represented by \a m_file.
+    uint64_t                    m_object_offset;
     std::auto_ptr<ObjectFile>   m_objfile_ap;   ///< A pointer to the object file parser for this module.
     std::auto_ptr<SymbolVendor> m_symfile_ap;   ///< A pointer to the symbol vendor for this module.
     ClangASTContext             m_ast;          ///< The AST context for this module.

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Tue Apr 12 00:54:46 2011
@@ -343,23 +343,17 @@
     SetCrashDescription (const char *description);
 
     static uint32_t
-    FindProcesses (const ProcessInfoMatch &match_info,
-                   ProcessInfoList &proc_infos);
+    FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                   ProcessInstanceInfoList &proc_infos);
     
     static bool
-    GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
+    GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
     
     static lldb::pid_t
     LaunchApplication (const FileSpec &app_file_spec);
 
-    static lldb::pid_t
-    LaunchInNewTerminal (const char *tty_name,  // Optional partial or full tty name ("/dev/ttys000" or "ttys000")
-                         const char **argv,     // argv[0] is executable, argv[1] and on are the arguments
-                         const char **envp,     
-                         const char *working_dir,
-                         const ArchSpec *arch_spec,
-                         bool stop_at_entry,
-                         bool disable_aslr);
+    static Error
+    LaunchProcess (ProcessLaunchInfo &launch_info);
     
     static bool
     OpenFileInExternalEditor (const FileSpec &file_spec, 

Modified: lldb/trunk/include/lldb/Interpreter/Args.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/Args.h (original)
+++ lldb/trunk/include/lldb/Interpreter/Args.h Tue Apr 12 00:54:46 2011
@@ -82,6 +82,11 @@
 
     Args (const char *command, size_t len);
 
+    Args (const Args &rhs);
+    
+    const Args &
+    operator= (const Args &rhs);
+
     //------------------------------------------------------------------
     /// Destructor.
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Tue Apr 12 00:54:46 2011
@@ -39,7 +39,8 @@
     };
 
     void
-    SourceInitFile (bool in_cwd, CommandReturnObject &result);
+    SourceInitFile (bool in_cwd, 
+                    CommandReturnObject &result);
 
     CommandInterpreter (Debugger &debugger,
                         lldb::ScriptLanguage script_language,
@@ -49,13 +50,16 @@
     ~CommandInterpreter ();
 
     lldb::CommandObjectSP
-    GetCommandSPExact (const char *cmd, bool include_aliases);
+    GetCommandSPExact (const char *cmd, 
+                       bool include_aliases);
 
     CommandObject *
-    GetCommandObjectExact (const char *cmd_cstr, bool include_aliases);
+    GetCommandObjectExact (const char *cmd_cstr, 
+                           bool include_aliases);
 
     CommandObject *
-    GetCommandObject (const char *cmd, StringList *matches = NULL);
+    GetCommandObject (const char *cmd, 
+                      StringList *matches = NULL);
 
     bool
     CommandExists (const char *cmd);
@@ -67,7 +71,8 @@
     UserCommandExists (const char *cmd);
 
     void
-    AddAlias (const char *alias_name, lldb::CommandObjectSP& command_obj_sp);
+    AddAlias (const char *alias_name, 
+              lldb::CommandObjectSP& command_obj_sp);
 
     bool
     RemoveAlias (const char *alias_name);
@@ -82,14 +87,19 @@
     RemoveAliasOptions (const char *alias_name);
 
     void
-    AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp);
+    AddOrReplaceAliasOptions (const char *alias_name, 
+                              OptionArgVectorSP &option_arg_vector_sp);
 
     bool
-    StripFirstWord (std::string &command_string, std::string &next_word);
+    StripFirstWord (std::string &command_string, 
+                    std::string &next_word);
 
     void
-    BuildAliasResult (const char *alias_name, std::string &raw_input_string, std::string &alias_result, 
-                      CommandObject *&alias_cmd_obj, CommandReturnObject &result);
+    BuildAliasResult (const char *alias_name, 
+                      std::string &raw_input_string, 
+                      std::string &alias_result, 
+                      CommandObject *&alias_cmd_obj, 
+                      CommandReturnObject &result);
 
     bool
     HandleCommand (const char *command_line, 
@@ -151,12 +161,12 @@
     //------------------------------------------------------------------
     void
     HandleCommandsFromFile (FileSpec &file, 
-                    ExecutionContext *context, 
-                    bool stop_on_continue, 
-                    bool stop_on_error, 
-                    bool echo_commands,
-                    bool print_results, 
-                    CommandReturnObject &result);
+                            ExecutionContext *context, 
+                            bool stop_on_continue, 
+                            bool stop_on_error, 
+                            bool echo_commands,
+                            bool print_results, 
+                            CommandReturnObject &result);
 
     CommandObject *
     GetCommandObjectForCommand (std::string &command_line);
@@ -177,11 +187,11 @@
 
     int
     HandleCompletion (const char *current_line,
-                                      const char *cursor,
-                                      const char *last_char,
-                                      int match_start_point,
-                                      int max_return_elements,
-                                      StringList &matches);
+                      const char *cursor,
+                      const char *last_char,
+                      int match_start_point,
+                      int max_return_elements,
+                      StringList &matches);
 
     // This version just returns matches, and doesn't compute the substring.  It is here so the
     // Help command can call it for the first argument.
@@ -190,22 +200,26 @@
 
     int
     HandleCompletionMatches (Args &input,
-                      int &cursor_index,
-                      int &cursor_char_position,
-                      int match_start_point,
-                      int max_return_elements,
-                      bool &word_complete,
-                      StringList &matches);
+                             int &cursor_index,
+                             int &cursor_char_position,
+                             int match_start_point,
+                             int max_return_elements,
+                             bool &word_complete,
+                             StringList &matches);
 
 
     int
-    GetCommandNamesMatchingPartialString (const char *cmd_cstr, bool include_aliases, StringList &matches);
+    GetCommandNamesMatchingPartialString (const char *cmd_cstr, 
+                                          bool include_aliases, 
+                                          StringList &matches);
 
     void
     GetHelp (CommandReturnObject &result);
 
     void
-    GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string);
+    GetAliasHelp (const char *alias_name, 
+                  const char *command_name, 
+                  StreamString &help_string);
 
     void
     OutputFormattedHelpText (Stream &stream,
@@ -219,6 +233,18 @@
     {
         return m_debugger;
     }
+    
+    ExecutionContext &
+    GetExecutionContext()
+    {
+        return m_exe_ctx;
+    }
+    
+    void
+    UpdateExecutionContext (ExecutionContext *override_context);
+
+    lldb::PlatformSP
+    GetPlatform (bool prefer_target_platform);
 
     const char *
     ProcessEmbeddedScriptCommands (const char *arg);
@@ -245,7 +271,8 @@
     Initialize ();
 
     void
-    CrossRegisterCommand (const char * dest_cmd, const char * object_type);
+    CrossRegisterCommand (const char *dest_cmd, 
+                          const char *object_type);
 
     void
     SetScriptLanguage (lldb::ScriptLanguage lang);
@@ -264,8 +291,11 @@
     HasAliasOptions ();
 
     void
-    BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, 
-                           std::string &raw_input_string, CommandReturnObject &result);
+    BuildAliasCommandArgs (CommandObject *alias_cmd_obj, 
+                           const char *alias_name, 
+                           Args &cmd_args, 
+                           std::string &raw_input_string, 
+                           CommandReturnObject &result);
 
     int
     GetOptionArgumentPosition (const char *in_string);
@@ -284,10 +314,12 @@
 
 #ifndef SWIG
     void
-    AddLogChannel (const char *name, const Log::Callbacks &log_callbacks);
+    AddLogChannel (const char *name, 
+                   const Log::Callbacks &log_callbacks);
 
     bool
-    GetLogChannelCallbacks (const char *channel, Log::Callbacks &log_callbacks);
+    GetLogChannelCallbacks (const char *channel, 
+                            Log::Callbacks &log_callbacks);
 
     bool
     RemoveLogChannel (const char *name);
@@ -297,11 +329,16 @@
     FindLongestCommandWord (CommandObject::CommandMap &dict);
 
     void
-    FindCommandsForApropos (const char *word, StringList &commands_found, StringList &commands_help);
+    FindCommandsForApropos (const char *word, 
+                            StringList &commands_found, 
+                            StringList &commands_help);
 
     void
-    AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word, 
-                           StringList &commands_found, StringList &commands_help);
+    AproposAllSubCommands (CommandObject *cmd_obj, 
+                           const char *prefix, 
+                           const char *search_word, 
+                           StringList &commands_found, 
+                           StringList &commands_help);
 
 protected:
     friend class Debugger;
@@ -314,15 +351,16 @@
 
 private:
 
-    Debugger &m_debugger;   // The debugger session that this interpreter is associated with
+    Debugger &m_debugger;                       // The debugger session that this interpreter is associated with
+    ExecutionContext m_exe_ctx;                 // The current execution context to use when handling commands
     bool m_synchronous_execution;
     bool m_skip_lldbinit_files;
-    CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten).
-    CommandObject::CommandMap m_alias_dict;   // Stores user aliases/abbreviations for commands
-    CommandObject::CommandMap m_user_dict;    // Stores user-defined commands
-    OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias.
+    CommandObject::CommandMap m_command_dict;   // Stores basic built-in commands (they cannot be deleted, removed or overwritten).
+    CommandObject::CommandMap m_alias_dict;     // Stores user aliases/abbreviations for commands
+    CommandObject::CommandMap m_user_dict;      // Stores user-defined commands
+    OptionArgMap m_alias_options;               // Stores any options (with or without arguments) that go with any alias.
     std::vector<std::string> m_command_history;
-    std::string m_repeat_command;  // Stores the command that will be executed for an empty command string.
+    std::string m_repeat_command;               // Stores the command that will be executed for an empty command string.
     std::auto_ptr<ScriptInterpreter> m_script_interpreter_ap;
     char m_comment_char;
 };

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Tue Apr 12 00:54:46 2011
@@ -123,6 +123,11 @@
         bool
         GetOSKernelDescription (std::string &s);
 
+        // Returns the the hostname if we are connected, else the short plugin
+        // name.
+        const char *
+        GetName ();
+
         virtual const char *
         GetHostname ();
 
@@ -252,83 +257,47 @@
                                          BreakpointSite *bp_site) = 0;
 
         //------------------------------------------------------------------
-        /// Launch a new process.
-        ///
-        /// Launch a new process by spawning a new process using the
-        /// target object's executable module's file as the file to launch.
-        /// Arguments are given in \a argv, and the environment variables
-        /// are in \a envp. Standard input and output files can be
-        /// optionally re-directed to \a stdin_path, \a stdout_path, and
-        /// \a stderr_path.
-        ///
-        /// This function is not meant to be overridden by Process
-        /// subclasses. It will first call Process::WillLaunch (Module *)
-        /// and if that returns \b true, Process::DoLaunch (Module*,
-        /// char const *[],char const *[],const char *,const char *,
-        /// const char *) will be called to actually do the launching. If
-        /// DoLaunch returns \b true, then Process::DidLaunch() will be
-        /// called.
-        ///
-        /// @param[in] argv
-        ///     The argument array.
-        ///
-        /// @param[in] envp
-        ///     The environment array.
-        ///
-        /// @param[in] launch_flags
-        ///     Flags to modify the launch (@see lldb::LaunchFlags)
-        ///
-        /// @param[in] stdin_path
-        ///     The path to use when re-directing the STDIN of the new
-        ///     process. If all stdXX_path arguments are NULL, a pseudo
-        ///     terminal will be used.
-        ///
-        /// @param[in] stdout_path
-        ///     The path to use when re-directing the STDOUT of the new
-        ///     process. If all stdXX_path arguments are NULL, a pseudo
-        ///     terminal will be used.
-        ///
-        /// @param[in] stderr_path
-        ///     The path to use when re-directing the STDERR of the new
-        ///     process. If all stdXX_path arguments are NULL, a pseudo
-        ///     terminal will be used.
-        ///
-        /// @param[in] working_directory
-        ///     The working directory to have the child process run in
-        ///
-        /// @return
-        ///     An error object. Call GetID() to get the process ID if
-        ///     the error object is success.
+        /// Launch a new process on a platform, not necessarily for 
+        /// debugging, it could be just for running the process.
         //------------------------------------------------------------------
-//        virtual lldb::ProcessSP
-//        Launch (char const *argv[],
-//                char const *envp[],
-//                uint32_t launch_flags,
-//                const char *stdin_path,
-//                const char *stdout_path,
-//                const char *stderr_path,
-//                const char *working_directory,
-//                Error &error) = 0;
+        virtual Error
+        LaunchProcess (ProcessLaunchInfo &launch_info);
+
+        //------------------------------------------------------------------
+        /// Subclasses should NOT need to implement this function as it uses
+        /// the Platform::LaunchProcess() followed by Platform::Attach ()
+        //------------------------------------------------------------------
+        lldb::ProcessSP
+        DebugProcess (ProcessLaunchInfo &launch_info,
+                      Debugger &debugger,
+                      Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                      Listener &listener,
+                      Error &error);
 
         //------------------------------------------------------------------
         /// Attach to an existing process using a process ID.
         ///
-        /// This function is not meant to be overridden by Process
-        /// subclasses. It will first call Process::WillAttach (lldb::pid_t)
-        /// and if that returns \b true, Process::DoAttach (lldb::pid_t) will
-        /// be called to actually do the attach. If DoAttach returns \b
-        /// true, then Process::DidAttach() will be called.
+        /// Each platform subclass needs to implement this function and 
+        /// attempt to attach to the process with the process ID of \a pid.
+        /// The platform subclass should return an appropriate ProcessSP 
+        /// subclass that is attached to the process, or an empty shared 
+        /// pointer with an appriopriate error.
         ///
         /// @param[in] pid
         ///     The process ID that we should attempt to attach to.
         ///
         /// @return
-        ///     Returns \a pid if attaching was successful, or
-        ///     LLDB_INVALID_PROCESS_ID if attaching fails.
-        //------------------------------------------------------------------
-//        virtual lldb::ProcessSP
-//        Attach (lldb::pid_t pid, 
-//                Error &error) = 0;
+        ///     An appropriate ProcessSP containing a valid shared pointer
+        ///     to the default Process subclass for the platform that is 
+        ///     attached to the process, or an empty shared pointer with an
+        ///     appriopriate error fill into the \a error object.
+        //------------------------------------------------------------------
+        virtual lldb::ProcessSP
+        Attach (lldb::pid_t pid, 
+                Debugger &debugger,
+                Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                Listener &listener,
+                Error &error) = 0;
 
         //------------------------------------------------------------------
         /// Attach to an existing process by process name.
@@ -357,11 +326,11 @@
         // Subclasses will need to fill in the remote case.
         //------------------------------------------------------------------
         virtual uint32_t
-        FindProcesses (const ProcessInfoMatch &match_info,
-                       ProcessInfoList &proc_infos);
+        FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                       ProcessInstanceInfoList &proc_infos);
 
         virtual bool
-        GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
+        GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
 
         const std::string &
         GetRemoteURL () const
@@ -529,7 +498,8 @@
     public:
         PlatformList() :
             m_mutex (Mutex::eMutexTypeRecursive),
-            m_platforms ()
+            m_platforms (),
+            m_selected_platform_sp()
         {
         }
         

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Apr 12 00:54:46 2011
@@ -11,8 +11,11 @@
 #define liblldb_Process_h_
 
 // C Includes
+#include <spawn.h>
+
 // C++ Includes
 #include <list>
+#include <iosfwd>
 #include <vector>
 
 // Other libraries and framework includes
@@ -39,7 +42,9 @@
 
 namespace lldb_private {
 
-
+//----------------------------------------------------------------------
+// ProcessInstanceSettings
+//----------------------------------------------------------------------
 class ProcessInstanceSettings : public InstanceSettings
 {
 public:
@@ -224,35 +229,38 @@
     bool m_got_host_env;
 };
 
-    
+//----------------------------------------------------------------------
+// ProcessInfo
+//
+// A base class for information for a process. This can be used to fill
+// out information for a process prior to launching it, or it can be 
+// used for an instance of a process and can be filled in with the 
+// existing values for that process.
+//----------------------------------------------------------------------
 class ProcessInfo
 {
 public:
     ProcessInfo () :
         m_executable (),
-        m_args (),
-        m_real_uid (UINT32_MAX),
-        m_real_gid (UINT32_MAX),
-        m_effective_uid (UINT32_MAX),
-        m_effective_gid (UINT32_MAX),
+        m_arguments (),
+        m_environment (),
+        m_uid (LLDB_INVALID_UID),
+        m_gid (LLDB_INVALID_UID),
         m_arch(),
-        m_pid (LLDB_INVALID_PROCESS_ID),
-        m_parent_pid (LLDB_INVALID_PROCESS_ID)
+        m_pid (LLDB_INVALID_PROCESS_ID)
     {
     }
-
+    
     ProcessInfo (const char *name,
                  const ArchSpec &arch,
                  lldb::pid_t pid) :
-        m_executable (),
-        m_args (),
-        m_real_uid (UINT32_MAX),
-        m_real_gid (UINT32_MAX),
-        m_effective_uid (UINT32_MAX),
-        m_effective_gid (UINT32_MAX),
+        m_executable (name, false),
+        m_arguments (),
+        m_environment(),
+        m_uid (LLDB_INVALID_UID),
+        m_gid (LLDB_INVALID_UID),
         m_arch (arch),
-        m_pid (pid),
-        m_parent_pid (LLDB_INVALID_PROCESS_ID)
+        m_pid (pid)
     {
     }
     
@@ -260,14 +268,12 @@
     Clear ()
     {
         m_executable.Clear();
-        m_args.Clear();
-        m_real_uid = UINT32_MAX;
-        m_real_gid = UINT32_MAX;
-        m_effective_uid = UINT32_MAX;
-        m_effective_gid = UINT32_MAX;
+        m_arguments.Clear();
+        m_environment.Clear();
+        m_uid = LLDB_INVALID_UID;
+        m_gid = LLDB_INVALID_UID;
         m_arch.Clear();
         m_pid = LLDB_INVALID_PROCESS_ID;
-        m_parent_pid = LLDB_INVALID_PROCESS_ID;
     }
     
     const char *
@@ -275,7 +281,7 @@
     {
         return m_executable.GetFilename().GetCString();
     }
-
+    
     size_t
     GetNameLength() const
     {
@@ -293,97 +299,61 @@
     {
         return m_executable;
     }
-
+    
     const FileSpec &
     GetExecutableFile () const
     {
         return m_executable;
     }
-
-    uint32_t
-    GetRealUserID() const
-    {
-        return m_real_uid;
-    }
     
     uint32_t
-    GetRealGroupID() const
-    {
-        return m_real_gid;
-    }
-
-    uint32_t
-    GetEffectiveUserID() const
+    GetUserID() const
     {
-        return m_effective_uid;
+        return m_uid;
     }
-
+    
     uint32_t
-    GetEffectiveGroupID() const
+    GetGroupID() const
     {
-        return m_effective_gid;
+        return m_gid;
     }
     
     bool
-    RealUserIDIsValid () const
+    UserIDIsValid () const
     {
-        return m_real_uid != UINT32_MAX;
+        return m_uid != UINT32_MAX;
     }
     
     bool
-    RealGroupIDIsValid () const
+    GroupIDIsValid () const
     {
-        return m_real_gid != UINT32_MAX;
+        return m_gid != UINT32_MAX;
     }
     
-    bool
-    EffectiveUserIDIsValid () const
-    {
-        return m_effective_uid != UINT32_MAX;
-    }
-
-    bool
-    EffectiveGroupIDIsValid () const
-    {
-        return m_effective_gid != UINT32_MAX;
-    }
-
-    void
-    SetRealUserID (uint32_t uid)
-    {
-        m_real_uid = uid;
-    }
-
-    void
-    SetRealGroupID (uint32_t gid)
-    {
-        m_real_gid = gid;
-    }
-
     void
-    SetEffectiveUserID (uint32_t uid)
+    SetUserID (uint32_t uid)
     {
-        m_effective_uid = uid;
+        m_uid = uid;
     }
     
     void
-    SetEffectiveGroupID (uint32_t gid)
+    SetGroupID (uint32_t gid)
     {
-        m_effective_gid = gid;
+        m_gid = gid;
     }
-
+    
     ArchSpec &
     GetArchitecture ()
     {
         return m_arch;
     }
-
+    
     const ArchSpec &
     GetArchitecture () const
     {
         return m_arch;
     }
-
+    
     lldb::pid_t
     GetProcessID () const
     {
@@ -401,6 +371,120 @@
     {
         return m_pid != LLDB_INVALID_PROCESS_ID;
     }
+    
+    void
+    Dump (Stream &s, Platform *platform) const;
+    
+    Args &
+    GetArguments ()
+    {
+        return m_arguments;
+    }
+    
+    const Args &
+    GetArguments () const
+    {
+        return m_arguments;
+    }
+    
+    void
+    SetArgumentsFromArgs (const Args& args, 
+                          bool first_arg_is_executable,
+                          bool first_arg_is_executable_and_argument);
+
+    Args &
+    GetEnvironmentEntries ()
+    {
+        return m_environment;
+    }
+    
+    const Args &
+    GetEnvironmentEntries () const
+    {
+        return m_environment;
+    }
+    
+protected:
+    FileSpec m_executable;
+    Args m_arguments;
+    Args m_environment;
+    uint32_t m_uid;
+    uint32_t m_gid;    
+    ArchSpec m_arch;
+    lldb::pid_t m_pid;
+};
+
+//----------------------------------------------------------------------
+// ProcessInstanceInfo
+//
+// Describes an existing process and any discoverable information that
+// pertains to that process.
+//----------------------------------------------------------------------
+class ProcessInstanceInfo : public ProcessInfo
+{
+public:
+    ProcessInstanceInfo () :
+        ProcessInfo (),
+        m_euid (UINT32_MAX),
+        m_egid (UINT32_MAX),
+        m_parent_pid (LLDB_INVALID_PROCESS_ID)
+    {
+    }
+
+    ProcessInstanceInfo (const char *name,
+                 const ArchSpec &arch,
+                 lldb::pid_t pid) :
+        ProcessInfo (name, arch, pid),
+        m_euid (UINT32_MAX),
+        m_egid (UINT32_MAX),
+        m_parent_pid (LLDB_INVALID_PROCESS_ID)
+    {
+    }
+    
+    void
+    Clear ()
+    {
+        ProcessInfo::Clear();
+        m_euid = UINT32_MAX;
+        m_egid = UINT32_MAX;
+        m_parent_pid = LLDB_INVALID_PROCESS_ID;
+    }
+    
+    uint32_t
+    GetEffectiveUserID() const
+    {
+        return m_euid;
+    }
+
+    uint32_t
+    GetEffectiveGroupID() const
+    {
+        return m_egid;
+    }
+    
+    bool
+    EffectiveUserIDIsValid () const
+    {
+        return m_euid != UINT32_MAX;
+    }
+
+    bool
+    EffectiveGroupIDIsValid () const
+    {
+        return m_egid != UINT32_MAX;
+    }
+
+    void
+    SetEffectiveUserID (uint32_t uid)
+    {
+        m_euid = uid;
+    }
+    
+    void
+    SetEffectiveGroupID (uint32_t gid)
+    {
+        m_egid = gid;
+    }
 
     lldb::pid_t
     GetParentProcessID () const
@@ -424,46 +508,272 @@
     Dump (Stream &s, Platform *platform) const;
 
     static void
-    DumpTableHeader (Stream &s, Platform *platform, bool verbose = false);
+    DumpTableHeader (Stream &s, Platform *platform, bool show_args, bool verbose);
+
+    void
+    DumpAsTableRow (Stream &s, Platform *platform, bool show_args, bool verbose) const;
+    
+protected:
+    uint32_t m_euid;
+    uint32_t m_egid;    
+    lldb::pid_t m_parent_pid;
+};
+    
+    
+//----------------------------------------------------------------------
+// ProcessLaunchInfo
+//
+// Describes any information that is required to launch a process.
+//----------------------------------------------------------------------
+
+class ProcessLaunchInfo : public ProcessInfo
+{
+public:
+
+    class FileAction
+    {
+    public:
+
+        FileAction () :
+            m_action (eFileActionNone),
+            m_fd (-1),
+            m_arg (-1),
+            m_path ()
+        {
+        }
+
+        void
+        Clear()
+        {
+            m_action = eFileActionNone;
+            m_fd = -1;
+            m_arg = -1;
+            m_path.clear();
+        }
+
+        bool
+        Close (int fd);
+
+        bool
+        Duplicate (int fd, int dup_fd);
+
+        bool
+        Open (int fd, const char *path, bool read, bool write);
+        
+        static bool
+        AddPosixSpawnFileAction (posix_spawn_file_actions_t *file_actions,
+                                 const FileAction *info,
+                                 Log *log, 
+                                 Error& error);
+
+    protected:
+        enum Action
+        {
+            eFileActionNone,
+            eFileActionClose,
+            eFileActionDuplicate,
+            eFileActionOpen
+        };
+
+        Action m_action;    // The action for this file
+        int m_fd;           // An existing file descriptor
+        int m_arg;          // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
+        std::string m_path; // A file path to use for opening after fork or posix_spawn
+    };
+    
+    ProcessLaunchInfo () :
+        ProcessInfo(),
+        m_flags (),
+        m_stdin_info (),
+        m_stdout_info (),
+        m_stderr_info ()
+    {
+    }
+
+    void
+    AppendFileAction (const FileAction &info)
+    {
+        m_file_actions.push_back(info);
+    }
+
+    void
+    AppendCloseFileAction (int fd)
+    {
+        FileAction file_action;
+        file_action.Close (fd);
+        AppendFileAction (file_action);
+    }
+
+    void
+    AppendDuplciateFileAction (int fd, int dup_fd)
+    {
+        FileAction file_action;
+        file_action.Duplicate (fd, dup_fd);
+        AppendFileAction (file_action);
+    }
+
+    void
+    AppendOpenFileAction (int fd, const char *path, bool read, bool write)
+    {
+        FileAction file_action;
+        file_action.Open (fd, path, read, write);
+        AppendFileAction (file_action);
+    }
+
+    void
+    AppendSuppressFileAction (int fd, bool read, bool write)
+    {
+        FileAction file_action;
+        file_action.Open (fd, "/dev/null", read, write);
+        AppendFileAction (file_action);
+    }
+
+    size_t
+    GetNumFileActions () const
+    {
+        return m_file_actions.size();
+    }
+    
+    const FileAction *
+    GetFileActionAtIndex (size_t idx) const
+    {
+        if (idx < m_file_actions.size())
+            return &m_file_actions[idx];
+        return NULL;
+    }
+
+    Flags &
+    GetFlags ()
+    {
+        return m_flags;
+    }
+
+    const Flags &
+    GetFlags () const
+    {
+        return m_flags;
+    }
+    
+    const char *
+    GetWorkingDirectory () const
+    {
+        if (m_working_dir.empty())
+            return NULL;
+        return m_working_dir.c_str();
+    }
+
+    void
+    SetWorkingDirectory (const char *working_dir)
+    {
+        if (working_dir && working_dir[0])
+            m_working_dir.assign (working_dir);
+        else
+            m_working_dir.clear();
+    }
 
     void
-    DumpAsTableRow (Stream &s, Platform *platform, bool verbose = false) const;
+    SwapWorkingDirectory (std::string &working_dir)
+    {
+        m_working_dir.swap (working_dir);
+    }
+
+
+    const char *
+    GetProcessPluginName () const
+    {
+        if (m_plugin_name.empty())
+            return NULL;
+        return m_plugin_name.c_str();
+    }
 
-    StringList &
-    GetArguments()
+    void
+    SetProcessPluginName (const char *plugin)
     {
-        return m_args;
+        if (plugin && plugin[0])
+            m_plugin_name.assign (plugin);
+        else
+            m_plugin_name.clear();
     }
     
-    const StringList &
-    GetArguments() const
+    void
+    Clear ()
     {
-        return m_args;
+        ProcessInfo::Clear();
+        m_working_dir.clear();
+        m_plugin_name.clear();
+        m_flags.Clear();
+        m_stdin_info.Clear();
+        m_stdout_info.Clear();
+        m_stderr_info.Clear();
+        m_file_actions.clear();
     }
 
 protected:
-    FileSpec m_executable;
-    StringList m_args;
-    uint32_t m_real_uid;
-    uint32_t m_real_gid;    
-    uint32_t m_effective_uid;
-    uint32_t m_effective_gid;    
-    ArchSpec m_arch;
-    lldb::pid_t m_pid;
-    lldb::pid_t m_parent_pid;
+    std::string m_working_dir;
+    std::string m_plugin_name;
+    Flags m_flags;       // Bitwise OR of bits from lldb::LaunchFlags
+    FileAction m_stdin_info;      // File action for stdin
+    FileAction m_stdout_info;     // File action for stdout
+    FileAction m_stderr_info;     // File action for stderr
+    std::vector<FileAction> m_file_actions; // File actions for any other files
+};
+
+class ProcessLaunchCommandOptions : public Options
+{
+public:
+    
+    ProcessLaunchCommandOptions (CommandInterpreter &interpreter) :
+        Options(interpreter)
+    {
+        // Keep default values of all options in one place: ResetOptionValues ()
+        ResetOptionValues ();
+    }
+    
+    ~ProcessLaunchCommandOptions ()
+    {
+    }
+    
+    Error
+    SetOptionValue (int option_idx, const char *option_arg);
+    
+    void
+    ResetOptionValues ()
+    {
+        launch_info.Clear();
+    }
+    
+    const OptionDefinition*
+    GetDefinitions ()
+    {
+        return g_option_table;
+    }
+    
+    // Options table: Required for subclasses of Options.
+    
+    static OptionDefinition g_option_table[];
+    
+    // Instance variables to hold the values for command options.
+    
+    ProcessLaunchInfo launch_info;
 };
 
-class ProcessInfoMatch
+//----------------------------------------------------------------------
+// ProcessInstanceInfoMatch
+//
+// A class to help matching one ProcessInstanceInfo to another.
+//----------------------------------------------------------------------
+
+class ProcessInstanceInfoMatch
 {
 public:
-    ProcessInfoMatch () :
+    ProcessInstanceInfoMatch () :
         m_match_info (),
         m_name_match_type (lldb_private::eNameMatchIgnore),
         m_match_all_users (false)
     {
     }
 
-    ProcessInfoMatch (const char *process_name, 
+    ProcessInstanceInfoMatch (const char *process_name, 
                       lldb_private::NameMatchType process_name_match_type) :
         m_match_info (),
         m_name_match_type (process_name_match_type),
@@ -472,13 +782,13 @@
         m_match_info.SetName (process_name);
     }
 
-    ProcessInfo &
+    ProcessInstanceInfo &
     GetProcessInfo ()
     {
         return m_match_info;
     }
 
-    const ProcessInfo &
+    const ProcessInstanceInfo &
     GetProcessInfo () const
     {
         return m_match_info;
@@ -512,7 +822,7 @@
     NameMatches (const char *process_name) const;
 
     bool
-    Matches (const ProcessInfo &proc_info) const;
+    Matches (const ProcessInstanceInfo &proc_info) const;
 
     bool
     MatchAllProcesses () const;
@@ -520,15 +830,15 @@
     Clear ();
 
 protected:
-    ProcessInfo m_match_info;
+    ProcessInstanceInfo m_match_info;
     lldb_private::NameMatchType m_name_match_type;
     bool m_match_all_users;
 };
 
-class ProcessInfoList
+class ProcessInstanceInfoList
 {
 public:
-    ProcessInfoList () :
+    ProcessInstanceInfoList () :
         m_infos()
     {
     }
@@ -546,7 +856,7 @@
     }
     
     void
-    Append (const ProcessInfo &info)
+    Append (const ProcessInstanceInfo &info)
     {
         m_infos.push_back (info);
     }
@@ -576,7 +886,7 @@
     }
 
     bool
-    GetInfoAtIndex (uint32_t idx, ProcessInfo &info)
+    GetInfoAtIndex (uint32_t idx, ProcessInstanceInfo &info)
     {
         if (idx < m_infos.size())
         {
@@ -587,7 +897,7 @@
     }
     
     // You must ensure "idx" is valid before calling this function
-    const ProcessInfo &
+    const ProcessInstanceInfo &
     GetProcessInfoAtIndex (uint32_t idx) const
     {
         assert (idx < m_infos.size());
@@ -595,7 +905,7 @@
     }
     
 protected:
-    typedef std::vector<ProcessInfo> collection;
+    typedef std::vector<ProcessInstanceInfo> collection;
     collection m_infos;
 };
 
@@ -1732,6 +2042,20 @@
                 size_t size,
                 Error &error);
 
+    //------------------------------------------------------------------
+    /// Read a NULL terminated C string from memory
+    ///
+    /// This function will read a cache page at a time until the NULL
+    /// C stirng terminator is found. It will stop reading if the NULL
+    /// termination byte isn't found before reading \a cstr_max_len
+    /// bytes, and the results are always guaranteed to be NULL 
+    /// terminated (at most cstr_max_len - 1 bytes will be read).
+    //------------------------------------------------------------------
+    size_t
+    ReadCStringFromMemory (lldb::addr_t vm_addr, 
+                           char *cstr, 
+                           size_t cstr_max_len);
+
     size_t
     ReadMemoryFromInferior (lldb::addr_t vm_addr, 
                             void *buf, 
@@ -2292,6 +2616,11 @@
               size_t dst_len,
               Error &error);
         
+        uint32_t
+        GetMemoryCacheLineSize() const
+        {
+            return m_cache_line_byte_size ;
+        }
     protected:
         typedef std::map<lldb::addr_t, lldb::DataBufferSP> collection;
         //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Apr 12 00:54:46 2011
@@ -39,9 +39,12 @@
     typedef enum LaunchFlags
     {
         eLaunchFlagNone         = 0u,
-        eLaunchFlagDisableASLR  = (1u << 0),  ///< Disable Address Space Layout Randomization
-        eLaunchFlagDisableSTDIO = (1u << 1),  ///< Disable stdio for inferior process (e.g. for a GUI app)
-        eLaunchFlagLaunchInTTY  = (1u << 2)   ///< Launch the process in a new TTY if supported by the host 
+        eLaunchFlagExec         = (1u << 0),  ///< Exec when launching and turn the calling process into a new process
+        eLaunchFlagDebug        = (1u << 1),  ///< Stop as soon as the process launches to allow the process to be debugged
+        eLaunchFlagStopAtEntry  = (1u << 2),  ///< Stop at the program entry point instead of auto-continuing when launching or attaching at entry point
+        eLaunchFlagDisableASLR  = (1u << 3),  ///< Disable Address Space Layout Randomization
+        eLaunchFlagDisableSTDIO = (1u << 4),  ///< Disable stdio for inferior process (e.g. for a GUI app)
+        eLaunchFlagLaunchInTTY  = (1u << 5)   ///< Launch the process in a new TTY if supported by the host 
     } LaunchFlags;
         
     //----------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Tue Apr 12 00:54:46 2011
@@ -103,8 +103,10 @@
 class   Platform;
 class   Process;
 class   ProcessInfo;
-class   ProcessInfoList;
-class   ProcessInfoMatch;
+class   ProcessInstanceInfo;
+class   ProcessInstanceInfoList;
+class   ProcessInstanceInfoMatch;
+class   ProcessLaunchInfo;
 class   RegisterContext;
 class   RegisterLocation;
 class   RegisterLocationList;

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Apr 12 00:54:46 2011
@@ -62,6 +62,7 @@
 		26680336116005EF008E1FE4 /* SBBreakpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16CC7114086A1007A7B3F /* SBBreakpointLocation.cpp */; };
 		26680337116005F1008E1FE4 /* SBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */; };
 		2668035C11601108008E1FE4 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
+		266E8C6A13528ABC000C2042 /* lldb-platform in Resources */ = {isa = PBXBuildFile; fileRef = 26DC6A101337FE6900FF7998 /* lldb-platform */; };
 		2671A0CE134825F6003A87BB /* ConnectionMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 2671A0CD134825F6003A87BB /* ConnectionMachPort.h */; };
 		2671A0D013482601003A87BB /* ConnectionMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */; };
 		26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
@@ -446,6 +447,13 @@
 			remoteGlobalIDString = 26680206115FD0ED008E1FE4;
 			remoteInfo = LLDB;
 		};
+		266E8C6C13528AD2000C2042 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 26DC6A0F1337FE6900FF7998;
+			remoteInfo = "lldb-platform";
+		};
 		2689011413353E9B00698AC0 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
@@ -2579,6 +2587,7 @@
 			buildRules = (
 			);
 			dependencies = (
+				266E8C6D13528AD2000C2042 /* PBXTargetDependency */,
 				2689011513353E9B00698AC0 /* PBXTargetDependency */,
 				262CFC7211A450CB00946C6C /* PBXTargetDependency */,
 				26368AF6126B95FA00E8659F /* PBXTargetDependency */,
@@ -2688,6 +2697,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				266E8C6A13528ABC000C2042 /* lldb-platform in Resources */,
 				262CFC7711A4510000946C6C /* debugserver in Resources */,
 				26368AF7126B960500E8659F /* darwin-debug in Resources */,
 			);
@@ -3143,6 +3153,11 @@
 			target = 26680206115FD0ED008E1FE4 /* LLDB */;
 			targetProxy = 266803611160110D008E1FE4 /* PBXContainerItemProxy */;
 		};
+		266E8C6D13528AD2000C2042 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 26DC6A0F1337FE6900FF7998 /* lldb-platform */;
+			targetProxy = 266E8C6C13528AD2000C2042 /* PBXContainerItemProxy */;
+		};
 		2689011513353E9B00698AC0 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 2689FFC913353D7A00698AC0 /* lldb-core */;

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Tue Apr 12 00:54:46 2011
@@ -204,65 +204,65 @@
             }
         }
         
-        if ((launch_flags & eLaunchFlagLaunchInTTY) || g_launch_tty)
-        {
-            ArchSpec arch (m_opaque_sp->GetArchitecture ());
-            
-            Module *exe_module = m_opaque_sp->GetExecutableModule().get();
-            if (exe_module)
-            {
-                char exec_file_path[PATH_MAX];
-                exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
-                if (exe_module->GetFileSpec().Exists())
-                {
-                    // Make a new argument vector
-                    std::vector<const char *> exec_path_plus_argv;
-                    // Append the resolved executable path
-                    exec_path_plus_argv.push_back (exec_file_path);
-                        
-                    // Push all args if there are any
-                    if (argv)
-                    {
-                        for (int i = 0; argv[i]; ++i)
-                            exec_path_plus_argv.push_back(argv[i]);
-                    }
-                        
-                    // Push a NULL to terminate the args.
-                    exec_path_plus_argv.push_back(NULL);
-                        
-
-                    const char *tty_name = NULL;
-                    if (g_launch_tty && g_launch_tty[0] == '/')
-                        tty_name = g_launch_tty;
-                    
-                    lldb::pid_t pid = Host::LaunchInNewTerminal (tty_name,
-                                                                 &exec_path_plus_argv[0],
-                                                                 envp,
-                                                                 working_directory,
-                                                                 &arch,
-                                                                 true,
-                                                                 launch_flags & eLaunchFlagDisableASLR);
-
-                    if (pid != LLDB_INVALID_PROCESS_ID)
-                    {
-                        sb_process = AttachToProcessWithID(listener, pid, error);
-                    }
-                    else
-                    {
-                        error.SetErrorStringWithFormat("failed to launch process in terminal");
-                    }
-                }
-                else
-                {
-                    error.SetErrorStringWithFormat("executable doesn't exist: \"%s\"", exec_file_path);
-                }
-            }            
-            else
-            {
-                error.SetErrorStringWithFormat("invalid executable");
-            }
-        }
-        else
+//        if ((launch_flags & eLaunchFlagLaunchInTTY) || g_launch_tty)
+//        {
+//            ArchSpec arch (m_opaque_sp->GetArchitecture ());
+//            
+//            Module *exe_module = m_opaque_sp->GetExecutableModule().get();
+//            if (exe_module)
+//            {
+//                char exec_file_path[PATH_MAX];
+//                exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
+//                if (exe_module->GetFileSpec().Exists())
+//                {
+//                    // Make a new argument vector
+//                    std::vector<const char *> exec_path_plus_argv;
+//                    // Append the resolved executable path
+//                    exec_path_plus_argv.push_back (exec_file_path);
+//                        
+//                    // Push all args if there are any
+//                    if (argv)
+//                    {
+//                        for (int i = 0; argv[i]; ++i)
+//                            exec_path_plus_argv.push_back(argv[i]);
+//                    }
+//                        
+//                    // Push a NULL to terminate the args.
+//                    exec_path_plus_argv.push_back(NULL);
+//                        
+//
+//                    const char *tty_name = NULL;
+//                    if (g_launch_tty && g_launch_tty[0] == '/')
+//                        tty_name = g_launch_tty;
+//                    
+//                    lldb::pid_t pid = Host::LaunchInNewTerminal (tty_name,
+//                                                                 &exec_path_plus_argv[0],
+//                                                                 envp,
+//                                                                 working_directory,
+//                                                                 &arch,
+//                                                                 true,
+//                                                                 launch_flags & eLaunchFlagDisableASLR);
+//
+//                    if (pid != LLDB_INVALID_PROCESS_ID)
+//                    {
+//                        sb_process = AttachToProcessWithID(listener, pid, error);
+//                    }
+//                    else
+//                    {
+//                        error.SetErrorStringWithFormat("failed to launch process in terminal");
+//                    }
+//                }
+//                else
+//                {
+//                    error.SetErrorStringWithFormat("executable doesn't exist: \"%s\"", exec_file_path);
+//                }
+//            }            
+//            else
+//            {
+//                error.SetErrorStringWithFormat("invalid executable");
+//            }
+//        }
+//        else
         {
             if (listener.IsValid())
                 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));

Modified: lldb/trunk/source/Commands/CommandObjectArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectArgs.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectArgs.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectArgs.cpp Tue Apr 12 00:54:46 2011
@@ -105,7 +105,7 @@
     ConstString target_triple;
     
     
-    Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+    Process *process = m_interpreter.GetExecutionContext().process;
     if (!process)
     {
         result.AppendError ("Args found no process.");
@@ -131,7 +131,7 @@
         return false;
     }
     
-    Thread *thread = m_interpreter.GetDebugger().GetExecutionContext ().thread;
+    Thread *thread = m_interpreter.GetExecutionContext ().thread;
     
     if (!thread)
     {

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Tue Apr 12 00:54:46 2011
@@ -322,7 +322,7 @@
                 FileSpec file;
                 if (m_options.m_filename.empty())
                 {
-                    StackFrame *cur_frame = m_interpreter.GetDebugger().GetExecutionContext().frame;
+                    StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame;
                     if (cur_frame == NULL)
                     {
                         result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");

Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Tue Apr 12 00:54:46 2011
@@ -128,7 +128,7 @@
         break;
 
     case 'a':
-        arch.SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
+            arch.SetTriple (option_arg, m_interpreter.GetPlatform (true).get());
         break;
 
     default:
@@ -257,7 +257,7 @@
     if (m_options.show_mixed && m_options.num_lines_context == 0)
         m_options.num_lines_context = 1;
 
-    ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+    ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
 
     if (!m_options.func_name.empty())
     {

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Apr 12 00:54:46 2011
@@ -295,7 +295,7 @@
     CommandReturnObject &result
 )
 {
-    m_exe_ctx = m_interpreter.GetDebugger().GetExecutionContext();
+    m_exe_ctx = m_interpreter.GetExecutionContext();
 
     m_options.Reset();
 

Modified: lldb/trunk/source/Commands/CommandObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFile.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFile.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFile.cpp Tue Apr 12 00:54:46 2011
@@ -58,7 +58,7 @@
     {
         case 'a':
             {
-                PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+                PlatformSP platform_sp (m_interpreter.GetPlatform (false));
                 ArchSpec option_arch (option_arg, platform_sp.get());
                 if (option_arch.IsValid())
                     m_arch = option_arch;

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Tue Apr 12 00:54:46 2011
@@ -69,7 +69,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         if (exe_ctx.frame)
         {
             exe_ctx.frame->DumpUsingSettingsFormat (&result.GetOutputStream());
@@ -188,7 +188,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        ExecutionContext exe_ctx (m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
         if (exe_ctx.thread)
         {
             const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
@@ -445,7 +445,7 @@
         CommandReturnObject &result
     )
     {
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         if (exe_ctx.frame == NULL)
         {
             result.AppendError ("you must be stopped in a valid stack frame to view frame variables.");

Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectImage.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectImage.cpp Tue Apr 12 00:54:46 2011
@@ -87,7 +87,7 @@
                 LineTable *line_table = sc.comp_unit->GetLineTable();
                 if (line_table)
                     line_table->GetDescription (&strm, 
-                                                interpreter.GetDebugger().GetExecutionContext().target, 
+                                                interpreter.GetExecutionContext().target, 
                                                 lldb::eDescriptionLevelBrief);
                 else
                     strm << "No line table";
@@ -165,7 +165,7 @@
         {
             Symtab *symtab = objfile->GetSymtab();
             if (symtab)
-                symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, sort_order);
+                symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order);
         }
     }
 }
@@ -183,9 +183,11 @@
             {
                 strm.PutCString ("Sections for '");
                 strm << module->GetFileSpec();
+                if (module->GetObjectName())
+                    strm << '(' << module->GetObjectName() << ')';
                 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
                 strm.IndentMore();
-                section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true, UINT32_MAX);
+                section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX);
                 strm.IndentLess();
             }
         }
@@ -224,7 +226,7 @@
         lldb::addr_t addr = raw_addr - offset;
         Address so_addr;
         SymbolContext sc;
-        Target *target = interpreter.GetDebugger().GetExecutionContext().target;
+        Target *target = interpreter.GetExecutionContext().target;
         if (target && !target->GetSectionLoadList().IsEmpty())
         {
             if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
@@ -242,7 +244,7 @@
         if (offset)
             strm.Printf("File Address: 0x%llx\n", addr);
 
-        ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
+        ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
         strm.IndentMore();
         strm.Indent ("    Address: ");
         so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
@@ -309,7 +311,7 @@
                     {
                         Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
                         strm.Indent ();
-                        symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().target, i);
+                        symbol->Dump (&strm, interpreter.GetExecutionContext().target, i);
                     }
                     strm.IndentLess ();
                     return num_matches;
@@ -338,9 +340,9 @@
             {
                 if (sc.line_entry.range.GetBaseAddress().IsValid())
                 {
-                    lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().target);
+                    lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetExecutionContext().target);
                     int addr_size = sizeof (addr_t);
-                    Process *process = interpreter.GetDebugger().GetExecutionContext().process;
+                    Process *process = interpreter.GetExecutionContext().process;
                     if (process)
                         addr_size = process->GetTarget().GetArchitecture().GetAddressByteSize();
                     if (vm_addr != LLDB_INVALID_ADDRESS)
@@ -351,7 +353,7 @@
                     strm.PutCString(" in ");
                 }
             }
-            sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
+            sc.DumpStopContext(&strm, interpreter.GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
         }
     }
     strm.IndentLess ();
@@ -1050,7 +1052,7 @@
         }
         else
         {
-            ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+            ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
             uint32_t total_num_dumped = 0;
 
             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
@@ -1233,9 +1235,11 @@
                     Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
                     strm.Printf("[%3u] ", image_idx);
 
+                    bool dump_object_name = false;
                     if (m_options.m_format_array.empty())
                     {
                         DumpFullpath(strm, &module->GetFileSpec(), 0);
+                        dump_object_name = true;
                     }
                     else
                     {
@@ -1254,6 +1258,7 @@
 
                             case 'f':
                                 DumpFullpath (strm, &module->GetFileSpec(), width);
+                                dump_object_name = true;
                                 break;
 
                             case 'd':
@@ -1262,6 +1267,7 @@
 
                             case 'b':
                                 DumpBasename (strm, &module->GetFileSpec(), width);
+                                dump_object_name = true;
                                 break;
 
                             case 's':
@@ -1277,6 +1283,7 @@
                                                 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
                                             else
                                                 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
+                                            dump_object_name = true;
                                             break;
                                         }
                                     }
@@ -1291,8 +1298,15 @@
                             default:
                                 break;
                             }
+                            
                         }
                     }
+                    if (dump_object_name)
+                    {
+                        const char *object_name = module->GetObjectName().GetCString();
+                        if (object_name)
+                            strm.Printf ("(%s)", object_name);
+                    }
                     strm.EOL();
                 }
                 result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -1682,16 +1696,16 @@
 OptionDefinition
 CommandObjectImageLookup::CommandOptions::g_option_table[] =
 {
-{ LLDB_OPT_SET_1,   true,  "address",    'a', required_argument, NULL, 0, eArgTypeAddress,    "Lookup an address in one or more executable images."},
-{ LLDB_OPT_SET_1,   false, "offset",     'o', required_argument, NULL, 0, eArgTypeOffset,  "When looking up an address subtract <offset> from any addresses before doing the lookup."},
-{ LLDB_OPT_SET_2,   true,  "symbol",     's', required_argument, NULL, 0, eArgTypeSymbol,    "Lookup a symbol by name in the symbol tables in one or more executable images."},
-{ LLDB_OPT_SET_2,   false, "regex",      'r', no_argument,       NULL, 0, eArgTypeNone,        "The <name> argument for name lookups are regular expressions."},
-{ LLDB_OPT_SET_3,   true,  "file",       'f', required_argument, NULL, 0, eArgTypeFilename,    "Lookup a file by fullpath or basename in one or more executable images."},
-{ LLDB_OPT_SET_3,   false, "line",       'l', required_argument, NULL, 0, eArgTypeLineNum,    "Lookup a line number in a file (must be used in conjunction with --file)."},
-{ LLDB_OPT_SET_3,   false, "no-inlines", 'i', no_argument,       NULL, 0, eArgTypeNone,        "Check inline line entries (must be used in conjunction with --file)."},
-{ LLDB_OPT_SET_4,   true,  "function",   'n', required_argument, NULL, 0, eArgTypeFunctionName,    "Lookup a function by name in the debug symbols in one or more executable images."},
-{ LLDB_OPT_SET_5,   true,  "type",       't', required_argument, NULL, 0, eArgTypeName,    "Lookup a type by name in the debug symbols in one or more executable images."},
-{ LLDB_OPT_SET_ALL, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,        "Enable verbose lookup information."},
+{ LLDB_OPT_SET_1,   true,  "address",    'a', required_argument, NULL, 0, eArgTypeAddress,      "Lookup an address in one or more executable images."},
+{ LLDB_OPT_SET_1,   false, "offset",     'o', required_argument, NULL, 0, eArgTypeOffset,       "When looking up an address subtract <offset> from any addresses before doing the lookup."},
+{ LLDB_OPT_SET_2,   true,  "symbol",     's', required_argument, NULL, 0, eArgTypeSymbol,       "Lookup a symbol by name in the symbol tables in one or more executable images."},
+{ LLDB_OPT_SET_2,   false, "regex",      'r', no_argument,       NULL, 0, eArgTypeNone,         "The <name> argument for name lookups are regular expressions."},
+{ LLDB_OPT_SET_3,   true,  "file",       'f', required_argument, NULL, 0, eArgTypeFilename,     "Lookup a file by fullpath or basename in one or more executable images."},
+{ LLDB_OPT_SET_3,   false, "line",       'l', required_argument, NULL, 0, eArgTypeLineNum,      "Lookup a line number in a file (must be used in conjunction with --file)."},
+{ LLDB_OPT_SET_3,   false, "no-inlines", 'i', no_argument,       NULL, 0, eArgTypeNone,         "Check inline line entries (must be used in conjunction with --file)."},
+{ LLDB_OPT_SET_4,   true,  "function",   'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more executable images."},
+{ LLDB_OPT_SET_5,   true,  "type",       't', required_argument, NULL, 0, eArgTypeName,         "Lookup a type by name in the debug symbols in one or more executable images."},
+{ LLDB_OPT_SET_ALL, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,         "Enable verbose lookup information."},
 { 0, false, NULL,           0, 0,                 NULL, 0, eArgTypeNone, NULL }
 };
 

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Tue Apr 12 00:54:46 2011
@@ -240,7 +240,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError("need a process to read memory");
@@ -415,7 +415,7 @@
 { SET1       , false, "format",       'f', required_argument, NULL, 0, eArgTypeFormat,       "The format that will be used to display the memory. Defaults to bytes with ASCII (--format=Y)."},
 { SET1       , false, "size",         's', required_argument, NULL, 0, eArgTypeByteSize,     "The size in bytes to use when displaying with the selected format."},
 { SET1       , false, "num-per-line", 'l', required_argument, NULL, 0, eArgTypeNumberPerLine,"The number of items per line to display."},
-{ SET1       , false, "count",        'c', required_argument, NULL, 0, eArgTypeCount,        "The number of total items to display."},
+{ SET1 | SET2, false, "count",        'c', required_argument, NULL, 0, eArgTypeCount,        "The number of total items to display."},
 { SET1 | SET2, false, "outfile",      'o', required_argument, NULL, 0, eArgTypeFilename,     "Dump memory read results into a file."},
 { SET1 | SET2, false, "append",       'a', no_argument,       NULL, 0, eArgTypeNone,         "Append memory read results to 'outfile'."},
 {        SET2, false, "binary",       'b', no_argument,       NULL, 0, eArgTypeNone,         "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
@@ -591,7 +591,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError("need a process to read memory");

Modified: lldb/trunk/source/Commands/CommandObjectPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectPlatform.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectPlatform.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectPlatform.cpp Tue Apr 12 00:54:46 2011
@@ -413,6 +413,134 @@
         return result.Succeeded();
     }
 };
+//----------------------------------------------------------------------
+// "platform process launch"
+//----------------------------------------------------------------------
+class CommandObjectPlatformProcessLaunch : public CommandObject
+{
+public:
+    CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
+        CommandObject (interpreter, 
+                       "platform process launch",
+                       "Launch a new process on a remote platform.",
+                       "platform process launch program",
+                       0),
+        m_options (interpreter)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformProcessLaunch ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        
+        if (platform_sp)
+        {
+            Error error;
+            const uint32_t argc = args.GetArgumentCount();
+            Target *target = m_interpreter.GetExecutionContext().target;
+            ModuleSP exe_module_sp;
+            if (target)
+            {
+                exe_module_sp = target->GetExecutableModule();
+                if (exe_module_sp)
+                {
+                    m_options.launch_info.GetExecutableFile () = exe_module_sp->GetFileSpec();
+                    char exe_path[PATH_MAX];
+                    if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
+                        m_options.launch_info.GetArguments().AppendArgument (exe_path);
+                    m_options.launch_info.GetArchitecture() = exe_module_sp->GetArchitecture();
+                }
+            }
+
+            if (argc > 0)
+            {
+                if (m_options.launch_info.GetExecutableFile ())
+                {
+                    // We already have an executable file, so we will use this
+                    // and all arguments to this function are extra arguments
+                    m_options.launch_info.GetArguments().AppendArguments (args);
+                }
+                else
+                {
+                    // We don't have any file yet, so the first argument is our
+                    // executable, and the rest are program arguments
+                    const bool first_arg_is_executable = true;
+                    m_options.launch_info.SetArgumentsFromArgs (args, 
+                                                                first_arg_is_executable, 
+                                                                first_arg_is_executable);
+                }
+            }
+            
+            if (m_options.launch_info.GetExecutableFile ())
+            {
+                Debugger &debugger = m_interpreter.GetDebugger();
+
+                if (argc == 0)
+                {
+                    lldb::UserSettingsControllerSP process_usc_sp (Process::GetSettingsController ());
+                    if (process_usc_sp)
+                    {
+                        SettableVariableType type;
+                        StringList settings_args (process_usc_sp->GetVariable ("process.run-args", 
+                                                                               type,
+                                                                               m_interpreter.GetDebugger().GetInstanceName().GetCString(),
+                                                                               error));
+                        if (error.Success())
+                        {
+                            const size_t num_settings_args = settings_args.GetSize();
+                            for (size_t i=0; i<num_settings_args; ++i)
+                                m_options.launch_info.GetArguments().AppendArgument (settings_args.GetStringAtIndex(i));
+                        }
+                    }
+                }
+
+                ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info, 
+                                                                 debugger,
+                                                                 target,
+                                                                 debugger.GetListener(),
+                                                                 error));
+                if (process_sp && process_sp->IsAlive())
+                {
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                    return true;
+                }
+                
+                if (error.Success())
+                    result.AppendError ("process launch failed");
+                else
+                    result.AppendError (error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+            else
+            {
+                result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+        }
+        else
+        {
+            result.AppendError ("no platform is selected\n");
+        }
+        return result.Succeeded();
+    }
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+protected:
+    ProcessLaunchCommandOptions m_options;
+};
+
 
 
 //----------------------------------------------------------------------
@@ -454,11 +582,11 @@
                     lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
                     if (pid != LLDB_INVALID_PROCESS_ID)
                     {
-                        ProcessInfo proc_info;
+                        ProcessInstanceInfo proc_info;
                         if (platform_sp->GetProcessInfo (pid, proc_info))
                         {
-                            ProcessInfo::DumpTableHeader (ostrm, platform_sp.get());
-                            proc_info.DumpAsTableRow(ostrm, platform_sp.get());
+                            ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
+                            proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
                             result.SetStatus (eReturnStatusSuccessFinishResult);
                         }
                         else
@@ -469,24 +597,25 @@
                     }
                     else
                     {
-                        ProcessInfoList proc_infos;
+                        ProcessInstanceInfoList proc_infos;
                         const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
-                        if (matches == 0)
+                        const char *match_desc = NULL;
+                        const char *match_name = m_options.match_info.GetProcessInfo().GetName();
+                        if (match_name && match_name[0])
                         {
-                            const char *match_desc = NULL;
-                            const char *match_name = m_options.match_info.GetProcessInfo().GetName();
-                            if (match_name && match_name[0])
+                            switch (m_options.match_info.GetNameMatchType())
                             {
-                                switch (m_options.match_info.GetNameMatchType())
-                                {
-                                    case eNameMatchIgnore: break;
-                                    case eNameMatchEquals: match_desc = "match"; break;
-                                    case eNameMatchContains: match_desc = "contains"; break;
-                                    case eNameMatchStartsWith: match_desc = "starts with"; break;
-                                    case eNameMatchEndsWith: match_desc = "end with"; break;
-                                    case eNameMatchRegularExpression: match_desc = "match the regular expression"; break;
-                                }
+                                case eNameMatchIgnore: break;
+                                case eNameMatchEquals: match_desc = "matched"; break;
+                                case eNameMatchContains: match_desc = "contained"; break;
+                                case eNameMatchStartsWith: match_desc = "started with"; break;
+                                case eNameMatchEndsWith: match_desc = "ended with"; break;
+                                case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
                             }
+                        }
+
+                        if (matches == 0)
+                        {
                             if (match_desc)
                                 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n", 
                                                               match_desc,
@@ -498,11 +627,19 @@
                         }
                         else
                         {
-
-                            ProcessInfo::DumpTableHeader (ostrm, platform_sp.get());
+                            result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"", 
+                                                            matches,
+                                                            matches > 1 ? "es were" : " was",
+                                                            platform_sp->GetName());
+                            if (match_desc)
+                                result.AppendMessageWithFormat (" whose name %s \"%s\"", 
+                                                                match_desc,
+                                                                match_name);
+                            result.AppendMessageWithFormat ("\n");
+                            ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
                             for (uint32_t i=0; i<matches; ++i)
                             {
-                                proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get());
+                                proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
                             }
                         }
                     }
@@ -567,7 +704,7 @@
                     break;
 
                 case 'u':
-                    match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+                    match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
                     if (!success)
                         error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
                     break;
@@ -579,7 +716,7 @@
                     break;
 
                 case 'g':
-                    match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+                    match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
                     if (!success)
                         error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
                     break;
@@ -596,26 +733,37 @@
 
                 case 'n':
                     match_info.GetProcessInfo().SetName (option_arg);
-                    if (match_info.GetNameMatchType() == eNameMatchIgnore)
-                        match_info.SetNameMatchType (eNameMatchEquals);
+                    match_info.SetNameMatchType (eNameMatchEquals);
                     break;
 
                 case 'e':
+                    match_info.GetProcessInfo().SetName (option_arg);
                     match_info.SetNameMatchType (eNameMatchEndsWith);
                     break;
 
                 case 's':
+                    match_info.GetProcessInfo().SetName (option_arg);
                     match_info.SetNameMatchType (eNameMatchStartsWith);
                     break;
                     
                 case 'c':
+                    match_info.GetProcessInfo().SetName (option_arg);
                     match_info.SetNameMatchType (eNameMatchContains);
                     break;
                     
                 case 'r':
+                    match_info.GetProcessInfo().SetName (option_arg);
                     match_info.SetNameMatchType (eNameMatchRegularExpression);
                     break;
 
+                case 'A':
+                    show_args = true;
+                    break;
+
+                case 'v':
+                    verbose = true;
+                    break;
+
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
                     break;
@@ -628,6 +776,8 @@
         ResetOptionValues ()
         {
             match_info.Clear();
+            show_args = false;
+            verbose = false;
         }
         
         const OptionDefinition*
@@ -642,7 +792,9 @@
         
         // Instance variables to hold the values for command options.
         
-        ProcessInfoMatch match_info;
+        ProcessInstanceInfoMatch match_info;
+        bool show_args;
+        bool verbose;
     };
     CommandOptions m_options;
 };
@@ -650,49 +802,23 @@
 OptionDefinition
 CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
 {
-{ LLDB_OPT_SET_1, false, "pid"              , 'p', required_argument, NULL, 0, eArgTypePid          , "List the process info for a specific process ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5, true , "name"             , 'n', required_argument, NULL, 0, eArgTypeProcessName  , "Find processes that match the supplied name." },
-{ LLDB_OPT_SET_2, false, "ends-with"        , 'e', no_argument      , NULL, 0, eArgTypeNone         , "Process names must end with the name supplied with the --name option." },
-{ LLDB_OPT_SET_3, false, "starts-with"      , 's', no_argument      , NULL, 0, eArgTypeNone         , "Process names must start with the name supplied with the --name option." },
-{ LLDB_OPT_SET_4, false, "contains"         , 'c', no_argument      , NULL, 0, eArgTypeNone         , "Process names must contain the name supplied with the --name option." },
-{ LLDB_OPT_SET_5, false, "regex"            , 'r', no_argument      , NULL, 0, eArgTypeNone         , "Process names must match name supplied with the --name option as a regular expression." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "parent"           , 'P', required_argument, NULL, 0, eArgTypePid          , "Find processes that have a matching parent process ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "uid"              , 'u', required_argument, NULL, 0, eArgTypeNone          , "Find processes that have a matching user ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "euid"             , 'U', required_argument, NULL, 0, eArgTypeNone          , "Find processes that have a matching effective user ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "gid"              , 'g', required_argument, NULL, 0, eArgTypeNone          , "Find processes that have a matching group ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "egid"             , 'G', required_argument, NULL, 0, eArgTypeNone          , "Find processes that have a matching effective group ID." },
-{ LLDB_OPT_SET_2|
-  LLDB_OPT_SET_3|
-  LLDB_OPT_SET_4|
-  LLDB_OPT_SET_5|
-  LLDB_OPT_SET_6, false, "arch"             , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
-{ 0             , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
+{   LLDB_OPT_SET_1, false, "pid"              , 'p', required_argument, NULL, 0, eArgTypePid          , "List the process info for a specific process ID." },
+{   LLDB_OPT_SET_2, true , "name"             , 'n', required_argument, NULL, 0, eArgTypeProcessName  , "Find processes with executable basenames that match a string." },
+{   LLDB_OPT_SET_3, true , "ends-with"        , 'e', required_argument, NULL, 0, eArgTypeNone         , "Find processes with executable basenames that end with a string." },
+{   LLDB_OPT_SET_4, true , "starts-with"      , 's', required_argument, NULL, 0, eArgTypeNone         , "Find processes with executable basenames that start with a string." },
+{   LLDB_OPT_SET_5, true , "contains"         , 'c', required_argument, NULL, 0, eArgTypeNone         , "Find processes with executable basenames that contain a string." },
+{   LLDB_OPT_SET_6, true , "regex"            , 'r', required_argument, NULL, 0, eArgTypeNone         , "Find processes with executable basenames that match a regular expression." },
+{  ~LLDB_OPT_SET_1, false, "parent"           , 'P', required_argument, NULL, 0, eArgTypePid          , "Find processes that have a matching parent process ID." },
+{  ~LLDB_OPT_SET_1, false, "uid"              , 'u', required_argument, NULL, 0, eArgTypeNone         , "Find processes that have a matching user ID." },
+{  ~LLDB_OPT_SET_1, false, "euid"             , 'U', required_argument, NULL, 0, eArgTypeNone         , "Find processes that have a matching effective user ID." },
+{  ~LLDB_OPT_SET_1, false, "gid"              , 'g', required_argument, NULL, 0, eArgTypeNone         , "Find processes that have a matching group ID." },
+{  ~LLDB_OPT_SET_1, false, "egid"             , 'G', required_argument, NULL, 0, eArgTypeNone         , "Find processes that have a matching effective group ID." },
+{  ~LLDB_OPT_SET_1, false, "arch"             , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
+{ LLDB_OPT_SET_ALL, false, "show-args"        , 'A', no_argument      , NULL, 0, eArgTypeNone         , "Show process arguments instead of the process executable basename." },
+{ LLDB_OPT_SET_ALL, false, "verbose"          , 'v', no_argument      , NULL, 0, eArgTypeNone         , "Enable verbose output." },
+{  0              , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
 };
 
-
 //----------------------------------------------------------------------
 // "platform process info"
 //----------------------------------------------------------------------
@@ -746,7 +872,7 @@
                         lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
                         if (success)
                         {
-                            ProcessInfo proc_info;
+                            ProcessInstanceInfo proc_info;
                             if (platform_sp->GetProcessInfo (pid, proc_info))
                             {
                                 ostrm.Printf ("Process information for process %i:\n", pid);
@@ -805,7 +931,7 @@
                                 "platform process [attach|launch|list] ...")
     {
 //        LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
-//        LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
+        LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
         LoadSubCommand ("info"  , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
         LoadSubCommand ("list"  , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
 

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Tue Apr 12 00:54:46 2011
@@ -175,7 +175,7 @@
         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
 
         StateType state = eStateInvalid;
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process)
         {
             state = process->GetState();
@@ -266,7 +266,10 @@
         
         if (process->GetDisableASLR())
             launch_flags |= eLaunchFlagDisableASLR;
-    
+
+        if (m_options.in_new_tty)
+            launch_flags |= eLaunchFlagLaunchInTTY; 
+
         if (m_options.no_stdio)
             launch_flags |= eLaunchFlagDisableSTDIO;
         else if (!m_options.in_new_tty
@@ -287,52 +290,35 @@
         if (!m_options.working_dir.empty())
             working_dir = m_options.working_dir.c_str();
 
-        if (m_options.in_new_tty)
-        {
-        
-            lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
-                                                         inferior_argv,
-                                                         inferior_envp,
-                                                         working_dir,
-                                                         &exe_module->GetArchitecture(),
-                                                         true,
-                                                         process->GetDisableASLR());
-            
-            if (pid != LLDB_INVALID_PROCESS_ID)
-                error = process->Attach (pid);
+        const char * stdin_path = NULL;
+        const char * stdout_path = NULL;
+        const char * stderr_path = NULL;
+
+        // Were any standard input/output/error paths given on the command line?
+        if (m_options.stdin_path.empty() &&
+            m_options.stdout_path.empty() &&
+            m_options.stderr_path.empty())
+        {
+            // No standard file handles were given on the command line, check
+            // with the process object in case they were give using "set settings"
+            stdin_path = process->GetStandardInputPath();
+            stdout_path = process->GetStandardOutputPath(); 
+            stderr_path = process->GetStandardErrorPath(); 
         }
         else
         {
-            const char * stdin_path = NULL;
-            const char * stdout_path = NULL;
-            const char * stderr_path = NULL;
-
-            // Were any standard input/output/error paths given on the command line?
-            if (m_options.stdin_path.empty() &&
-                m_options.stdout_path.empty() &&
-                m_options.stderr_path.empty())
-            {
-                // No standard file handles were given on the command line, check
-                // with the process object in case they were give using "set settings"
-                stdin_path = process->GetStandardInputPath();
-                stdout_path = process->GetStandardOutputPath(); 
-                stderr_path = process->GetStandardErrorPath(); 
-            }
-            else
-            {
-                stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
-                stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
-                stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
-            }
-
-            error = process->Launch (inferior_argv,
-                                     inferior_envp,
-                                     launch_flags,
-                                     stdin_path,
-                                     stdout_path,
-                                     stderr_path,
-                                     working_dir);
+            stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
+            stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
+            stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
         }
+
+        error = process->Launch (inferior_argv,
+                                 inferior_envp,
+                                 launch_flags,
+                                 stdin_path,
+                                 stdout_path,
+                                 stderr_path,
+                                 working_dir);
                      
         if (error.Success())
         {
@@ -521,11 +507,11 @@
                 const char *partial_name = NULL;
                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
 
-                PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ());
+                PlatformSP platform_sp (m_interpreter.GetPlatform (true));
                 if (platform_sp)
                 {
-                    ProcessInfoList process_infos;
-                    ProcessInfoMatch match_info;
+                    ProcessInstanceInfoList process_infos;
+                    ProcessInstanceInfoMatch match_info;
                     if (partial_name)
                     {
                         match_info.GetProcessInfo().SetName(partial_name);
@@ -579,7 +565,7 @@
         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
         bool synchronous_execution = m_interpreter.GetSynchronous ();
         
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         StateType state = eStateInvalid;
         if (process)
         {
@@ -707,11 +693,11 @@
                     
                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
                     {
-                        ProcessInfoList process_infos;
-                        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ());
+                        ProcessInstanceInfoList process_infos;
+                        PlatformSP platform_sp (m_interpreter.GetPlatform (true));
                         if (platform_sp)
                         {
-                            ProcessInfoMatch match_info (wait_name, eNameMatchEquals);
+                            ProcessInstanceInfoMatch match_info (wait_name, eNameMatchEquals);
                             platform_sp->FindProcesses (match_info, process_infos);
                         }
                         if (process_infos.GetSize() > 1)
@@ -860,7 +846,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         bool synchronous_execution = m_interpreter.GetSynchronous ();
 
         if (process == NULL)
@@ -947,7 +933,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("must have a valid process in order to detach");
@@ -1057,7 +1043,7 @@
         
         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
         Error error;        
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process)
         {
             if (process->IsAlive())
@@ -1172,7 +1158,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("must have a valid process in order to load a shared library");
@@ -1230,7 +1216,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("must have a valid process in order to load a shared library");
@@ -1307,7 +1293,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("no process to signal");
@@ -1382,7 +1368,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("no process to halt");
@@ -1444,7 +1430,7 @@
     Execute (Args& command,
              CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("no process to kill");
@@ -1507,7 +1493,7 @@
     {
         Stream &output_stream = result.GetOutputStream();
         result.SetStatus (eReturnStatusSuccessFinishNoResult);
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         if (exe_ctx.process)
         {
             const StateType state = exe_ctx.process->GetState();

Modified: lldb/trunk/source/Commands/CommandObjectRegister.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectRegister.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectRegister.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectRegister.cpp Tue Apr 12 00:54:46 2011
@@ -75,7 +75,7 @@
     {
         Stream &output_stream = result.GetOutputStream();
         DataExtractor reg_data;
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
 
         if (reg_context)
@@ -274,7 +274,7 @@
     )
     {
         DataExtractor reg_data;
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
 
         if (reg_context)

Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSource.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectSource.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectSource.cpp Tue Apr 12 00:54:46 2011
@@ -272,7 +272,7 @@
             result.SetStatus (eReturnStatusFailed);
         }
 
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         
         if (!m_options.symbol_name.empty())
         {

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Tue Apr 12 00:54:46 2011
@@ -362,7 +362,7 @@
         
         if (command.GetArgumentCount() == 0)
         {
-            ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+            ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
             if (exe_ctx.thread)
             {
                 if (DisplayFramesForExecutionContext (exe_ctx.thread,
@@ -386,7 +386,7 @@
         }
         else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
         {
-            Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+            Process *process = m_interpreter.GetExecutionContext().process;
             uint32_t num_threads = process->GetThreadList().GetSize();
             for (uint32_t i = 0; i < num_threads; i++)
             {
@@ -412,7 +412,7 @@
         else
         {
             uint32_t num_args = command.GetArgumentCount();
-            Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+            Process *process = m_interpreter.GetExecutionContext().process;
             std::vector<ThreadSP> thread_sps;
 
             for (uint32_t i = 0; i < num_args; i++)
@@ -610,7 +610,7 @@
         CommandReturnObject &result
     )
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         bool synchronous_execution = m_interpreter.GetSynchronous();
 
         if (process == NULL)
@@ -851,7 +851,7 @@
             return false;
         }
 
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("no process exists. Cannot continue");
@@ -1115,7 +1115,7 @@
             return false;
         }
 
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("need a valid process to step");
@@ -1308,7 +1308,7 @@
         CommandReturnObject &result
     )
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("no process");
@@ -1378,7 +1378,7 @@
     {
         Stream &strm = result.GetOutputStream();
         result.SetStatus (eReturnStatusSuccessFinishNoResult);
-        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
         if (exe_ctx.process)
         {
             const StateType state = exe_ctx.process->GetState();

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Tue Apr 12 00:54:46 2011
@@ -459,6 +459,41 @@
 }
 
 ConnectionStatus
+ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
+{
+    Close (m_fd, NULL);
+    m_is_socket = true;
+
+    // Open the socket that was passed in as an option
+    struct sockaddr_un saddr_un;
+    m_fd = ::socket (AF_UNIX, SOCK_STREAM, 0);
+    if (m_fd == -1)
+    {
+        if (error_ptr)
+            error_ptr->SetErrorToErrno();
+        return eConnectionStatusError;
+    }
+
+    saddr_un.sun_family = AF_UNIX;
+    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
+    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
+#if defined(__APPLE__) || defined(__FreeBSD__)
+    saddr_un.sun_len = SUN_LEN (&saddr_un);
+#endif
+
+    if (::connect (m_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
+    {
+        if (error_ptr)
+            error_ptr->SetErrorToErrno();
+        Close (m_fd, NULL);
+        return eConnectionStatusError;
+    }
+    if (error_ptr)
+        error_ptr->Clear();
+    return eConnectionStatusSuccess;
+}
+
+ConnectionStatus
 ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
 {
     lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Apr 12 00:54:46 2011
@@ -229,7 +229,6 @@
     m_listener ("lldb.Debugger"),
     m_source_manager (),
     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
-    m_exe_ctx (),
     m_input_readers (),
     m_input_reader_data ()
 {
@@ -556,51 +555,6 @@
     }
 }
 
-void
-Debugger::UpdateExecutionContext (ExecutionContext *override_context)
-{
-    m_exe_ctx.Clear();
-
-    if (override_context != NULL)
-    {
-        m_exe_ctx.target = override_context->target;
-        m_exe_ctx.process = override_context->process;
-        m_exe_ctx.thread = override_context->thread;
-        m_exe_ctx.frame = override_context->frame;
-    }
-    else
-    {
-        TargetSP target_sp (GetSelectedTarget());
-        if (target_sp)
-        {
-            m_exe_ctx.target = target_sp.get();
-            m_exe_ctx.process = target_sp->GetProcessSP().get();
-            if (m_exe_ctx.process && m_exe_ctx.process->IsAlive() && !m_exe_ctx.process->IsRunning())
-            {
-                m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get();
-                if (m_exe_ctx.thread == NULL)
-                {
-                    m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
-                    // If we didn't have a selected thread, select one here.
-                    if (m_exe_ctx.thread != NULL)
-                        m_exe_ctx.process->GetThreadList().SetSelectedThreadByID(m_exe_ctx.thread->GetID());
-                }
-                if (m_exe_ctx.thread)
-                {
-                    m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get();
-                    if (m_exe_ctx.frame == NULL)
-                    {
-                        m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
-                        // If we didn't have a selected frame select one here.
-                        if (m_exe_ctx.frame != NULL)
-                            m_exe_ctx.thread->SetSelectedFrame(m_exe_ctx.frame);
-                    }
-                }
-            }
-        }
-    }
-}
-
 DebuggerSP
 Debugger::FindDebuggerWithID (lldb::user_id_t id)
 {

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Tue Apr 12 00:54:46 2011
@@ -28,6 +28,7 @@
     m_file (file_spec),
     m_platform_file(),
     m_object_name (),
+    m_object_offset (object_offset),
     m_objfile_ap (),
     m_symfile_ap (),
     m_ast (),
@@ -534,7 +535,7 @@
         m_did_load_objfile = true;
         Timer scoped_timer(__PRETTY_FUNCTION__,
                            "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
-        m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, 0, m_file.GetByteSize()));
+        m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize()));
     }
     return m_objfile_ap.get();
 }

Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Tue Apr 12 00:54:46 2011
@@ -63,36 +63,46 @@
 void
 ModuleList::Append (ModuleSP &module_sp)
 {
-    Mutex::Locker locker(m_modules_mutex);
-    m_modules.push_back(module_sp);
+    if (module_sp)
+    {
+        Mutex::Locker locker(m_modules_mutex);
+        m_modules.push_back(module_sp);
+    }
 }
 
 bool
 ModuleList::AppendIfNeeded (ModuleSP &module_sp)
 {
-    Mutex::Locker locker(m_modules_mutex);
-    collection::iterator pos, end = m_modules.end();
-    for (pos = m_modules.begin(); pos != end; ++pos)
+    if (module_sp)
     {
-        if (pos->get() == module_sp.get())
-            return false; // Already in the list
+        Mutex::Locker locker(m_modules_mutex);
+        collection::iterator pos, end = m_modules.end();
+        for (pos = m_modules.begin(); pos != end; ++pos)
+        {
+            if (pos->get() == module_sp.get())
+                return false; // Already in the list
+        }
+        // Only push module_sp on the list if it wasn't already in there.
+        m_modules.push_back(module_sp);
+        return true;
     }
-    // Only push module_sp on the list if it wasn't already in there.
-    m_modules.push_back(module_sp);
-    return true;
+    return false;
 }
 
 bool
 ModuleList::Remove (ModuleSP &module_sp)
 {
-    Mutex::Locker locker(m_modules_mutex);
-    collection::iterator pos, end = m_modules.end();
-    for (pos = m_modules.begin(); pos != end; ++pos)
+    if (module_sp)
     {
-        if (pos->get() == module_sp.get())
+        Mutex::Locker locker(m_modules_mutex);
+        collection::iterator pos, end = m_modules.end();
+        for (pos = m_modules.begin(); pos != end; ++pos)
         {
-            m_modules.erase (pos);
-            return true;
+            if (pos->get() == module_sp.get())
+            {
+                m_modules.erase (pos);
+                return true;
+            }
         }
     }
     return false;

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Tue Apr 12 00:54:46 2011
@@ -1138,14 +1138,14 @@
 }
 
 uint32_t
-Host::FindProcesses (const ProcessInfoMatch &match_info, ProcessInfoList &process_infos)
+Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
 {
     process_infos.Clear();
     return process_infos.GetSize();
 }
 
 bool
-Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     process_info.Clear();
     return false;

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Tue Apr 12 00:54:46 2011
@@ -14,6 +14,7 @@
 #include <grp.h>
 #include <libproc.h>
 #include <pwd.h>
+#include <spawn.h>
 #include <stdio.h>
 #include <sys/proc.h>
 #include <sys/stat.h>
@@ -25,12 +26,15 @@
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/DataExtractor.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/FileSpec.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/CleanUp.h"
 
 #include "cfcpp/CFCBundle.h"
 #include "cfcpp/CFCMutableArray.h"
@@ -47,6 +51,10 @@
 #include <Carbon/Carbon.h>
 #include <Foundation/Foundation.h>
 
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR       0x0100
+#endif
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -414,57 +422,64 @@
 	do script the_shell_script\n\
 end tell\n";
 
-lldb::pid_t
-LaunchInNewTerminalWithAppleScript
-(
-    const char *tty_name,
-    const char **argv, 
-    const char **envp,
-    const char *working_dir,
-    const ArchSpec *arch_spec,
-    bool stop_at_entry,
-    bool disable_aslr
-)
+static Error
+LaunchInNewTerminalWithAppleScript (const char *exe_path,
+                                    ProcessLaunchInfo &launch_info)
 {
-    if (!argv || !argv[0])
-        return LLDB_INVALID_PROCESS_ID;
+    Error error;
+    if (exe_path == NULL || exe_path[0] == '\0')
+    {
+        error.SetErrorString ("invalid executable path");
+        return error;
+    }
     
-    std::string unix_socket_name;
-
-    char temp_file_path[PATH_MAX] = "/tmp/XXXXXX";    
-    if (::mktemp (temp_file_path) == NULL)
-        return LLDB_INVALID_PROCESS_ID;
-
-    unix_socket_name.assign (temp_file_path);
+    char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX";    
+    if (::mktemp (unix_socket_name) == NULL)
+    {
+        error.SetErrorString ("failed to make temporary path for a unix socket");
+        return error;
+    }
     
     StreamString command;
     FileSpec darwin_debug_file_spec;
     if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec))
-        return LLDB_INVALID_PROCESS_ID;
+    {
+        error.SetErrorString ("can't locate the 'darwin-debug' executable");
+        return error;
+    }
+
     darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
         
     if (!darwin_debug_file_spec.Exists())
-        return LLDB_INVALID_PROCESS_ID;
+    {
+        error.SetErrorStringWithFormat ("the 'darwin-debug' executable doesn't exists at %s/%s", 
+                                        darwin_debug_file_spec.GetDirectory().GetCString(),
+                                        darwin_debug_file_spec.GetFilename().GetCString());
+        return error;
+    }
     
     char launcher_path[PATH_MAX];
     darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
 
-    if (arch_spec)
-        command.Printf("arch -arch %s ", arch_spec->GetArchitectureName());
+    const ArchSpec &arch_spec = launch_info.GetArchitecture();
+    if (arch_spec.IsValid())
+        command.Printf("arch -arch %s ", arch_spec.GetArchitectureName());
 
-    command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name.c_str());
+    command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name);
 
-    if (arch_spec && arch_spec->IsValid())
-        command.Printf(" --arch=%s", arch_spec->GetArchitectureName());
+    if (arch_spec.IsValid())
+        command.Printf(" --arch=%s", arch_spec.GetArchitectureName());
 
+    const char *working_dir = launch_info.GetWorkingDirectory();
     if (working_dir)
         command.Printf(" --working-dir '%s'", working_dir);
     
-    if (disable_aslr)
+    if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
         command.PutCString(" --disable-aslr");
         
-    command.PutCString(" --");
+    command.Printf(" -- '%s'", exe_path);
 
+    const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
     if (argv)
     {
         for (size_t i=0; argv[i] != NULL; ++i)
@@ -477,17 +492,17 @@
     StreamString applescript_source;
 
     const char *tty_command = command.GetString().c_str();
-    if (tty_name && tty_name[0])
-    {
-        applescript_source.Printf (applscript_in_existing_tty, 
-                                   tty_command,
-                                   tty_name);
-    }
-    else
-    {
+//    if (tty_name && tty_name[0])
+//    {
+//        applescript_source.Printf (applscript_in_existing_tty, 
+//                                   tty_command,
+//                                   tty_name);
+//    }
+//    else
+//    {
         applescript_source.Printf (applscript_in_new_tty, 
                                    tty_command);
-    }
+//    }
 
     
 
@@ -501,11 +516,15 @@
     // Sleep and wait a bit for debugserver to start to listen...
     ConnectionFileDescriptor file_conn;
     char connect_url[128];
-    ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name.c_str());
+    ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name);
 
     // Spawn a new thread to accept incoming connection on the connect_url
-    // so we can grab the pid from the inferior
-    lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name.c_str(),
+    // so we can grab the pid from the inferior. We have to do this because we
+    // are sending an AppleScript that will launch a process in Terminal.app,
+    // in a shell and the shell will fork/exec a couple of times before we get
+    // to the process that we wanted to launch. So when our process actually
+    // gets launched, we will handshake with it and get the process ID for it.
+    lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name,
                                                        AcceptPIDFromInferior,
                                                        connect_url,
                                                        &lldb_error);
@@ -526,33 +545,14 @@
             WaitForProcessToSIGSTOP (pid, 5);
         }
     }
-    ::unlink (unix_socket_name.c_str());
+    ::unlink (unix_socket_name);
     [applescript release];
-    return pid;
+    if (pid != LLDB_INVALID_PROCESS_ID)
+        launch_info.SetProcessID (pid);
+    return error;
 }
 
 
-#define LLDB_HOST_USE_APPLESCRIPT
-
-lldb::pid_t
-Host::LaunchInNewTerminal 
-(
-    const char *tty_name,
-    const char **argv, 
-    const char **envp,
-    const char *working_dir,
-    const ArchSpec *arch_spec,
-    bool stop_at_entry,
-    bool disable_aslr
-)
-{
-#if defined (LLDB_HOST_USE_APPLESCRIPT)
-    return LaunchInNewTerminalWithAppleScript (tty_name, argv, envp, working_dir, arch_spec, stop_at_entry, disable_aslr);
-#else
-    return LaunchInNewTerminalWithCommandFile (argv, envp, working_dir, arch_spec, stop_at_entry, disable_aslr);
-#endif
-}
-
 // On MacOSX CrashReporter will display a string for each shared library if
 // the shared library has an exported symbol named "__crashreporter_info__".
 
@@ -914,8 +914,8 @@
 }
 
 static bool
-GetMacOSXProcessName (const ProcessInfoMatch *match_info_ptr,
-                      ProcessInfo &process_info)
+GetMacOSXProcessName (const ProcessInstanceInfoMatch *match_info_ptr,
+                      ProcessInstanceInfo &process_info)
 {
     if (process_info.ProcessIDIsValid())
     {
@@ -938,7 +938,7 @@
 
 
 static bool
-GetMacOSXProcessCPUType (ProcessInfo &process_info)
+GetMacOSXProcessCPUType (ProcessInstanceInfo &process_info)
 {
     if (process_info.ProcessIDIsValid())
     {
@@ -970,8 +970,8 @@
 }
 
 static bool
-GetMacOSXProcessArgs (const ProcessInfoMatch *match_info_ptr,
-                      ProcessInfo &process_info)
+GetMacOSXProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr,
+                      ProcessInstanceInfo &process_info)
 {
     if (process_info.ProcessIDIsValid())
     {
@@ -1006,13 +1006,13 @@
                         ++offset;
                     }
                     // Now extract all arguments
-                    StringList &proc_args = process_info.GetArguments();
+                    Args &proc_args = process_info.GetArguments();
                     for (int i=0; i<argc; ++i)
                     {
                         start_offset = offset;
                         cstr = data.GetCStr(&offset);
                         if (cstr)
-                            proc_args.AppendString (cstr, offset - start_offset);
+                            proc_args.AppendArgument(cstr);
                     }
                     return true;
                 }
@@ -1023,7 +1023,7 @@
 }
 
 static bool
-GetMacOSXProcessUserAndGroup (ProcessInfo &process_info)
+GetMacOSXProcessUserAndGroup (ProcessInstanceInfo &process_info)
 {
     if (process_info.ProcessIDIsValid())
     {
@@ -1040,8 +1040,8 @@
             if (proc_kinfo_size > 0)
             {
                 process_info.SetParentProcessID (proc_kinfo.kp_eproc.e_ppid);
-                process_info.SetRealUserID (proc_kinfo.kp_eproc.e_pcred.p_ruid);
-                process_info.SetRealGroupID (proc_kinfo.kp_eproc.e_pcred.p_rgid);
+                process_info.SetUserID (proc_kinfo.kp_eproc.e_pcred.p_ruid);
+                process_info.SetGroupID (proc_kinfo.kp_eproc.e_pcred.p_rgid);
                 process_info.SetEffectiveUserID (proc_kinfo.kp_eproc.e_ucred.cr_uid);
                 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
                     process_info.SetEffectiveGroupID (proc_kinfo.kp_eproc.e_ucred.cr_groups[0]);
@@ -1052,8 +1052,8 @@
         }
     }
     process_info.SetParentProcessID (LLDB_INVALID_PROCESS_ID);
-    process_info.SetRealUserID (UINT32_MAX);
-    process_info.SetRealGroupID (UINT32_MAX);
+    process_info.SetUserID (UINT32_MAX);
+    process_info.SetGroupID (UINT32_MAX);
     process_info.SetEffectiveUserID (UINT32_MAX);
     process_info.SetEffectiveGroupID (UINT32_MAX);            
     return false;
@@ -1061,7 +1061,7 @@
 
 
 uint32_t
-Host::FindProcesses (const ProcessInfoMatch &match_info, ProcessInfoList &process_infos)
+Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
 {
     std::vector<struct kinfo_proc> kinfos;
     
@@ -1104,11 +1104,11 @@
             kinfo.kp_proc.p_flag & P_TRANSLATED)   // Skip translated ppc (Rosetta)
             continue;
 
-        ProcessInfo process_info;
+        ProcessInstanceInfo process_info;
         process_info.SetProcessID (kinfo.kp_proc.p_pid);
         process_info.SetParentProcessID (kinfo.kp_eproc.e_ppid);
-        process_info.SetRealUserID (kinfo.kp_eproc.e_pcred.p_ruid);
-        process_info.SetRealGroupID (kinfo.kp_eproc.e_pcred.p_rgid);
+        process_info.SetUserID (kinfo.kp_eproc.e_pcred.p_ruid);
+        process_info.SetGroupID (kinfo.kp_eproc.e_pcred.p_rgid);
         process_info.SetEffectiveUserID (kinfo.kp_eproc.e_ucred.cr_uid);
         if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
             process_info.SetEffectiveGroupID (kinfo.kp_eproc.e_ucred.cr_groups[0]);
@@ -1130,7 +1130,7 @@
 }
 
 bool
-Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     process_info.SetProcessID(pid);
     if (GetMacOSXProcessArgs (NULL, process_info))
@@ -1144,3 +1144,194 @@
 }
 
 
+Error
+Host::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+    char exe_path[PATH_MAX];
+    PlatformSP host_platform_sp (Platform::GetDefaultPlatform ());
+    
+    const ArchSpec &arch_spec = launch_info.GetArchitecture();
+
+    FileSpec exe_spec(launch_info.GetExecutableFile());
+
+    FileSpec::FileType file_type = exe_spec.GetFileType();
+    if (file_type != FileSpec::eFileTypeRegular)
+    {
+        lldb::ModuleSP exe_module_sp;
+        error = host_platform_sp->ResolveExecutable (exe_spec,
+                                                     arch_spec,
+                                                     exe_module_sp);
+    
+        if (error.Fail())
+            return error;
+    
+        if (exe_module_sp)
+            exe_spec = exe_module_sp->GetFileSpec();
+    }
+    
+    if (exe_spec.Exists())
+    {
+        exe_spec.GetPath (exe_path, sizeof(exe_path));
+    }
+    else
+    {
+        launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path));
+        error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path);
+        return error;
+    }
+
+    
+    if (launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
+    {
+#if !defined(__arm__)
+        return LaunchInNewTerminalWithAppleScript (exe_path, launch_info);
+#else
+        error.SetErrorString ("launching a processs in a new terminal is not supported on iOS devices");
+        return error;
+#endif
+    }
+    
+    Error local_err;    // Errors that don't affect the spawning.
+    posix_spawnattr_t attr;
+    error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
+    
+    if (error.Fail() || log)
+        error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
+    if (error.Fail())
+        return error;
+
+    // Make a quick class that will cleanup the posix spawn attributes in case
+    // we return in the middle of this function.
+    lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy);
+    
+    short flags = 0;
+    if (launch_info.GetFlags().Test (eLaunchFlagExec))
+        flags |= POSIX_SPAWN_SETEXEC;           // Darwin specific posix_spawn flag
+
+    if (launch_info.GetFlags().Test (eLaunchFlagDebug))
+        flags |= POSIX_SPAWN_START_SUSPENDED;   // Darwin specific posix_spawn flag
+
+    if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
+        flags |= _POSIX_SPAWN_DISABLE_ASLR;     // Darwin specific posix_spawn flag
+    
+    error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
+    if (error.Fail() || log)
+        error.PutToLog(log.get(), "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
+    if (error.Fail())
+        return error;
+    
+#if !defined(__arm__)
+    
+    // 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 = arch_spec.GetMachOCPUType();
+    if (cpu != 0 && 
+        cpu != UINT32_MAX && 
+        cpu != LLDB_INVALID_CPUTYPE)
+    {
+        size_t ocount = 0;
+        error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
+        if (error.Fail() || log)
+            error.PutToLog(log.get(), "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu, ocount);
+        
+        if (error.Fail() || ocount != 1)
+            return error;
+    }
+    
+#endif
+    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+    const char *tmp_argv[2];
+    char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
+    char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+    if (argv == NULL)
+    {
+        // posix_spawn gets very unhappy if it doesn't have at least the program
+        // name in argv[0]. One of the side affects I have noticed is the environment
+        // variables don't make it into the child process if "argv == NULL"!!!
+        tmp_argv[0] = exe_path;
+        tmp_argv[1] = NULL;
+        argv = (char * const*)tmp_argv;
+    }
+
+
+    const size_t num_file_actions = launch_info.GetNumFileActions ();
+    if (num_file_actions > 0)
+    {
+        posix_spawn_file_actions_t file_actions;
+        error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
+        if (error.Fail() || log)
+            error.PutToLog(log.get(), "::posix_spawn_file_actions_init ( &file_actions )");
+        if (error.Fail())
+            return error;
+
+        // Make a quick class that will cleanup the posix spawn attributes in case
+        // we return in the middle of this function.
+        lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy);
+
+        for (size_t i=0; i<num_file_actions; ++i)
+        {
+            const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
+            if (launch_file_action)
+            {
+                if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
+                                                                             launch_file_action,
+                                                                             log.get(),
+                                                                             error))
+                    return error;
+            }
+        }
+        
+        error.SetError (::posix_spawnp (&pid, 
+                                        exe_path, 
+                                        &file_actions, 
+                                        &attr, 
+                                        argv,
+                                        envp),
+                        eErrorTypePOSIX);
+
+        if (error.Fail() || log)
+            error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 
+                           pid, 
+                           exe_path, 
+                           &file_actions, 
+                           &attr, 
+                           argv, 
+                           envp);
+    }
+    else
+    {
+        error.SetError (::posix_spawnp (&pid, 
+                                        exe_path, 
+                                        NULL, 
+                                        &attr, 
+                                        argv,
+                                        envp),
+                        eErrorTypePOSIX);
+
+        if (error.Fail() || log)
+            error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 
+                           pid, 
+                           exe_path, 
+                           &attr, 
+                           argv, 
+                           envp);
+    }
+    
+    if (pid != LLDB_INVALID_PROCESS_ID)
+    {
+        // If all went well, then set the process ID into the launch info
+        launch_info.SetProcessID(pid);        
+    }
+    else
+    {
+        // Invalid process ID, something didn't go well
+        if (error.Success())
+            error.SetErrorString ("process launch failed for unknown reasons");
+    }
+    return error;
+}
+
+

Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp Tue Apr 12 00:54:46 2011
@@ -25,8 +25,8 @@
 #include "lldb/Core/UUID.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Utility/CleanUp.h"
-
 #include "Host/macosx/cfcpp/CFCReleaser.h"
+#include "Host/macosx/cfcpp/CFCString.h"
 #include "mach/machine.h"
 
 using namespace lldb;
@@ -352,11 +352,18 @@
                         CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));;
                         if (dict.get())
                         {
-                            CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (dict.get(), CFSTR("DBGSymbolRichExecutable")));
-                            if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
+                            char uuid_cstr_buf[64];
+                            const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf));
+                            CFCString uuid_cfstr (uuid_cstr);
+                            CFDictionaryRef uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
+                            if (uuid_dict)
                             {
-                                ++items_found;
-                                out_dsym_fspec->SetFile(path, false);
+                                CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable")));
+                                if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
+                                {
+                                    ++items_found;
+                                    out_exec_fspec->SetFile(path, path[0] == '~');
+                                }
                             }
                         }
                     }

Modified: lldb/trunk/source/Host/macosx/cfcpp/CFCString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/cfcpp/CFCString.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/cfcpp/CFCString.h (original)
+++ lldb/trunk/source/Host/macosx/cfcpp/CFCString.h Tue Apr 12 00:54:46 2011
@@ -21,7 +21,7 @@
     // Constructors and Destructors
     //------------------------------------------------------------------
                         CFCString (CFStringRef cf_str = NULL);
-                        CFCString (const char *s, CFStringEncoding encoding);
+                        CFCString (const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
                         CFCString (const CFCString& rhs);
                         CFCString& operator= (const CFCString& rhs);
                         virtual ~CFCString ();

Modified: lldb/trunk/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/Args.cpp (original)
+++ lldb/trunk/source/Interpreter/Args.cpp Tue Apr 12 00:54:46 2011
@@ -28,7 +28,8 @@
 //----------------------------------------------------------------------
 Args::Args (const char *command) :
     m_args(),
-    m_argv()
+    m_argv(),
+    m_args_quote_char()
 {
     if (command)
         SetCommandString (command);
@@ -37,13 +38,49 @@
 
 Args::Args (const char *command, size_t len) :
     m_args(),
-    m_argv()
+    m_argv(),
+    m_args_quote_char()
 {
     if (command && len)
         SetCommandString (command, len);
 }
 
 //----------------------------------------------------------------------
+// We have to be very careful on the copy constructor of this class
+// to make sure we copy all of the string values, but we can't copy the
+// rhs.m_argv into m_argv since it will point to the "const char *" c 
+// strings in rhs.m_args. We need to copy the string list and update our
+// own m_argv appropriately. 
+//----------------------------------------------------------------------
+Args::Args (const Args &rhs) :
+    m_args (rhs.m_args),
+    m_argv (),
+    m_args_quote_char(rhs.m_args_quote_char)
+{
+    UpdateArgvFromArgs();
+}
+
+//----------------------------------------------------------------------
+// We have to be very careful on the copy constructor of this class
+// to make sure we copy all of the string values, but we can't copy the
+// rhs.m_argv into m_argv since it will point to the "const char *" c 
+// strings in rhs.m_args. We need to copy the string list and update our
+// own m_argv appropriately. 
+//----------------------------------------------------------------------
+const Args &
+Args::operator= (const Args &rhs)
+{
+    // Make sure we aren't assigning to self
+    if (this != &rhs)
+    {
+        m_args = rhs.m_args;
+        m_args_quote_char = rhs.m_args_quote_char;
+        UpdateArgvFromArgs();
+    }
+    return *this;
+}
+
+//----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
 Args::~Args ()

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Tue Apr 12 00:54:46 2011
@@ -100,22 +100,23 @@
     HandleCommand ("command alias continue process continue", false, result);
     HandleCommand ("command alias expr     expression", false, result);
     HandleCommand ("command alias exit     quit", false, result);
-    HandleCommand ("command alias b        regexp-break", false, result);
+    HandleCommand ("command alias b        _regexp-break", false, result);
     HandleCommand ("command alias bt       thread backtrace", false, result);
     HandleCommand ("command alias si       thread step-inst", false, result);
     HandleCommand ("command alias step     thread step-in", false, result);
     HandleCommand ("command alias s        thread step-in", false, result);
     HandleCommand ("command alias next     thread step-over", false, result);
     HandleCommand ("command alias n        thread step-over", false, result);
+    HandleCommand ("command alias f        thread step-out", false, result);
     HandleCommand ("command alias finish   thread step-out", false, result);
     HandleCommand ("command alias x        memory read", false, result);
     HandleCommand ("command alias l        source list", false, result);
     HandleCommand ("command alias list     source list", false, result);
-    HandleCommand ("command alias p        frame variable", false, result);
+    HandleCommand ("command alias p        expression --", false, result);
     HandleCommand ("command alias print    expression --", false, result);
     HandleCommand ("command alias po       expression -o --", false, result);
-    HandleCommand ("command alias up       regexp-up", false, result);
-    HandleCommand ("command alias down     regexp-down", false, result);
+    HandleCommand ("command alias up       _regexp-up", false, result);
+    HandleCommand ("command alias down     _regexp-down", false, result);
     
 }
 
@@ -183,15 +184,15 @@
 
     std::auto_ptr<CommandObjectRegexCommand>
     break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
-                                                      "regexp-break",
+                                                      "_regexp-break",
                                                       "Set a breakpoint using a regular expression to specify the location.",
-                                                      "regexp-break [<filename>:<linenum>]\nregexp-break [<address>]\nregexp-break <...>", 2));
+                                                      "_regexp-break [<filename>:<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
     if (break_regex_cmd_ap.get())
     {
         if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") &&
             break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") &&
             break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") &&
-            break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list") &&
+            break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full") &&
             break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") &&
             break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'") &&
             break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"))
@@ -203,9 +204,9 @@
 
     std::auto_ptr<CommandObjectRegexCommand>
     down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
-                                                      "regexp-down",
-                                                      "Go down \"n\" frames in the stack (1 frame by default).",
-                                                      "down [n]", 2));
+                                                     "_regexp-down",
+                                                     "Go down \"n\" frames in the stack (1 frame by default).",
+                                                     "_regexp-down [n]", 2));
     if (down_regex_cmd_ap.get())
     {
         if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
@@ -218,9 +219,9 @@
     
     std::auto_ptr<CommandObjectRegexCommand>
     up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
-                                                      "regexp-up",
-                                                      "Go up \"n\" frames in the stack (1 frame by default).",
-                                                      "up [n]", 2));
+                                                   "_regexp-up",
+                                                   "Go up \"n\" frames in the stack (1 frame by default).",
+                                                   "_regexp-up [n]", 2));
     if (up_regex_cmd_ap.get())
     {
         if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
@@ -759,7 +760,7 @@
 
     Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
     
-    m_debugger.UpdateExecutionContext (override_context);
+    UpdateExecutionContext (override_context);
 
     bool empty_command = false;
     bool comment_command = false;
@@ -1542,6 +1543,18 @@
     }
 }
 
+PlatformSP
+CommandInterpreter::GetPlatform (bool prefer_target_platform)
+{
+    PlatformSP platform_sp;
+    if (prefer_target_platform && m_exe_ctx.target)
+        platform_sp = m_exe_ctx.target->GetPlatform();
+
+    if (!platform_sp)
+        platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
+    return platform_sp;
+}
+
 void
 CommandInterpreter::HandleCommands (const StringList &commands, 
                                     ExecutionContext *override_context, 
@@ -1562,7 +1575,7 @@
     // cause series of commands that change the context, then do an operation that relies on that context to fail.
     
     if (override_context != NULL)
-            m_debugger.UpdateExecutionContext (override_context);
+        UpdateExecutionContext (override_context);
             
     if (!stop_on_continue)
     {
@@ -1842,3 +1855,50 @@
       
     }
 }
+
+
+void
+CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
+{
+    m_exe_ctx.Clear();
+    
+    if (override_context != NULL)
+    {
+        m_exe_ctx.target = override_context->target;
+        m_exe_ctx.process = override_context->process;
+        m_exe_ctx.thread = override_context->thread;
+        m_exe_ctx.frame = override_context->frame;
+    }
+    else
+    {
+        TargetSP target_sp (m_debugger.GetSelectedTarget());
+        if (target_sp)
+        {
+            m_exe_ctx.target = target_sp.get();
+            m_exe_ctx.process = target_sp->GetProcessSP().get();
+            if (m_exe_ctx.process && m_exe_ctx.process->IsAlive() && !m_exe_ctx.process->IsRunning())
+            {
+                m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get();
+                if (m_exe_ctx.thread == NULL)
+                {
+                    m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
+                    // If we didn't have a selected thread, select one here.
+                    if (m_exe_ctx.thread != NULL)
+                        m_exe_ctx.process->GetThreadList().SetSelectedThreadByID(m_exe_ctx.thread->GetID());
+                }
+                if (m_exe_ctx.thread)
+                {
+                    m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get();
+                    if (m_exe_ctx.frame == NULL)
+                    {
+                        m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
+                        // If we didn't have a selected frame select one here.
+                        if (m_exe_ctx.frame != NULL)
+                            m_exe_ctx.thread->SetSelectedFrame(m_exe_ctx.frame);
+                    }
+                }
+            }
+        }
+    }
+}
+

Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Tue Apr 12 00:54:46 2011
@@ -219,7 +219,7 @@
 
     if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
     {
-        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        Process *process = m_interpreter.GetExecutionContext().process;
         if (process == NULL)
         {
             result.AppendError ("Process must exist.");

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=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Tue Apr 12 00:54:46 2011
@@ -295,7 +295,7 @@
             // it again (since Target::SetExecutableModule() will clear the
             // images). So append the dyld module back to the list if it is
             /// unique!
-            if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
+            if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
                 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
 
             return true;
@@ -603,6 +603,7 @@
 
         uint32_t idx;
         uint32_t i = 0;
+        // Since we can't downsize a vector, we must do this using the swap method
         DYLDImageInfo::collection old_dyld_all_image_infos;
         old_dyld_all_image_infos.swap(m_dyld_image_infos);
 
@@ -639,7 +640,10 @@
                         m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
 
                         char raw_path[PATH_MAX];
-                        m_process->ReadMemory (path_addr, raw_path, sizeof(raw_path), error);
+                        m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
+                        char raw_path2[PATH_MAX];// TODO: remove after assertion doesn't assert
+                        m_process->ReadMemory (path_addr, raw_path2, sizeof(raw_path2), error);// TODO: remove after assertion doesn't assert
+                        assert (strcmp (raw_path, raw_path2) == 0);// TODO: remove after assertion doesn't assert
                         m_dyld_image_infos[i].file_spec.SetFile(raw_path, true);
                     }
                     assert(i == m_dyld_all_image_infos.dylib_info_count);
@@ -653,10 +657,6 @@
                 }
             }
         }
-        else
-        {
-            m_dyld_image_infos.clear();
-        }
 
         // If our new list is smaller than our old list, we have unloaded
         // some shared libraries
@@ -763,9 +763,9 @@
                             {
                                 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
                                                                                                    arch,
-                                                                                                   &m_dyld_image_infos[idx].uuid,
+                                                                                                   NULL,
                                                                                                    &commpage_dbstr,
-                                                                                                   objfile->GetOffset() + commpage_section->GetOffset());
+                                                                                                   objfile->GetOffset() + commpage_section->GetFileOffset());
                             }
                             if (commpage_image_module_sp)
                                 UpdateCommPageLoadAddress (commpage_image_module_sp.get());

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Tue Apr 12 00:54:46 2011
@@ -14,6 +14,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Debugger.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Target/Target.h"
@@ -50,17 +51,47 @@
     Error error;
     // Nothing special to do here, just use the actual file and architecture
 
+    char exe_path[PATH_MAX];
     FileSpec resolved_exe_file (exe_file);
     
-    // If we have "ls" as the exe_file, resolve the executable loation based on
-    // the current path variables
-    if (!resolved_exe_file.Exists())
-        resolved_exe_file.ResolveExecutableLocation ();
+    if (IsHost())
+    {
+        // If we have "ls" as the exe_file, resolve the executable loation based on
+        // the current path variables
+        if (!resolved_exe_file.Exists())
+        {
+            exe_file.GetPath (exe_path, sizeof(exe_path));
+            resolved_exe_file.SetFile(exe_path, true);
+        }
 
-    // Resolve any executable within a bundle on MacOSX
-    Host::ResolveExecutableInBundle (resolved_exe_file);
+        if (!resolved_exe_file.Exists())
+            resolved_exe_file.ResolveExecutableLocation ();
 
-    if (resolved_exe_file.Exists())
+        // Resolve any executable within a bundle on MacOSX
+        Host::ResolveExecutableInBundle (resolved_exe_file);
+        
+        if (resolved_exe_file.Exists())
+            error.Clear();
+        else
+        {
+            exe_file.GetPath (exe_path, sizeof(exe_path));
+            error.SetErrorStringWithFormat ("enable to find executable for '%s'", exe_path);
+        }
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+        {
+            error = m_remote_platform_sp->ResolveExecutable (exe_file, 
+                                                             exe_arch,
+                                                             exe_module_sp);
+        }
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    
+
+    if (error.Success())
     {
         if (exe_arch.IsValid())
         {
@@ -321,7 +352,7 @@
 
 
 bool
-PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     bool sucess = false;
     if (IsHost())
@@ -339,8 +370,8 @@
 
 
 uint32_t
-PlatformDarwin::FindProcesses (const ProcessInfoMatch &match_info,
-                               ProcessInfoList &process_infos)
+PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                               ProcessInstanceInfoList &process_infos)
 {
     uint32_t match_count = 0;
     if (IsHost())
@@ -357,6 +388,71 @@
     return match_count;    
 }
 
+Error
+PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    if (IsHost())
+    {
+        error = Platform::LaunchProcess (launch_info);
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            error = m_remote_platform_sp->LaunchProcess (launch_info);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return error;
+}
+
+lldb::ProcessSP
+PlatformDarwin::Attach (lldb::pid_t pid, 
+                        Debugger &debugger,
+                        Target *target,
+                        Listener &listener, 
+                        Error &error)
+{
+    lldb::ProcessSP process_sp;
+    if (IsHost())
+    {
+        if (target == NULL)
+        {
+            TargetSP new_target_sp;
+            FileSpec emptyFileSpec;
+            ArchSpec emptyArchSpec;
+            
+            error = debugger.GetTargetList().CreateTarget (debugger,
+                                                           emptyFileSpec,
+                                                           emptyArchSpec, 
+                                                           false,
+                                                           new_target_sp);
+            target = new_target_sp.get();
+        }
+        else
+            error.Clear();
+    
+        if (target && error.Success())
+        {
+            debugger.GetTargetList().SetSelectedTarget(target);
+            // The darwin always currently uses the GDB remote debugger plug-in
+            // so even when debugging locally we are debugging remotely!
+            process_sp = target->CreateProcess (listener, "gdb-remote");
+            
+            if (process_sp)
+                error = process_sp->Attach (pid);
+        }
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            process_sp = m_remote_platform_sp->Attach (pid, debugger, target, listener, error);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return process_sp;
+}
+
 const char *
 PlatformDarwin::GetUserName (uint32_t uid)
 {

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Tue Apr 12 00:54:46 2011
@@ -69,12 +69,22 @@
 
     virtual bool
     GetProcessInfo (lldb::pid_t pid, 
-                    lldb_private::ProcessInfo &proc_info);
+                    lldb_private::ProcessInstanceInfo &proc_info);
     
     virtual uint32_t
-    FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
-                   lldb_private::ProcessInfoList &process_infos);
+    FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
+                   lldb_private::ProcessInstanceInfoList &process_infos);
     
+    virtual lldb_private::Error
+    LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
+
+    virtual lldb::ProcessSP
+    Attach (lldb::pid_t pid, 
+            lldb_private::Debugger &debugger,
+            lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+            lldb_private::Listener &listener, 
+            lldb_private::Error &error);
+
 protected:
     lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS
 

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp Tue Apr 12 00:54:46 2011
@@ -447,8 +447,8 @@
 
 
 uint32_t
-PlatformRemoteiOS::FindProcesses (const ProcessInfoMatch &match_info,
-                                  ProcessInfoList &process_infos)
+PlatformRemoteiOS::FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                                  ProcessInstanceInfoList &process_infos)
 {
     // TODO: if connected, send a packet to get the remote process infos by name
     process_infos.Clear();
@@ -456,7 +456,7 @@
 }
 
 bool
-PlatformRemoteiOS::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+PlatformRemoteiOS::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     // TODO: if connected, send a packet to get the remote process info
     process_info.Clear();

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h Tue Apr 12 00:54:46 2011
@@ -103,12 +103,12 @@
                      bool *did_create_ptr);
 
     virtual uint32_t
-    FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
-                   lldb_private::ProcessInfoList &process_infos);
+    FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
+                   lldb_private::ProcessInstanceInfoList &process_infos);
 
     virtual bool
     GetProcessInfo (lldb::pid_t pid, 
-                    lldb_private::ProcessInfo &proc_info);
+                    lldb_private::ProcessInstanceInfo &proc_info);
 
     virtual bool
     GetSupportedArchitectureAtIndex (uint32_t idx, 

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Tue Apr 12 00:54:46 2011
@@ -17,6 +17,7 @@
 // Project includes
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/ConnectionFileDescriptor.h"
+#include "lldb/Core/Debugger.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
@@ -112,7 +113,8 @@
 /// Default Constructor
 //------------------------------------------------------------------
 PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
-    Platform(false) // This is a remote platform
+    Platform(false), // This is a remote platform
+    m_gdb_client(true)
 {
 }
 
@@ -267,17 +269,139 @@
 }
 
 uint32_t
-PlatformRemoteGDBServer::FindProcesses (const ProcessInfoMatch &match_info,
-                                        ProcessInfoList &process_infos)
+PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                                        ProcessInstanceInfoList &process_infos)
 {
     return m_gdb_client.FindProcesses (match_info, process_infos);
 }
 
 bool
-PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     return m_gdb_client.GetProcessInfo (pid, process_info);
 }
 
 
+Error
+PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+    
+    m_gdb_client.SetSTDIN ("/dev/null");
+    m_gdb_client.SetSTDOUT ("/dev/null");
+    m_gdb_client.SetSTDERR ("/dev/null");
+    m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
+    
+    const char *working_dir = launch_info.GetWorkingDirectory();
+    if (working_dir && working_dir[0])
+    {
+        m_gdb_client.SetWorkingDir (working_dir);
+    }
+    
+    // Send the environment and the program + arguments after we connect
+    const char **argv = launch_info.GetArguments().GetConstArgumentVector();
+    const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+    if (envp)
+    {
+        const char *env_entry;
+        for (int i=0; (env_entry = envp[i]); ++i)
+        {
+            if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
+                break;
+        }
+    }
+    const uint32_t old_packet_timeout = m_gdb_client.SetPacketTimeout (3000); // TODO: lower this to 5 seconds prior to checkin!!!
+    int arg_packet_err = m_gdb_client.SendArgumentsPacket (argv);
+    m_gdb_client.SetPacketTimeout (old_packet_timeout);
+    if (arg_packet_err == 0)
+    {
+        std::string error_str;
+        if (m_gdb_client.GetLaunchSuccess (error_str))
+        {
+            pid = m_gdb_client.GetCurrentProcessID ();
+            if (pid != LLDB_INVALID_PROCESS_ID)
+                launch_info.SetProcessID (pid);
+        }
+        else
+        {
+            error.SetErrorString (error_str.c_str());
+        }
+    }
+    else
+    {
+        error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err);
+    }
+    return error;
+}
+
+lldb::ProcessSP
+PlatformRemoteGDBServer::Attach (lldb::pid_t pid, 
+                                 Debugger &debugger,
+                                 Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                                 Listener &listener, 
+                                 Error &error)
+{
+    lldb::ProcessSP process_sp;
+    if (IsRemote())
+    {
+        if (IsConnected())
+        {
+            uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort();
+            
+            if (port == 0)
+            {
+                error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
+            }
+            else
+            {
+                if (target == NULL)
+                {
+                    TargetSP new_target_sp;
+                    FileSpec emptyFileSpec;
+                    ArchSpec emptyArchSpec;
+                    
+                    error = debugger.GetTargetList().CreateTarget (debugger,
+                                                                   emptyFileSpec,
+                                                                   emptyArchSpec, 
+                                                                   false,
+                                                                   new_target_sp);
+                    target = new_target_sp.get();
+                }
+                else
+                    error.Clear();
+                
+                if (target && error.Success())
+                {
+                    debugger.GetTargetList().SetSelectedTarget(target);
+                    
+                    // The darwin always currently uses the GDB remote debugger plug-in
+                    // so even when debugging locally we are debugging remotely!
+                    process_sp = target->CreateProcess (listener, "gdb-remote");
+                    
+                    if (process_sp)
+                    {
+                        char connect_url[256];
+                        const int connect_url_len = ::snprintf (connect_url, 
+                                                                sizeof(connect_url), 
+                                                                "connect://%s:%u", 
+                                                                GetHostname (), 
+                                                                port);
+                        assert (connect_url_len < sizeof(connect_url));
+                        error = process_sp->ConnectRemote (connect_url);
+                        if (error.Success())
+                            error = process_sp->Attach(pid);
+                    }
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("not connected to remote gdb server");
+        }
+    }
+    return process_sp;
+}
+
 

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Tue Apr 12 00:54:46 2011
@@ -83,11 +83,22 @@
              lldb_private::FileSpec &local_file);
 
     virtual bool
-    GetProcessInfo (lldb::pid_t pid, lldb_private::ProcessInfo &proc_info);
+    GetProcessInfo (lldb::pid_t pid, 
+                    lldb_private::ProcessInstanceInfo &proc_info);
     
     virtual uint32_t
-    FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
-                   lldb_private::ProcessInfoList &process_infos);
+    FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
+                   lldb_private::ProcessInstanceInfoList &process_infos);
+
+    virtual lldb_private::Error
+    LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
+    
+    virtual lldb::ProcessSP
+    Attach (lldb::pid_t pid, 
+            lldb_private::Debugger &debugger,
+            lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+            lldb_private::Listener &listener,
+            lldb_private::Error &error);
 
     virtual bool
     GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Tue Apr 12 00:54:46 2011
@@ -17,25 +17,33 @@
 // Other libraries and framework includes
 #include "lldb/Core/Log.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
 #include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Process.h"
 
 // Project includes
 #include "ProcessGDBRemoteLog.h"
 
+#define DEBUGSERVER_BASENAME    "debugserver"
+
 using namespace lldb;
 using namespace lldb_private;
 
 //----------------------------------------------------------------------
 // GDBRemoteCommunication constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) :
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, 
+                                               const char *listener_name, 
+                                               bool is_platform) :
     Communication(comm_name),
     m_packet_timeout (60),
     m_rx_packet_listener (listener_name),
     m_sequence_mutex (Mutex::eMutexTypeRecursive),
     m_public_is_running (false),
     m_private_is_running (false),
-    m_send_acks (true)
+    m_send_acks (true),
+    m_is_platform (is_platform)
 {
     m_rx_packet_listener.StartListeningForEvents(this,
                                                  Communication::eBroadcastBitPacketAvailable  |
@@ -328,3 +336,131 @@
     }
 }
 
+Error
+GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
+                                                 const char *unix_socket_name,  // For handshaking
+                                                 lldb_private::ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    // If we locate debugserver, keep that located version around
+    static FileSpec g_debugserver_file_spec;
+    
+    // This function will fill in the launch information for the debugserver
+    // instance that gets launched.
+    launch_info.Clear();
+    
+    char debugserver_path[PATH_MAX];
+    FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
+    
+    // Always check to see if we have an environment override for the path
+    // to the debugserver to use and use it if we do.
+    const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
+    if (env_debugserver_path)
+        debugserver_file_spec.SetFile (env_debugserver_path, false);
+    else
+        debugserver_file_spec = g_debugserver_file_spec;
+    bool debugserver_exists = debugserver_file_spec.Exists();
+    if (!debugserver_exists)
+    {
+        // The debugserver binary is in the LLDB.framework/Resources
+        // directory. 
+        if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
+        {
+            debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
+            debugserver_exists = debugserver_file_spec.Exists();
+            if (debugserver_exists)
+            {
+                g_debugserver_file_spec = debugserver_file_spec;
+            }
+            else
+            {
+                g_debugserver_file_spec.Clear();
+                debugserver_file_spec.Clear();
+            }
+        }
+    }
+    
+    if (debugserver_exists)
+    {
+        debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
+
+        Args &debugserver_args = launch_info.GetArguments();
+        debugserver_args.Clear();
+        char arg_cstr[PATH_MAX];
+        
+        // Start args with "debugserver /file/path -r --"
+        debugserver_args.AppendArgument(debugserver_path);
+        debugserver_args.AppendArgument(debugserver_url);
+        // use native registers, not the GDB registers
+        debugserver_args.AppendArgument("--native-regs");   
+        // make debugserver run in its own session so signals generated by 
+        // special terminal key sequences (^C) don't affect debugserver
+        debugserver_args.AppendArgument("--setsid");
+        
+        if (unix_socket_name && unix_socket_name[0])
+        {
+            debugserver_args.AppendArgument("--unix-socket");
+            debugserver_args.AppendArgument(unix_socket_name);
+        }
+
+        const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
+        if (env_debugserver_log_file)
+        {
+            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
+            debugserver_args.AppendArgument(arg_cstr);
+        }
+        
+        const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
+        if (env_debugserver_log_flags)
+        {
+            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
+            debugserver_args.AppendArgument(arg_cstr);
+        }
+        //            debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
+        //            debugserver_args.AppendArgument("--log-flags=0x802e0e");
+        
+        // We currently send down all arguments, attach pids, or attach 
+        // process names in dedicated GDB server packets, so we don't need
+        // to pass them as arguments. This is currently because of all the
+        // things we need to setup prior to launching: the environment,
+        // current working dir, file actions, etc.
+#if 0
+        // Now append the program arguments
+        if (inferior_argv)
+        {
+            // Terminate the debugserver args so we can now append the inferior args
+            debugserver_args.AppendArgument("--");
+            
+            for (int i = 0; inferior_argv[i] != NULL; ++i)
+                debugserver_args.AppendArgument (inferior_argv[i]);
+        }
+        else if (attach_pid != LLDB_INVALID_PROCESS_ID)
+        {
+            ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
+            debugserver_args.AppendArgument (arg_cstr);
+        }
+        else if (attach_name && attach_name[0])
+        {
+            if (wait_for_launch)
+                debugserver_args.AppendArgument ("--waitfor");
+            else
+                debugserver_args.AppendArgument ("--attach");
+            debugserver_args.AppendArgument (attach_name);
+        }
+#endif
+        
+        // Close STDIN, STDOUT and STDERR. We might need to redirect them
+        // to "/dev/null" if we run into any problems.
+//        launch_info.AppendCloseFileAction (STDIN_FILENO);
+//        launch_info.AppendCloseFileAction (STDOUT_FILENO);
+//        launch_info.AppendCloseFileAction (STDERR_FILENO);
+        
+        error = Host::LaunchProcess(launch_info);
+    }
+    else
+    {
+        error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n");
+    }
+    return error;
+}
+

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Tue Apr 12 00:54:46 2011
@@ -37,7 +37,9 @@
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
-    GDBRemoteCommunication(const char *comm_name, const char *listener_name);
+    GDBRemoteCommunication(const char *comm_name, 
+                           const char *listener_name,
+                           bool is_platform);
 
     virtual
     ~GDBRemoteCommunication();
@@ -119,6 +121,15 @@
         return old_packet_timeout;
     }
 
+    //------------------------------------------------------------------
+    // Start a debugserver instance on the current host using the
+    // supplied connection URL.
+    //------------------------------------------------------------------
+    lldb_private::Error
+    StartDebugserverProcess (const char *connect_url,
+                             const char *unix_socket_name,
+                             lldb_private::ProcessLaunchInfo &launch_info); 
+
 protected:
     typedef std::list<std::string> packet_collection;
 
@@ -142,10 +153,13 @@
     lldb_private::Predicate<bool> m_public_is_running;
     lldb_private::Predicate<bool> m_private_is_running;
     bool m_send_acks;
-
+    bool m_is_platform; // Set to true if this class represents a platform,
+                        // false if this class represents a debug session for
+                        // a single process
     
 
 
+
 private:
     //------------------------------------------------------------------
     // For GDBRemoteCommunication only

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Apr 12 00:54:46 2011
@@ -34,8 +34,8 @@
 //----------------------------------------------------------------------
 // GDBRemoteCommunicationClient constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
-    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
+    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
     m_supports_not_sending_acks (eLazyBoolCalculate),
     m_supports_thread_suffix (eLazyBoolCalculate),
     m_supports_vCont_all (eLazyBoolCalculate),
@@ -49,6 +49,14 @@
     m_supports_qfProcessInfo (true),
     m_supports_qUserName (true),
     m_supports_qGroupName (true),
+    m_supports_qThreadStopInfo (true),
+    m_supports_z0 (true),
+    m_supports_z1 (true),
+    m_supports_z2 (true),
+    m_supports_z3 (true),
+    m_supports_z4 (true),
+    m_curr_tid (LLDB_INVALID_THREAD_ID),
+    m_curr_tid_run (LLDB_INVALID_THREAD_ID),
     m_async_mutex (Mutex::eMutexTypeRecursive),
     m_async_packet_predicate (false),
     m_async_packet (),
@@ -126,6 +134,12 @@
     m_supports_qfProcessInfo = true;
     m_supports_qUserName = true;
     m_supports_qGroupName = true;
+    m_supports_qThreadStopInfo = true;
+    m_supports_z0 = true;
+    m_supports_z1 = true;
+    m_supports_z2 = true;
+    m_supports_z3 = true;
+    m_supports_z4 = true;
     m_host_arch.Clear();
 }
 
@@ -1119,7 +1133,7 @@
 }
 
 bool
-GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInfo &process_info)
+GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
 {
     if (response.IsNormalResponse())
     {
@@ -1139,7 +1153,7 @@
             }
             else if (name.compare("uid") == 0)
             {
-                process_info.SetRealUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+                process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
             }
             else if (name.compare("euid") == 0)
             {
@@ -1147,7 +1161,7 @@
             }
             else if (name.compare("gid") == 0)
             {
-                process_info.SetRealGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+                process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
             }
             else if (name.compare("egid") == 0)
             {
@@ -1180,7 +1194,7 @@
 }
 
 bool
-GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     process_info.Clear();
     
@@ -1205,8 +1219,8 @@
 }
 
 uint32_t
-GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info,
-                                             ProcessInfoList &process_infos)
+GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                                             ProcessInstanceInfoList &process_infos)
 {
     process_infos.Clear();
     
@@ -1261,10 +1275,10 @@
                 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
             if (match_info.GetProcessInfo().ParentProcessIDIsValid())
                 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
-            if (match_info.GetProcessInfo().RealUserIDIsValid())
-                packet.Printf("uid:%u;",match_info.GetProcessInfo().GetRealUserID());
-            if (match_info.GetProcessInfo().RealGroupIDIsValid())
-                packet.Printf("gid:%u;",match_info.GetProcessInfo().GetRealGroupID());
+            if (match_info.GetProcessInfo().UserIDIsValid())
+                packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
+            if (match_info.GetProcessInfo().GroupIDIsValid())
+                packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
             if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
                 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
             if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
@@ -1291,7 +1305,7 @@
 
             do
             {
-                ProcessInfo process_info;
+                ProcessInstanceInfo process_info;
                 if (!DecodeProcessInfoResponse (response, process_info))
                     break;
                 process_infos.Append(process_info);
@@ -1447,3 +1461,154 @@
     }
     return false;
 }
+
+uint16_t
+GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
+{
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
+    {
+        std::string name;
+        std::string value;
+        uint16_t port = 0;
+        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+        while (response.GetNameColonValue(name, value))
+        {
+            if (name.size() == 4 && name.compare("port") == 0)
+                port = Args::StringToUInt32(value.c_str(), 0, 0);
+            if (name.size() == 3 && name.compare("pid") == 0)
+                pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
+        }
+        return port;
+    }
+    return 0;
+}
+
+bool
+GDBRemoteCommunicationClient::SetCurrentThread (int tid)
+{
+    if (m_curr_tid == tid)
+        return true;
+    
+    char packet[32];
+    int packet_len;
+    if (tid <= 0)
+        packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
+    else
+        packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
+    assert (packet_len + 1 < sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.IsOKResponse())
+        {
+            m_curr_tid = tid;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
+{
+    if (m_curr_tid_run == tid)
+        return true;
+    
+    char packet[32];
+    int packet_len;
+    if (tid <= 0)
+        packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
+    else
+        packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
+    
+    assert (packet_len + 1 < sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.IsOKResponse())
+        {
+            m_curr_tid_run = tid;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
+{
+    if (SendPacketAndWaitForResponse("?", 1, response, false))
+        return response.IsNormalResponse();
+    return false;
+}
+
+bool
+GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
+{
+    if (m_supports_qThreadStopInfo)
+    {
+        char packet[256];
+        int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
+        assert (packet_len < sizeof(packet));
+        if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+        {
+            if (response.IsUnsupportedResponse())
+                m_supports_qThreadStopInfo = false;
+            else if (response.IsNormalResponse())
+                return true;
+            else
+                return false;
+        }
+    }
+    if (SetCurrentThread (tid))
+        return GetStopReply (response);
+    return false;
+}
+
+
+uint8_t
+GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert,  addr_t addr, uint32_t length)
+{
+    switch (type)
+    {
+    case eBreakpointSoftware:   if (!m_supports_z0) return UINT8_MAX; break;
+    case eBreakpointHardware:   if (!m_supports_z1) return UINT8_MAX; break;
+    case eWatchpointWrite:      if (!m_supports_z2) return UINT8_MAX; break;
+    case eWatchpointRead:       if (!m_supports_z3) return UINT8_MAX; break;
+    case eWatchpointReadWrite:  if (!m_supports_z4) return UINT8_MAX; break;
+    default:                    return UINT8_MAX;
+    }
+
+    char packet[64];
+    const int packet_len = ::snprintf (packet, 
+                                       sizeof(packet), 
+                                       "%c%i,%llx,%x", 
+                                       insert ? 'Z' : 'z', 
+                                       type, 
+                                       addr, 
+                                       length);
+
+    assert (packet_len + 1 < sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
+    {
+        if (response.IsOKResponse())
+            return 0;
+        if (response.IsUnsupportedResponse())
+        {
+            switch (type)
+            {
+                case eBreakpointSoftware:   m_supports_z0 = false; break;
+                case eBreakpointHardware:   m_supports_z1 = false; break;
+                case eWatchpointWrite:      m_supports_z2 = false; break;
+                case eWatchpointRead:       m_supports_z3 = false; break;
+                case eWatchpointReadWrite:  m_supports_z4 = false; break;
+                default:                    break;
+            }
+        }
+        else if (response.IsErrorResponse())
+            return response.GetError();
+    }
+    return UINT8_MAX;
+}

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Tue Apr 12 00:54:46 2011
@@ -18,13 +18,22 @@
 
 #include "GDBRemoteCommunication.h"
 
+typedef enum 
+{
+    eBreakpointSoftware = 0,
+    eBreakpointHardware,
+    eWatchpointWrite,
+    eWatchpointRead,
+    eWatchpointReadWrite
+} GDBStoppointType;
+
 class GDBRemoteCommunicationClient : public GDBRemoteCommunication
 {
 public:
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
-    GDBRemoteCommunicationClient();
+    GDBRemoteCommunicationClient(bool is_platform);
 
     virtual
     ~GDBRemoteCommunicationClient();
@@ -74,6 +83,9 @@
     bool
     GetLaunchSuccess (std::string &error_str);
 
+    uint16_t
+    LaunchGDBserverAndGetPort ();
+
     //------------------------------------------------------------------
     /// Sends a GDB remote protocol 'A' packet that delivers program
     /// arguments to the remote server.
@@ -214,11 +226,11 @@
 
     bool
     GetProcessInfo (lldb::pid_t pid, 
-                    lldb_private::ProcessInfo &process_info);
+                    lldb_private::ProcessInstanceInfo &process_info);
 
     uint32_t
-    FindProcesses (const lldb_private::ProcessInfoMatch &process_match_info,
-                   lldb_private::ProcessInfoList &process_infos);
+    FindProcesses (const lldb_private::ProcessInstanceInfoMatch &process_match_info,
+                   lldb_private::ProcessInstanceInfoList &process_infos);
 
     bool
     GetUserName (uint32_t uid, std::string &name);
@@ -246,6 +258,33 @@
         return old_packet_timeout;
     }
 
+    bool
+    GetStopReply (StringExtractorGDBRemote &response);
+
+    bool
+    GetThreadStopInfo (uint32_t tid, 
+                       StringExtractorGDBRemote &response);
+
+    bool
+    SupportsGDBStoppointPacket (GDBStoppointType type)
+    {
+        switch (type)
+        {
+        case eBreakpointSoftware:   return m_supports_z0;
+        case eBreakpointHardware:   return m_supports_z1;
+        case eWatchpointWrite:      return m_supports_z2;
+        case eWatchpointRead:       return m_supports_z3;
+        case eWatchpointReadWrite:  return m_supports_z4;
+        default:                    break;
+        }
+        return false;
+    }
+    uint8_t
+    SendGDBStoppointTypePacket (GDBStoppointType type,   // Type of breakpoint or watchpoint
+                                bool insert,              // Insert or remove?
+                                lldb::addr_t addr,        // Address of breakpoint or watchpoint
+                                uint32_t length);         // Byte Size of breakpoint or watchpoint
+
     void
     TestPacketSpeed (const uint32_t num_packets);
 
@@ -257,6 +296,13 @@
     bool
     SendSpeedTestPacket (uint32_t send_size, 
                          uint32_t recv_size);
+    
+    bool
+    SetCurrentThread (int tid);
+    
+    bool
+    SetCurrentThreadForRun (int tid);
+
 protected:
 
     //------------------------------------------------------------------
@@ -271,10 +317,21 @@
     lldb_private::LazyBool m_supports_vCont_s;
     lldb_private::LazyBool m_supports_vCont_S;
     lldb_private::LazyBool m_qHostInfo_is_valid;
-    bool m_supports_qProcessInfoPID;
-    bool m_supports_qfProcessInfo;
-    bool m_supports_qUserName;
-    bool m_supports_qGroupName;
+    bool
+        m_supports_qProcessInfoPID:1,
+        m_supports_qfProcessInfo:1,
+        m_supports_qUserName:1,
+        m_supports_qGroupName:1,
+        m_supports_qThreadStopInfo:1,
+        m_supports_z0:1,
+        m_supports_z1:1,
+        m_supports_z2:1,
+        m_supports_z3:1,
+        m_supports_z4:1;
+
+    lldb::tid_t m_curr_tid;         // Current gdb remote protocol thread index for all other operations
+    lldb::tid_t m_curr_tid_run;     // Current gdb remote protocol thread index for continue, step, etc
+
 
     // If we need to send a packet while the target is running, the m_async_XXX
     // member variables take care of making this happen.
@@ -294,7 +351,7 @@
     
     bool
     DecodeProcessInfoResponse (StringExtractorGDBRemote &response, 
-                               lldb_private::ProcessInfo &process_info);
+                               lldb_private::ProcessInstanceInfo &process_info);
 private:
     //------------------------------------------------------------------
     // For GDBRemoteCommunicationClient only

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Tue Apr 12 00:54:46 2011
@@ -21,6 +21,7 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Process.h"
 
 // Project includes
 #include "Utility/StringExtractorGDBRemote.h"
@@ -33,9 +34,15 @@
 //----------------------------------------------------------------------
 // GDBRemoteCommunicationServer constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
-    GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
-    m_async_thread (LLDB_INVALID_HOST_THREAD)
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
+    GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
+    m_async_thread (LLDB_INVALID_HOST_THREAD),
+    m_process_launch_info (),
+    m_process_launch_error (),
+    m_proc_infos (),
+    m_proc_infos_index (0),
+    m_lo_port_num (0),
+    m_hi_port_num (0)
 {
 }
 
@@ -82,45 +89,76 @@
         const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
         switch (packet_type)
         {
-        case StringExtractorGDBRemote::eServerPacketType_nack:
-        case StringExtractorGDBRemote::eServerPacketType_ack:
-            break;
-
-        case StringExtractorGDBRemote::eServerPacketType_invalid:
-            error.SetErrorString("invalid packet");
-            quit = true;
-            break;
-
-        case StringExtractorGDBRemote::eServerPacketType_interrupt:
-            error.SetErrorString("interrupt received");
-            interrupt = true;
-            break;
-        
-        case StringExtractorGDBRemote::eServerPacketType_unimplemented:
-            return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
-
-        case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
-            return Handle_qHostInfo (packet);
-
-        case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
-            return Handle_qProcessInfoPID (packet);
-
-        case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
-            return Handle_qfProcessInfo (packet);
-
-        case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
-            return Handle_qsProcessInfo (packet);
-        
-        case StringExtractorGDBRemote::eServerPacketType_qUserName:
-            return Handle_qUserName (packet);
-
-        case StringExtractorGDBRemote::eServerPacketType_qGroupName:
-            return Handle_qGroupName (packet);
-
-        case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
-            return Handle_qSpeedTest (packet);
-        case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
-            return Handle_QStartNoAckMode (packet);
+            case StringExtractorGDBRemote::eServerPacketType_nack:
+            case StringExtractorGDBRemote::eServerPacketType_ack:
+                break;
+
+            case StringExtractorGDBRemote::eServerPacketType_invalid:
+                error.SetErrorString("invalid packet");
+                quit = true;
+                break;
+
+            case StringExtractorGDBRemote::eServerPacketType_interrupt:
+                error.SetErrorString("interrupt received");
+                interrupt = true;
+                break;
+            
+            case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+                return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
+
+            case StringExtractorGDBRemote::eServerPacketType_A:
+                return Handle_A (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
+                return Handle_qfProcessInfo (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
+                return Handle_qsProcessInfo (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qC:
+                return Handle_qC (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
+                return Handle_qHostInfo (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
+                return Handle_qLaunchGDBServer (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
+                return Handle_qLaunchSuccess (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qGroupName:
+                return Handle_qGroupName (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
+                return Handle_qProcessInfoPID (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
+                return Handle_qSpeedTest (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_qUserName:
+                return Handle_qUserName (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
+                return Handle_QEnvironment (packet);
+            
+            case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
+                return Handle_QSetDisableASLR (packet);
+            
+            case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
+                return Handle_QSetSTDIN (packet);
+            
+            case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
+                return Handle_QSetSTDOUT (packet);
+            
+            case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
+                return Handle_QSetSTDERR (packet);
+            
+            case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
+                return Handle_QSetWorkingDir (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
+                return Handle_QStartNoAckMode (packet);
         }
         return true;
     }
@@ -236,13 +274,13 @@
 }
 
 static void
-CreateProcessInfoResponse (const ProcessInfo &proc_info, StreamString &response)
+CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response)
 {
     response.Printf ("pid:%i;ppid:%i;uid:%i;gid:%i;euid:%i;egid:%i;", 
                      proc_info.GetProcessID(),
                      proc_info.GetParentProcessID(),
-                     proc_info.GetRealUserID(),
-                     proc_info.GetRealGroupID(),
+                     proc_info.GetUserID(),
+                     proc_info.GetGroupID(),
                      proc_info.GetEffectiveUserID(),
                      proc_info.GetEffectiveGroupID());
     response.PutCString ("name:");
@@ -262,11 +300,11 @@
 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
 {
     // Packet format: "qProcessInfoPID:%i" where %i is the pid
-    packet.SetFilePos(strlen ("qProcessInfoPID:"));
+    packet.SetFilePos(::strlen ("qProcessInfoPID:"));
     lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
     if (pid != LLDB_INVALID_PROCESS_ID)
     {
-        ProcessInfo proc_info;
+        ProcessInstanceInfo proc_info;
         if (Host::GetProcessInfo(pid, proc_info))
         {
             StreamString response;
@@ -283,8 +321,8 @@
     m_proc_infos_index = 0;
     m_proc_infos.Clear();
 
-    ProcessInfoMatch match_info;
-    packet.SetFilePos(strlen ("qfProcessInfo"));
+    ProcessInstanceInfoMatch match_info;
+    packet.SetFilePos(::strlen ("qfProcessInfo"));
     if (packet.GetChar() == ':')
     {
     
@@ -337,11 +375,11 @@
             }
             else if (key.compare("uid") == 0)
             {
-                match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+                match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
             }
             else if (key.compare("gid") == 0)
             {
-                match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+                match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
             }
             else if (key.compare("euid") == 0)
             {
@@ -395,7 +433,7 @@
 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
 {
     // Packet format: "qUserName:%i" where %i is the uid
-    packet.SetFilePos(strlen ("qUserName:"));
+    packet.SetFilePos(::strlen ("qUserName:"));
     uint32_t uid = packet.GetU32 (UINT32_MAX);
     if (uid != UINT32_MAX)
     {
@@ -415,7 +453,7 @@
 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
 {
     // Packet format: "qGroupName:%i" where %i is the gid
-    packet.SetFilePos(strlen ("qGroupName:"));
+    packet.SetFilePos(::strlen ("qGroupName:"));
     uint32_t gid = packet.GetU32 (UINT32_MAX);
     if (gid != UINT32_MAX)
     {
@@ -433,7 +471,7 @@
 bool
 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
 {
-    packet.SetFilePos(strlen ("qSpeedTest:"));
+    packet.SetFilePos(::strlen ("qSpeedTest:"));
 
     std::string key;
     std::string value;
@@ -466,6 +504,327 @@
     }
     return SendErrorResponse (7);
 }
+
+
+static void *
+AcceptPortFromInferior (void *arg)
+{
+    const char *connect_url = (const char *)arg;
+    ConnectionFileDescriptor file_conn;
+    Error error;
+    if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess)
+    {
+        char pid_str[256];
+        ::memset (pid_str, 0, sizeof(pid_str));
+        ConnectionStatus status;
+        const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), status, NULL);
+        if (pid_str_len > 0)
+        {
+            int pid = atoi (pid_str);
+            return (void *)(intptr_t)pid;
+        }
+    }
+    return NULL;
+}
+//
+//static bool
+//WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
+//{
+//    const int time_delta_usecs = 100000;
+//    const int num_retries = timeout_in_seconds/time_delta_usecs;
+//    for (int i=0; i<num_retries; i++)
+//    {
+//        struct proc_bsdinfo bsd_info;
+//        int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, 
+//                                    (uint64_t) 0, 
+//                                    &bsd_info, 
+//                                    PROC_PIDTBSDINFO_SIZE);
+//        
+//        switch (error)
+//        {
+//            case EINVAL:
+//            case ENOTSUP:
+//            case ESRCH:
+//            case EPERM:
+//                return false;
+//                
+//            default:
+//                break;
+//                
+//            case 0:
+//                if (bsd_info.pbi_status == SSTOP)
+//                    return true;
+//        }
+//        ::usleep (time_delta_usecs);
+//    }
+//    return false;
+//}
+
+bool
+GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
+{
+    // The 'A' packet is the most over designed packet ever here with 
+    // redundant argument indexes, redundant argument lengths and needed hex 
+    // encoded argument string values. Really all that is needed is a comma 
+    // separated hex encoded argument value list, but we will stay true to the
+    // documented version of the 'A' packet here...
+
+    packet.SetFilePos(1); // Skip the 'A'
+    bool success = true;
+    while (success && packet.GetBytesLeft() > 0)
+    {
+        // Decode the decimal argument string length. This length is the
+        // number of hex nibbles in the argument string value.
+        const uint32_t arg_len = packet.GetU32(UINT32_MAX);
+        if (arg_len == UINT32_MAX)
+            success = false;
+        else
+        {
+            // Make sure the argument hex string length is followed by a comma
+            if (packet.GetChar() != ',')
+                success = false;
+            else
+            {
+                // Decode the argument index. We ignore this really becuase
+                // who would really send down the arguments in a random order???
+                const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
+                if (arg_idx == UINT32_MAX)
+                    success = false;
+                else
+                {
+                    // Make sure the argument index is followed by a comma
+                    if (packet.GetChar() != ',')
+                        success = false;
+                    else
+                    {
+                        // Decode the argument string value from hex bytes
+                        // back into a UTF8 string and make sure the length
+                        // matches the one supplied in the packet
+                        std::string arg;
+                        if (packet.GetHexByteString(arg) != (arg_len / 2))
+                            success = false;
+                        else
+                        {
+                            // If there are any bytes lft
+                            if (packet.GetBytesLeft())
+                            {
+                                if (packet.GetChar() != ',')
+                                    success = false;
+                            }
+                            
+                            if (success)
+                            {
+                                if (arg_idx == 0)
+                                    m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
+                                m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (success)
+    {
+        m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
+        m_process_launch_error = Host::LaunchProcess (m_process_launch_info);
+        if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
+        {
+            return SendOKResponse ();
+        }
+    }
+    return SendErrorResponse (8);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
+{
+    lldb::pid_t pid = m_process_launch_info.GetProcessID();
+    StreamString response;
+    response.Printf("QC%x", pid);
+    if (m_is_platform)
+    {
+        // If we launch a process and this GDB server is acting as a platform, 
+        // then we need to clear the process launch state so we can start 
+        // launching another process. In order to launch a process a bunch or
+        // packets need to be sent: environment packets, working directory,
+        // disable ASLR, and many more settings. When we launch a process we 
+        // then need to know when to clear this information. Currently we are
+        // selecting the 'qC' packet as that packet which seems to make the most
+        // sense.
+        if (pid != LLDB_INVALID_PROCESS_ID)
+        {
+            m_process_launch_info.Clear();
+        }
+    }
+    return SendPacket (response);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
+{
+    // Spawn a local debugserver as a platform so we can then attach or launch
+    // a process...
+
+    if (m_is_platform)
+    {
+        // Sleep and wait a bit for debugserver to start to listen...
+        ConnectionFileDescriptor file_conn;
+        char connect_url[PATH_MAX];
+        Error error;
+        char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX";    
+        if (::mktemp (unix_socket_name) == NULL)
+        {
+            error.SetErrorString ("failed to make temporary path for a unix socket");
+        }
+        else
+        {
+            ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name);
+            // Spawn a new thread to accept the port that gets bound after
+            // binding to port 0 (zero).
+            lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name,
+                                                               AcceptPortFromInferior,
+                                                               connect_url,
+                                                               &error);
+            
+            if (IS_VALID_LLDB_HOST_THREAD(accept_thread))
+            {
+                // Spawn a debugserver and try to get
+                ProcessLaunchInfo debugserver_launch_info;
+                error = StartDebugserverProcess ("localhost:0", 
+                                                 unix_socket_name, 
+                                                 debugserver_launch_info);
+                
+                lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
+                if (error.Success())
+                {
+                    bool success = false;
+                    
+                    thread_result_t accept_thread_result = NULL;
+                    if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error))
+                    {
+                        if (accept_thread_result)
+                        {
+                            uint16_t port = (intptr_t)accept_thread_result;
+                            char response[256];
+                            const int response_len = ::snprintf (response, sizeof(response), "pid:%u;port:%u;", debugserver_pid, port);
+                            assert (response_len < sizeof(response));
+                            //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
+                            success = SendPacket (response, response_len) > 0;
+                        }
+                    }
+                    ::unlink (unix_socket_name);
+                    
+                    if (!success)
+                    {
+                        if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+                            ::kill (debugserver_pid, SIGINT);
+                    }
+                    return success;
+                }
+            }
+        }
+    }
+    return SendErrorResponse (13);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
+{
+    if (m_process_launch_error.Success())
+        return SendOKResponse();
+    StreamString response;    
+    response.PutChar('E');
+    response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
+    return SendPacket (response);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QEnvironment  (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QEnvironment:"));
+    const uint32_t bytes_left = packet.GetBytesLeft();
+    if (bytes_left > 0)
+    {
+        m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
+        return SendOKResponse ();
+    }
+    return SendErrorResponse (9);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QSetDisableASLR:"));
+    if (packet.GetU32(0))
+        m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+    else
+        m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
+    return SendOKResponse ();
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QSetWorkingDir:"));
+    std::string path;
+    packet.GetHexByteString(path);
+    m_process_launch_info.SwapWorkingDirectory (path);
+    return SendOKResponse ();
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QSetSTDIN:"));
+    ProcessLaunchInfo::FileAction file_action;
+    std::string path;
+    packet.GetHexByteString(path);
+    const bool read = false;
+    const bool write = true;
+    if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
+    {
+        m_process_launch_info.AppendFileAction(file_action);
+        return SendOKResponse ();
+    }
+    return SendErrorResponse (10);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QSetSTDOUT:"));
+    ProcessLaunchInfo::FileAction file_action;
+    std::string path;
+    packet.GetHexByteString(path);
+    const bool read = true;
+    const bool write = false;
+    if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
+    {
+        m_process_launch_info.AppendFileAction(file_action);
+        return SendOKResponse ();
+    }
+    return SendErrorResponse (11);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen ("QSetSTDERR:"));
+    ProcessLaunchInfo::FileAction file_action;
+    std::string path;
+    packet.GetHexByteString(path);
+    const bool read = true;
+    const bool write = true;
+    if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
+    {
+        m_process_launch_info.AppendFileAction(file_action);
+        return SendOKResponse ();
+    }
+    return SendErrorResponse (12);
+}
+
 bool
 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
 {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Tue Apr 12 00:54:46 2011
@@ -31,7 +31,7 @@
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
-    GDBRemoteCommunicationServer();
+    GDBRemoteCommunicationServer(bool is_platform);
 
     virtual
     ~GDBRemoteCommunicationServer();
@@ -53,10 +53,26 @@
     bool
     HandshakeWithClient (lldb_private::Error *error_ptr);
 
+    // Set both ports to zero to let the platform automatically bind to 
+    // a port chosen by the OS.
+    void
+    SetPortRange (uint16_t lo_port_num, uint16_t hi_port_num)
+    {
+        m_lo_port_num = lo_port_num;
+        m_hi_port_num = hi_port_num;
+    }
+
 protected:
+    //typedef std::map<uint16_t, lldb::pid_t> PortToPIDMap;
+
     lldb::thread_t m_async_thread;
-    lldb_private::ProcessInfoList m_proc_infos;
+    lldb_private::ProcessLaunchInfo m_process_launch_info;
+    lldb_private::Error m_process_launch_error;
+    lldb_private::ProcessInstanceInfoList m_proc_infos;
     uint32_t m_proc_infos_index;
+    uint16_t m_lo_port_num;
+    uint16_t m_hi_port_num;
+    //PortToPIDMap m_port_to_pid_map;
 
     size_t
     SendUnimplementedResponse (const char *packet);
@@ -68,9 +84,18 @@
     SendOKResponse ();
 
     bool
+    Handle_A (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
+
+    bool
     Handle_qHostInfo (StringExtractorGDBRemote &packet);
     
     bool
+    Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
+
+    bool
     Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
     
     bool
@@ -79,6 +104,9 @@
     bool 
     Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
 
+    bool
+    Handle_qC (StringExtractorGDBRemote &packet);
+
     bool 
     Handle_qUserName (StringExtractorGDBRemote &packet);
 
@@ -89,8 +117,26 @@
     Handle_qSpeedTest (StringExtractorGDBRemote &packet);
 
     bool
+    Handle_QEnvironment  (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+
+    bool
     Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
 
+    bool
+    Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
+    
 private:
     //------------------------------------------------------------------
     // For GDBRemoteCommunicationServer only

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Tue Apr 12 00:54:46 2011
@@ -220,7 +220,7 @@
         if (gdb_comm.GetSequenceMutex (locker))
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-            if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+            if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
             {
                 char packet[64];
                 StringExtractorGDBRemote response;
@@ -329,7 +329,7 @@
         if (gdb_comm.GetSequenceMutex (locker))
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-            if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+            if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
             {
                 uint32_t offset, end_offset;
                 StreamString packet;
@@ -407,7 +407,7 @@
     {
         char packet[32];
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-        if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+        if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
         {
             int packet_len = 0;
             if (thread_suffix_supported)
@@ -449,7 +449,7 @@
     if (gdb_comm.GetSequenceMutex (locker))
     {
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-        if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+        if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
         {
             if (gdb_comm.SendPacketAndWaitForResponse((const char *)data_sp->GetBytes(), 
                                                       data_sp->GetByteSize(), 
@@ -474,91 +474,102 @@
 void
 GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters()
 {
-    static RegisterInfo
-    g_register_infos[] =
-    {
-        //  NAME        ALT     SZ  OFF   ENCODING           FORMAT            COMPILER              DWARF               GENERIC              GDB                    LLDB NATIVE
-        //  ======      ======= ==  ====  =============      ============    ===============         ===============     =========             =====                   ===========
-        {   "r0",       NULL,   4,    0,  eEncodingUint,     eFormatHex,     { gcc_r0,               dwarf_r0,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    0  }},
-        {   "r1",       NULL,   4,    4,  eEncodingUint,     eFormatHex,     { gcc_r1,               dwarf_r1,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    1 }},
-        {   "r2",       NULL,   4,    8,  eEncodingUint,     eFormatHex,     { gcc_r2,               dwarf_r2,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    2 }},
-        {   "r3",       NULL,   4,   12,  eEncodingUint,     eFormatHex,     { gcc_r3,               dwarf_r3,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    3 }},
-        {   "r4",       NULL,   4,   16,  eEncodingUint,     eFormatHex,     { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    4 }},
-        {   "r5",       NULL,   4,   20,  eEncodingUint,     eFormatHex,     { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    5 }},
-        {   "r6",       NULL,   4,   24,  eEncodingUint,     eFormatHex,     { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    6 }},
-        {   "r7",       NULL,   4,   28,  eEncodingUint,     eFormatHex,     { gcc_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,  LLDB_INVALID_REGNUM, 7 }},
-        {   "r8",       NULL,   4,   32,  eEncodingUint,     eFormatHex,     { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    8 }},
-        {   "r9",       NULL,   4,   36,  eEncodingUint,     eFormatHex,     { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    9 }},
-        {   "r10",      NULL,   4,   40,  eEncodingUint,     eFormatHex,     { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    10 }},
-        {   "r11",      NULL,   4,   44,  eEncodingUint,     eFormatHex,     { gcc_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    11 }},
-        {   "r12",      NULL,   4,   48,  eEncodingUint,     eFormatHex,     { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,    12 }},
-        {   "sp",      "r13",   4,   52,  eEncodingUint,     eFormatHex,     { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,  LLDB_INVALID_REGNUM, 13 }},
-        {   "lr",      "r14",   4,   56,  eEncodingUint,     eFormatHex,     { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,  LLDB_INVALID_REGNUM, 14 }},
-        {   "pc",      "r15",   4,   60,  eEncodingUint,     eFormatHex,     { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,  LLDB_INVALID_REGNUM, 15 }},
-//        {   NULL,       NULL,  12,   64,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 16 }},
-//        {   NULL,       NULL,  12,   76,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 17 }},
-//        {   NULL,       NULL,  12,   88,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 18 }},
-//        {   NULL,       NULL,  12,  100,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 19 }},
-//        {   NULL,       NULL,  12,  112,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 20 }},
-//        {   NULL,       NULL,  12,  124,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 21 }},
-//        {   NULL,       NULL,  12,  136,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 22 }},
-//        {   NULL,       NULL,  12,  148,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 23 }},
-//        {   NULL,       NULL,  12,  160,  eEncodingIEEE754,  eFormatFloat,   { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM, 24 }},
-        {   "cpsr",     "psr",  4,  172,  eEncodingUint,     eFormatHex,     { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM,  25 }},
-        {   "s0",       NULL,   4,  176,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     26 }},
-        {   "s1",       NULL,   4,  180,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     27 }},
-        {   "s2",       NULL,   4,  184,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     28 }},
-        {   "s3",       NULL,   4,  188,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     29 }},
-        {   "s4",       NULL,   4,  192,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     30 }},
-        {   "s5",       NULL,   4,  196,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     31 }},
-        {   "s6",       NULL,   4,  200,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     32 }},
-        {   "s7",       NULL,   4,  204,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     33 }},
-        {   "s8",       NULL,   4,  208,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     34 }},
-        {   "s9",       NULL,   4,  212,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     35 }},
-        {   "s10",      NULL,   4,  216,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     36 }},
-        {   "s11",      NULL,   4,  220,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     37 }},
-        {   "s12",      NULL,   4,  224,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     38 }},
-        {   "s13",      NULL,   4,  228,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     39 }},
-        {   "s14",      NULL,   4,  232,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     40 }},
-        {   "s15",      NULL,   4,  236,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     41 }},
-        {   "s16",      NULL,   4,  240,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     42 }},
-        {   "s17",      NULL,   4,  244,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     43 }},
-        {   "s18",      NULL,   4,  248,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     44 }},
-        {   "s19",      NULL,   4,  252,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     45 }},
-        {   "s20",      NULL,   4,  256,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     46 }},
-        {   "s21",      NULL,   4,  260,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     47 }},
-        {   "s22",      NULL,   4,  264,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     48 }},
-        {   "s23",      NULL,   4,  268,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     49 }},
-        {   "s24",      NULL,   4,  272,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     50 }},
-        {   "s25",      NULL,   4,  276,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     51 }},
-        {   "s26",      NULL,   4,  280,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     52 }},
-        {   "s27",      NULL,   4,  284,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     53 }},
-        {   "s28",      NULL,   4,  288,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     54 }},
-        {   "s29",      NULL,   4,  292,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     55 }},
-        {   "s30",      NULL,   4,  296,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     56 }},
-        {   "s31",      NULL,   4,  300,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     57 }},
-        {   "fpscr",    NULL,   4,  304,  eEncodingUint,     eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     58 }},
-        {   "d16",      NULL,   8,  308,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d16,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     59 }},
-        {   "d17",      NULL,   8,  316,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d17,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     60 }},
-        {   "d18",      NULL,   8,  324,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d18,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     61 }},
-        {   "d19",      NULL,   8,  332,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d19,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     62 }},
-        {   "d20",      NULL,   8,  340,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d20,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     63 }},
-        {   "d21",      NULL,   8,  348,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d21,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     64 }},
-        {   "d22",      NULL,   8,  356,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d22,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     65 }},
-        {   "d23",      NULL,   8,  364,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d23,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     66 }},
-        {   "d24",      NULL,   8,  372,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d24,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     67 }},
-        {   "d25",      NULL,   8,  380,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d25,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     68 }},
-        {   "d26",      NULL,   8,  388,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d26,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     69 }},
-        {   "d27",      NULL,   8,  396,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d27,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     70 }},
-        {   "d28",      NULL,   8,  404,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d28,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     71 }},
-        {   "d29",      NULL,   8,  412,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d29,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     72 }},
-        {   "d30",      NULL,   8,  420,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d30,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     73 }},
-        {   "d31",      NULL,   8,  428,  eEncodingIEEE754,  eFormatFloat,   { LLDB_INVALID_REGNUM,  dwarf_d31,          LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,     74 }},
+    static RegisterInfo g_register_infos[] = {
+//   NAME    ALT    SZ  OFF  ENCODING          FORMAT          COMPILER             DWARF                GENERIC                 GDB    LLDB
+//   ======  ====== === ===  =============     ============    ===================  ===================  ======================  ===    ====
+    { "r0",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r0,              dwarf_r0,            LLDB_INVALID_REGNUM,     0,      0 }},
+    { "r1",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r1,              dwarf_r1,            LLDB_INVALID_REGNUM,     1,      1 }},
+    { "r2",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r2,              dwarf_r2,            LLDB_INVALID_REGNUM,     2,      2 }},
+    { "r3",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r3,              dwarf_r3,            LLDB_INVALID_REGNUM,     3,      3 }},
+    { "r4",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r4,              dwarf_r4,            LLDB_INVALID_REGNUM,     4,      4 }},
+    { "r5",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r5,              dwarf_r5,            LLDB_INVALID_REGNUM,     5,      5 }},
+    { "r6",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r6,              dwarf_r6,            LLDB_INVALID_REGNUM,     6,      6 }},
+    { "r7",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r7,              dwarf_r7,            LLDB_REGNUM_GENERIC_FP,  7,      7 }},
+    { "r8",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r8,              dwarf_r8,            LLDB_INVALID_REGNUM,     8,      8 }},
+    { "r9",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r9,              dwarf_r9,            LLDB_INVALID_REGNUM,     9,      9 }},
+    { "r10",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r10,             dwarf_r10,           LLDB_INVALID_REGNUM,    10,     10 }},
+    { "r11",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r11,             dwarf_r11,           LLDB_INVALID_REGNUM,    11,     11 }},
+    { "r12",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r12,             dwarf_r12,           LLDB_INVALID_REGNUM,    12,     12 }},
+    { "sp",   "r13",  4,   0, eEncodingUint,    eFormatHex,   { gcc_sp,              dwarf_sp,            LLDB_REGNUM_GENERIC_SP, 13,     13 }},
+    { "lr",   "r14",  4,   0, eEncodingUint,    eFormatHex,   { gcc_lr,              dwarf_lr,            LLDB_REGNUM_GENERIC_RA, 14,     14 }},
+    { "pc",   "r15",  4,   0, eEncodingUint,    eFormatHex,   { gcc_pc,              dwarf_pc,            LLDB_REGNUM_GENERIC_PC, 15,     15 }},
+    { "f0",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    16,     16 }},
+    { "f1",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    17,     17 }},
+    { "f2",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    18,     18 }},
+    { "f3",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    19,     19 }},
+    { "f4",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    20,     20 }},
+    { "f5",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    21,     21 }},
+    { "f6",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    22,     22 }},
+    { "f7",   NULL,  12,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    23,     23 }},
+    { "fps",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    24,     24 }},
+    { "cpsr", "psr",  4,   0, eEncodingUint,    eFormatHex,   { gcc_cpsr,            dwarf_cpsr,          LLDB_INVALID_REGNUM,    25,     25 }},
+    { "s0",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s0,            LLDB_INVALID_REGNUM,    26,     26 }},
+    { "s1",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s1,            LLDB_INVALID_REGNUM,    27,     27 }},
+    { "s2",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s2,            LLDB_INVALID_REGNUM,    28,     28 }},
+    { "s3",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s3,            LLDB_INVALID_REGNUM,    29,     29 }},
+    { "s4",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s4,            LLDB_INVALID_REGNUM,    30,     30 }},
+    { "s5",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s5,            LLDB_INVALID_REGNUM,    31,     31 }},
+    { "s6",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s6,            LLDB_INVALID_REGNUM,    32,     32 }},
+    { "s7",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s7,            LLDB_INVALID_REGNUM,    33,     33 }},
+    { "s8",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s8,            LLDB_INVALID_REGNUM,    34,     34 }},
+    { "s9",   NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s9,            LLDB_INVALID_REGNUM,    35,     35 }},
+    { "s10",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s10,           LLDB_INVALID_REGNUM,    36,     36 }},
+    { "s11",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s11,           LLDB_INVALID_REGNUM,    37,     37 }},
+    { "s12",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s12,           LLDB_INVALID_REGNUM,    38,     38 }},
+    { "s13",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s13,           LLDB_INVALID_REGNUM,    39,     39 }},
+    { "s14",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s14,           LLDB_INVALID_REGNUM,    40,     40 }},
+    { "s15",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s15,           LLDB_INVALID_REGNUM,    41,     41 }},
+    { "s16",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s16,           LLDB_INVALID_REGNUM,    42,     42 }},
+    { "s17",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s17,           LLDB_INVALID_REGNUM,    43,     43 }},
+    { "s18",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s18,           LLDB_INVALID_REGNUM,    44,     44 }},
+    { "s19",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s19,           LLDB_INVALID_REGNUM,    45,     45 }},
+    { "s20",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s20,           LLDB_INVALID_REGNUM,    46,     46 }},
+    { "s21",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s21,           LLDB_INVALID_REGNUM,    47,     47 }},
+    { "s22",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s22,           LLDB_INVALID_REGNUM,    48,     48 }},
+    { "s23",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s23,           LLDB_INVALID_REGNUM,    49,     49 }},
+    { "s24",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s24,           LLDB_INVALID_REGNUM,    50,     50 }},
+    { "s25",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s25,           LLDB_INVALID_REGNUM,    51,     51 }},
+    { "s26",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s26,           LLDB_INVALID_REGNUM,    52,     52 }},
+    { "s27",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s27,           LLDB_INVALID_REGNUM,    53,     53 }},
+    { "s28",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s28,           LLDB_INVALID_REGNUM,    54,     54 }},
+    { "s29",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s29,           LLDB_INVALID_REGNUM,    55,     55 }},
+    { "s30",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s30,           LLDB_INVALID_REGNUM,    56,     56 }},
+    { "s31",  NULL,   4,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_s31,           LLDB_INVALID_REGNUM,    57,     57 }},
+    { "fpscr",NULL,   4,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    58,     58 }},
+    { "d16",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d16,           LLDB_INVALID_REGNUM,    59,     59 }},
+    { "d17",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d17,           LLDB_INVALID_REGNUM,    60,     60 }},
+    { "d18",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d18,           LLDB_INVALID_REGNUM,    61,     61 }},
+    { "d19",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d19,           LLDB_INVALID_REGNUM,    62,     62 }},
+    { "d20",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d20,           LLDB_INVALID_REGNUM,    63,     63 }},
+    { "d21",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d21,           LLDB_INVALID_REGNUM,    64,     64 }},
+    { "d22",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d22,           LLDB_INVALID_REGNUM,    65,     65 }},
+    { "d23",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d23,           LLDB_INVALID_REGNUM,    66,     66 }},
+    { "d24",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d24,           LLDB_INVALID_REGNUM,    67,     67 }},
+    { "d25",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d25,           LLDB_INVALID_REGNUM,    68,     68 }},
+    { "d26",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d26,           LLDB_INVALID_REGNUM,    69,     69 }},
+    { "d27",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d27,           LLDB_INVALID_REGNUM,    70,     70 }},
+    { "d28",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d28,           LLDB_INVALID_REGNUM,    71,     71 }},
+    { "d29",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d29,           LLDB_INVALID_REGNUM,    72,     72 }},
+    { "d30",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d30,           LLDB_INVALID_REGNUM,    73,     73 }},
+    { "d31",  NULL,   8,   0, eEncodingIEEE754, eFormatHex,   { LLDB_INVALID_REGNUM, dwarf_d31,           LLDB_INVALID_REGNUM,    74,     74 }},
     };
+
     static const uint32_t num_registers = sizeof (g_register_infos)/sizeof (RegisterInfo);
     static ConstString gpr_reg_set ("General Purpose Registers");
+    static ConstString sfp_reg_set ("Software Floating Point Registers");
     static ConstString vfp_reg_set ("Floating Point Registers");
-    for (uint32_t i=0; i<num_registers; ++i)
+    uint32_t i;
+    // Calculate the offsets of the registers
+    if (g_register_infos[2].byte_offset == 0)
+    {
+        uint32_t byte_offset = 0;
+        for (i=0; i<num_registers; ++i)
+        {
+            g_register_infos[i].byte_offset = byte_offset;
+            byte_offset += g_register_infos[i].byte_size;
+        }
+    }
+    for (i=0; i<num_registers; ++i)
     {
         ConstString name;
         ConstString alt_name;
@@ -566,8 +577,13 @@
             name.SetCString(g_register_infos[i].name);
         if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
             alt_name.SetCString(g_register_infos[i].alt_name);
-
-        AddRegister (g_register_infos[i], name, alt_name, i < 26 ? gpr_reg_set : vfp_reg_set);
+        
+        if (i <= 15 || i == 25)
+            AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set);
+        else if (i <= 24)
+            AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set);
+        else
+            AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set);
     }
 }
 

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=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Apr 12 00:54:46 2011
@@ -114,16 +114,13 @@
     Process (target, listener),
     m_flags (0),
     m_stdio_mutex (Mutex::eMutexTypeRecursive),
-    m_gdb_comm(),
+    m_gdb_comm(false),
     m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
     m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
     m_last_stop_packet (),
     m_register_info (),
     m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
     m_async_thread (LLDB_INVALID_HOST_THREAD),
-    m_curr_tid (LLDB_INVALID_THREAD_ID),
-    m_curr_tid_run (LLDB_INVALID_THREAD_ID),
-    m_z0_supported (1),
     m_continue_c_tids (),
     m_continue_C_tids (),
     m_continue_s_tids (),
@@ -430,7 +427,6 @@
     ObjectFile * object_file = module->GetObjectFile();
     if (object_file)
     {
-        ArchSpec inferior_arch(module->GetArchitecture());
         char host_port[128];
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
         char connect_url[128];
@@ -439,13 +435,7 @@
         // Make sure we aren't already connected?
         if (!m_gdb_comm.IsConnected())
         {
-            error = StartDebugserverProcess (host_port,
-                                             NULL,
-                                             NULL,
-                                             LLDB_INVALID_PROCESS_ID,
-                                             NULL, 
-                                             false,
-                                             inferior_arch);
+            error = StartDebugserverProcess (host_port);
             if (error.Fail())
                 return error;
 
@@ -700,8 +690,6 @@
     Error error;
     // Clear out and clean up from any current state
     Clear();
-    const ArchSpec &arch_spec = GetTarget().GetArchitecture();
-
     if (attach_pid != LLDB_INVALID_PROCESS_ID)
     {
         // Make sure we aren't already connected?
@@ -712,13 +700,7 @@
             char connect_url[128];
             snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
 
-            error = StartDebugserverProcess (host_port,                 // debugserver_url
-                                             NULL,                      // inferior_argv
-                                             NULL,                      // inferior_envp
-                                             LLDB_INVALID_PROCESS_ID,   // Don't send any attach to pid options to debugserver
-                                             NULL,                      // Don't send any attach by process name option to debugserver
-                                             false,                     // Don't send any attach wait_for_launch flag as an option to debugserver
-                                             arch_spec);
+            error = StartDebugserverProcess (host_port);
             
             if (error.Fail())
             {
@@ -778,21 +760,12 @@
         // Make sure we aren't already connected?
         if (!m_gdb_comm.IsConnected())
         {
-
-            const ArchSpec &arch_spec = GetTarget().GetArchitecture();
-
             char host_port[128];
             snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
             char connect_url[128];
             snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
 
-            error = StartDebugserverProcess (host_port,                 // debugserver_url
-                                             NULL,                      // inferior_argv
-                                             NULL,                      // inferior_envp
-                                             LLDB_INVALID_PROCESS_ID,   // Don't send any attach to pid options to debugserver
-                                             NULL,                      // Don't send any attach by process name option to debugserver
-                                             false,                     // Don't send any attach wait_for_launch flag as an option to debugserver
-                                             arch_spec);
+            error = StartDebugserverProcess (host_port);
             if (error.Fail())
             {
                 const char *error_string = error.AsCString();
@@ -925,7 +898,7 @@
                 if (num_continue_c_tids == num_threads)
                 {
                     // All threads are resuming...
-                    SetCurrentGDBRemoteThreadForRun (-1);
+                    m_gdb_comm.SetCurrentThreadForRun (-1);
                     continue_packet.PutChar ('c');                
                 }
                 else if (num_continue_c_tids == 1 &&
@@ -934,7 +907,7 @@
                          num_continue_S_tids == 0 )
                 {
                     // Only one thread is continuing
-                    SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
+                    m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
                     continue_packet.PutChar ('c');                
                 }
                 else
@@ -960,7 +933,7 @@
                     if (!continue_packet_error)
                     {
                         // Add threads continuing with the same signo...
-                        SetCurrentGDBRemoteThreadForRun (-1);
+                        m_gdb_comm.SetCurrentThreadForRun (-1);
                         continue_packet.Printf("C%2.2x", continue_signo);
                     }
                 }
@@ -970,7 +943,7 @@
                          num_continue_S_tids == 0 )
                 {
                     // Only one thread is continuing with signal
-                    SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
+                    m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
                     continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
                 }
                 else
@@ -985,7 +958,7 @@
                 if (num_continue_s_tids == num_threads)
                 {
                     // All threads are resuming...
-                    SetCurrentGDBRemoteThreadForRun (-1);
+                    m_gdb_comm.SetCurrentThreadForRun (-1);
                     continue_packet.PutChar ('s');                
                 }
                 else if (num_continue_c_tids == 0 &&
@@ -994,7 +967,7 @@
                          num_continue_S_tids == 0 )
                 {
                     // Only one thread is stepping
-                    SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
+                    m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
                     continue_packet.PutChar ('s');                
                 }
                 else
@@ -1021,7 +994,7 @@
                     if (!continue_packet_error)
                     {
                         // Add threads stepping with the same signo...
-                        SetCurrentGDBRemoteThreadForRun (-1);
+                        m_gdb_comm.SetCurrentThreadForRun (-1);
                         continue_packet.Printf("S%2.2x", step_signo);
                     }
                 }
@@ -1031,7 +1004,7 @@
                          num_continue_S_tids == 1 )
                 {
                     // Only one thread is stepping with signal
-                    SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
+                    m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
                     continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
                 }
                 else
@@ -1667,40 +1640,28 @@
         {
             // Try and set hardware breakpoint, and if that fails, fall through
             // and set a software breakpoint?
-        }
-
-        if (m_z0_supported)
-        {
-            char packet[64];
-            const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
-            assert (packet_len + 1 < sizeof(packet));
-            StringExtractorGDBRemote response;
-            if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
+            if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointHardware))
             {
-                if (response.IsUnsupportedResponse())
-                {
-                    // Disable z packet support and try again
-                    m_z0_supported = 0;
-                    return EnableBreakpoint (bp_site);
-                }
-                else if (response.IsOKResponse())
+                if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0)
                 {
                     bp_site->SetEnabled(true);
-                    bp_site->SetType (BreakpointSite::eExternal);
+                    bp_site->SetType (BreakpointSite::eHardware);
                     return error;
                 }
-                else
-                {
-                    uint8_t error_byte = response.GetError();
-                    if (error_byte)
-                        error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
-                }
             }
         }
-        else
+
+        if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointSoftware))
         {
-            return EnableSoftwareBreakpoint (bp_site);
+            if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0)
+            {
+                bp_site->SetEnabled(true);
+                bp_site->SetType (BreakpointSite::eExternal);
+                return error;
+            }
         }
+
+        return EnableSoftwareBreakpoint (bp_site);
     }
 
     if (log)
@@ -1731,44 +1692,25 @@
     {
         const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
 
-        if (bp_site->IsHardware())
-        {
-            // TODO: disable hardware breakpoint...
-        }
-        else
+        BreakpointSite::Type bp_type = bp_site->GetType();
+        switch (bp_type)
         {
-            if (m_z0_supported)
-            {
-                char packet[64];
-                const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
-                assert (packet_len + 1 < sizeof(packet));
-                StringExtractorGDBRemote response;
-                if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
-                {
-                    if (response.IsUnsupportedResponse())
-                    {
-                        error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
-                    }
-                    else if (response.IsOKResponse())
-                    {
-                        if (log)
-                            log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
-                        bp_site->SetEnabled(false);
-                        return error;
-                    }
-                    else
-                    {
-                        uint8_t error_byte = response.GetError();
-                        if (error_byte)
-                            error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
-                    }
-                }
-            }
-            else
-            {
-                return DisableSoftwareBreakpoint (bp_site);
-            }
+        case BreakpointSite::eSoftware:
+            error = DisableSoftwareBreakpoint (bp_site);
+            break;
+
+        case BreakpointSite::eHardware:
+            if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size))
+                error.SetErrorToGenericError();
+            break;
+
+        case BreakpointSite::eExternal:
+            if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size))
+                error.SetErrorToGenericError();
+            break;
         }
+        if (error.Success())
+            bp_site->SetEnabled(false);
     }
     else
     {
@@ -1869,16 +1811,7 @@
 }
 
 Error
-ProcessGDBRemote::StartDebugserverProcess
-(
-    const char *debugserver_url,    // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
-    char const *inferior_argv[],    // Arguments for the inferior program including the path to the inferior itself as the first argument
-    char const *inferior_envp[],    // Environment to pass along to the inferior program
-    lldb::pid_t attach_pid,         // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver
-    const char *attach_name,        // Wait for the next process to launch whose basename matches "attach_name"
-    bool wait_for_launch,           // Wait for the process named "attach_name" to launch
-    const ArchSpec& inferior_arch   // The arch of the inferior that we will launch
-)
+ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url)    // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
 {
     Error error;
     if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
@@ -1886,8 +1819,9 @@
         // If we locate debugserver, keep that located version around
         static FileSpec g_debugserver_file_spec;
 
-        FileSpec debugserver_file_spec;
+        ProcessLaunchInfo launch_info;
         char debugserver_path[PATH_MAX];
+        FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
 
         // Always check to see if we have an environment override for the path
         // to the debugserver to use and use it if we do.
@@ -1922,25 +1856,10 @@
             debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
 
             m_stdio_communication.Clear();
-            posix_spawnattr_t attr;
 
             LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
 
-            Error local_err;    // Errors that don't affect the spawning.
-            if (log)
-                log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )", 
-                             __FUNCTION__, 
-                             debugserver_path, 
-                             inferior_argv, 
-                             inferior_envp, 
-                             inferior_arch.GetArchitectureName());
-            error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
-            if (error.Fail() || log)
-                error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
-            if (error.Fail())
-                return error;
-
-            Args debugserver_args;
+            Args &debugserver_args = launch_info.GetArguments();
             char arg_cstr[PATH_MAX];
 
             // Start args with "debugserver /file/path -r --"
@@ -1968,6 +1887,12 @@
 //            debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
 //            debugserver_args.AppendArgument("--log-flags=0x802e0e");
 
+            // We currently send down all arguments, attach pids, or attach 
+            // process names in dedicated GDB server packets, so we don't need
+            // to pass them as arguments. This is currently because of all the
+            // things we need to setup prior to launching: the environment,
+            // current working dir, file actions, etc.
+#if 0
             // Now append the program arguments
             if (inferior_argv)
             {
@@ -1990,20 +1915,18 @@
                     debugserver_args.AppendArgument ("--attach");
                 debugserver_args.AppendArgument (attach_name);
             }
-
-            Error file_actions_err;
-            posix_spawn_file_actions_t file_actions;
-#if DONT_CLOSE_DEBUGSERVER_STDIO
-            file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
-#else
-            file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
-            if (file_actions_err.Success())
-            {
-                ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
-                ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
-                ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
-            }
 #endif
+            
+            ProcessLaunchInfo::FileAction file_action;
+            
+            // Close STDIN, STDOUT and STDERR. We might need to redirect them
+            // to "/dev/null" if we run into any problems.
+            file_action.Close (STDIN_FILENO);
+            launch_info.AppendFileAction (file_action);
+            file_action.Close (STDOUT_FILENO);
+            launch_info.AppendFileAction (file_action);
+            file_action.Close (STDERR_FILENO);
+            launch_info.AppendFileAction (file_action);
 
             if (log)
             {
@@ -2012,28 +1935,15 @@
                 log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
             }
 
-            error.SetError (::posix_spawnp (&m_debugserver_pid,
-                                            debugserver_path,
-                                            file_actions_err.Success() ? &file_actions : NULL,
-                                            &attr,
-                                            debugserver_args.GetArgumentVector(),
-                                            (char * const*)inferior_envp),
-                            eErrorTypePOSIX);
-            
-
-            ::posix_spawnattr_destroy (&attr);
-
-            if (file_actions_err.Success())
-                ::posix_spawn_file_actions_destroy (&file_actions);
+            error = Host::LaunchProcess(launch_info);
 
-            // We have seen some cases where posix_spawnp was returning a valid
-            // looking pid even when an error was returned, so clear it out
-            if (error.Fail())
+            if (error.Success ())
+                m_debugserver_pid = launch_info.GetProcessID();
+            else
                 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
 
             if (error.Fail() || log)
-                error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp);
-
+                error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%i, path='%s'", m_debugserver_pid, debugserver_path);
         }
         else
         {
@@ -2143,71 +2053,8 @@
 }
 
 bool
-ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
-{
-    if (m_curr_tid == tid)
-        return true;
-
-    char packet[32];
-    int packet_len;
-    if (tid <= 0)
-        packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
-    else
-        packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
-    assert (packet_len + 1 < sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
-    {
-        if (response.IsOKResponse())
-        {
-            m_curr_tid = tid;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
-{
-    if (m_curr_tid_run == tid)
-        return true;
-
-    char packet[32];
-    int packet_len;
-    if (tid <= 0)
-        packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
-    else
-        packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
-
-    assert (packet_len + 1 < sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
-    {
-        if (response.IsOKResponse())
-        {
-            m_curr_tid_run = tid;
-            return true;
-        }
-    }
-    return false;
-}
-
-void
-ProcessGDBRemote::ResetGDBRemoteState ()
-{
-    // Reset and GDB remote state
-    m_curr_tid = LLDB_INVALID_THREAD_ID;
-    m_curr_tid_run = LLDB_INVALID_THREAD_ID;
-    m_z0_supported = 1;
-}
-
-
-bool
 ProcessGDBRemote::StartAsyncThread ()
 {
-    ResetGDBRemoteState ();
-
     LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 
     if (log)

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=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Apr 12 00:54:46 2011
@@ -215,12 +215,6 @@
     friend class GDBRemoteCommunicationClient;
     friend class GDBRemoteRegisterContext;
 
-    bool
-    SetCurrentGDBRemoteThread (int tid);
-
-    bool
-    SetCurrentGDBRemoteThreadForRun (int tid);
-
     //----------------------------------------------------------------------
     // Accessors
     //----------------------------------------------------------------------
@@ -275,13 +269,7 @@
     UpdateThreadListIfNeeded ();
 
     lldb_private::Error
-    StartDebugserverProcess (const char *debugserver_url,   // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
-                             char const *inferior_argv[],
-                             char const *inferior_envp[],
-                             lldb::pid_t attach_pid,        // If inferior inferior_argv == NULL, then attach to this pid
-                             const char *attach_pid_name,   // Wait for the next process to launch whose basename matches "attach_wait_name"
-                             bool wait_for_launch,          // Wait for the process named "attach_wait_name" to launch
-                             const lldb_private::ArchSpec& arch_spec);
+    StartDebugserverProcess (const char *debugserver_url);
 
     void
     KillDebugserverProcess ();
@@ -313,11 +301,6 @@
     GDBRemoteDynamicRegisterInfo m_register_info;
     lldb_private::Broadcaster m_async_broadcaster;
     lldb::thread_t m_async_thread;
-    // Current GDB remote state. Any members added here need to be reset to
-    // proper default values in ResetGDBRemoteState ().
-    lldb::tid_t m_curr_tid;         // Current gdb remote protocol thread index for all other operations
-    lldb::tid_t m_curr_tid_run;     // Current gdb remote protocol thread index for continue, step, etc
-    uint32_t m_z0_supported:1;      // Set to non-zero if Z0 and z0 packets are supported
     typedef std::vector<lldb::tid_t> tid_collection;
     typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
     tid_collection m_continue_c_tids;                  // 'c' for continue
@@ -330,9 +313,6 @@
     bool m_local_debugserver;  // Is the debugserver process we are talking to local or on another machine.
     std::vector<lldb::user_id_t>  m_thread_observation_bps;
 
-    void
-    ResetGDBRemoteState ();
-
     bool
     StartAsyncThread ();
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Tue Apr 12 00:54:46 2011
@@ -261,13 +261,10 @@
         m_thread_stop_reason_stop_id = process_stop_id;
         m_actual_stop_info_sp.reset();
 
-        char packet[256];
-        ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", GetID());
         StringExtractorGDBRemote stop_packet;
-        if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, false))
-        {
-            GetGDBProcess().SetThreadStopInfo (stop_packet);
-        }
+        ProcessGDBRemote &gdb_process = GetGDBProcess();
+        if (gdb_process.GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
+            gdb_process.SetThreadStopInfo (stop_packet);
     }
     return m_actual_stop_info_sp;
 }

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Tue Apr 12 00:54:46 2011
@@ -61,8 +61,8 @@
 
             // No need to delegate further if (file_offset, file_size) exceeds the total file size.
             // This is the base case.
-            if (file_offset + file_size > file->GetByteSize())
-                return NULL;
+//            if (file_offset + file_size > file->GetByteSize())
+//                return NULL;
 
             DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
             uint32_t idx;

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Tue Apr 12 00:54:46 2011
@@ -14,9 +14,11 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
 using namespace lldb;
@@ -165,6 +167,9 @@
     m_max_uid_name_len (0),
     m_max_gid_name_len (0)
 {
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf ("%p Platform::Platform()", this);
 }
 
 //------------------------------------------------------------------
@@ -175,6 +180,9 @@
 //------------------------------------------------------------------
 Platform::~Platform()
 {
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf ("%p Platform::~Platform()", this);
 }
 
 void
@@ -300,6 +308,15 @@
 }
 
 const char *
+Platform::GetName ()
+{
+    const char *name = GetHostname();
+    if (name == NULL || name[0] == '\0')
+        name = GetShortPluginName();
+    return name;
+}
+
+const char *
 Platform::GetHostname ()
 {
     if (IsHost() && m_name.empty())
@@ -498,21 +515,66 @@
 }
 
 bool
-Platform::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     // Take care of the host case so that each subclass can just 
-    // call Platform::GetProcessInfo (pid, process_info)
+    // call this function to get the host functionality.
     if (IsHost())
         return Host::GetProcessInfo (pid, process_info);
     return false;
 }
 
 uint32_t
-Platform::FindProcesses (const ProcessInfoMatch &match_info,
-                         ProcessInfoList &process_infos)
+Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
+                         ProcessInstanceInfoList &process_infos)
 {
+    // Take care of the host case so that each subclass can just 
+    // call this function to get the host functionality.
     uint32_t match_count = 0;
     if (IsHost())
         match_count = Host::FindProcesses (match_info, process_infos);
     return match_count;    
 }
+
+
+Error
+Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    // Take care of the host case so that each subclass can just 
+    // call this function to get the host functionality.
+    if (IsHost())
+        error = Host::LaunchProcess (launch_info);
+    else
+        error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
+    return error;
+}
+
+lldb::ProcessSP
+Platform::DebugProcess (ProcessLaunchInfo &launch_info, 
+                        Debugger &debugger,
+                        Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                        Listener &listener,
+                        Error &error)
+{
+    ProcessSP process_sp;
+    // Make sure we stop at the entry point
+    launch_info.GetFlags ().Set (eLaunchFlagDebug);
+    error = LaunchProcess (launch_info);
+    if (error.Success())
+    {
+        lldb::pid_t pid = launch_info.GetProcessID();
+        if (pid != LLDB_INVALID_PROCESS_ID)
+        {
+            process_sp = Attach (pid, debugger, target, listener, error);
+            
+//            if (process_sp)
+//            {
+//                if (launch_info.GetFlags().IsClear (eLaunchFlagStopAtEntry))
+//                    process_sp->Resume();
+//            }
+        }
+    }
+    return process_sp;
+}
+

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Apr 12 00:54:46 2011
@@ -40,7 +40,7 @@
 using namespace lldb_private;
 
 void
-ProcessInfo::Dump (Stream &s, Platform *platform) const
+ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
 {
     const char *cstr;
     if (m_pid != LLDB_INVALID_PROCESS_ID)       
@@ -56,59 +56,80 @@
         m_executable.Dump(&s);
         s.EOL();
     }
-    const uint32_t argc = m_args.GetSize();
+    const uint32_t argc = m_arguments.GetArgumentCount();
     if (argc > 0)
     {
         for (uint32_t i=0; i<argc; i++)
         {
+            const char *arg = m_arguments.GetArgumentAtIndex(i);
             if (i < 10)
-                s.Printf (" arg[%u] = %s\n", i, m_args.GetStringAtIndex(i));
+                s.Printf (" arg[%u] = %s\n", i, arg);
             else
-                s.Printf ("arg[%u] = %s\n", i, m_args.GetStringAtIndex(i));
+                s.Printf ("arg[%u] = %s\n", i, arg);
         }
     }
+
+    const uint32_t envc = m_environment.GetArgumentCount();
+    if (envc > 0)
+    {
+        for (uint32_t i=0; i<envc; i++)
+        {
+            const char *env = m_environment.GetArgumentAtIndex(i);
+            if (i < 10)
+                s.Printf (" env[%u] = %s\n", i, env);
+            else
+                s.Printf ("env[%u] = %s\n", i, env);
+        }
+    }
+
     if (m_arch.IsValid())                       
         s.Printf ("   arch = %s\n", m_arch.GetTriple().str().c_str());
 
-    if (m_real_uid != UINT32_MAX)
+    if (m_uid != UINT32_MAX)
     {
-        cstr = platform->GetUserName (m_real_uid);
-        s.Printf ("    uid = %-5u (%s)\n", m_real_uid, cstr ? cstr : "");
+        cstr = platform->GetUserName (m_uid);
+        s.Printf ("    uid = %-5u (%s)\n", m_uid, cstr ? cstr : "");
     }
-    if (m_real_gid != UINT32_MAX)
+    if (m_gid != UINT32_MAX)
     {
-        cstr = platform->GetGroupName (m_real_gid);
-        s.Printf ("    gid = %-5u (%s)\n", m_real_gid, cstr ? cstr : "");
+        cstr = platform->GetGroupName (m_gid);
+        s.Printf ("    gid = %-5u (%s)\n", m_gid, cstr ? cstr : "");
     }
-    if (m_effective_uid != UINT32_MAX)
+    if (m_euid != UINT32_MAX)
     {
-        cstr = platform->GetUserName (m_effective_uid);
-        s.Printf ("   euid = %-5u (%s)\n", m_effective_uid, cstr ? cstr : "");
+        cstr = platform->GetUserName (m_euid);
+        s.Printf ("   euid = %-5u (%s)\n", m_euid, cstr ? cstr : "");
     }
-    if (m_effective_gid != UINT32_MAX)
+    if (m_egid != UINT32_MAX)
     {
-        cstr = platform->GetGroupName (m_effective_gid);
-        s.Printf ("   egid = %-5u (%s)\n", m_effective_gid, cstr ? cstr : "");
+        cstr = platform->GetGroupName (m_egid);
+        s.Printf ("   egid = %-5u (%s)\n", m_egid, cstr ? cstr : "");
     }
 }
 
 void
-ProcessInfo::DumpTableHeader (Stream &s, Platform *platform, bool verbose)
+ProcessInstanceInfo::DumpTableHeader (Stream &s, Platform *platform, bool show_args, bool verbose)
 {
+    const char *label;
+    if (show_args || verbose)
+        label = "ARGUMENTS";
+    else
+        label = "NAME";
+
     if (verbose)
     {
-        s.PutCString ("PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE                   NAME\n");
+        s.Printf     ("PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE                   %s\n", label);
         s.PutCString ("====== ====== ========== ========== ========== ========== ======================== ============================\n");
     }
     else
     {
-        s.PutCString ("PID    PARENT USER       ARCH    NAME\n");
+        s.Printf     ("PID    PARENT USER       ARCH    %s\n", label);
         s.PutCString ("====== ====== ========== ======= ============================\n");
     }
 }
 
 void
-ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform, bool verbose) const
+ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_args, bool verbose) const
 {
     if (m_pid != LLDB_INVALID_PROCESS_ID)
     {
@@ -118,49 +139,49 @@
     
         if (verbose)
         {
-            cstr = platform->GetUserName (m_real_uid);
+            cstr = platform->GetUserName (m_uid);
             if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
                 s.Printf ("%-10s ", cstr);
             else
-                s.Printf ("%-10u ", m_real_uid);
+                s.Printf ("%-10u ", m_uid);
 
-            cstr = platform->GetGroupName (m_real_gid);
+            cstr = platform->GetGroupName (m_gid);
             if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
                 s.Printf ("%-10s ", cstr);
             else
-                s.Printf ("%-10u ", m_real_gid);
+                s.Printf ("%-10u ", m_gid);
 
-            cstr = platform->GetUserName (m_effective_uid);
+            cstr = platform->GetUserName (m_euid);
             if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
                 s.Printf ("%-10s ", cstr);
             else
-                s.Printf ("%-10u ", m_effective_uid);
+                s.Printf ("%-10u ", m_euid);
             
-            cstr = platform->GetGroupName (m_effective_gid);
+            cstr = platform->GetGroupName (m_egid);
             if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
                 s.Printf ("%-10s ", cstr);
             else
-                s.Printf ("%-10u ", m_effective_gid);
+                s.Printf ("%-10u ", m_egid);
             s.Printf ("%-24s ", m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "");
         }
         else
         {
             s.Printf ("%-10s %.*-7s ", 
-                      platform->GetUserName (m_effective_uid),
+                      platform->GetUserName (m_euid),
                       (int)m_arch.GetTriple().getArchName().size(),
                       m_arch.GetTriple().getArchName().data());
         }
 
-        if (verbose)
+        if (verbose || show_args)
         {
-            const uint32_t argc = m_args.GetSize();
+            const uint32_t argc = m_arguments.GetArgumentCount();
             if (argc > 0)
             {
                 for (uint32_t i=0; i<argc; i++)
                 {
                     if (i > 0)
                         s.PutChar (' ');
-                    s.PutCString (m_args.GetStringAtIndex(i));
+                    s.PutCString (m_arguments.GetArgumentAtIndex(i));
                 }
             }
         }
@@ -173,8 +194,263 @@
     }
 }
 
+
+void
+ProcessInfo::SetArgumentsFromArgs (const Args& args, 
+                                       bool first_arg_is_executable,
+                                       bool first_arg_is_executable_and_argument)
+{
+    // Copy all arguments
+    m_arguments = args;
+
+    // Is the first argument the executable?
+    if (first_arg_is_executable)
+    {
+        const char *first_arg = args.GetArgumentAtIndex (0);
+        if (first_arg)
+        {
+            // Yes the first argument is an executable, set it as the executable
+            // in the launch options. Don't resolve the file path as the path
+            // could be a remote platform path
+            const bool resolve = false;
+            m_executable.SetFile(first_arg, resolve); 
+    
+            // If argument zero is an executable and shouldn't be included
+            // in the arguments, remove it from the front of the arguments
+            if (first_arg_is_executable_and_argument == false)
+                m_arguments.DeleteArgumentAtIndex (0);
+        }
+    }
+}
+
+bool
+ProcessLaunchInfo::FileAction::Open (int fd, const char *path, bool read, bool write)
+{
+    if ((read || write) && fd >= 0 && path && path[0])
+    {
+        m_action = eFileActionOpen;
+        m_fd = fd;
+        if (read && write)
+            m_arg = O_RDWR;
+        else if (read)
+            m_arg = O_RDONLY;
+        else
+            m_arg = O_WRONLY;
+        m_path.assign (path);
+        return true;
+    }
+    else
+    {
+        Clear();
+    }
+    return false;
+}
+
+bool
+ProcessLaunchInfo::FileAction::Close (int fd)
+{
+    Clear();
+    if (fd >= 0)
+    {
+        m_action = eFileActionClose;
+        m_fd = fd;
+    }
+    return m_fd >= 0;
+}
+
+
 bool
-ProcessInfoMatch::NameMatches (const char *process_name) const
+ProcessLaunchInfo::FileAction::Duplicate (int fd, int dup_fd)
+{
+    Clear();
+    if (fd >= 0 && dup_fd >= 0)
+    {
+        m_action = eFileActionDuplicate;
+        m_fd = fd;
+        m_arg = dup_fd;
+    }
+    return m_fd >= 0;
+}
+
+
+
+bool
+ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (posix_spawn_file_actions_t *file_actions,
+                                                        const FileAction *info,
+                                                        Log *log, 
+                                                        Error& error)
+{
+    if (info == NULL)
+        return false;
+
+    switch (info->m_action)
+    {
+        case eFileActionNone:
+            error.Clear();
+            break;
+
+        case eFileActionClose:
+            if (info->m_fd == -1)
+                error.SetErrorString ("invalid fd for posix_spawn_file_actions_addclose(...)");
+            else
+            {
+                error.SetError (::posix_spawn_file_actions_addclose (file_actions, info->m_fd), 
+                                eErrorTypePOSIX);
+                if (log && (error.Fail() || log))
+                    error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", 
+                                   file_actions, info->m_fd);
+            }
+            break;
+
+        case eFileActionDuplicate:
+            if (info->m_fd == -1)
+                error.SetErrorString ("invalid fd for posix_spawn_file_actions_adddup2(...)");
+            else if (info->m_arg == -1)
+                error.SetErrorString ("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
+            else
+            {
+                error.SetError (::posix_spawn_file_actions_adddup2 (file_actions, info->m_fd, info->m_arg),
+                                eErrorTypePOSIX);
+                if (log && (error.Fail() || log))
+                    error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", 
+                                   file_actions, info->m_fd, info->m_arg);
+            }
+            break;
+
+        case eFileActionOpen:
+            if (info->m_fd == -1)
+                error.SetErrorString ("invalid fd in posix_spawn_file_actions_addopen(...)");
+            else
+            {
+                int oflag = info->m_arg;
+                mode_t mode = 0;
+
+                error.SetError (::posix_spawn_file_actions_addopen (file_actions, 
+                                                                    info->m_fd,
+                                                                    info->m_path.c_str(), 
+                                                                    oflag,
+                                                                    mode), 
+                                eErrorTypePOSIX);
+                if (error.Fail() || log)
+                    error.PutToLog(log, 
+                                   "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", 
+                                   file_actions, info->m_fd, info->m_path.c_str(), oflag, mode);
+            }
+            break;
+        
+        default:
+            error.SetErrorStringWithFormat ("invalid file action: %i", info->m_action);
+            break;
+    }
+    return error.Success();
+}
+
+Error
+ProcessLaunchCommandOptions::SetOptionValue (int option_idx, const char *option_arg)
+{
+    Error error;
+    char short_option = (char) m_getopt_table[option_idx].val;
+    
+    switch (short_option)
+    {
+        case 's':   // Stop at program entry point
+            launch_info.GetFlags().Set (eLaunchFlagStopAtEntry); 
+            break;
+            
+        case 'e':   // STDERR for read + write
+            {   
+                ProcessLaunchInfo::FileAction action;
+                if (action.Open(STDERR_FILENO, option_arg, true, true))
+                    launch_info.AppendFileAction (action);
+            }
+            break;
+            
+        case 'i':   // STDIN for read only
+            {   
+                ProcessLaunchInfo::FileAction action;
+                if (action.Open(STDIN_FILENO, option_arg, true, false))
+                    launch_info.AppendFileAction (action);
+            }
+            break;
+            
+        case 'o':   // Open STDOUT for write only
+            {   
+                ProcessLaunchInfo::FileAction action;
+                if (action.Open(STDOUT_FILENO, option_arg, false, true))
+                    launch_info.AppendFileAction (action);
+            }
+            break;
+            
+        case 'p':   // Process plug-in name
+            launch_info.SetProcessPluginName (option_arg);    
+            break;
+            
+        case 'n':   // Disable STDIO
+            {
+                ProcessLaunchInfo::FileAction action;
+                if (action.Open(STDERR_FILENO, "/dev/null", true, true))
+                    launch_info.AppendFileAction (action);
+                if (action.Open(STDOUT_FILENO, "/dev/null", false, true))
+                    launch_info.AppendFileAction (action);
+                if (action.Open(STDIN_FILENO, "/dev/null", true, false))
+                    launch_info.AppendFileAction (action);
+            }
+            break;
+            
+        case 'w': 
+            launch_info.SetWorkingDirectory (option_arg);    
+            break;
+            
+        case 't':   // Open process in new terminal window
+            launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY); 
+            break;
+            
+        case 'a':
+            launch_info.GetArchitecture().SetTriple (option_arg, 
+                                                     m_interpreter.GetPlatform(true).get());
+            break;
+            
+        case 'A':   
+            launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 
+            break;
+            
+        case 'v':
+            launch_info.GetEnvironmentEntries().AppendArgument(option_arg);
+            break;
+
+        default:
+            error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+            break;
+            
+    }
+    return error;
+}
+
+OptionDefinition
+ProcessLaunchCommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,          "Stop at the entry point of the program when launching a process."},
+{ LLDB_OPT_SET_ALL, false, "disable-aslr",  'A', no_argument,       NULL, 0, eArgTypeNone,          "Disable address space layout randomization when launching a process."},
+{ LLDB_OPT_SET_ALL, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
+{ LLDB_OPT_SET_ALL, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypePath,          "Set the current working directory to <path> when running the inferior."},
+{ LLDB_OPT_SET_ALL, false, "arch",          'a', required_argument, NULL, 0, eArgTypeArchitecture,  "Set the architecture for the process to launch when ambiguous."},
+{ LLDB_OPT_SET_ALL, false, "environment",   'v', required_argument, NULL, 0, eArgTypeNone,          "Specify an environment variable name/value stirng (--environement NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
+
+{ LLDB_OPT_SET_1  , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
+{ LLDB_OPT_SET_1  , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
+{ LLDB_OPT_SET_1  , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
+
+{ LLDB_OPT_SET_2  , false, "tty",           't', no_argument,       NULL, 0, eArgTypeNone,    "Start the process in a terminal (not supported on all platforms)."},
+
+{ LLDB_OPT_SET_3  , false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
+
+{ 0               , false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
+};
+
+
+
+bool
+ProcessInstanceInfoMatch::NameMatches (const char *process_name) const
 {
     if (m_name_match_type == eNameMatchIgnore || process_name == NULL)
         return true;
@@ -186,7 +462,7 @@
 }
 
 bool
-ProcessInfoMatch::Matches (const ProcessInfo &proc_info) const
+ProcessInstanceInfoMatch::Matches (const ProcessInstanceInfo &proc_info) const
 {
     if (!NameMatches (proc_info.GetName()))
         return false;
@@ -199,12 +475,12 @@
         m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
         return false;
 
-    if (m_match_info.RealUserIDIsValid () && 
-        m_match_info.GetRealUserID() != proc_info.GetRealUserID())
+    if (m_match_info.UserIDIsValid () && 
+        m_match_info.GetUserID() != proc_info.GetUserID())
         return false;
     
-    if (m_match_info.RealGroupIDIsValid () && 
-        m_match_info.GetRealGroupID() != proc_info.GetRealGroupID())
+    if (m_match_info.GroupIDIsValid () && 
+        m_match_info.GetGroupID() != proc_info.GetGroupID())
         return false;
     
     if (m_match_info.EffectiveUserIDIsValid () && 
@@ -222,7 +498,7 @@
 }
 
 bool
-ProcessInfoMatch::MatchAllProcesses () const
+ProcessInstanceInfoMatch::MatchAllProcesses () const
 {
     if (m_name_match_type != eNameMatchIgnore)
         return false;
@@ -233,10 +509,10 @@
     if (m_match_info.ParentProcessIDIsValid())
         return false;
     
-    if (m_match_info.RealUserIDIsValid ())
+    if (m_match_info.UserIDIsValid ())
         return false;
     
-    if (m_match_info.RealGroupIDIsValid ())
+    if (m_match_info.GroupIDIsValid ())
         return false;
     
     if (m_match_info.EffectiveUserIDIsValid ())
@@ -256,7 +532,7 @@
 }
 
 void
-ProcessInfoMatch::Clear()
+ProcessInstanceInfoMatch::Clear()
 {
     m_match_info.Clear();
     m_name_match_type = eNameMatchIgnore;
@@ -1504,6 +1780,46 @@
 
 
 size_t
+Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len)
+{
+    size_t total_cstr_len = 0;
+    if (dst && dst_max_len)
+    {
+        // NULL out everything just to be safe
+        memset (dst, 0, dst_max_len);
+        Error error;
+        addr_t curr_addr = addr;
+        const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize();
+        size_t bytes_left = dst_max_len - 1;
+        char *curr_dst = dst;
+        
+        while (bytes_left > 0)
+        {
+            addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+            addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+            size_t bytes_read = ReadMemory (curr_addr, curr_dst, bytes_to_read, error);
+            
+            if (bytes_read == 0)
+            {
+                dst[total_cstr_len] = '\0';
+                break;
+            }
+            const size_t len = strlen(curr_dst);
+
+            total_cstr_len += len;
+
+            if (len < bytes_to_read)
+                break;
+
+            curr_dst += bytes_read;
+            curr_addr += bytes_read;
+            bytes_left -= bytes_read;
+        }
+    }
+    return total_cstr_len;
+}
+
+size_t
 Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &error)
 {
     if (buf == NULL || size == 0)
@@ -1894,7 +2210,7 @@
     // Find the process and its architecture.  Make sure it matches the architecture
     // of the current Target, and if not adjust it.
     
-    ProcessInfo process_info;
+    ProcessInstanceInfo process_info;
     PlatformSP platform_sp (m_target.GetDebugger().GetPlatformList().GetSelectedPlatform ());
     if (platform_sp)
     {
@@ -1947,11 +2263,11 @@
     
     if (!wait_for_launch)
     {
-        ProcessInfoList process_infos;
+        ProcessInstanceInfoList process_infos;
         PlatformSP platform_sp (m_target.GetDebugger().GetPlatformList().GetSelectedPlatform ());
         if (platform_sp)
         {
-            ProcessInfoMatch match_info;
+            ProcessInstanceInfoMatch match_info;
             match_info.GetProcessInfo().SetName(process_name);
             match_info.SetNameMatchType (eNameMatchEquals);
             platform_sp->FindProcesses (match_info, process_infos);
@@ -1965,7 +2281,7 @@
             }
             else 
             {
-                ProcessInfo process_info;
+                ProcessInstanceInfo process_info;
                 if (process_infos.GetInfoAtIndex (0, process_info))
                 {
                     const ArchSpec &process_arch = process_info.GetArchitecture();
@@ -2034,7 +2350,7 @@
     for (int i = 0; i < num_modules; i++)
     {
         ModuleSP module_sp (modules.GetModuleAtIndex(i));
-        if (module_sp->IsExecutable())
+        if (module_sp && module_sp->IsExecutable())
         {
             ModuleSP target_exe_module_sp (m_target.GetExecutableModule());
             if (target_exe_module_sp != module_sp)
@@ -2391,8 +2707,12 @@
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
 
+    bool already_running = PrivateStateThreadIsValid ();
     if (log)
-        log->Printf ("Process::%s ( )", __FUNCTION__);
+        log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread");
+
+    if (already_running)
+        return true;
 
     // Create a thread that watches our internal state and controls which
     // events make it to clients (into the DCProcess event queue).
@@ -2417,7 +2737,8 @@
 void
 Process::StopPrivateStateThread ()
 {
-    ControlPrivateStateThread (eBroadcastInternalStateControlStop);
+    if (PrivateStateThreadIsValid ())
+        ControlPrivateStateThread (eBroadcastInternalStateControlStop);
 }
 
 void
@@ -2702,7 +3023,7 @@
     if (m_process_sp)
         s->Printf(" process = %p (pid = %u), ", m_process_sp.get(), m_process_sp->GetID());
 
-    s->Printf("state = %s", StateAsCString(GetState()));;
+    s->Printf("state = %s", StateAsCString(GetState()));
 }
 
 const Process::ProcessEventData *
@@ -3005,7 +3326,7 @@
         sstr.Printf ("%s", module_sp->GetFileSpec().GetFilename().AsCString());
                     
         GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(),
-                                                                  sstr.GetData());
+                                                         sstr.GetData());
     }
 }
 
@@ -3661,7 +3982,11 @@
         UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err);
     else if (var_name == EnvVarsVarName())
     {
-        GetHostEnvironmentIfNeeded ();
+        // This is nice for local debugging, but it is isn't correct for
+        // remote debugging. We need to stop process.env-vars from being 
+        // populated with the host environment and add this as a launch option
+        // and get the correct environment from the Target's platform.
+        // GetHostEnvironmentIfNeeded ();
         UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err);
     }
     else if (var_name == InputPathVarName())

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Tue Apr 12 00:54:46 2011
@@ -53,48 +53,90 @@
 StringExtractorGDBRemote::ServerPacketType
 StringExtractorGDBRemote::GetServerPacketType () const
 {
+#define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
+#define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
+    
     // Empty is not a supported packet...
     if (m_packet.empty())
         return eServerPacketType_invalid;
 
+    const size_t packet_size = m_packet.size();
     const char *packet_cstr = m_packet.c_str();
     switch (m_packet[0])
     {
     case '\x03':
-        if (m_packet.size() == 1)
-            return eServerPacketType_interrupt;
+        if (packet_size == 1) return eServerPacketType_interrupt;
         break;
 
     case '-':
-        if (m_packet.size() == 1)
-            return eServerPacketType_nack;
+        if (packet_size == 1) return eServerPacketType_nack;
         break;
 
     case '+':
-        if (m_packet.size() == 1)
-            return eServerPacketType_ack;
+        if (packet_size == 1) return eServerPacketType_ack;
         break;
 
+    case 'A':
+        return eServerPacketType_A;
+            
     case 'Q':
-        if (strcmp (packet_cstr, "QStartNoAckMode") == 0)
-            return eServerPacketType_QStartNoAckMode;
+        switch (packet_cstr[1])
+        {
+        case 'E':
+            if (PACKET_STARTS_WITH ("QEnvironment:"))           return eServerPacketType_QEnvironment; 
+            break;
+
+        case 'S':
+            if (PACKET_MATCHES ("QStartNoAckMode"))             return eServerPacketType_QStartNoAckMode;
+            else if (PACKET_STARTS_WITH ("QSetDisableASLR:"))   return eServerPacketType_QSetDisableASLR;
+            else if (PACKET_STARTS_WITH ("QSetSTDIN:"))         return eServerPacketType_QSetSTDIN;
+            else if (PACKET_STARTS_WITH ("QSetSTDOUT:"))        return eServerPacketType_QSetSTDOUT;
+            else if (PACKET_STARTS_WITH ("QSetSTDERR:"))        return eServerPacketType_QSetSTDERR;
+            else if (PACKET_STARTS_WITH ("QSetWorkingDir:"))    return eServerPacketType_QSetWorkingDir;
+            break;
+        }
         break;
             
     case 'q':
-             if (packet_cstr[1] == 'S' && 0 == ::strncmp(packet_cstr, "qSpeedTest:", strlen("qSpeedTest:")))
-            return eServerPacketType_qSpeedTest;
-        else if (packet_cstr[1] == 'H' && 0 == ::strcmp (packet_cstr, "qHostInfo"))
-            return eServerPacketType_qHostInfo;
-        else if (packet_cstr[1] == 'P' && 0 == ::strncmp(packet_cstr, "qProcessInfoPID:", strlen("qProcessInfoPID:")))
-            return eServerPacketType_qProcessInfoPID;
-        else if (packet_cstr[1] == 'f' && 0 == ::strncmp(packet_cstr, "qfProcessInfo", strlen("qfProcessInfo")))
-            return eServerPacketType_qfProcessInfo;
-        else if (packet_cstr[1] == 'U' && 0 == ::strncmp(packet_cstr, "qUserName:", strlen("qUserName:")))
-            return eServerPacketType_qUserName;
-        else if (packet_cstr[1] == 'G' && 0 == ::strncmp(packet_cstr, "qGroupName:", strlen("qGroupName:")))
-            return eServerPacketType_qGroupName;
-        else if (packet_cstr[1] == 's' && 0 == ::strcmp (packet_cstr, "qsProcessInfo"))
-            return eServerPacketType_qsProcessInfo;
+        switch (packet_cstr[1])
+        {
+        case 's':
+            if (PACKET_MATCHES ("qsProcessInfo"))               return eServerPacketType_qsProcessInfo;
+            break;
+
+        case 'f':
+            if (PACKET_STARTS_WITH ("qfProcessInfo"))           return eServerPacketType_qfProcessInfo;
+            break;
+
+        case 'C':
+            if (packet_size == 2)                               return eServerPacketType_qC;
+            break;
+
+        case 'G':
+            if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
+            break;
+
+        case 'H':
+            if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
+            break;
+
+        case 'L':
+            if (PACKET_MATCHES ("qLaunchGDBServer"))            return eServerPacketType_qLaunchGDBServer;
+            if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
+            break;
+            
+        case 'P':
+            if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
+            break;
+
+        case 'S':
+            if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
+            break;
+
+        case 'U':
+            if (PACKET_STARTS_WITH ("qUserName:"))              return eServerPacketType_qUserName;
+            break;
+        }
         break;
     }
     return eServerPacketType_unimplemented;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Tue Apr 12 00:54:46 2011
@@ -46,13 +46,23 @@
         eServerPacketType_invalid,
         eServerPacketType_unimplemented,
         eServerPacketType_interrupt, // CTRL+c packet or "\x03"
-        eServerPacketType_qHostInfo,
-        eServerPacketType_qProcessInfoPID,
+        eServerPacketType_A, // Program arguments packet
         eServerPacketType_qfProcessInfo,
         eServerPacketType_qsProcessInfo,
-        eServerPacketType_qUserName,
+        eServerPacketType_qC,
         eServerPacketType_qGroupName,
+        eServerPacketType_qHostInfo,
+        eServerPacketType_qLaunchGDBServer,
+        eServerPacketType_qLaunchSuccess,
+        eServerPacketType_qProcessInfoPID,
         eServerPacketType_qSpeedTest,
+        eServerPacketType_qUserName,
+        eServerPacketType_QEnvironment,
+        eServerPacketType_QSetDisableASLR,
+        eServerPacketType_QSetSTDIN,
+        eServerPacketType_QSetSTDOUT,
+        eServerPacketType_QSetSTDERR,
+        eServerPacketType_QSetWorkingDir,
         eServerPacketType_QStartNoAckMode
     };
     

Modified: lldb/trunk/test/abbreviation_tests/TestAbbreviations.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/abbreviation_tests/TestAbbreviations.py?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/test/abbreviation_tests/TestAbbreviations.py (original)
+++ lldb/trunk/test/abbreviation_tests/TestAbbreviations.py Tue Apr 12 00:54:46 2011
@@ -74,7 +74,7 @@
         self.expect("fil " + exe,
                     patterns = [ "Current executable set to .*a.out.*" ])
 
-        self.expect("regexp-b product",
+        self.expect("_regexp-b product",
                     substrs = [ "breakpoint set --name 'product'",
                                 "Breakpoint created: 1: name = 'product', locations = 1" ])
 

Modified: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/test/dotest.py (original)
+++ lldb/trunk/test/dotest.py Tue Apr 12 00:54:46 2011
@@ -216,9 +216,9 @@
 Collected 4 tests
 
 test_break_with_dsym (TestObjCMethods.FoundationTestCase)
-Test setting objc breakpoints using 'regexp-break' and 'breakpoint set'. ... ok
+Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
 test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
-Test setting objc breakpoints using 'regexp-break' and 'breakpoint set'. ... ok
+Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
 test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
 Lookup objective-c data types and evaluate expressions. ... ok
 test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)

Modified: lldb/trunk/test/foundation/TestFoundationDisassembly.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestFoundationDisassembly.py?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/test/foundation/TestFoundationDisassembly.py (original)
+++ lldb/trunk/test/foundation/TestFoundationDisassembly.py Tue Apr 12 00:54:46 2011
@@ -70,7 +70,7 @@
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Stop at +[NSString stringWithFormat:].
-        self.expect("regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
+        self.expect("_regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
             substrs = ["Breakpoint created: 1: name = '+[NSString stringWithFormat:]', locations = 1"])
 
         # Stop at -[MyString initWithNSString:].
@@ -82,7 +82,7 @@
             startstr = "Breakpoint created: 3: name = 'description', locations = 1")
 
         # Stop at -[NSAutoreleasePool release].
-        self.expect("regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
+        self.expect("_regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
             substrs = ["Breakpoint created: 4: name = '-[NSAutoreleasePool release]', locations = 1"])
 
         self.runCmd("run", RUN_SUCCEEDED)

Modified: lldb/trunk/test/foundation/TestObjCMethods.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods.py?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/test/foundation/TestObjCMethods.py (original)
+++ lldb/trunk/test/foundation/TestObjCMethods.py Tue Apr 12 00:54:46 2011
@@ -14,12 +14,12 @@
     mydir = "foundation"
 
     def test_break_with_dsym(self):
-        """Test setting objc breakpoints using 'regexp-break' and 'breakpoint set'."""
+        """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
         self.buildDsym()
         self.break_on_objc_methods()
 
     def test_break_with_dwarf(self):
-        """Test setting objc breakpoints using 'regexp-break' and 'breakpoint set'."""
+        """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
         self.buildDwarf()
         self.break_on_objc_methods()
 
@@ -50,12 +50,12 @@
         self.print_ivars_correctly()
 
     def break_on_objc_methods(self):
-        """Test setting objc breakpoints using 'regexp-break' and 'breakpoint set'."""
+        """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
         exe = os.path.join(os.getcwd(), "a.out")
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Stop at +[NSString stringWithFormat:].
-        self.expect("regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
+        self.expect("_regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
             substrs = ["Breakpoint created: 1: name = '+[NSString stringWithFormat:]', locations = 1"])
 
         # Stop at -[MyString initWithNSString:].
@@ -67,7 +67,7 @@
             startstr = "Breakpoint created: 3: name = 'description', locations = 1")
 
         # Stop at -[NSAutoreleasePool release].
-        self.expect("regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
+        self.expect("_regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
             substrs = ["Breakpoint created: 4: name = '-[NSAutoreleasePool release]', locations = 1"])
 
         self.runCmd("run", RUN_SUCCEEDED)

Modified: lldb/trunk/tools/darwin-debug/darwin-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/darwin-debug/darwin-debug.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/darwin-debug/darwin-debug.cpp (original)
+++ lldb/trunk/tools/darwin-debug/darwin-debug.cpp Tue Apr 12 00:54:46 2011
@@ -246,7 +246,7 @@
         printf ("argv[%u] = '%s'\n", i, argv[i]);
 #endif
 
-    // Open the socket that was passed in as an argument
+    // Open the socket that was passed in as an option
     struct sockaddr_un saddr_un;
     int s = ::socket (AF_UNIX, SOCK_STREAM, 0);
     if (s < 0)

Modified: lldb/trunk/tools/debugserver/source/MacOSX/CFString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/CFString.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/CFString.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/CFString.h Tue Apr 12 00:54:46 2011
@@ -24,7 +24,7 @@
     // Constructors and Destructors
     //------------------------------------------------------------------
                         CFString (CFStringRef cf_str = NULL);
-                        CFString (const char *s, CFStringEncoding encoding);
+                        CFString (const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
                         CFString (const CFString& rhs);
                         CFString& operator= (const CFString& rhs);
                         virtual ~CFString ();

Modified: lldb/trunk/tools/debugserver/source/RNBSocket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBSocket.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBSocket.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBSocket.cpp Tue Apr 12 00:54:46 2011
@@ -31,78 +31,90 @@
    This function blocks while waiting for that connection.  */
 
 rnb_err_t
-RNBSocket::Listen (in_port_t listen_port_num)
+RNBSocket::Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton)
 {
     //DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
     // Disconnect without saving errno
     Disconnect (false);
 
     DNBError err;
-    int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (listen_port == -1)
+    int listen_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (listen_fd == -1)
         err.SetError(errno, DNBError::POSIX);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::socket ( domain = AF_INET, type = SOCK_STREAM, protocol = IPPROTO_TCP ) => socket = %i", listen_port);
+        err.LogThreaded("::socket ( domain = AF_INET, type = SOCK_STREAM, protocol = IPPROTO_TCP ) => socket = %i", listen_fd);
 
     if (err.Fail())
         return rnb_err;
 
     // enable local address reuse
-    SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1);
+    SetSocketOption (listen_fd, SOL_SOCKET, SO_REUSEADDR, 1);
 
     struct sockaddr_in sa;
     ::memset (&sa, 0, sizeof sa);
     sa.sin_len = sizeof sa;
     sa.sin_family = AF_INET;
-    sa.sin_port = htons (listen_port_num);
+    sa.sin_port = htons (port);
     sa.sin_addr.s_addr = htonl (INADDR_ANY);
 
-    int error = ::bind (listen_port, (struct sockaddr *) &sa, sizeof(sa));
+    int error = ::bind (listen_fd, (struct sockaddr *) &sa, sizeof(sa));
     if (error == -1)
         err.SetError(errno, DNBError::POSIX);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::bind ( socket = %i, (struct sockaddr *) &sa, sizeof(sa)) )", listen_port);
+        err.LogThreaded("::bind ( socket = %i, (struct sockaddr *) &sa, sizeof(sa)) )", listen_fd);
 
     if (err.Fail())
     {
-        ClosePort (listen_port, false);
+        ClosePort (listen_fd, false);
         return rnb_err;
     }
 
-    error = ::listen (listen_port, 1);
+    if (callback && port == 0)
+    {
+        // We were asked to listen on port zero which means we
+        // must now read the actual port that was given to us 
+        // as port zero is a special code for "find an open port
+        // for me".
+        socklen_t sa_len = sizeof (sa);
+        if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0)
+        {
+            port = ntohs (sa.sin_port);
+            callback (callback_baton, port);
+        }
+    }
+
+    error = ::listen (listen_fd, 1);
     if (error == -1)
         err.SetError(errno, DNBError::POSIX);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::listen ( socket = %i, backlog = 1 )", listen_port);
+        err.LogThreaded("::listen ( socket = %i, backlog = 1 )", listen_fd);
 
     if (err.Fail())
     {
-        ClosePort (listen_port, false);
+        ClosePort (listen_fd, false);
         return rnb_err;
     }
 
-    m_conn_port = ::accept (listen_port, NULL, 0);
-    if (m_conn_port == -1)
+    m_fd = ::accept (listen_fd, NULL, 0);
+    if (m_fd == -1)
         err.SetError(errno, DNBError::POSIX);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::accept ( socket = %i, address = NULL, address_len = 0 )", listen_port);
+        err.LogThreaded("::accept ( socket = %i, address = NULL, address_len = 0 )", listen_fd);
+
+    ClosePort (listen_fd, false);
 
     if (err.Fail())
     {
-        ClosePort (listen_port, false);
         return rnb_err;
     }
     else
     {
-        // We are done with the listen port
-        ClosePort (listen_port, false);
-
         // Keep our TCP packets coming without any delays.
-        SetSocketOption (m_conn_port, IPPROTO_TCP, TCP_NODELAY, 1);
+        SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
     }
 
     return rnb_success;
@@ -114,12 +126,12 @@
     Disconnect (false);
 
     // Create the socket
-    m_conn_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (m_conn_port == -1)
+    m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (m_fd == -1)
         return rnb_err;
     
     // Enable local address reuse
-    SetSocketOption (m_conn_port, SOL_SOCKET, SO_REUSEADDR, 1);
+    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
     
     struct sockaddr_in sa;
     ::memset (&sa, 0, sizeof (sa));
@@ -146,14 +158,14 @@
         }
     }
     
-    if (-1 == ::connect (m_conn_port, (const struct sockaddr *)&sa, sizeof(sa)))
+    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
     {
         Disconnect (false);
         return rnb_err;
     }
     
     // Keep our TCP packets coming without any delays.
-    SetSocketOption (m_conn_port, IPPROTO_TCP, TCP_NODELAY, 1);
+    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
     return rnb_success;
 }
 
@@ -165,13 +177,13 @@
     // Disconnect from any previous connections
     Disconnect(false);
 
-    m_conn_port = ::lockdown_checkin (NULL, NULL);
-    if (m_conn_port == -1)
+    m_fd = ::lockdown_checkin (NULL, NULL);
+    if (m_fd == -1)
     {
         DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_checkin(NULL, NULL) failed");
         return rnb_not_connected;
     }
-    m_conn_port_from_lockdown = true;
+    m_fd_from_lockdown = true;
     return rnb_success;
 }
 #endif
@@ -180,8 +192,8 @@
 RNBSocket::OpenFile (const char *path)
 {
     DNBError err;
-    m_conn_port = open (path, O_RDWR);
-    if (m_conn_port == -1)
+    m_fd = open (path, O_RDWR);
+    if (m_fd == -1)
     {
         err.SetError(errno, DNBError::POSIX);
         err.LogThreaded ("can't open file '%s'", path);
@@ -191,11 +203,11 @@
     {
         struct termios stdin_termios;
 
-        if (::tcgetattr (m_conn_port, &stdin_termios) == 0)
+        if (::tcgetattr (m_fd, &stdin_termios) == 0)
         {
             stdin_termios.c_lflag &= ~ECHO;     // Turn off echoing
             stdin_termios.c_lflag &= ~ICANON;   // Get one char at a time
-            ::tcsetattr (m_conn_port, TCSANOW, &stdin_termios);
+            ::tcsetattr (m_fd, TCSANOW, &stdin_termios);
         }
     }
     return rnb_success;
@@ -210,9 +222,9 @@
 rnb_err_t
 RNBSocket::Disconnect (bool save_errno)
 {
-    if (m_conn_port_from_lockdown)
-        m_conn_port_from_lockdown = false;
-    return ClosePort (m_conn_port, save_errno);
+    if (m_fd_from_lockdown)
+        m_fd_from_lockdown = false;
+    return ClosePort (m_fd, save_errno);
 }
 
 
@@ -225,29 +237,29 @@
     // Note that BUF is on the stack so we must be careful to keep any
     // writes to BUF from overflowing or we'll have security issues.
 
-    if (m_conn_port == -1)
+    if (m_fd == -1)
         return rnb_err;
 
     //DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s calling read()", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
     DNBError err;
-    int bytesread = read (m_conn_port, buf, sizeof (buf));
+    int bytesread = read (m_fd, buf, sizeof (buf));
     if (bytesread <= 0)
         err.SetError(errno, DNBError::POSIX);
     else
         p.append(buf, bytesread);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::read ( %i, %p, %zu ) => %i", m_conn_port, buf, sizeof (buf), bytesread);
+        err.LogThreaded("::read ( %i, %p, %zu ) => %i", m_fd, buf, sizeof (buf), bytesread);
 
     // Our port went away - we have to mark this so IsConnected will return the truth.
     if (bytesread == 0)
     {
-        m_conn_port = -1;
+        m_fd = -1;
         return rnb_not_connected;
     }
     else if (bytesread == -1)
     {
-        m_conn_port = -1;
+        m_fd = -1;
         return rnb_err;
     }
     // Strip spaces from the end of the buffer
@@ -262,16 +274,16 @@
 rnb_err_t
 RNBSocket::Write (const void *buffer, size_t length)
 {
-    if (m_conn_port == -1)
+    if (m_fd == -1)
         return rnb_err;
 
     DNBError err;
-    int bytessent = send (m_conn_port, buffer, length, 0);
+    int bytessent = send (m_fd, buffer, length, 0);
     if (bytessent < 0)
         err.SetError(errno, DNBError::POSIX);
 
     if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::send ( socket = %i, buffer = %p, length = %zu, flags = 0 ) => %i", m_conn_port, buffer, length, bytessent);
+        err.LogThreaded("::send ( socket = %i, buffer = %p, length = %zu, flags = 0 ) => %i", m_fd, buffer, length, bytessent);
 
     if (bytessent < 0)
         return rnb_err;

Modified: lldb/trunk/tools/debugserver/source/RNBSocket.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBSocket.h?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBSocket.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBSocket.h Tue Apr 12 00:54:46 2011
@@ -23,10 +23,11 @@
 class RNBSocket
 {
 public:
+    typedef void (*PortBoundCallback) (const void *baton, in_port_t port);
 
     RNBSocket () :
-        m_conn_port (-1),
-        m_conn_port_from_lockdown (false),
+        m_fd (-1),
+        m_fd_from_lockdown (false),
         m_timer (true)      // Make a thread safe timer
     {
     }
@@ -35,7 +36,7 @@
         Disconnect (false);
     }
 
-    rnb_err_t Listen (in_port_t listen_port_num);
+    rnb_err_t Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton);
     rnb_err_t Connect (const char *host, uint16_t port);
 
 #if defined (__arm__)
@@ -46,7 +47,7 @@
     rnb_err_t Read (std::string &p);
     rnb_err_t Write (const void *buffer, size_t length);
 
-    bool IsConnected () const { return m_conn_port != -1; }
+    bool IsConnected () const { return m_fd != -1; }
     void SaveErrno (int curr_errno);
     DNBTimer& Timer() { return m_timer; }
 
@@ -58,8 +59,8 @@
 protected:
     rnb_err_t ClosePort (int& fd, bool save_errno);
 
-    int m_conn_port;    // Socket we use to communicate once conn established
-    bool m_conn_port_from_lockdown;
+    int m_fd;    // Socket we use to communicate once conn established
+    bool m_fd_from_lockdown;
     DNBTimer m_timer;
 };
 

Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/trunk/tools/debugserver/source/debugserver.cpp Tue Apr 12 00:54:46 2011
@@ -17,6 +17,12 @@
 #include <string>
 #include <vector>
 #include <asl.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <sys/types.h>
 
 #include "CFString.h"
 #include "DNB.h"
@@ -608,13 +614,68 @@
 // Returns 1 for success 0 for failure.
 //----------------------------------------------------------------------
 
+static void
+PortWasBoundCallback (const void *baton, in_port_t port)
+{
+    //::printf ("PortWasBoundCallback (baton = %p, port = %u)\n", baton, port);
+
+    const char *unix_socket_name = (const char *)baton;
+    
+    if (unix_socket_name && unix_socket_name[0])
+    {
+        // We were given a unix socket name to use to communicate the port
+        // that we ended up binding to back to our parent process
+        struct sockaddr_un saddr_un;
+        int s = ::socket (AF_UNIX, SOCK_STREAM, 0);
+        if (s < 0)
+        {
+            perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
+            exit(1);
+        }
+        
+        saddr_un.sun_family = AF_UNIX;
+        ::strncpy(saddr_un.sun_path, unix_socket_name, sizeof(saddr_un.sun_path) - 1);
+        saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
+        saddr_un.sun_len = SUN_LEN (&saddr_un);
+        
+        if (::connect (s, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
+        {
+            perror("error: connect (socket, &saddr_un, saddr_un_len)");
+            exit(1);
+        }
+        
+        //::printf ("connect () sucess!!\n");
+
+        
+        // We were able to connect to the socket, now write our PID so whomever
+        // launched us will know this process's ID
+        RNBLogSTDOUT ("Listening to port %i...\n", port);
+        
+        char pid_str[64];
+        const int pid_str_len = ::snprintf (pid_str, sizeof(pid_str), "%u", port);
+        const int bytes_sent = ::send (s, pid_str, pid_str_len, 0);
+        
+        if (pid_str_len != bytes_sent)
+        {
+            perror("error: send (s, pid_str, pid_str_len, 0)");
+            exit (1);
+        }
+
+        //::printf ("send () sucess!!\n");
+
+        // We are done with the socket
+        close (s);
+    }
+}
+
 static int
-StartListening (RNBRemote *remote, int listen_port)
+StartListening (RNBRemote *remote, int listen_port, const char *unix_socket_name)
 {
     if (!remote->Comm().IsConnected())
     {
-        RNBLogSTDOUT ("Listening to port %i...\n", listen_port);
-        if (remote->Comm().Listen(listen_port) != rnb_success)
+        if (listen_port != 0)
+            RNBLogSTDOUT ("Listening to port %i...\n", listen_port);
+        if (remote->Comm().Listen(listen_port, PortWasBoundCallback, unix_socket_name) != rnb_success)
         {
             RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
             return 0;
@@ -709,6 +770,7 @@
     { "disable-aslr",       no_argument,        NULL,               'D' },  // Use _POSIX_SPAWN_DISABLE_ASLR to avoid shared library randomization
     { "working-dir",        required_argument,  NULL,               'W' },  // The working directory that the inferior process should have (only if debugserver launches the process)
     { "platform",           required_argument,  NULL,               'p' },  // Put this executable into a remote platform mode
+    { "unix-socket",        required_argument,  NULL,               'u' },  // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
     { NULL,                 0,                  NULL,               0   }
 };
 
@@ -757,7 +819,8 @@
     std::string waitfor_pid_name;           // Wait for a process that starts with this name
     std::string attach_pid_name;
     std::string arch_name;
-    std::string working_dir;          // The new working directory to use for the inferior
+    std::string working_dir;                // The new working directory to use for the inferior
+    std::string unix_socket_name;           // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
     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.
     bool no_stdio = false;
@@ -768,7 +831,7 @@
 
     RNBRunLoopMode start_mode = eRNBRunLoopModeExit;
 
-    while ((ch = getopt_long(argc, argv, "a:A:d:gi:vktl:f:w:x:rs:n", g_long_options, &long_option_index)) != -1)
+    while ((ch = getopt_long(argc, argv, "a:A:d:gi:vktl:f:w:x:rs:nu:", g_long_options, &long_option_index)) != -1)
     {
         DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
                     ch, (uint8_t)ch,
@@ -967,6 +1030,11 @@
             case 'p':
                 start_mode = eRNBRunLoopModePlatformMode;
                 break;
+
+            case 'u':
+                unix_socket_name.assign (optarg);
+                break;
+                
         }
     }
     
@@ -1171,7 +1239,7 @@
 #endif
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_port))
+                    if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')
@@ -1282,7 +1350,7 @@
                 {
                     if (listen_port != INT32_MAX)
                     {
-                        if (!StartListening (remote, listen_port))
+                        if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
                             mode = eRNBRunLoopModeExit;
                     }
                     else if (str[0] == '/')
@@ -1307,7 +1375,7 @@
                     {
                         if (listen_port != INT32_MAX)
                         {
-                            if (!StartListening (remote, listen_port))
+                            if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
                                 mode = eRNBRunLoopModeExit;
                         }
                         else if (str[0] == '/')
@@ -1334,7 +1402,7 @@
             case eRNBRunLoopModePlatformMode:
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_port))
+                    if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')

Modified: lldb/trunk/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-platform/lldb-platform.cpp?rev=129351&r1=129350&r2=129351&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/trunk/tools/lldb-platform/lldb-platform.cpp Tue Apr 12 00:54:46 2011
@@ -180,7 +180,7 @@
     argv += optind;
 
 
-    GDBRemoteCommunicationServer gdb_server;
+    GDBRemoteCommunicationServer gdb_server (true);
     if (!listen_host_post.empty())
     {
         std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());





More information about the lldb-commits mailing list