SectionLoadList.cpp revision 49480b158ee907f30afea651d2c81a67b5dbc971
1//===-- SectionLoadList.cpp -------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/Target/SectionLoadList.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Core/Log.h" 17#include "lldb/Core/Module.h" 18#include "lldb/Core/Section.h" 19#include "lldb/Core/Stream.h" 20#include "lldb/Symbol/Block.h" 21#include "lldb/Symbol/Symbol.h" 22#include "lldb/Symbol/SymbolContext.h" 23 24using namespace lldb; 25using namespace lldb_private; 26 27 28bool 29SectionLoadList::IsEmpty() const 30{ 31 return m_section_load_info.IsEmpty(); 32} 33 34void 35SectionLoadList::Clear () 36{ 37 m_section_load_info.Clear(); 38} 39 40addr_t 41SectionLoadList::GetSectionLoadAddress (const Section *section) const 42{ 43 // TODO: add support for the same section having multiple load addresses 44 addr_t section_load_addr = LLDB_INVALID_ADDRESS; 45 if (m_section_load_info.GetFirstKeyForValue (section, section_load_addr)) 46 return section_load_addr; 47 return LLDB_INVALID_ADDRESS; 48} 49 50bool 51SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr) 52{ 53 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE); 54 55 if (log) 56 log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", 57 __FUNCTION__, 58 section, 59 section->GetModule()->GetFileSpec().GetFilename().AsCString(), 60 section->GetName().AsCString(), 61 load_addr); 62 63 64 const Section *existing_section = NULL; 65 Mutex::Locker locker(m_section_load_info.GetMutex()); 66 67 if (m_section_load_info.GetValueForKeyNoLock (load_addr, existing_section)) 68 { 69 if (existing_section == section) 70 return false; // No change 71 } 72 m_section_load_info.SetValueForKeyNoLock (load_addr, section); 73 return true; // Changed 74} 75 76size_t 77SectionLoadList::SetSectionUnloaded (const Section *section) 78{ 79 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE); 80 81 if (log) 82 log->Printf ("SectionLoadList::%s (section = %p (%s.%s))", 83 __FUNCTION__, 84 section, 85 section->GetModule()->GetFileSpec().GetFilename().AsCString(), 86 section->GetName().AsCString()); 87 88 Mutex::Locker locker(m_section_load_info.GetMutex()); 89 90 size_t unload_count = 0; 91 addr_t section_load_addr; 92 while (m_section_load_info.GetFirstKeyForValueNoLock (section, section_load_addr)) 93 { 94 unload_count += m_section_load_info.EraseNoLock (section_load_addr); 95 } 96 return unload_count; 97} 98 99bool 100SectionLoadList::SetSectionUnloaded (const Section *section, addr_t load_addr) 101{ 102 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE); 103 104 if (log) 105 log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", 106 __FUNCTION__, 107 section, 108 section->GetModule()->GetFileSpec().GetFilename().AsCString(), 109 section->GetName().AsCString(), 110 load_addr); 111 112 return m_section_load_info.Erase (load_addr) == 1; 113} 114 115 116bool 117SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const 118{ 119 addr_t section_load_addr = LLDB_INVALID_ADDRESS; 120 const Section *section = NULL; 121 122 // First find the top level section that this load address exists in 123 if (m_section_load_info.LowerBound (load_addr, section_load_addr, section, true)) 124 { 125 addr_t offset = load_addr - section_load_addr; 126 if (offset < section->GetByteSize()) 127 { 128 // We have found the top level section, now we need to find the 129 // deepest child section. 130 return section->ResolveContainedAddress (offset, so_addr); 131 } 132 } 133 so_addr.Clear(); 134 return false; 135} 136