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 12 // C Includes 13 #include <stdio.h> 14 #include <sys/utsname.h> 15 16 // C++ Includes 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/Core/Error.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/ModuleList.h" 22 #include "lldb/Core/PluginManager.h" 23 #include "lldb/Core/StreamString.h" 24 #include "lldb/Host/FileSpec.h" 25 #include "lldb/Host/Host.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Process.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 Platform * 33 PlatformLinux::CreateInstance () 34 { 35 return new PlatformLinux(); 36 } 37 38 const char * 39 PlatformLinux::GetPluginNameStatic() 40 { 41 return "plugin.platform.linux"; 42 } 43 44 const char * 45 PlatformLinux::GetPluginDescriptionStatic() 46 { 47 return "Default platform plugin for Linux"; 48 } 49 50 void 51 PlatformLinux::Initialize () 52 { 53 static bool g_initialized = false; 54 55 if (!g_initialized) 56 { 57 PlatformSP default_platform_sp (CreateInstance()); 58 Platform::SetDefaultPlatform (default_platform_sp); 59 PluginManager::RegisterPlugin(GetPluginNameStatic(), 60 GetPluginDescriptionStatic(), 61 CreateInstance); 62 g_initialized = true; 63 } 64 } 65 66 void 67 PlatformLinux::Terminate () 68 { 69 } 70 71 72 Error 73 PlatformLinux::ResolveExecutable (const FileSpec &exe_file, 74 const ArchSpec &exe_arch, 75 lldb::ModuleSP &exe_module_sp) 76 { 77 Error error; 78 // Nothing special to do here, just use the actual file and architecture 79 80 FileSpec resolved_exe_file (exe_file); 81 82 // If we have "ls" as the exe_file, resolve the executable loation based on 83 // the current path variables 84 if (!resolved_exe_file.Exists()) 85 resolved_exe_file.ResolveExecutableLocation (); 86 87 // Resolve any executable within a bundle on MacOSX 88 Host::ResolveExecutableInBundle (resolved_exe_file); 89 90 if (resolved_exe_file.Exists()) 91 { 92 if (exe_arch.IsValid()) 93 { 94 error = ModuleList::GetSharedModule (resolved_exe_file, 95 exe_arch, 96 NULL, 97 NULL, 98 0, 99 exe_module_sp, 100 NULL, 101 NULL); 102 103 if (exe_module_sp->GetObjectFile() == NULL) 104 { 105 exe_module_sp.reset(); 106 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s", 107 exe_file.GetDirectory().AsCString(""), 108 exe_file.GetDirectory() ? "/" : "", 109 exe_file.GetFilename().AsCString(""), 110 exe_arch.GetArchitectureName()); 111 } 112 } 113 else 114 { 115 // No valid architecture was specified, ask the platform for 116 // the architectures that we should be using (in the correct order) 117 // and see if we can find a match that way 118 StreamString arch_names; 119 ArchSpec platform_arch; 120 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) 121 { 122 error = ModuleList::GetSharedModule (resolved_exe_file, 123 platform_arch, 124 NULL, 125 NULL, 126 0, 127 exe_module_sp, 128 NULL, 129 NULL); 130 // Did we find an executable using one of the 131 if (error.Success()) 132 { 133 if (exe_module_sp && exe_module_sp->GetObjectFile()) 134 break; 135 else 136 error.SetErrorToGenericError(); 137 } 138 139 if (idx > 0) 140 arch_names.PutCString (", "); 141 arch_names.PutCString (platform_arch.GetArchitectureName()); 142 } 143 144 if (error.Fail() || !exe_module_sp) 145 { 146 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", 147 exe_file.GetDirectory().AsCString(""), 148 exe_file.GetDirectory() ? "/" : "", 149 exe_file.GetFilename().AsCString(""), 150 GetShortPluginName(), 151 arch_names.GetString().c_str()); 152 } 153 } 154 } 155 else 156 { 157 error.SetErrorStringWithFormat ("'%s%s%s' does not exist", 158 exe_file.GetDirectory().AsCString(""), 159 exe_file.GetDirectory() ? "/" : "", 160 exe_file.GetFilename().AsCString("")); 161 } 162 163 return error; 164 } 165 166 Error 167 PlatformLinux::GetFile (const FileSpec &platform_file, 168 const UUID *uuid, FileSpec &local_file) 169 { 170 // Default to the local case 171 local_file = platform_file; 172 return Error(); 173 } 174 175 176 //------------------------------------------------------------------ 177 /// Default Constructor 178 //------------------------------------------------------------------ 179 PlatformLinux::PlatformLinux () : 180 Platform(true) 181 { 182 } 183 184 //------------------------------------------------------------------ 185 /// Destructor. 186 /// 187 /// The destructor is virtual since this class is designed to be 188 /// inherited from by the plug-in instance. 189 //------------------------------------------------------------------ 190 PlatformLinux::~PlatformLinux() 191 { 192 } 193 194 bool 195 PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 196 { 197 return Host::GetProcessInfo (pid, process_info); 198 } 199 200 bool 201 PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 202 { 203 if (idx == 0) 204 { 205 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 206 return arch.IsValid(); 207 } 208 return false; 209 } 210 211 void 212 PlatformLinux::GetStatus (Stream &strm) 213 { 214 struct utsname un; 215 216 if (uname(&un)) { 217 strm << "Linux"; 218 return; 219 } 220 221 strm << un.sysname << ' ' << un.release << ' ' << un.version << '\n'; 222 } 223 224 size_t 225 PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, 226 BreakpointSite *bp_site) 227 { 228 static const uint8_t g_i386_opcode[] = { 0xCC }; 229 230 ArchSpec arch = target.GetArchitecture(); 231 const uint8_t *opcode = NULL; 232 size_t opcode_size = 0; 233 234 switch (arch.GetCore()) 235 { 236 default: 237 assert(false && "CPU type not supported!"); 238 break; 239 240 case ArchSpec::eCore_x86_32_i386: 241 case ArchSpec::eCore_x86_64_x86_64: 242 opcode = g_i386_opcode; 243 opcode_size = sizeof(g_i386_opcode); 244 break; 245 } 246 247 bp_site->SetTrapOpcode(opcode, opcode_size); 248 return opcode_size; 249 } 250 251 lldb::ProcessSP 252 PlatformLinux::Attach(lldb::pid_t pid, 253 Debugger &debugger, 254 Target *target, 255 Listener &listener, 256 Error &error) 257 { 258 ProcessSP processSP; 259 assert(!"Not implemented yet!"); 260 return processSP; 261 } 262