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.







git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@129351 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index a54a15e..551a496 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -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()));
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
index 6064ec8..0ed4a06 100644
--- a/source/Commands/CommandObjectArgs.cpp
+++ b/source/Commands/CommandObjectArgs.cpp
@@ -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)
     {
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index c828701..d5a4345 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -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.");
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 1301fd9..dea7640 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -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())
     {
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 31ecaf1..c96b247 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -295,7 +295,7 @@
     CommandReturnObject &result
 )
 {
-    m_exe_ctx = m_interpreter.GetDebugger().GetExecutionContext();
+    m_exe_ctx = m_interpreter.GetExecutionContext();
 
     m_options.Reset();
 
diff --git a/source/Commands/CommandObjectFile.cpp b/source/Commands/CommandObjectFile.cpp
index e0c81bb..1177f5a 100644
--- a/source/Commands/CommandObjectFile.cpp
+++ b/source/Commands/CommandObjectFile.cpp
@@ -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;
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index aaaee06..57286ac 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -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.");
diff --git a/source/Commands/CommandObjectImage.cpp b/source/Commands/CommandObjectImage.cpp
index 3d005a8..ca109d5 100644
--- a/source/Commands/CommandObjectImage.cpp
+++ b/source/Commands/CommandObjectImage.cpp
@@ -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 }
 };
 
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index c731c61..7993f54 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -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");
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index a72b0db4..730a1b3 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -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);
+                        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())
+                            {
+                                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)
                         {
-                            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())
-                                {
-                                    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;
-                                }
-                            }
                             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)));
 
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 116309d..1fc573b 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -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)
+        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())
         {
-        
-            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);
+            // 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();
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index d50d7d7..2607854 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -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)
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 9fbf602..29b17dc 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -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())
         {
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index abb6f5f..f321000 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -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();
diff --git a/source/Core/ConnectionFileDescriptor.cpp b/source/Core/ConnectionFileDescriptor.cpp
index e5b27bc..ce306c9 100644
--- a/source/Core/ConnectionFileDescriptor.cpp
+++ b/source/Core/ConnectionFileDescriptor.cpp
@@ -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,
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index ca0dde9..073986a 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -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)
 {
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 7ceff58..0b31465 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -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();
 }
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index e2e0aa2..18f3bbf 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -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;
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 5d98402..a665472 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -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;
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index 65d60d7..28d8d81 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -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;
+}
+
+
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index 7a32e08..c6d2f08 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -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] == '~');
+                                }
                             }
                         }
                     }
diff --git a/source/Host/macosx/cfcpp/CFCString.h b/source/Host/macosx/cfcpp/CFCString.h
index 521d2c0..27c0903 100644
--- a/source/Host/macosx/cfcpp/CFCString.h
+++ b/source/Host/macosx/cfcpp/CFCString.h
@@ -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 ();
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index df276ba..13ecd11 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -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 ()
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 98786f7..6dcc4a1 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -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);
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index f93ed6e..16c68ec 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -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.");
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 0b06b4c..1040994 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -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());
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 63cb4ac..d3a11e4 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -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)
 {
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 7464736..38804ed 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -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
 
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 2ae4a90..3e0b2b1 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -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();
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 63ac852..08968f4 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -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, 
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index a6bcb9b..f8b67a3 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -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;
+}
+
 
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index a016e01..36c48c2 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -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);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 3b8d605..93e4166 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -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;
+}
+
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index f53d036..77e3e1a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -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
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 2cebb10..d4f6592 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -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;
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index ae1674a..5c24d64 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -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
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index c243138..9379077 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -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_nack:
+            case StringExtractorGDBRemote::eServerPacketType_ack:
+                break;
 
-        case StringExtractorGDBRemote::eServerPacketType_invalid:
-            error.SetErrorString("invalid packet");
-            quit = true;
-            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_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_A:
+                return Handle_A (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_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_qfProcessInfo:
-            return Handle_qfProcessInfo (packet);
+            case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
+                return Handle_qProcessInfoPID (packet);
 
-        case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
-            return Handle_qsProcessInfo (packet);
-        
-        case StringExtractorGDBRemote::eServerPacketType_qUserName:
-            return Handle_qUserName (packet);
+            case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
+                return Handle_qSpeedTest (packet);
 
-        case StringExtractorGDBRemote::eServerPacketType_qGroupName:
-            return Handle_qGroupName (packet);
+            case StringExtractorGDBRemote::eServerPacketType_qUserName:
+                return Handle_qUserName (packet);
 
-        case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
-            return Handle_qSpeedTest (packet);
-        case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
-            return Handle_QStartNoAckMode (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)
 {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 02440a2..1fddaeb 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -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
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 0a1f872..841efa2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -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);
     }
 }
 
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ec07fbe..79f77e2 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -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())
+        BreakpointSite::Type bp_type = bp_site->GetType();
+        switch (bp_type)
         {
-            // TODO: disable hardware breakpoint...
+        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;
         }
-        else
-        {
-            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);
-            }
-        }
+        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);
-            
+            error = Host::LaunchProcess(launch_info);
 
-            ::posix_spawnattr_destroy (&attr);
-
-            if (file_actions_err.Success())
-                ::posix_spawn_file_actions_destroy (&file_actions);
-
-            // 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)
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index e9ab4df..cf03604 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -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 ();
 
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 9955409..351b6eb 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -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;
 }
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index 4584208..a2568a3 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -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;
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index cddd37f..34c7337 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -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;
+}
+
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 940ff2b..c33dd18 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -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
-ProcessInfoMatch::NameMatches (const char *process_name) const
+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
+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())
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 3c0a9ca..7e06a0f 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -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;
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
index 36fd034..5a24d89 100644
--- a/source/Utility/StringExtractorGDBRemote.h
+++ b/source/Utility/StringExtractorGDBRemote.h
@@ -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
     };