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/SBProcess.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/API/SBSymbolContextList.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Section.h"
19 #include "lldb/Core/StreamString.h"
20 #include "lldb/Core/ValueObjectList.h"
21 #include "lldb/Core/ValueObjectVariable.h"
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Symbol/Symtab.h"
25 #include "lldb/Symbol/VariableList.h"
26 #include "lldb/Target/Target.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 
32 SBModule::SBModule () :
33     m_opaque_sp ()
34 {
35 }
36 
37 SBModule::SBModule (const lldb::ModuleSP& module_sp) :
38     m_opaque_sp (module_sp)
39 {
40 }
41 
42 SBModule::SBModule(const SBModule &rhs) :
43     m_opaque_sp (rhs.m_opaque_sp)
44 {
45 }
46 
47 SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
48     m_opaque_sp ()
49 {
50     ProcessSP process_sp (process.GetSP());
51     if (process_sp)
52     {
53         const bool add_image_to_target = true;
54         const bool load_image_sections_in_target = true;
55         m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(),
56                                                         header_addr,
57                                                         add_image_to_target,
58                                                         load_image_sections_in_target);
59     }
60 }
61 
62 const SBModule &
63 SBModule::operator = (const SBModule &rhs)
64 {
65     if (this != &rhs)
66         m_opaque_sp = rhs.m_opaque_sp;
67     return *this;
68 }
69 
70 SBModule::~SBModule ()
71 {
72 }
73 
74 bool
75 SBModule::IsValid () const
76 {
77     return m_opaque_sp.get() != NULL;
78 }
79 
80 void
81 SBModule::Clear()
82 {
83     m_opaque_sp.reset();
84 }
85 
86 SBFileSpec
87 SBModule::GetFileSpec () const
88 {
89     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
90 
91     SBFileSpec file_spec;
92     ModuleSP module_sp (GetSP ());
93     if (module_sp)
94         file_spec.SetFileSpec(module_sp->GetFileSpec());
95 
96     if (log)
97     {
98         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
99         module_sp.get(), file_spec.get());
100     }
101 
102     return file_spec;
103 }
104 
105 lldb::SBFileSpec
106 SBModule::GetPlatformFileSpec () const
107 {
108     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
109 
110     SBFileSpec file_spec;
111     ModuleSP module_sp (GetSP ());
112     if (module_sp)
113         file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());
114 
115     if (log)
116     {
117         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
118                      module_sp.get(), file_spec.get());
119     }
120 
121     return file_spec;
122 
123 }
124 
125 bool
126 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
127 {
128     bool result = false;
129     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
130 
131     ModuleSP module_sp (GetSP ());
132     if (module_sp)
133     {
134         module_sp->SetPlatformFileSpec(*platform_file);
135         result = true;
136     }
137 
138     if (log)
139     {
140         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
141                      module_sp.get(),
142                      platform_file.get(),
143                      platform_file->GetDirectory().GetCString(),
144                      platform_file->GetDirectory() ? "/" : "",
145                      platform_file->GetFilename().GetCString(),
146                      result);
147     }
148     return result;
149 }
150 
151 
152 
153 const uint8_t *
154 SBModule::GetUUIDBytes () const
155 {
156     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
157 
158     const uint8_t *uuid_bytes = NULL;
159     ModuleSP module_sp (GetSP ());
160     if (module_sp)
161         uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
162 
163     if (log)
164     {
165         if (uuid_bytes)
166         {
167             StreamString s;
168             module_sp->GetUUID().Dump (&s);
169             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData());
170         }
171         else
172             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get());
173     }
174     return uuid_bytes;
175 }
176 
177 
178 const char *
179 SBModule::GetUUIDString () const
180 {
181     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
182 
183     static char uuid_string[80];
184     const char * uuid_c_string = NULL;
185     ModuleSP module_sp (GetSP ());
186     if (module_sp)
187         uuid_c_string = (const char *)module_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string));
188 
189     if (log)
190     {
191         if (uuid_c_string)
192         {
193             StreamString s;
194             module_sp->GetUUID().Dump (&s);
195             log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData());
196         }
197         else
198             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get());
199     }
200     return uuid_c_string;
201 }
202 
203 
204 bool
205 SBModule::operator == (const SBModule &rhs) const
206 {
207     if (m_opaque_sp)
208         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
209     return false;
210 }
211 
212 bool
213 SBModule::operator != (const SBModule &rhs) const
214 {
215     if (m_opaque_sp)
216         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
217     return false;
218 }
219 
220 ModuleSP
221 SBModule::GetSP () const
222 {
223     return m_opaque_sp;
224 }
225 
226 void
227 SBModule::SetSP (const ModuleSP &module_sp)
228 {
229     m_opaque_sp = module_sp;
230 }
231 
232 SBAddress
233 SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
234 {
235     lldb::SBAddress sb_addr;
236     ModuleSP module_sp (GetSP ());
237     if (module_sp)
238     {
239         Address addr;
240         if (module_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     ModuleSP module_sp (GetSP ());
251     if (module_sp && addr.IsValid())
252         module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
253     return sb_sc;
254 }
255 
256 bool
257 SBModule::GetDescription (SBStream &description)
258 {
259     Stream &strm = description.ref();
260 
261     ModuleSP module_sp (GetSP ());
262     if (module_sp)
263     {
264         module_sp->GetDescription (&strm);
265     }
266     else
267         strm.PutCString ("No value");
268 
269     return true;
270 }
271 
272 uint32_t
273 SBModule::GetNumCompileUnits()
274 {
275     ModuleSP module_sp (GetSP ());
276     if (module_sp)
277     {
278         return module_sp->GetNumCompileUnits ();
279     }
280     return 0;
281 }
282 
283 SBCompileUnit
284 SBModule::GetCompileUnitAtIndex (uint32_t index)
285 {
286     SBCompileUnit sb_cu;
287     ModuleSP module_sp (GetSP ());
288     if (module_sp)
289     {
290         CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
291         sb_cu.reset(cu_sp.get());
292     }
293     return sb_cu;
294 }
295 
296 size_t
297 SBModule::GetNumSymbols ()
298 {
299     ModuleSP module_sp (GetSP ());
300     if (module_sp)
301     {
302         ObjectFile *obj_file = module_sp->GetObjectFile();
303         if (obj_file)
304         {
305             Symtab *symtab = obj_file->GetSymtab();
306             if (symtab)
307                 return symtab->GetNumSymbols();
308         }
309     }
310     return 0;
311 }
312 
313 SBSymbol
314 SBModule::GetSymbolAtIndex (size_t idx)
315 {
316     SBSymbol sb_symbol;
317     ModuleSP module_sp (GetSP ());
318     if (module_sp)
319     {
320         ObjectFile *obj_file = module_sp->GetObjectFile();
321         if (obj_file)
322         {
323             Symtab *symtab = obj_file->GetSymtab();
324             if (symtab)
325                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
326         }
327     }
328     return sb_symbol;
329 }
330 
331 size_t
332 SBModule::GetNumSections ()
333 {
334     ModuleSP module_sp (GetSP ());
335     if (module_sp)
336     {
337         ObjectFile *obj_file = module_sp->GetObjectFile();
338         if (obj_file)
339         {
340             SectionList *section_list = obj_file->GetSectionList ();
341             if (section_list)
342                 return section_list->GetSize();
343         }
344     }
345     return 0;
346 }
347 
348 SBSection
349 SBModule::GetSectionAtIndex (size_t idx)
350 {
351     SBSection sb_section;
352     ModuleSP module_sp (GetSP ());
353     if (module_sp)
354     {
355         ObjectFile *obj_file = module_sp->GetObjectFile();
356         if (obj_file)
357         {
358             SectionList *section_list = obj_file->GetSectionList ();
359 
360             if (section_list)
361                 sb_section.SetSP(section_list->GetSectionAtIndex (idx));
362         }
363     }
364     return sb_section;
365 }
366 
367 lldb::SBSymbolContextList
368 SBModule::FindFunctions (const char *name,
369                          uint32_t name_type_mask)
370 {
371     lldb::SBSymbolContextList sb_sc_list;
372     ModuleSP module_sp (GetSP ());
373     if (name && module_sp)
374     {
375         const bool append = true;
376         const bool symbols_ok = true;
377         const bool inlines_ok = true;
378         module_sp->FindFunctions (ConstString(name),
379                                   NULL,
380                                   name_type_mask,
381                                   symbols_ok,
382                                   inlines_ok,
383                                   append,
384                                   *sb_sc_list);
385     }
386     return sb_sc_list;
387 }
388 
389 
390 SBValueList
391 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
392 {
393     SBValueList sb_value_list;
394     ModuleSP module_sp (GetSP ());
395     if (name && module_sp)
396     {
397         VariableList variable_list;
398         const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
399                                                                      NULL,
400                                                                      false,
401                                                                      max_matches,
402                                                                      variable_list);
403 
404         if (match_count > 0)
405         {
406             ValueObjectList &value_object_list = sb_value_list.ref();
407             for (uint32_t i=0; i<match_count; ++i)
408             {
409                 lldb::ValueObjectSP valobj_sp;
410                 TargetSP target_sp (target.GetSP());
411                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
412                 if (valobj_sp)
413                     value_object_list.Append(valobj_sp);
414             }
415         }
416     }
417 
418     return sb_value_list;
419 }
420 
421 lldb::SBType
422 SBModule::FindFirstType (const char *name_cstr)
423 {
424     SBType sb_type;
425     ModuleSP module_sp (GetSP ());
426     if (name_cstr && module_sp)
427     {
428         SymbolContext sc;
429         TypeList type_list;
430         uint32_t num_matches = 0;
431         const bool exact_match = false;
432         ConstString name(name_cstr);
433 
434         num_matches = module_sp->FindTypes (sc,
435                                             name,
436                                             exact_match,
437                                             1,
438                                             type_list);
439 
440         if (num_matches)
441             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
442     }
443     return sb_type;
444 }
445 
446 lldb::SBTypeList
447 SBModule::FindTypes (const char *type)
448 {
449 
450     SBTypeList retval;
451 
452     ModuleSP module_sp (GetSP ());
453     if (type && module_sp)
454     {
455         SymbolContext sc;
456         TypeList type_list;
457         const bool exact_match = false;
458         uint32_t num_matches = 0;
459         ConstString name(type);
460 
461         num_matches = module_sp->FindTypes (sc,
462                                             name,
463                                             exact_match,
464                                             UINT32_MAX,
465                                             type_list);
466 
467         for (size_t idx = 0; idx < num_matches; idx++)
468         {
469             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
470             if (type_sp)
471                 retval.Append(SBType(type_sp));
472         }
473     }
474 
475     return retval;
476 }
477 
478 
479 SBSection
480 SBModule::FindSection (const char *sect_name)
481 {
482     SBSection sb_section;
483 
484     ModuleSP module_sp (GetSP ());
485     if (sect_name && module_sp)
486     {
487         ObjectFile *objfile = module_sp->GetObjectFile();
488         if (objfile)
489         {
490             SectionList *section_list = objfile->GetSectionList();
491             if (section_list)
492             {
493                 ConstString const_sect_name(sect_name);
494                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
495                 if (section_sp)
496                 {
497                     sb_section.SetSP (section_sp);
498                 }
499             }
500         }
501     }
502     return sb_section;
503 }
504 
505 lldb::ByteOrder
506 SBModule::GetByteOrder ()
507 {
508     ModuleSP module_sp (GetSP ());
509     if (module_sp)
510         return module_sp->GetArchitecture().GetByteOrder();
511     return eByteOrderInvalid;
512 }
513 
514 const char *
515 SBModule::GetTriple ()
516 {
517     ModuleSP module_sp (GetSP ());
518     if (module_sp)
519     {
520         std::string triple (module_sp->GetArchitecture().GetTriple().str());
521         // Unique the string so we don't run into ownership issues since
522         // the const strings put the string into the string pool once and
523         // the strings never comes out
524         ConstString const_triple (triple.c_str());
525         return const_triple.GetCString();
526     }
527     return NULL;
528 }
529 
530 uint32_t
531 SBModule::GetAddressByteSize()
532 {
533     ModuleSP module_sp (GetSP ());
534     if (module_sp)
535         return module_sp->GetArchitecture().GetAddressByteSize();
536     return sizeof(void*);
537 }
538 
539 
540 uint32_t
541 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
542 {
543     ModuleSP module_sp (GetSP ());
544     if (module_sp)
545         return module_sp->GetVersion(versions, num_versions);
546     else
547     {
548         if (versions && num_versions)
549         {
550             for (uint32_t i=0; i<num_versions; ++i)
551                 versions[i] = UINT32_MAX;
552         }
553         return 0;
554     }
555 }
556 
557