mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
ObjectFile::SetLoadAddress (Target &target,
lldb::addr_t value,
bool value_is_offset);
Now "value" is a slide if "value_is_offset" is true, and "value" is an image base address otherwise. All previous usage of this API was using slides.
Updated the ObjectFileELF and ObjectFileMachO SetLoadAddress methods to do the right thing.
Also updated the ObjectFileMachO::SetLoadAddress() function to not load __LINKEDIT when it isn't needed and to only load sections that belong to the executable object file.
llvm-svn: 201003
215 lines
6.2 KiB
C++
215 lines
6.2 KiB
C++
//===-- DynamicLoader.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/lldb-private.h"
|
|
#include "lldb/Target/DynamicLoader.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Core/PluginManager.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/ModuleSpec.h"
|
|
#include "lldb/Core/Section.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
DynamicLoader*
|
|
DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
|
|
{
|
|
DynamicLoaderCreateInstance create_callback = NULL;
|
|
if (plugin_name)
|
|
{
|
|
ConstString const_plugin_name(plugin_name);
|
|
create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
|
|
if (create_callback)
|
|
{
|
|
std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
|
|
if (instance_ap.get())
|
|
return instance_ap.release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
|
|
{
|
|
std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
|
|
if (instance_ap.get())
|
|
return instance_ap.release();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// DynamicLoader constructor
|
|
//----------------------------------------------------------------------
|
|
DynamicLoader::DynamicLoader(Process *process) :
|
|
m_process (process)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Destructor
|
|
//----------------------------------------------------------------------
|
|
DynamicLoader::~DynamicLoader()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Accessosors to the global setting as to whether to stop at image
|
|
// (shared library) loading/unloading.
|
|
//----------------------------------------------------------------------
|
|
bool
|
|
DynamicLoader::GetStopWhenImagesChange () const
|
|
{
|
|
return m_process->GetStopOnSharedLibraryEvents();
|
|
}
|
|
|
|
void
|
|
DynamicLoader::SetStopWhenImagesChange (bool stop)
|
|
{
|
|
m_process->SetStopOnSharedLibraryEvents (stop);
|
|
}
|
|
|
|
ModuleSP
|
|
DynamicLoader::GetTargetExecutable()
|
|
{
|
|
Target &target = m_process->GetTarget();
|
|
ModuleSP executable = target.GetExecutableModule();
|
|
|
|
if (executable.get())
|
|
{
|
|
if (executable->GetFileSpec().Exists())
|
|
{
|
|
ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
|
|
ModuleSP module_sp (new Module (module_spec));
|
|
|
|
// Check if the executable has changed and set it to the target executable if they differ.
|
|
if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
|
|
{
|
|
if (module_sp->GetUUID() != executable->GetUUID())
|
|
executable.reset();
|
|
}
|
|
else if (executable->FileHasChanged())
|
|
{
|
|
executable.reset();
|
|
}
|
|
|
|
if (!executable.get())
|
|
{
|
|
executable = target.GetSharedModule(module_spec);
|
|
if (executable.get() != target.GetExecutableModulePointer())
|
|
{
|
|
// Don't load dependent images since we are in dyld where we will know
|
|
// and find out about all images that are loaded
|
|
const bool get_dependent_images = false;
|
|
target.SetExecutableModule(executable, get_dependent_images);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return executable;
|
|
}
|
|
|
|
void
|
|
DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
|
|
{
|
|
UpdateLoadedSectionsCommon(module, base_addr);
|
|
}
|
|
|
|
void
|
|
DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr)
|
|
{
|
|
bool changed;
|
|
const bool base_addr_is_offset = true;
|
|
module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
|
|
}
|
|
|
|
void
|
|
DynamicLoader::UnloadSections(const ModuleSP module)
|
|
{
|
|
UnloadSectionsCommon(module);
|
|
}
|
|
|
|
void
|
|
DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
|
|
{
|
|
Target &target = m_process->GetTarget();
|
|
const SectionList *sections = GetSectionListFromModule(module);
|
|
|
|
assert(sections && "SectionList missing from unloaded module.");
|
|
|
|
const size_t num_sections = sections->GetSize();
|
|
for (size_t i = 0; i < num_sections; ++i)
|
|
{
|
|
SectionSP section_sp (sections->GetSectionAtIndex(i));
|
|
target.SetSectionUnloaded(section_sp);
|
|
}
|
|
}
|
|
|
|
|
|
const SectionList *
|
|
DynamicLoader::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;
|
|
}
|
|
|
|
ModuleSP
|
|
DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
|
|
{
|
|
Target &target = m_process->GetTarget();
|
|
ModuleList &modules = target.GetImages();
|
|
ModuleSP module_sp;
|
|
|
|
ModuleSpec module_spec (file, target.GetArchitecture());
|
|
if ((module_sp = modules.FindFirstModule (module_spec)))
|
|
{
|
|
UpdateLoadedSections(module_sp, link_map_addr, base_addr);
|
|
}
|
|
else if ((module_sp = target.GetSharedModule(module_spec)))
|
|
{
|
|
UpdateLoadedSections(module_sp, link_map_addr, base_addr);
|
|
}
|
|
|
|
return module_sp;
|
|
}
|
|
|
|
int64_t
|
|
DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
|
|
{
|
|
Error error;
|
|
|
|
uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
|
|
if (error.Fail())
|
|
return -1;
|
|
else
|
|
return (int64_t)value;
|
|
}
|
|
|
|
addr_t
|
|
DynamicLoader::ReadPointer(addr_t addr)
|
|
{
|
|
Error error;
|
|
addr_t value = m_process->ReadPointerFromMemory(addr, error);
|
|
if (error.Fail())
|
|
return LLDB_INVALID_ADDRESS;
|
|
else
|
|
return value;
|
|
}
|