<div dir="ltr">I committed in a fix for the issue as <a href="http://reviews.llvm.org/rL236826">http://reviews.llvm.org/rL236826</a>. Please take a look and let me know if it causing some issue for you.<div><br></div><div>Tamas</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 8, 2015 at 11:42 AM, Tamas Berghammer <span dir="ltr"><<a href="mailto:tberghammer@google.com" target="_blank">tberghammer@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Aidan,<div><br></div><div>This patch caused a regression on android-arm (remote debugging) with breaking the code for setting a breakpoint. I haven't found out the exact reason for the problem but it looks like as the location of the breakpoints isn't deduced correctly because of a wrong load address for the executable (android use position independent code what might effect this issue). Please take a look into it.</div><div><br></div><div>Thanks,</div><div>Tamas</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 8, 2015 at 10:36 AM, Aidan Dodds <span dir="ltr"><<a href="mailto:aidan@codeplay.com" target="_blank">aidan@codeplay.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: aidandodds<br>
Date: Fri May 8 04:36:31 2015<br>
New Revision: 236817<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=236817&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=236817&view=rev</a><br>
Log:<br>
This patch allows LLDB to use the $qXfer:Libraries: packet.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D9471" target="_blank">http://reviews.llvm.org/D9471</a><br>
<br>
Modified:<br>
lldb/trunk/include/lldb/Target/Process.h<br>
lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp<br>
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp<br>
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h<br>
lldb/trunk/source/Target/Target.cpp<br>
<br>
Modified: lldb/trunk/include/lldb/Target/Process.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=236817&r1=236816&r2=236817&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=236817&r1=236816&r2=236817&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/Target/Process.h (original)<br>
+++ lldb/trunk/include/lldb/Target/Process.h Fri May 8 04:36:31 2015<br>
@@ -1121,6 +1121,22 @@ public:<br>
virtual const lldb::DataBufferSP<br>
GetAuxvData();<br>
<br>
+ //------------------------------------------------------------------<br>
+ /// Sometimes processes know how to retrieve and load shared libraries.<br>
+ /// This is normally done by DynamicLoader plug-ins, but sometimes the<br>
+ /// connection to the process allows retrieving this information. The<br>
+ /// dynamic loader plug-ins can use this function if they can't<br>
+ /// determine the current shared library load state.<br>
+ ///<br>
+ /// @return<br>
+ /// The number of shared libraries that were loaded<br>
+ //------------------------------------------------------------------<br>
+ virtual size_t<br>
+ LoadModules ()<br>
+ {<br>
+ return 0;<br>
+ }<br>
+<br>
protected:<br>
virtual JITLoaderList &<br>
GetJITLoaders ();<br>
<br>
Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=236817&r1=236816&r2=236817&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=236817&r1=236816&r2=236817&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)<br>
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Fri May 8 04:36:31 2015<br>
@@ -120,15 +120,45 @@ DynamicLoaderPOSIXDYLD::DidAttach()<br>
if (log)<br>
log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);<br>
<br>
- ModuleSP executable_sp = GetTargetExecutable();<br>
- ResolveExecutableModule(executable_sp);<br>
+ // ask the process if it can load any of its own modules<br>
+ m_process->LoadModules ();<br>
<br>
- addr_t load_offset = ComputeLoadOffset();<br>
+ ModuleSP executable_sp = GetTargetExecutable ();<br>
+ ResolveExecutableModule (executable_sp);<br>
+<br>
+ // find the main process load offset<br>
+ addr_t load_offset = ComputeLoadOffset ();<br>
if (log)<br>
log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " executable '%s', load_offset 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp ? executable_sp->GetFileSpec().GetPath().c_str () : "<null executable>", load_offset);<br>
<br>
+ // if we dont have a load address we cant re-base<br>
+ bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;<br>
<br>
- if (executable_sp && load_offset != LLDB_INVALID_ADDRESS)<br>
+ // if we have a valid executable<br>
+ if (executable_sp.get())<br>
+ {<br>
+ lldb_private::ObjectFile * obj = executable_sp->GetObjectFile();<br>
+ if (obj)<br>
+ {<br>
+ // don't rebase if the module is not an executable<br>
+ if (obj->GetType() != ObjectFile::Type::eTypeExecutable)<br>
+ rebase_exec = false;<br>
+<br>
+ // don't rebase if the module already has a load address<br>
+ Target & target = m_process->GetTarget ();<br>
+ Address addr = obj->GetImageInfoAddress (&target);<br>
+ if (addr.GetLoadAddress (&target) != LLDB_INVALID_ADDRESS)<br>
+ rebase_exec = false;<br>
+ }<br>
+ }<br>
+ else<br>
+ {<br>
+ // no executable, nothing to re-base<br>
+ rebase_exec = false;<br>
+ }<br>
+<br>
+ // if the target executable should be re-based<br>
+ if (rebase_exec)<br>
{<br>
ModuleList module_list;<br>
<br>
@@ -537,6 +567,9 @@ DynamicLoaderPOSIXDYLD::ComputeLoadOffse<br>
if (!exe)<br>
return LLDB_INVALID_ADDRESS;<br>
<br>
+ if (exe->GetType() != ObjectFile::Type::eTypeExecutable)<br>
+ return LLDB_INVALID_ADDRESS;<br>
+<br>
Address file_entry = exe->GetEntryPointAddress();<br>
<br>
if (!file_entry.IsValid())<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=236817&r1=236816&r2=236817&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=236817&r1=236816&r2=236817&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)<br>
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri May 8 04:36:31 2015<br>
@@ -174,6 +174,107 @@ namespace {<br>
<br>
} // anonymous namespace end<br>
<br>
+class ProcessGDBRemote::GDBLoadedModuleInfoList<br>
+{<br>
+public:<br>
+<br>
+ class LoadedModuleInfo<br>
+ {<br>
+ public:<br>
+<br>
+ enum e_data_point<br>
+ {<br>
+ e_has_name = 0,<br>
+ e_has_base ,<br>
+ e_has_dynamic ,<br>
+ e_has_link_map ,<br>
+ e_num<br>
+ };<br>
+<br>
+ LoadedModuleInfo ()<br>
+ {<br>
+ for (uint32_t i = 0; i < e_num; ++i)<br>
+ m_has[i] = false;<br>
+ };<br>
+<br>
+ void set_name (const std::string & name)<br>
+ {<br>
+ m_name = name;<br>
+ m_has[e_has_name] = true;<br>
+ }<br>
+ bool get_name (std::string & out) const<br>
+ {<br>
+ out = m_name;<br>
+ return m_has[e_has_name];<br>
+ }<br>
+<br>
+ void set_base (const lldb::addr_t base)<br>
+ {<br>
+ m_base = base;<br>
+ m_has[e_has_base] = true;<br>
+ }<br>
+ bool get_base (lldb::addr_t & out) const<br>
+ {<br>
+ out = m_base;<br>
+ return m_has[e_has_base];<br>
+ }<br>
+<br>
+ void set_link_map (const lldb::addr_t addr)<br>
+ {<br>
+ m_link_map = addr;<br>
+ m_has[e_has_link_map] = true;<br>
+ }<br>
+ bool get_link_map (lldb::addr_t & out) const<br>
+ {<br>
+ out = m_link_map;<br>
+ return m_has[e_has_link_map];<br>
+ }<br>
+<br>
+ void set_dynamic (const lldb::addr_t addr)<br>
+ {<br>
+ m_dynamic = addr;<br>
+ m_has[e_has_dynamic] = true;<br>
+ }<br>
+ bool get_dynamic (lldb::addr_t & out) const<br>
+ {<br>
+ out = m_dynamic;<br>
+ return m_has[e_has_dynamic];<br>
+ }<br>
+<br>
+ bool has_info (e_data_point datum)<br>
+ {<br>
+ assert (datum < e_num);<br>
+ return m_has[datum];<br>
+ }<br>
+<br>
+ protected:<br>
+<br>
+ bool m_has[e_num];<br>
+ std::string m_name;<br>
+ lldb::addr_t m_link_map;<br>
+ lldb::addr_t m_base;<br>
+ lldb::addr_t m_dynamic;<br>
+ };<br>
+<br>
+ GDBLoadedModuleInfoList ()<br>
+ : m_list ()<br>
+ , m_link_map (LLDB_INVALID_ADDRESS)<br>
+ {}<br>
+<br>
+ void add (const LoadedModuleInfo & mod)<br>
+ {<br>
+ m_list.push_back (mod);<br>
+ }<br>
+<br>
+ void clear ()<br>
+ {<br>
+ m_list.clear ();<br>
+ }<br>
+<br>
+ std::vector<LoadedModuleInfo> m_list;<br>
+ lldb::addr_t m_link_map;<br>
+};<br>
+<br>
// TODO Randomly assigning a port is unsafe. We should get an unused<br>
// ephemeral port from the kernel and make sure we reserve it before passing<br>
// it to debugserver.<br>
@@ -575,7 +676,7 @@ ProcessGDBRemote::BuildDynamicRegisterIn<br>
if (reg_num == 0)<br>
{<br>
// try to extract information from servers target.xml<br>
- if ( GetGDBServerInfo( ) )<br>
+ if (GetGDBServerRegisterInfo ())<br>
return;<br>
<br>
FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();<br>
@@ -2281,7 +2382,18 @@ ProcessGDBRemote::IsAlive ()<br>
addr_t<br>
ProcessGDBRemote::GetImageInfoAddress()<br>
{<br>
- return m_gdb_comm.GetShlibInfoAddr();<br>
+ // request the link map address via the $qShlibInfoAddr packet<br>
+ lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();<br>
+<br>
+ // the loaded module list can also provides a link map address<br>
+ if (addr == LLDB_INVALID_ADDRESS)<br>
+ {<br>
+ GDBLoadedModuleInfoList list;<br>
+ if (GetLoadedModuleList (list).Success())<br>
+ addr = list.m_link_map;<br>
+ }<br>
+<br>
+ return addr;<br>
}<br>
<br>
//------------------------------------------------------------------<br>
@@ -3855,7 +3967,7 @@ libxml2NullErrorFunc (void *ctx, const c<br>
// return: 'true' on success<br>
// 'false' on failure<br>
bool<br>
-ProcessGDBRemote::GetGDBServerInfo ()<br>
+ProcessGDBRemote::GetGDBServerRegisterInfo ()<br>
{<br>
<br>
// redirect libxml2's error handler since the default prints to stdout<br>
@@ -3928,12 +4040,140 @@ ProcessGDBRemote::GetGDBServerInfo ()<br>
return true;<br>
}<br>
<br>
+Error<br>
+ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)<br>
+{<br>
+ Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);<br>
+ if (log)<br>
+ log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);<br>
+<br>
+ // redirect libxml2's error handler since the default prints to stdout<br>
+ xmlGenericErrorFunc func = libxml2NullErrorFunc;<br>
+ initGenericErrorDefaultFunc (&func);<br>
+<br>
+ GDBRemoteCommunicationClient & comm = m_gdb_comm;<br>
+ GDBRemoteDynamicRegisterInfo & regInfo = m_register_info;<br>
+<br>
+ // check that we have extended feature read support<br>
+ if (!comm.GetQXferLibrariesSVR4ReadSupported ())<br>
+ return Error (0, ErrorType::eErrorTypeGeneric);<br>
+<br>
+ list.clear ();<br>
+<br>
+ // request the loaded library list<br>
+ std::string raw;<br>
+ lldb_private::Error lldberr;<br>
+ if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr))<br>
+ return Error (0, ErrorType::eErrorTypeGeneric);<br>
+<br>
+ // parse the xml file in memory<br>
+ if (log)<br>
+ log->Printf ("parsing: %s", raw.c_str());<br>
+ xmlDocPtr doc = xmlReadMemory (raw.c_str(), raw.size(), "noname.xml", nullptr, 0);<br>
+ if (doc == nullptr)<br>
+ return Error (0, ErrorType::eErrorTypeGeneric);<br>
+<br>
+ xmlNodePtr elm = xmlExFindElement (doc->children, {"library-list-svr4"});<br>
+ if (!elm)<br>
+ return Error();<br>
+<br>
+ // main link map structure<br>
+ xmlAttr * attr = xmlExFindAttribute (elm, "main-lm");<br>
+ if (attr)<br>
+ {<br>
+ std::string val = xmlExGetTextContent (attr);<br>
+ if (val.length() > 2)<br>
+ {<br>
+ uint32_t process_lm = std::stoul (val.c_str()+2, 0, 16);<br>
+ list.m_link_map = process_lm;<br>
+ }<br>
+ }<br>
+<br>
+ // parse individual library entries<br>
+ for (xmlNode * child = elm->children; child; child=child->next)<br>
+ {<br>
+ if (!child->name)<br>
+ continue;<br>
+<br>
+ if (strcmp ((char*)child->name, "library") != 0)<br>
+ continue;<br>
+<br>
+ GDBLoadedModuleInfoList::LoadedModuleInfo module;<br>
+<br>
+ for (xmlAttrPtr prop = child->properties; prop; prop=prop->next)<br>
+ {<br>
+ if (strcmp ((char*)prop->name, "name") == 0)<br>
+ module.set_name (xmlExGetTextContent (prop));<br>
+<br>
+ // the address of the link_map struct.<br>
+ if (strcmp ((char*)prop->name, "lm") == 0)<br>
+ {<br>
+ std::string val = xmlExGetTextContent (prop);<br>
+ if (val.length() > 2)<br>
+ {<br>
+ uint32_t module_lm = std::stoul (val.c_str()+2, 0, 16);<br>
+ module.set_link_map (module_lm);<br>
+ }<br>
+ }<br>
+<br>
+ // the displacement as read from the field 'l_addr' of the link_map struct.<br>
+ if (strcmp ((char*)prop->name, "l_addr") == 0)<br>
+ {<br>
+ std::string val = xmlExGetTextContent (prop);<br>
+ if (val.length() > 2)<br>
+ {<br>
+ uint32_t module_base = std::stoul (val.c_str()+2, 0, 16);<br>
+ module.set_base (module_base);<br>
+ }<br>
+ }<br>
+<br>
+ // the memory address of the libraries PT_DYAMIC section.<br>
+ if (strcmp ((char*)prop->name, "l_ld") == 0)<br>
+ {<br>
+ std::string val = xmlExGetTextContent (prop);<br>
+ if (val.length() > 2)<br>
+ {<br>
+ uint32_t module_dyn = std::stoul (val.c_str()+2, 0, 16);<br>
+ module.set_dynamic (module_dyn);<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ if (log)<br>
+ {<br>
+ std::string name ("");<br>
+ lldb::addr_t lm=0, base=0, ld=0;<br>
+<br>
+ module.get_name (name);<br>
+ module.get_link_map (lm);<br>
+ module.get_base (base);<br>
+ module.get_dynamic (ld);<br>
+<br>
+ log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str());<br>
+ }<br>
+<br>
+ list.add (module);<br>
+ }<br>
+<br>
+ if (log)<br>
+ log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());<br>
+<br>
+ return Error();<br>
+}<br>
+<br>
#else // if defined( LIBXML2_DEFINED )<br>
<br>
-using namespace lldb_private::process_gdb_remote;<br>
+Error<br>
+ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList &)<br>
+{<br>
+ // stub (libxml2 not present)<br>
+ Error err;<br>
+ err.SetError (0, ErrorType::eErrorTypeGeneric);<br>
+ return err;<br>
+}<br>
<br>
bool<br>
-ProcessGDBRemote::GetGDBServerInfo ()<br>
+ProcessGDBRemote::GetGDBServerRegisterInfo ()<br>
{<br>
// stub (libxml2 not present)<br>
return false;<br>
@@ -3941,6 +4181,91 @@ ProcessGDBRemote::GetGDBServerInfo ()<br>
<br>
#endif // if defined( LIBXML2_DEFINED )<br>
<br>
+lldb::ModuleSP<br>
+ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr)<br>
+{<br>
+ Target &target = m_process->GetTarget();<br>
+ ModuleList &modules = target.GetImages();<br>
+ ModuleSP module_sp;<br>
+<br>
+ bool changed = false;<br>
+<br>
+ ModuleSpec module_spec (file, target.GetArchitecture());<br>
+ if ((module_sp = modules.FindFirstModule (module_spec)))<br>
+ {<br>
+ module_sp->SetLoadAddress (target, base_addr, true, changed);<br>
+ }<br>
+ else if ((module_sp = target.GetSharedModule (module_spec)))<br>
+ {<br>
+ module_sp->SetLoadAddress (target, base_addr, true, changed);<br>
+ }<br>
+<br>
+ return module_sp;<br>
+}<br>
+<br>
+size_t<br>
+ProcessGDBRemote::LoadModules ()<br>
+{<br>
+ using lldb_private::process_gdb_remote::ProcessGDBRemote;<br>
+<br>
+ // request a list of loaded libraries from GDBServer<br>
+ GDBLoadedModuleInfoList module_list;<br>
+ if (GetLoadedModuleList (module_list).Fail())<br>
+ return 0;<br>
+<br>
+ // get a list of all the modules<br>
+ ModuleList new_modules;<br>
+<br>
+ for (GDBLoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)<br>
+ {<br>
+ std::string mod_name;<br>
+ lldb::addr_t mod_base;<br>
+<br>
+ bool valid = true;<br>
+ valid &= modInfo.get_name (mod_name);<br>
+ valid &= modInfo.get_base (mod_base);<br>
+ if (!valid)<br>
+ continue;<br>
+<br>
+ // hack (cleaner way to get file name only?) (win/unix compat?)<br>
+ int marker = mod_name.rfind ('/');<br>
+ if (marker == std::string::npos)<br>
+ marker = 0;<br>
+ else<br>
+ marker += 1;<br>
+<br>
+ FileSpec file (mod_name.c_str()+marker, true);<br>
+ lldb::ModuleSP module_sp = LoadModuleAtAddress (file, mod_base);<br>
+<br>
+ if (module_sp.get())<br>
+ new_modules.Append (module_sp);<br>
+ }<br>
+<br>
+ if (new_modules.GetSize() > 0)<br>
+ {<br>
+ Target & target = m_target;<br>
+<br>
+ new_modules.ForEach ([&target](const lldb::ModuleSP module_sp) -> bool<br>
+ {<br>
+ lldb_private::ObjectFile * obj = module_sp->GetObjectFile ();<br>
+ if (!obj)<br>
+ return true;<br>
+<br>
+ if (obj->GetType () != ObjectFile::Type::eTypeExecutable)<br>
+ return true;<br>
+<br>
+ lldb::ModuleSP module_copy_sp = module_sp;<br>
+ target.SetExecutableModule (module_copy_sp, false);<br>
+ return false;<br>
+ });<br>
+<br>
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();<br>
+ loaded_modules.AppendIfNeeded (new_modules);<br>
+ m_process->GetTarget().ModulesDidLoad (new_modules);<br>
+ }<br>
+<br>
+ return new_modules.GetSize();<br>
+}<br>
<br>
class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed<br>
{<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=236817&r1=236816&r2=236817&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=236817&r1=236816&r2=236817&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)<br>
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Fri May 8 04:36:31 2015<br>
@@ -241,15 +241,16 @@ public:<br>
const ArchSpec& arch,<br>
ModuleSpec &module_spec) override;<br>
<br>
- // query remote gdbserver for information<br>
- bool<br>
- GetGDBServerInfo ( );<br>
+ virtual size_t<br>
+ LoadModules () override;<br>
<br>
protected:<br>
friend class ThreadGDBRemote;<br>
friend class GDBRemoteCommunicationClient;<br>
friend class GDBRemoteRegisterContext;<br>
<br>
+ class GDBLoadedModuleInfoList;<br>
+<br>
//----------------------------------------------------------------------<br>
// Accessors<br>
//----------------------------------------------------------------------<br>
@@ -396,6 +397,17 @@ protected:<br>
DynamicLoader *<br>
GetDynamicLoader () override;<br>
<br>
+ // Query remote GDBServer for register information<br>
+ bool<br>
+ GetGDBServerRegisterInfo ();<br>
+<br>
+ // Query remote GDBServer for a detailed loaded library list<br>
+ Error<br>
+ GetLoadedModuleList (GDBLoadedModuleInfoList &);<br>
+<br>
+ lldb::ModuleSP<br>
+ LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr);<br>
+<br>
private:<br>
//------------------------------------------------------------------<br>
// For ProcessGDBRemote only<br>
<br>
Modified: lldb/trunk/source/Target/Target.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=236817&r1=236816&r2=236817&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=236817&r1=236816&r2=236817&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Target/Target.cpp (original)<br>
+++ lldb/trunk/source/Target/Target.cpp Fri May 8 04:36:31 2015<br>
@@ -1057,13 +1057,24 @@ Target::IgnoreWatchpointByID (lldb::watc<br>
ModuleSP<br>
Target::GetExecutableModule ()<br>
{<br>
- return m_images.GetModuleAtIndex(0);<br>
+ // search for the first executable in the module list<br>
+ for (size_t i = 0; i < m_images.GetSize(); ++i)<br>
+ {<br>
+ ModuleSP module_sp = m_images.GetModuleAtIndex (i);<br>
+ lldb_private::ObjectFile * obj = module_sp->GetObjectFile();<br>
+ if (obj == nullptr)<br>
+ continue;<br>
+ if (obj->GetType() == ObjectFile::Type::eTypeExecutable)<br>
+ return module_sp;<br>
+ }<br>
+ // as fall back return the first module loaded<br>
+ return m_images.GetModuleAtIndex (0);<br>
}<br>
<br>
Module*<br>
Target::GetExecutableModulePointer ()<br>
{<br>
- return m_images.GetModulePointerAtIndex(0);<br>
+ return GetExecutableModule().get();<br>
}<br>
<br>
static void<br>
<br>
<br>
_______________________________________________<br>
lldb-commits mailing list<br>
<a href="mailto:lldb-commits@cs.uiuc.edu" target="_blank">lldb-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>