<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="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">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>