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