1 //===-- SectionLoadHistory.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Target/SectionLoadHistory.h"
14 // Other libraries and framework includes
16 #include "lldb/Target/SectionLoadList.h"
17 #include "lldb/Utility/Stream.h"
20 using namespace lldb_private;
22 bool SectionLoadHistory::IsEmpty() const {
23 std::lock_guard<std::recursive_mutex> guard(m_mutex);
24 return m_stop_id_to_section_load_list.empty();
27 void SectionLoadHistory::Clear() {
28 std::lock_guard<std::recursive_mutex> guard(m_mutex);
29 m_stop_id_to_section_load_list.clear();
32 uint32_t SectionLoadHistory::GetLastStopID() const {
33 std::lock_guard<std::recursive_mutex> guard(m_mutex);
34 if (m_stop_id_to_section_load_list.empty())
37 return m_stop_id_to_section_load_list.rbegin()->first;
41 SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
43 if (!m_stop_id_to_section_load_list.empty()) {
45 // The section load list is for reading data only so we don't need to
46 // create a new SectionLoadList for the current stop ID, just return the
47 // section load list for the stop ID that is equal to or less than the
49 if (stop_id == eStopIDNow) {
50 // If we are asking for the latest and greatest value, it is always at
51 // the end of our list because that will be the highest stop ID.
52 StopIDToSectionLoadList::reverse_iterator rpos =
53 m_stop_id_to_section_load_list.rbegin();
54 return rpos->second.get();
56 StopIDToSectionLoadList::iterator pos =
57 m_stop_id_to_section_load_list.lower_bound(stop_id);
58 if (pos != m_stop_id_to_section_load_list.end() &&
59 pos->first == stop_id)
60 return pos->second.get();
61 else if (pos != m_stop_id_to_section_load_list.begin()) {
63 return pos->second.get();
67 // You can only use "eStopIDNow" when reading from the section load
69 assert(stop_id != eStopIDNow);
71 // We are updating the section load list (not read only), so if the stop
72 // ID passed in isn't the same as the last stop ID in our collection,
73 // then create a new node using the current stop ID
74 StopIDToSectionLoadList::iterator pos =
75 m_stop_id_to_section_load_list.lower_bound(stop_id);
76 if (pos != m_stop_id_to_section_load_list.end() &&
77 pos->first == stop_id) {
78 // We already have an entry for this value
79 return pos->second.get();
82 // We must make a new section load list that is based on the last valid
83 // section load list, so here we copy the last section load list and add
84 // a new node for the current stop ID.
85 StopIDToSectionLoadList::reverse_iterator rpos =
86 m_stop_id_to_section_load_list.rbegin();
87 SectionLoadListSP section_load_list_sp(
88 new SectionLoadList(*rpos->second.get()));
89 m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
90 return section_load_list_sp.get();
93 SectionLoadListSP section_load_list_sp(new SectionLoadList());
94 if (stop_id == eStopIDNow)
96 m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
97 return section_load_list_sp.get();
100 SectionLoadList &SectionLoadHistory::GetCurrentSectionLoadList() {
101 const bool read_only = true;
102 std::lock_guard<std::recursive_mutex> guard(m_mutex);
103 SectionLoadList *section_load_list =
104 GetSectionLoadListForStopID(eStopIDNow, read_only);
105 assert(section_load_list != NULL);
106 return *section_load_list;
110 SectionLoadHistory::GetSectionLoadAddress(uint32_t stop_id,
111 const lldb::SectionSP §ion_sp) {
112 std::lock_guard<std::recursive_mutex> guard(m_mutex);
113 const bool read_only = true;
114 SectionLoadList *section_load_list =
115 GetSectionLoadListForStopID(stop_id, read_only);
116 return section_load_list->GetSectionLoadAddress(section_sp);
119 bool SectionLoadHistory::ResolveLoadAddress(uint32_t stop_id, addr_t load_addr,
121 // First find the top level section that this load address exists in
122 std::lock_guard<std::recursive_mutex> guard(m_mutex);
123 const bool read_only = true;
124 SectionLoadList *section_load_list =
125 GetSectionLoadListForStopID(stop_id, read_only);
126 return section_load_list->ResolveLoadAddress(load_addr, so_addr);
129 bool SectionLoadHistory::SetSectionLoadAddress(
130 uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr,
131 bool warn_multiple) {
132 std::lock_guard<std::recursive_mutex> guard(m_mutex);
133 const bool read_only = false;
134 SectionLoadList *section_load_list =
135 GetSectionLoadListForStopID(stop_id, read_only);
136 return section_load_list->SetSectionLoadAddress(section_sp, load_addr,
141 SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
142 const lldb::SectionSP §ion_sp) {
143 std::lock_guard<std::recursive_mutex> guard(m_mutex);
144 const bool read_only = false;
145 SectionLoadList *section_load_list =
146 GetSectionLoadListForStopID(stop_id, read_only);
147 return section_load_list->SetSectionUnloaded(section_sp);
150 bool SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
151 const lldb::SectionSP §ion_sp,
153 std::lock_guard<std::recursive_mutex> guard(m_mutex);
154 const bool read_only = false;
155 SectionLoadList *section_load_list =
156 GetSectionLoadListForStopID(stop_id, read_only);
157 return section_load_list->SetSectionUnloaded(section_sp, load_addr);
160 void SectionLoadHistory::Dump(Stream &s, Target *target) {
161 std::lock_guard<std::recursive_mutex> guard(m_mutex);
162 StopIDToSectionLoadList::iterator pos,
163 end = m_stop_id_to_section_load_list.end();
164 for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {
165 s.Printf("StopID = %u:\n", pos->first);
166 pos->second->Dump(s, target);