1//===-- DynamicLoaderStatic.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/Core/Module.h"
11#include "lldb/Core/PluginManager.h"
12#include "lldb/Core/Section.h"
13#include "lldb/Symbol/ObjectFile.h"
14#include "lldb/Target/Target.h"
15
16#include "DynamicLoaderStatic.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21//----------------------------------------------------------------------
22// Create an instance of this class. This function is filled into
23// the plugin info class that gets handed out by the plugin factory and
24// allows the lldb to instantiate an instance of this class.
25//----------------------------------------------------------------------
26DynamicLoader *
27DynamicLoaderStatic::CreateInstance (Process* process, bool force)
28{
29    bool create = force;
30    if (!create)
31    {
32        const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
33        const llvm::Triple::OSType os_type = triple_ref.getOS();
34        if ((os_type == llvm::Triple::UnknownOS))
35            create = true;
36    }
37
38    if (!create)
39    {
40        Module *exe_module = process->GetTarget().GetExecutableModulePointer();
41        if (exe_module)
42        {
43            ObjectFile *object_file = exe_module->GetObjectFile();
44            if (object_file)
45            {
46                create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
47            }
48        }
49    }
50
51    if (create)
52        return new DynamicLoaderStatic (process);
53    return NULL;
54}
55
56//----------------------------------------------------------------------
57// Constructor
58//----------------------------------------------------------------------
59DynamicLoaderStatic::DynamicLoaderStatic (Process* process) :
60    DynamicLoader(process)
61{
62}
63
64//----------------------------------------------------------------------
65// Destructor
66//----------------------------------------------------------------------
67DynamicLoaderStatic::~DynamicLoaderStatic()
68{
69}
70
71//------------------------------------------------------------------
72/// Called after attaching a process.
73///
74/// Allow DynamicLoader plug-ins to execute some code after
75/// attaching to a process.
76//------------------------------------------------------------------
77void
78DynamicLoaderStatic::DidAttach ()
79{
80    LoadAllImagesAtFileAddresses();
81}
82
83//------------------------------------------------------------------
84/// Called after attaching a process.
85///
86/// Allow DynamicLoader plug-ins to execute some code after
87/// attaching to a process.
88//------------------------------------------------------------------
89void
90DynamicLoaderStatic::DidLaunch ()
91{
92    LoadAllImagesAtFileAddresses();
93}
94
95void
96DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
97{
98    const ModuleList &module_list = m_process->GetTarget().GetImages();
99
100    ModuleList loaded_module_list;
101
102    // Disable JIT for static dynamic loader targets
103    m_process->SetCanJIT(false);
104
105    Mutex::Locker mutex_locker(module_list.GetMutex());
106
107    const size_t num_modules = module_list.GetSize();
108    for (uint32_t idx = 0; idx < num_modules; ++idx)
109    {
110        ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (idx));
111        if (module_sp)
112        {
113            bool changed = false;
114            ObjectFile *image_object_file = module_sp->GetObjectFile();
115            if (image_object_file)
116            {
117                SectionList *section_list = image_object_file->GetSectionList ();
118                if (section_list)
119                {
120                    // All sections listed in the dyld image info structure will all
121                    // either be fixed up already, or they will all be off by a single
122                    // slide amount that is determined by finding the first segment
123                    // that is at file offset zero which also has bytes (a file size
124                    // that is greater than zero) in the object file.
125
126                    // Determine the slide amount (if any)
127                    const size_t num_sections = section_list->GetSize();
128                    size_t sect_idx = 0;
129                    for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
130                    {
131                        // Iterate through the object file sections to find the
132                        // first section that starts of file offset zero and that
133                        // has bytes in the file...
134                        SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
135                        if (section_sp)
136                        {
137                            if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress()))
138                                changed = true;
139                        }
140                    }
141                }
142            }
143
144            if (changed)
145                loaded_module_list.AppendIfNeeded (module_sp);
146        }
147    }
148
149    m_process->GetTarget().ModulesDidLoad (loaded_module_list);
150}
151
152ThreadPlanSP
153DynamicLoaderStatic::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
154{
155    return ThreadPlanSP();
156}
157
158Error
159DynamicLoaderStatic::CanLoadImage ()
160{
161    Error error;
162    error.SetErrorString ("can't load images on with a static debug session");
163    return error;
164}
165
166void
167DynamicLoaderStatic::Initialize()
168{
169    PluginManager::RegisterPlugin (GetPluginNameStatic(),
170                                   GetPluginDescriptionStatic(),
171                                   CreateInstance);
172}
173
174void
175DynamicLoaderStatic::Terminate()
176{
177    PluginManager::UnregisterPlugin (CreateInstance);
178}
179
180
181lldb_private::ConstString
182DynamicLoaderStatic::GetPluginNameStatic()
183{
184    static ConstString g_name("static");
185    return g_name;
186}
187
188const char *
189DynamicLoaderStatic::GetPluginDescriptionStatic()
190{
191    return "Dynamic loader plug-in that will load any images at the static addresses contained in each image.";
192}
193
194
195//------------------------------------------------------------------
196// PluginInterface protocol
197//------------------------------------------------------------------
198lldb_private::ConstString
199DynamicLoaderStatic::GetPluginName()
200{
201    return GetPluginNameStatic();
202}
203
204uint32_t
205DynamicLoaderStatic::GetPluginVersion()
206{
207    return 1;
208}
209
210