1254721Semaste//===-- PlatformFreeBSD.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "PlatformFreeBSD.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste#include <stdio.h> 16254721Semaste#include <sys/utsname.h> 17254721Semaste 18254721Semaste// C++ Includes 19254721Semaste// Other libraries and framework includes 20254721Semaste// Project includes 21254721Semaste#include "lldb/Core/Error.h" 22254721Semaste#include "lldb/Core/Debugger.h" 23254721Semaste#include "lldb/Core/Module.h" 24254721Semaste#include "lldb/Core/ModuleSpec.h" 25254721Semaste#include "lldb/Core/PluginManager.h" 26254721Semaste#include "lldb/Host/Host.h" 27254721Semaste 28254721Semasteusing namespace lldb; 29254721Semasteusing namespace lldb_private; 30254721Semaste 31254721SemastePlatform * 32254721SemastePlatformFreeBSD::CreateInstance (bool force, const lldb_private::ArchSpec *arch) 33254721Semaste{ 34254721Semaste // The only time we create an instance is when we are creating a remote 35254721Semaste // freebsd platform 36254721Semaste const bool is_host = false; 37254721Semaste 38254721Semaste bool create = force; 39254721Semaste if (create == false && arch && arch->IsValid()) 40254721Semaste { 41254721Semaste const llvm::Triple &triple = arch->GetTriple(); 42254721Semaste switch (triple.getVendor()) 43254721Semaste { 44254721Semaste case llvm::Triple::PC: 45254721Semaste create = true; 46254721Semaste break; 47254721Semaste 48254721Semaste#if defined(__FreeBSD__) || defined(__OpenBSD__) 49254721Semaste // Only accept "unknown" for the vendor if the host is BSD and 50254721Semaste // it "unknown" wasn't specified (it was just returned becasue it 51254721Semaste // was NOT specified) 52254721Semaste case llvm::Triple::UnknownArch: 53254721Semaste create = !arch->TripleVendorWasSpecified(); 54254721Semaste break; 55254721Semaste#endif 56254721Semaste default: 57254721Semaste break; 58254721Semaste } 59254721Semaste 60254721Semaste if (create) 61254721Semaste { 62254721Semaste switch (triple.getOS()) 63254721Semaste { 64254721Semaste case llvm::Triple::FreeBSD: 65254721Semaste case llvm::Triple::KFreeBSD: 66254721Semaste break; 67254721Semaste 68254721Semaste#if defined(__FreeBSD__) || defined(__OpenBSD__) 69254721Semaste // Only accept "unknown" for the OS if the host is BSD and 70254721Semaste // it "unknown" wasn't specified (it was just returned becasue it 71254721Semaste // was NOT specified) 72254721Semaste case llvm::Triple::UnknownOS: 73254721Semaste create = arch->TripleOSWasSpecified(); 74254721Semaste break; 75254721Semaste#endif 76254721Semaste default: 77254721Semaste create = false; 78254721Semaste break; 79254721Semaste } 80254721Semaste } 81254721Semaste } 82254721Semaste if (create) 83254721Semaste return new PlatformFreeBSD (is_host); 84254721Semaste return NULL; 85254721Semaste 86254721Semaste} 87254721Semaste 88254721Semastelldb_private::ConstString 89254721SemastePlatformFreeBSD::GetPluginNameStatic (bool is_host) 90254721Semaste{ 91254721Semaste if (is_host) 92254721Semaste { 93254721Semaste static ConstString g_host_name(Platform::GetHostPlatformName ()); 94254721Semaste return g_host_name; 95254721Semaste } 96254721Semaste else 97254721Semaste { 98254721Semaste static ConstString g_remote_name("remote-freebsd"); 99254721Semaste return g_remote_name; 100254721Semaste } 101254721Semaste} 102254721Semaste 103254721Semasteconst char * 104254721SemastePlatformFreeBSD::GetDescriptionStatic (bool is_host) 105254721Semaste{ 106254721Semaste if (is_host) 107254721Semaste return "Local FreeBSD user platform plug-in."; 108254721Semaste else 109254721Semaste return "Remote FreeBSD user platform plug-in."; 110254721Semaste} 111254721Semaste 112254721Semastestatic uint32_t g_initialize_count = 0; 113254721Semaste 114254721Semastevoid 115254721SemastePlatformFreeBSD::Initialize () 116254721Semaste{ 117254721Semaste if (g_initialize_count++ == 0) 118254721Semaste { 119254721Semaste#if defined (__FreeBSD__) 120254721Semaste // Force a host flag to true for the default platform object. 121254721Semaste PlatformSP default_platform_sp (new PlatformFreeBSD(true)); 122254721Semaste default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); 123254721Semaste Platform::SetDefaultPlatform (default_platform_sp); 124254721Semaste#endif 125254721Semaste PluginManager::RegisterPlugin(PlatformFreeBSD::GetPluginNameStatic(false), 126254721Semaste PlatformFreeBSD::GetDescriptionStatic(false), 127254721Semaste PlatformFreeBSD::CreateInstance); 128254721Semaste } 129254721Semaste} 130254721Semaste 131254721Semastevoid 132254721SemastePlatformFreeBSD::Terminate () 133254721Semaste{ 134254721Semaste if (g_initialize_count > 0 && --g_initialize_count == 0) 135254721Semaste PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance); 136254721Semaste} 137254721Semaste 138254721Semaste//------------------------------------------------------------------ 139254721Semaste/// Default Constructor 140254721Semaste//------------------------------------------------------------------ 141254721SemastePlatformFreeBSD::PlatformFreeBSD (bool is_host) : 142254721SemastePlatform(is_host) 143254721Semaste{ 144254721Semaste} 145254721Semaste 146254721Semaste//------------------------------------------------------------------ 147254721Semaste/// Destructor. 148254721Semaste/// 149254721Semaste/// The destructor is virtual since this class is designed to be 150254721Semaste/// inherited from by the plug-in instance. 151254721Semaste//------------------------------------------------------------------ 152254721SemastePlatformFreeBSD::~PlatformFreeBSD() 153254721Semaste{ 154254721Semaste} 155254721Semaste 156254721Semaste 157254721SemasteError 158254721SemastePlatformFreeBSD::ResolveExecutable (const FileSpec &exe_file, 159254721Semaste const ArchSpec &exe_arch, 160254721Semaste lldb::ModuleSP &exe_module_sp, 161254721Semaste const FileSpecList *module_search_paths_ptr) 162254721Semaste{ 163254721Semaste Error error; 164254721Semaste // Nothing special to do here, just use the actual file and architecture 165254721Semaste 166254721Semaste char exe_path[PATH_MAX]; 167254721Semaste FileSpec resolved_exe_file (exe_file); 168254721Semaste 169254721Semaste if (IsHost()) 170254721Semaste { 171254721Semaste // If we have "ls" as the exe_file, resolve the executable location based on 172254721Semaste // the current path variables 173254721Semaste if (!resolved_exe_file.Exists()) 174254721Semaste { 175254721Semaste exe_file.GetPath(exe_path, sizeof(exe_path)); 176254721Semaste resolved_exe_file.SetFile(exe_path, true); 177254721Semaste } 178254721Semaste 179254721Semaste if (!resolved_exe_file.Exists()) 180254721Semaste resolved_exe_file.ResolveExecutableLocation (); 181254721Semaste 182254721Semaste if (resolved_exe_file.Exists()) 183254721Semaste error.Clear(); 184254721Semaste else 185254721Semaste { 186254721Semaste exe_file.GetPath(exe_path, sizeof(exe_path)); 187254721Semaste error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); 188254721Semaste } 189254721Semaste } 190254721Semaste else 191254721Semaste { 192254721Semaste if (m_remote_platform_sp) 193254721Semaste { 194254721Semaste error = m_remote_platform_sp->ResolveExecutable (exe_file, 195254721Semaste exe_arch, 196254721Semaste exe_module_sp, 197254721Semaste module_search_paths_ptr); 198254721Semaste } 199254721Semaste else 200254721Semaste { 201254721Semaste // We may connect to a process and use the provided executable (Don't use local $PATH). 202254721Semaste 203254721Semaste // Resolve any executable within a bundle on MacOSX 204254721Semaste Host::ResolveExecutableInBundle (resolved_exe_file); 205254721Semaste 206254721Semaste if (resolved_exe_file.Exists()) { 207254721Semaste error.Clear(); 208254721Semaste } 209254721Semaste else 210254721Semaste { 211254721Semaste exe_file.GetPath(exe_path, sizeof(exe_path)); 212254721Semaste error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); 213254721Semaste } 214254721Semaste } 215254721Semaste } 216254721Semaste 217254721Semaste 218254721Semaste if (error.Success()) 219254721Semaste { 220254721Semaste ModuleSpec module_spec (resolved_exe_file, exe_arch); 221254721Semaste if (module_spec.GetArchitecture().IsValid()) 222254721Semaste { 223254721Semaste error = ModuleList::GetSharedModule (module_spec, 224254721Semaste exe_module_sp, 225254721Semaste module_search_paths_ptr, 226254721Semaste NULL, 227254721Semaste NULL); 228254721Semaste 229254721Semaste if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) 230254721Semaste { 231254721Semaste exe_module_sp.reset(); 232254721Semaste error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", 233254721Semaste exe_file.GetPath().c_str(), 234254721Semaste exe_arch.GetArchitectureName()); 235254721Semaste } 236254721Semaste } 237254721Semaste else 238254721Semaste { 239254721Semaste // No valid architecture was specified, ask the platform for 240254721Semaste // the architectures that we should be using (in the correct order) 241254721Semaste // and see if we can find a match that way 242254721Semaste StreamString arch_names; 243254721Semaste ArchSpec platform_arch; 244254721Semaste for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) 245254721Semaste { 246254721Semaste error = ModuleList::GetSharedModule (module_spec, 247254721Semaste exe_module_sp, 248254721Semaste module_search_paths_ptr, 249254721Semaste NULL, 250254721Semaste NULL); 251254721Semaste // Did we find an executable using one of the 252254721Semaste if (error.Success()) 253254721Semaste { 254254721Semaste if (exe_module_sp && exe_module_sp->GetObjectFile()) 255254721Semaste break; 256254721Semaste else 257254721Semaste error.SetErrorToGenericError(); 258254721Semaste } 259254721Semaste 260254721Semaste if (idx > 0) 261254721Semaste arch_names.PutCString (", "); 262254721Semaste arch_names.PutCString (platform_arch.GetArchitectureName()); 263254721Semaste } 264254721Semaste 265254721Semaste if (error.Fail() || !exe_module_sp) 266254721Semaste { 267254721Semaste error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 268254721Semaste exe_file.GetPath().c_str(), 269254721Semaste GetPluginName().GetCString(), 270254721Semaste arch_names.GetString().c_str()); 271254721Semaste } 272254721Semaste } 273254721Semaste } 274254721Semaste else 275254721Semaste { 276254721Semaste error.SetErrorStringWithFormat ("'%s' does not exist", 277254721Semaste exe_file.GetPath().c_str()); 278254721Semaste } 279254721Semaste 280254721Semaste return error; 281254721Semaste} 282254721Semaste 283254721Semastesize_t 284254721SemastePlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 285254721Semaste{ 286254721Semaste ArchSpec arch = target.GetArchitecture(); 287254721Semaste const uint8_t *trap_opcode = NULL; 288254721Semaste size_t trap_opcode_size = 0; 289254721Semaste 290254721Semaste switch (arch.GetCore()) 291254721Semaste { 292254721Semaste default: 293254721Semaste assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()"); 294254721Semaste break; 295254721Semaste 296254721Semaste case ArchSpec::eCore_x86_32_i386: 297254721Semaste case ArchSpec::eCore_x86_64_x86_64: 298254721Semaste { 299254721Semaste static const uint8_t g_i386_opcode[] = { 0xCC }; 300254721Semaste trap_opcode = g_i386_opcode; 301254721Semaste trap_opcode_size = sizeof(g_i386_opcode); 302254721Semaste } 303254721Semaste break; 304254721Semaste } 305254721Semaste 306254721Semaste if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 307254721Semaste return trap_opcode_size; 308254721Semaste 309254721Semaste return 0; 310254721Semaste} 311254721Semaste 312254721Semastebool 313254721SemastePlatformFreeBSD::GetRemoteOSVersion () 314254721Semaste{ 315254721Semaste if (m_remote_platform_sp) 316254721Semaste return m_remote_platform_sp->GetOSVersion (m_major_os_version, 317254721Semaste m_minor_os_version, 318254721Semaste m_update_os_version); 319254721Semaste return false; 320254721Semaste} 321254721Semaste 322254721Semastebool 323254721SemastePlatformFreeBSD::GetRemoteOSBuildString (std::string &s) 324254721Semaste{ 325254721Semaste if (m_remote_platform_sp) 326254721Semaste return m_remote_platform_sp->GetRemoteOSBuildString (s); 327254721Semaste s.clear(); 328254721Semaste return false; 329254721Semaste} 330254721Semaste 331254721Semastebool 332254721SemastePlatformFreeBSD::GetRemoteOSKernelDescription (std::string &s) 333254721Semaste{ 334254721Semaste if (m_remote_platform_sp) 335254721Semaste return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 336254721Semaste s.clear(); 337254721Semaste return false; 338254721Semaste} 339254721Semaste 340254721Semaste// Remote Platform subclasses need to override this function 341254721SemasteArchSpec 342254721SemastePlatformFreeBSD::GetRemoteSystemArchitecture () 343254721Semaste{ 344254721Semaste if (m_remote_platform_sp) 345254721Semaste return m_remote_platform_sp->GetRemoteSystemArchitecture (); 346254721Semaste return ArchSpec(); 347254721Semaste} 348254721Semaste 349254721Semaste 350254721Semasteconst char * 351254721SemastePlatformFreeBSD::GetHostname () 352254721Semaste{ 353254721Semaste if (IsHost()) 354254721Semaste return Platform::GetHostname(); 355254721Semaste 356254721Semaste if (m_remote_platform_sp) 357254721Semaste return m_remote_platform_sp->GetHostname (); 358254721Semaste return NULL; 359254721Semaste} 360254721Semaste 361254721Semastebool 362254721SemastePlatformFreeBSD::IsConnected () const 363254721Semaste{ 364254721Semaste if (IsHost()) 365254721Semaste return true; 366254721Semaste else if (m_remote_platform_sp) 367254721Semaste return m_remote_platform_sp->IsConnected(); 368254721Semaste return false; 369254721Semaste} 370254721Semaste 371254721SemasteError 372254721SemastePlatformFreeBSD::ConnectRemote (Args& args) 373254721Semaste{ 374254721Semaste Error error; 375254721Semaste if (IsHost()) 376254721Semaste { 377254721Semaste error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 378254721Semaste } 379254721Semaste else 380254721Semaste { 381254721Semaste if (!m_remote_platform_sp) 382254721Semaste m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 383254721Semaste 384254721Semaste if (m_remote_platform_sp) 385254721Semaste { 386254721Semaste if (error.Success()) 387254721Semaste { 388254721Semaste if (m_remote_platform_sp) 389254721Semaste { 390254721Semaste error = m_remote_platform_sp->ConnectRemote (args); 391254721Semaste } 392254721Semaste else 393254721Semaste { 394254721Semaste error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); 395254721Semaste } 396254721Semaste } 397254721Semaste } 398254721Semaste else 399254721Semaste error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 400254721Semaste 401254721Semaste if (error.Fail()) 402254721Semaste m_remote_platform_sp.reset(); 403254721Semaste } 404254721Semaste 405254721Semaste return error; 406254721Semaste} 407254721Semaste 408254721SemasteError 409254721SemastePlatformFreeBSD::DisconnectRemote () 410254721Semaste{ 411254721Semaste Error error; 412254721Semaste 413254721Semaste if (IsHost()) 414254721Semaste { 415254721Semaste error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 416254721Semaste } 417254721Semaste else 418254721Semaste { 419254721Semaste if (m_remote_platform_sp) 420254721Semaste error = m_remote_platform_sp->DisconnectRemote (); 421254721Semaste else 422254721Semaste error.SetErrorString ("the platform is not currently connected"); 423254721Semaste } 424254721Semaste return error; 425254721Semaste} 426254721Semaste 427254721Semastebool 428254721SemastePlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 429254721Semaste{ 430254721Semaste bool success = false; 431254721Semaste if (IsHost()) 432254721Semaste { 433254721Semaste success = Platform::GetProcessInfo (pid, process_info); 434254721Semaste } 435254721Semaste else if (m_remote_platform_sp) 436254721Semaste { 437254721Semaste success = m_remote_platform_sp->GetProcessInfo (pid, process_info); 438254721Semaste } 439254721Semaste return success; 440254721Semaste} 441254721Semaste 442254721Semaste 443254721Semaste 444254721Semasteuint32_t 445254721SemastePlatformFreeBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info, 446254721Semaste ProcessInstanceInfoList &process_infos) 447254721Semaste{ 448254721Semaste uint32_t match_count = 0; 449254721Semaste if (IsHost()) 450254721Semaste { 451254721Semaste // Let the base class figure out the host details 452254721Semaste match_count = Platform::FindProcesses (match_info, process_infos); 453254721Semaste } 454254721Semaste else 455254721Semaste { 456254721Semaste // If we are remote, we can only return results if we are connected 457254721Semaste if (m_remote_platform_sp) 458254721Semaste match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 459254721Semaste } 460254721Semaste return match_count; 461254721Semaste} 462254721Semaste 463254721SemasteError 464254721SemastePlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info) 465254721Semaste{ 466254721Semaste Error error; 467254721Semaste if (IsHost()) 468254721Semaste { 469254721Semaste error = Platform::LaunchProcess (launch_info); 470254721Semaste } 471254721Semaste else 472254721Semaste { 473254721Semaste if (m_remote_platform_sp) 474254721Semaste error = m_remote_platform_sp->LaunchProcess (launch_info); 475254721Semaste else 476254721Semaste error.SetErrorString ("the platform is not currently connected"); 477254721Semaste } 478254721Semaste return error; 479254721Semaste} 480254721Semaste 481254721Semastelldb::ProcessSP 482254721SemastePlatformFreeBSD::Attach(ProcessAttachInfo &attach_info, 483254721Semaste Debugger &debugger, 484254721Semaste Target *target, 485254721Semaste Listener &listener, 486254721Semaste Error &error) 487254721Semaste{ 488254721Semaste lldb::ProcessSP process_sp; 489254721Semaste if (IsHost()) 490254721Semaste { 491254721Semaste if (target == NULL) 492254721Semaste { 493254721Semaste TargetSP new_target_sp; 494254721Semaste ArchSpec emptyArchSpec; 495254721Semaste 496254721Semaste error = debugger.GetTargetList().CreateTarget (debugger, 497254721Semaste NULL, 498254721Semaste emptyArchSpec, 499254721Semaste false, 500254721Semaste m_remote_platform_sp, 501254721Semaste new_target_sp); 502254721Semaste target = new_target_sp.get(); 503254721Semaste } 504254721Semaste else 505254721Semaste error.Clear(); 506254721Semaste 507254721Semaste if (target && error.Success()) 508254721Semaste { 509254721Semaste debugger.GetTargetList().SetSelectedTarget(target); 510254721Semaste // The freebsd always currently uses the GDB remote debugger plug-in 511254721Semaste // so even when debugging locally we are debugging remotely! 512254721Semaste // Just like the darwin plugin. 513254721Semaste process_sp = target->CreateProcess (listener, "gdb-remote", NULL); 514254721Semaste 515254721Semaste if (process_sp) 516254721Semaste error = process_sp->Attach (attach_info); 517254721Semaste } 518254721Semaste } 519254721Semaste else 520254721Semaste { 521254721Semaste if (m_remote_platform_sp) 522254721Semaste process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 523254721Semaste else 524254721Semaste error.SetErrorString ("the platform is not currently connected"); 525254721Semaste } 526254721Semaste return process_sp; 527254721Semaste} 528254721Semaste 529254721Semasteconst char * 530254721SemastePlatformFreeBSD::GetUserName (uint32_t uid) 531254721Semaste{ 532254721Semaste // Check the cache in Platform in case we have already looked this uid up 533254721Semaste const char *user_name = Platform::GetUserName(uid); 534254721Semaste if (user_name) 535254721Semaste return user_name; 536254721Semaste 537254721Semaste if (IsRemote() && m_remote_platform_sp) 538254721Semaste return m_remote_platform_sp->GetUserName(uid); 539254721Semaste return NULL; 540254721Semaste} 541254721Semaste 542254721Semasteconst char * 543254721SemastePlatformFreeBSD::GetGroupName (uint32_t gid) 544254721Semaste{ 545254721Semaste const char *group_name = Platform::GetGroupName(gid); 546254721Semaste if (group_name) 547254721Semaste return group_name; 548254721Semaste 549254721Semaste if (IsRemote() && m_remote_platform_sp) 550254721Semaste return m_remote_platform_sp->GetGroupName(gid); 551254721Semaste return NULL; 552254721Semaste} 553254721Semaste 554254721Semaste 555254721Semaste// From PlatformMacOSX only 556254721SemasteError 557254721SemastePlatformFreeBSD::GetFile (const FileSpec &platform_file, 558254721Semaste const UUID *uuid_ptr, 559254721Semaste FileSpec &local_file) 560254721Semaste{ 561254721Semaste if (IsRemote()) 562254721Semaste { 563254721Semaste if (m_remote_platform_sp) 564254721Semaste return m_remote_platform_sp->GetFile (platform_file, uuid_ptr, local_file); 565254721Semaste } 566254721Semaste 567254721Semaste // Default to the local case 568254721Semaste local_file = platform_file; 569254721Semaste return Error(); 570254721Semaste} 571254721Semaste 572254721SemasteError 573254721SemastePlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec, 574254721Semaste ModuleSP &module_sp, 575254721Semaste const FileSpecList *module_search_paths_ptr, 576254721Semaste ModuleSP *old_module_sp_ptr, 577254721Semaste bool *did_create_ptr) 578254721Semaste{ 579254721Semaste Error error; 580254721Semaste module_sp.reset(); 581254721Semaste 582254721Semaste if (IsRemote()) 583254721Semaste { 584254721Semaste // If we have a remote platform always, let it try and locate 585254721Semaste // the shared module first. 586254721Semaste if (m_remote_platform_sp) 587254721Semaste { 588254721Semaste error = m_remote_platform_sp->GetSharedModule (module_spec, 589254721Semaste module_sp, 590254721Semaste module_search_paths_ptr, 591254721Semaste old_module_sp_ptr, 592254721Semaste did_create_ptr); 593254721Semaste } 594254721Semaste } 595254721Semaste 596254721Semaste if (!module_sp) 597254721Semaste { 598254721Semaste // Fall back to the local platform and find the file locally 599254721Semaste error = Platform::GetSharedModule (module_spec, 600254721Semaste module_sp, 601254721Semaste module_search_paths_ptr, 602254721Semaste old_module_sp_ptr, 603254721Semaste did_create_ptr); 604254721Semaste } 605254721Semaste if (module_sp) 606254721Semaste module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 607254721Semaste return error; 608254721Semaste} 609254721Semaste 610254721Semaste 611254721Semastebool 612254721SemastePlatformFreeBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 613254721Semaste{ 614254721Semaste // From macosx;s plugin code. For FreeBSD we may want to support more archs. 615254721Semaste if (idx == 0) 616254721Semaste { 617254721Semaste arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 618254721Semaste return arch.IsValid(); 619254721Semaste } 620254721Semaste else if (idx == 1) 621254721Semaste { 622254721Semaste ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); 623254721Semaste ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); 624254721Semaste if (platform_arch.IsExactMatch(platform_arch64)) 625254721Semaste { 626254721Semaste // This freebsd platform supports both 32 and 64 bit. Since we already 627254721Semaste // returned the 64 bit arch for idx == 0, return the 32 bit arch 628254721Semaste // for idx == 1 629254721Semaste arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 630254721Semaste return arch.IsValid(); 631254721Semaste } 632254721Semaste } 633254721Semaste return false; 634254721Semaste} 635254721Semaste 636254721Semastevoid 637254721SemastePlatformFreeBSD::GetStatus (Stream &strm) 638254721Semaste{ 639254721Semaste struct utsname un; 640254721Semaste 641254721Semaste if (uname(&un)) { 642254721Semaste strm << "FreeBSD"; 643254721Semaste return; 644254721Semaste } 645254721Semaste 646254721Semaste strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n'; 647254721Semaste Platform::GetStatus(strm); 648254721Semaste} 649