diff options
Diffstat (limited to 'source/Plugins/Platform/Kalimba/PlatformKalimba.cpp')
-rw-r--r-- | source/Plugins/Platform/Kalimba/PlatformKalimba.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp new file mode 100644 index 0000000000000..2f1e4d5543201 --- /dev/null +++ b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp @@ -0,0 +1,324 @@ +//===-- PlatformKalimba.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PlatformKalimba.h" +#include "lldb/Host/Config.h" + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Error.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Process.h" + +using namespace lldb; +using namespace lldb_private; + +static uint32_t g_initialize_count = 0; + +PlatformSP +PlatformKalimba::CreateInstance (bool force, const ArchSpec *arch) +{ + bool create = force; + if (create == false && arch && arch->IsValid()) + { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) + { + case llvm::Triple::CSR: + create = true; + break; + + default: + break; + } + } + if (create) + return PlatformSP(new PlatformKalimba(false)); + return PlatformSP(); +} + +lldb_private::ConstString +PlatformKalimba::GetPluginNameStatic (bool /*is_host*/) +{ + static ConstString g_remote_name("kalimba"); + return g_remote_name; +} + +const char * +PlatformKalimba::GetPluginDescriptionStatic (bool /*is_host*/) +{ + return "Kalimba user platform plug-in."; +} + +lldb_private::ConstString +PlatformKalimba::GetPluginName() +{ + return GetPluginNameStatic(false); +} + +void +PlatformKalimba::Initialize () +{ + Platform::Initialize (); + + if (g_initialize_count++ == 0) + { + PluginManager::RegisterPlugin(PlatformKalimba::GetPluginNameStatic(false), + PlatformKalimba::GetPluginDescriptionStatic(false), + PlatformKalimba::CreateInstance); + } +} + +void +PlatformKalimba::Terminate () +{ + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformKalimba::CreateInstance); + } + } + + Platform::Terminate (); +} + +Error +PlatformKalimba::ResolveExecutable (const ModuleSpec &ms, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) +{ + Error error; + char exe_path[PATH_MAX]; + ModuleSpec resolved_module_spec(ms); + + if (!resolved_module_spec.GetFileSpec().Exists()) + { + resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); + } + + if (error.Success()) + { + if (resolved_module_spec.GetArchitecture().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + if (error.Fail()) + { + // If we failed, it may be because the vendor and os aren't known. If that is the + // case, try setting them to the host architecture and give it another try. + llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple(); + bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); + bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); + if (!is_vendor_specified || !is_os_specified) + { + const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); + + if (!is_vendor_specified) + module_triple.setVendorName (host_triple.getVendorName()); + if (!is_os_specified) + module_triple.setOSName (host_triple.getOSName()); + + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + } + } + + // TODO find out why exe_module_sp might be NULL + if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) + { + exe_module_sp.reset(); + error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + } + else + { + // No valid architecture was specified, ask the platform for + // the architectures that we should be using (in the correct order) + // and see if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + } + + return error; +} + +Error +PlatformKalimba::GetFileWithUUID (const FileSpec & /*platform_file*/, + const UUID * /*uuid_ptr*/, FileSpec & /*local_file*/) +{ + return Error(); +} + + +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformKalimba::PlatformKalimba (bool is_host) : + Platform(is_host), // This is the local host platform + m_remote_platform_sp () +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformKalimba::~PlatformKalimba() +{ +} + +bool +PlatformKalimba::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) +{ + bool success = false; + if (IsHost()) + { + success = false; + } + else + { + if (m_remote_platform_sp) + success = m_remote_platform_sp->GetProcessInfo (pid, process_info); + } + return success; +} + +bool +PlatformKalimba::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + if (idx == 0) + { + arch = ArchSpec("kalimba3-csr-unknown"); + return true; + } + if (idx == 1) + { + arch = ArchSpec("kalimba4-csr-unknown"); + return true; + } + if (idx == 2) + { + arch = ArchSpec("kalimba5-csr-unknown"); + return true; + } + return false; +} + +void +PlatformKalimba::GetStatus (Stream &strm) +{ + Platform::GetStatus(strm); +} + +size_t +PlatformKalimba::GetSoftwareBreakpointTrapOpcode (Target & /*target*/, + BreakpointSite * /*bp_site*/) +{ + // the target hardware does not support software breakpoints + return 0; +} + +Error +PlatformKalimba::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + + if (IsHost()) + { + error.SetErrorString ("native execution is not possible"); + } + else + { + error.SetErrorString ("the platform is not currently connected"); + } + return error; +} + +lldb::ProcessSP +PlatformKalimba::Attach(ProcessAttachInfo &attach_info, + Debugger &debugger, + Target *target, + Error &error) +{ + lldb::ProcessSP process_sp; + if (IsHost()) + { + error.SetErrorString ("native execution is not possible"); + } + 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; +} + +void +PlatformKalimba::CalculateTrapHandlerSymbolNames () +{ + // TODO Research this sometime. +} |