From 1e8ac36b605e90c46b8d445dc300456978f75e4d Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 16 Apr 2012 21:01:30 +0000 Subject: [PATCH] Fixed the ability to load multiple __LINKEDIT segments at the same address for darwin shared cache entries. Now when registering the load address of a section, the DynamicLoader objects can specify if they should warn or not. This will fix the ability to load the nlist entries for shared libraries in the darwin shared caches when no on disk representation is available for a shared library. llvm-svn: 154860 --- lldb/include/lldb/Target/SectionLoadList.h | 2 +- .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 22 +++++++++---------- lldb/source/Target/SectionLoadList.cpp | 16 ++++++++++++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lldb/include/lldb/Target/SectionLoadList.h b/lldb/include/lldb/Target/SectionLoadList.h index 31970272f0e6..641b19e0f441 100644 --- a/lldb/include/lldb/Target/SectionLoadList.h +++ b/lldb/include/lldb/Target/SectionLoadList.h @@ -53,7 +53,7 @@ public: ResolveLoadAddress (lldb::addr_t load_addr, Address &so_addr) const; bool - SetSectionLoadAddress (const Section *section, lldb::addr_t load_addr); + SetSectionLoadAddress (const Section *section, lldb::addr_t load_addr, bool warn_multiple = false); // The old load address should be specified when unloading to ensure we get // the correct instance of the section as a shared library could be loaded diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index dd7a101fc9f2..2ea134c42d74 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -440,18 +440,18 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& if (section_sp) { - // Don't ever load any __LINKEDIT sections since the ones in the shared - // cached will be coalesced into a single section and we will get warnings - // about multiple sections mapping to the same address. - if (section_sp->GetName() != g_section_name_LINKEDIT) + // __LINKEDIT sections from files in the shared cache + // can overlap so check to see what the segment name is + // and pass "false" so we don't warn of overlapping + // "Section" objects, and "true" for all other sections. + const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT; + + const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); + if (old_section_load_addr == LLDB_INVALID_ADDRESS || + old_section_load_addr != new_section_load_addr) { - const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); - if (old_section_load_addr == LLDB_INVALID_ADDRESS || - old_section_load_addr != new_section_load_addr) - { - if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr)) - changed = true; - } + if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr, warn_multiple)) + changed = true; } } else diff --git a/lldb/source/Target/SectionLoadList.cpp b/lldb/source/Target/SectionLoadList.cpp index 05a97a297e96..6add3ec6a2b8 100644 --- a/lldb/source/Target/SectionLoadList.cpp +++ b/lldb/source/Target/SectionLoadList.cpp @@ -57,7 +57,7 @@ SectionLoadList::GetSectionLoadAddress (const Section *section) const } bool -SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr) +SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr, bool warn_multiple) { LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); @@ -77,6 +77,7 @@ SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr if (section->GetByteSize() == 0) return false; // No change + // Fill in the section -> load_addr map Mutex::Locker locker(m_mutex); sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section); if (sta_pos != m_sect_to_addr.end()) @@ -89,10 +90,21 @@ SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr else m_sect_to_addr[section] = load_addr; + // Fill in the load_addr -> section map addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr); if (ats_pos != m_addr_to_sect.end()) { - if (section != ats_pos->second) + // Some sections are ok to overlap, and for others we should warn. When + // we have multiple load addresses that correspond to a section, we will + // allways attribute the section to the be last section that claims it + // exists at that address. Sometimes it is ok for more that one section + // to be loaded at a specific load address, and other times it isn't. + // The "warn_multiple" parameter tells us if we should warn in this case + // or not. The DynamicLoader plug-in subclasses should know which + // sections should warn and which shouldn't (darwin shared cache modules + // all shared the same "__LINKEDIT" sections, so the dynamic loader can + // pass false for "warn_multiple"). + if (warn_multiple && section != ats_pos->second) { ModuleSP module_sp (section->GetModule()); if (module_sp) -- GitLab