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 24 using namespace lldb; 25 using namespace lldb_private; 26 27 28 bool 29 SectionLoadList::IsEmpty() const 30 { 31 return m_section_load_info.IsEmpty(); 32 } 33 34 void 35 SectionLoadList::Clear () 36 { 37 m_section_load_info.Clear(); 38 } 39 40 addr_t 41 SectionLoadList::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 50 bool 51 SectionLoadList::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 76 size_t 77 SectionLoadList::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 99 bool 100 SectionLoadList::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 116 bool 117 SectionLoadList::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