mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 11:02:04 +08:00
For logical backtrace work, lldb needs to track Module unloads etc & symoblicate an address based on a point in time
<rdar://problem/15314403> This patch adds a new lldb_private::SectionLoadHistory class that tracks what shared libraries were loaded given a process stop ID. This allows us to keep a history of the sections that were loaded for a time T. Many items in history objects will rely upon the process stop ID in the future. llvm-svn: 196557
This commit is contained in:
@@ -646,9 +646,47 @@ public:
|
||||
void
|
||||
Clear ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve a current load address into a section offset address.
|
||||
///
|
||||
/// @param[in] vm_addr
|
||||
/// A virtual address from the current process state that is to
|
||||
/// be translated into a section offset address.
|
||||
///
|
||||
/// @return
|
||||
/// An SBAddress which will be valid if \a vm_addr was
|
||||
/// successfully resolved into a section offset address, or an
|
||||
/// invalid SBAddress if \a vm_addr doesn't resolve to a section
|
||||
/// in a module.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBAddress
|
||||
ResolveLoadAddress (lldb::addr_t vm_addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve a current load address into a section offset address
|
||||
/// using the process stop ID to identify a time in the past.
|
||||
///
|
||||
/// @param[in] stop_id
|
||||
/// Each time a process stops, the process stop ID integer gets
|
||||
/// incremented. These stop IDs are used to identify past times
|
||||
/// and can be used in history objects as a cheap way to store
|
||||
/// the time at which the sample was taken. Specifying
|
||||
/// UINT32_MAX will always resolve the address using the
|
||||
/// currently loaded sections.
|
||||
///
|
||||
/// @param[in] vm_addr
|
||||
/// A virtual address from the current process state that is to
|
||||
/// be translated into a section offset address.
|
||||
///
|
||||
/// @return
|
||||
/// An SBAddress which will be valid if \a vm_addr was
|
||||
/// successfully resolved into a section offset address, or an
|
||||
/// invalid SBAddress if \a vm_addr doesn't resolve to a section
|
||||
/// in a module.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBAddress
|
||||
ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr);
|
||||
|
||||
SBSymbolContext
|
||||
ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
uint32_t resolve_scope);
|
||||
|
||||
109
lldb/include/lldb/Target/SectionLoadHistory.h
Normal file
109
lldb/include/lldb/Target/SectionLoadHistory.h
Normal file
@@ -0,0 +1,109 @@
|
||||
//===-- SectionLoadHistory.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_SectionLoadHistory_h_
|
||||
#define liblldb_SectionLoadHistory_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <map>
|
||||
|
||||
// Project includes
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class SectionLoadHistory
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
// Pass eStopIDNow to any function that takes a stop ID to get
|
||||
// the current value.
|
||||
eStopIDNow = UINT32_MAX
|
||||
};
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
SectionLoadHistory () :
|
||||
m_stop_id_to_section_load_list(),
|
||||
m_mutex (Mutex::eMutexTypeRecursive)
|
||||
{
|
||||
}
|
||||
|
||||
~SectionLoadHistory()
|
||||
{
|
||||
// Call clear since this takes a lock and clears the section load list
|
||||
// in case another thread is currently using this section load list
|
||||
Clear();
|
||||
}
|
||||
|
||||
SectionLoadList &
|
||||
GetCurrentSectionLoadList ();
|
||||
|
||||
bool
|
||||
IsEmpty() const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
uint32_t
|
||||
GetLastStopID() const;
|
||||
|
||||
// Get the section load address given a process stop ID
|
||||
lldb::addr_t
|
||||
GetSectionLoadAddress (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp);
|
||||
|
||||
bool
|
||||
ResolveLoadAddress (uint32_t stop_id,
|
||||
lldb::addr_t load_addr,
|
||||
Address &so_addr);
|
||||
|
||||
bool
|
||||
SetSectionLoadAddress (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp,
|
||||
lldb::addr_t load_addr,
|
||||
bool warn_multiple = false);
|
||||
|
||||
// The old load address should be specified when unloading to ensure we get
|
||||
// the correct instance of the section as a shared library could be loaded
|
||||
// at more than one location.
|
||||
bool
|
||||
SetSectionUnloaded (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp,
|
||||
lldb::addr_t load_addr);
|
||||
|
||||
// Unload all instances of a section. This function can be used on systems
|
||||
// that don't support multiple copies of the same shared library to be
|
||||
// loaded at the same time.
|
||||
size_t
|
||||
SetSectionUnloaded (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp);
|
||||
|
||||
void
|
||||
Dump (Stream &s,
|
||||
Target *target);
|
||||
|
||||
protected:
|
||||
|
||||
SectionLoadList *
|
||||
GetSectionLoadListForStopID (uint32_t stop_id, bool read_only);
|
||||
|
||||
typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList;
|
||||
StopIDToSectionLoadList m_stop_id_to_section_load_list;
|
||||
mutable Mutex m_mutex;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (SectionLoadHistory);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_SectionLoadHistory_h_
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
SectionLoadList (const SectionLoadList& rhs);
|
||||
|
||||
~SectionLoadList()
|
||||
{
|
||||
// Call clear since this takes a lock and clears the section load list
|
||||
@@ -43,6 +45,9 @@ public:
|
||||
Clear();
|
||||
}
|
||||
|
||||
void
|
||||
operator=(const SectionLoadList &rhs);
|
||||
|
||||
bool
|
||||
IsEmpty() const;
|
||||
|
||||
@@ -79,9 +84,6 @@ protected:
|
||||
addr_to_sect_collection m_addr_to_sect;
|
||||
sect_to_addr_collection m_sect_to_addr;
|
||||
mutable Mutex m_mutex;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (SectionLoadList);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/PathMappingList.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/SectionLoadHistory.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@@ -1001,14 +1001,14 @@ public:
|
||||
SectionLoadList&
|
||||
GetSectionLoadList()
|
||||
{
|
||||
return m_section_load_list;
|
||||
return m_section_load_history.GetCurrentSectionLoadList();
|
||||
}
|
||||
|
||||
const SectionLoadList&
|
||||
GetSectionLoadList() const
|
||||
{
|
||||
return m_section_load_list;
|
||||
}
|
||||
// const SectionLoadList&
|
||||
// GetSectionLoadList() const
|
||||
// {
|
||||
// return const_cast<SectionLoadHistory *>(&m_section_load_history)->GetCurrentSectionLoadList();
|
||||
// }
|
||||
|
||||
static Target *
|
||||
GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr,
|
||||
@@ -1048,6 +1048,26 @@ public:
|
||||
Error
|
||||
Install(ProcessLaunchInfo *launch_info);
|
||||
|
||||
|
||||
bool
|
||||
ResolveLoadAddress (lldb::addr_t load_addr,
|
||||
Address &so_addr,
|
||||
uint32_t stop_id = SectionLoadHistory::eStopIDNow);
|
||||
|
||||
bool
|
||||
SetSectionLoadAddress (const lldb::SectionSP §ion,
|
||||
lldb::addr_t load_addr,
|
||||
bool warn_multiple = false);
|
||||
|
||||
bool
|
||||
SetSectionUnloaded (const lldb::SectionSP §ion_sp);
|
||||
|
||||
bool
|
||||
SetSectionUnloaded (const lldb::SectionSP §ion_sp, lldb::addr_t load_addr);
|
||||
|
||||
void
|
||||
ClearAllLoadedSections ();
|
||||
|
||||
// Since expressions results can persist beyond the lifetime of a process,
|
||||
// and the const expression results are available after a process is gone,
|
||||
// we provide a way for expressions to be evaluated from the Target itself.
|
||||
@@ -1250,7 +1270,7 @@ protected:
|
||||
Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
|
||||
ArchSpec m_arch;
|
||||
ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
|
||||
SectionLoadList m_section_load_list;
|
||||
SectionLoadHistory m_section_load_history;
|
||||
BreakpointList m_breakpoint_list;
|
||||
BreakpointList m_internal_breakpoint_list;
|
||||
lldb::BreakpointSP m_last_created_breakpoint;
|
||||
@@ -1260,7 +1280,6 @@ protected:
|
||||
// we can correctly tear down everything that we need to, so the only
|
||||
// class that knows about the process lifespan is this target class.
|
||||
lldb::ProcessSP m_process_sp;
|
||||
bool m_valid;
|
||||
lldb::SearchFilterSP m_search_filter_sp;
|
||||
PathMappingList m_image_search_paths;
|
||||
std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap;
|
||||
@@ -1273,8 +1292,8 @@ protected:
|
||||
typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
|
||||
StopHookCollection m_stop_hooks;
|
||||
lldb::user_id_t m_stop_hook_next_id;
|
||||
bool m_valid;
|
||||
bool m_suppress_stop_hooks;
|
||||
bool m_suppress_synthetic_value;
|
||||
|
||||
static void
|
||||
ImageSearchPathsChanged (const PathMappingList &path_list,
|
||||
|
||||
@@ -181,6 +181,8 @@ class SearchFilter;
|
||||
class Section;
|
||||
class SectionImpl;
|
||||
class SectionList;
|
||||
class SectionLoadHistory;
|
||||
class SectionLoadList;
|
||||
class Settings;
|
||||
class SourceManager;
|
||||
class SourceManagerImpl;
|
||||
@@ -340,6 +342,7 @@ namespace lldb {
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
typedef std::shared_ptr<lldb_private::Section> SectionSP;
|
||||
typedef std::weak_ptr<lldb_private::Section> SectionWP;
|
||||
typedef std::shared_ptr<lldb_private::SectionLoadList> SectionLoadListSP;
|
||||
typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP;
|
||||
typedef std::shared_ptr<lldb_private::Settings> SettingsSP;
|
||||
typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP;
|
||||
|
||||
@@ -85,6 +85,8 @@
|
||||
260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */; };
|
||||
261744781168585B005ADD65 /* SBType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261744771168585B005ADD65 /* SBType.cpp */; };
|
||||
2617447A11685869005ADD65 /* SBType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2617447911685869005ADD65 /* SBType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
262173A118395D3800C52091 /* SectionLoadHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 262173A018395D3800C52091 /* SectionLoadHistory.h */; };
|
||||
262173A318395D4600C52091 /* SectionLoadHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262173A218395D4600C52091 /* SectionLoadHistory.cpp */; };
|
||||
26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26274FA514030F79006BA130 /* DynamicLoaderDarwinKernel.cpp */; };
|
||||
2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2628A4D313D4977900F5487A /* ThreadKDP.cpp */; };
|
||||
262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; };
|
||||
@@ -952,6 +954,8 @@
|
||||
2618EE641315B29C001D6D71 /* ThreadGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadGDBRemote.h; sourceTree = "<group>"; };
|
||||
261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SharingPtr.cpp; path = source/Utility/SharingPtr.cpp; sourceTree = "<group>"; };
|
||||
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharingPtr.h; path = include/lldb/Utility/SharingPtr.h; sourceTree = "<group>"; };
|
||||
262173A018395D3800C52091 /* SectionLoadHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SectionLoadHistory.h; path = include/lldb/Target/SectionLoadHistory.h; sourceTree = "<group>"; };
|
||||
262173A218395D4600C52091 /* SectionLoadHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SectionLoadHistory.cpp; path = source/Target/SectionLoadHistory.cpp; sourceTree = "<group>"; };
|
||||
26217930133BC8640083B112 /* lldb-private-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-types.h"; path = "include/lldb/lldb-private-types.h"; sourceTree = "<group>"; };
|
||||
26217932133BCB850083B112 /* lldb-private-enumerations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-enumerations.h"; path = "include/lldb/lldb-private-enumerations.h"; sourceTree = "<group>"; };
|
||||
2623096E13D0EFFB006381D9 /* StreamBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StreamBuffer.h; path = include/lldb/Core/StreamBuffer.h; sourceTree = "<group>"; };
|
||||
@@ -3159,6 +3163,8 @@
|
||||
26AB54111832DC3400EADFF3 /* RegisterCheckpoint.h */,
|
||||
26BC7DF410F1B81A00F91463 /* RegisterContext.h */,
|
||||
26BC7F3710F1B90C00F91463 /* RegisterContext.cpp */,
|
||||
262173A018395D3800C52091 /* SectionLoadHistory.h */,
|
||||
262173A218395D4600C52091 /* SectionLoadHistory.cpp */,
|
||||
2618D78F1240115500F2B8FE /* SectionLoadList.h */,
|
||||
2618D7911240116900F2B8FE /* SectionLoadList.cpp */,
|
||||
26BC7DF510F1B81A00F91463 /* StackFrame.h */,
|
||||
@@ -3688,6 +3694,7 @@
|
||||
260CC63015D04377002BF2E0 /* OptionValueBoolean.h in Headers */,
|
||||
260CC63115D04377002BF2E0 /* OptionValueProperties.h in Headers */,
|
||||
260CC63215D04377002BF2E0 /* OptionValueDictionary.h in Headers */,
|
||||
262173A118395D3800C52091 /* SectionLoadHistory.h in Headers */,
|
||||
260CC63315D04377002BF2E0 /* OptionValueEnumeration.h in Headers */,
|
||||
260CC63415D04377002BF2E0 /* OptionValueFileSpec.h in Headers */,
|
||||
AF9B8F34182DB52900DA866F /* SystemRuntimeMacOSX.h in Headers */,
|
||||
@@ -4130,6 +4137,7 @@
|
||||
2689001A13353DDE00698AC0 /* CommandObjectFrame.cpp in Sources */,
|
||||
2689001B13353DDE00698AC0 /* CommandObjectHelp.cpp in Sources */,
|
||||
2689001D13353DDE00698AC0 /* CommandObjectLog.cpp in Sources */,
|
||||
262173A318395D4600C52091 /* SectionLoadHistory.cpp in Sources */,
|
||||
2689001E13353DDE00698AC0 /* CommandObjectMemory.cpp in Sources */,
|
||||
2689001F13353DDE00698AC0 /* CommandObjectPlatform.cpp in Sources */,
|
||||
2689002013353DDE00698AC0 /* CommandObjectProcess.cpp in Sources */,
|
||||
|
||||
@@ -649,6 +649,9 @@ public:
|
||||
|
||||
lldb::SBAddress
|
||||
ResolveLoadAddress (lldb::addr_t vm_addr);
|
||||
|
||||
lldb::SBAddress
|
||||
ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr);
|
||||
|
||||
SBSymbolContext
|
||||
ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/LanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
|
||||
@@ -1263,7 +1264,7 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
|
||||
if (target_sp)
|
||||
{
|
||||
Mutex::Locker api_locker (target_sp->GetAPIMutex());
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr))
|
||||
if (target_sp->ResolveLoadAddress (vm_addr, addr))
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
@@ -1273,6 +1274,26 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
|
||||
lldb::SBAddress
|
||||
SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
|
||||
{
|
||||
lldb::SBAddress sb_addr;
|
||||
Address &addr = sb_addr.ref();
|
||||
TargetSP target_sp(GetSP());
|
||||
if (target_sp)
|
||||
{
|
||||
Mutex::Locker api_locker (target_sp->GetAPIMutex());
|
||||
if (target_sp->ResolveLoadAddress (vm_addr, addr))
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
// We have a load address that isn't in a section, just return an address
|
||||
// with the offset filled in (the address) and the section set to NULL
|
||||
addr.SetRawAddress(vm_addr);
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
SBSymbolContext
|
||||
SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
uint32_t resolve_scope)
|
||||
@@ -2479,10 +2500,14 @@ SBTarget::SetSectionLoadAddress (lldb::SBSection section,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr))
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr))
|
||||
{
|
||||
// Flush info in the process (stack frames, etc)
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
if (process_sp)
|
||||
process_sp->Flush();
|
||||
}
|
||||
@@ -2511,10 +2536,14 @@ SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP()))
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
if (target_sp->SetSectionUnloaded (section.GetSP()))
|
||||
{
|
||||
// Flush info in the process (stack frames, etc)
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
if (process_sp)
|
||||
process_sp->Flush();
|
||||
}
|
||||
@@ -2586,13 +2615,18 @@ SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
|
||||
SectionList *section_list = objfile->GetSectionList();
|
||||
if (section_list)
|
||||
{
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
bool changed = false;
|
||||
const size_t num_sections = section_list->GetSize();
|
||||
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
|
||||
{
|
||||
SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
|
||||
if (section_sp)
|
||||
changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0;
|
||||
changed |= target_sp->SetSectionUnloaded (section_sp) > 0;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "lldb/Symbol/Function.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "lldb/Symbol/Function.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
#include "lldb/Interpreter/CommandCompletions.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "lldb/Symbol/UnwindPlan.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Symbol/SymbolVendor.h"
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "lldb/Target/CPPLanguageRuntime.h"
|
||||
#include "lldb/Target/ObjCLanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Symbol/SymbolFile.h"
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "lldb/Symbol/Variable.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "lldb/Target/ObjCLanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
|
||||
|
||||
@@ -921,7 +921,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *p
|
||||
const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
|
||||
if (memory_section)
|
||||
{
|
||||
target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
|
||||
target.SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
|
||||
++num_sections_loaded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,13 +484,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo&
|
||||
// "Section" objects, and "true" for all other sections.
|
||||
const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
|
||||
|
||||
const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
|
||||
if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
|
||||
old_section_load_addr != new_section_load_addr)
|
||||
{
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple))
|
||||
changed = true;
|
||||
}
|
||||
changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -568,7 +562,7 @@ DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo&
|
||||
if (section_sp)
|
||||
{
|
||||
const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp, old_section_load_addr))
|
||||
if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
@@ -1524,7 +1518,7 @@ DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
|
||||
DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
|
||||
Clear(true);
|
||||
m_process = process;
|
||||
m_process->GetTarget().GetSectionLoadList().Clear();
|
||||
m_process->GetTarget().ClearAllLoadedSections();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1541,7 +1535,7 @@ DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
|
||||
// breakpoint gets hit. We will use this to track when shared
|
||||
// libraries get loaded/unloaded.
|
||||
|
||||
if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
|
||||
if (m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
|
||||
{
|
||||
Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true, false).get();
|
||||
dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
|
||||
|
||||
@@ -211,7 +211,7 @@ DynamicLoaderPOSIXDYLD::CanLoadImage()
|
||||
void
|
||||
DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
|
||||
{
|
||||
SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList();
|
||||
Target &target = m_process->GetTarget();
|
||||
const SectionList *sections = GetSectionListFromModule(module);
|
||||
|
||||
assert(sections && "SectionList missing from loaded module.");
|
||||
@@ -224,23 +224,20 @@ DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_ad
|
||||
{
|
||||
SectionSP section_sp (sections->GetSectionAtIndex(i));
|
||||
lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
|
||||
lldb::addr_t old_load_addr = load_list.GetSectionLoadAddress(section_sp);
|
||||
|
||||
// If the file address of the section is zero then this is not an
|
||||
// allocatable/loadable section (property of ELF sh_addr). Skip it.
|
||||
if (new_load_addr == base_addr)
|
||||
continue;
|
||||
|
||||
if (old_load_addr == LLDB_INVALID_ADDRESS ||
|
||||
old_load_addr != new_load_addr)
|
||||
load_list.SetSectionLoadAddress(section_sp, new_load_addr);
|
||||
target.SetSectionLoadAddress(section_sp, new_load_addr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module)
|
||||
{
|
||||
SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList();
|
||||
Target &target = m_process->GetTarget();
|
||||
const SectionList *sections = GetSectionListFromModule(module);
|
||||
|
||||
assert(sections && "SectionList missing from unloaded module.");
|
||||
@@ -251,7 +248,7 @@ DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module)
|
||||
for (size_t i = 0; i < num_sections; ++i)
|
||||
{
|
||||
SectionSP section_sp (sections->GetSectionAtIndex(i));
|
||||
load_list.SetSectionUnloaded(section_sp);
|
||||
target.SetSectionUnloaded(section_sp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
|
||||
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
|
||||
if (section_sp)
|
||||
{
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress()))
|
||||
if (m_process->GetTarget().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress()))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "lldb/Symbol/TypeList.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
182
lldb/source/Target/SectionLoadHistory.cpp
Normal file
182
lldb/source/Target/SectionLoadHistory.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//===-- SectionLoadHistory.cpp ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Target/SectionLoadHistory.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
bool
|
||||
SectionLoadHistory::IsEmpty() const
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
return m_stop_id_to_section_load_list.empty();
|
||||
}
|
||||
|
||||
void
|
||||
SectionLoadHistory::Clear ()
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
m_stop_id_to_section_load_list.clear();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SectionLoadHistory::GetLastStopID() const
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
if (m_stop_id_to_section_load_list.empty())
|
||||
return 0;
|
||||
else
|
||||
return m_stop_id_to_section_load_list.rbegin()->first;
|
||||
}
|
||||
|
||||
SectionLoadList *
|
||||
SectionLoadHistory::GetSectionLoadListForStopID (uint32_t stop_id, bool read_only)
|
||||
{
|
||||
if (m_stop_id_to_section_load_list.empty())
|
||||
{
|
||||
SectionLoadListSP section_load_list_sp(new SectionLoadList());
|
||||
if (stop_id == eStopIDNow)
|
||||
stop_id = 0;
|
||||
m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
|
||||
return section_load_list_sp.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read_only)
|
||||
{
|
||||
// The section load list is for reading data only so we don't need to create
|
||||
// a new SectionLoadList for the current stop ID, just return the section
|
||||
// load list for the stop ID that is equal to or less than the current stop ID
|
||||
if (stop_id == eStopIDNow)
|
||||
{
|
||||
// If we are asking for the latest and greatest value, it is always
|
||||
// at the end of our list becuase that will be the highest stop ID.
|
||||
StopIDToSectionLoadList::reverse_iterator rpos = m_stop_id_to_section_load_list.rbegin();
|
||||
return rpos->second.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopIDToSectionLoadList::iterator pos = m_stop_id_to_section_load_list.lower_bound(stop_id);
|
||||
if (pos != m_stop_id_to_section_load_list.end() && pos->first == stop_id)
|
||||
return pos->second.get();
|
||||
else if (pos != m_stop_id_to_section_load_list.begin())
|
||||
{
|
||||
--pos;
|
||||
return pos->second.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// You can only use "eStopIDNow" when reading from the section load history
|
||||
assert(stop_id != eStopIDNow);
|
||||
|
||||
// We are updating the section load list (not read only), so if the stop ID
|
||||
// passed in isn't the same as the last stop ID in our collection, then create
|
||||
// a new node using the current stop ID
|
||||
StopIDToSectionLoadList::iterator pos = m_stop_id_to_section_load_list.lower_bound(stop_id);
|
||||
if (pos != m_stop_id_to_section_load_list.end() && pos->first == stop_id)
|
||||
{
|
||||
// We already have an entry for this value
|
||||
return pos->second.get();
|
||||
}
|
||||
|
||||
// We must make a new section load list that is based on the last valid
|
||||
// section load list, so here we copy the last section load list and add
|
||||
// a new node for the current stop ID.
|
||||
StopIDToSectionLoadList::reverse_iterator rpos = m_stop_id_to_section_load_list.rbegin();
|
||||
SectionLoadListSP section_load_list_sp(new SectionLoadList(*rpos->second.get()));
|
||||
m_stop_id_to_section_load_list[stop_id] = section_load_list_sp;
|
||||
return section_load_list_sp.get();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SectionLoadList &
|
||||
SectionLoadHistory::GetCurrentSectionLoadList ()
|
||||
{
|
||||
const bool read_only = true;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (eStopIDNow, read_only);
|
||||
assert(section_load_list != NULL);
|
||||
return *section_load_list;
|
||||
}
|
||||
|
||||
addr_t
|
||||
SectionLoadHistory::GetSectionLoadAddress (uint32_t stop_id, const lldb::SectionSP §ion_sp)
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
const bool read_only = true;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
|
||||
return section_load_list->GetSectionLoadAddress(section_sp);
|
||||
}
|
||||
|
||||
bool
|
||||
SectionLoadHistory::ResolveLoadAddress (uint32_t stop_id, addr_t load_addr, Address &so_addr)
|
||||
{
|
||||
// First find the top level section that this load address exists in
|
||||
Mutex::Locker locker(m_mutex);
|
||||
const bool read_only = true;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
|
||||
return section_load_list->ResolveLoadAddress (load_addr, so_addr);
|
||||
}
|
||||
|
||||
bool
|
||||
SectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp,
|
||||
addr_t load_addr,
|
||||
bool warn_multiple)
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
const bool read_only = false;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
|
||||
return section_load_list->SetSectionLoadAddress(section_sp, load_addr, warn_multiple);
|
||||
}
|
||||
|
||||
size_t
|
||||
SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp)
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
const bool read_only = false;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
|
||||
return section_load_list->SetSectionUnloaded (section_sp);
|
||||
}
|
||||
|
||||
bool
|
||||
SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr)
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
const bool read_only = false;
|
||||
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
|
||||
return section_load_list->SetSectionUnloaded (section_sp, load_addr);
|
||||
}
|
||||
|
||||
void
|
||||
SectionLoadHistory::Dump (Stream &s, Target *target)
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
StopIDToSectionLoadList::iterator pos, end = m_stop_id_to_section_load_list.end();
|
||||
for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos)
|
||||
{
|
||||
s.Printf("StopID = %u:\n", pos->first);
|
||||
pos->second->Dump(s, target);
|
||||
s.EOL();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
SectionLoadList::SectionLoadList (const SectionLoadList& rhs) :
|
||||
m_addr_to_sect(),
|
||||
m_sect_to_addr(),
|
||||
m_mutex (Mutex::eMutexTypeRecursive)
|
||||
{
|
||||
Mutex::Locker locker(rhs.m_mutex);
|
||||
m_addr_to_sect = rhs.m_addr_to_sect;
|
||||
m_sect_to_addr = rhs.m_sect_to_addr;
|
||||
}
|
||||
|
||||
void
|
||||
SectionLoadList::operator=(const SectionLoadList &rhs)
|
||||
{
|
||||
Mutex::Locker lhs_locker (m_mutex);
|
||||
Mutex::Locker rhs_locker (rhs.m_mutex);
|
||||
m_addr_to_sect = rhs.m_addr_to_sect;
|
||||
m_sect_to_addr = rhs.m_sect_to_addr;
|
||||
}
|
||||
|
||||
bool
|
||||
SectionLoadList::IsEmpty() const
|
||||
{
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "lldb/lldb-private-log.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/SystemRuntime.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
@@ -69,12 +70,11 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
|
||||
m_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_arch (target_arch),
|
||||
m_images (this),
|
||||
m_section_load_list (),
|
||||
m_section_load_history (),
|
||||
m_breakpoint_list (false),
|
||||
m_internal_breakpoint_list (true),
|
||||
m_watchpoint_list (),
|
||||
m_process_sp (),
|
||||
m_valid (true),
|
||||
m_search_filter_sp (),
|
||||
m_image_search_paths (ImageSearchPathsChanged, this),
|
||||
m_scratch_ast_context_ap (),
|
||||
@@ -84,6 +84,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
|
||||
m_source_manager_ap(),
|
||||
m_stop_hooks (),
|
||||
m_stop_hook_next_id (0),
|
||||
m_valid (true),
|
||||
m_suppress_stop_hooks (false)
|
||||
{
|
||||
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
|
||||
@@ -158,7 +159,7 @@ Target::DeleteCurrentProcess ()
|
||||
{
|
||||
if (m_process_sp.get())
|
||||
{
|
||||
m_section_load_list.Clear();
|
||||
m_section_load_history.Clear();
|
||||
if (m_process_sp->IsAlive())
|
||||
m_process_sp->Destroy();
|
||||
|
||||
@@ -193,7 +194,7 @@ Target::Destroy()
|
||||
m_platform_sp.reset();
|
||||
m_arch.Clear();
|
||||
ClearModules(true);
|
||||
m_section_load_list.Clear();
|
||||
m_section_load_history.Clear();
|
||||
const bool notify = false;
|
||||
m_breakpoint_list.RemoveAll(notify);
|
||||
m_internal_breakpoint_list.RemoveAll(notify);
|
||||
@@ -314,7 +315,7 @@ Target::CreateBreakpoint (lldb::addr_t addr, bool internal, bool hardware)
|
||||
// it doesn't resolve to section/offset.
|
||||
|
||||
// Try and resolve as a load address if possible
|
||||
m_section_load_list.ResolveLoadAddress(addr, so_addr);
|
||||
GetSectionLoadList().ResolveLoadAddress(addr, so_addr);
|
||||
if (!so_addr.IsValid())
|
||||
{
|
||||
// The address didn't resolve, so just set this as an absolute address
|
||||
@@ -1017,7 +1018,7 @@ void
|
||||
Target::ClearModules(bool delete_locations)
|
||||
{
|
||||
ModulesDidUnload (m_images, delete_locations);
|
||||
GetSectionLoadList().Clear();
|
||||
m_section_load_history.Clear();
|
||||
m_images.Clear();
|
||||
m_scratch_ast_context_ap.reset();
|
||||
m_scratch_ast_source_ap.reset();
|
||||
@@ -1307,7 +1308,8 @@ Target::ReadMemory (const Address& addr,
|
||||
Address resolved_addr;
|
||||
if (!addr.IsSectionOffset())
|
||||
{
|
||||
if (m_section_load_list.IsEmpty())
|
||||
SectionLoadList §ion_load_list = GetSectionLoadList();
|
||||
if (section_load_list.IsEmpty())
|
||||
{
|
||||
// No sections are loaded, so we must assume we are not running
|
||||
// yet and anything we are given is a file address.
|
||||
@@ -1321,7 +1323,7 @@ Target::ReadMemory (const Address& addr,
|
||||
// or because we have have a live process that has sections loaded
|
||||
// through the dynamic loader
|
||||
load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its offset is the load address
|
||||
m_section_load_list.ResolveLoadAddress (load_addr, resolved_addr);
|
||||
section_load_list.ResolveLoadAddress (load_addr, resolved_addr);
|
||||
}
|
||||
}
|
||||
if (!resolved_addr.IsValid())
|
||||
@@ -1534,7 +1536,8 @@ Target::ReadPointerFromMemory (const Address& addr,
|
||||
addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
|
||||
if (pointer_vm_addr != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
if (m_section_load_list.IsEmpty())
|
||||
SectionLoadList §ion_load_list = GetSectionLoadList();
|
||||
if (section_load_list.IsEmpty())
|
||||
{
|
||||
// No sections are loaded, so we must assume we are not running
|
||||
// yet and anything we are given is a file address.
|
||||
@@ -1546,7 +1549,7 @@ Target::ReadPointerFromMemory (const Address& addr,
|
||||
// we have manually loaded some sections with "target modules load ..."
|
||||
// or because we have have a live process that has sections loaded
|
||||
// through the dynamic loader
|
||||
m_section_load_list.ResolveLoadAddress (pointer_vm_addr, pointer_addr);
|
||||
section_load_list.ResolveLoadAddress (pointer_vm_addr, pointer_addr);
|
||||
}
|
||||
// We weren't able to resolve the pointer value, so just return
|
||||
// an address with no section
|
||||
@@ -2259,6 +2262,61 @@ Target::Install (ProcessLaunchInfo *launch_info)
|
||||
return error;
|
||||
}
|
||||
|
||||
bool
|
||||
Target::ResolveLoadAddress (addr_t load_addr, Address &so_addr, uint32_t stop_id)
|
||||
{
|
||||
return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);
|
||||
}
|
||||
|
||||
bool
|
||||
Target::SetSectionLoadAddress (const SectionSP §ion_sp, addr_t new_section_load_addr, bool warn_multiple)
|
||||
{
|
||||
const addr_t old_section_load_addr = m_section_load_history.GetSectionLoadAddress (SectionLoadHistory::eStopIDNow, section_sp);
|
||||
if (old_section_load_addr != new_section_load_addr)
|
||||
{
|
||||
uint32_t stop_id = 0;
|
||||
ProcessSP process_sp(GetProcessSP());
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
else
|
||||
stop_id = m_section_load_history.GetLastStopID();
|
||||
if (m_section_load_history.SetSectionLoadAddress (stop_id, section_sp, new_section_load_addr, warn_multiple))
|
||||
return true; // Return true if the section load address was changed...
|
||||
}
|
||||
return false; // Return false to indicate nothing changed
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
Target::SetSectionUnloaded (const lldb::SectionSP §ion_sp)
|
||||
{
|
||||
uint32_t stop_id = 0;
|
||||
ProcessSP process_sp(GetProcessSP());
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
else
|
||||
stop_id = m_section_load_history.GetLastStopID();
|
||||
return m_section_load_history.SetSectionUnloaded (stop_id, section_sp);
|
||||
}
|
||||
|
||||
bool
|
||||
Target::SetSectionUnloaded (const lldb::SectionSP §ion_sp, addr_t load_addr)
|
||||
{
|
||||
uint32_t stop_id = 0;
|
||||
ProcessSP process_sp(GetProcessSP());
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
else
|
||||
stop_id = m_section_load_history.GetLastStopID();
|
||||
return m_section_load_history.SetSectionUnloaded (stop_id, section_sp, load_addr);
|
||||
}
|
||||
|
||||
void
|
||||
Target::ClearAllLoadedSections ()
|
||||
{
|
||||
m_section_load_history.Clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Target::StopHook
|
||||
//--------------------------------------------------------------
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
Reference in New Issue
Block a user