diff options
| author | Ed Maste <emaste@FreeBSD.org> | 2013-11-12 17:25:33 +0000 |
|---|---|---|
| committer | Ed Maste <emaste@FreeBSD.org> | 2013-11-12 17:25:33 +0000 |
| commit | 3561791104e5399ef9bcd45b3be0755dcde3464d (patch) | |
| tree | b9aa1d1064fb25a0f2313d9a7964c862c0b7b354 /contrib/llvm/tools/lldb/source/Plugins/DynamicLoader | |
| parent | 43a3230ade8b170222e4d0378c40afa93908d2aa (diff) | |
| parent | f21a844f60ae6c74fcf1fddca32461acce3c1ee0 (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/DynamicLoader')
5 files changed, 295 insertions, 43 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp index 2604ae670164..c079d0fc381f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp @@ -19,7 +19,7 @@ #include "lldb/Core/Log.h" #include "lldb/Target/Process.h" -#if defined(__linux__) or defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) #include "Plugins/Process/elf-core/ProcessElfCore.h" #endif @@ -57,7 +57,7 @@ ParseAuxvEntry(DataExtractor &data, DataBufferSP AuxVector::GetAuxvData() { -#if defined(__linux__) or defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) return static_cast<ProcessElfCore *>(m_process)->GetAuxvData(); #endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 3e1b52938f49..3c5dcc5222af 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -30,17 +31,14 @@ ResolveRendezvousAddress(Process *process) addr_t info_location; addr_t info_addr; Error error; - size_t size; info_location = process->GetImageInfoAddress(); if (info_location == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; - info_addr = 0; - size = process->DoReadMemory(info_location, &info_addr, - process->GetAddressByteSize(), error); - if (size != process->GetAddressByteSize() || error.Fail()) + info_addr = process->ReadPointerFromMemory(info_location, error); + if (error.Fail()) return LLDB_INVALID_ADDRESS; if (info_addr == 0) @@ -58,6 +56,8 @@ DYLDRendezvous::DYLDRendezvous(Process *process) m_added_soentries(), m_removed_soentries() { + m_thread_info.valid = false; + // Cache a copy of the executable path if (m_process) { @@ -88,19 +88,19 @@ DYLDRendezvous::Resolve() if (cursor == LLDB_INVALID_ADDRESS) return false; - if (!(cursor = ReadMemory(cursor, &info.version, word_size))) + if (!(cursor = ReadWord(cursor, &info.version, word_size))) return false; - if (!(cursor = ReadMemory(cursor + padding, &info.map_addr, address_size))) + if (!(cursor = ReadPointer(cursor + padding, &info.map_addr))) return false; - if (!(cursor = ReadMemory(cursor, &info.brk, address_size))) + if (!(cursor = ReadPointer(cursor, &info.brk))) return false; - if (!(cursor = ReadMemory(cursor, &info.state, word_size))) + if (!(cursor = ReadWord(cursor, &info.state, word_size))) return false; - if (!(cursor = ReadMemory(cursor + padding, &info.ldbase, address_size))) + if (!(cursor = ReadPointer(cursor + padding, &info.ldbase))) return false; // The rendezvous was successfully read. Update our internal state. @@ -234,16 +234,27 @@ DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) } addr_t -DYLDRendezvous::ReadMemory(addr_t addr, void *dst, size_t size) +DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size) { - size_t bytes_read; Error error; - bytes_read = m_process->DoReadMemory(addr, dst, size, error); - if (bytes_read != size || error.Fail()) + *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error); + if (error.Fail()) return 0; - return addr + bytes_read; + return addr + size; +} + +addr_t +DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) +{ + Error error; + + *dst = m_process->ReadPointerFromMemory(addr, error); + if (error.Fail()) + return 0; + + return addr + m_process->GetAddressByteSize(); } std::string @@ -275,23 +286,38 @@ DYLDRendezvous::ReadStringFromMemory(addr_t addr) bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { - size_t address_size = m_process->GetAddressByteSize(); - entry.clear(); + + entry.link_addr = addr; - if (!(addr = ReadMemory(addr, &entry.base_addr, address_size))) + if (!(addr = ReadPointer(addr, &entry.base_addr))) return false; + + // mips adds an extra load offset field to the link map struct on + // FreeBSD and NetBSD (need to validate other OSes). + // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57 + const ArchSpec &arch = m_process->GetTarget().GetArchitecture(); + if (arch.GetCore() == ArchSpec::eCore_mips64) + { + assert (arch.GetTriple().getOS() == llvm::Triple::FreeBSD || + arch.GetTriple().getOS() == llvm::Triple::NetBSD); + addr_t mips_l_offs; + if (!(addr = ReadPointer(addr, &mips_l_offs))) + return false; + if (mips_l_offs != 0 && mips_l_offs != entry.base_addr) + return false; + } - if (!(addr = ReadMemory(addr, &entry.path_addr, address_size))) + if (!(addr = ReadPointer(addr, &entry.path_addr))) return false; - if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size))) + if (!(addr = ReadPointer(addr, &entry.dyn_addr))) return false; - if (!(addr = ReadMemory(addr, &entry.next, address_size))) + if (!(addr = ReadPointer(addr, &entry.next))) return false; - if (!(addr = ReadMemory(addr, &entry.prev, address_size))) + if (!(addr = ReadPointer(addr, &entry.prev))) return false; entry.path = ReadStringFromMemory(entry.path_addr); @@ -299,6 +325,51 @@ DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) return true; } + +bool +DYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value) +{ + Target& target = m_process->GetTarget(); + + SymbolContextList list; + if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list)) + return false; + + Address address = list[0].symbol->GetAddress(); + addr_t addr = address.GetLoadAddress (&target); + if (addr == LLDB_INVALID_ADDRESS) + return false; + + Error error; + value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error); + if (error.Fail()) + return false; + + if (field == eSize) + value /= 8; // convert bits to bytes + + return true; +} + +const DYLDRendezvous::ThreadInfo& +DYLDRendezvous::GetThreadInfo() +{ + if (!m_thread_info.valid) + { + bool ok = true; + + ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset); + ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size); + ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset); + ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset); + + if (ok) + m_thread_info.valid = true; + } + + return m_thread_info; +} + void DYLDRendezvous::DumpToLog(Log *log) const { diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index 67e7228a38de..ca0089317998 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -48,6 +48,16 @@ class DYLDRendezvous { }; public: + // Various metadata supplied by the inferior's threading library to describe + // the per-thread state. + struct ThreadInfo { + bool valid; // whether we read valid metadata + uint32_t dtv_offset; // offset of DTV pointer within pthread + uint32_t dtv_slot_size; // size of one DTV slot + uint32_t modid_offset; // offset of module ID within link_map + uint32_t tls_offset; // offset of TLS pointer within DTV slot + }; + DYLDRendezvous(lldb_private::Process *process); /// Update the internal snapshot of runtime linker rendezvous and recompute @@ -100,6 +110,10 @@ public: lldb::addr_t GetLDBase() const { return m_current.ldbase; } + /// @returns the thread layout metadata from the inferiors thread library. + const ThreadInfo& + GetThreadInfo(); + /// @returns true if modules have been loaded into the inferior since the /// last call to Resolve(). bool @@ -128,6 +142,7 @@ public: /// This object is a rough analogue to the struct link_map object which /// actually lives in the inferiors memory. struct SOEntry { + lldb::addr_t link_addr; ///< Address of this link_map. lldb::addr_t base_addr; ///< Base address of the loaded object. lldb::addr_t path_addr; ///< String naming the shared object. lldb::addr_t dyn_addr; ///< Dynamic section of shared object. @@ -142,6 +157,7 @@ public: } void clear() { + link_addr = 0; base_addr = 0; path_addr = 0; dyn_addr = 0; @@ -194,12 +210,22 @@ protected: /// Resolve(). SOEntryList m_removed_soentries; - /// Reads @p size bytes from the inferiors address space starting at @p - /// addr. + /// Threading metadata read from the inferior. + ThreadInfo m_thread_info; + + /// Reads an unsigned integer of @p size bytes from the inferior's address + /// space starting at @p addr. /// /// @returns addr + size if the read was successful and false otherwise. lldb::addr_t - ReadMemory(lldb::addr_t addr, void *dst, size_t size); + ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size); + + /// Reads an address from the inferior's address space starting at @p addr. + /// + /// @returns addr + target address size if the read was successful and + /// 0 otherwise. + lldb::addr_t + ReadPointer(lldb::addr_t addr, lldb::addr_t *dst); /// Reads a null-terminated C string from the memory location starting at @p /// addr. @@ -225,6 +251,10 @@ protected: /// supplied by the runtime linker. bool TakeSnapshot(SOEntryList &entry_list); + + enum PThreadField { eSize, eNElem, eOffset }; + + bool FindMetadata(const char *name, PThreadField field, uint32_t& value); }; #endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 91c7cd3dfca7..4284558c4409 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -123,7 +123,7 @@ DynamicLoaderPOSIXDYLD::DidAttach() { ModuleList module_list; module_list.Append(executable); - UpdateLoadedSections(executable, load_offset); + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset); LoadAllCurrentModules(); m_process->GetTarget().ModulesDidLoad(module_list); } @@ -144,7 +144,7 @@ DynamicLoaderPOSIXDYLD::DidLaunch() { ModuleList module_list; module_list.Append(executable); - UpdateLoadedSections(executable, load_offset); + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset); ProbeEntry(); m_process->GetTarget().ModulesDidLoad(module_list); } @@ -209,11 +209,15 @@ DynamicLoaderPOSIXDYLD::CanLoadImage() } void -DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t base_addr) +DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) { - ObjectFile *obj_file = module->GetObjectFile(); - SectionList *sections = obj_file->GetSectionList(); SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList(); + const SectionList *sections = GetSectionListFromModule(module); + + assert(sections && "SectionList missing from loaded module."); + + m_loaded_modules[module] = link_map_addr; + const size_t num_sections = sections->GetSize(); for (unsigned i = 0; i < num_sections; ++i) @@ -234,6 +238,24 @@ DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t base_addr) } void +DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) +{ + SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList(); + const SectionList *sections = GetSectionListFromModule(module); + + assert(sections && "SectionList missing from unloaded module."); + + m_loaded_modules.erase(module); + + const size_t num_sections = sections->GetSize(); + for (size_t i = 0; i < num_sections; ++i) + { + SectionSP section_sp (sections->GetSectionAtIndex(i)); + load_list.SetSectionUnloaded(section_sp); + } +} + +void DynamicLoaderPOSIXDYLD::ProbeEntry() { Breakpoint *entry_break; @@ -242,7 +264,7 @@ DynamicLoaderPOSIXDYLD::ProbeEntry() if ((entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS) return; - entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get(); + entry_break = m_process->GetTarget().CreateBreakpoint(entry, true, false).get(); entry_break->SetCallback(EntryBreakpointHit, this, true); entry_break->SetBreakpointKind("shared-library-event"); } @@ -275,7 +297,7 @@ DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() if (m_dyld_bid == LLDB_INVALID_BREAK_ID) { - Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true).get(); + Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true, false).get(); dyld_break->SetCallback(RendezvousBreakpointHit, this, true); dyld_break->SetBreakpointKind ("shared-library-event"); m_dyld_bid = dyld_break->GetID(); @@ -319,10 +341,14 @@ DynamicLoaderPOSIXDYLD::RefreshModules() for (I = m_rendezvous.loaded_begin(); I != E; ++I) { FileSpec file(I->path.c_str(), true); - ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); if (module_sp.get()) + { loaded_modules.AppendIfNeeded(module_sp); + new_modules.Append(module_sp); + } } + m_process->GetTarget().ModulesDidLoad(new_modules); } if (m_rendezvous.ModulesDidUnload()) @@ -336,10 +362,15 @@ DynamicLoaderPOSIXDYLD::RefreshModules() ModuleSpec module_spec (file); ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec); + if (module_sp.get()) + { old_modules.Append(module_sp); + UnloadSections(module_sp); + } } loaded_modules.Remove(old_modules); + m_process->GetTarget().ModulesDidUnload(old_modules, false); } } @@ -404,21 +435,43 @@ DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() ModuleList module_list; if (!m_rendezvous.Resolve()) + { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD rendezvous address", + __FUNCTION__); return; + } + + // The rendezvous class doesn't enumerate the main module, so track + // that ourselves here. + ModuleSP executable = GetTargetExecutable(); + m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); + for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { - FileSpec file(I->path.c_str(), false); - ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr); + const char *module_path = I->path.c_str(); + FileSpec file(module_path, false); + ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); if (module_sp.get()) + { module_list.Append(module_sp); + } + else + { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, + __FUNCTION__, module_path, I->base_addr); + } } m_process->GetTarget().ModulesDidLoad(module_list); } ModuleSP -DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t base_addr) +DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) { Target &target = m_process->GetTarget(); ModuleList &modules = target.GetImages(); @@ -427,11 +480,11 @@ DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t base_ad ModuleSpec module_spec (file, target.GetArchitecture()); if ((module_sp = modules.FindFirstModule (module_spec))) { - UpdateLoadedSections(module_sp, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr); } else if ((module_sp = target.GetSharedModule(module_spec))) { - UpdateLoadedSections(module_sp, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr); } return module_sp; @@ -479,3 +532,83 @@ DynamicLoaderPOSIXDYLD::GetEntryPoint() m_entry_point = static_cast<addr_t>(I->value); return m_entry_point; } + +const SectionList * +DynamicLoaderPOSIXDYLD::GetSectionListFromModule(const ModuleSP module) const +{ + SectionList *sections = nullptr; + if (module.get()) + { + ObjectFile *obj_file = module->GetObjectFile(); + if (obj_file) + { + sections = obj_file->GetSectionList(); + } + } + return sections; +} + +static int ReadInt(Process *process, addr_t addr) +{ + Error error; + int value = (int)process->ReadUnsignedIntegerFromMemory(addr, sizeof(uint32_t), 0, error); + if (error.Fail()) + return -1; + else + return value; +} + +static addr_t ReadPointer(Process *process, addr_t addr) +{ + Error error; + addr_t value = process->ReadPointerFromMemory(addr, error); + if (error.Fail()) + return LLDB_INVALID_ADDRESS; + else + return value; +} + +lldb::addr_t +DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread) +{ + auto it = m_loaded_modules.find (module); + if (it == m_loaded_modules.end()) + return LLDB_INVALID_ADDRESS; + + addr_t link_map = it->second; + if (link_map == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + + const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo(); + if (!metadata.valid) + return LLDB_INVALID_ADDRESS; + + // Get the thread pointer. + addr_t tp = thread->GetThreadPointer (); + if (tp == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + + // Find the module's modid. + int modid = ReadInt (m_process, link_map + metadata.modid_offset); + if (modid == -1) + return LLDB_INVALID_ADDRESS; + + // Lookup the DTV stucture for this thread. + addr_t dtv_ptr = tp + metadata.dtv_offset; + addr_t dtv = ReadPointer (m_process, dtv_ptr); + if (dtv == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + + // Find the TLS block for this module. + addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid; + addr_t tls_block = ReadPointer (m_process, dtv_slot + metadata.tls_offset); + + Module *mod = module.get(); + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: " + "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%i, tls_block=0x%" PRIx64 "\n", + mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block); + + return tls_block; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h index 0476e45d0465..7997b34195a4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -61,6 +61,9 @@ public: virtual lldb_private::Error CanLoadImage(); + virtual lldb::addr_t + GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -95,6 +98,9 @@ protected: /// Rendezvous breakpoint. lldb::break_id_t m_dyld_bid; + /// Loaded module list. (link map for each module) + std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules; + /// Enables a breakpoint on a function called by the runtime /// linker each time a module is loaded or unloaded. void @@ -117,15 +123,24 @@ protected: /// /// @param module The module to traverse. /// + /// @param link_map_addr The virtual address of the link map for the @p module. + /// /// @param base_addr The virtual base address @p module is loaded at. void - UpdateLoadedSections(lldb::ModuleSP module, - lldb::addr_t base_addr = 0); + UpdateLoadedSections(lldb::ModuleSP module, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr); + + /// Removes the loaded sections from the target in @p module. + /// + /// @param module The module to traverse. + void + UnloadSections(const lldb::ModuleSP module); /// Locates or creates a module given by @p file and updates/loads the /// resulting module at the virtual base address @p base_addr. lldb::ModuleSP - LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t base_addr); + LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr); /// Resolves the entry point for the current inferior process and sets a /// breakpoint at that address. @@ -165,6 +180,9 @@ protected: private: DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD); + + const lldb_private::SectionList * + GetSectionListFromModule(const lldb::ModuleSP module) const; }; #endif // liblldb_DynamicLoaderPOSIXDYLD_H_ |
