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/SBModuleSpec.h"
14#include "lldb/API/SBProcess.h"
15#include "lldb/API/SBStream.h"
16#include "lldb/API/SBSymbolContextList.h"
17#include "lldb/Core/Module.h"
18#include "lldb/Core/Log.h"
19#include "lldb/Core/Section.h"
20#include "lldb/Core/StreamString.h"
21#include "lldb/Core/ValueObjectList.h"
22#include "lldb/Core/ValueObjectVariable.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/SymbolVendor.h"
25#include "lldb/Symbol/Symtab.h"
26#include "lldb/Symbol/VariableList.h"
27#include "lldb/Target/Target.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
32
33SBModule::SBModule () :
34    m_opaque_sp ()
35{
36}
37
38SBModule::SBModule (const lldb::ModuleSP& module_sp) :
39    m_opaque_sp (module_sp)
40{
41}
42
43SBModule::SBModule(const SBModuleSpec &module_spec) :
44    m_opaque_sp ()
45{
46    ModuleSP module_sp;
47    Error error = ModuleList::GetSharedModule (*module_spec.m_opaque_ap,
48                                               module_sp,
49                                               NULL,
50                                               NULL,
51                                               NULL);
52    if (module_sp)
53        SetSP(module_sp);
54}
55
56SBModule::SBModule(const SBModule &rhs) :
57    m_opaque_sp (rhs.m_opaque_sp)
58{
59}
60
61SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
62    m_opaque_sp ()
63{
64    ProcessSP process_sp (process.GetSP());
65    if (process_sp)
66    {
67        m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr);
68        if (m_opaque_sp)
69        {
70            Target &target = process_sp->GetTarget();
71            bool changed = false;
72            m_opaque_sp->SetLoadAddress(target, 0, true, changed);
73            target.GetImages().Append(m_opaque_sp);
74        }
75    }
76}
77
78const SBModule &
79SBModule::operator = (const SBModule &rhs)
80{
81    if (this != &rhs)
82        m_opaque_sp = rhs.m_opaque_sp;
83    return *this;
84}
85
86SBModule::~SBModule ()
87{
88}
89
90bool
91SBModule::IsValid () const
92{
93    return m_opaque_sp.get() != NULL;
94}
95
96void
97SBModule::Clear()
98{
99    m_opaque_sp.reset();
100}
101
102SBFileSpec
103SBModule::GetFileSpec () const
104{
105    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
106
107    SBFileSpec file_spec;
108    ModuleSP module_sp (GetSP ());
109    if (module_sp)
110        file_spec.SetFileSpec(module_sp->GetFileSpec());
111
112    if (log)
113    {
114        log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
115        module_sp.get(), file_spec.get());
116    }
117
118    return file_spec;
119}
120
121lldb::SBFileSpec
122SBModule::GetPlatformFileSpec () const
123{
124    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
125
126    SBFileSpec file_spec;
127    ModuleSP module_sp (GetSP ());
128    if (module_sp)
129        file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());
130
131    if (log)
132    {
133        log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
134                     module_sp.get(), file_spec.get());
135    }
136
137    return file_spec;
138
139}
140
141bool
142SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
143{
144    bool result = false;
145    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
146
147    ModuleSP module_sp (GetSP ());
148    if (module_sp)
149    {
150        module_sp->SetPlatformFileSpec(*platform_file);
151        result = true;
152    }
153
154    if (log)
155    {
156        log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i",
157                     module_sp.get(),
158                     platform_file.get(),
159                     platform_file->GetPath().c_str(),
160                     result);
161    }
162    return result;
163}
164
165lldb::SBFileSpec
166SBModule::GetRemoteInstallFileSpec ()
167{
168    SBFileSpec sb_file_spec;
169    ModuleSP module_sp (GetSP ());
170    if (module_sp)
171        sb_file_spec.SetFileSpec (module_sp->GetRemoteInstallFileSpec());
172    return sb_file_spec;
173}
174
175bool
176SBModule::SetRemoteInstallFileSpec (lldb::SBFileSpec &file)
177{
178    ModuleSP module_sp (GetSP ());
179    if (module_sp)
180    {
181        module_sp->SetRemoteInstallFileSpec(file.ref());
182        return true;
183    }
184    return false;
185}
186
187
188const uint8_t *
189SBModule::GetUUIDBytes () const
190{
191    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
192
193    const uint8_t *uuid_bytes = NULL;
194    ModuleSP module_sp (GetSP ());
195    if (module_sp)
196        uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
197
198    if (log)
199    {
200        if (uuid_bytes)
201        {
202            StreamString s;
203            module_sp->GetUUID().Dump (&s);
204            log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData());
205        }
206        else
207            log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get());
208    }
209    return uuid_bytes;
210}
211
212
213const char *
214SBModule::GetUUIDString () const
215{
216    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
217
218    static char uuid_string_buffer[80];
219    const char *uuid_c_string = NULL;
220    std::string uuid_string;
221    ModuleSP module_sp (GetSP ());
222    if (module_sp)
223        uuid_string = module_sp->GetUUID().GetAsString();
224
225    if (!uuid_string.empty())
226    {
227        strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer));
228        uuid_c_string = uuid_string_buffer;
229    }
230
231    if (log)
232    {
233        if (!uuid_string.empty())
234        {
235            StreamString s;
236            module_sp->GetUUID().Dump (&s);
237            log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData());
238        }
239        else
240            log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get());
241    }
242    return uuid_c_string;
243}
244
245
246bool
247SBModule::operator == (const SBModule &rhs) const
248{
249    if (m_opaque_sp)
250        return m_opaque_sp.get() == rhs.m_opaque_sp.get();
251    return false;
252}
253
254bool
255SBModule::operator != (const SBModule &rhs) const
256{
257    if (m_opaque_sp)
258        return m_opaque_sp.get() != rhs.m_opaque_sp.get();
259    return false;
260}
261
262ModuleSP
263SBModule::GetSP () const
264{
265    return m_opaque_sp;
266}
267
268void
269SBModule::SetSP (const ModuleSP &module_sp)
270{
271    m_opaque_sp = module_sp;
272}
273
274SBAddress
275SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
276{
277    lldb::SBAddress sb_addr;
278    ModuleSP module_sp (GetSP ());
279    if (module_sp)
280    {
281        Address addr;
282        if (module_sp->ResolveFileAddress (vm_addr, addr))
283            sb_addr.ref() = addr;
284    }
285    return sb_addr;
286}
287
288SBSymbolContext
289SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
290{
291    SBSymbolContext sb_sc;
292    ModuleSP module_sp (GetSP ());
293    if (module_sp && addr.IsValid())
294        module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
295    return sb_sc;
296}
297
298bool
299SBModule::GetDescription (SBStream &description)
300{
301    Stream &strm = description.ref();
302
303    ModuleSP module_sp (GetSP ());
304    if (module_sp)
305    {
306        module_sp->GetDescription (&strm);
307    }
308    else
309        strm.PutCString ("No value");
310
311    return true;
312}
313
314uint32_t
315SBModule::GetNumCompileUnits()
316{
317    ModuleSP module_sp (GetSP ());
318    if (module_sp)
319    {
320        return module_sp->GetNumCompileUnits ();
321    }
322    return 0;
323}
324
325SBCompileUnit
326SBModule::GetCompileUnitAtIndex (uint32_t index)
327{
328    SBCompileUnit sb_cu;
329    ModuleSP module_sp (GetSP ());
330    if (module_sp)
331    {
332        CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
333        sb_cu.reset(cu_sp.get());
334    }
335    return sb_cu;
336}
337
338static Symtab *
339GetUnifiedSymbolTable (const lldb::ModuleSP& module_sp)
340{
341    if (module_sp)
342    {
343        SymbolVendor *symbols = module_sp->GetSymbolVendor();
344        if (symbols)
345            return symbols->GetSymtab();
346    }
347    return NULL;
348}
349
350size_t
351SBModule::GetNumSymbols ()
352{
353    ModuleSP module_sp (GetSP ());
354    if (module_sp)
355    {
356        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
357        if (symtab)
358            return symtab->GetNumSymbols();
359    }
360    return 0;
361}
362
363SBSymbol
364SBModule::GetSymbolAtIndex (size_t idx)
365{
366    SBSymbol sb_symbol;
367    ModuleSP module_sp (GetSP ());
368    Symtab *symtab = GetUnifiedSymbolTable (module_sp);
369    if (symtab)
370        sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
371    return sb_symbol;
372}
373
374lldb::SBSymbol
375SBModule::FindSymbol (const char *name,
376                      lldb::SymbolType symbol_type)
377{
378    SBSymbol sb_symbol;
379    if (name && name[0])
380    {
381        ModuleSP module_sp (GetSP ());
382        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
383        if (symtab)
384            sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
385    }
386    return sb_symbol;
387}
388
389
390lldb::SBSymbolContextList
391SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
392{
393    SBSymbolContextList sb_sc_list;
394    if (name && name[0])
395    {
396        ModuleSP module_sp (GetSP ());
397        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
398        if (symtab)
399        {
400            std::vector<uint32_t> matching_symbol_indexes;
401            const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
402            if (num_matches)
403            {
404                SymbolContext sc;
405                sc.module_sp = module_sp;
406                SymbolContextList &sc_list = *sb_sc_list;
407                for (size_t i=0; i<num_matches; ++i)
408                {
409                    sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
410                    if (sc.symbol)
411                        sc_list.Append(sc);
412                }
413            }
414        }
415    }
416    return sb_sc_list;
417
418}
419
420
421
422size_t
423SBModule::GetNumSections ()
424{
425    ModuleSP module_sp (GetSP ());
426    if (module_sp)
427    {
428        // Give the symbol vendor a chance to add to the unified section list.
429        module_sp->GetSymbolVendor();
430        SectionList *section_list = module_sp->GetSectionList();
431        if (section_list)
432            return section_list->GetSize();
433    }
434    return 0;
435}
436
437SBSection
438SBModule::GetSectionAtIndex (size_t idx)
439{
440    SBSection sb_section;
441    ModuleSP module_sp (GetSP ());
442    if (module_sp)
443    {
444        // Give the symbol vendor a chance to add to the unified section list.
445        module_sp->GetSymbolVendor();
446        SectionList *section_list = module_sp->GetSectionList ();
447
448        if (section_list)
449            sb_section.SetSP(section_list->GetSectionAtIndex (idx));
450    }
451    return sb_section;
452}
453
454lldb::SBSymbolContextList
455SBModule::FindFunctions (const char *name,
456                         uint32_t name_type_mask)
457{
458    lldb::SBSymbolContextList sb_sc_list;
459    ModuleSP module_sp (GetSP ());
460    if (name && module_sp)
461    {
462        const bool append = true;
463        const bool symbols_ok = true;
464        const bool inlines_ok = true;
465        module_sp->FindFunctions (ConstString(name),
466                                  NULL,
467                                  name_type_mask,
468                                  symbols_ok,
469                                  inlines_ok,
470                                  append,
471                                  *sb_sc_list);
472    }
473    return sb_sc_list;
474}
475
476
477SBValueList
478SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
479{
480    SBValueList sb_value_list;
481    ModuleSP module_sp (GetSP ());
482    if (name && module_sp)
483    {
484        VariableList variable_list;
485        const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
486                                                                     NULL,
487                                                                     false,
488                                                                     max_matches,
489                                                                     variable_list);
490
491        if (match_count > 0)
492        {
493            for (uint32_t i=0; i<match_count; ++i)
494            {
495                lldb::ValueObjectSP valobj_sp;
496                TargetSP target_sp (target.GetSP());
497                valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
498                if (valobj_sp)
499                    sb_value_list.Append(SBValue(valobj_sp));
500            }
501        }
502    }
503
504    return sb_value_list;
505}
506
507lldb::SBValue
508SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
509{
510    SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
511    if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
512        return sb_value_list.GetValueAtIndex(0);
513    return SBValue();
514}
515
516lldb::SBType
517SBModule::FindFirstType (const char *name_cstr)
518{
519    SBType sb_type;
520    ModuleSP module_sp (GetSP ());
521    if (name_cstr && module_sp)
522    {
523        SymbolContext sc;
524        const bool exact_match = false;
525        ConstString name(name_cstr);
526
527        sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
528
529        if (!sb_type.IsValid())
530            sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
531    }
532    return sb_type;
533}
534
535lldb::SBType
536SBModule::GetBasicType(lldb::BasicType type)
537{
538    ModuleSP module_sp (GetSP ());
539    if (module_sp)
540        return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
541    return SBType();
542}
543
544lldb::SBTypeList
545SBModule::FindTypes (const char *type)
546{
547    SBTypeList retval;
548
549    ModuleSP module_sp (GetSP ());
550    if (type && module_sp)
551    {
552        SymbolContext sc;
553        TypeList type_list;
554        const bool exact_match = false;
555        ConstString name(type);
556        const uint32_t num_matches = module_sp->FindTypes (sc,
557                                                           name,
558                                                           exact_match,
559                                                           UINT32_MAX,
560                                                           type_list);
561
562        if (num_matches > 0)
563        {
564            for (size_t idx = 0; idx < num_matches; idx++)
565            {
566                TypeSP type_sp (type_list.GetTypeAtIndex(idx));
567                if (type_sp)
568                    retval.Append(SBType(type_sp));
569            }
570        }
571        else
572        {
573            SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
574            if (sb_type.IsValid())
575                retval.Append(sb_type);
576        }
577    }
578
579    return retval;
580}
581
582lldb::SBType
583SBModule::GetTypeByID (lldb::user_id_t uid)
584{
585    ModuleSP module_sp (GetSP ());
586    if (module_sp)
587    {
588        SymbolVendor* vendor = module_sp->GetSymbolVendor();
589        if (vendor)
590        {
591            Type *type_ptr = vendor->ResolveTypeUID(uid);
592            if (type_ptr)
593                return SBType(type_ptr->shared_from_this());
594        }
595    }
596    return SBType();
597}
598
599lldb::SBTypeList
600SBModule::GetTypes (uint32_t type_mask)
601{
602    SBTypeList sb_type_list;
603
604    ModuleSP module_sp (GetSP ());
605    if (module_sp)
606    {
607        SymbolVendor* vendor = module_sp->GetSymbolVendor();
608        if (vendor)
609        {
610            TypeList type_list;
611            vendor->GetTypes (NULL, type_mask, type_list);
612            sb_type_list.m_opaque_ap->Append(type_list);
613        }
614    }
615    return sb_type_list;
616}
617
618SBSection
619SBModule::FindSection (const char *sect_name)
620{
621    SBSection sb_section;
622
623    ModuleSP module_sp (GetSP ());
624    if (sect_name && module_sp)
625    {
626        // Give the symbol vendor a chance to add to the unified section list.
627        module_sp->GetSymbolVendor();
628        SectionList *section_list = module_sp->GetSectionList();
629        if (section_list)
630        {
631            ConstString const_sect_name(sect_name);
632            SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
633            if (section_sp)
634            {
635                sb_section.SetSP (section_sp);
636            }
637        }
638    }
639    return sb_section;
640}
641
642lldb::ByteOrder
643SBModule::GetByteOrder ()
644{
645    ModuleSP module_sp (GetSP ());
646    if (module_sp)
647        return module_sp->GetArchitecture().GetByteOrder();
648    return eByteOrderInvalid;
649}
650
651const char *
652SBModule::GetTriple ()
653{
654    ModuleSP module_sp (GetSP ());
655    if (module_sp)
656    {
657        std::string triple (module_sp->GetArchitecture().GetTriple().str());
658        // Unique the string so we don't run into ownership issues since
659        // the const strings put the string into the string pool once and
660        // the strings never comes out
661        ConstString const_triple (triple.c_str());
662        return const_triple.GetCString();
663    }
664    return NULL;
665}
666
667uint32_t
668SBModule::GetAddressByteSize()
669{
670    ModuleSP module_sp (GetSP ());
671    if (module_sp)
672        return module_sp->GetArchitecture().GetAddressByteSize();
673    return sizeof(void*);
674}
675
676
677uint32_t
678SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
679{
680    ModuleSP module_sp (GetSP ());
681    if (module_sp)
682        return module_sp->GetVersion(versions, num_versions);
683    else
684    {
685        if (versions && num_versions)
686        {
687            for (uint32_t i=0; i<num_versions; ++i)
688                versions[i] = UINT32_MAX;
689        }
690        return 0;
691    }
692}
693
694