Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Target/SectionLoadHistory.cpp
39587 views
1
//===-- SectionLoadHistory.cpp --------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lldb/Target/SectionLoadHistory.h"
10
11
#include "lldb/Target/SectionLoadList.h"
12
#include "lldb/Utility/Stream.h"
13
14
using namespace lldb;
15
using namespace lldb_private;
16
17
bool SectionLoadHistory::IsEmpty() const {
18
std::lock_guard<std::recursive_mutex> guard(m_mutex);
19
return m_stop_id_to_section_load_list.empty();
20
}
21
22
void SectionLoadHistory::Clear() {
23
std::lock_guard<std::recursive_mutex> guard(m_mutex);
24
m_stop_id_to_section_load_list.clear();
25
}
26
27
uint32_t SectionLoadHistory::GetLastStopID() const {
28
std::lock_guard<std::recursive_mutex> guard(m_mutex);
29
if (m_stop_id_to_section_load_list.empty())
30
return 0;
31
else
32
return m_stop_id_to_section_load_list.rbegin()->first;
33
}
34
35
SectionLoadList *
36
SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
37
bool read_only) {
38
if (!m_stop_id_to_section_load_list.empty()) {
39
if (read_only) {
40
// The section load list is for reading data only so we don't need to
41
// create a new SectionLoadList for the current stop ID, just return the
42
// section load list for the stop ID that is equal to or less than the
43
// current stop ID
44
if (stop_id == eStopIDNow) {
45
// If we are asking for the latest and greatest value, it is always at
46
// the end of our list because that will be the highest stop ID.
47
StopIDToSectionLoadList::reverse_iterator rpos =
48
m_stop_id_to_section_load_list.rbegin();
49
return rpos->second.get();
50
} else {
51
StopIDToSectionLoadList::iterator pos =
52
m_stop_id_to_section_load_list.lower_bound(stop_id);
53
if (pos != m_stop_id_to_section_load_list.end() &&
54
pos->first == stop_id)
55
return pos->second.get();
56
else if (pos != m_stop_id_to_section_load_list.begin()) {
57
--pos;
58
return pos->second.get();
59
}
60
}
61
} else {
62
// You can only use "eStopIDNow" when reading from the section load
63
// history
64
assert(stop_id != eStopIDNow);
65
66
// We are updating the section load list (not read only), so if the stop
67
// ID passed in isn't the same as the last stop ID in our collection,
68
// then create a new node using the current stop ID
69
StopIDToSectionLoadList::iterator pos =
70
m_stop_id_to_section_load_list.lower_bound(stop_id);
71
if (pos != m_stop_id_to_section_load_list.end() &&
72
pos->first == stop_id) {
73
// We already have an entry for this value
74
return pos->second.get();
75
}
76
77
// We must make a new section load list that is based on the last valid
78
// section load list, so here we copy the last section load list and add
79
// a new node for the current stop ID.
80
StopIDToSectionLoadList::reverse_iterator rpos =
81
m_stop_id_to_section_load_list.rbegin();
82
SectionLoadListSP section_load_list_sp(
83
new SectionLoadList(*rpos->second));
84
m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
85
return section_load_list_sp.get();
86
}
87
}
88
SectionLoadListSP section_load_list_sp(new SectionLoadList());
89
if (stop_id == eStopIDNow)
90
stop_id = 0;
91
m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
92
return section_load_list_sp.get();
93
}
94
95
SectionLoadList &SectionLoadHistory::GetCurrentSectionLoadList() {
96
const bool read_only = true;
97
std::lock_guard<std::recursive_mutex> guard(m_mutex);
98
SectionLoadList *section_load_list =
99
GetSectionLoadListForStopID(eStopIDNow, read_only);
100
assert(section_load_list != nullptr);
101
return *section_load_list;
102
}
103
104
addr_t
105
SectionLoadHistory::GetSectionLoadAddress(uint32_t stop_id,
106
const lldb::SectionSP &section_sp) {
107
std::lock_guard<std::recursive_mutex> guard(m_mutex);
108
const bool read_only = true;
109
SectionLoadList *section_load_list =
110
GetSectionLoadListForStopID(stop_id, read_only);
111
return section_load_list->GetSectionLoadAddress(section_sp);
112
}
113
114
bool SectionLoadHistory::ResolveLoadAddress(uint32_t stop_id, addr_t load_addr,
115
Address &so_addr) {
116
// First find the top level section that this load address exists in
117
std::lock_guard<std::recursive_mutex> guard(m_mutex);
118
const bool read_only = true;
119
SectionLoadList *section_load_list =
120
GetSectionLoadListForStopID(stop_id, read_only);
121
return section_load_list->ResolveLoadAddress(load_addr, so_addr);
122
}
123
124
bool SectionLoadHistory::SetSectionLoadAddress(
125
uint32_t stop_id, const lldb::SectionSP &section_sp, addr_t load_addr,
126
bool warn_multiple) {
127
std::lock_guard<std::recursive_mutex> guard(m_mutex);
128
const bool read_only = false;
129
SectionLoadList *section_load_list =
130
GetSectionLoadListForStopID(stop_id, read_only);
131
return section_load_list->SetSectionLoadAddress(section_sp, load_addr,
132
warn_multiple);
133
}
134
135
size_t
136
SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
137
const lldb::SectionSP &section_sp) {
138
std::lock_guard<std::recursive_mutex> guard(m_mutex);
139
const bool read_only = false;
140
SectionLoadList *section_load_list =
141
GetSectionLoadListForStopID(stop_id, read_only);
142
return section_load_list->SetSectionUnloaded(section_sp);
143
}
144
145
bool SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
146
const lldb::SectionSP &section_sp,
147
addr_t load_addr) {
148
std::lock_guard<std::recursive_mutex> guard(m_mutex);
149
const bool read_only = false;
150
SectionLoadList *section_load_list =
151
GetSectionLoadListForStopID(stop_id, read_only);
152
return section_load_list->SetSectionUnloaded(section_sp, load_addr);
153
}
154
155
void SectionLoadHistory::Dump(Stream &s, Target *target) {
156
std::lock_guard<std::recursive_mutex> guard(m_mutex);
157
StopIDToSectionLoadList::iterator pos,
158
end = m_stop_id_to_section_load_list.end();
159
for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {
160
s.Printf("StopID = %u:\n", pos->first);
161
pos->second->Dump(s, target);
162
s.EOL();
163
}
164
}
165
166