Greg Clayton wrote:
A few questions:
In PlatformKalimba::GetProcessInfo() the code is:
bool
PlatformKalimba::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo
&process_info)
{
bool success = false;
if (IsHost())
{
success = Platform::GetProcessInfo (pid, process_info);
}
else
{
if (m_remote_platform_sp)
success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
}
return success;
}
Can "kalimba" processes actually run locally on your host machine as native apps? I would
guess that PlatformKalimba is for remote debugging only and would expect your code to return false
if "IsHost()" is true in that case. If you are running a simulator that uses local
processes on the host machine, then this is correct.
We can't run kalimba ELFs on the host. We do have a simulator (which
acts on a file resulting from turning an ELF into a bespoke target
memory view) to run on the host, but we'd connect to the sim, in the
"same" way as a real device, except that the CSR-type SPI wire packets,
move over TCP/IP not on a real wire as such. So debugging kalimba on a
simulator is still remote debugging. I'll modify my implementation as
follows:
bool success = false;
if (IsHost())
{
- success = Platform::GetProcessInfo (pid, process_info);
+ success = false;
}
else
{
which I believe to be your suggestion.
In your GetSupportedArchitectureAtIndex you should only return true if "idx ==
0":
bool
PlatformKalimba::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
if (idx == 0)
{
arch = ArchSpec("kalimba-csr-unknown");
return true;
}
return false;
}
GetSupportedArchitectureAtIndex gets used when you select your platform and then load an executable. It will
search for valid architectures by iterating through the architectures using an increasing index. This is needed
for cases like iOS where the iOS device might be "armv7s", but when we load a binary, we will start with
"armv7s" and then back up to looking for "armv7", armv6", etc.
Ok, thanks for this, I'll modify my next patch attempt accordingly.
You will need to fill out:
size_t
PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
*bp_site)
{
}
You mainly need to figure out which opcode your target will use as a breakpoint
instruction and return its size and fill in the bytes for the instruction, see
PlatformDarwin::GetSoftwareBreakpointTrapOpcode() for an example.
Software breakpoints aren't properly supported on kalimba. We did have
them in the earlier variants, but I'm told that these never worked well:
there were issues in the pipeline implementation and so on.
So I think that my original implementation of "return 0" was correct.
Kalimba architectures do, however, support setting up to 8 hardware
breakpoints. That is, we have dedicated debug registers in the hardware.
By the way what sort of thing should PlatformKalimba do for
CalculateTrapHandlerSymbolNames? Should that be a no-op, not a
m_trap_handlers.push_back (ConstString ("_sigtramp"));?
In PlatformKalimba::LaunchProcess() you end up launching a host process after
checking IsHost(), is this your intention? Are you running a simulator?
Ok. So is it correct to merely do something like this:
if (IsHost())
{
error.SetErrorString ("native execution is not possible");
}
?
Same thing for PlatformKalimba::Attach().
Ok. So I'll make a similar change to the one made to LaunchProcess.
In response to Greg's review and my current thoughts I'm attaching the
latest version of the PlatformKalimba.cpp. Is this file now a good
enough first attempt? Or are there any further areas to complete?
In summary I've
1. Modified GetProcessInfo to return false if IsHost()==true.
2. Implemented GetSupportedArchitectureAtIndex as per Greg's suggestion.
3. Modified LaunchProcess and Attach to merely set up an error if
IsHost()==true.
4. Retained my previous implementation for
GetSoftwareBreakpointTrapOpcode with reasoning.
5. Remove m_trap_handlers.push_back (ConstString ("_sigtramp")); from
CalculateTrapHandlerSymbolNames.
I look forward to further comment.
thanks
Matt
Member of the CSR plc group of companies. CSR plc registered in England and
Wales, registered number 4187346, registered office Churchill House, Cambridge
Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our
technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube,
www.youtube.com/user/CSRplc, Facebook,
www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at
www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at
www.aptx.com.
//===-- 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 "lldb/lldb-python.h"
#include "PlatformKalimba.h"
#include "lldb/Host/Config.h"
// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
// 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/Host.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;
Platform *
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 new PlatformKalimba(false);
return NULL;
}
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 ()
{
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);
}
}
}
Error
PlatformKalimba::ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &exe_arch,
lldb::ModuleSP &exe_module_sp,
const FileSpecList *module_search_paths_ptr)
{
Error error;
char exe_path[PATH_MAX];
FileSpec resolved_exe_file (exe_file);
if (!resolved_exe_file.Exists())
{
exe_file.GetPath(exe_path, sizeof(exe_path));
error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
}
if (error.Success())
{
ModuleSpec module_spec (resolved_exe_file, exe_arch);
if (exe_arch.IsValid())
{
error = ModuleList::GetSharedModule (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 = 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 = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple();
if (!is_vendor_specified)
module_triple.setVendorName (host_triple.getVendorName());
if (!is_os_specified)
module_triple.setOSName (host_triple.getOSName());
error = ModuleList::GetSharedModule (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",
exe_file.GetPath().c_str(),
exe_arch.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, module_spec.GetArchitecture()); ++idx)
{
error = ModuleList::GetSharedModule (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 (module_spec.GetArchitecture().GetArchitectureName());
}
if (error.Fail() || !exe_module_sp)
{
error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
exe_file.GetPath().c_str(),
GetPluginName().GetCString(),
arch_names.GetString().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("kalimba-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,
Listener &listener,
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, listener, error);
else
error.SetErrorString ("the platform is not currently connected");
}
return process_sp;
}
void
PlatformKalimba::CalculateTrapHandlerSymbolNames ()
{
}
Error
PlatformKalimba::LaunchNativeProcess (
ProcessLaunchInfo &,
lldb_private::NativeProcessProtocol::NativeDelegate &,
NativeProcessProtocolSP &)
{
return Error();
}
Error
PlatformKalimba::AttachNativeProcess (lldb::pid_t,
lldb_private::NativeProcessProtocol::NativeDelegate &,
NativeProcessProtocolSP &)
{
return Error();
}
_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev