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