1 //===-- SBModule.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/API/SBModule.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBSymbolContextList.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/StreamString.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/ValueObjectVariable.h"
20 #include "lldb/Symbol/SymbolVendor.h"
21 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Target/Target.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 
28 SBModule::SBModule () :
29     m_opaque_sp ()
30 {
31 }
32 
33 SBModule::SBModule (const lldb::ModuleSP& module_sp) :
34     m_opaque_sp (module_sp)
35 {
36 }
37 
38 SBModule::SBModule(const SBModule &rhs) :
39     m_opaque_sp (rhs.m_opaque_sp)
40 {
41 }
42 
43 const SBModule &
44 SBModule::operator = (const SBModule &rhs)
45 {
46     if (this != &rhs)
47         m_opaque_sp = rhs.m_opaque_sp;
48     return *this;
49 }
50 
51 SBModule::~SBModule ()
52 {
53 }
54 
55 bool
56 SBModule::IsValid () const
57 {
58     return m_opaque_sp.get() != NULL;
59 }
60 
61 SBFileSpec
62 SBModule::GetFileSpec () const
63 {
64     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
65 
66     SBFileSpec file_spec;
67     if (m_opaque_sp)
68         file_spec.SetFileSpec(m_opaque_sp->GetFileSpec());
69 
70     if (log)
71     {
72         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
73         m_opaque_sp.get(), file_spec.get());
74     }
75 
76     return file_spec;
77 }
78 
79 lldb::SBFileSpec
80 SBModule::GetPlatformFileSpec () const
81 {
82     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
83 
84     SBFileSpec file_spec;
85     if (m_opaque_sp)
86         file_spec.SetFileSpec(m_opaque_sp->GetPlatformFileSpec());
87 
88     if (log)
89     {
90         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
91                      m_opaque_sp.get(), file_spec.get());
92     }
93 
94     return file_spec;
95 
96 }
97 
98 bool
99 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
100 {
101     bool result = false;
102     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
103 
104     if (m_opaque_sp)
105     {
106         m_opaque_sp->SetPlatformFileSpec(*platform_file);
107         result = true;
108     }
109 
110     if (log)
111     {
112         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
113                      m_opaque_sp.get(),
114                      platform_file.get(),
115                      platform_file->GetDirectory().GetCString(),
116                      platform_file->GetDirectory() ? "/" : "",
117                      platform_file->GetFilename().GetCString(),
118                      result);
119     }
120     return result;
121 }
122 
123 
124 
125 const uint8_t *
126 SBModule::GetUUIDBytes () const
127 {
128     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
129 
130     const uint8_t *uuid_bytes = NULL;
131     if (m_opaque_sp)
132         uuid_bytes = (const uint8_t *)m_opaque_sp->GetUUID().GetBytes();
133 
134     if (log)
135     {
136         if (uuid_bytes)
137         {
138             StreamString s;
139             m_opaque_sp->GetUUID().Dump (&s);
140             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", m_opaque_sp.get(), s.GetData());
141         }
142         else
143             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", m_opaque_sp.get());
144     }
145     return uuid_bytes;
146 }
147 
148 
149 const char *
150 SBModule::GetUUIDString () const
151 {
152     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
153 
154     static char uuid_string[80];
155     const char * uuid_c_string = NULL;
156     if (m_opaque_sp)
157         uuid_c_string = (const char *)m_opaque_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string));
158 
159     if (log)
160     {
161         if (uuid_c_string)
162         {
163             StreamString s;
164             m_opaque_sp->GetUUID().Dump (&s);
165             log->Printf ("SBModule(%p)::GetUUIDString () => %s", m_opaque_sp.get(), s.GetData());
166         }
167         else
168             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", m_opaque_sp.get());
169     }
170     return uuid_c_string;
171 }
172 
173 
174 bool
175 SBModule::operator == (const SBModule &rhs) const
176 {
177     if (m_opaque_sp)
178         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
179     return false;
180 }
181 
182 bool
183 SBModule::operator != (const SBModule &rhs) const
184 {
185     if (m_opaque_sp)
186         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
187     return false;
188 }
189 
190 lldb::ModuleSP &
191 SBModule::operator *()
192 {
193     return m_opaque_sp;
194 }
195 
196 lldb_private::Module *
197 SBModule::operator ->()
198 {
199     return m_opaque_sp.get();
200 }
201 
202 const lldb_private::Module *
203 SBModule::operator ->() const
204 {
205     return m_opaque_sp.get();
206 }
207 
208 lldb_private::Module *
209 SBModule::get()
210 {
211     return m_opaque_sp.get();
212 }
213 
214 const lldb_private::Module *
215 SBModule::get() const
216 {
217     return m_opaque_sp.get();
218 }
219 
220 const lldb::ModuleSP &
221 SBModule::get_sp() const
222 {
223     return m_opaque_sp;
224 }
225 
226 void
227 SBModule::SetModule (const lldb::ModuleSP& module_sp)
228 {
229     m_opaque_sp = module_sp;
230 }
231 
232 
233 SBAddress
234 SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
235 {
236     lldb::SBAddress sb_addr;
237     if (m_opaque_sp)
238     {
239         Address addr;
240         if (m_opaque_sp->ResolveFileAddress (vm_addr, addr))
241             sb_addr.ref() = addr;
242     }
243     return sb_addr;
244 }
245 
246 SBSymbolContext
247 SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
248 {
249     SBSymbolContext sb_sc;
250     if (m_opaque_sp && addr.IsValid())
251         m_opaque_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
252     return sb_sc;
253 }
254 
255 bool
256 SBModule::GetDescription (SBStream &description)
257 {
258     if (m_opaque_sp)
259     {
260         description.ref();
261         m_opaque_sp->GetDescription (description.get());
262     }
263     else
264         description.Printf ("No value");
265 
266     return true;
267 }
268 
269 size_t
270 SBModule::GetNumSymbols ()
271 {
272     if (m_opaque_sp)
273     {
274         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
275         if (obj_file)
276         {
277             Symtab *symtab = obj_file->GetSymtab();
278             if (symtab)
279                 return symtab->GetNumSymbols();
280         }
281     }
282     return 0;
283 }
284 
285 SBSymbol
286 SBModule::GetSymbolAtIndex (size_t idx)
287 {
288     SBSymbol sb_symbol;
289     if (m_opaque_sp)
290     {
291         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
292         if (obj_file)
293         {
294             Symtab *symtab = obj_file->GetSymtab();
295             if (symtab)
296                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
297         }
298     }
299     return sb_symbol;
300 }
301 
302 size_t
303 SBModule::GetNumSections ()
304 {
305     if (m_opaque_sp)
306     {
307         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
308         if (obj_file)
309         {
310             SectionList *section_list = obj_file->GetSectionList ();
311             if (section_list)
312                 return section_list->GetSize();
313         }
314     }
315     return 0;
316 }
317 
318 SBSection
319 SBModule::GetSectionAtIndex (size_t idx)
320 {
321     SBSection sb_section;
322     if (m_opaque_sp)
323     {
324         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
325         if (obj_file)
326         {
327             SectionList *section_list = obj_file->GetSectionList ();
328 
329             if (section_list)
330                 sb_section.SetSection(section_list->GetSectionAtIndex (idx).get());
331         }
332     }
333     return sb_section;
334 }
335 
336 uint32_t
337 SBModule::FindFunctions (const char *name,
338                          uint32_t name_type_mask,
339                          bool append,
340                          lldb::SBSymbolContextList& sc_list)
341 {
342     if (!append)
343         sc_list.Clear();
344     if (m_opaque_sp)
345     {
346         const bool symbols_ok = true;
347         return m_opaque_sp->FindFunctions (ConstString(name),
348                                            NULL,
349                                            name_type_mask,
350                                            symbols_ok,
351                                            append,
352                                            *sc_list);
353     }
354     return 0;
355 }
356 
357 
358 SBValueList
359 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
360 {
361     SBValueList sb_value_list;
362     if (m_opaque_sp)
363     {
364         VariableList variable_list;
365         const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name),
366                                                                        NULL,
367                                                                        false,
368                                                                        max_matches,
369                                                                        variable_list);
370 
371         if (match_count > 0)
372         {
373             ValueObjectList &value_object_list = sb_value_list.ref();
374             for (uint32_t i=0; i<match_count; ++i)
375             {
376                 lldb::ValueObjectSP valobj_sp;
377                 if (target.IsValid())
378                     valobj_sp = ValueObjectVariable::Create (target.get(), variable_list.GetVariableAtIndex(i));
379                 else
380                     valobj_sp = ValueObjectVariable::Create (NULL, variable_list.GetVariableAtIndex(i));
381                 if (valobj_sp)
382                     value_object_list.Append(valobj_sp);
383             }
384         }
385     }
386 
387     return sb_value_list;
388 }
389 
390 lldb::SBType
391 SBModule::FindFirstType (const char* name_cstr)
392 {
393     SBType sb_type;
394     if (IsValid())
395     {
396         SymbolContext sc;
397         TypeList type_list;
398         uint32_t num_matches = 0;
399         ConstString name(name_cstr);
400 
401         num_matches = m_opaque_sp->FindTypes(sc,
402                                              name,
403                                              NULL,
404                                              false,
405                                              1,
406                                              type_list);
407 
408         if (num_matches)
409             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
410     }
411     return sb_type;
412 }
413 
414 lldb::SBTypeList
415 SBModule::FindTypes (const char* type)
416 {
417 
418     SBTypeList retval;
419 
420     if (IsValid())
421     {
422         SymbolContext sc;
423         TypeList type_list;
424         uint32_t num_matches = 0;
425         ConstString name(type);
426 
427         num_matches = m_opaque_sp->FindTypes(sc,
428                                              name,
429                                              NULL,
430                                              false,
431                                              UINT32_MAX,
432                                              type_list);
433 
434         for (size_t idx = 0; idx < num_matches; idx++)
435         {
436             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
437             if (type_sp)
438                 retval.Append(SBType(type_sp));
439         }
440     }
441 
442     return retval;
443 }
444 
445 
446 SBSection
447 SBModule::FindSection (const char *sect_name)
448 {
449     SBSection sb_section;
450 
451     if (IsValid())
452     {
453         ObjectFile *objfile = m_opaque_sp->GetObjectFile();
454         if (objfile)
455         {
456             SectionList *section_list = objfile->GetSectionList();
457             if (section_list)
458             {
459                 ConstString const_sect_name(sect_name);
460                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
461                 if (section_sp)
462                 {
463                     sb_section.SetSection(section_sp.get());
464                 }
465             }
466         }
467     }
468     return sb_section;
469 }
470 
471