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