DynamicLoader.cpp revision 269024
1//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-private.h"
11#include "lldb/Target/DynamicLoader.h"
12#include "lldb/Target/Process.h"
13#include "lldb/Target/Target.h"
14#include "lldb/Core/PluginManager.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
17#include "lldb/Core/Section.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22DynamicLoader*
23DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
24{
25    DynamicLoaderCreateInstance create_callback = NULL;
26    if (plugin_name)
27    {
28        ConstString const_plugin_name(plugin_name);
29        create_callback  = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
30        if (create_callback)
31        {
32            std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
33            if (instance_ap.get())
34                return instance_ap.release();
35        }
36    }
37    else
38    {
39        for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
40        {
41            std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
42            if (instance_ap.get())
43                return instance_ap.release();
44        }
45    }
46    return NULL;
47}
48
49
50//----------------------------------------------------------------------
51// DynamicLoader constructor
52//----------------------------------------------------------------------
53DynamicLoader::DynamicLoader(Process *process) :
54    m_process (process)
55{
56}
57
58//----------------------------------------------------------------------
59// Destructor
60//----------------------------------------------------------------------
61DynamicLoader::~DynamicLoader()
62{
63}
64
65//----------------------------------------------------------------------
66// Accessosors to the global setting as to whether to stop at image
67// (shared library) loading/unloading.
68//----------------------------------------------------------------------
69bool
70DynamicLoader::GetStopWhenImagesChange () const
71{
72    return m_process->GetStopOnSharedLibraryEvents();
73}
74
75void
76DynamicLoader::SetStopWhenImagesChange (bool stop)
77{
78    m_process->SetStopOnSharedLibraryEvents (stop);
79}
80
81ModuleSP
82DynamicLoader::GetTargetExecutable()
83{
84    Target &target = m_process->GetTarget();
85    ModuleSP executable = target.GetExecutableModule();
86
87    if (executable.get())
88    {
89        if (executable->GetFileSpec().Exists())
90        {
91            ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
92            ModuleSP module_sp (new Module (module_spec));
93
94            // Check if the executable has changed and set it to the target executable if they differ.
95            if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
96            {
97                if (module_sp->GetUUID() != executable->GetUUID())
98                    executable.reset();
99            }
100            else if (executable->FileHasChanged())
101            {
102                executable.reset();
103            }
104
105            if (!executable.get())
106            {
107                executable = target.GetSharedModule(module_spec);
108                if (executable.get() != target.GetExecutableModulePointer())
109                {
110                    // Don't load dependent images since we are in dyld where we will know
111                    // and find out about all images that are loaded
112                    const bool get_dependent_images = false;
113                    target.SetExecutableModule(executable, get_dependent_images);
114                }
115            }
116        }
117    }
118    return executable;
119}
120
121void
122DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
123{
124    UpdateLoadedSectionsCommon(module, base_addr);
125}
126
127void
128DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr)
129{
130    bool changed;
131    const bool base_addr_is_offset = true;
132    module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
133}
134
135void
136DynamicLoader::UnloadSections(const ModuleSP module)
137{
138    UnloadSectionsCommon(module);
139}
140
141void
142DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
143{
144    Target &target = m_process->GetTarget();
145    const SectionList *sections = GetSectionListFromModule(module);
146
147    assert(sections && "SectionList missing from unloaded module.");
148
149    const size_t num_sections = sections->GetSize();
150    for (size_t i = 0; i < num_sections; ++i)
151    {
152        SectionSP section_sp (sections->GetSectionAtIndex(i));
153        target.SetSectionUnloaded(section_sp);
154    }
155}
156
157
158const SectionList *
159DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
160{
161    SectionList *sections = nullptr;
162    if (module.get())
163    {
164        ObjectFile *obj_file = module->GetObjectFile();
165        if (obj_file)
166        {
167            sections = obj_file->GetSectionList();
168        }
169    }
170    return sections;
171}
172
173ModuleSP
174DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
175{
176    Target &target = m_process->GetTarget();
177    ModuleList &modules = target.GetImages();
178    ModuleSP module_sp;
179
180    ModuleSpec module_spec (file, target.GetArchitecture());
181    if ((module_sp = modules.FindFirstModule (module_spec)))
182    {
183        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
184    }
185    else if ((module_sp = target.GetSharedModule(module_spec)))
186    {
187        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
188    }
189
190    return module_sp;
191}
192
193int64_t
194DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
195{
196    Error error;
197
198    uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
199    if (error.Fail())
200        return -1;
201    else
202        return (int64_t)value;
203}
204
205addr_t
206DynamicLoader::ReadPointer(addr_t addr)
207{
208    Error error;
209    addr_t value = m_process->ReadPointerFromMemory(addr, error);
210    if (error.Fail())
211        return LLDB_INVALID_ADDRESS;
212    else
213        return value;
214}
215