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