1 //===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "PlatformLinux.h"
13 #include "lldb/Host/Config.h"
14 
15 // C Includes
16 #include <stdio.h>
17 #ifndef LLDB_DISABLE_POSIX
18 #include <sys/utsname.h>
19 #endif
20 
21 // C++ Includes
22 // Other libraries and framework includes
23 // Project includes
24 #include "lldb/Core/Debugger.h"
25 #include "lldb/Core/Error.h"
26 #include "lldb/Core/Log.h"
27 #include "lldb/Core/Module.h"
28 #include "lldb/Core/ModuleList.h"
29 #include "lldb/Core/ModuleSpec.h"
30 #include "lldb/Core/PluginManager.h"
31 #include "lldb/Core/State.h"
32 #include "lldb/Core/StreamString.h"
33 #include "lldb/Host/FileSpec.h"
34 #include "lldb/Host/HostInfo.h"
35 #include "lldb/Interpreter/OptionValueProperties.h"
36 #include "lldb/Interpreter/Property.h"
37 #include "lldb/Target/Target.h"
38 #include "lldb/Target/Process.h"
39 
40 #if defined(__linux__)
41 #include "../../Process/Linux/NativeProcessLinux.h"
42 #endif
43 
44 using namespace lldb;
45 using namespace lldb_private;
46 
47 static uint32_t g_initialize_count = 0;
48 
49 //------------------------------------------------------------------
50 /// Code to handle the PlatformLinux settings
51 //------------------------------------------------------------------
52 
53 namespace
54 {
55     enum
56     {
57         ePropertyUseLlgsForLocal = 0,
58     };
59 
60     const PropertyDefinition*
61     GetStaticPropertyDefinitions ()
62     {
63         static PropertyDefinition
64         g_properties[] =
65         {
66             { "use-llgs-for-local" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "Control whether the platform uses llgs for local debug sessions." },
67             {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
68         };
69 
70         // Allow environment variable to force using llgs-local.
71         if (getenv("PLATFORM_LINUX_FORCE_LLGS_LOCAL"))
72             g_properties[ePropertyUseLlgsForLocal].default_uint_value = true;
73 
74         return g_properties;
75     }
76 }
77 
78 class PlatformLinuxProperties : public Properties
79 {
80 public:
81 
82     static ConstString &
83     GetSettingName ()
84     {
85         static ConstString g_setting_name("linux");
86         return g_setting_name;
87     }
88 
89     PlatformLinuxProperties() :
90     Properties ()
91     {
92         m_collection_sp.reset (new OptionValueProperties(GetSettingName ()));
93         m_collection_sp->Initialize (GetStaticPropertyDefinitions ());
94     }
95 
96     virtual
97     ~PlatformLinuxProperties()
98     {
99     }
100 
101     bool
102     GetUseLlgsForLocal() const
103     {
104         const uint32_t idx = ePropertyUseLlgsForLocal;
105         return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, GetStaticPropertyDefinitions()[idx].default_uint_value != 0);
106     }
107 };
108 
109 typedef std::shared_ptr<PlatformLinuxProperties> PlatformLinuxPropertiesSP;
110 
111 static const PlatformLinuxPropertiesSP &
112 GetGlobalProperties()
113 {
114     static PlatformLinuxPropertiesSP g_settings_sp;
115     if (!g_settings_sp)
116         g_settings_sp.reset (new PlatformLinuxProperties ());
117     return g_settings_sp;
118 }
119 
120 void
121 PlatformLinux::DebuggerInitialize (lldb_private::Debugger &debugger)
122 {
123     if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformLinuxProperties::GetSettingName()))
124     {
125         const bool is_global_setting = true;
126         PluginManager::CreateSettingForPlatformPlugin (debugger,
127                                                        GetGlobalProperties()->GetValueProperties(),
128                                                        ConstString ("Properties for the PlatformLinux plug-in."),
129                                                        is_global_setting);
130     }
131 }
132 
133 
134 //------------------------------------------------------------------
135 
136 PlatformSP
137 PlatformLinux::CreateInstance (bool force, const ArchSpec *arch)
138 {
139     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
140     if (log)
141     {
142         const char *arch_name;
143         if (arch && arch->GetArchitectureName ())
144             arch_name = arch->GetArchitectureName ();
145         else
146             arch_name = "<null>";
147 
148         const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>";
149 
150         log->Printf ("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
151     }
152 
153     bool create = force;
154     if (create == false && arch && arch->IsValid())
155     {
156         const llvm::Triple &triple = arch->GetTriple();
157         switch (triple.getVendor())
158         {
159             case llvm::Triple::PC:
160                 create = true;
161                 break;
162 
163 #if defined(__linux__)
164             // Only accept "unknown" for the vendor if the host is linux and
165             // it "unknown" wasn't specified (it was just returned because it
166             // was NOT specified_
167             case llvm::Triple::VendorType::UnknownVendor:
168                 create = !arch->TripleVendorWasSpecified();
169                 break;
170 #endif
171             default:
172                 break;
173         }
174 
175         if (create)
176         {
177             switch (triple.getOS())
178             {
179                 case llvm::Triple::Linux:
180                     break;
181 
182 #if defined(__linux__)
183                 // Only accept "unknown" for the OS if the host is linux and
184                 // it "unknown" wasn't specified (it was just returned because it
185                 // was NOT specified)
186                 case llvm::Triple::OSType::UnknownOS:
187                     create = !arch->TripleOSWasSpecified();
188                     break;
189 #endif
190                 default:
191                     create = false;
192                     break;
193             }
194         }
195     }
196 
197     if (create)
198     {
199         if (log)
200             log->Printf ("PlatformLinux::%s() creating remote-linux platform", __FUNCTION__);
201         return PlatformSP(new PlatformLinux(false));
202     }
203 
204     if (log)
205         log->Printf ("PlatformLinux::%s() aborting creation of remote-linux platform", __FUNCTION__);
206 
207     return PlatformSP();
208 }
209 
210 
211 lldb_private::ConstString
212 PlatformLinux::GetPluginNameStatic (bool is_host)
213 {
214     if (is_host)
215     {
216         static ConstString g_host_name(Platform::GetHostPlatformName ());
217         return g_host_name;
218     }
219     else
220     {
221         static ConstString g_remote_name("remote-linux");
222         return g_remote_name;
223     }
224 }
225 
226 const char *
227 PlatformLinux::GetPluginDescriptionStatic (bool is_host)
228 {
229     if (is_host)
230         return "Local Linux user platform plug-in.";
231     else
232         return "Remote Linux user platform plug-in.";
233 }
234 
235 lldb_private::ConstString
236 PlatformLinux::GetPluginName()
237 {
238     return GetPluginNameStatic(IsHost());
239 }
240 
241 void
242 PlatformLinux::Initialize ()
243 {
244     if (g_initialize_count++ == 0)
245     {
246 #if defined(__linux__)
247         PlatformSP default_platform_sp (new PlatformLinux(true));
248         default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
249         Platform::SetHostPlatform (default_platform_sp);
250 #endif
251         PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false),
252                                       PlatformLinux::GetPluginDescriptionStatic(false),
253                                       PlatformLinux::CreateInstance,
254                                       PlatformLinux::DebuggerInitialize);
255     }
256 }
257 
258 void
259 PlatformLinux::Terminate ()
260 {
261     if (g_initialize_count > 0)
262     {
263         if (--g_initialize_count == 0)
264         {
265             PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance);
266         }
267     }
268 }
269 
270 Error
271 PlatformLinux::ResolveExecutable (const FileSpec &exe_file,
272                                   const ArchSpec &exe_arch,
273                                   lldb::ModuleSP &exe_module_sp,
274                                   const FileSpecList *module_search_paths_ptr)
275 {
276     Error error;
277     // Nothing special to do here, just use the actual file and architecture
278 
279     char exe_path[PATH_MAX];
280     FileSpec resolved_exe_file (exe_file);
281 
282     if (IsHost())
283     {
284         // If we have "ls" as the exe_file, resolve the executable location based on
285         // the current path variables
286         if (!resolved_exe_file.Exists())
287         {
288             exe_file.GetPath(exe_path, sizeof(exe_path));
289             resolved_exe_file.SetFile(exe_path, true);
290         }
291 
292         if (!resolved_exe_file.Exists())
293             resolved_exe_file.ResolveExecutableLocation ();
294 
295         if (resolved_exe_file.Exists())
296             error.Clear();
297         else
298         {
299             exe_file.GetPath(exe_path, sizeof(exe_path));
300             error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
301         }
302     }
303     else
304     {
305         if (m_remote_platform_sp)
306         {
307             error = m_remote_platform_sp->ResolveExecutable (exe_file,
308                                                              exe_arch,
309                                                              exe_module_sp,
310                                                              NULL);
311         }
312         else
313         {
314             // We may connect to a process and use the provided executable (Don't use local $PATH).
315 
316             if (resolved_exe_file.Exists())
317                 error.Clear();
318             else
319                 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
320         }
321     }
322 
323     if (error.Success())
324     {
325         ModuleSpec module_spec (resolved_exe_file, exe_arch);
326         if (exe_arch.IsValid())
327         {
328             error = ModuleList::GetSharedModule (module_spec,
329                                                  exe_module_sp,
330                                                  NULL,
331                                                  NULL,
332                                                  NULL);
333             if (error.Fail())
334             {
335                 // If we failed, it may be because the vendor and os aren't known. If that is the
336                 // case, try setting them to the host architecture and give it another try.
337                 llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple();
338                 bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
339                 bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
340                 if (!is_vendor_specified || !is_os_specified)
341                 {
342                     const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
343 
344                     if (!is_vendor_specified)
345                         module_triple.setVendorName (host_triple.getVendorName());
346                     if (!is_os_specified)
347                         module_triple.setOSName (host_triple.getOSName());
348 
349                     error = ModuleList::GetSharedModule (module_spec,
350                                                          exe_module_sp,
351                                                          NULL,
352                                                          NULL,
353                                                          NULL);
354                 }
355             }
356 
357             // TODO find out why exe_module_sp might be NULL
358             if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
359             {
360                 exe_module_sp.reset();
361                 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
362                                                 exe_file.GetPath().c_str(),
363                                                 exe_arch.GetArchitectureName());
364             }
365         }
366         else
367         {
368             // No valid architecture was specified, ask the platform for
369             // the architectures that we should be using (in the correct order)
370             // and see if we can find a match that way
371             StreamString arch_names;
372             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
373             {
374                 error = ModuleList::GetSharedModule (module_spec,
375                                                      exe_module_sp,
376                                                      NULL,
377                                                      NULL,
378                                                      NULL);
379                 // Did we find an executable using one of the
380                 if (error.Success())
381                 {
382                     if (exe_module_sp && exe_module_sp->GetObjectFile())
383                         break;
384                     else
385                         error.SetErrorToGenericError();
386                 }
387 
388                 if (idx > 0)
389                     arch_names.PutCString (", ");
390                 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
391             }
392 
393             if (error.Fail() || !exe_module_sp)
394             {
395                 if (exe_file.Readable())
396                 {
397                     error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
398                                                     exe_file.GetPath().c_str(),
399                                                     GetPluginName().GetCString(),
400                                                     arch_names.GetString().c_str());
401                 }
402                 else
403                 {
404                     error.SetErrorStringWithFormat("'%s' is not readable", exe_file.GetPath().c_str());
405                 }
406             }
407         }
408     }
409 
410     return error;
411 }
412 
413 Error
414 PlatformLinux::GetFileWithUUID (const FileSpec &platform_file,
415                                 const UUID *uuid_ptr, FileSpec &local_file)
416 {
417     if (IsRemote())
418     {
419         if (m_remote_platform_sp)
420             return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
421     }
422 
423     // Default to the local case
424     local_file = platform_file;
425     return Error();
426 }
427 
428 
429 //------------------------------------------------------------------
430 /// Default Constructor
431 //------------------------------------------------------------------
432 PlatformLinux::PlatformLinux (bool is_host) :
433     PlatformPOSIX(is_host)  // This is the local host platform
434 {
435 }
436 
437 //------------------------------------------------------------------
438 /// Destructor.
439 ///
440 /// The destructor is virtual since this class is designed to be
441 /// inherited from by the plug-in instance.
442 //------------------------------------------------------------------
443 PlatformLinux::~PlatformLinux()
444 {
445 }
446 
447 bool
448 PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
449 {
450     bool success = false;
451     if (IsHost())
452     {
453         success = Platform::GetProcessInfo (pid, process_info);
454     }
455     else
456     {
457         if (m_remote_platform_sp)
458             success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
459     }
460     return success;
461 }
462 
463 bool
464 PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
465 {
466     if (idx == 0)
467     {
468         arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
469         return arch.IsValid();
470     }
471     else if (idx == 1)
472     {
473         // If the default host architecture is 64-bit, look for a 32-bit variant
474         ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
475         if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
476         {
477             arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
478             return arch.IsValid();
479         }
480     }
481     return false;
482 }
483 
484 void
485 PlatformLinux::GetStatus (Stream &strm)
486 {
487     Platform::GetStatus(strm);
488 
489 #ifndef LLDB_DISABLE_POSIX
490     struct utsname un;
491 
492     if (uname(&un))
493         return;
494 
495     strm.Printf ("    Kernel: %s\n", un.sysname);
496     strm.Printf ("   Release: %s\n", un.release);
497     strm.Printf ("   Version: %s\n", un.version);
498 #endif
499 }
500 
501 size_t
502 PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
503                                                 BreakpointSite *bp_site)
504 {
505     ArchSpec arch = target.GetArchitecture();
506     const uint8_t *trap_opcode = NULL;
507     size_t trap_opcode_size = 0;
508 
509     switch (arch.GetMachine())
510     {
511     default:
512         assert(false && "CPU type not supported!");
513         break;
514 
515     case llvm::Triple::aarch64:
516         {
517             static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
518             trap_opcode = g_aarch64_opcode;
519             trap_opcode_size = sizeof(g_aarch64_opcode);
520         }
521         break;
522     case llvm::Triple::x86:
523     case llvm::Triple::x86_64:
524         {
525             static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
526             trap_opcode = g_i386_breakpoint_opcode;
527             trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
528         }
529         break;
530     case llvm::Triple::hexagon:
531         {
532             static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
533             trap_opcode = g_hex_opcode;
534             trap_opcode_size = sizeof(g_hex_opcode);
535         }
536         break;
537     }
538 
539     if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
540         return trap_opcode_size;
541     return 0;
542 }
543 
544 int32_t
545 PlatformLinux::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
546 {
547     int32_t resume_count = 0;
548 
549     // Always resume past the initial stop when we use eLaunchFlagDebug
550     if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
551     {
552         // Resume past the stop for the final exec into the true inferior.
553         ++resume_count;
554     }
555 
556     // If we're not launching a shell, we're done.
557     const char *shell = launch_info.GetShell();
558     if (shell == NULL)
559         return resume_count;
560 
561     // We're in a shell, so for sure we have to resume past the shell exec.
562     ++resume_count;
563 
564     // Figure out what shell we're planning on using.
565     const char *shell_name = strrchr (shell, '/');
566     if (shell_name == NULL)
567         shell_name = shell;
568     else
569         shell_name++;
570 
571     if (strcmp (shell_name, "csh") == 0
572              || strcmp (shell_name, "tcsh") == 0
573              || strcmp (shell_name, "zsh") == 0
574              || strcmp (shell_name, "sh") == 0)
575     {
576         // These shells seem to re-exec themselves.  Add another resume.
577         ++resume_count;
578     }
579 
580     return resume_count;
581 }
582 
583 bool
584 PlatformLinux::UseLlgsForLocalDebugging ()
585 {
586     PlatformLinuxPropertiesSP properties_sp = GetGlobalProperties ();
587     assert (properties_sp && "global properties shared pointer is null");
588     return properties_sp ? properties_sp->GetUseLlgsForLocal () : false;
589 }
590 
591 bool
592 PlatformLinux::CanDebugProcess ()
593 {
594     if (IsHost ())
595     {
596         // The platform only does local debugging (i.e. uses llgs) when the setting indicates we do that.
597         // Otherwise, we'll use ProcessLinux/ProcessPOSIX to handle with ProcessMonitor.
598         return UseLlgsForLocalDebugging ();
599     }
600     else
601     {
602         // If we're connected, we can debug.
603         return IsConnected ();
604     }
605 }
606 
607 // For local debugging, Linux will override the debug logic to use llgs-launch rather than
608 // lldb-launch, llgs-attach.  This differs from current lldb-launch, debugserver-attach
609 // approach on MacOSX.
610 lldb::ProcessSP
611 PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
612                         Debugger &debugger,
613                         Target *target,       // Can be NULL, if NULL create a new target, else use existing one
614                         Listener &listener,
615                         Error &error)
616 {
617     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
618     if (log)
619         log->Printf ("PlatformLinux::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));
620 
621     // If we're a remote host, use standard behavior from parent class.
622     if (!IsHost ())
623         return PlatformPOSIX::DebugProcess (launch_info, debugger, target, listener, error);
624 
625     //
626     // For local debugging, we'll insist on having ProcessGDBRemote create the process.
627     //
628 
629     ProcessSP process_sp;
630 
631     // Ensure we're using llgs for local debugging.
632     if (!UseLlgsForLocalDebugging ())
633     {
634         assert (false && "we're trying to debug a local process but platform.plugin.linux.use-llgs-for-local is false, should never get here");
635         error.SetErrorString ("attempted to start gdb-remote-based debugging for local process but platform.plugin.linux.use-llgs-for-local is false");
636         return process_sp;
637     }
638 
639     // Make sure we stop at the entry point
640     launch_info.GetFlags ().Set (eLaunchFlagDebug);
641 
642     // We always launch the process we are going to debug in a separate process
643     // group, since then we can handle ^C interrupts ourselves w/o having to worry
644     // about the target getting them as well.
645     launch_info.SetLaunchInSeparateProcessGroup(true);
646 
647     // Ensure we have a target.
648     if (target == nullptr)
649     {
650         if (log)
651             log->Printf ("PlatformLinux::%s creating new target", __FUNCTION__);
652 
653         TargetSP new_target_sp;
654         error = debugger.GetTargetList().CreateTarget (debugger,
655                                                        nullptr,
656                                                        nullptr,
657                                                        false,
658                                                        nullptr,
659                                                        new_target_sp);
660         if (error.Fail ())
661         {
662             if (log)
663                 log->Printf ("PlatformLinux::%s failed to create new target: %s", __FUNCTION__, error.AsCString ());
664             return process_sp;
665         }
666 
667         target = new_target_sp.get();
668         if (!target)
669         {
670             error.SetErrorString ("CreateTarget() returned nullptr");
671             if (log)
672                 log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
673             return process_sp;
674         }
675     }
676     else
677     {
678         if (log)
679             log->Printf ("PlatformLinux::%s using provided target", __FUNCTION__);
680     }
681 
682     // Mark target as currently selected target.
683     debugger.GetTargetList().SetSelectedTarget(target);
684 
685     // Now create the gdb-remote process.
686     if (log)
687         log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__);
688     process_sp = target->CreateProcess (listener, "gdb-remote", nullptr);
689 
690     if (!process_sp)
691     {
692         error.SetErrorString ("CreateProcess() failed for gdb-remote process");
693         if (log)
694             log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
695         return process_sp;
696     }
697     else
698     {
699         if (log)
700             log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__);
701     }
702 
703     // Set the unix signals properly.
704     process_sp->SetUnixSignals (Host::GetUnixSignals ());
705 
706     // Adjust launch for a hijacker.
707     ListenerSP listener_sp;
708     if (!launch_info.GetHijackListener ())
709     {
710         if (log)
711             log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
712 
713         listener_sp.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
714         launch_info.SetHijackListener (listener_sp);
715         process_sp->HijackProcessEvents (listener_sp.get ());
716     }
717 
718     // Log file actions.
719     if (log)
720     {
721         log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__);
722 
723         StreamString stream;
724         size_t i = 0;
725         const FileAction *file_action;
726         while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr)
727         {
728             file_action->Dump (stream);
729             log->PutCString (stream.GetString().c_str ());
730             stream.Clear();
731         }
732     }
733 
734     // Do the launch.
735     error = process_sp->Launch(launch_info);
736     if (error.Success ())
737     {
738         // Handle the hijacking of process events.
739         if (listener_sp)
740         {
741             const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
742             process_sp->RestoreProcessEvents();
743 
744             if (state == eStateStopped)
745             {
746                 if (log)
747                     log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n",
748                                  __FUNCTION__, process_sp->GetID (), StateAsCString (state));
749             }
750             else
751             {
752                 if (log)
753                     log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n",
754                                  __FUNCTION__, process_sp->GetID (), StateAsCString (state));
755             }
756         }
757 
758         // Hook up process PTY if we have one (which we should for local debugging with llgs).
759         int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
760         if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
761         {
762             process_sp->SetSTDIOFileDescriptor(pty_fd);
763             if (log)
764                 log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ());
765         }
766         else
767         {
768             if (log)
769                 log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ());
770         }
771     }
772     else
773     {
774         if (log)
775             log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ());
776         // FIXME figure out appropriate cleanup here.  Do we delete the target? Do we delete the process?  Does our caller do that?
777     }
778 
779     return process_sp;
780 }
781 
782 void
783 PlatformLinux::CalculateTrapHandlerSymbolNames ()
784 {
785     m_trap_handlers.push_back (ConstString ("_sigtramp"));
786 }
787 
788 Error
789 PlatformLinux::LaunchNativeProcess (
790     ProcessLaunchInfo &launch_info,
791     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
792     NativeProcessProtocolSP &process_sp)
793 {
794 #if !defined(__linux__)
795     return Error("only implemented on Linux hosts");
796 #else
797     if (!IsHost ())
798         return Error("PlatformLinux::%s (): cannot launch a debug process when not the host", __FUNCTION__);
799 
800     // Retrieve the exe module.
801     lldb::ModuleSP exe_module_sp;
802 
803     Error error = ResolveExecutable (
804         launch_info.GetExecutableFile (),
805         launch_info.GetArchitecture (),
806         exe_module_sp,
807         NULL);
808 
809     if (!error.Success ())
810         return error;
811 
812     if (!exe_module_sp)
813         return Error("exe_module_sp could not be resolved for %s", launch_info.GetExecutableFile ().GetPath ().c_str ());
814 
815     // Launch it for debugging
816     error = NativeProcessLinux::LaunchProcess (
817         exe_module_sp.get (),
818         launch_info,
819         native_delegate,
820         process_sp);
821 
822     return error;
823 #endif
824 }
825 
826 Error
827 PlatformLinux::AttachNativeProcess (lldb::pid_t pid,
828                                     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
829                                     NativeProcessProtocolSP &process_sp)
830 {
831 #if !defined(__linux__)
832     return Error("only implemented on Linux hosts");
833 #else
834     if (!IsHost ())
835         return Error("PlatformLinux::%s (): cannot attach to a debug process when not the host", __FUNCTION__);
836 
837     // Launch it for debugging
838     return NativeProcessLinux::AttachToProcess (pid, native_delegate, process_sp);
839 #endif
840 }
841