Added a hollowed out version of an OperatingSystem plugin that will use a class in python to get thread information for threads stored in memory.
llvm-svn: 162472
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
#include "OperatingSystemPython.h"
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
#include "lldb/Symbol/ClangNamespaceDecl.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/ThreadList.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
|
||||
#include "Plugins/Process/Utility/RegisterContextMemory.h"
|
||||
#include "Plugins/Process/Utility/ThreadMemory.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
void
|
||||
OperatingSystemPython::Initialize()
|
||||
{
|
||||
PluginManager::RegisterPlugin (GetPluginNameStatic(),
|
||||
GetPluginDescriptionStatic(),
|
||||
CreateInstance);
|
||||
}
|
||||
|
||||
void
|
||||
OperatingSystemPython::Terminate()
|
||||
{
|
||||
PluginManager::UnregisterPlugin (CreateInstance);
|
||||
}
|
||||
|
||||
OperatingSystem *
|
||||
OperatingSystemPython::CreateInstance (Process *process, bool force)
|
||||
{
|
||||
// Python OperatingSystem plug-ins must be requested by name, so force must be true
|
||||
if (force)
|
||||
return new OperatingSystemPython (process);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
OperatingSystemPython::GetPluginNameStatic()
|
||||
{
|
||||
return "python";
|
||||
}
|
||||
|
||||
const char *
|
||||
OperatingSystemPython::GetPluginDescriptionStatic()
|
||||
{
|
||||
return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
|
||||
}
|
||||
|
||||
|
||||
OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
|
||||
OperatingSystem (process),
|
||||
m_thread_list_valobj_sp (),
|
||||
m_register_info_ap ()
|
||||
{
|
||||
// TODO: python: create a new python class the implements the necessary
|
||||
// python class that will cache a SBProcess that contains the "process"
|
||||
// argument above and implements:
|
||||
// dict get_thread_info()
|
||||
// dict get_register_info()
|
||||
// Bytes get_register_context_data(SBThread thread)
|
||||
}
|
||||
|
||||
OperatingSystemPython::~OperatingSystemPython ()
|
||||
{
|
||||
}
|
||||
|
||||
DynamicRegisterInfo *
|
||||
OperatingSystemPython::GetDynamicRegisterInfo ()
|
||||
{
|
||||
// TODO: python: call get_register_info() on the python object that
|
||||
// represents our instance of the OperatingSystem plug-in
|
||||
|
||||
// Example code below shows creating a new DynamicRegisterInfo()
|
||||
if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp)
|
||||
{
|
||||
// static ConstString g_gpr_member_name("gpr");
|
||||
// m_register_info_ap.reset (new DynamicRegisterInfo());
|
||||
// ConstString empty_name;
|
||||
// const bool can_create = true;
|
||||
// AddressType addr_type;
|
||||
// addr_t base_addr = LLDB_INVALID_ADDRESS;
|
||||
// ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
|
||||
//
|
||||
// if (gpr_valobj_sp->IsPointerType ())
|
||||
// base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
|
||||
// else
|
||||
// base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
|
||||
//
|
||||
// ValueObjectSP child_valobj_sp;
|
||||
// if (gpr_valobj_sp)
|
||||
// {
|
||||
// ABI *abi = m_process->GetABI().get();
|
||||
// assert (abi);
|
||||
// uint32_t num_children = gpr_valobj_sp->GetNumChildren();
|
||||
//
|
||||
// ConstString gpr_name (gpr_valobj_sp->GetName());
|
||||
// uint32_t reg_num = 0;
|
||||
// for (uint32_t i=0; i<num_children; ++i)
|
||||
// {
|
||||
// child_valobj_sp = gpr_valobj_sp->GetChildAtIndex(i, can_create);
|
||||
//
|
||||
// ConstString reg_name(child_valobj_sp->GetName());
|
||||
// if (reg_name)
|
||||
// {
|
||||
// const char *reg_name_cstr = reg_name.GetCString();
|
||||
// while (reg_name_cstr[0] == '_')
|
||||
// ++reg_name_cstr;
|
||||
// if (reg_name_cstr != reg_name.GetCString())
|
||||
// reg_name.SetCString (reg_name_cstr);
|
||||
// }
|
||||
//
|
||||
// RegisterInfo reg_info;
|
||||
// if (abi->GetRegisterInfoByName(reg_name, reg_info))
|
||||
// {
|
||||
// // Adjust the byte size and the offset to match the layout of registers in our struct
|
||||
// reg_info.byte_size = child_valobj_sp->GetByteSize();
|
||||
// reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
|
||||
// reg_info.kinds[eRegisterKindLLDB] = reg_num++;
|
||||
// m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// m_register_info_ap->Finalize();
|
||||
// }
|
||||
}
|
||||
assert (m_register_info_ap.get());
|
||||
return m_register_info_ap.get();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
//------------------------------------------------------------------
|
||||
const char *
|
||||
OperatingSystemPython::GetPluginName()
|
||||
{
|
||||
return "OperatingSystemPython";
|
||||
}
|
||||
|
||||
const char *
|
||||
OperatingSystemPython::GetShortPluginName()
|
||||
{
|
||||
return GetPluginNameStatic();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OperatingSystemPython::GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool
|
||||
OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
|
||||
{
|
||||
// TODO: python: call "dict get_thread_info()" on the
|
||||
// python object that represents our instance of the OperatingSystem plug-in
|
||||
// and parse the returned dictionary. We need to pass in the a Dictionary
|
||||
// with the same kind of info we want back so we can reuse old threads, but
|
||||
// only create new ones.
|
||||
|
||||
// Make any constant strings once and cache the uniqued C string values
|
||||
// so we don't have to rehash them each time through this function call
|
||||
// dict thread_info_dict = python.get_thread_info()
|
||||
// for thread_info in thread_info_dict:
|
||||
// {
|
||||
// ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
// if (!thread_sp)
|
||||
// thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
|
||||
// new_thread_list.AddThread(thread_sp);
|
||||
// }
|
||||
new_thread_list = old_thread_list;
|
||||
return new_thread_list.GetSize(false) > 0;
|
||||
}
|
||||
|
||||
void
|
||||
OperatingSystemPython::ThreadWasSelected (Thread *thread)
|
||||
{
|
||||
}
|
||||
|
||||
RegisterContextSP
|
||||
OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
|
||||
{
|
||||
// TODO: python: call "bytes get_register_context_data(SBThread thread)"
|
||||
// and populate resulting data into thread
|
||||
RegisterContextSP reg_ctx_sp;
|
||||
// bytes b = get_register_context_data(thread)
|
||||
// if (b)
|
||||
// {
|
||||
// reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
|
||||
// // set bytes
|
||||
// }
|
||||
return reg_ctx_sp;
|
||||
}
|
||||
|
||||
StopInfoSP
|
||||
OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
|
||||
{
|
||||
// We should have gotten the thread stop info from the dictionary of data for
|
||||
// the thread in the initial call to get_thread_info(), this should have been
|
||||
// cached so we can return it here
|
||||
StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
|
||||
return stop_info_sp;
|
||||
}
|
||||
|
||||
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
Reference in New Issue
Block a user