1262182Semaste//===-- SectionLoadHistory.cpp ----------------------------------*- C++ -*-===// 2262182Semaste// 3262182Semaste// The LLVM Compiler Infrastructure 4262182Semaste// 5262182Semaste// This file is distributed under the University of Illinois Open Source 6262182Semaste// License. See LICENSE.TXT for details. 7262182Semaste// 8262182Semaste//===----------------------------------------------------------------------===// 9262182Semaste 10262182Semaste#include "lldb/Target/SectionLoadHistory.h" 11262182Semaste 12262182Semaste// C Includes 13262182Semaste// C++ Includes 14262182Semaste// Other libraries and framework includes 15262182Semaste// Project includes 16262182Semaste#include "lldb/Core/Stream.h" 17262182Semaste#include "lldb/Target/SectionLoadList.h" 18262182Semaste 19262182Semasteusing namespace lldb; 20262182Semasteusing namespace lldb_private; 21262182Semaste 22262182Semaste 23262182Semastebool 24262182SemasteSectionLoadHistory::IsEmpty() const 25262182Semaste{ 26262182Semaste Mutex::Locker locker(m_mutex); 27262182Semaste return m_stop_id_to_section_load_list.empty(); 28262182Semaste} 29262182Semaste 30262182Semastevoid 31262182SemasteSectionLoadHistory::Clear () 32262182Semaste{ 33262182Semaste Mutex::Locker locker(m_mutex); 34262182Semaste m_stop_id_to_section_load_list.clear(); 35262182Semaste} 36262182Semaste 37262182Semasteuint32_t 38262182SemasteSectionLoadHistory::GetLastStopID() const 39262182Semaste{ 40262182Semaste Mutex::Locker locker(m_mutex); 41262182Semaste if (m_stop_id_to_section_load_list.empty()) 42262182Semaste return 0; 43262182Semaste else 44262182Semaste return m_stop_id_to_section_load_list.rbegin()->first; 45262182Semaste} 46262182Semaste 47262182SemasteSectionLoadList * 48262182SemasteSectionLoadHistory::GetSectionLoadListForStopID (uint32_t stop_id, bool read_only) 49262182Semaste{ 50262182Semaste if (m_stop_id_to_section_load_list.empty()) 51262182Semaste { 52262182Semaste SectionLoadListSP section_load_list_sp(new SectionLoadList()); 53262182Semaste if (stop_id == eStopIDNow) 54262182Semaste stop_id = 0; 55262182Semaste m_stop_id_to_section_load_list[stop_id] = section_load_list_sp; 56262182Semaste return section_load_list_sp.get(); 57262182Semaste } 58262182Semaste else 59262182Semaste { 60262182Semaste if (read_only) 61262182Semaste { 62262182Semaste // The section load list is for reading data only so we don't need to create 63262182Semaste // a new SectionLoadList for the current stop ID, just return the section 64262182Semaste // load list for the stop ID that is equal to or less than the current stop ID 65262182Semaste if (stop_id == eStopIDNow) 66262182Semaste { 67262182Semaste // If we are asking for the latest and greatest value, it is always 68262182Semaste // at the end of our list becuase that will be the highest stop ID. 69262182Semaste StopIDToSectionLoadList::reverse_iterator rpos = m_stop_id_to_section_load_list.rbegin(); 70262182Semaste return rpos->second.get(); 71262182Semaste } 72262182Semaste else 73262182Semaste { 74262182Semaste StopIDToSectionLoadList::iterator pos = m_stop_id_to_section_load_list.lower_bound(stop_id); 75262182Semaste if (pos != m_stop_id_to_section_load_list.end() && pos->first == stop_id) 76262182Semaste return pos->second.get(); 77262182Semaste else if (pos != m_stop_id_to_section_load_list.begin()) 78262182Semaste { 79262182Semaste --pos; 80262182Semaste return pos->second.get(); 81262182Semaste } 82262182Semaste } 83262182Semaste } 84262182Semaste else 85262182Semaste { 86262182Semaste // You can only use "eStopIDNow" when reading from the section load history 87262182Semaste assert(stop_id != eStopIDNow); 88262182Semaste 89262182Semaste // We are updating the section load list (not read only), so if the stop ID 90262182Semaste // passed in isn't the same as the last stop ID in our collection, then create 91262182Semaste // a new node using the current stop ID 92262182Semaste StopIDToSectionLoadList::iterator pos = m_stop_id_to_section_load_list.lower_bound(stop_id); 93262182Semaste if (pos != m_stop_id_to_section_load_list.end() && pos->first == stop_id) 94262182Semaste { 95262182Semaste // We already have an entry for this value 96262182Semaste return pos->second.get(); 97262182Semaste } 98262182Semaste 99262182Semaste // We must make a new section load list that is based on the last valid 100262182Semaste // section load list, so here we copy the last section load list and add 101262182Semaste // a new node for the current stop ID. 102262182Semaste StopIDToSectionLoadList::reverse_iterator rpos = m_stop_id_to_section_load_list.rbegin(); 103262182Semaste SectionLoadListSP section_load_list_sp(new SectionLoadList(*rpos->second.get())); 104262182Semaste m_stop_id_to_section_load_list[stop_id] = section_load_list_sp; 105262182Semaste return section_load_list_sp.get(); 106262182Semaste } 107262182Semaste } 108262182Semaste return NULL; 109262182Semaste} 110262182Semaste 111262182SemasteSectionLoadList & 112262182SemasteSectionLoadHistory::GetCurrentSectionLoadList () 113262182Semaste{ 114262182Semaste const bool read_only = true; 115262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (eStopIDNow, read_only); 116262182Semaste assert(section_load_list != NULL); 117262182Semaste return *section_load_list; 118262182Semaste} 119262182Semaste 120262182Semasteaddr_t 121262182SemasteSectionLoadHistory::GetSectionLoadAddress (uint32_t stop_id, const lldb::SectionSP §ion_sp) 122262182Semaste{ 123262182Semaste Mutex::Locker locker(m_mutex); 124262182Semaste const bool read_only = true; 125262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); 126262182Semaste return section_load_list->GetSectionLoadAddress(section_sp); 127262182Semaste} 128262182Semaste 129262182Semastebool 130262182SemasteSectionLoadHistory::ResolveLoadAddress (uint32_t stop_id, addr_t load_addr, Address &so_addr) 131262182Semaste{ 132262182Semaste // First find the top level section that this load address exists in 133262182Semaste Mutex::Locker locker(m_mutex); 134262182Semaste const bool read_only = true; 135262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); 136262182Semaste return section_load_list->ResolveLoadAddress (load_addr, so_addr); 137262182Semaste} 138262182Semaste 139262182Semastebool 140262182SemasteSectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id, 141262182Semaste const lldb::SectionSP §ion_sp, 142262182Semaste addr_t load_addr, 143262182Semaste bool warn_multiple) 144262182Semaste{ 145262182Semaste Mutex::Locker locker(m_mutex); 146262182Semaste const bool read_only = false; 147262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); 148262182Semaste return section_load_list->SetSectionLoadAddress(section_sp, load_addr, warn_multiple); 149262182Semaste} 150262182Semaste 151262182Semastesize_t 152262182SemasteSectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp) 153262182Semaste{ 154262182Semaste Mutex::Locker locker(m_mutex); 155262182Semaste const bool read_only = false; 156262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); 157262182Semaste return section_load_list->SetSectionUnloaded (section_sp); 158262182Semaste} 159262182Semaste 160262182Semastebool 161262182SemasteSectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr) 162262182Semaste{ 163262182Semaste Mutex::Locker locker(m_mutex); 164262182Semaste const bool read_only = false; 165262182Semaste SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); 166262182Semaste return section_load_list->SetSectionUnloaded (section_sp, load_addr); 167262182Semaste} 168262182Semaste 169262182Semastevoid 170262182SemasteSectionLoadHistory::Dump (Stream &s, Target *target) 171262182Semaste{ 172262182Semaste Mutex::Locker locker(m_mutex); 173262182Semaste StopIDToSectionLoadList::iterator pos, end = m_stop_id_to_section_load_list.end(); 174262182Semaste for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) 175262182Semaste { 176262182Semaste s.Printf("StopID = %u:\n", pos->first); 177262182Semaste pos->second->Dump(s, target); 178262182Semaste s.EOL(); 179262182Semaste } 180262182Semaste} 181262182Semaste 182262182Semaste 183