1*80814287SRaphael Isemann //===-- SectionLoadHistory.cpp --------------------------------------------===//
2d5944cd1SGreg Clayton //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d5944cd1SGreg Clayton //
7d5944cd1SGreg Clayton //===----------------------------------------------------------------------===//
8d5944cd1SGreg Clayton
9d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadHistory.h"
10d5944cd1SGreg Clayton
11d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h"
12bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
13d5944cd1SGreg Clayton
14d5944cd1SGreg Clayton using namespace lldb;
15d5944cd1SGreg Clayton using namespace lldb_private;
16d5944cd1SGreg Clayton
IsEmpty() const17b9c1b51eSKate Stone bool SectionLoadHistory::IsEmpty() const {
1816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
19d5944cd1SGreg Clayton return m_stop_id_to_section_load_list.empty();
20d5944cd1SGreg Clayton }
21d5944cd1SGreg Clayton
Clear()22b9c1b51eSKate Stone void SectionLoadHistory::Clear() {
2316ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
24d5944cd1SGreg Clayton m_stop_id_to_section_load_list.clear();
25d5944cd1SGreg Clayton }
26d5944cd1SGreg Clayton
GetLastStopID() const27b9c1b51eSKate Stone uint32_t SectionLoadHistory::GetLastStopID() const {
2816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
29d5944cd1SGreg Clayton if (m_stop_id_to_section_load_list.empty())
30d5944cd1SGreg Clayton return 0;
31d5944cd1SGreg Clayton else
32d5944cd1SGreg Clayton return m_stop_id_to_section_load_list.rbegin()->first;
33d5944cd1SGreg Clayton }
34d5944cd1SGreg Clayton
35d5944cd1SGreg Clayton SectionLoadList *
GetSectionLoadListForStopID(uint32_t stop_id,bool read_only)36b9c1b51eSKate Stone SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
37b9c1b51eSKate Stone bool read_only) {
38b9c1b51eSKate Stone if (!m_stop_id_to_section_load_list.empty()) {
39b9c1b51eSKate Stone if (read_only) {
40b9c1b51eSKate Stone // The section load list is for reading data only so we don't need to
4105097246SAdrian Prantl // create a new SectionLoadList for the current stop ID, just return the
4205097246SAdrian Prantl // section load list for the stop ID that is equal to or less than the
4305097246SAdrian Prantl // current stop ID
44b9c1b51eSKate Stone if (stop_id == eStopIDNow) {
4505097246SAdrian Prantl // If we are asking for the latest and greatest value, it is always at
4605097246SAdrian Prantl // the end of our list because that will be the highest stop ID.
47b9c1b51eSKate Stone StopIDToSectionLoadList::reverse_iterator rpos =
48b9c1b51eSKate Stone m_stop_id_to_section_load_list.rbegin();
49d5944cd1SGreg Clayton return rpos->second.get();
50b9c1b51eSKate Stone } else {
51b9c1b51eSKate Stone StopIDToSectionLoadList::iterator pos =
52b9c1b51eSKate Stone m_stop_id_to_section_load_list.lower_bound(stop_id);
53b9c1b51eSKate Stone if (pos != m_stop_id_to_section_load_list.end() &&
54b9c1b51eSKate Stone pos->first == stop_id)
55d5944cd1SGreg Clayton return pos->second.get();
56b9c1b51eSKate Stone else if (pos != m_stop_id_to_section_load_list.begin()) {
57d5944cd1SGreg Clayton --pos;
58d5944cd1SGreg Clayton return pos->second.get();
59d5944cd1SGreg Clayton }
60d5944cd1SGreg Clayton }
61b9c1b51eSKate Stone } else {
62b9c1b51eSKate Stone // You can only use "eStopIDNow" when reading from the section load
63b9c1b51eSKate Stone // history
64d5944cd1SGreg Clayton assert(stop_id != eStopIDNow);
65d5944cd1SGreg Clayton
66b9c1b51eSKate Stone // We are updating the section load list (not read only), so if the stop
6705097246SAdrian Prantl // ID passed in isn't the same as the last stop ID in our collection,
6805097246SAdrian Prantl // then create a new node using the current stop ID
69b9c1b51eSKate Stone StopIDToSectionLoadList::iterator pos =
70b9c1b51eSKate Stone m_stop_id_to_section_load_list.lower_bound(stop_id);
71b9c1b51eSKate Stone if (pos != m_stop_id_to_section_load_list.end() &&
72b9c1b51eSKate Stone pos->first == stop_id) {
73d5944cd1SGreg Clayton // We already have an entry for this value
74d5944cd1SGreg Clayton return pos->second.get();
75d5944cd1SGreg Clayton }
76d5944cd1SGreg Clayton
77d5944cd1SGreg Clayton // We must make a new section load list that is based on the last valid
78d5944cd1SGreg Clayton // section load list, so here we copy the last section load list and add
79d5944cd1SGreg Clayton // a new node for the current stop ID.
80b9c1b51eSKate Stone StopIDToSectionLoadList::reverse_iterator rpos =
81b9c1b51eSKate Stone m_stop_id_to_section_load_list.rbegin();
82b9c1b51eSKate Stone SectionLoadListSP section_load_list_sp(
8370355aceSJonas Devlieghere new SectionLoadList(*rpos->second));
84d5944cd1SGreg Clayton m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
85d5944cd1SGreg Clayton return section_load_list_sp.get();
86d5944cd1SGreg Clayton }
87d5944cd1SGreg Clayton }
8824feaf70SGreg Clayton SectionLoadListSP section_load_list_sp(new SectionLoadList());
8924feaf70SGreg Clayton if (stop_id == eStopIDNow)
9024feaf70SGreg Clayton stop_id = 0;
9124feaf70SGreg Clayton m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
9224feaf70SGreg Clayton return section_load_list_sp.get();
93d5944cd1SGreg Clayton }
94d5944cd1SGreg Clayton
GetCurrentSectionLoadList()95b9c1b51eSKate Stone SectionLoadList &SectionLoadHistory::GetCurrentSectionLoadList() {
96d5944cd1SGreg Clayton const bool read_only = true;
9716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
98b9c1b51eSKate Stone SectionLoadList *section_load_list =
99b9c1b51eSKate Stone GetSectionLoadListForStopID(eStopIDNow, read_only);
100248a1305SKonrad Kleine assert(section_load_list != nullptr);
101d5944cd1SGreg Clayton return *section_load_list;
102d5944cd1SGreg Clayton }
103d5944cd1SGreg Clayton
104d5944cd1SGreg Clayton addr_t
GetSectionLoadAddress(uint32_t stop_id,const lldb::SectionSP & section_sp)105b9c1b51eSKate Stone SectionLoadHistory::GetSectionLoadAddress(uint32_t stop_id,
106b9c1b51eSKate Stone const lldb::SectionSP §ion_sp) {
10716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
108d5944cd1SGreg Clayton const bool read_only = true;
109b9c1b51eSKate Stone SectionLoadList *section_load_list =
110b9c1b51eSKate Stone GetSectionLoadListForStopID(stop_id, read_only);
111d5944cd1SGreg Clayton return section_load_list->GetSectionLoadAddress(section_sp);
112d5944cd1SGreg Clayton }
113d5944cd1SGreg Clayton
ResolveLoadAddress(uint32_t stop_id,addr_t load_addr,Address & so_addr)114b9c1b51eSKate Stone bool SectionLoadHistory::ResolveLoadAddress(uint32_t stop_id, addr_t load_addr,
115b9c1b51eSKate Stone Address &so_addr) {
116d5944cd1SGreg Clayton // First find the top level section that this load address exists in
11716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
118d5944cd1SGreg Clayton const bool read_only = true;
119b9c1b51eSKate Stone SectionLoadList *section_load_list =
120b9c1b51eSKate Stone GetSectionLoadListForStopID(stop_id, read_only);
121d5944cd1SGreg Clayton return section_load_list->ResolveLoadAddress(load_addr, so_addr);
122d5944cd1SGreg Clayton }
123d5944cd1SGreg Clayton
SetSectionLoadAddress(uint32_t stop_id,const lldb::SectionSP & section_sp,addr_t load_addr,bool warn_multiple)124b9c1b51eSKate Stone bool SectionLoadHistory::SetSectionLoadAddress(
125b9c1b51eSKate Stone uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr,
126b9c1b51eSKate Stone bool warn_multiple) {
12716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
128d5944cd1SGreg Clayton const bool read_only = false;
129b9c1b51eSKate Stone SectionLoadList *section_load_list =
130b9c1b51eSKate Stone GetSectionLoadListForStopID(stop_id, read_only);
131b9c1b51eSKate Stone return section_load_list->SetSectionLoadAddress(section_sp, load_addr,
132b9c1b51eSKate Stone warn_multiple);
133d5944cd1SGreg Clayton }
134d5944cd1SGreg Clayton
135d5944cd1SGreg Clayton size_t
SetSectionUnloaded(uint32_t stop_id,const lldb::SectionSP & section_sp)136b9c1b51eSKate Stone SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
137b9c1b51eSKate Stone const lldb::SectionSP §ion_sp) {
13816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
139d5944cd1SGreg Clayton const bool read_only = false;
140b9c1b51eSKate Stone SectionLoadList *section_load_list =
141b9c1b51eSKate Stone GetSectionLoadListForStopID(stop_id, read_only);
142d5944cd1SGreg Clayton return section_load_list->SetSectionUnloaded(section_sp);
143d5944cd1SGreg Clayton }
144d5944cd1SGreg Clayton
SetSectionUnloaded(uint32_t stop_id,const lldb::SectionSP & section_sp,addr_t load_addr)145b9c1b51eSKate Stone bool SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,
146b9c1b51eSKate Stone const lldb::SectionSP §ion_sp,
147b9c1b51eSKate Stone addr_t load_addr) {
14816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
149d5944cd1SGreg Clayton const bool read_only = false;
150b9c1b51eSKate Stone SectionLoadList *section_load_list =
151b9c1b51eSKate Stone GetSectionLoadListForStopID(stop_id, read_only);
152d5944cd1SGreg Clayton return section_load_list->SetSectionUnloaded(section_sp, load_addr);
153d5944cd1SGreg Clayton }
154d5944cd1SGreg Clayton
Dump(Stream & s,Target * target)155b9c1b51eSKate Stone void SectionLoadHistory::Dump(Stream &s, Target *target) {
15616ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
157b9c1b51eSKate Stone StopIDToSectionLoadList::iterator pos,
158b9c1b51eSKate Stone end = m_stop_id_to_section_load_list.end();
159b9c1b51eSKate Stone for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {
160d5944cd1SGreg Clayton s.Printf("StopID = %u:\n", pos->first);
161d5944cd1SGreg Clayton pos->second->Dump(s, target);
162d5944cd1SGreg Clayton s.EOL();
163d5944cd1SGreg Clayton }
164d5944cd1SGreg Clayton }
165