1254721Semaste//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-private.h"
11254721Semaste#include "lldb/Target/DynamicLoader.h"
12254721Semaste#include "lldb/Target/Process.h"
13269024Semaste#include "lldb/Target/Target.h"
14254721Semaste#include "lldb/Core/PluginManager.h"
15269024Semaste#include "lldb/Core/Module.h"
16269024Semaste#include "lldb/Core/ModuleSpec.h"
17269024Semaste#include "lldb/Core/Section.h"
18254721Semaste
19254721Semasteusing namespace lldb;
20254721Semasteusing namespace lldb_private;
21254721Semaste
22254721SemasteDynamicLoader*
23254721SemasteDynamicLoader::FindPlugin (Process *process, const char *plugin_name)
24254721Semaste{
25254721Semaste    DynamicLoaderCreateInstance create_callback = NULL;
26254721Semaste    if (plugin_name)
27254721Semaste    {
28254721Semaste        ConstString const_plugin_name(plugin_name);
29254721Semaste        create_callback  = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
30254721Semaste        if (create_callback)
31254721Semaste        {
32254721Semaste            std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
33254721Semaste            if (instance_ap.get())
34254721Semaste                return instance_ap.release();
35254721Semaste        }
36254721Semaste    }
37254721Semaste    else
38254721Semaste    {
39254721Semaste        for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
40254721Semaste        {
41254721Semaste            std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
42254721Semaste            if (instance_ap.get())
43254721Semaste                return instance_ap.release();
44254721Semaste        }
45254721Semaste    }
46254721Semaste    return NULL;
47254721Semaste}
48254721Semaste
49254721Semaste
50254721Semaste//----------------------------------------------------------------------
51254721Semaste// DynamicLoader constructor
52254721Semaste//----------------------------------------------------------------------
53254721SemasteDynamicLoader::DynamicLoader(Process *process) :
54254721Semaste    m_process (process)
55254721Semaste{
56254721Semaste}
57254721Semaste
58254721Semaste//----------------------------------------------------------------------
59254721Semaste// Destructor
60254721Semaste//----------------------------------------------------------------------
61254721SemasteDynamicLoader::~DynamicLoader()
62254721Semaste{
63254721Semaste}
64254721Semaste
65254721Semaste//----------------------------------------------------------------------
66254721Semaste// Accessosors to the global setting as to whether to stop at image
67254721Semaste// (shared library) loading/unloading.
68254721Semaste//----------------------------------------------------------------------
69254721Semastebool
70254721SemasteDynamicLoader::GetStopWhenImagesChange () const
71254721Semaste{
72254721Semaste    return m_process->GetStopOnSharedLibraryEvents();
73254721Semaste}
74254721Semaste
75254721Semastevoid
76254721SemasteDynamicLoader::SetStopWhenImagesChange (bool stop)
77254721Semaste{
78254721Semaste    m_process->SetStopOnSharedLibraryEvents (stop);
79254721Semaste}
80254721Semaste
81269024SemasteModuleSP
82269024SemasteDynamicLoader::GetTargetExecutable()
83269024Semaste{
84269024Semaste    Target &target = m_process->GetTarget();
85269024Semaste    ModuleSP executable = target.GetExecutableModule();
86269024Semaste
87269024Semaste    if (executable.get())
88269024Semaste    {
89269024Semaste        if (executable->GetFileSpec().Exists())
90269024Semaste        {
91269024Semaste            ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
92269024Semaste            ModuleSP module_sp (new Module (module_spec));
93269024Semaste
94269024Semaste            // Check if the executable has changed and set it to the target executable if they differ.
95269024Semaste            if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
96269024Semaste            {
97269024Semaste                if (module_sp->GetUUID() != executable->GetUUID())
98269024Semaste                    executable.reset();
99269024Semaste            }
100269024Semaste            else if (executable->FileHasChanged())
101269024Semaste            {
102269024Semaste                executable.reset();
103269024Semaste            }
104269024Semaste
105269024Semaste            if (!executable.get())
106269024Semaste            {
107269024Semaste                executable = target.GetSharedModule(module_spec);
108269024Semaste                if (executable.get() != target.GetExecutableModulePointer())
109269024Semaste                {
110269024Semaste                    // Don't load dependent images since we are in dyld where we will know
111269024Semaste                    // and find out about all images that are loaded
112269024Semaste                    const bool get_dependent_images = false;
113269024Semaste                    target.SetExecutableModule(executable, get_dependent_images);
114269024Semaste                }
115269024Semaste            }
116269024Semaste        }
117269024Semaste    }
118269024Semaste    return executable;
119269024Semaste}
120269024Semaste
121269024Semastevoid
122269024SemasteDynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
123269024Semaste{
124269024Semaste    UpdateLoadedSectionsCommon(module, base_addr);
125269024Semaste}
126269024Semaste
127269024Semastevoid
128269024SemasteDynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr)
129269024Semaste{
130269024Semaste    bool changed;
131269024Semaste    const bool base_addr_is_offset = true;
132269024Semaste    module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
133269024Semaste}
134269024Semaste
135269024Semastevoid
136269024SemasteDynamicLoader::UnloadSections(const ModuleSP module)
137269024Semaste{
138269024Semaste    UnloadSectionsCommon(module);
139269024Semaste}
140269024Semaste
141269024Semastevoid
142269024SemasteDynamicLoader::UnloadSectionsCommon(const ModuleSP module)
143269024Semaste{
144269024Semaste    Target &target = m_process->GetTarget();
145269024Semaste    const SectionList *sections = GetSectionListFromModule(module);
146269024Semaste
147269024Semaste    assert(sections && "SectionList missing from unloaded module.");
148269024Semaste
149269024Semaste    const size_t num_sections = sections->GetSize();
150269024Semaste    for (size_t i = 0; i < num_sections; ++i)
151269024Semaste    {
152269024Semaste        SectionSP section_sp (sections->GetSectionAtIndex(i));
153269024Semaste        target.SetSectionUnloaded(section_sp);
154269024Semaste    }
155269024Semaste}
156269024Semaste
157269024Semaste
158269024Semasteconst SectionList *
159269024SemasteDynamicLoader::GetSectionListFromModule(const ModuleSP module) const
160269024Semaste{
161269024Semaste    SectionList *sections = nullptr;
162269024Semaste    if (module.get())
163269024Semaste    {
164269024Semaste        ObjectFile *obj_file = module->GetObjectFile();
165269024Semaste        if (obj_file)
166269024Semaste        {
167269024Semaste            sections = obj_file->GetSectionList();
168269024Semaste        }
169269024Semaste    }
170269024Semaste    return sections;
171269024Semaste}
172269024Semaste
173269024SemasteModuleSP
174269024SemasteDynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
175269024Semaste{
176269024Semaste    Target &target = m_process->GetTarget();
177269024Semaste    ModuleList &modules = target.GetImages();
178269024Semaste    ModuleSP module_sp;
179269024Semaste
180269024Semaste    ModuleSpec module_spec (file, target.GetArchitecture());
181269024Semaste    if ((module_sp = modules.FindFirstModule (module_spec)))
182269024Semaste    {
183269024Semaste        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
184269024Semaste    }
185269024Semaste    else if ((module_sp = target.GetSharedModule(module_spec)))
186269024Semaste    {
187269024Semaste        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
188269024Semaste    }
189269024Semaste
190269024Semaste    return module_sp;
191269024Semaste}
192269024Semaste
193269024Semasteint64_t
194269024SemasteDynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
195269024Semaste{
196269024Semaste    Error error;
197269024Semaste
198269024Semaste    uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
199269024Semaste    if (error.Fail())
200269024Semaste        return -1;
201269024Semaste    else
202269024Semaste        return (int64_t)value;
203269024Semaste}
204269024Semaste
205269024Semasteaddr_t
206269024SemasteDynamicLoader::ReadPointer(addr_t addr)
207269024Semaste{
208269024Semaste    Error error;
209269024Semaste    addr_t value = m_process->ReadPointerFromMemory(addr, error);
210269024Semaste    if (error.Fail())
211269024Semaste        return LLDB_INVALID_ADDRESS;
212269024Semaste    else
213269024Semaste        return value;
214269024Semaste}
215