117f69208SGreg Clayton //===-- SectionLoadList.cpp -------------------------------------*- C++ -*-===// 217f69208SGreg Clayton // 317f69208SGreg Clayton // The LLVM Compiler Infrastructure 417f69208SGreg Clayton // 517f69208SGreg Clayton // This file is distributed under the University of Illinois Open Source 617f69208SGreg Clayton // License. See LICENSE.TXT for details. 717f69208SGreg Clayton // 817f69208SGreg Clayton //===----------------------------------------------------------------------===// 917f69208SGreg Clayton 1017f69208SGreg Clayton #include "lldb/Target/SectionLoadList.h" 1117f69208SGreg Clayton 1217f69208SGreg Clayton // C Includes 1317f69208SGreg Clayton // C++ Includes 1417f69208SGreg Clayton // Other libraries and framework includes 1517f69208SGreg Clayton // Project includes 1617f69208SGreg Clayton #include "lldb/Core/Log.h" 1717f69208SGreg Clayton #include "lldb/Core/Module.h" 1817f69208SGreg Clayton #include "lldb/Core/Section.h" 1917f69208SGreg Clayton #include "lldb/Core/Stream.h" 2017f69208SGreg Clayton #include "lldb/Symbol/Block.h" 2117f69208SGreg Clayton #include "lldb/Symbol/Symbol.h" 2217f69208SGreg Clayton #include "lldb/Symbol/SymbolContext.h" 2317f69208SGreg Clayton 2417f69208SGreg Clayton using namespace lldb; 2517f69208SGreg Clayton using namespace lldb_private; 2617f69208SGreg Clayton 2717f69208SGreg Clayton 2817f69208SGreg Clayton bool 2917f69208SGreg Clayton SectionLoadList::IsEmpty() const 3017f69208SGreg Clayton { 3117f69208SGreg Clayton return m_section_load_info.IsEmpty(); 3217f69208SGreg Clayton } 3317f69208SGreg Clayton 3417f69208SGreg Clayton void 3517f69208SGreg Clayton SectionLoadList::Clear () 3617f69208SGreg Clayton { 3717f69208SGreg Clayton m_section_load_info.Clear(); 3817f69208SGreg Clayton } 3917f69208SGreg Clayton 4017f69208SGreg Clayton addr_t 4117f69208SGreg Clayton SectionLoadList::GetSectionLoadAddress (const Section *section) const 4217f69208SGreg Clayton { 4317f69208SGreg Clayton // TODO: add support for the same section having multiple load addresses 4417f69208SGreg Clayton addr_t section_load_addr = LLDB_INVALID_ADDRESS; 4517f69208SGreg Clayton if (m_section_load_info.GetFirstKeyForValue (section, section_load_addr)) 4617f69208SGreg Clayton return section_load_addr; 4717f69208SGreg Clayton return LLDB_INVALID_ADDRESS; 4817f69208SGreg Clayton } 4917f69208SGreg Clayton 5017f69208SGreg Clayton bool 5117f69208SGreg Clayton SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr) 5217f69208SGreg Clayton { 53*2d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); 5417f69208SGreg Clayton 5517f69208SGreg Clayton if (log) 5617f69208SGreg Clayton log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", 5717f69208SGreg Clayton __FUNCTION__, 5817f69208SGreg Clayton section, 5917f69208SGreg Clayton section->GetModule()->GetFileSpec().GetFilename().AsCString(), 6017f69208SGreg Clayton section->GetName().AsCString(), 6117f69208SGreg Clayton load_addr); 6217f69208SGreg Clayton 6317f69208SGreg Clayton 6417f69208SGreg Clayton const Section *existing_section = NULL; 6517f69208SGreg Clayton Mutex::Locker locker(m_section_load_info.GetMutex()); 6617f69208SGreg Clayton 6717f69208SGreg Clayton if (m_section_load_info.GetValueForKeyNoLock (load_addr, existing_section)) 6817f69208SGreg Clayton { 6917f69208SGreg Clayton if (existing_section == section) 7017f69208SGreg Clayton return false; // No change 7117f69208SGreg Clayton } 7217f69208SGreg Clayton m_section_load_info.SetValueForKeyNoLock (load_addr, section); 7317f69208SGreg Clayton return true; // Changed 7417f69208SGreg Clayton } 7517f69208SGreg Clayton 7617f69208SGreg Clayton size_t 7717f69208SGreg Clayton SectionLoadList::SetSectionUnloaded (const Section *section) 7817f69208SGreg Clayton { 79*2d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); 8017f69208SGreg Clayton 8117f69208SGreg Clayton if (log) 8217f69208SGreg Clayton log->Printf ("SectionLoadList::%s (section = %p (%s.%s))", 8317f69208SGreg Clayton __FUNCTION__, 8417f69208SGreg Clayton section, 8517f69208SGreg Clayton section->GetModule()->GetFileSpec().GetFilename().AsCString(), 8617f69208SGreg Clayton section->GetName().AsCString()); 8717f69208SGreg Clayton 8817f69208SGreg Clayton Mutex::Locker locker(m_section_load_info.GetMutex()); 8917f69208SGreg Clayton 9017f69208SGreg Clayton size_t unload_count = 0; 9117f69208SGreg Clayton addr_t section_load_addr; 9217f69208SGreg Clayton while (m_section_load_info.GetFirstKeyForValueNoLock (section, section_load_addr)) 9317f69208SGreg Clayton { 9417f69208SGreg Clayton unload_count += m_section_load_info.EraseNoLock (section_load_addr); 9517f69208SGreg Clayton } 9617f69208SGreg Clayton return unload_count; 9717f69208SGreg Clayton } 9817f69208SGreg Clayton 9917f69208SGreg Clayton bool 10017f69208SGreg Clayton SectionLoadList::SetSectionUnloaded (const Section *section, addr_t load_addr) 10117f69208SGreg Clayton { 102*2d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); 10317f69208SGreg Clayton 10417f69208SGreg Clayton if (log) 10517f69208SGreg Clayton log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", 10617f69208SGreg Clayton __FUNCTION__, 10717f69208SGreg Clayton section, 10817f69208SGreg Clayton section->GetModule()->GetFileSpec().GetFilename().AsCString(), 10917f69208SGreg Clayton section->GetName().AsCString(), 11017f69208SGreg Clayton load_addr); 11117f69208SGreg Clayton 11217f69208SGreg Clayton return m_section_load_info.Erase (load_addr) == 1; 11317f69208SGreg Clayton } 11417f69208SGreg Clayton 11517f69208SGreg Clayton 11617f69208SGreg Clayton bool 11717f69208SGreg Clayton SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const 11817f69208SGreg Clayton { 11917f69208SGreg Clayton addr_t section_load_addr = LLDB_INVALID_ADDRESS; 12017f69208SGreg Clayton const Section *section = NULL; 12117f69208SGreg Clayton 12217f69208SGreg Clayton // First find the top level section that this load address exists in 12317f69208SGreg Clayton if (m_section_load_info.LowerBound (load_addr, section_load_addr, section, true)) 12417f69208SGreg Clayton { 12517f69208SGreg Clayton addr_t offset = load_addr - section_load_addr; 12617f69208SGreg Clayton if (offset < section->GetByteSize()) 12717f69208SGreg Clayton { 12817f69208SGreg Clayton // We have found the top level section, now we need to find the 12917f69208SGreg Clayton // deepest child section. 13017f69208SGreg Clayton return section->ResolveContainedAddress (offset, so_addr); 13117f69208SGreg Clayton } 13217f69208SGreg Clayton } 13317f69208SGreg Clayton so_addr.Clear(); 13417f69208SGreg Clayton return false; 13517f69208SGreg Clayton } 136