1e996fd30SGreg Clayton //===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===//
2e996fd30SGreg Clayton //
3e996fd30SGreg Clayton //                     The LLVM Compiler Infrastructure
4e996fd30SGreg Clayton //
5e996fd30SGreg Clayton // This file is distributed under the University of Illinois Open Source
6e996fd30SGreg Clayton // License. See LICENSE.TXT for details.
7e996fd30SGreg Clayton //
8e996fd30SGreg Clayton //===----------------------------------------------------------------------===//
9e996fd30SGreg Clayton 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
12e996fd30SGreg Clayton #include "PlatformLinux.h"
13b2f1fb29SVirgile Bello #include "lldb/Host/Config.h"
14e996fd30SGreg Clayton 
15e996fd30SGreg Clayton // C Includes
16ecc11474SStephen Wilson #include <stdio.h>
17b2f1fb29SVirgile Bello #ifndef LLDB_DISABLE_POSIX
18ecc11474SStephen Wilson #include <sys/utsname.h>
19b2f1fb29SVirgile Bello #endif
20ecc11474SStephen Wilson 
21e996fd30SGreg Clayton // C++ Includes
22e996fd30SGreg Clayton // Other libraries and framework includes
23e996fd30SGreg Clayton // Project includes
24e996fd30SGreg Clayton #include "lldb/Core/Error.h"
2528041352SGreg Clayton #include "lldb/Core/Debugger.h"
26e996fd30SGreg Clayton #include "lldb/Core/Module.h"
27e996fd30SGreg Clayton #include "lldb/Core/ModuleList.h"
281f746071SGreg Clayton #include "lldb/Core/ModuleSpec.h"
29ecc11474SStephen Wilson #include "lldb/Core/PluginManager.h"
30e996fd30SGreg Clayton #include "lldb/Core/StreamString.h"
31e996fd30SGreg Clayton #include "lldb/Host/FileSpec.h"
32e996fd30SGreg Clayton #include "lldb/Host/Host.h"
33ecc11474SStephen Wilson #include "lldb/Target/Target.h"
34e996fd30SGreg Clayton #include "lldb/Target/Process.h"
35e996fd30SGreg Clayton 
36af245d11STodd Fiala #if defined(__linux__)
37af245d11STodd Fiala #include "../../Process/Linux/NativeProcessLinux.h"
38af245d11STodd Fiala #endif
39af245d11STodd Fiala 
40e996fd30SGreg Clayton using namespace lldb;
41e996fd30SGreg Clayton using namespace lldb_private;
42e996fd30SGreg Clayton 
4328041352SGreg Clayton static uint32_t g_initialize_count = 0;
4428041352SGreg Clayton 
45ecc11474SStephen Wilson Platform *
46b3a40ba8SGreg Clayton PlatformLinux::CreateInstance (bool force, const ArchSpec *arch)
47ecc11474SStephen Wilson {
48b3a40ba8SGreg Clayton     bool create = force;
49b3a40ba8SGreg Clayton     if (create == false && arch && arch->IsValid())
50b3a40ba8SGreg Clayton     {
51b3a40ba8SGreg Clayton         const llvm::Triple &triple = arch->GetTriple();
5270512317SGreg Clayton         switch (triple.getVendor())
5370512317SGreg Clayton         {
5470512317SGreg Clayton             case llvm::Triple::PC:
55b3a40ba8SGreg Clayton                 create = true;
5670512317SGreg Clayton                 break;
5770512317SGreg Clayton 
58dbc6c0bbSGreg Clayton #if defined(__linux__)
59dbc6c0bbSGreg Clayton             // Only accept "unknown" for the vendor if the host is linux and
606a7f3338SBruce Mitchener             // it "unknown" wasn't specified (it was just returned because it
61dbc6c0bbSGreg Clayton             // was NOT specified_
6270512317SGreg Clayton             case llvm::Triple::UnknownArch:
6370512317SGreg Clayton                 create = !arch->TripleVendorWasSpecified();
6470512317SGreg Clayton                 break;
65dbc6c0bbSGreg Clayton #endif
6670512317SGreg Clayton             default:
6770512317SGreg Clayton                 break;
6870512317SGreg Clayton         }
6970512317SGreg Clayton 
7070512317SGreg Clayton         if (create)
7170512317SGreg Clayton         {
7270512317SGreg Clayton             switch (triple.getOS())
7370512317SGreg Clayton             {
7470512317SGreg Clayton                 case llvm::Triple::Linux:
7570512317SGreg Clayton                     break;
7670512317SGreg Clayton 
77dbc6c0bbSGreg Clayton #if defined(__linux__)
78dbc6c0bbSGreg Clayton                 // Only accept "unknown" for the OS if the host is linux and
796a7f3338SBruce Mitchener                 // it "unknown" wasn't specified (it was just returned because it
80dbc6c0bbSGreg Clayton                 // was NOT specified)
8170512317SGreg Clayton                 case llvm::Triple::UnknownOS:
8270512317SGreg Clayton                     create = !arch->TripleOSWasSpecified();
8370512317SGreg Clayton                     break;
84dbc6c0bbSGreg Clayton #endif
8570512317SGreg Clayton                 default:
8670512317SGreg Clayton                     create = false;
8770512317SGreg Clayton                     break;
8870512317SGreg Clayton             }
8970512317SGreg Clayton         }
90b3a40ba8SGreg Clayton     }
91b3a40ba8SGreg Clayton     if (create)
92a4756939STodd Fiala         return new PlatformLinux(false);
93b3a40ba8SGreg Clayton     return NULL;
94ecc11474SStephen Wilson }
95ecc11474SStephen Wilson 
96ecc11474SStephen Wilson 
9757abc5d6SGreg Clayton lldb_private::ConstString
9857abc5d6SGreg Clayton PlatformLinux::GetPluginNameStatic (bool is_host)
99ecc11474SStephen Wilson {
10028041352SGreg Clayton     if (is_host)
10157abc5d6SGreg Clayton     {
10257abc5d6SGreg Clayton         static ConstString g_host_name(Platform::GetHostPlatformName ());
10357abc5d6SGreg Clayton         return g_host_name;
10457abc5d6SGreg Clayton     }
10528041352SGreg Clayton     else
10657abc5d6SGreg Clayton     {
10757abc5d6SGreg Clayton         static ConstString g_remote_name("remote-linux");
10857abc5d6SGreg Clayton         return g_remote_name;
10957abc5d6SGreg Clayton     }
11028041352SGreg Clayton }
11128041352SGreg Clayton 
11228041352SGreg Clayton const char *
11328041352SGreg Clayton PlatformLinux::GetPluginDescriptionStatic (bool is_host)
11428041352SGreg Clayton {
11528041352SGreg Clayton     if (is_host)
11628041352SGreg Clayton         return "Local Linux user platform plug-in.";
11728041352SGreg Clayton     else
11828041352SGreg Clayton         return "Remote Linux user platform plug-in.";
119ecc11474SStephen Wilson }
120ecc11474SStephen Wilson 
12157abc5d6SGreg Clayton lldb_private::ConstString
12257abc5d6SGreg Clayton PlatformLinux::GetPluginName()
12357abc5d6SGreg Clayton {
12457abc5d6SGreg Clayton     return GetPluginNameStatic(IsHost());
12557abc5d6SGreg Clayton }
12657abc5d6SGreg Clayton 
127e996fd30SGreg Clayton void
128e996fd30SGreg Clayton PlatformLinux::Initialize ()
129e996fd30SGreg Clayton {
13028041352SGreg Clayton     if (g_initialize_count++ == 0)
131ecc11474SStephen Wilson     {
13228041352SGreg Clayton #if defined(__linux__)
13328041352SGreg Clayton         PlatformSP default_platform_sp (new PlatformLinux(true));
13428041352SGreg Clayton         default_platform_sp->SetSystemArchitecture (Host::GetArchitecture());
135e996fd30SGreg Clayton         Platform::SetDefaultPlatform (default_platform_sp);
13628041352SGreg Clayton #endif
13757abc5d6SGreg Clayton         PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false),
13828041352SGreg Clayton                                       PlatformLinux::GetPluginDescriptionStatic(false),
13928041352SGreg Clayton                                       PlatformLinux::CreateInstance);
140ecc11474SStephen Wilson     }
141e996fd30SGreg Clayton }
142e996fd30SGreg Clayton 
143e996fd30SGreg Clayton void
144e996fd30SGreg Clayton PlatformLinux::Terminate ()
145e996fd30SGreg Clayton {
14628041352SGreg Clayton     if (g_initialize_count > 0)
14728041352SGreg Clayton     {
14828041352SGreg Clayton         if (--g_initialize_count == 0)
14928041352SGreg Clayton         {
15028041352SGreg Clayton             PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance);
151e996fd30SGreg Clayton         }
15228041352SGreg Clayton     }
15328041352SGreg Clayton }
154e996fd30SGreg Clayton 
155e996fd30SGreg Clayton Error
156e996fd30SGreg Clayton PlatformLinux::ResolveExecutable (const FileSpec &exe_file,
157e996fd30SGreg Clayton                                   const ArchSpec &exe_arch,
158ea5e0cc3SGreg Clayton                                   lldb::ModuleSP &exe_module_sp,
159ea5e0cc3SGreg Clayton                                   const FileSpecList *module_search_paths_ptr)
160e996fd30SGreg Clayton {
161e996fd30SGreg Clayton     Error error;
162e996fd30SGreg Clayton     // Nothing special to do here, just use the actual file and architecture
163e996fd30SGreg Clayton 
16428041352SGreg Clayton     char exe_path[PATH_MAX];
165e996fd30SGreg Clayton     FileSpec resolved_exe_file (exe_file);
166e996fd30SGreg Clayton 
16728041352SGreg Clayton     if (IsHost())
16828041352SGreg Clayton     {
16928041352SGreg Clayton         // If we have "ls" as the exe_file, resolve the executable location based on
170e996fd30SGreg Clayton         // the current path variables
171e996fd30SGreg Clayton         if (!resolved_exe_file.Exists())
17228041352SGreg Clayton         {
17328041352SGreg Clayton             exe_file.GetPath(exe_path, sizeof(exe_path));
17428041352SGreg Clayton             resolved_exe_file.SetFile(exe_path, true);
17528041352SGreg Clayton         }
17628041352SGreg Clayton 
17728041352SGreg Clayton         if (!resolved_exe_file.Exists())
178e996fd30SGreg Clayton             resolved_exe_file.ResolveExecutableLocation ();
179e996fd30SGreg Clayton 
18028041352SGreg Clayton         if (resolved_exe_file.Exists())
18128041352SGreg Clayton             error.Clear();
18228041352SGreg Clayton         else
18328041352SGreg Clayton         {
18428041352SGreg Clayton             exe_file.GetPath(exe_path, sizeof(exe_path));
18528041352SGreg Clayton             error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
18628041352SGreg Clayton         }
18728041352SGreg Clayton     }
18828041352SGreg Clayton     else
18928041352SGreg Clayton     {
19028041352SGreg Clayton         if (m_remote_platform_sp)
19128041352SGreg Clayton         {
19228041352SGreg Clayton             error = m_remote_platform_sp->ResolveExecutable (exe_file,
19328041352SGreg Clayton                                                              exe_arch,
1940c90ef47SGreg Clayton                                                              exe_module_sp,
1950c90ef47SGreg Clayton                                                              NULL);
19628041352SGreg Clayton         }
19728041352SGreg Clayton         else
19828041352SGreg Clayton         {
19928041352SGreg Clayton             // We may connect to a process and use the provided executable (Don't use local $PATH).
200e996fd30SGreg Clayton 
201e996fd30SGreg Clayton             if (resolved_exe_file.Exists())
20228041352SGreg Clayton                 error.Clear();
20328041352SGreg Clayton             else
20428041352SGreg Clayton                 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
20528041352SGreg Clayton         }
20628041352SGreg Clayton     }
20728041352SGreg Clayton 
20828041352SGreg Clayton     if (error.Success())
209e996fd30SGreg Clayton     {
210ea5e0cc3SGreg Clayton         ModuleSpec module_spec (resolved_exe_file, exe_arch);
211e996fd30SGreg Clayton         if (exe_arch.IsValid())
212e996fd30SGreg Clayton         {
213ea5e0cc3SGreg Clayton             error = ModuleList::GetSharedModule (module_spec,
214e996fd30SGreg Clayton                                                  exe_module_sp,
215e996fd30SGreg Clayton                                                  NULL,
2160c90ef47SGreg Clayton                                                  NULL,
217e996fd30SGreg Clayton                                                  NULL);
2189f0013d8SMichael Sartain             if (error.Fail())
2199f0013d8SMichael Sartain             {
2209f0013d8SMichael Sartain                 // If we failed, it may be because the vendor and os aren't known. If that is the
2219f0013d8SMichael Sartain                 // case, try setting them to the host architecture and give it another try.
2229f0013d8SMichael Sartain                 llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple();
2239f0013d8SMichael Sartain                 bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
2249f0013d8SMichael Sartain                 bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
2259f0013d8SMichael Sartain                 if (!is_vendor_specified || !is_os_specified)
2269f0013d8SMichael Sartain                 {
2279f0013d8SMichael Sartain                     const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple();
2289f0013d8SMichael Sartain 
2299f0013d8SMichael Sartain                     if (!is_vendor_specified)
2309f0013d8SMichael Sartain                         module_triple.setVendorName (host_triple.getVendorName());
2319f0013d8SMichael Sartain                     if (!is_os_specified)
2329f0013d8SMichael Sartain                         module_triple.setOSName (host_triple.getOSName());
2339f0013d8SMichael Sartain 
2349f0013d8SMichael Sartain                     error = ModuleList::GetSharedModule (module_spec,
2359f0013d8SMichael Sartain                                                          exe_module_sp,
2369f0013d8SMichael Sartain                                                          NULL,
2379f0013d8SMichael Sartain                                                          NULL,
2389f0013d8SMichael Sartain                                                          NULL);
2399f0013d8SMichael Sartain                 }
2409f0013d8SMichael Sartain             }
241e996fd30SGreg Clayton 
242e635db49SSean Callanan             // TODO find out why exe_module_sp might be NULL
243e635db49SSean Callanan             if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
244e996fd30SGreg Clayton             {
245e996fd30SGreg Clayton                 exe_module_sp.reset();
246b5ad4ec7SGreg Clayton                 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
247b5ad4ec7SGreg Clayton                                                 exe_file.GetPath().c_str(),
248e996fd30SGreg Clayton                                                 exe_arch.GetArchitectureName());
249e996fd30SGreg Clayton             }
250e996fd30SGreg Clayton         }
251e996fd30SGreg Clayton         else
252e996fd30SGreg Clayton         {
253e996fd30SGreg Clayton             // No valid architecture was specified, ask the platform for
254e996fd30SGreg Clayton             // the architectures that we should be using (in the correct order)
255e996fd30SGreg Clayton             // and see if we can find a match that way
256e996fd30SGreg Clayton             StreamString arch_names;
257ea5e0cc3SGreg Clayton             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
258e996fd30SGreg Clayton             {
259ea5e0cc3SGreg Clayton                 error = ModuleList::GetSharedModule (module_spec,
260e996fd30SGreg Clayton                                                      exe_module_sp,
261e996fd30SGreg Clayton                                                      NULL,
2620c90ef47SGreg Clayton                                                      NULL,
263e996fd30SGreg Clayton                                                      NULL);
264e996fd30SGreg Clayton                 // Did we find an executable using one of the
265e996fd30SGreg Clayton                 if (error.Success())
266e996fd30SGreg Clayton                 {
267e996fd30SGreg Clayton                     if (exe_module_sp && exe_module_sp->GetObjectFile())
268e996fd30SGreg Clayton                         break;
269e996fd30SGreg Clayton                     else
270e996fd30SGreg Clayton                         error.SetErrorToGenericError();
271e996fd30SGreg Clayton                 }
272e996fd30SGreg Clayton 
273e996fd30SGreg Clayton                 if (idx > 0)
274e996fd30SGreg Clayton                     arch_names.PutCString (", ");
275ea5e0cc3SGreg Clayton                 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
276e996fd30SGreg Clayton             }
277e996fd30SGreg Clayton 
278e996fd30SGreg Clayton             if (error.Fail() || !exe_module_sp)
279e996fd30SGreg Clayton             {
280b5ad4ec7SGreg Clayton                 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
281b5ad4ec7SGreg Clayton                                                 exe_file.GetPath().c_str(),
28257abc5d6SGreg Clayton                                                 GetPluginName().GetCString(),
283e996fd30SGreg Clayton                                                 arch_names.GetString().c_str());
284e996fd30SGreg Clayton             }
285e996fd30SGreg Clayton         }
286e996fd30SGreg Clayton     }
287e996fd30SGreg Clayton 
288e996fd30SGreg Clayton     return error;
289e996fd30SGreg Clayton }
290e996fd30SGreg Clayton 
291e996fd30SGreg Clayton Error
292fc995725SSteve Pucci PlatformLinux::GetFileWithUUID (const FileSpec &platform_file,
29328041352SGreg Clayton                                 const UUID *uuid_ptr, FileSpec &local_file)
294e996fd30SGreg Clayton {
29528041352SGreg Clayton     if (IsRemote())
29628041352SGreg Clayton     {
29728041352SGreg Clayton         if (m_remote_platform_sp)
298fc995725SSteve Pucci             return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
29928041352SGreg Clayton     }
30028041352SGreg Clayton 
301e996fd30SGreg Clayton     // Default to the local case
302e996fd30SGreg Clayton     local_file = platform_file;
303e996fd30SGreg Clayton     return Error();
304e996fd30SGreg Clayton }
305e996fd30SGreg Clayton 
306e996fd30SGreg Clayton 
307e996fd30SGreg Clayton //------------------------------------------------------------------
308e996fd30SGreg Clayton /// Default Constructor
309e996fd30SGreg Clayton //------------------------------------------------------------------
31028041352SGreg Clayton PlatformLinux::PlatformLinux (bool is_host) :
31128041352SGreg Clayton     Platform(is_host),  // This is the local host platform
31228041352SGreg Clayton     m_remote_platform_sp ()
313e996fd30SGreg Clayton {
314e996fd30SGreg Clayton }
315e996fd30SGreg Clayton 
316e996fd30SGreg Clayton //------------------------------------------------------------------
317e996fd30SGreg Clayton /// Destructor.
318e996fd30SGreg Clayton ///
319e996fd30SGreg Clayton /// The destructor is virtual since this class is designed to be
320e996fd30SGreg Clayton /// inherited from by the plug-in instance.
321e996fd30SGreg Clayton //------------------------------------------------------------------
322e996fd30SGreg Clayton PlatformLinux::~PlatformLinux()
323e996fd30SGreg Clayton {
324e996fd30SGreg Clayton }
325e996fd30SGreg Clayton 
326e996fd30SGreg Clayton bool
32713e8e1c3SJohnny Chen PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
328e996fd30SGreg Clayton {
32928041352SGreg Clayton     bool success = false;
33028041352SGreg Clayton     if (IsHost())
33128041352SGreg Clayton     {
33228041352SGreg Clayton         success = Platform::GetProcessInfo (pid, process_info);
33328041352SGreg Clayton     }
33428041352SGreg Clayton     else
33528041352SGreg Clayton     {
33628041352SGreg Clayton         if (m_remote_platform_sp)
33728041352SGreg Clayton             success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
33828041352SGreg Clayton     }
33928041352SGreg Clayton     return success;
340e996fd30SGreg Clayton }
341e996fd30SGreg Clayton 
342e996fd30SGreg Clayton bool
343e996fd30SGreg Clayton PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
344e996fd30SGreg Clayton {
345e996fd30SGreg Clayton     if (idx == 0)
346e996fd30SGreg Clayton     {
347e996fd30SGreg Clayton         arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
348e996fd30SGreg Clayton         return arch.IsValid();
349e996fd30SGreg Clayton     }
350542e4075SGreg Clayton     else if (idx == 1)
351542e4075SGreg Clayton     {
352542e4075SGreg Clayton         // If the default host architecture is 64-bit, look for a 32-bit variant
353542e4075SGreg Clayton         ArchSpec hostArch
354542e4075SGreg Clayton                       = Host::GetArchitecture(Host::eSystemDefaultArchitecture);
355542e4075SGreg Clayton         if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
356542e4075SGreg Clayton         {
357542e4075SGreg Clayton             arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
358542e4075SGreg Clayton             return arch.IsValid();
359542e4075SGreg Clayton         }
360542e4075SGreg Clayton     }
361e996fd30SGreg Clayton     return false;
362e996fd30SGreg Clayton }
363ecc11474SStephen Wilson 
364ecc11474SStephen Wilson void
365ecc11474SStephen Wilson PlatformLinux::GetStatus (Stream &strm)
366ecc11474SStephen Wilson {
3673be69dacSDaniel Malea     Platform::GetStatus(strm);
368ecc11474SStephen Wilson 
369b2f1fb29SVirgile Bello #ifndef LLDB_DISABLE_POSIX
370b2f1fb29SVirgile Bello     struct utsname un;
371b2f1fb29SVirgile Bello 
3723be69dacSDaniel Malea     if (uname(&un))
3733be69dacSDaniel Malea         return;
3743be69dacSDaniel Malea 
3753be69dacSDaniel Malea     strm.Printf ("    Kernel: %s\n", un.sysname);
3763be69dacSDaniel Malea     strm.Printf ("   Release: %s\n", un.release);
3773be69dacSDaniel Malea     strm.Printf ("   Version: %s\n", un.version);
378b2f1fb29SVirgile Bello #endif
379ecc11474SStephen Wilson }
380ecc11474SStephen Wilson 
381ecc11474SStephen Wilson size_t
382ecc11474SStephen Wilson PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
383ecc11474SStephen Wilson                                                 BreakpointSite *bp_site)
384ecc11474SStephen Wilson {
385ecc11474SStephen Wilson     ArchSpec arch = target.GetArchitecture();
38628041352SGreg Clayton     const uint8_t *trap_opcode = NULL;
38728041352SGreg Clayton     size_t trap_opcode_size = 0;
388ecc11474SStephen Wilson 
389906e9acfSGreg Clayton     switch (arch.GetMachine())
390ecc11474SStephen Wilson     {
391ecc11474SStephen Wilson     default:
392ecc11474SStephen Wilson         assert(false && "CPU type not supported!");
393ecc11474SStephen Wilson         break;
394ecc11474SStephen Wilson 
395906e9acfSGreg Clayton     case llvm::Triple::x86:
396906e9acfSGreg Clayton     case llvm::Triple::x86_64:
39728041352SGreg Clayton         {
39828041352SGreg Clayton             static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
39928041352SGreg Clayton             trap_opcode = g_i386_breakpoint_opcode;
40028041352SGreg Clayton             trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
40128041352SGreg Clayton         }
402ecc11474SStephen Wilson         break;
403906e9acfSGreg Clayton     case llvm::Triple::hexagon:
404*8006d319SDeepak Panickal         {
405*8006d319SDeepak Panickal             static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
406*8006d319SDeepak Panickal             trap_opcode = g_hex_opcode;
407*8006d319SDeepak Panickal             trap_opcode_size = sizeof(g_hex_opcode);
408*8006d319SDeepak Panickal         }
409*8006d319SDeepak Panickal         break;
410ecc11474SStephen Wilson     }
411ecc11474SStephen Wilson 
41228041352SGreg Clayton     if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
41328041352SGreg Clayton         return trap_opcode_size;
41428041352SGreg Clayton     return 0;
41528041352SGreg Clayton }
41628041352SGreg Clayton 
41728041352SGreg Clayton Error
41828041352SGreg Clayton PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info)
41928041352SGreg Clayton {
42028041352SGreg Clayton     Error error;
42128041352SGreg Clayton 
42228041352SGreg Clayton     if (IsHost())
42328041352SGreg Clayton     {
42428041352SGreg Clayton         if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
42528041352SGreg Clayton         {
42628041352SGreg Clayton             const bool is_localhost = true;
427d1cf11a7SGreg Clayton             const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
428d1cf11a7SGreg Clayton             const bool first_arg_is_full_shell_command = false;
429d3990793SJim Ingham             uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info);
430d1cf11a7SGreg Clayton             if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
431d1cf11a7SGreg Clayton                                                                   is_localhost,
432d1cf11a7SGreg Clayton                                                                   will_debug,
433df0ae22fSJim Ingham                                                                   first_arg_is_full_shell_command,
434df0ae22fSJim Ingham                                                                   num_resumes))
43528041352SGreg Clayton                 return error;
43628041352SGreg Clayton         }
43728041352SGreg Clayton         error = Platform::LaunchProcess (launch_info);
43828041352SGreg Clayton     }
43928041352SGreg Clayton     else
44028041352SGreg Clayton     {
44128041352SGreg Clayton         error.SetErrorString ("the platform is not currently connected");
44228041352SGreg Clayton     }
44328041352SGreg Clayton     return error;
444ecc11474SStephen Wilson }
44513e8e1c3SJohnny Chen 
44613e8e1c3SJohnny Chen lldb::ProcessSP
447fb2b629dSPeter Collingbourne PlatformLinux::Attach(ProcessAttachInfo &attach_info,
44813e8e1c3SJohnny Chen                       Debugger &debugger,
44913e8e1c3SJohnny Chen                       Target *target,
45013e8e1c3SJohnny Chen                       Listener &listener,
45113e8e1c3SJohnny Chen                       Error &error)
45213e8e1c3SJohnny Chen {
45328041352SGreg Clayton     lldb::ProcessSP process_sp;
45428041352SGreg Clayton     if (IsHost())
45528041352SGreg Clayton     {
45628041352SGreg Clayton         if (target == NULL)
45728041352SGreg Clayton         {
45828041352SGreg Clayton             TargetSP new_target_sp;
45928041352SGreg Clayton             ArchSpec emptyArchSpec;
46028041352SGreg Clayton 
46128041352SGreg Clayton             error = debugger.GetTargetList().CreateTarget (debugger,
462a0ca6601SGreg Clayton                                                            NULL,
46328041352SGreg Clayton                                                            emptyArchSpec,
46428041352SGreg Clayton                                                            false,
46528041352SGreg Clayton                                                            m_remote_platform_sp,
46628041352SGreg Clayton                                                            new_target_sp);
46728041352SGreg Clayton             target = new_target_sp.get();
46828041352SGreg Clayton         }
46928041352SGreg Clayton         else
47028041352SGreg Clayton             error.Clear();
47128041352SGreg Clayton 
47228041352SGreg Clayton         if (target && error.Success())
47328041352SGreg Clayton         {
47428041352SGreg Clayton             debugger.GetTargetList().SetSelectedTarget(target);
47528041352SGreg Clayton 
4760c90ef47SGreg Clayton             process_sp = target->CreateProcess (listener,
4770c90ef47SGreg Clayton                                                 attach_info.GetProcessPluginName(),
4780c90ef47SGreg Clayton                                                 NULL);
47928041352SGreg Clayton 
48028041352SGreg Clayton             if (process_sp)
48128041352SGreg Clayton                 error = process_sp->Attach (attach_info);
48228041352SGreg Clayton         }
48328041352SGreg Clayton     }
48428041352SGreg Clayton     else
48528041352SGreg Clayton     {
48628041352SGreg Clayton         if (m_remote_platform_sp)
48728041352SGreg Clayton             process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
48828041352SGreg Clayton         else
48928041352SGreg Clayton             error.SetErrorString ("the platform is not currently connected");
49028041352SGreg Clayton     }
49128041352SGreg Clayton     return process_sp;
49213e8e1c3SJohnny Chen }
4932094dbf4SJason Molenda 
4942094dbf4SJason Molenda void
4952094dbf4SJason Molenda PlatformLinux::CalculateTrapHandlerSymbolNames ()
4962094dbf4SJason Molenda {
4972094dbf4SJason Molenda     m_trap_handlers.push_back (ConstString ("_sigtramp"));
4982094dbf4SJason Molenda }
499af245d11STodd Fiala 
500af245d11STodd Fiala Error
501af245d11STodd Fiala PlatformLinux::LaunchNativeProcess (
502af245d11STodd Fiala     ProcessLaunchInfo &launch_info,
503af245d11STodd Fiala     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
504af245d11STodd Fiala     NativeProcessProtocolSP &process_sp)
505af245d11STodd Fiala {
506af245d11STodd Fiala #if !defined(__linux__)
507af245d11STodd Fiala     return Error("only implemented on Linux hosts");
508af245d11STodd Fiala #else
509af245d11STodd Fiala     if (!IsHost ())
510af245d11STodd Fiala         return Error("PlatformLinux::%s (): cannot launch a debug process when not the host", __FUNCTION__);
511af245d11STodd Fiala 
512af245d11STodd Fiala     // Retrieve the exe module.
513af245d11STodd Fiala     lldb::ModuleSP exe_module_sp;
514af245d11STodd Fiala 
515af245d11STodd Fiala     Error error = ResolveExecutable (
516af245d11STodd Fiala         launch_info.GetExecutableFile (),
517af245d11STodd Fiala         launch_info.GetArchitecture (),
518af245d11STodd Fiala         exe_module_sp,
519af245d11STodd Fiala         NULL);
520af245d11STodd Fiala 
521af245d11STodd Fiala     if (!error.Success ())
522af245d11STodd Fiala         return error;
523af245d11STodd Fiala 
524af245d11STodd Fiala     if (!exe_module_sp)
525af245d11STodd Fiala         return Error("exe_module_sp could not be resolved for %s", launch_info.GetExecutableFile ().GetPath ().c_str ());
526af245d11STodd Fiala 
527af245d11STodd Fiala     // Launch it for debugging
528af245d11STodd Fiala     error = NativeProcessLinux::LaunchProcess (
529af245d11STodd Fiala         exe_module_sp.get (),
530af245d11STodd Fiala         launch_info,
531af245d11STodd Fiala         native_delegate,
532af245d11STodd Fiala         process_sp);
533af245d11STodd Fiala 
534af245d11STodd Fiala     return error;
535af245d11STodd Fiala #endif
536af245d11STodd Fiala }
537af245d11STodd Fiala 
538af245d11STodd Fiala Error
539af245d11STodd Fiala PlatformLinux::AttachNativeProcess (lldb::pid_t pid,
540af245d11STodd Fiala                                     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
541af245d11STodd Fiala                                     NativeProcessProtocolSP &process_sp)
542af245d11STodd Fiala {
543af245d11STodd Fiala #if !defined(__linux__)
544af245d11STodd Fiala     return Error("only implemented on Linux hosts");
545af245d11STodd Fiala #else
546af245d11STodd Fiala     if (!IsHost ())
547af245d11STodd Fiala         return Error("PlatformLinux::%s (): cannot attach to a debug process when not the host", __FUNCTION__);
548af245d11STodd Fiala 
549af245d11STodd Fiala     // Launch it for debugging
550af245d11STodd Fiala     return NativeProcessLinux::AttachToProcess (pid, native_delegate, process_sp);
551af245d11STodd Fiala #endif
552af245d11STodd Fiala }
553af245d11STodd Fiala 
554