Path: blob/main/contrib/llvm-project/lldb/source/Target/SectionLoadHistory.cpp
39587 views
//===-- SectionLoadHistory.cpp --------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Target/SectionLoadHistory.h"910#include "lldb/Target/SectionLoadList.h"11#include "lldb/Utility/Stream.h"1213using namespace lldb;14using namespace lldb_private;1516bool SectionLoadHistory::IsEmpty() const {17std::lock_guard<std::recursive_mutex> guard(m_mutex);18return m_stop_id_to_section_load_list.empty();19}2021void SectionLoadHistory::Clear() {22std::lock_guard<std::recursive_mutex> guard(m_mutex);23m_stop_id_to_section_load_list.clear();24}2526uint32_t SectionLoadHistory::GetLastStopID() const {27std::lock_guard<std::recursive_mutex> guard(m_mutex);28if (m_stop_id_to_section_load_list.empty())29return 0;30else31return m_stop_id_to_section_load_list.rbegin()->first;32}3334SectionLoadList *35SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,36bool read_only) {37if (!m_stop_id_to_section_load_list.empty()) {38if (read_only) {39// The section load list is for reading data only so we don't need to40// create a new SectionLoadList for the current stop ID, just return the41// section load list for the stop ID that is equal to or less than the42// current stop ID43if (stop_id == eStopIDNow) {44// If we are asking for the latest and greatest value, it is always at45// the end of our list because that will be the highest stop ID.46StopIDToSectionLoadList::reverse_iterator rpos =47m_stop_id_to_section_load_list.rbegin();48return rpos->second.get();49} else {50StopIDToSectionLoadList::iterator pos =51m_stop_id_to_section_load_list.lower_bound(stop_id);52if (pos != m_stop_id_to_section_load_list.end() &&53pos->first == stop_id)54return pos->second.get();55else if (pos != m_stop_id_to_section_load_list.begin()) {56--pos;57return pos->second.get();58}59}60} else {61// You can only use "eStopIDNow" when reading from the section load62// history63assert(stop_id != eStopIDNow);6465// We are updating the section load list (not read only), so if the stop66// ID passed in isn't the same as the last stop ID in our collection,67// then create a new node using the current stop ID68StopIDToSectionLoadList::iterator pos =69m_stop_id_to_section_load_list.lower_bound(stop_id);70if (pos != m_stop_id_to_section_load_list.end() &&71pos->first == stop_id) {72// We already have an entry for this value73return pos->second.get();74}7576// We must make a new section load list that is based on the last valid77// section load list, so here we copy the last section load list and add78// a new node for the current stop ID.79StopIDToSectionLoadList::reverse_iterator rpos =80m_stop_id_to_section_load_list.rbegin();81SectionLoadListSP section_load_list_sp(82new SectionLoadList(*rpos->second));83m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;84return section_load_list_sp.get();85}86}87SectionLoadListSP section_load_list_sp(new SectionLoadList());88if (stop_id == eStopIDNow)89stop_id = 0;90m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;91return section_load_list_sp.get();92}9394SectionLoadList &SectionLoadHistory::GetCurrentSectionLoadList() {95const bool read_only = true;96std::lock_guard<std::recursive_mutex> guard(m_mutex);97SectionLoadList *section_load_list =98GetSectionLoadListForStopID(eStopIDNow, read_only);99assert(section_load_list != nullptr);100return *section_load_list;101}102103addr_t104SectionLoadHistory::GetSectionLoadAddress(uint32_t stop_id,105const lldb::SectionSP §ion_sp) {106std::lock_guard<std::recursive_mutex> guard(m_mutex);107const bool read_only = true;108SectionLoadList *section_load_list =109GetSectionLoadListForStopID(stop_id, read_only);110return section_load_list->GetSectionLoadAddress(section_sp);111}112113bool SectionLoadHistory::ResolveLoadAddress(uint32_t stop_id, addr_t load_addr,114Address &so_addr) {115// First find the top level section that this load address exists in116std::lock_guard<std::recursive_mutex> guard(m_mutex);117const bool read_only = true;118SectionLoadList *section_load_list =119GetSectionLoadListForStopID(stop_id, read_only);120return section_load_list->ResolveLoadAddress(load_addr, so_addr);121}122123bool SectionLoadHistory::SetSectionLoadAddress(124uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr,125bool warn_multiple) {126std::lock_guard<std::recursive_mutex> guard(m_mutex);127const bool read_only = false;128SectionLoadList *section_load_list =129GetSectionLoadListForStopID(stop_id, read_only);130return section_load_list->SetSectionLoadAddress(section_sp, load_addr,131warn_multiple);132}133134size_t135SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,136const lldb::SectionSP §ion_sp) {137std::lock_guard<std::recursive_mutex> guard(m_mutex);138const bool read_only = false;139SectionLoadList *section_load_list =140GetSectionLoadListForStopID(stop_id, read_only);141return section_load_list->SetSectionUnloaded(section_sp);142}143144bool SectionLoadHistory::SetSectionUnloaded(uint32_t stop_id,145const lldb::SectionSP §ion_sp,146addr_t load_addr) {147std::lock_guard<std::recursive_mutex> guard(m_mutex);148const bool read_only = false;149SectionLoadList *section_load_list =150GetSectionLoadListForStopID(stop_id, read_only);151return section_load_list->SetSectionUnloaded(section_sp, load_addr);152}153154void SectionLoadHistory::Dump(Stream &s, Target *target) {155std::lock_guard<std::recursive_mutex> guard(m_mutex);156StopIDToSectionLoadList::iterator pos,157end = m_stop_id_to_section_load_list.end();158for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {159s.Printf("StopID = %u:\n", pos->first);160pos->second->Dump(s, target);161s.EOL();162}163}164165166