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