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" 26015d818bSTodd Fiala #include "lldb/Core/Log.h" 27e996fd30SGreg Clayton #include "lldb/Core/Module.h" 28e996fd30SGreg Clayton #include "lldb/Core/ModuleList.h" 291f746071SGreg Clayton #include "lldb/Core/ModuleSpec.h" 30ecc11474SStephen Wilson #include "lldb/Core/PluginManager.h" 31e996fd30SGreg Clayton #include "lldb/Core/StreamString.h" 32e996fd30SGreg Clayton #include "lldb/Host/FileSpec.h" 3313b18261SZachary Turner #include "lldb/Host/HostInfo.h" 34ecc11474SStephen Wilson #include "lldb/Target/Target.h" 35e996fd30SGreg Clayton #include "lldb/Target/Process.h" 36e996fd30SGreg Clayton 37af245d11STodd Fiala #if defined(__linux__) 38af245d11STodd Fiala #include "../../Process/Linux/NativeProcessLinux.h" 39af245d11STodd Fiala #endif 40af245d11STodd Fiala 41e996fd30SGreg Clayton using namespace lldb; 42e996fd30SGreg Clayton using namespace lldb_private; 43e996fd30SGreg Clayton 4428041352SGreg Clayton static uint32_t g_initialize_count = 0; 4528041352SGreg Clayton 46281961a8STodd Fiala //------------------------------------------------------------------ 47281961a8STodd Fiala /// Code to handle the PlatformLinux settings 48281961a8STodd Fiala //------------------------------------------------------------------ 49281961a8STodd Fiala 50281961a8STodd Fiala static PropertyDefinition 51281961a8STodd Fiala g_properties[] = 52281961a8STodd Fiala { 53281961a8STodd Fiala { "use-llgs-for-local" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "Control whether the platform uses llgs for local debug sessions." }, 54281961a8STodd Fiala { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL } 55281961a8STodd Fiala }; 56281961a8STodd Fiala 57281961a8STodd Fiala enum { 58281961a8STodd Fiala ePropertyUseLlgsForLocal = 0, 59281961a8STodd Fiala }; 60281961a8STodd Fiala 61281961a8STodd Fiala 62281961a8STodd Fiala 63281961a8STodd Fiala class PlatformLinuxProperties : public Properties 64281961a8STodd Fiala { 65281961a8STodd Fiala public: 66281961a8STodd Fiala 67281961a8STodd Fiala static ConstString & 68281961a8STodd Fiala GetSettingName () 69281961a8STodd Fiala { 70281961a8STodd Fiala static ConstString g_setting_name("linux"); 71281961a8STodd Fiala return g_setting_name; 72281961a8STodd Fiala } 73281961a8STodd Fiala 74281961a8STodd Fiala PlatformLinuxProperties() : 75281961a8STodd Fiala Properties () 76281961a8STodd Fiala { 77281961a8STodd Fiala m_collection_sp.reset (new OptionValueProperties(GetSettingName())); 78281961a8STodd Fiala m_collection_sp->Initialize(g_properties); 79281961a8STodd Fiala } 80281961a8STodd Fiala 81281961a8STodd Fiala virtual 82281961a8STodd Fiala ~PlatformLinuxProperties() 83281961a8STodd Fiala { 84281961a8STodd Fiala } 85281961a8STodd Fiala 86281961a8STodd Fiala bool 87281961a8STodd Fiala GetUseLlgsForLocal() const 88281961a8STodd Fiala { 89281961a8STodd Fiala const uint32_t idx = ePropertyUseLlgsForLocal; 90281961a8STodd Fiala return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 91281961a8STodd Fiala } 92281961a8STodd Fiala }; 93281961a8STodd Fiala 94281961a8STodd Fiala typedef std::shared_ptr<PlatformLinuxProperties> PlatformLinuxPropertiesSP; 95281961a8STodd Fiala 96281961a8STodd Fiala static const PlatformLinuxPropertiesSP & 97281961a8STodd Fiala GetGlobalProperties() 98281961a8STodd Fiala { 99281961a8STodd Fiala static PlatformLinuxPropertiesSP g_settings_sp; 100281961a8STodd Fiala if (!g_settings_sp) 101281961a8STodd Fiala g_settings_sp.reset (new PlatformLinuxProperties ()); 102281961a8STodd Fiala return g_settings_sp; 103281961a8STodd Fiala } 104281961a8STodd Fiala 105281961a8STodd Fiala void 106281961a8STodd Fiala PlatformLinux::DebuggerInitialize (lldb_private::Debugger &debugger) 107281961a8STodd Fiala { 108281961a8STodd Fiala if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformLinuxProperties::GetSettingName())) 109281961a8STodd Fiala { 110281961a8STodd Fiala const bool is_global_setting = true; 111281961a8STodd Fiala PluginManager::CreateSettingForPlatformPlugin (debugger, 112281961a8STodd Fiala GetGlobalProperties()->GetValueProperties(), 113281961a8STodd Fiala ConstString ("Properties for the PlatformLinux plug-in."), 114281961a8STodd Fiala is_global_setting); 115281961a8STodd Fiala } 116281961a8STodd Fiala } 117281961a8STodd Fiala 118281961a8STodd Fiala 119281961a8STodd Fiala //------------------------------------------------------------------ 120281961a8STodd Fiala 121*615eb7e6SGreg Clayton PlatformSP 122b3a40ba8SGreg Clayton PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) 123ecc11474SStephen Wilson { 124015d818bSTodd Fiala Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 125015d818bSTodd Fiala if (log) 126015d818bSTodd Fiala { 127015d818bSTodd Fiala const char *arch_name; 128015d818bSTodd Fiala if (arch && arch->GetArchitectureName ()) 129015d818bSTodd Fiala arch_name = arch->GetArchitectureName (); 130015d818bSTodd Fiala else 131015d818bSTodd Fiala arch_name = "<null>"; 132015d818bSTodd Fiala 133015d818bSTodd Fiala const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>"; 134015d818bSTodd Fiala 135015d818bSTodd Fiala log->Printf ("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); 136015d818bSTodd Fiala } 137015d818bSTodd Fiala 138b3a40ba8SGreg Clayton bool create = force; 139b3a40ba8SGreg Clayton if (create == false && arch && arch->IsValid()) 140b3a40ba8SGreg Clayton { 141b3a40ba8SGreg Clayton const llvm::Triple &triple = arch->GetTriple(); 14270512317SGreg Clayton switch (triple.getVendor()) 14370512317SGreg Clayton { 14470512317SGreg Clayton case llvm::Triple::PC: 145b3a40ba8SGreg Clayton create = true; 14670512317SGreg Clayton break; 14770512317SGreg Clayton 148dbc6c0bbSGreg Clayton #if defined(__linux__) 149dbc6c0bbSGreg Clayton // Only accept "unknown" for the vendor if the host is linux and 1506a7f3338SBruce Mitchener // it "unknown" wasn't specified (it was just returned because it 151dbc6c0bbSGreg Clayton // was NOT specified_ 152015d818bSTodd Fiala case llvm::Triple::VendorType::UnknownVendor: 15370512317SGreg Clayton create = !arch->TripleVendorWasSpecified(); 15470512317SGreg Clayton break; 155dbc6c0bbSGreg Clayton #endif 15670512317SGreg Clayton default: 15770512317SGreg Clayton break; 15870512317SGreg Clayton } 15970512317SGreg Clayton 16070512317SGreg Clayton if (create) 16170512317SGreg Clayton { 16270512317SGreg Clayton switch (triple.getOS()) 16370512317SGreg Clayton { 16470512317SGreg Clayton case llvm::Triple::Linux: 16570512317SGreg Clayton break; 16670512317SGreg Clayton 167dbc6c0bbSGreg Clayton #if defined(__linux__) 168dbc6c0bbSGreg Clayton // Only accept "unknown" for the OS if the host is linux and 1696a7f3338SBruce Mitchener // it "unknown" wasn't specified (it was just returned because it 170dbc6c0bbSGreg Clayton // was NOT specified) 171015d818bSTodd Fiala case llvm::Triple::OSType::UnknownOS: 17270512317SGreg Clayton create = !arch->TripleOSWasSpecified(); 17370512317SGreg Clayton break; 174dbc6c0bbSGreg Clayton #endif 17570512317SGreg Clayton default: 17670512317SGreg Clayton create = false; 17770512317SGreg Clayton break; 17870512317SGreg Clayton } 17970512317SGreg Clayton } 180b3a40ba8SGreg Clayton } 181015d818bSTodd Fiala 182b3a40ba8SGreg Clayton if (create) 183015d818bSTodd Fiala { 184015d818bSTodd Fiala if (log) 185015d818bSTodd Fiala log->Printf ("PlatformLinux::%s() creating remote-linux platform", __FUNCTION__); 186*615eb7e6SGreg Clayton return PlatformSP(new PlatformLinux(false)); 187015d818bSTodd Fiala } 188015d818bSTodd Fiala 189015d818bSTodd Fiala if (log) 190015d818bSTodd Fiala log->Printf ("PlatformLinux::%s() aborting creation of remote-linux platform", __FUNCTION__); 191015d818bSTodd Fiala 192*615eb7e6SGreg Clayton return PlatformSP(); 193ecc11474SStephen Wilson } 194ecc11474SStephen Wilson 195ecc11474SStephen Wilson 19657abc5d6SGreg Clayton lldb_private::ConstString 19757abc5d6SGreg Clayton PlatformLinux::GetPluginNameStatic (bool is_host) 198ecc11474SStephen Wilson { 19928041352SGreg Clayton if (is_host) 20057abc5d6SGreg Clayton { 20157abc5d6SGreg Clayton static ConstString g_host_name(Platform::GetHostPlatformName ()); 20257abc5d6SGreg Clayton return g_host_name; 20357abc5d6SGreg Clayton } 20428041352SGreg Clayton else 20557abc5d6SGreg Clayton { 20657abc5d6SGreg Clayton static ConstString g_remote_name("remote-linux"); 20757abc5d6SGreg Clayton return g_remote_name; 20857abc5d6SGreg Clayton } 20928041352SGreg Clayton } 21028041352SGreg Clayton 21128041352SGreg Clayton const char * 21228041352SGreg Clayton PlatformLinux::GetPluginDescriptionStatic (bool is_host) 21328041352SGreg Clayton { 21428041352SGreg Clayton if (is_host) 21528041352SGreg Clayton return "Local Linux user platform plug-in."; 21628041352SGreg Clayton else 21728041352SGreg Clayton return "Remote Linux user platform plug-in."; 218ecc11474SStephen Wilson } 219ecc11474SStephen Wilson 22057abc5d6SGreg Clayton lldb_private::ConstString 22157abc5d6SGreg Clayton PlatformLinux::GetPluginName() 22257abc5d6SGreg Clayton { 22357abc5d6SGreg Clayton return GetPluginNameStatic(IsHost()); 22457abc5d6SGreg Clayton } 22557abc5d6SGreg Clayton 226e996fd30SGreg Clayton void 227e996fd30SGreg Clayton PlatformLinux::Initialize () 228e996fd30SGreg Clayton { 22928041352SGreg Clayton if (g_initialize_count++ == 0) 230ecc11474SStephen Wilson { 23128041352SGreg Clayton #if defined(__linux__) 23228041352SGreg Clayton PlatformSP default_platform_sp (new PlatformLinux(true)); 23313b18261SZachary Turner default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 234*615eb7e6SGreg Clayton Platform::SetHostPlatform (default_platform_sp); 23528041352SGreg Clayton #endif 23657abc5d6SGreg Clayton PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false), 23728041352SGreg Clayton PlatformLinux::GetPluginDescriptionStatic(false), 238281961a8STodd Fiala PlatformLinux::CreateInstance, 239281961a8STodd Fiala PlatformLinux::DebuggerInitialize); 240ecc11474SStephen Wilson } 241e996fd30SGreg Clayton } 242e996fd30SGreg Clayton 243e996fd30SGreg Clayton void 244e996fd30SGreg Clayton PlatformLinux::Terminate () 245e996fd30SGreg Clayton { 24628041352SGreg Clayton if (g_initialize_count > 0) 24728041352SGreg Clayton { 24828041352SGreg Clayton if (--g_initialize_count == 0) 24928041352SGreg Clayton { 25028041352SGreg Clayton PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance); 251e996fd30SGreg Clayton } 25228041352SGreg Clayton } 25328041352SGreg Clayton } 254e996fd30SGreg Clayton 255e996fd30SGreg Clayton Error 256e996fd30SGreg Clayton PlatformLinux::ResolveExecutable (const FileSpec &exe_file, 257e996fd30SGreg Clayton const ArchSpec &exe_arch, 258ea5e0cc3SGreg Clayton lldb::ModuleSP &exe_module_sp, 259ea5e0cc3SGreg Clayton const FileSpecList *module_search_paths_ptr) 260e996fd30SGreg Clayton { 261e996fd30SGreg Clayton Error error; 262e996fd30SGreg Clayton // Nothing special to do here, just use the actual file and architecture 263e996fd30SGreg Clayton 26428041352SGreg Clayton char exe_path[PATH_MAX]; 265e996fd30SGreg Clayton FileSpec resolved_exe_file (exe_file); 266e996fd30SGreg Clayton 26728041352SGreg Clayton if (IsHost()) 26828041352SGreg Clayton { 26928041352SGreg Clayton // If we have "ls" as the exe_file, resolve the executable location based on 270e996fd30SGreg Clayton // the current path variables 271e996fd30SGreg Clayton if (!resolved_exe_file.Exists()) 27228041352SGreg Clayton { 27328041352SGreg Clayton exe_file.GetPath(exe_path, sizeof(exe_path)); 27428041352SGreg Clayton resolved_exe_file.SetFile(exe_path, true); 27528041352SGreg Clayton } 27628041352SGreg Clayton 27728041352SGreg Clayton if (!resolved_exe_file.Exists()) 278e996fd30SGreg Clayton resolved_exe_file.ResolveExecutableLocation (); 279e996fd30SGreg Clayton 28028041352SGreg Clayton if (resolved_exe_file.Exists()) 28128041352SGreg Clayton error.Clear(); 28228041352SGreg Clayton else 28328041352SGreg Clayton { 28428041352SGreg Clayton exe_file.GetPath(exe_path, sizeof(exe_path)); 28528041352SGreg Clayton error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); 28628041352SGreg Clayton } 28728041352SGreg Clayton } 28828041352SGreg Clayton else 28928041352SGreg Clayton { 29028041352SGreg Clayton if (m_remote_platform_sp) 29128041352SGreg Clayton { 29228041352SGreg Clayton error = m_remote_platform_sp->ResolveExecutable (exe_file, 29328041352SGreg Clayton exe_arch, 2940c90ef47SGreg Clayton exe_module_sp, 2950c90ef47SGreg Clayton NULL); 29628041352SGreg Clayton } 29728041352SGreg Clayton else 29828041352SGreg Clayton { 29928041352SGreg Clayton // We may connect to a process and use the provided executable (Don't use local $PATH). 300e996fd30SGreg Clayton 301e996fd30SGreg Clayton if (resolved_exe_file.Exists()) 30228041352SGreg Clayton error.Clear(); 30328041352SGreg Clayton else 30428041352SGreg Clayton error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); 30528041352SGreg Clayton } 30628041352SGreg Clayton } 30728041352SGreg Clayton 30828041352SGreg Clayton if (error.Success()) 309e996fd30SGreg Clayton { 310ea5e0cc3SGreg Clayton ModuleSpec module_spec (resolved_exe_file, exe_arch); 311e996fd30SGreg Clayton if (exe_arch.IsValid()) 312e996fd30SGreg Clayton { 313ea5e0cc3SGreg Clayton error = ModuleList::GetSharedModule (module_spec, 314e996fd30SGreg Clayton exe_module_sp, 315e996fd30SGreg Clayton NULL, 3160c90ef47SGreg Clayton NULL, 317e996fd30SGreg Clayton NULL); 3189f0013d8SMichael Sartain if (error.Fail()) 3199f0013d8SMichael Sartain { 3209f0013d8SMichael Sartain // If we failed, it may be because the vendor and os aren't known. If that is the 3219f0013d8SMichael Sartain // case, try setting them to the host architecture and give it another try. 3229f0013d8SMichael Sartain llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); 3239f0013d8SMichael Sartain bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); 3249f0013d8SMichael Sartain bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); 3259f0013d8SMichael Sartain if (!is_vendor_specified || !is_os_specified) 3269f0013d8SMichael Sartain { 32713b18261SZachary Turner const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); 3289f0013d8SMichael Sartain 3299f0013d8SMichael Sartain if (!is_vendor_specified) 3309f0013d8SMichael Sartain module_triple.setVendorName (host_triple.getVendorName()); 3319f0013d8SMichael Sartain if (!is_os_specified) 3329f0013d8SMichael Sartain module_triple.setOSName (host_triple.getOSName()); 3339f0013d8SMichael Sartain 3349f0013d8SMichael Sartain error = ModuleList::GetSharedModule (module_spec, 3359f0013d8SMichael Sartain exe_module_sp, 3369f0013d8SMichael Sartain NULL, 3379f0013d8SMichael Sartain NULL, 3389f0013d8SMichael Sartain NULL); 3399f0013d8SMichael Sartain } 3409f0013d8SMichael Sartain } 341e996fd30SGreg Clayton 342e635db49SSean Callanan // TODO find out why exe_module_sp might be NULL 343e635db49SSean Callanan if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) 344e996fd30SGreg Clayton { 345e996fd30SGreg Clayton exe_module_sp.reset(); 346b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", 347b5ad4ec7SGreg Clayton exe_file.GetPath().c_str(), 348e996fd30SGreg Clayton exe_arch.GetArchitectureName()); 349e996fd30SGreg Clayton } 350e996fd30SGreg Clayton } 351e996fd30SGreg Clayton else 352e996fd30SGreg Clayton { 353e996fd30SGreg Clayton // No valid architecture was specified, ask the platform for 354e996fd30SGreg Clayton // the architectures that we should be using (in the correct order) 355e996fd30SGreg Clayton // and see if we can find a match that way 356e996fd30SGreg Clayton StreamString arch_names; 357ea5e0cc3SGreg Clayton for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 358e996fd30SGreg Clayton { 359ea5e0cc3SGreg Clayton error = ModuleList::GetSharedModule (module_spec, 360e996fd30SGreg Clayton exe_module_sp, 361e996fd30SGreg Clayton NULL, 3620c90ef47SGreg Clayton NULL, 363e996fd30SGreg Clayton NULL); 364e996fd30SGreg Clayton // Did we find an executable using one of the 365e996fd30SGreg Clayton if (error.Success()) 366e996fd30SGreg Clayton { 367e996fd30SGreg Clayton if (exe_module_sp && exe_module_sp->GetObjectFile()) 368e996fd30SGreg Clayton break; 369e996fd30SGreg Clayton else 370e996fd30SGreg Clayton error.SetErrorToGenericError(); 371e996fd30SGreg Clayton } 372e996fd30SGreg Clayton 373e996fd30SGreg Clayton if (idx > 0) 374e996fd30SGreg Clayton arch_names.PutCString (", "); 375ea5e0cc3SGreg Clayton arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); 376e996fd30SGreg Clayton } 377e996fd30SGreg Clayton 378e996fd30SGreg Clayton if (error.Fail() || !exe_module_sp) 379e996fd30SGreg Clayton { 38039945dccSGreg Clayton if (exe_file.Readable()) 38139945dccSGreg Clayton { 382b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 383b5ad4ec7SGreg Clayton exe_file.GetPath().c_str(), 38457abc5d6SGreg Clayton GetPluginName().GetCString(), 385e996fd30SGreg Clayton arch_names.GetString().c_str()); 386e996fd30SGreg Clayton } 38739945dccSGreg Clayton else 38839945dccSGreg Clayton { 38939945dccSGreg Clayton error.SetErrorStringWithFormat("'%s' is not readable", exe_file.GetPath().c_str()); 39039945dccSGreg Clayton } 39139945dccSGreg Clayton } 392e996fd30SGreg Clayton } 393e996fd30SGreg Clayton } 394e996fd30SGreg Clayton 395e996fd30SGreg Clayton return error; 396e996fd30SGreg Clayton } 397e996fd30SGreg Clayton 398e996fd30SGreg Clayton Error 399fc995725SSteve Pucci PlatformLinux::GetFileWithUUID (const FileSpec &platform_file, 40028041352SGreg Clayton const UUID *uuid_ptr, FileSpec &local_file) 401e996fd30SGreg Clayton { 40228041352SGreg Clayton if (IsRemote()) 40328041352SGreg Clayton { 40428041352SGreg Clayton if (m_remote_platform_sp) 405fc995725SSteve Pucci return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file); 40628041352SGreg Clayton } 40728041352SGreg Clayton 408e996fd30SGreg Clayton // Default to the local case 409e996fd30SGreg Clayton local_file = platform_file; 410e996fd30SGreg Clayton return Error(); 411e996fd30SGreg Clayton } 412e996fd30SGreg Clayton 413e996fd30SGreg Clayton 414e996fd30SGreg Clayton //------------------------------------------------------------------ 415e996fd30SGreg Clayton /// Default Constructor 416e996fd30SGreg Clayton //------------------------------------------------------------------ 41728041352SGreg Clayton PlatformLinux::PlatformLinux (bool is_host) : 418015d818bSTodd Fiala PlatformPOSIX(is_host) // This is the local host platform 419e996fd30SGreg Clayton { 420e996fd30SGreg Clayton } 421e996fd30SGreg Clayton 422e996fd30SGreg Clayton //------------------------------------------------------------------ 423e996fd30SGreg Clayton /// Destructor. 424e996fd30SGreg Clayton /// 425e996fd30SGreg Clayton /// The destructor is virtual since this class is designed to be 426e996fd30SGreg Clayton /// inherited from by the plug-in instance. 427e996fd30SGreg Clayton //------------------------------------------------------------------ 428e996fd30SGreg Clayton PlatformLinux::~PlatformLinux() 429e996fd30SGreg Clayton { 430e996fd30SGreg Clayton } 431e996fd30SGreg Clayton 432e996fd30SGreg Clayton bool 43313e8e1c3SJohnny Chen PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 434e996fd30SGreg Clayton { 43528041352SGreg Clayton bool success = false; 43628041352SGreg Clayton if (IsHost()) 43728041352SGreg Clayton { 43828041352SGreg Clayton success = Platform::GetProcessInfo (pid, process_info); 43928041352SGreg Clayton } 44028041352SGreg Clayton else 44128041352SGreg Clayton { 44228041352SGreg Clayton if (m_remote_platform_sp) 44328041352SGreg Clayton success = m_remote_platform_sp->GetProcessInfo (pid, process_info); 44428041352SGreg Clayton } 44528041352SGreg Clayton return success; 446e996fd30SGreg Clayton } 447e996fd30SGreg Clayton 448e996fd30SGreg Clayton bool 449e996fd30SGreg Clayton PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 450e996fd30SGreg Clayton { 451e996fd30SGreg Clayton if (idx == 0) 452e996fd30SGreg Clayton { 45313b18261SZachary Turner arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 454e996fd30SGreg Clayton return arch.IsValid(); 455e996fd30SGreg Clayton } 456542e4075SGreg Clayton else if (idx == 1) 457542e4075SGreg Clayton { 458542e4075SGreg Clayton // If the default host architecture is 64-bit, look for a 32-bit variant 45913b18261SZachary Turner ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 460542e4075SGreg Clayton if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) 461542e4075SGreg Clayton { 46213b18261SZachary Turner arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 463542e4075SGreg Clayton return arch.IsValid(); 464542e4075SGreg Clayton } 465542e4075SGreg Clayton } 466e996fd30SGreg Clayton return false; 467e996fd30SGreg Clayton } 468ecc11474SStephen Wilson 469ecc11474SStephen Wilson void 470ecc11474SStephen Wilson PlatformLinux::GetStatus (Stream &strm) 471ecc11474SStephen Wilson { 4723be69dacSDaniel Malea Platform::GetStatus(strm); 473ecc11474SStephen Wilson 474b2f1fb29SVirgile Bello #ifndef LLDB_DISABLE_POSIX 475b2f1fb29SVirgile Bello struct utsname un; 476b2f1fb29SVirgile Bello 4773be69dacSDaniel Malea if (uname(&un)) 4783be69dacSDaniel Malea return; 4793be69dacSDaniel Malea 4803be69dacSDaniel Malea strm.Printf (" Kernel: %s\n", un.sysname); 4813be69dacSDaniel Malea strm.Printf (" Release: %s\n", un.release); 4823be69dacSDaniel Malea strm.Printf (" Version: %s\n", un.version); 483b2f1fb29SVirgile Bello #endif 484ecc11474SStephen Wilson } 485ecc11474SStephen Wilson 486ecc11474SStephen Wilson size_t 487ecc11474SStephen Wilson PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, 488ecc11474SStephen Wilson BreakpointSite *bp_site) 489ecc11474SStephen Wilson { 490ecc11474SStephen Wilson ArchSpec arch = target.GetArchitecture(); 49128041352SGreg Clayton const uint8_t *trap_opcode = NULL; 49228041352SGreg Clayton size_t trap_opcode_size = 0; 493ecc11474SStephen Wilson 494906e9acfSGreg Clayton switch (arch.GetMachine()) 495ecc11474SStephen Wilson { 496ecc11474SStephen Wilson default: 497ecc11474SStephen Wilson assert(false && "CPU type not supported!"); 498ecc11474SStephen Wilson break; 499ecc11474SStephen Wilson 5002afc5966STodd Fiala case llvm::Triple::aarch64: 5012afc5966STodd Fiala { 5022afc5966STodd Fiala static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 }; 5032afc5966STodd Fiala trap_opcode = g_aarch64_opcode; 5042afc5966STodd Fiala trap_opcode_size = sizeof(g_aarch64_opcode); 5052afc5966STodd Fiala } 5062afc5966STodd Fiala break; 507906e9acfSGreg Clayton case llvm::Triple::x86: 508906e9acfSGreg Clayton case llvm::Triple::x86_64: 50928041352SGreg Clayton { 51028041352SGreg Clayton static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 51128041352SGreg Clayton trap_opcode = g_i386_breakpoint_opcode; 51228041352SGreg Clayton trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 51328041352SGreg Clayton } 514ecc11474SStephen Wilson break; 515906e9acfSGreg Clayton case llvm::Triple::hexagon: 5168006d319SDeepak Panickal { 5178006d319SDeepak Panickal static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 }; 5188006d319SDeepak Panickal trap_opcode = g_hex_opcode; 5198006d319SDeepak Panickal trap_opcode_size = sizeof(g_hex_opcode); 5208006d319SDeepak Panickal } 5218006d319SDeepak Panickal break; 522ecc11474SStephen Wilson } 523ecc11474SStephen Wilson 52428041352SGreg Clayton if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 52528041352SGreg Clayton return trap_opcode_size; 52628041352SGreg Clayton return 0; 52728041352SGreg Clayton } 52828041352SGreg Clayton 52928041352SGreg Clayton Error 53028041352SGreg Clayton PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info) 53128041352SGreg Clayton { 532015d818bSTodd Fiala Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 53328041352SGreg Clayton Error error; 53428041352SGreg Clayton 53528041352SGreg Clayton if (IsHost()) 53628041352SGreg Clayton { 537015d818bSTodd Fiala if (log) 538015d818bSTodd Fiala log->Printf ("PlatformLinux::%s() launching process as host", __FUNCTION__); 539015d818bSTodd Fiala 54028041352SGreg Clayton if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 54128041352SGreg Clayton { 54228041352SGreg Clayton const bool is_localhost = true; 543d1cf11a7SGreg Clayton const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 544d1cf11a7SGreg Clayton const bool first_arg_is_full_shell_command = false; 545d3990793SJim Ingham uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info); 546d1cf11a7SGreg Clayton if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 547d1cf11a7SGreg Clayton is_localhost, 548d1cf11a7SGreg Clayton will_debug, 549df0ae22fSJim Ingham first_arg_is_full_shell_command, 550df0ae22fSJim Ingham num_resumes)) 55128041352SGreg Clayton return error; 55228041352SGreg Clayton } 55328041352SGreg Clayton error = Platform::LaunchProcess (launch_info); 55428041352SGreg Clayton } 55528041352SGreg Clayton else 55628041352SGreg Clayton { 557015d818bSTodd Fiala if (m_remote_platform_sp) 558015d818bSTodd Fiala { 559015d818bSTodd Fiala if (log) 560015d818bSTodd Fiala log->Printf ("PlatformLinux::%s() attempting to launch remote process", __FUNCTION__); 561015d818bSTodd Fiala error = m_remote_platform_sp->LaunchProcess (launch_info); 562015d818bSTodd Fiala } 563015d818bSTodd Fiala else 564015d818bSTodd Fiala { 565015d818bSTodd Fiala if (log) 566015d818bSTodd Fiala log->Printf ("PlatformLinux::%s() attempted to launch process but is not the host and no remote platform set", __FUNCTION__); 56728041352SGreg Clayton error.SetErrorString ("the platform is not currently connected"); 56828041352SGreg Clayton } 569015d818bSTodd Fiala } 57028041352SGreg Clayton return error; 571ecc11474SStephen Wilson } 57213e8e1c3SJohnny Chen 573015d818bSTodd Fiala // Linux processes can not be launched by spawning and attaching. 574015d818bSTodd Fiala bool 575015d818bSTodd Fiala PlatformLinux::CanDebugProcess () 576015d818bSTodd Fiala { 577015d818bSTodd Fiala // If we're the host, launch via normal host setup. 578015d818bSTodd Fiala if (IsHost ()) 579015d818bSTodd Fiala return false; 580015d818bSTodd Fiala 581015d818bSTodd Fiala // If we're connected, we can debug. 582015d818bSTodd Fiala return IsConnected (); 583015d818bSTodd Fiala } 584015d818bSTodd Fiala 58513e8e1c3SJohnny Chen lldb::ProcessSP 586fb2b629dSPeter Collingbourne PlatformLinux::Attach(ProcessAttachInfo &attach_info, 58713e8e1c3SJohnny Chen Debugger &debugger, 58813e8e1c3SJohnny Chen Target *target, 58913e8e1c3SJohnny Chen Listener &listener, 59013e8e1c3SJohnny Chen Error &error) 59113e8e1c3SJohnny Chen { 59228041352SGreg Clayton lldb::ProcessSP process_sp; 59328041352SGreg Clayton if (IsHost()) 59428041352SGreg Clayton { 59528041352SGreg Clayton if (target == NULL) 59628041352SGreg Clayton { 59728041352SGreg Clayton TargetSP new_target_sp; 59828041352SGreg Clayton ArchSpec emptyArchSpec; 59928041352SGreg Clayton 60028041352SGreg Clayton error = debugger.GetTargetList().CreateTarget (debugger, 601a0ca6601SGreg Clayton NULL, 60228041352SGreg Clayton emptyArchSpec, 60328041352SGreg Clayton false, 60428041352SGreg Clayton m_remote_platform_sp, 60528041352SGreg Clayton new_target_sp); 60628041352SGreg Clayton target = new_target_sp.get(); 60728041352SGreg Clayton } 60828041352SGreg Clayton else 60928041352SGreg Clayton error.Clear(); 61028041352SGreg Clayton 61128041352SGreg Clayton if (target && error.Success()) 61228041352SGreg Clayton { 61328041352SGreg Clayton debugger.GetTargetList().SetSelectedTarget(target); 61428041352SGreg Clayton 6150c90ef47SGreg Clayton process_sp = target->CreateProcess (listener, 6160c90ef47SGreg Clayton attach_info.GetProcessPluginName(), 6170c90ef47SGreg Clayton NULL); 61828041352SGreg Clayton 61928041352SGreg Clayton if (process_sp) 62028041352SGreg Clayton error = process_sp->Attach (attach_info); 62128041352SGreg Clayton } 62228041352SGreg Clayton } 62328041352SGreg Clayton else 62428041352SGreg Clayton { 62528041352SGreg Clayton if (m_remote_platform_sp) 62628041352SGreg Clayton process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 62728041352SGreg Clayton else 62828041352SGreg Clayton error.SetErrorString ("the platform is not currently connected"); 62928041352SGreg Clayton } 63028041352SGreg Clayton return process_sp; 63113e8e1c3SJohnny Chen } 6322094dbf4SJason Molenda 6332094dbf4SJason Molenda void 6342094dbf4SJason Molenda PlatformLinux::CalculateTrapHandlerSymbolNames () 6352094dbf4SJason Molenda { 6362094dbf4SJason Molenda m_trap_handlers.push_back (ConstString ("_sigtramp")); 6372094dbf4SJason Molenda } 638af245d11STodd Fiala 639af245d11STodd Fiala Error 640af245d11STodd Fiala PlatformLinux::LaunchNativeProcess ( 641af245d11STodd Fiala ProcessLaunchInfo &launch_info, 642af245d11STodd Fiala lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 643af245d11STodd Fiala NativeProcessProtocolSP &process_sp) 644af245d11STodd Fiala { 645af245d11STodd Fiala #if !defined(__linux__) 646af245d11STodd Fiala return Error("only implemented on Linux hosts"); 647af245d11STodd Fiala #else 648af245d11STodd Fiala if (!IsHost ()) 649af245d11STodd Fiala return Error("PlatformLinux::%s (): cannot launch a debug process when not the host", __FUNCTION__); 650af245d11STodd Fiala 651af245d11STodd Fiala // Retrieve the exe module. 652af245d11STodd Fiala lldb::ModuleSP exe_module_sp; 653af245d11STodd Fiala 654af245d11STodd Fiala Error error = ResolveExecutable ( 655af245d11STodd Fiala launch_info.GetExecutableFile (), 656af245d11STodd Fiala launch_info.GetArchitecture (), 657af245d11STodd Fiala exe_module_sp, 658af245d11STodd Fiala NULL); 659af245d11STodd Fiala 660af245d11STodd Fiala if (!error.Success ()) 661af245d11STodd Fiala return error; 662af245d11STodd Fiala 663af245d11STodd Fiala if (!exe_module_sp) 664af245d11STodd Fiala return Error("exe_module_sp could not be resolved for %s", launch_info.GetExecutableFile ().GetPath ().c_str ()); 665af245d11STodd Fiala 666af245d11STodd Fiala // Launch it for debugging 667af245d11STodd Fiala error = NativeProcessLinux::LaunchProcess ( 668af245d11STodd Fiala exe_module_sp.get (), 669af245d11STodd Fiala launch_info, 670af245d11STodd Fiala native_delegate, 671af245d11STodd Fiala process_sp); 672af245d11STodd Fiala 673af245d11STodd Fiala return error; 674af245d11STodd Fiala #endif 675af245d11STodd Fiala } 676af245d11STodd Fiala 677af245d11STodd Fiala Error 678af245d11STodd Fiala PlatformLinux::AttachNativeProcess (lldb::pid_t pid, 679af245d11STodd Fiala lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 680af245d11STodd Fiala NativeProcessProtocolSP &process_sp) 681af245d11STodd Fiala { 682af245d11STodd Fiala #if !defined(__linux__) 683af245d11STodd Fiala return Error("only implemented on Linux hosts"); 684af245d11STodd Fiala #else 685af245d11STodd Fiala if (!IsHost ()) 686af245d11STodd Fiala return Error("PlatformLinux::%s (): cannot attach to a debug process when not the host", __FUNCTION__); 687af245d11STodd Fiala 688af245d11STodd Fiala // Launch it for debugging 689af245d11STodd Fiala return NativeProcessLinux::AttachToProcess (pid, native_delegate, process_sp); 690af245d11STodd Fiala #endif 691af245d11STodd Fiala } 692