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         m_opaque_sp->FindFunctions (ConstString(name),
331                                     NULL,
332                                     name_type_mask,
333                                     symbols_ok,
334                                     append,
335                                     *sb_sc_list);
336     }
337     return sb_sc_list;
338 }
339 
340 
341 SBValueList
342 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
343 {
344     SBValueList sb_value_list;
345     if (name && m_opaque_sp)
346     {
347         VariableList variable_list;
348         const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name),
349                                                                        NULL,
350                                                                        false,
351                                                                        max_matches,
352                                                                        variable_list);
353 
354         if (match_count > 0)
355         {
356             ValueObjectList &value_object_list = sb_value_list.ref();
357             for (uint32_t i=0; i<match_count; ++i)
358             {
359                 lldb::ValueObjectSP valobj_sp;
360                 TargetSP target_sp (target.GetSP());
361                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
362                 if (valobj_sp)
363                     value_object_list.Append(valobj_sp);
364             }
365         }
366     }
367 
368     return sb_value_list;
369 }
370 
371 lldb::SBType
372 SBModule::FindFirstType (const char *name_cstr)
373 {
374     SBType sb_type;
375     if (name_cstr && IsValid())
376     {
377         SymbolContext sc;
378         TypeList type_list;
379         uint32_t num_matches = 0;
380         ConstString name(name_cstr);
381 
382         num_matches = m_opaque_sp->FindTypes(sc,
383                                              name,
384                                              NULL,
385                                              false,
386                                              1,
387                                              type_list);
388 
389         if (num_matches)
390             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
391     }
392     return sb_type;
393 }
394 
395 lldb::SBTypeList
396 SBModule::FindTypes (const char *type)
397 {
398 
399     SBTypeList retval;
400 
401     if (type && IsValid())
402     {
403         SymbolContext sc;
404         TypeList type_list;
405         uint32_t num_matches = 0;
406         ConstString name(type);
407 
408         num_matches = m_opaque_sp->FindTypes(sc,
409                                              name,
410                                              NULL,
411                                              false,
412                                              UINT32_MAX,
413                                              type_list);
414 
415         for (size_t idx = 0; idx < num_matches; idx++)
416         {
417             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
418             if (type_sp)
419                 retval.Append(SBType(type_sp));
420         }
421     }
422 
423     return retval;
424 }
425 
426 
427 SBSection
428 SBModule::FindSection (const char *sect_name)
429 {
430     SBSection sb_section;
431 
432     if (sect_name && IsValid())
433     {
434         ObjectFile *objfile = m_opaque_sp->GetObjectFile();
435         if (objfile)
436         {
437             SectionList *section_list = objfile->GetSectionList();
438             if (section_list)
439             {
440                 ConstString const_sect_name(sect_name);
441                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
442                 if (section_sp)
443                 {
444                     sb_section.SetSection(section_sp.get());
445                 }
446             }
447         }
448     }
449     return sb_section;
450 }
451 
452 lldb::ByteOrder
453 SBModule::GetByteOrder ()
454 {
455     if (m_opaque_sp)
456         return m_opaque_sp->GetArchitecture().GetByteOrder();
457     return eByteOrderInvalid;
458 }
459 
460 const char *
461 SBModule::GetTriple ()
462 {
463     if (m_opaque_sp)
464     {
465         std::string triple (m_opaque_sp->GetArchitecture().GetTriple().str());
466         // Unique the string so we don't run into ownership issues since
467         // the const strings put the string into the string pool once and
468         // the strings never comes out
469         ConstString const_triple (triple.c_str());
470         return const_triple.GetCString();
471     }
472     return NULL;
473 }
474 
475 uint32_t
476 SBModule::GetAddressByteSize()
477 {
478     if (m_opaque_sp)
479         return m_opaque_sp->GetArchitecture().GetAddressByteSize();
480     return sizeof(void*);
481 }
482 
483