summaryrefslogtreecommitdiff
path: root/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp')
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp445
1 files changed, 261 insertions, 184 deletions
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 3b38a5819934..9b3c57501117 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "PlatformFreeBSD.h"
#include "lldb/Host/Config.h"
@@ -21,6 +19,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -28,12 +28,14 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Process.h"
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::platform_freebsd;
PlatformSP
-PlatformFreeBSD::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
+PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch)
{
// The only time we create an instance is when we are creating a remote
// freebsd platform
@@ -43,45 +45,23 @@ PlatformFreeBSD::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
if (create == false && arch && arch->IsValid())
{
const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
+ switch (triple.getOS())
{
- case llvm::Triple::PC:
+ case llvm::Triple::FreeBSD:
create = true;
break;
#if defined(__FreeBSD__) || defined(__OpenBSD__)
- // Only accept "unknown" for the vendor if the host is BSD and
+ // Only accept "unknown" for the OS if the host is BSD and
// it "unknown" wasn't specified (it was just returned because it
// was NOT specified)
- case llvm::Triple::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
+ case llvm::Triple::OSType::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
break;
#endif
default:
break;
}
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::FreeBSD:
- case llvm::Triple::KFreeBSD:
- break;
-
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
- // Only accept "unknown" for the OS if the host is BSD and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
}
if (create)
return PlatformSP(new PlatformFreeBSD (is_host));
@@ -89,8 +69,8 @@ PlatformFreeBSD::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
}
-lldb_private::ConstString
-PlatformFreeBSD::GetPluginNameStatic (bool is_host)
+ConstString
+PlatformFreeBSD::GetPluginNameStatic(bool is_host)
{
if (is_host)
{
@@ -118,6 +98,8 @@ static uint32_t g_initialize_count = 0;
void
PlatformFreeBSD::Initialize ()
{
+ Platform::Initialize ();
+
if (g_initialize_count++ == 0)
{
#if defined (__FreeBSD__)
@@ -137,35 +119,28 @@ PlatformFreeBSD::Terminate ()
{
if (g_initialize_count > 0 && --g_initialize_count == 0)
PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance);
-}
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformFreeBSD::PlatformFreeBSD (bool is_host) :
-Platform(is_host),
-m_remote_platform_sp()
-{
+ Platform::Terminate ();
}
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformFreeBSD::~PlatformFreeBSD()
+bool
+PlatformFreeBSD::GetModuleSpec (const FileSpec& module_file_spec,
+ const ArchSpec& arch,
+ ModuleSpec &module_spec)
{
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+
+ return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
}
-//TODO:VK: inherit PlatformPOSIX
-lldb_private::Error
-PlatformFreeBSD::RunShellCommand (const char *command,
- const char *working_dir,
- int *status_ptr,
- int *signo_ptr,
- std::string *command_output,
- uint32_t timeout_sec)
+Error
+PlatformFreeBSD::RunShellCommand(const char *command,
+ const FileSpec &working_dir,
+ int *status_ptr,
+ int *signo_ptr,
+ std::string *command_output,
+ uint32_t timeout_sec)
{
if (IsHost())
return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
@@ -178,7 +153,6 @@ PlatformFreeBSD::RunShellCommand (const char *command,
}
}
-
Error
PlatformFreeBSD::ResolveExecutable (const ModuleSpec &module_spec,
lldb::ModuleSP &exe_module_sp,
@@ -214,9 +188,7 @@ PlatformFreeBSD::ResolveExecutable (const ModuleSpec &module_spec,
{
if (m_remote_platform_sp)
{
- error = m_remote_platform_sp->ResolveExecutable (module_spec,
- exe_module_sp,
- module_search_paths_ptr);
+ error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
}
else
{
@@ -301,41 +273,46 @@ PlatformFreeBSD::ResolveExecutable (const ModuleSpec &module_spec,
return error;
}
-size_t
-PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
+// From PlatformMacOSX only
+Error
+PlatformFreeBSD::GetFileWithUUID (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file)
{
- ArchSpec arch = target.GetArchitecture();
- const uint8_t *trap_opcode = NULL;
- size_t trap_opcode_size = 0;
-
- switch (arch.GetMachine())
+ if (IsRemote())
{
- default:
- assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()");
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_opcode[] = { 0xCC };
- trap_opcode = g_i386_opcode;
- trap_opcode_size = sizeof(g_i386_opcode);
- }
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- {
- static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
- trap_opcode = g_ppc_opcode;
- trap_opcode_size = sizeof(g_ppc_opcode);
- }
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
}
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
+}
- return 0;
+
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformFreeBSD::PlatformFreeBSD (bool is_host) :
+ Platform(is_host),
+ m_remote_platform_sp()
+{
+}
+
+//------------------------------------------------------------------
+/// Destructor.
+///
+/// The destructor is virtual since this class is designed to be
+/// inherited from by the plug-in instance.
+//------------------------------------------------------------------
+PlatformFreeBSD::~PlatformFreeBSD()
+{
}
+//TODO:VK: inherit PlatformPOSIX
+
+
bool
PlatformFreeBSD::GetRemoteOSVersion ()
{
@@ -466,8 +443,6 @@ PlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_i
return success;
}
-
-
uint32_t
PlatformFreeBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos)
@@ -487,71 +462,6 @@ PlatformFreeBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info,
return match_count;
}
-Error
-PlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
- if (IsHost())
- {
- error = Platform::LaunchProcess (launch_info);
- }
- else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess (launch_info);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
-}
-
-lldb::ProcessSP
-PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsHost())
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- emptyArchSpec,
- false,
- m_remote_platform_sp,
- new_target_sp);
- target = new_target_sp.get();
- }
- else
- error.Clear();
-
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
- // The freebsd always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- // Just like the darwin plugin.
- process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
-
- if (process_sp)
- error = process_sp->Attach (attach_info);
- }
- }
- else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
-}
-
const char *
PlatformFreeBSD::GetUserName (uint32_t uid)
{
@@ -578,25 +488,9 @@ PlatformFreeBSD::GetGroupName (uint32_t gid)
}
-// From PlatformMacOSX only
-Error
-PlatformFreeBSD::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
- }
-
- // Default to the local case
- local_file = platform_file;
- return Error();
-}
-
Error
PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
+ Process* process,
ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr,
@@ -612,6 +506,7 @@ PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
if (m_remote_platform_sp)
{
error = m_remote_platform_sp->GetSharedModule (module_spec,
+ process,
module_sp,
module_search_paths_ptr,
old_module_sp_ptr,
@@ -623,6 +518,7 @@ PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
{
// Fall back to the local platform and find the file locally
error = Platform::GetSharedModule (module_spec,
+ process,
module_sp,
module_search_paths_ptr,
old_module_sp_ptr,
@@ -637,24 +533,56 @@ PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
bool
PlatformFreeBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
- // From macosx;s plugin code. For FreeBSD we may want to support more archs.
- if (idx == 0)
+ if (IsHost())
{
- arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- return arch.IsValid();
+ ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ if (hostArch.GetTriple().isOSFreeBSD())
+ {
+ if (idx == 0)
+ {
+ arch = hostArch;
+ return arch.IsValid();
+ }
+ else if (idx == 1)
+ {
+ // If the default host architecture is 64-bit, look for a 32-bit variant
+ if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
+ {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return arch.IsValid();
+ }
+ }
+ }
}
- else if (idx == 1)
+ else
{
- ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64));
- if (platform_arch.IsExactMatch(platform_arch64))
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
+
+ llvm::Triple triple;
+ // Set the OS to FreeBSD
+ triple.setOS(llvm::Triple::FreeBSD);
+ // Set the architecture
+ switch (idx)
{
- // This freebsd platform supports both 32 and 64 bit. Since we already
- // returned the 64 bit arch for idx == 0, return the 32 bit arch
- // for idx == 1
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
+ case 0: triple.setArchName("x86_64"); break;
+ case 1: triple.setArchName("i386"); break;
+ case 2: triple.setArchName("aarch64"); break;
+ case 3: triple.setArchName("arm"); break;
+ case 4: triple.setArchName("mips64"); break;
+ case 5: triple.setArchName("mips"); break;
+ case 6: triple.setArchName("ppc64"); break;
+ case 7: triple.setArchName("ppc"); break;
+ default: return false;
}
+ // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
+ // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
+ // This means when someone calls triple.GetVendorName() it will return an empty string
+ // which indicates that the vendor can be set when two architectures are merged
+
+ // Now set the triple into "arch" and return true
+ arch.SetTriple(triple);
+ return true;
}
return false;
}
@@ -683,8 +611,157 @@ PlatformFreeBSD::GetStatus (Stream &strm)
Platform::GetStatus(strm);
}
+size_t
+PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
+{
+ ArchSpec arch = target.GetArchitecture();
+ const uint8_t *trap_opcode = NULL;
+ size_t trap_opcode_size = 0;
+
+ switch (arch.GetMachine())
+ {
+ default:
+ assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()");
+ break;
+ case llvm::Triple::aarch64:
+ {
+ static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
+ trap_opcode = g_aarch64_opcode;
+ trap_opcode_size = sizeof(g_aarch64_opcode);
+ }
+ break;
+ // TODO: support big-endian arm and thumb trap codes.
+ case llvm::Triple::arm:
+ {
+ static const uint8_t g_arm_breakpoint_opcode[] = { 0xfe, 0xde, 0xff, 0xe7 };
+ static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
+
+ lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp)
+ addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
+
+ if (addr_class == eAddressClassCodeAlternateISA
+ || (addr_class == eAddressClassUnknown && (bp_site->GetLoadAddress() & 1)))
+ {
+ // TODO: Enable when FreeBSD supports thumb breakpoints.
+ // FreeBSD kernel as of 10.x, does not support thumb breakpoints
+ trap_opcode = g_thumb_breakpoint_opcode;
+ trap_opcode_size = 0;
+ }
+ else
+ {
+ trap_opcode = g_arm_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ }
+ }
+ break;
+ case llvm::Triple::mips64:
+ {
+ static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+ case llvm::Triple::mips64el:
+ {
+ static const uint8_t g_hex_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ {
+ static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
+ trap_opcode = g_ppc_opcode;
+ trap_opcode_size = sizeof(g_ppc_opcode);
+ }
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ {
+ static const uint8_t g_i386_opcode[] = { 0xCC };
+ trap_opcode = g_i386_opcode;
+ trap_opcode_size = sizeof(g_i386_opcode);
+ }
+ break;
+ }
+
+ if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
+ return trap_opcode_size;
+ return 0;
+}
+
+
void
PlatformFreeBSD::CalculateTrapHandlerSymbolNames ()
{
m_trap_handlers.push_back (ConstString ("_sigtramp"));
}
+
+Error
+PlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+ Error error;
+ if (IsHost())
+ {
+ error = Platform::LaunchProcess (launch_info);
+ }
+ else
+ {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->LaunchProcess (launch_info);
+ else
+ error.SetErrorString ("the platform is not currently connected");
+ }
+ return error;
+}
+
+lldb::ProcessSP
+PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger,
+ Target *target,
+ Error &error)
+{
+ lldb::ProcessSP process_sp;
+ if (IsHost())
+ {
+ if (target == NULL)
+ {
+ TargetSP new_target_sp;
+ ArchSpec emptyArchSpec;
+
+ error = debugger.GetTargetList().CreateTarget (debugger,
+ NULL,
+ emptyArchSpec,
+ false,
+ m_remote_platform_sp,
+ new_target_sp);
+ target = new_target_sp.get();
+ }
+ else
+ error.Clear();
+
+ if (target && error.Success())
+ {
+ debugger.GetTargetList().SetSelectedTarget(target);
+ // The freebsd always currently uses the GDB remote debugger plug-in
+ // so even when debugging locally we are debugging remotely!
+ // Just like the darwin plugin.
+ process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
+
+ if (process_sp)
+ error = process_sp->Attach (attach_info);
+ }
+ }
+ else
+ {
+ if (m_remote_platform_sp)
+ process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
+ else
+ error.SetErrorString ("the platform is not currently connected");
+ }
+ return process_sp;
+}