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, 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
165
166
167const uint8_t *
168SBModule::GetUUIDBytes () const
169{
170    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
171
172    const uint8_t *uuid_bytes = NULL;
173    ModuleSP module_sp (GetSP ());
174    if (module_sp)
175        uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
176
177    if (log)
178    {
179        if (uuid_bytes)
180        {
181            StreamString s;
182            module_sp->GetUUID().Dump (&s);
183            log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData());
184        }
185        else
186            log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get());
187    }
188    return uuid_bytes;
189}
190
191
192const char *
193SBModule::GetUUIDString () const
194{
195    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
196
197    static char uuid_string_buffer[80];
198    const char *uuid_c_string = NULL;
199    std::string uuid_string;
200    ModuleSP module_sp (GetSP ());
201    if (module_sp)
202        uuid_string = module_sp->GetUUID().GetAsString();
203
204    if (!uuid_string.empty())
205    {
206        strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer));
207        uuid_c_string = uuid_string_buffer;
208    }
209
210    if (log)
211    {
212        if (!uuid_string.empty())
213        {
214            StreamString s;
215            module_sp->GetUUID().Dump (&s);
216            log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData());
217        }
218        else
219            log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get());
220    }
221    return uuid_c_string;
222}
223
224
225bool
226SBModule::operator == (const SBModule &rhs) const
227{
228    if (m_opaque_sp)
229        return m_opaque_sp.get() == rhs.m_opaque_sp.get();
230    return false;
231}
232
233bool
234SBModule::operator != (const SBModule &rhs) const
235{
236    if (m_opaque_sp)
237        return m_opaque_sp.get() != rhs.m_opaque_sp.get();
238    return false;
239}
240
241ModuleSP
242SBModule::GetSP () const
243{
244    return m_opaque_sp;
245}
246
247void
248SBModule::SetSP (const ModuleSP &module_sp)
249{
250    m_opaque_sp = module_sp;
251}
252
253SBAddress
254SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
255{
256    lldb::SBAddress sb_addr;
257    ModuleSP module_sp (GetSP ());
258    if (module_sp)
259    {
260        Address addr;
261        if (module_sp->ResolveFileAddress (vm_addr, addr))
262            sb_addr.ref() = addr;
263    }
264    return sb_addr;
265}
266
267SBSymbolContext
268SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
269{
270    SBSymbolContext sb_sc;
271    ModuleSP module_sp (GetSP ());
272    if (module_sp && addr.IsValid())
273        module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
274    return sb_sc;
275}
276
277bool
278SBModule::GetDescription (SBStream &description)
279{
280    Stream &strm = description.ref();
281
282    ModuleSP module_sp (GetSP ());
283    if (module_sp)
284    {
285        module_sp->GetDescription (&strm);
286    }
287    else
288        strm.PutCString ("No value");
289
290    return true;
291}
292
293uint32_t
294SBModule::GetNumCompileUnits()
295{
296    ModuleSP module_sp (GetSP ());
297    if (module_sp)
298    {
299        return module_sp->GetNumCompileUnits ();
300    }
301    return 0;
302}
303
304SBCompileUnit
305SBModule::GetCompileUnitAtIndex (uint32_t index)
306{
307    SBCompileUnit sb_cu;
308    ModuleSP module_sp (GetSP ());
309    if (module_sp)
310    {
311        CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
312        sb_cu.reset(cu_sp.get());
313    }
314    return sb_cu;
315}
316
317static Symtab *
318GetUnifiedSymbolTable (const lldb::ModuleSP& module_sp)
319{
320    if (module_sp)
321    {
322        SymbolVendor *symbols = module_sp->GetSymbolVendor();
323        if (symbols)
324            return symbols->GetSymtab();
325    }
326    return NULL;
327}
328
329size_t
330SBModule::GetNumSymbols ()
331{
332    ModuleSP module_sp (GetSP ());
333    if (module_sp)
334    {
335        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
336        if (symtab)
337            return symtab->GetNumSymbols();
338    }
339    return 0;
340}
341
342SBSymbol
343SBModule::GetSymbolAtIndex (size_t idx)
344{
345    SBSymbol sb_symbol;
346    ModuleSP module_sp (GetSP ());
347    Symtab *symtab = GetUnifiedSymbolTable (module_sp);
348    if (symtab)
349        sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
350    return sb_symbol;
351}
352
353lldb::SBSymbol
354SBModule::FindSymbol (const char *name,
355                      lldb::SymbolType symbol_type)
356{
357    SBSymbol sb_symbol;
358    if (name && name[0])
359    {
360        ModuleSP module_sp (GetSP ());
361        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
362        if (symtab)
363            sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
364    }
365    return sb_symbol;
366}
367
368
369lldb::SBSymbolContextList
370SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
371{
372    SBSymbolContextList sb_sc_list;
373    if (name && name[0])
374    {
375        ModuleSP module_sp (GetSP ());
376        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
377        if (symtab)
378        {
379            std::vector<uint32_t> matching_symbol_indexes;
380            const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
381            if (num_matches)
382            {
383                SymbolContext sc;
384                sc.module_sp = module_sp;
385                SymbolContextList &sc_list = *sb_sc_list;
386                for (size_t i=0; i<num_matches; ++i)
387                {
388                    sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
389                    if (sc.symbol)
390                        sc_list.Append(sc);
391                }
392            }
393        }
394    }
395    return sb_sc_list;
396
397}
398
399
400
401size_t
402SBModule::GetNumSections ()
403{
404    ModuleSP module_sp (GetSP ());
405    if (module_sp)
406    {
407        // Give the symbol vendor a chance to add to the unified section list.
408        module_sp->GetSymbolVendor();
409        SectionList *section_list = module_sp->GetSectionList();
410        if (section_list)
411            return section_list->GetSize();
412    }
413    return 0;
414}
415
416SBSection
417SBModule::GetSectionAtIndex (size_t idx)
418{
419    SBSection sb_section;
420    ModuleSP module_sp (GetSP ());
421    if (module_sp)
422    {
423        // Give the symbol vendor a chance to add to the unified section list.
424        module_sp->GetSymbolVendor();
425        SectionList *section_list = module_sp->GetSectionList ();
426
427        if (section_list)
428            sb_section.SetSP(section_list->GetSectionAtIndex (idx));
429    }
430    return sb_section;
431}
432
433lldb::SBSymbolContextList
434SBModule::FindFunctions (const char *name,
435                         uint32_t name_type_mask)
436{
437    lldb::SBSymbolContextList sb_sc_list;
438    ModuleSP module_sp (GetSP ());
439    if (name && module_sp)
440    {
441        const bool append = true;
442        const bool symbols_ok = true;
443        const bool inlines_ok = true;
444        module_sp->FindFunctions (ConstString(name),
445                                  NULL,
446                                  name_type_mask,
447                                  symbols_ok,
448                                  inlines_ok,
449                                  append,
450                                  *sb_sc_list);
451    }
452    return sb_sc_list;
453}
454
455
456SBValueList
457SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
458{
459    SBValueList sb_value_list;
460    ModuleSP module_sp (GetSP ());
461    if (name && module_sp)
462    {
463        VariableList variable_list;
464        const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
465                                                                     NULL,
466                                                                     false,
467                                                                     max_matches,
468                                                                     variable_list);
469
470        if (match_count > 0)
471        {
472            for (uint32_t i=0; i<match_count; ++i)
473            {
474                lldb::ValueObjectSP valobj_sp;
475                TargetSP target_sp (target.GetSP());
476                valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
477                if (valobj_sp)
478                    sb_value_list.Append(SBValue(valobj_sp));
479            }
480        }
481    }
482
483    return sb_value_list;
484}
485
486lldb::SBValue
487SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
488{
489    SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
490    if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
491        return sb_value_list.GetValueAtIndex(0);
492    return SBValue();
493}
494
495lldb::SBType
496SBModule::FindFirstType (const char *name_cstr)
497{
498    SBType sb_type;
499    ModuleSP module_sp (GetSP ());
500    if (name_cstr && module_sp)
501    {
502        SymbolContext sc;
503        const bool exact_match = false;
504        ConstString name(name_cstr);
505
506        sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
507
508        if (!sb_type.IsValid())
509            sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
510    }
511    return sb_type;
512}
513
514lldb::SBType
515SBModule::GetBasicType(lldb::BasicType type)
516{
517    ModuleSP module_sp (GetSP ());
518    if (module_sp)
519        return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
520    return SBType();
521}
522
523lldb::SBTypeList
524SBModule::FindTypes (const char *type)
525{
526    SBTypeList retval;
527
528    ModuleSP module_sp (GetSP ());
529    if (type && module_sp)
530    {
531        SymbolContext sc;
532        TypeList type_list;
533        const bool exact_match = false;
534        ConstString name(type);
535        const uint32_t num_matches = module_sp->FindTypes (sc,
536                                                           name,
537                                                           exact_match,
538                                                           UINT32_MAX,
539                                                           type_list);
540
541        if (num_matches > 0)
542        {
543            for (size_t idx = 0; idx < num_matches; idx++)
544            {
545                TypeSP type_sp (type_list.GetTypeAtIndex(idx));
546                if (type_sp)
547                    retval.Append(SBType(type_sp));
548            }
549        }
550        else
551        {
552            SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
553            if (sb_type.IsValid())
554                retval.Append(sb_type);
555        }
556    }
557
558    return retval;
559}
560
561lldb::SBTypeList
562SBModule::GetTypes (uint32_t type_mask)
563{
564    SBTypeList sb_type_list;
565
566    ModuleSP module_sp (GetSP ());
567    if (module_sp)
568    {
569        SymbolVendor* vendor = module_sp->GetSymbolVendor();
570        if (vendor)
571        {
572            TypeList type_list;
573            vendor->GetTypes (NULL, type_mask, type_list);
574            sb_type_list.m_opaque_ap->Append(type_list);
575        }
576    }
577    return sb_type_list;
578}
579
580SBSection
581SBModule::FindSection (const char *sect_name)
582{
583    SBSection sb_section;
584
585    ModuleSP module_sp (GetSP ());
586    if (sect_name && module_sp)
587    {
588        // Give the symbol vendor a chance to add to the unified section list.
589        module_sp->GetSymbolVendor();
590        SectionList *section_list = module_sp->GetSectionList();
591        if (section_list)
592        {
593            ConstString const_sect_name(sect_name);
594            SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
595            if (section_sp)
596            {
597                sb_section.SetSP (section_sp);
598            }
599        }
600    }
601    return sb_section;
602}
603
604lldb::ByteOrder
605SBModule::GetByteOrder ()
606{
607    ModuleSP module_sp (GetSP ());
608    if (module_sp)
609        return module_sp->GetArchitecture().GetByteOrder();
610    return eByteOrderInvalid;
611}
612
613const char *
614SBModule::GetTriple ()
615{
616    ModuleSP module_sp (GetSP ());
617    if (module_sp)
618    {
619        std::string triple (module_sp->GetArchitecture().GetTriple().str());
620        // Unique the string so we don't run into ownership issues since
621        // the const strings put the string into the string pool once and
622        // the strings never comes out
623        ConstString const_triple (triple.c_str());
624        return const_triple.GetCString();
625    }
626    return NULL;
627}
628
629uint32_t
630SBModule::GetAddressByteSize()
631{
632    ModuleSP module_sp (GetSP ());
633    if (module_sp)
634        return module_sp->GetArchitecture().GetAddressByteSize();
635    return sizeof(void*);
636}
637
638
639uint32_t
640SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
641{
642    ModuleSP module_sp (GetSP ());
643    if (module_sp)
644        return module_sp->GetVersion(versions, num_versions);
645    else
646    {
647        if (versions && num_versions)
648        {
649            for (uint32_t i=0; i<num_versions; ++i)
650                versions[i] = UINT32_MAX;
651        }
652        return 0;
653    }
654}
655
656