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