1 //===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/lldb-python.h" 11 12 #include "PlatformLinux.h" 13 #include "lldb/Host/Config.h" 14 15 // C Includes 16 #include <stdio.h> 17 #ifndef LLDB_DISABLE_POSIX 18 #include <sys/utsname.h> 19 #endif 20 21 // C++ Includes 22 // Other libraries and framework includes 23 // Project includes 24 #include "lldb/Core/Error.h" 25 #include "lldb/Core/Debugger.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/StreamString.h" 31 #include "lldb/Host/FileSpec.h" 32 #include "lldb/Host/Host.h" 33 #include "lldb/Target/Target.h" 34 #include "lldb/Target/Process.h" 35 36 #if defined(__linux__) 37 #include "../../Process/Linux/NativeProcessLinux.h" 38 #endif 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 static uint32_t g_initialize_count = 0; 44 45 Platform * 46 PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) 47 { 48 bool create = force; 49 if (create == false && arch && arch->IsValid()) 50 { 51 const llvm::Triple &triple = arch->GetTriple(); 52 switch (triple.getVendor()) 53 { 54 case llvm::Triple::PC: 55 create = true; 56 break; 57 58 #if defined(__linux__) 59 // Only accept "unknown" for the vendor if the host is linux and 60 // it "unknown" wasn't specified (it was just returned because it 61 // was NOT specified_ 62 case llvm::Triple::UnknownArch: 63 create = !arch->TripleVendorWasSpecified(); 64 break; 65 #endif 66 default: 67 break; 68 } 69 70 if (create) 71 { 72 switch (triple.getOS()) 73 { 74 case llvm::Triple::Linux: 75 break; 76 77 #if defined(__linux__) 78 // Only accept "unknown" for the OS if the host is linux and 79 // it "unknown" wasn't specified (it was just returned because it 80 // was NOT specified) 81 case llvm::Triple::UnknownOS: 82 create = !arch->TripleOSWasSpecified(); 83 break; 84 #endif 85 default: 86 create = false; 87 break; 88 } 89 } 90 } 91 if (create) 92 return new PlatformLinux(false); 93 return NULL; 94 } 95 96 97 lldb_private::ConstString 98 PlatformLinux::GetPluginNameStatic (bool is_host) 99 { 100 if (is_host) 101 { 102 static ConstString g_host_name(Platform::GetHostPlatformName ()); 103 return g_host_name; 104 } 105 else 106 { 107 static ConstString g_remote_name("remote-linux"); 108 return g_remote_name; 109 } 110 } 111 112 const char * 113 PlatformLinux::GetPluginDescriptionStatic (bool is_host) 114 { 115 if (is_host) 116 return "Local Linux user platform plug-in."; 117 else 118 return "Remote Linux user platform plug-in."; 119 } 120 121 lldb_private::ConstString 122 PlatformLinux::GetPluginName() 123 { 124 return GetPluginNameStatic(IsHost()); 125 } 126 127 void 128 PlatformLinux::Initialize () 129 { 130 if (g_initialize_count++ == 0) 131 { 132 #if defined(__linux__) 133 PlatformSP default_platform_sp (new PlatformLinux(true)); 134 default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); 135 Platform::SetDefaultPlatform (default_platform_sp); 136 #endif 137 PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false), 138 PlatformLinux::GetPluginDescriptionStatic(false), 139 PlatformLinux::CreateInstance); 140 } 141 } 142 143 void 144 PlatformLinux::Terminate () 145 { 146 if (g_initialize_count > 0) 147 { 148 if (--g_initialize_count == 0) 149 { 150 PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance); 151 } 152 } 153 } 154 155 Error 156 PlatformLinux::ResolveExecutable (const FileSpec &exe_file, 157 const ArchSpec &exe_arch, 158 lldb::ModuleSP &exe_module_sp, 159 const FileSpecList *module_search_paths_ptr) 160 { 161 Error error; 162 // Nothing special to do here, just use the actual file and architecture 163 164 char exe_path[PATH_MAX]; 165 FileSpec resolved_exe_file (exe_file); 166 167 if (IsHost()) 168 { 169 // If we have "ls" as the exe_file, resolve the executable location based on 170 // the current path variables 171 if (!resolved_exe_file.Exists()) 172 { 173 exe_file.GetPath(exe_path, sizeof(exe_path)); 174 resolved_exe_file.SetFile(exe_path, true); 175 } 176 177 if (!resolved_exe_file.Exists()) 178 resolved_exe_file.ResolveExecutableLocation (); 179 180 if (resolved_exe_file.Exists()) 181 error.Clear(); 182 else 183 { 184 exe_file.GetPath(exe_path, sizeof(exe_path)); 185 error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); 186 } 187 } 188 else 189 { 190 if (m_remote_platform_sp) 191 { 192 error = m_remote_platform_sp->ResolveExecutable (exe_file, 193 exe_arch, 194 exe_module_sp, 195 NULL); 196 } 197 else 198 { 199 // We may connect to a process and use the provided executable (Don't use local $PATH). 200 201 if (resolved_exe_file.Exists()) 202 error.Clear(); 203 else 204 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); 205 } 206 } 207 208 if (error.Success()) 209 { 210 ModuleSpec module_spec (resolved_exe_file, exe_arch); 211 if (exe_arch.IsValid()) 212 { 213 error = ModuleList::GetSharedModule (module_spec, 214 exe_module_sp, 215 NULL, 216 NULL, 217 NULL); 218 if (error.Fail()) 219 { 220 // If we failed, it may be because the vendor and os aren't known. If that is the 221 // case, try setting them to the host architecture and give it another try. 222 llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); 223 bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); 224 bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); 225 if (!is_vendor_specified || !is_os_specified) 226 { 227 const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple(); 228 229 if (!is_vendor_specified) 230 module_triple.setVendorName (host_triple.getVendorName()); 231 if (!is_os_specified) 232 module_triple.setOSName (host_triple.getOSName()); 233 234 error = ModuleList::GetSharedModule (module_spec, 235 exe_module_sp, 236 NULL, 237 NULL, 238 NULL); 239 } 240 } 241 242 // TODO find out why exe_module_sp might be NULL 243 if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) 244 { 245 exe_module_sp.reset(); 246 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", 247 exe_file.GetPath().c_str(), 248 exe_arch.GetArchitectureName()); 249 } 250 } 251 else 252 { 253 // No valid architecture was specified, ask the platform for 254 // the architectures that we should be using (in the correct order) 255 // and see if we can find a match that way 256 StreamString arch_names; 257 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 258 { 259 error = ModuleList::GetSharedModule (module_spec, 260 exe_module_sp, 261 NULL, 262 NULL, 263 NULL); 264 // Did we find an executable using one of the 265 if (error.Success()) 266 { 267 if (exe_module_sp && exe_module_sp->GetObjectFile()) 268 break; 269 else 270 error.SetErrorToGenericError(); 271 } 272 273 if (idx > 0) 274 arch_names.PutCString (", "); 275 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); 276 } 277 278 if (error.Fail() || !exe_module_sp) 279 { 280 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 281 exe_file.GetPath().c_str(), 282 GetPluginName().GetCString(), 283 arch_names.GetString().c_str()); 284 } 285 } 286 } 287 288 return error; 289 } 290 291 Error 292 PlatformLinux::GetFileWithUUID (const FileSpec &platform_file, 293 const UUID *uuid_ptr, FileSpec &local_file) 294 { 295 if (IsRemote()) 296 { 297 if (m_remote_platform_sp) 298 return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file); 299 } 300 301 // Default to the local case 302 local_file = platform_file; 303 return Error(); 304 } 305 306 307 //------------------------------------------------------------------ 308 /// Default Constructor 309 //------------------------------------------------------------------ 310 PlatformLinux::PlatformLinux (bool is_host) : 311 Platform(is_host), // This is the local host platform 312 m_remote_platform_sp () 313 { 314 } 315 316 //------------------------------------------------------------------ 317 /// Destructor. 318 /// 319 /// The destructor is virtual since this class is designed to be 320 /// inherited from by the plug-in instance. 321 //------------------------------------------------------------------ 322 PlatformLinux::~PlatformLinux() 323 { 324 } 325 326 bool 327 PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 328 { 329 bool success = false; 330 if (IsHost()) 331 { 332 success = Platform::GetProcessInfo (pid, process_info); 333 } 334 else 335 { 336 if (m_remote_platform_sp) 337 success = m_remote_platform_sp->GetProcessInfo (pid, process_info); 338 } 339 return success; 340 } 341 342 bool 343 PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 344 { 345 if (idx == 0) 346 { 347 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 348 return arch.IsValid(); 349 } 350 else if (idx == 1) 351 { 352 // If the default host architecture is 64-bit, look for a 32-bit variant 353 ArchSpec hostArch 354 = Host::GetArchitecture(Host::eSystemDefaultArchitecture); 355 if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) 356 { 357 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 358 return arch.IsValid(); 359 } 360 } 361 return false; 362 } 363 364 void 365 PlatformLinux::GetStatus (Stream &strm) 366 { 367 Platform::GetStatus(strm); 368 369 #ifndef LLDB_DISABLE_POSIX 370 struct utsname un; 371 372 if (uname(&un)) 373 return; 374 375 strm.Printf (" Kernel: %s\n", un.sysname); 376 strm.Printf (" Release: %s\n", un.release); 377 strm.Printf (" Version: %s\n", un.version); 378 #endif 379 } 380 381 size_t 382 PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, 383 BreakpointSite *bp_site) 384 { 385 ArchSpec arch = target.GetArchitecture(); 386 const uint8_t *trap_opcode = NULL; 387 size_t trap_opcode_size = 0; 388 389 switch (arch.GetMachine()) 390 { 391 default: 392 assert(false && "CPU type not supported!"); 393 break; 394 395 case llvm::Triple::x86: 396 case llvm::Triple::x86_64: 397 { 398 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 399 trap_opcode = g_i386_breakpoint_opcode; 400 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 401 } 402 break; 403 case llvm::Triple::hexagon: 404 return 0; 405 } 406 407 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 408 return trap_opcode_size; 409 return 0; 410 } 411 412 Error 413 PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info) 414 { 415 Error error; 416 417 if (IsHost()) 418 { 419 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 420 { 421 const bool is_localhost = true; 422 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 423 const bool first_arg_is_full_shell_command = false; 424 uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info); 425 if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 426 is_localhost, 427 will_debug, 428 first_arg_is_full_shell_command, 429 num_resumes)) 430 return error; 431 } 432 error = Platform::LaunchProcess (launch_info); 433 } 434 else 435 { 436 error.SetErrorString ("the platform is not currently connected"); 437 } 438 return error; 439 } 440 441 lldb::ProcessSP 442 PlatformLinux::Attach(ProcessAttachInfo &attach_info, 443 Debugger &debugger, 444 Target *target, 445 Listener &listener, 446 Error &error) 447 { 448 lldb::ProcessSP process_sp; 449 if (IsHost()) 450 { 451 if (target == NULL) 452 { 453 TargetSP new_target_sp; 454 ArchSpec emptyArchSpec; 455 456 error = debugger.GetTargetList().CreateTarget (debugger, 457 NULL, 458 emptyArchSpec, 459 false, 460 m_remote_platform_sp, 461 new_target_sp); 462 target = new_target_sp.get(); 463 } 464 else 465 error.Clear(); 466 467 if (target && error.Success()) 468 { 469 debugger.GetTargetList().SetSelectedTarget(target); 470 471 process_sp = target->CreateProcess (listener, 472 attach_info.GetProcessPluginName(), 473 NULL); 474 475 if (process_sp) 476 error = process_sp->Attach (attach_info); 477 } 478 } 479 else 480 { 481 if (m_remote_platform_sp) 482 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 483 else 484 error.SetErrorString ("the platform is not currently connected"); 485 } 486 return process_sp; 487 } 488 489 void 490 PlatformLinux::CalculateTrapHandlerSymbolNames () 491 { 492 m_trap_handlers.push_back (ConstString ("_sigtramp")); 493 } 494 495 Error 496 PlatformLinux::LaunchNativeProcess ( 497 ProcessLaunchInfo &launch_info, 498 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 499 NativeProcessProtocolSP &process_sp) 500 { 501 #if !defined(__linux__) 502 return Error("only implemented on Linux hosts"); 503 #else 504 if (!IsHost ()) 505 return Error("PlatformLinux::%s (): cannot launch a debug process when not the host", __FUNCTION__); 506 507 // Retrieve the exe module. 508 lldb::ModuleSP exe_module_sp; 509 510 Error error = ResolveExecutable ( 511 launch_info.GetExecutableFile (), 512 launch_info.GetArchitecture (), 513 exe_module_sp, 514 NULL); 515 516 if (!error.Success ()) 517 return error; 518 519 if (!exe_module_sp) 520 return Error("exe_module_sp could not be resolved for %s", launch_info.GetExecutableFile ().GetPath ().c_str ()); 521 522 // Launch it for debugging 523 error = NativeProcessLinux::LaunchProcess ( 524 exe_module_sp.get (), 525 launch_info, 526 native_delegate, 527 process_sp); 528 529 return error; 530 #endif 531 } 532 533 Error 534 PlatformLinux::AttachNativeProcess (lldb::pid_t pid, 535 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 536 NativeProcessProtocolSP &process_sp) 537 { 538 #if !defined(__linux__) 539 return Error("only implemented on Linux hosts"); 540 #else 541 if (!IsHost ()) 542 return Error("PlatformLinux::%s (): cannot attach to a debug process when not the host", __FUNCTION__); 543 544 // Launch it for debugging 545 return NativeProcessLinux::AttachToProcess (pid, native_delegate, process_sp); 546 #endif 547 } 548 549