blob: 740f48bc829c1bbaf5ae532d85007ebd65ff048a [file] [log] [blame]
Greg Claytond5944cd2013-12-06 01:12:00 +00001//===-- SectionLoadHistory.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/SectionLoadHistory.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Greg Claytond5944cd2013-12-06 01:12:00 +000016#include "lldb/Target/SectionLoadList.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000017#include "lldb/Utility/Stream.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000018
19using namespace lldb;
20using namespace lldb_private;
21
Kate Stoneb9c1b512016-09-06 20:57:50 +000022bool SectionLoadHistory::IsEmpty() const {
23 std::lock_guard<std::recursive_mutex> guard(m_mutex);
24 return m_stop_id_to_section_load_list.empty();
Greg Claytond5944cd2013-12-06 01:12:00 +000025}
26
Kate Stoneb9c1b512016-09-06 20:57:50 +000027void SectionLoadHistory::Clear() {
28 std::lock_guard<std::recursive_mutex> guard(m_mutex);
29 m_stop_id_to_section_load_list.clear();
Greg Claytond5944cd2013-12-06 01:12:00 +000030}
31
Kate Stoneb9c1b512016-09-06 20:57:50 +000032uint32_t SectionLoadHistory::GetLastStopID() const {
33 std::lock_guard<std::recursive_mutex> guard(m_mutex);
34 if (m_stop_id_to_section_load_list.empty())
35 return 0;
36 else
37 return m_stop_id_to_section_load_list.rbegin()->first;
Greg Claytond5944cd2013-12-06 01:12:00 +000038}
39
40SectionLoadList *
Kate Stoneb9c1b512016-09-06 20:57:50 +000041SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
42 bool read_only) {
43 if (!m_stop_id_to_section_load_list.empty()) {
44 if (read_only) {
45 // The section load list is for reading data only so we don't need to
46 // create
47 // a new SectionLoadList for the current stop ID, just return the section
48 // load list for the stop ID that is equal to or less than the current
49 // stop ID
50 if (stop_id == eStopIDNow) {
51 // If we are asking for the latest and greatest value, it is always
52 // at the end of our list because that will be the highest stop ID.
53 StopIDToSectionLoadList::reverse_iterator rpos =
54 m_stop_id_to_section_load_list.rbegin();
55 return rpos->second.get();
56 } else {
57 StopIDToSectionLoadList::iterator pos =
58 m_stop_id_to_section_load_list.lower_bound(stop_id);
59 if (pos != m_stop_id_to_section_load_list.end() &&
60 pos->first == stop_id)
61 return pos->second.get();
62 else if (pos != m_stop_id_to_section_load_list.begin()) {
63 --pos;
64 return pos->second.get();
Greg Claytond5944cd2013-12-06 01:12:00 +000065 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 }
67 } else {
68 // You can only use "eStopIDNow" when reading from the section load
69 // history
70 assert(stop_id != eStopIDNow);
Greg Claytond5944cd2013-12-06 01:12:00 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 // We are updating the section load list (not read only), so if the stop
73 // ID
74 // passed in isn't the same as the last stop ID in our collection, then
75 // create
76 // a new node using the current stop ID
77 StopIDToSectionLoadList::iterator pos =
78 m_stop_id_to_section_load_list.lower_bound(stop_id);
79 if (pos != m_stop_id_to_section_load_list.end() &&
80 pos->first == stop_id) {
81 // We already have an entry for this value
82 return pos->second.get();
83 }
84
85 // We must make a new section load list that is based on the last valid
86 // section load list, so here we copy the last section load list and add
87 // a new node for the current stop ID.
88 StopIDToSectionLoadList::reverse_iterator rpos =
89 m_stop_id_to_section_load_list.rbegin();
90 SectionLoadListSP section_load_list_sp(
91 new SectionLoadList(*rpos->second.get()));
92 m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
93 return section_load_list_sp.get();
Greg Claytond5944cd2013-12-06 01:12:00 +000094 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 }
96 SectionLoadListSP section_load_list_sp(new SectionLoadList());
97 if (stop_id == eStopIDNow)
98 stop_id = 0;
99 m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
100 return section_load_list_sp.get();
Greg Claytond5944cd2013-12-06 01:12:00 +0000101}
102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103SectionLoadList &SectionLoadHistory::GetCurrentSectionLoadList() {
104 const bool read_only = true;
105 std::lock_guard<std::recursive_mutex> guard(m_mutex);
106 SectionLoadList *section_load_list =
107 GetSectionLoadListForStopID(eStopIDNow, read_only);
108 assert(section_load_list != NULL);
109 return *section_load_list;
Greg Claytond5944cd2013-12-06 01:12:00 +0000110}
111
112addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113SectionLoadHistory::GetSectionLoadAddress(uint32_t stop_id,
114 const lldb::SectionSP &section_sp) {
115 std::lock_guard<std::recursive_mutex> guard(m_mutex);
116 const bool read_only = true;
117 SectionLoadList *section_load_list =
118 GetSectionLoadListForStopID(stop_id, read_only);
119 return section_load_list->GetSectionLoadAddress(section_sp);
Greg Claytond5944cd2013-12-06 01:12:00 +0000120}
121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122bool SectionLoadHistory::ResolveLoadAddress(uint32_t stop_id, addr_t load_addr,
123 Address &so_addr) {
124 // First find the top level section that this load address exists in
125 std::lock_guard<std::recursive_mutex> guard(m_mutex);
126 const bool read_only = true;
127 SectionLoadList *section_load_list =
128 GetSectionLoadListForStopID(stop_id, read_only);
129 return section_load_list->ResolveLoadAddress(load_addr, so_addr);
Greg Claytond5944cd2013-12-06 01:12:00 +0000130}
131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132bool SectionLoadHistory::SetSectionLoadAddress(
133 uint32_t stop_id, const lldb::SectionSP &section_sp, addr_t load_addr,
134 bool warn_multiple) {
135 std::lock_guard<std::recursive_mutex> guard(m_mutex);
136 const bool read_only = false;
137 SectionLoadList *section_load_list =
138 GetSectionLoadListForStopID(stop_id, read_only);
139 return section_load_list->SetSectionLoadAddress(section_sp, load_addr,
140 warn_multiple);
Greg Claytond5944cd2013-12-06 01:12:00 +0000141}
142
143size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
145 const lldb::SectionSP &section_sp) {
146 std::lock_guard<std::recursive_mutex> guard(m_mutex);
147 const bool read_only = false;
148 SectionLoadList *section_load_list =
149 GetSectionLoadListForStopID(stop_id, read_only);
150 return section_load_list->SetSectionUnloaded(section_sp);
Greg Claytond5944cd2013-12-06 01:12:00 +0000151}
152
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153bool SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
154 const lldb::SectionSP &section_sp,
155 addr_t load_addr) {
156 std::lock_guard<std::recursive_mutex> guard(m_mutex);
157 const bool read_only = false;
158 SectionLoadList *section_load_list =
159 GetSectionLoadListForStopID(stop_id, read_only);
160 return section_load_list->SetSectionUnloaded(section_sp, load_addr);
Greg Claytond5944cd2013-12-06 01:12:00 +0000161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163void SectionLoadHistory::Dump(Stream &s, Target *target) {
164 std::lock_guard<std::recursive_mutex> guard(m_mutex);
165 StopIDToSectionLoadList::iterator pos,
166 end = m_stop_id_to_section_load_list.end();
167 for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {
168 s.Printf("StopID = %u:\n", pos->first);
169 pos->second->Dump(s, target);
170 s.EOL();
171 }
Greg Claytond5944cd2013-12-06 01:12:00 +0000172}