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