forked from OSchip/llvm-project
Create a Process::ModulesDidLoad() method to handle process-related tasks, as suggested by Jim Ingham. Make JITLoader instances use this to probe only new modules for relevant JIT symbols. Also re-enable the JITLoader hooks in Process.
llvm-svn: 203774
This commit is contained in:
parent
32956d651a
commit
eb4d0607bf
|
@ -56,7 +56,7 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
/// Called after attaching a process.
|
||||
///
|
||||
/// Allow DynamicLoader plug-ins to execute some code after
|
||||
/// Allow JITLoader plug-ins to execute some code after
|
||||
/// attaching to a process.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
|
@ -65,12 +65,19 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
/// Called after launching a process.
|
||||
///
|
||||
/// Allow DynamicLoader plug-ins to execute some code after
|
||||
/// Allow JITLoader plug-ins to execute some code after
|
||||
/// the process has stopped for the first time on launch.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
DidLaunch () = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called after a new shared object has been loaded so that it can
|
||||
/// be probed for JIT entry point hooks.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
ModulesDidLoad (lldb_private::ModuleList &module_list) = 0;
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
void
|
||||
DidAttach();
|
||||
|
||||
void
|
||||
ModulesDidLoad (ModuleList &module_list);
|
||||
|
||||
private:
|
||||
std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
|
||||
lldb_private::Mutex m_jit_loaders_mutex;
|
||||
|
|
|
@ -2575,6 +2575,9 @@ public:
|
|||
void
|
||||
SendAsyncInterrupt ();
|
||||
|
||||
void
|
||||
ModulesDidLoad (ModuleList &module_list);
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
|
|
|
@ -55,37 +55,43 @@ struct jit_descriptor
|
|||
JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
|
||||
JITLoader(process),
|
||||
m_jit_objects(),
|
||||
m_jit_break_id(LLDB_INVALID_BREAK_ID)
|
||||
m_jit_break_id(LLDB_INVALID_BREAK_ID),
|
||||
m_jit_descriptor_addr(LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
m_notification_callbacks.baton = this;
|
||||
m_notification_callbacks.initialize = nullptr;
|
||||
m_notification_callbacks.process_state_changed =
|
||||
ProcessStateChangedCallback;
|
||||
m_process->RegisterNotificationCallbacks(m_notification_callbacks);
|
||||
}
|
||||
|
||||
JITLoaderGDB::~JITLoaderGDB ()
|
||||
{
|
||||
if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
|
||||
m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
|
||||
m_jit_break_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
|
||||
void JITLoaderGDB::DidAttach()
|
||||
{
|
||||
SetJITBreakpoint();
|
||||
Target &target = m_process->GetTarget();
|
||||
ModuleList &module_list = target.GetImages();
|
||||
SetJITBreakpoint(module_list);
|
||||
}
|
||||
|
||||
void JITLoaderGDB::DidLaunch()
|
||||
{
|
||||
SetJITBreakpoint();
|
||||
Target &target = m_process->GetTarget();
|
||||
ModuleList &module_list = target.GetImages();
|
||||
SetJITBreakpoint(module_list);
|
||||
}
|
||||
|
||||
void
|
||||
JITLoaderGDB::ModulesDidLoad(ModuleList &module_list)
|
||||
{
|
||||
if (!DidSetJITBreakpoint() && m_process->IsAlive())
|
||||
SetJITBreakpoint(module_list);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Setup the JIT Breakpoint
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
JITLoaderGDB::SetJITBreakpoint()
|
||||
JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
|
||||
{
|
||||
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
|
||||
|
||||
|
@ -96,11 +102,22 @@ JITLoaderGDB::SetJITBreakpoint()
|
|||
log->Printf("JITLoaderGDB::%s looking for JIT register hook",
|
||||
__FUNCTION__);
|
||||
|
||||
addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_register_code"),
|
||||
eSymbolTypeAny);
|
||||
addr_t jit_addr = GetSymbolAddress(
|
||||
module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
|
||||
if (jit_addr == LLDB_INVALID_ADDRESS)
|
||||
return;
|
||||
|
||||
m_jit_descriptor_addr = GetSymbolAddress(
|
||||
module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
|
||||
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
if (log)
|
||||
log->Printf(
|
||||
"JITLoaderGDB::%s failed to find JIT descriptor address",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
|
||||
__FUNCTION__);
|
||||
|
@ -130,26 +147,18 @@ JITLoaderGDB::JITDebugBreakpointHit(void *baton,
|
|||
bool
|
||||
JITLoaderGDB::ReadJITDescriptor(bool all_entries)
|
||||
{
|
||||
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
|
||||
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
|
||||
Target &target = m_process->GetTarget();
|
||||
ModuleList &images = target.GetImages();
|
||||
|
||||
addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_descriptor"),
|
||||
eSymbolTypeData);
|
||||
if (jit_addr == LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
if (log)
|
||||
log->Printf(
|
||||
"JITLoaderGDB::%s failed to find JIT descriptor address",
|
||||
__FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
ModuleList &module_list = target.GetImages();
|
||||
|
||||
jit_descriptor jit_desc;
|
||||
const size_t jit_desc_size = sizeof(jit_desc);
|
||||
Error error;
|
||||
size_t bytes_read =
|
||||
m_process->DoReadMemory(jit_addr, &jit_desc, jit_desc_size, error);
|
||||
size_t bytes_read = m_process->DoReadMemory(
|
||||
m_jit_descriptor_addr, &jit_desc, jit_desc_size, error);
|
||||
if (bytes_read != jit_desc_size || !error.Success())
|
||||
{
|
||||
if (log)
|
||||
|
@ -208,7 +217,7 @@ JITLoaderGDB::ReadJITDescriptor(bool all_entries)
|
|||
// load the symbol table right away
|
||||
module_sp->GetObjectFile()->GetSymtab();
|
||||
|
||||
images.AppendIfNeeded(module_sp);
|
||||
module_list.AppendIfNeeded(module_sp);
|
||||
|
||||
ModuleList module_list;
|
||||
module_list.Append(module_sp);
|
||||
|
@ -250,7 +259,7 @@ JITLoaderGDB::ReadJITDescriptor(bool all_entries)
|
|||
}
|
||||
}
|
||||
}
|
||||
images.Remove(module_sp);
|
||||
module_list.Remove(module_sp);
|
||||
m_jit_objects.erase(it);
|
||||
}
|
||||
}
|
||||
|
@ -327,48 +336,15 @@ JITLoaderGDB::DidSetJITBreakpoint() const
|
|||
return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
|
||||
}
|
||||
|
||||
void
|
||||
JITLoaderGDB::ProcessStateChangedCallback(void *baton,
|
||||
lldb_private::Process *process,
|
||||
lldb::StateType state)
|
||||
{
|
||||
JITLoaderGDB* instance = static_cast<JITLoaderGDB*>(baton);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case eStateConnected:
|
||||
case eStateAttaching:
|
||||
case eStateLaunching:
|
||||
case eStateInvalid:
|
||||
case eStateUnloaded:
|
||||
case eStateExited:
|
||||
case eStateDetached:
|
||||
// instance->Clear(false);
|
||||
break;
|
||||
|
||||
case eStateRunning:
|
||||
case eStateStopped:
|
||||
// Keep trying to set our JIT breakpoint each time we stop until we
|
||||
// succeed
|
||||
if (!instance->DidSetJITBreakpoint() && process->IsAlive())
|
||||
instance->SetJITBreakpoint();
|
||||
break;
|
||||
|
||||
case eStateStepping:
|
||||
case eStateCrashed:
|
||||
case eStateSuspended:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addr_t
|
||||
JITLoaderGDB::GetSymbolAddress(const ConstString &name, SymbolType symbol_type) const
|
||||
JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
|
||||
SymbolType symbol_type) const
|
||||
{
|
||||
SymbolContextList target_symbols;
|
||||
Target &target = m_process->GetTarget();
|
||||
ModuleList &images = target.GetImages();
|
||||
|
||||
if (!images.FindSymbolsWithNameAndType(name, symbol_type, target_symbols))
|
||||
if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
|
||||
target_symbols))
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
SymbolContext sym_ctx;
|
||||
|
|
|
@ -63,13 +63,17 @@ public:
|
|||
virtual void
|
||||
DidLaunch ();
|
||||
|
||||
virtual void
|
||||
ModulesDidLoad (lldb_private::ModuleList &module_list);
|
||||
|
||||
private:
|
||||
lldb::addr_t
|
||||
GetSymbolAddress(const lldb_private::ConstString &name,
|
||||
GetSymbolAddress(lldb_private::ModuleList &module_list,
|
||||
const lldb_private::ConstString &name,
|
||||
lldb::SymbolType symbol_type) const;
|
||||
|
||||
void
|
||||
SetJITBreakpoint();
|
||||
SetJITBreakpoint(lldb_private::ModuleList &module_list);
|
||||
|
||||
bool
|
||||
DidSetJITBreakpoint() const;
|
||||
|
@ -93,7 +97,7 @@ private:
|
|||
JITObjectMap m_jit_objects;
|
||||
|
||||
lldb::user_id_t m_jit_break_id;
|
||||
lldb_private::Process::Notifications m_notification_callbacks;
|
||||
lldb::addr_t m_jit_descriptor_addr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -67,3 +67,11 @@ JITLoaderList::DidAttach()
|
|||
for (auto const &jit_loader : m_jit_loaders_vec)
|
||||
jit_loader->DidAttach();
|
||||
}
|
||||
|
||||
void
|
||||
JITLoaderList::ModulesDidLoad(ModuleList &module_list)
|
||||
{
|
||||
Mutex::Locker locker(m_jit_loaders_mutex);
|
||||
for (auto const &jit_loader : m_jit_loaders_vec)
|
||||
jit_loader->ModulesDidLoad(module_list);
|
||||
}
|
||||
|
|
|
@ -3068,7 +3068,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
|
|||
if (dyld)
|
||||
dyld->DidLaunch();
|
||||
|
||||
// GetJITLoaders().DidLaunch();
|
||||
GetJITLoaders().DidLaunch();
|
||||
|
||||
SystemRuntime *system_runtime = GetSystemRuntime ();
|
||||
if (system_runtime)
|
||||
|
@ -3117,7 +3117,7 @@ Process::LoadCore ()
|
|||
if (dyld)
|
||||
dyld->DidAttach();
|
||||
|
||||
//GetJITLoaders().DidAttach();
|
||||
GetJITLoaders().DidAttach();
|
||||
|
||||
SystemRuntime *system_runtime = GetSystemRuntime ();
|
||||
if (system_runtime)
|
||||
|
@ -3396,7 +3396,7 @@ Process::CompleteAttach ()
|
|||
if (dyld)
|
||||
dyld->DidAttach();
|
||||
|
||||
// GetJITLoaders().DidAttach();
|
||||
GetJITLoaders().DidAttach();
|
||||
|
||||
SystemRuntime *system_runtime = GetSystemRuntime ();
|
||||
if (system_runtime)
|
||||
|
@ -6052,3 +6052,14 @@ Process::ResolveIndirectFunction(const Address *address, Error &error)
|
|||
return function_addr;
|
||||
}
|
||||
|
||||
void
|
||||
Process::ModulesDidLoad (ModuleList &module_list)
|
||||
{
|
||||
SystemRuntime *sys_runtime = GetSystemRuntime();
|
||||
if (sys_runtime)
|
||||
{
|
||||
sys_runtime->ModulesDidLoad (module_list);
|
||||
}
|
||||
|
||||
GetJITLoaders().ModulesDidLoad (module_list);
|
||||
}
|
||||
|
|
|
@ -1172,11 +1172,7 @@ Target::ModulesDidLoad (ModuleList &module_list)
|
|||
m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
|
||||
if (m_process_sp)
|
||||
{
|
||||
SystemRuntime *sys_runtime = m_process_sp->GetSystemRuntime();
|
||||
if (sys_runtime)
|
||||
{
|
||||
sys_runtime->ModulesDidLoad (module_list);
|
||||
}
|
||||
m_process_sp->ModulesDidLoad (module_list);
|
||||
}
|
||||
// TODO: make event data that packages up the module_list
|
||||
BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
|
||||
|
|
Loading…
Reference in New Issue