diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Expression')
14 files changed, 1378 insertions, 344 deletions
diff --git a/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp b/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp index 2f14721..c3d42cb 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp @@ -480,10 +480,10 @@ ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) } void -ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) +ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD) { if (m_passthrough) - m_passthrough->HandleVTable(RD, DefinitionRequired); + m_passthrough->HandleVTable(RD); } void diff --git a/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp b/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp index 2a8b7bc..98628db 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp @@ -186,10 +186,10 @@ ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D) } void -ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) +ASTStructExtractor::HandleVTable(CXXRecordDecl *RD) { if (m_passthrough) - m_passthrough->HandleVTable(RD, DefinitionRequired); + m_passthrough->HandleVTable(RD); } void diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp index 9a6d6e5..3988cd6 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp @@ -16,15 +16,45 @@ #include "lldb/Expression/ASTDumper.h" #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" +#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" +#include <vector> + using namespace clang; using namespace lldb_private; +//------------------------------------------------------------------ +// Scoped class that will remove an active lexical decl from the set +// when it goes out of scope. +//------------------------------------------------------------------ +namespace { + class ScopedLexicalDeclEraser + { + public: + ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls, + const clang::Decl *decl) + : m_active_lexical_decls(decls), m_decl(decl) + { + } + + ~ScopedLexicalDeclEraser() + { + m_active_lexical_decls.erase(m_decl); + } + + private: + std::set<const clang::Decl *> &m_active_lexical_decls; + const clang::Decl *m_decl; + }; +} + ClangASTSource::~ClangASTSource() { m_ast_importer->ForgetDestination(m_ast_context); @@ -186,6 +216,12 @@ ClangASTSource::CompleteType (TagDecl *tag_decl) dumper.ToLog(log, " [CTD] "); } + auto iter = m_active_lexical_decls.find(tag_decl); + if (iter != m_active_lexical_decls.end()) + return; + m_active_lexical_decls.insert(tag_decl); + ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); + if (!m_ast_importer->CompleteTagDecl (tag_decl)) { // We couldn't complete the type. Maybe there's a definition @@ -397,6 +433,12 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, if (!context_decl) return ELR_Failure; + auto iter = m_active_lexical_decls.find(context_decl); + if (iter != m_active_lexical_decls.end()) + return ELR_Failure; + m_active_lexical_decls.insert(context_decl); + ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl); + static unsigned int invocation_id = 0; unsigned int current_id = invocation_id++; @@ -1529,41 +1571,50 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) while(0); } -typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap; -typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap; +typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap; +typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap; template <class D, class O> static bool -ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map, - llvm::DenseMap <const D*, O> &source_map, - ClangASTImporter *importer, - ASTContext &dest_ctx) +ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map, + ClangASTImporter *importer, ASTContext &dest_ctx) { - typedef llvm::DenseMap <const D*, O> MapType; - - for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end(); - fi != fe; - ++fi) + // When importing fields into a new record, clang has a hard requirement that + // fields be imported in field offset order. Since they are stored in a DenseMap + // with a pointer as the key type, this means we cannot simply iterate over the + // map, as the order will be non-deterministic. Instead we have to sort by the offset + // and then insert in sorted order. + typedef llvm::DenseMap<const D *, O> MapType; + typedef typename MapType::value_type PairType; + std::vector<PairType> sorted_items; + sorted_items.reserve(source_map.size()); + sorted_items.assign(source_map.begin(), source_map.end()); + std::sort(sorted_items.begin(), sorted_items.end(), + [](const PairType &lhs, const PairType &rhs) + { + return lhs.second < rhs.second; + }); + + for (const auto &item : sorted_items) { - DeclFromUser <D> user_decl(const_cast<D*>(fi->first)); + DeclFromUser<D> user_decl(const_cast<D *>(item.first)); DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx)); if (parser_decl.IsInvalid()) return false; - destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second)); + destination_map.insert(std::pair<const D *, O>(parser_decl.decl, item.second)); } return true; } -template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout, - DeclFromUser<const CXXRecordDecl> &record, - BaseOffsetMap &base_offsets) +template <bool IsVirtual> +bool +ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXRecordDecl> &record, + BaseOffsetMap &base_offsets) { - for (CXXRecordDecl::base_class_const_iterator - bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), - be = (IsVirtual ? record->vbases_end() : record->bases_end()); - bi != be; - ++bi) + for (CXXRecordDecl::base_class_const_iterator bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), + be = (IsVirtual ? record->vbases_end() : record->bases_end()); + bi != be; ++bi) { if (!IsVirtual && bi->isVirtual()) continue; @@ -1598,11 +1649,8 @@ template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record } bool -ClangASTSource::layoutRecordType(const RecordDecl *record, - uint64_t &size, - uint64_t &alignment, - FieldOffsetMap &field_offsets, - BaseOffsetMap &base_offsets, +ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint64_t &alignment, + FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets, BaseOffsetMap &virtual_base_offsets) { ClangASTMetrics::RegisterRecordLayout(); @@ -1637,9 +1685,7 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, int field_idx = 0, field_count = record_layout.getFieldCount(); - for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); - fi != fe; - ++fi) + for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); fi != fe; ++fi) { if (field_idx >= field_count) return false; // Layout didn't go well. Bail out. @@ -1682,9 +1728,8 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, fi != fe; ++fi) { - log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", - current_id, static_cast<void*>(*fi), - fi->getNameAsString().c_str(), field_offsets[*fi]); + log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", current_id, + static_cast<void *>(*fi), fi->getNameAsString().c_str(), field_offsets[*fi]); } DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); if (parser_cxx_record.IsValid()) @@ -1701,13 +1746,11 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, DeclFromParser <RecordDecl> base_record(base_record_type->getDecl()); DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); - log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", - current_id, (is_virtual ? "Virtual " : ""), - static_cast<void*>(base_cxx_record.decl), + log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id, + (is_virtual ? "Virtual " : ""), static_cast<void *>(base_cxx_record.decl), base_cxx_record.decl->getNameAsString().c_str(), - (is_virtual - ? virtual_base_offsets[base_cxx_record.decl].getQuantity() - : base_offsets[base_cxx_record.decl].getQuantity())); + (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() + : base_offsets[base_cxx_record.decl].getQuantity())); } } else @@ -1883,7 +1926,7 @@ NameSearchContext::AddVarDecl(const ClangASTType &type) } clang::NamedDecl * -NameSearchContext::AddFunDecl (const ClangASTType &type) +NameSearchContext::AddFunDecl (const ClangASTType &type, bool extern_c) { assert (type && "Type for variable must be valid!"); @@ -1902,15 +1945,26 @@ NameSearchContext::AddFunDecl (const ClangASTType &type) const bool isInlineSpecified = false; const bool hasWrittenPrototype = true; const bool isConstexprSpecified = false; + + clang::DeclContext *context = const_cast<DeclContext*>(m_decl_context); + + if (extern_c) { + context = LinkageSpecDecl::Create(*ast, + context, + SourceLocation(), + SourceLocation(), + clang::LinkageSpecDecl::LanguageIDs::lang_c, + false); + } clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast, - const_cast<DeclContext*>(m_decl_context), + context, SourceLocation(), SourceLocation(), m_decl_name.getAsIdentifierInfo(), qual_type, NULL, - SC_Static, + SC_Extern, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified); @@ -1933,7 +1987,7 @@ NameSearchContext::AddFunDecl (const ClangASTType &type) QualType arg_qual_type (func_proto_type->getParamType(ArgIndex)); parm_var_decls.push_back(ParmVarDecl::Create (*ast, - const_cast<DeclContext*>(m_decl_context), + const_cast<DeclContext*>(context), SourceLocation(), SourceLocation(), NULL, @@ -1969,7 +2023,7 @@ NameSearchContext::AddGenericFunDecl() ArrayRef<QualType>(), // argument types proto_info)); - return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type)); + return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type), true); } clang::NamedDecl * @@ -2008,7 +2062,7 @@ NameSearchContext::AddTypeDecl(const ClangASTType &clang_type) } void -NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result) +NameSearchContext::AddLookupResult (clang::DeclContextLookupResult result) { for (clang::NamedDecl *decl : result) m_decls.push_back (decl); diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp index e302737..2c66a0a 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Expression/ClangExpressionDeclMap.h" +#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Decl.h" @@ -22,6 +23,7 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/ASTDumper.h" #include "lldb/Expression/ClangASTSource.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/Materializer.h" #include "lldb/Host/Endian.h" @@ -110,6 +112,13 @@ ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx, } void +ClangExpressionDeclMap::InstallCodeGenerator (clang::ASTConsumer *code_gen) +{ + assert(m_parser_vars); + m_parser_vars->m_code_gen = code_gen; +} + +void ClangExpressionDeclMap::DidParse() { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -492,33 +501,56 @@ FindCodeSymbolInContext SymbolContextList &sc_list ) { + sc_list.Clear(); SymbolContextList temp_sc_list; if (sym_ctx.module_sp) - sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list); - - if (!sc_list.GetSize() && sym_ctx.target_sp) - sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list); + sym_ctx.module_sp->FindFunctions(name, + NULL, + eFunctionNameTypeAuto, + true, // include_symbols + false, // include_inlines + true, // append + temp_sc_list); + if (temp_sc_list.GetSize() == 0) + { + if (sym_ctx.target_sp) + sym_ctx.target_sp->GetImages().FindFunctions(name, + eFunctionNameTypeAuto, + true, // include_symbols + false, // include_inlines + true, // append + temp_sc_list); + } + SymbolContextList internal_symbol_sc_list; unsigned temp_sc_list_size = temp_sc_list.GetSize(); for (unsigned i = 0; i < temp_sc_list_size; i++) { - SymbolContext sym_ctx; - temp_sc_list.GetContextAtIndex(i, sym_ctx); - if (sym_ctx.symbol) + SymbolContext sc; + temp_sc_list.GetContextAtIndex(i, sc); + if (sc.function) { - switch (sym_ctx.symbol->GetType()) + sc_list.Append(sc); + } + else if (sc.symbol) + { + if (sc.symbol->IsExternal()) { - case eSymbolTypeCode: - case eSymbolTypeResolver: - case eSymbolTypeReExported: - sc_list.Append(sym_ctx); - break; - - default: - break; + sc_list.Append(sc); + } + else + { + internal_symbol_sc_list.Append(sc); } } } + + // If we had internal symbols and we didn't find any external symbols or + // functions in debug info, then fallback to the internal symbols + if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize()) + { + sc_list = internal_symbol_sc_list; + } } bool @@ -564,31 +596,15 @@ ClangExpressionDeclMap::GetFunctionAddress sc_list_size = sc_list.GetSize(); } } - - if (sc_list_size == 0) - { - // Sometimes we get a mangled name for a global function that actually should be "extern C." - // This is a hack to compensate. - - const bool is_mangled = true; - Mangled mangled(name, is_mangled); - - CPPLanguageRuntime::MethodName method_name(mangled.GetDemangledName()); - - llvm::StringRef basename = method_name.GetBasename(); - - if (!basename.empty()) - { - FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); - sc_list_size = sc_list.GetSize(); - } - } + + lldb::addr_t intern_callable_load_addr = LLDB_INVALID_ADDRESS; for (uint32_t i=0; i<sc_list_size; ++i) { SymbolContext sym_ctx; sc_list.GetContextAtIndex(i, sym_ctx); + lldb::addr_t callable_load_addr = LLDB_INVALID_ADDRESS; if (sym_ctx.function) @@ -601,7 +617,13 @@ ClangExpressionDeclMap::GetFunctionAddress } else if (sym_ctx.symbol) { - callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target); + if (sym_ctx.symbol->IsExternal()) + callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target); + else + { + if (intern_callable_load_addr == LLDB_INVALID_ADDRESS) + intern_callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target); + } } if (callable_load_addr != LLDB_INVALID_ADDRESS) @@ -610,6 +632,14 @@ ClangExpressionDeclMap::GetFunctionAddress return true; } } + + // See if we found an internal symbol + if (intern_callable_load_addr != LLDB_INVALID_ADDRESS) + { + func_addr = intern_callable_load_addr; + return true; + } + return false; } @@ -635,74 +665,71 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target, SymbolContext sym_ctx; sc_list.GetContextAtIndex(i, sym_ctx); - const Address *sym_address = &sym_ctx.symbol->GetAddress(); + const Address sym_address = sym_ctx.symbol->GetAddress(); - if (!sym_address || !sym_address->IsValid()) + if (!sym_address.IsValid()) continue; - if (sym_address) + switch (sym_ctx.symbol->GetType()) { - switch (sym_ctx.symbol->GetType()) - { - case eSymbolTypeCode: - case eSymbolTypeTrampoline: - symbol_load_addr = sym_address->GetCallableLoadAddress (&target); - break; + case eSymbolTypeCode: + case eSymbolTypeTrampoline: + symbol_load_addr = sym_address.GetCallableLoadAddress (&target); + break; - case eSymbolTypeResolver: - symbol_load_addr = sym_address->GetCallableLoadAddress (&target, true); - break; + case eSymbolTypeResolver: + symbol_load_addr = sym_address.GetCallableLoadAddress (&target, true); + break; - case eSymbolTypeReExported: + case eSymbolTypeReExported: + { + ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName(); + if (reexport_name) { - ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName(); - if (reexport_name) + ModuleSP reexport_module_sp; + ModuleSpec reexport_module_spec; + reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary(); + if (reexport_module_spec.GetPlatformFileSpec()) { - ModuleSP reexport_module_sp; - ModuleSpec reexport_module_spec; - reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary(); - if (reexport_module_spec.GetPlatformFileSpec()) + reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); + if (!reexport_module_sp) { + reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear(); reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); - if (!reexport_module_sp) - { - reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear(); - reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); - } } - symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get()); } + symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get()); } - break; - - case eSymbolTypeData: - case eSymbolTypeRuntime: - case eSymbolTypeVariable: - case eSymbolTypeLocal: - case eSymbolTypeParam: - case eSymbolTypeInvalid: - case eSymbolTypeAbsolute: - case eSymbolTypeException: - case eSymbolTypeSourceFile: - case eSymbolTypeHeaderFile: - case eSymbolTypeObjectFile: - case eSymbolTypeCommonBlock: - case eSymbolTypeBlock: - case eSymbolTypeVariableType: - case eSymbolTypeLineEntry: - case eSymbolTypeLineHeader: - case eSymbolTypeScopeBegin: - case eSymbolTypeScopeEnd: - case eSymbolTypeAdditional: - case eSymbolTypeCompiler: - case eSymbolTypeInstrumentation: - case eSymbolTypeUndefined: - case eSymbolTypeObjCClass: - case eSymbolTypeObjCMetaClass: - case eSymbolTypeObjCIVar: - symbol_load_addr = sym_address->GetLoadAddress (&target); - break; - } + } + break; + + case eSymbolTypeData: + case eSymbolTypeRuntime: + case eSymbolTypeVariable: + case eSymbolTypeLocal: + case eSymbolTypeParam: + case eSymbolTypeInvalid: + case eSymbolTypeAbsolute: + case eSymbolTypeException: + case eSymbolTypeSourceFile: + case eSymbolTypeHeaderFile: + case eSymbolTypeObjectFile: + case eSymbolTypeCommonBlock: + case eSymbolTypeBlock: + case eSymbolTypeVariableType: + case eSymbolTypeLineEntry: + case eSymbolTypeLineHeader: + case eSymbolTypeScopeBegin: + case eSymbolTypeScopeEnd: + case eSymbolTypeAdditional: + case eSymbolTypeCompiler: + case eSymbolTypeInstrumentation: + case eSymbolTypeUndefined: + case eSymbolTypeObjCClass: + case eSymbolTypeObjCMetaClass: + case eSymbolTypeObjCIVar: + symbol_load_addr = sym_address.GetLoadAddress (&target); + break; } } @@ -750,9 +777,9 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target, if (sym_ctx.symbol) { const Symbol *symbol = sym_ctx.symbol; - const Address *sym_address = &symbol->GetAddress(); + const Address sym_address = symbol->GetAddress(); - if (sym_address && sym_address->IsValid()) + if (sym_address.IsValid()) { switch (symbol->GetType()) { @@ -789,6 +816,11 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target, reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); } } + // Don't allow us to try and resolve a re-exported symbol if it is the same + // as the current symbol + if (name == symbol->GetReExportedSymbolName() && module == reexport_module_sp.get()) + return NULL; + return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get()); } } @@ -1053,7 +1085,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, { // This branch will get hit if we are executing code in the context of a function that // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a - // method of the class. In that case, just look up the "this" variable in the the current + // method of the class. In that case, just look up the "this" variable in the current // scope and use its type. // FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer // for C++ so it hasn't actually been tested. @@ -1172,7 +1204,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, { // This branch will get hit if we are executing code in the context of a function that // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a - // method of the class. In that case, just look up the "self" variable in the the current + // method of the class. In that case, just look up the "self" variable in the current // scope and use its type. VariableList *vars = frame->GetVariableList(false); @@ -1442,6 +1474,87 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, } } } + + if (!context.m_found.function_with_type_info) + { + // Try the modules next. + + do + { + if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor()) + { + bool append = false; + uint32_t max_matches = 1; + std::vector <clang::NamedDecl *> decls; + + if (!modules_decl_vendor->FindDecls(name, + append, + max_matches, + decls)) + break; + + clang::NamedDecl *const decl_from_modules = decls[0]; + + if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) + { + if (log) + { + log->Printf(" CAS::FEVD[%u] Matching function found for \"%s\" in the modules", + current_id, + name.GetCString()); + } + + clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules); + clang::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr; + + if (!copied_function_decl) + { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a function declaration from the modules", + current_id); + + break; + } + + if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) + { + DeclGroupRef decl_group_ref(copied_function_decl); + m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref); + } + + context.AddNamedDecl(copied_function_decl); + + context.m_found.function_with_type_info = true; + context.m_found.function = true; + } + else if (llvm::isa<clang::VarDecl>(decl_from_modules)) + { + if (log) + { + log->Printf(" CAS::FEVD[%u] Matching variable found for \"%s\" in the modules", + current_id, + name.GetCString()); + } + + clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules); + clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr; + + if (!copied_var_decl) + { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a variable declaration from the modules", + current_id); + + break; + } + + context.AddNamedDecl(copied_var_decl); + + context.m_found.variable = true; + } + } + } while (0); + } if (target && !context.m_found.variable && !namespace_decl) { @@ -1727,7 +1840,7 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, entity->EnableParserVars(GetParserID()); ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); - const Address &symbol_address = symbol.GetAddress(); + const Address symbol_address = symbol.GetAddress(); lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target); //parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); @@ -1866,7 +1979,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); NamedDecl *function_decl = NULL; - const Address *fun_address = NULL; + Address fun_address; ClangASTType function_clang_type; bool is_indirect_function = false; @@ -1891,7 +2004,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, return; } - fun_address = &function->GetAddressRange().GetBaseAddress(); + fun_address = function->GetAddressRange().GetBaseAddress(); ClangASTType copied_function_type = GuardedCopyType(function_clang_type); if (copied_function_type) @@ -1925,7 +2038,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, } else if (symbol) { - fun_address = &symbol->GetAddress(); + fun_address = symbol->GetAddress(); function_decl = context.AddGenericFunDecl(); is_indirect_function = symbol->IsIndirect(); } @@ -1938,7 +2051,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); - lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function); + lldb::addr_t load_addr = fun_address.GetCallableLoadAddress(target, is_indirect_function); ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), m_parser_vars->m_target_info.byte_order, @@ -1961,7 +2074,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, { // We have to try finding a file address. - lldb::addr_t file_addr = fun_address->GetFileAddress(); + lldb::addr_t file_addr = fun_address.GetFileAddress(); parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress); parser_vars->m_lldb_value.GetScalar() = file_addr; @@ -1977,7 +2090,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, StreamString ss; - fun_address->Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); + fun_address.Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s", current_id, diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp index 4906108..2b344b0 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" - #include "lldb/Expression/ClangExpressionParser.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" @@ -23,6 +22,7 @@ #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangModulesDeclVendor.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/IRInterpreter.h" @@ -95,12 +95,15 @@ std::string GetBuiltinIncludePath(const char *Argv0) { class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks { - ClangModulesDeclVendor &m_decl_vendor; - StreamString m_error_stream; - bool m_has_errors = false; + ClangModulesDeclVendor &m_decl_vendor; + ClangPersistentVariables &m_persistent_vars; + StreamString m_error_stream; + bool m_has_errors = false; public: - LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor) : - m_decl_vendor(decl_vendor) + LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor, + ClangPersistentVariables &persistent_vars) : + m_decl_vendor(decl_vendor), + m_persistent_vars(persistent_vars) { } @@ -108,19 +111,26 @@ public: ModuleIdPath path, const clang::Module * /*null*/) { - std::vector<llvm::StringRef> string_path; + std::vector<ConstString> string_path; for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) { - string_path.push_back(component.first->getName()); + string_path.push_back(ConstString(component.first->getName())); } StreamString error_stream; - if (!m_decl_vendor.AddModule(string_path, m_error_stream)) + ClangModulesDeclVendor::ModuleVector exported_modules; + + if (!m_decl_vendor.AddModule(string_path, &exported_modules, m_error_stream)) { m_has_errors = true; } + + for (ClangModulesDeclVendor::ModuleID module : exported_modules) + { + m_persistent_vars.AddHandLoadedClangModule(module); + } } bool hasErrors() @@ -227,6 +237,9 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, if (expr.DesiredResultType() == ClangExpression::eResultTypeId) m_compiler->getLangOpts().DebuggerCastResultToId = true; + m_compiler->getLangOpts().CharIsSigned = + ArchSpec(m_compiler->getTargetOpts().Triple.c_str()).CharIsSignedByDefault(); + // Spell checking is a nice feature, but it ends up completing a // lot of types that we didn't strictly speaking need to complete. // As a result, we spend a long time parsing and importing debug @@ -294,7 +307,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor()) { - std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor)); + std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor, target_sp->GetPersistentVariables())); m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get()); m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); } @@ -305,10 +318,10 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_builtin_context.reset(new Builtin::Context()); std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(), - m_compiler->getSourceManager(), - m_compiler->getPreprocessor().getIdentifierTable(), - *m_selector_table.get(), - *m_builtin_context.get())); + m_compiler->getSourceManager(), + m_compiler->getPreprocessor().getIdentifierTable(), + *m_selector_table.get(), + *m_builtin_context.get())); ast_context->InitBuiltinTypes(m_compiler->getTarget()); @@ -328,8 +341,9 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_llvm_context.reset(new LLVMContext()); m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(), module_name, + m_compiler->getHeaderSearchOpts(), + m_compiler->getPreprocessorOpts(), m_compiler->getCodeGenOpts(), - m_compiler->getTargetOpts(), *m_llvm_context)); } @@ -395,6 +409,9 @@ ClangExpressionParser::Parse (Stream &stream) ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get()); + if (ClangExpressionDeclMap *decl_map = m_expr.DeclMap()) + decl_map->InstallCodeGenerator(m_code_generator.get()); + if (ast_transformer) ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext()); else @@ -524,10 +541,11 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule()); Error interpret_error; + Process *process = exe_ctx.GetProcessPtr(); - can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error); + bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls(); + can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls); - Process *process = exe_ctx.GetProcessPtr(); if (!ir_can_run) { diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangModulesDeclVendor.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangModulesDeclVendor.cpp index 46adaaf..e825363 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ClangModulesDeclVendor.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ClangModulesDeclVendor.cpp @@ -7,12 +7,18 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/StreamString.h" +#include <mutex> // std::once + #include "lldb/Expression/ClangModulesDeclVendor.h" + +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBAssert.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" @@ -22,7 +28,6 @@ #include "clang/Sema/Lookup.h" #include "clang/Serialization/ASTReader.h" -#include <mutex> using namespace lldb_private; @@ -58,25 +63,52 @@ namespace { std::unique_ptr<clang::Parser> &&parser); virtual bool - AddModule(std::vector<llvm::StringRef> &path, - Stream &error_stream); + AddModule(ModulePath &path, + ModuleVector *exported_modules, + Stream &error_stream) override; + + virtual bool + AddModulesForCompileUnit(CompileUnit &cu, + ModuleVector &exported_modules, + Stream &error_stream) override; virtual uint32_t FindDecls (const ConstString &name, bool append, uint32_t max_matches, - std::vector <clang::NamedDecl*> &decls); + std::vector <clang::NamedDecl*> &decls) override; + + virtual void + ForEachMacro(const ModuleVector &modules, + std::function<bool (const std::string &)> handler) override; ~ClangModulesDeclVendorImpl(); private: + void + ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports, + clang::Module *module); + + void + ReportModuleExports (ModuleVector &exports, + clang::Module *module); + clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path, bool make_visible); + bool m_enabled = false; + llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine; llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation; std::unique_ptr<clang::CompilerInstance> m_compiler_instance; std::unique_ptr<clang::Parser> m_parser; + size_t m_source_location_index = 0; // used to give name components fake SourceLocations + + typedef std::vector<ConstString> ImportedModule; + typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap; + typedef std::set<ModuleID> ImportedModuleSet; + ImportedModuleMap m_imported_modules; + ImportedModuleSet m_user_imported_modules; }; } @@ -149,12 +181,47 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr< m_diagnostics_engine(diagnostics_engine), m_compiler_invocation(compiler_invocation), m_compiler_instance(std::move(compiler_instance)), - m_parser(std::move(parser)) + m_parser(std::move(parser)), + m_imported_modules() { } +void +ClangModulesDeclVendorImpl::ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports, + clang::Module *module) +{ + if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module))) + return; + + exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)); + + llvm::SmallVector<clang::Module*, 2> sub_exports; + + module->getExportedModules(sub_exports); + + for (clang::Module *module : sub_exports) + { + ReportModuleExportsHelper(exports, module); + } +} + +void +ClangModulesDeclVendorImpl::ReportModuleExports (ClangModulesDeclVendor::ModuleVector &exports, + clang::Module *module) +{ + std::set<ClangModulesDeclVendor::ModuleID> exports_set; + + ReportModuleExportsHelper(exports_set, module); + + for (ModuleID module : exports_set) + { + exports.push_back(module); + } +} + bool -ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, +ClangModulesDeclVendorImpl::AddModule(ModulePath &path, + ModuleVector *exported_modules, Stream &error_stream) { // Fail early. @@ -165,22 +232,43 @@ ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, return false; } - if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0])) + // Check if we've already imported this module. + + std::vector<ConstString> imported_module; + + for (ConstString path_component : path) + { + imported_module.push_back(path_component); + } + + { + ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module); + + if (mi != m_imported_modules.end()) + { + if (exported_modules) + { + ReportModuleExports(*exported_modules, mi->second); + } + return true; + } + } + + if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0].GetStringRef())) { - error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].str().c_str()); + error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].AsCString()); return false; } llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4> clang_path; { - size_t source_loc_counter = 0; clang::SourceManager &source_manager = m_compiler_instance->getASTContext().getSourceManager(); - for (llvm::StringRef &component : path) + for (ConstString path_component : path) { - clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(component), - source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(source_loc_counter++))); + clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(path_component.GetStringRef()), + source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(m_source_location_index++))); } } @@ -193,7 +281,7 @@ ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, if (!top_level_module) { diagnostic_consumer->DumpDiagnostics(error_stream); - error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].str().c_str()); + error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].AsCString()); return false; } @@ -201,7 +289,7 @@ ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, for (size_t ci = 1; ci < path.size(); ++ci) { - llvm::StringRef &component = path[ci]; + llvm::StringRef component = path[ci].GetStringRef(); submodule = submodule->findSubmodule(component.str()); if (!submodule) { @@ -213,7 +301,66 @@ ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, clang::Module *requested_module = DoGetModule(clang_path, true); - return (requested_module != nullptr); + if (requested_module != nullptr) + { + if (exported_modules) + { + ReportModuleExports(*exported_modules, requested_module); + } + + m_imported_modules[imported_module] = requested_module; + + m_enabled = true; + + return true; + } + + return false; +} + + +bool +ClangModulesDeclVendor::LanguageSupportsClangModules (lldb::LanguageType language) +{ + switch (language) + { + default: + return false; + // C++ and friends to be added + case lldb::LanguageType::eLanguageTypeC: + case lldb::LanguageType::eLanguageTypeC11: + case lldb::LanguageType::eLanguageTypeC89: + case lldb::LanguageType::eLanguageTypeC99: + case lldb::LanguageType::eLanguageTypeObjC: + return true; + } +} + +bool +ClangModulesDeclVendorImpl::AddModulesForCompileUnit(CompileUnit &cu, + ClangModulesDeclVendor::ModuleVector &exported_modules, + Stream &error_stream) +{ + if (LanguageSupportsClangModules(cu.GetLanguage())) + { + std::vector<ConstString> imported_modules = cu.GetImportedModules(); + + for (ConstString imported_module : imported_modules) + { + std::vector<ConstString> path; + + path.push_back(imported_module); + + if (!AddModule(path, &exported_modules, error_stream)) + { + return false; + } + } + + return true; + } + + return true; } // ClangImporter::lookupValue @@ -224,6 +371,11 @@ ClangModulesDeclVendorImpl::FindDecls (const ConstString &name, uint32_t max_matches, std::vector <clang::NamedDecl*> &decls) { + if (!m_enabled) + { + return 0; + } + if (!append) decls.clear(); @@ -250,6 +402,201 @@ ClangModulesDeclVendorImpl::FindDecls (const ConstString &name, return num_matches; } +void +ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVector &modules, + std::function<bool (const std::string &)> handler) +{ + if (!m_enabled) + { + return; + } + + typedef std::map<ModuleID, ssize_t> ModulePriorityMap; + ModulePriorityMap module_priorities; + + ssize_t priority = 0; + + for (ModuleID module : modules) + { + module_priorities[module] = priority++; + } + + if (m_compiler_instance->getPreprocessor().getExternalSource()) + { + m_compiler_instance->getPreprocessor().getExternalSource()->ReadDefinedMacros(); + } + + for (clang::Preprocessor::macro_iterator mi = m_compiler_instance->getPreprocessor().macro_begin(), + me = m_compiler_instance->getPreprocessor().macro_end(); + mi != me; + ++mi) + { + const clang::IdentifierInfo *ii = nullptr; + + { + if (clang::IdentifierInfoLookup *lookup = m_compiler_instance->getPreprocessor().getIdentifierTable().getExternalIdentifierLookup()) + { + lookup->get(mi->first->getName()); + } + if (!ii) + { + ii = mi->first; + } + } + + ssize_t found_priority = -1; + clang::MacroInfo *macro_info = nullptr; + + for (clang::ModuleMacro *module_macro : m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) + { + clang::Module *module = module_macro->getOwningModule(); + + { + ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(module)); + + if (pi != module_priorities.end() && pi->second > found_priority) + { + macro_info = module_macro->getMacroInfo(); + found_priority = pi->second; + } + } + + clang::Module *top_level_module = module->getTopLevelModule(); + + if (top_level_module != module) + { + ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(top_level_module)); + + if ((pi != module_priorities.end()) && pi->second > found_priority) + { + macro_info = module_macro->getMacroInfo(); + found_priority = pi->second; + } + } + } + + if (macro_info) + { + std::string macro_expansion = "#define "; + macro_expansion.append(mi->first->getName().str().c_str()); + + { + if (macro_info->isFunctionLike()) + { + macro_expansion.append("("); + + bool first_arg = true; + + for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(), + ae = macro_info->arg_end(); + ai != ae; + ++ai) + { + if (!first_arg) + { + macro_expansion.append(", "); + } + else + { + first_arg = false; + } + + macro_expansion.append((*ai)->getName().str()); + } + + if (macro_info->isC99Varargs()) + { + if (first_arg) + { + macro_expansion.append("..."); + } + else + { + macro_expansion.append(", ..."); + } + } + else if (macro_info->isGNUVarargs()) + { + macro_expansion.append("..."); + } + + macro_expansion.append(")"); + } + + macro_expansion.append(" "); + + bool first_token = true; + + for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(), + te = macro_info->tokens_end(); + ti != te; + ++ti) + { + if (!first_token) + { + macro_expansion.append(" "); + } + else + { + first_token = false; + } + + if (ti->isLiteral()) + { + if (const char *literal_data = ti->getLiteralData()) + { + std::string token_str(literal_data, ti->getLength()); + macro_expansion.append(token_str); + } + else + { + bool invalid = false; + const char *literal_source = m_compiler_instance->getSourceManager().getCharacterData(ti->getLocation(), &invalid); + + if (invalid) + { + lldbassert(!"Unhandled token kind"); + macro_expansion.append("<unknown literal value>"); + } + else + { + macro_expansion.append(std::string(literal_source, ti->getLength())); + } + } + } + else if (const char *punctuator_spelling = clang::tok::getPunctuatorSpelling(ti->getKind())) + { + macro_expansion.append(punctuator_spelling); + } + else if (const char *keyword_spelling = clang::tok::getKeywordSpelling(ti->getKind())) + { + macro_expansion.append(keyword_spelling); + } + else + { + switch (ti->getKind()) + { + case clang::tok::TokenKind::identifier: + macro_expansion.append(ti->getIdentifierInfo()->getName().str()); + break; + case clang::tok::TokenKind::raw_identifier: + macro_expansion.append(ti->getRawIdentifier().str()); + default: + macro_expansion.append(ti->getName()); + break; + } + } + } + + if (handler(macro_expansion)) + { + return; + } + } + } + } +} + ClangModulesDeclVendorImpl::~ClangModulesDeclVendorImpl() { } @@ -289,7 +636,7 @@ ClangModulesDeclVendor::Create(Target &target) "-Werror=non-modular-include-in-framework-module" }; - target.GetPlatform()->AddClangModuleCompilationOptions(compiler_invocation_arguments); + target.GetPlatform()->AddClangModuleCompilationOptions(&target, compiler_invocation_arguments); compiler_invocation_arguments.push_back(ModuleImportBufferName); @@ -306,6 +653,18 @@ ClangModulesDeclVendor::Create(Target &target) compiler_invocation_arguments.push_back(module_cache_argument); } + FileSpecList &module_search_paths = target.GetClangModuleSearchPaths(); + + for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) + { + const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi); + + std::string search_path_argument = "-I"; + search_path_argument.append(search_path.GetPath()); + + compiler_invocation_arguments.push_back(search_path_argument); + } + { FileSpec clang_resource_dir = GetResourceDir(); diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp index 5514846..0da70e2 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp @@ -26,6 +26,8 @@ #include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangExpressionParser.h" #include "lldb/Expression/ClangFunction.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/ClangUserExpression.h" #include "lldb/Expression/ExpressionSourceCode.h" #include "lldb/Expression/IRExecutionUnit.h" @@ -70,9 +72,9 @@ ClangUserExpression::ClangUserExpression (const char *expr, m_result_synthesizer(), m_jit_module_wp(), m_enforce_valid_object (true), - m_cplusplus (false), - m_objectivec (false), - m_static_method(false), + m_in_cplusplus_method (false), + m_in_objectivec_method (false), + m_in_static_method(false), m_needs_object_ptr (false), m_const_object (false), m_target (NULL), @@ -194,7 +196,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) } } - m_cplusplus = true; + m_in_cplusplus_method = true; m_needs_object_ptr = true; } } @@ -225,17 +227,17 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) } } - m_objectivec = true; + m_in_objectivec_method = true; m_needs_object_ptr = true; if (!method_decl->isInstanceMethod()) - m_static_method = true; + m_in_static_method = true; } } else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context)) { // We might also have a function that said in the debug information that it captured an - // object pointer. The best way to deal with getting to the ivars at present it by pretending + // object pointer. The best way to deal with getting to the ivars at present is by pretending // that this is a method of a class in whatever runtime the debug info says the object pointer // belongs to. Do that here. @@ -268,7 +270,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) } } - m_cplusplus = true; + m_in_cplusplus_method = true; m_needs_object_ptr = true; } else if (language == lldb::eLanguageTypeObjC) @@ -317,7 +319,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) } else if (self_clang_type.IsObjCObjectPointerType()) { - m_objectivec = true; + m_in_objectivec_method = true; m_needs_object_ptr = true; } else @@ -328,7 +330,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) } else { - m_objectivec = true; + m_in_objectivec_method = true; m_needs_object_ptr = true; } } @@ -452,18 +454,51 @@ ClangUserExpression::Parse (Stream &error_stream, ApplyObjcCastHack(m_expr_text); //ApplyUnicharHack(m_expr_text); - std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str())); + std::string prefix = m_expr_prefix; + + if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor()) + { + const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = m_target->GetPersistentVariables().GetHandLoadedClangModules(); + ClangModulesDeclVendor::ModuleVector modules_for_macros; + + for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) + { + modules_for_macros.push_back(module); + } + if (m_target->GetEnableAutoImportClangModules()) + { + if (StackFrame *frame = exe_ctx.GetFramePtr()) + { + if (Block *block = frame->GetFrameBlock()) + { + SymbolContext sc; + + block->CalculateSymbolContext(&sc); + + if (sc.comp_unit) + { + StreamString error_stream; + + decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream); + } + } + } + } + } + + std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str())); + lldb::LanguageType lang_type; - if (m_cplusplus) + if (m_in_cplusplus_method) lang_type = lldb::eLanguageTypeC_plus_plus; - else if(m_objectivec) + else if (m_in_objectivec_method) lang_type = lldb::eLanguageTypeObjC; else lang_type = lldb::eLanguageTypeC; - if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method, exe_ctx)) + if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx)) { error_stream.PutCString ("error: couldn't construct expression body"); return false; @@ -666,11 +701,11 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, { ConstString object_name; - if (m_cplusplus) + if (m_in_cplusplus_method) { object_name.SetCString("this"); } - else if (m_objectivec) + else if (m_in_objectivec_method) { object_name.SetCString("self"); } @@ -690,7 +725,7 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, object_ptr = 0; } - if (m_objectivec) + if (m_in_objectivec_method) { ConstString cmd_name("_cmd"); @@ -799,7 +834,7 @@ lldb::ExpressionResults ClangUserExpression::Execute (Stream &error_stream, ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, - ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, + lldb::ClangUserExpressionSP &shared_ptr_to_me, lldb::ClangExpressionVariableSP &result) { // The expression log is quite verbose, and if you're just tracking the execution of the @@ -841,7 +876,7 @@ ClangUserExpression::Execute (Stream &error_stream, { args.push_back(object_ptr); - if (m_objectivec) + if (m_in_objectivec_method) args.push_back(cmd_ptr); } @@ -856,7 +891,8 @@ ClangUserExpression::Execute (Stream &error_stream, *m_execution_unit_sp.get(), interpreter_error, function_stack_bottom, - function_stack_top); + function_stack_top, + exe_ctx); if (!interpreter_error.Success()) { @@ -878,7 +914,7 @@ ClangUserExpression::Execute (Stream &error_stream, if (m_needs_object_ptr) { args.push_back(object_ptr); - if (m_objectivec) + if (m_in_objectivec_method) args.push_back(cmd_ptr); } @@ -1008,7 +1044,22 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, if (process == NULL || !process->CanJIT()) execution_policy = eExecutionPolicyNever; - ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type)); + const char *full_prefix = NULL; + const char *option_prefix = options.GetPrefix(); + std::string full_prefix_storage; + if (expr_prefix && option_prefix) + { + full_prefix_storage.assign(expr_prefix); + full_prefix_storage.append(option_prefix); + if (!full_prefix_storage.empty()) + full_prefix = full_prefix_storage.c_str(); + } + else if (expr_prefix) + full_prefix = expr_prefix; + else + full_prefix = option_prefix; + + lldb::ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, full_prefix, language, desired_type)); StreamString error_stream; @@ -1031,10 +1082,11 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, keep_expression_in_memory, generate_debug_info)) { + execution_results = lldb::eExpressionParseError; if (error_stream.GetString().empty()) - error.SetExpressionError (lldb::eExpressionParseError, "expression failed to parse, unknown error"); + error.SetExpressionError (execution_results, "expression failed to parse, unknown error"); else - error.SetExpressionError (lldb::eExpressionParseError, error_stream.GetString().c_str()); + error.SetExpressionError (execution_results, error_stream.GetString().c_str()); } else { diff --git a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp index 827bddd..9307c84 100644 --- a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp @@ -30,8 +30,6 @@ #include "lldb/Host/Endian.h" #include "lldb/Host/Host.h" -#include "lldb/lldb-private-log.h" - #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -611,7 +609,6 @@ DWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset)); break; -// case DW_OP_form_tls_address: s << "form_tls_address"; break; // 0x9b DWARF3 // case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break; // 0x9c DWARF3 // case DW_OP_bit_piece: // 0x9d DWARF3 2 // s->Printf("DW_OP_bit_piece(0x%x, 0x%x)", m_data.GetULEB128(&offset), m_data.GetULEB128(&offset)); @@ -624,6 +621,9 @@ DWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t // case DW_OP_APPLE_array_ref: // s->PutCString("DW_OP_APPLE_array_ref"); // break; + case DW_OP_form_tls_address: + s->PutCString("DW_OP_form_tls_address"); // 0x9b + break; case DW_OP_GNU_push_tls_address: s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0 break; @@ -2198,6 +2198,13 @@ DWARFExpression::Evaluate // constant. //---------------------------------------------------------------------- case DW_OP_bra: + if (stack.empty()) + { + if (error_ptr) + error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_bra."); + return false; + } + else { tmp = stack.back(); stack.pop_back(); @@ -2890,17 +2897,24 @@ DWARFExpression::Evaluate break; //---------------------------------------------------------------------- - // OPCODE: DW_OP_GNU_push_tls_address + // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension opcode, DW_OP_GNU_push_tls_address) // OPERANDS: none // DESCRIPTION: Pops a TLS offset from the stack, converts it to - // an absolute value, and pushes it back on. + // an address in the current thread's thread-local storage block, + // and pushes it on the stack. //---------------------------------------------------------------------- + case DW_OP_form_tls_address: case DW_OP_GNU_push_tls_address: { if (stack.size() < 1) { if (error_ptr) - error_ptr->SetErrorString("DW_OP_GNU_push_tls_address needs an argument."); + { + if (op == DW_OP_form_tls_address) + error_ptr->SetErrorString("DW_OP_form_tls_address needs an argument."); + else + error_ptr->SetErrorString("DW_OP_GNU_push_tls_address needs an argument."); + } return false; } diff --git a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp index 080562e..9a42510 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp @@ -10,24 +10,33 @@ #include "lldb/Expression/ExpressionSourceCode.h" #include "lldb/Core/StreamString.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" +#include "lldb/Expression/ClangPersistentVariables.h" +#include "lldb/Symbol/Block.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" +#include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" using namespace lldb_private; const char * ExpressionSourceCode::g_expression_prefix = R"( -#undef NULL -#undef Nil -#undef nil -#undef YES -#undef NO +#ifndef NULL #define NULL (__null) +#endif +#ifndef Nil #define Nil (__null) +#endif +#ifndef nil #define nil (__null) +#endif +#ifndef YES #define YES ((BOOL)1) +#endif +#ifndef NO #define NO ((BOOL)0) +#endif typedef __INT8_TYPE__ int8_t; typedef __UINT8_TYPE__ uint8_t; typedef __INT16_TYPE__ int16_t; @@ -41,13 +50,17 @@ typedef __UINTPTR_TYPE__ uintptr_t; typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef unsigned short unichar; +extern "C" +{ + int printf(const char * __restrict, ...); +} )"; bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const { const char *target_specific_defines = "typedef signed char BOOL;\n"; - static ConstString g_platform_ios_simulator ("PlatformiOSSimulator"); + std::string module_macros; if (Target *target = exe_ctx.GetTargetPtr()) { @@ -59,12 +72,51 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi { if (lldb::PlatformSP platform_sp = target->GetPlatform()) { + static ConstString g_platform_ios_simulator ("ios-simulator"); if (platform_sp->GetPluginName() == g_platform_ios_simulator) { target_specific_defines = "typedef bool BOOL;\n"; } } } + + if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor()) + { + const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = target->GetPersistentVariables().GetHandLoadedClangModules(); + ClangModulesDeclVendor::ModuleVector modules_for_macros; + + for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) + { + modules_for_macros.push_back(module); + } + + if (target->GetEnableAutoImportClangModules()) + { + if (StackFrame *frame = exe_ctx.GetFramePtr()) + { + if (Block *block = frame->GetFrameBlock()) + { + SymbolContext sc; + + block->CalculateSymbolContext(&sc); + + if (sc.comp_unit) + { + StreamString error_stream; + + decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream); + } + } + } + } + + decl_vendor->ForEachMacro(modules_for_macros, [&module_macros] (const std::string &expansion) -> bool { + module_macros.append(expansion); + module_macros.append("\n"); + return false; + }); + } + } if (m_wrap) @@ -81,37 +133,31 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi StreamString wrap_stream; + wrap_stream.Printf("%s\n%s\n%s\n%s\n", + module_macros.c_str(), + g_expression_prefix, + target_specific_defines, + m_prefix.c_str()); + switch (wrapping_language) { default: break; case lldb::eLanguageTypeC: - wrap_stream.Printf("%s \n" - "%s \n" - "%s \n" - "void \n" + wrap_stream.Printf("void \n" "%s(void *$__lldb_arg) \n" "{ \n" " %s; \n" "} \n", - g_expression_prefix, - target_specific_defines, - m_prefix.c_str(), m_name.c_str(), m_body.c_str()); break; case lldb::eLanguageTypeC_plus_plus: - wrap_stream.Printf("%s \n" - "%s \n" - "%s \n" - "void \n" + wrap_stream.Printf("void \n" "$__lldb_class::%s(void *$__lldb_arg) %s\n" "{ \n" " %s; \n" "} \n", - g_expression_prefix, - target_specific_defines, - m_prefix.c_str(), m_name.c_str(), (const_object ? "const" : ""), m_body.c_str()); @@ -119,10 +165,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi case lldb::eLanguageTypeObjC: if (static_method) { - wrap_stream.Printf("%s \n" - "%s \n" - "%s \n" - "@interface $__lldb_objc_class ($__lldb_category) \n" + wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category) \n" "+(void)%s:(void *)$__lldb_arg; \n" "@end \n" "@implementation $__lldb_objc_class ($__lldb_category) \n" @@ -131,19 +174,13 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi " %s; \n" "} \n" "@end \n", - g_expression_prefix, - target_specific_defines, - m_prefix.c_str(), m_name.c_str(), m_name.c_str(), m_body.c_str()); } else { - wrap_stream.Printf("%s \n" - "%s \n" - "%s \n" - "@interface $__lldb_objc_class ($__lldb_category) \n" + wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category) \n" "-(void)%s:(void *)$__lldb_arg; \n" "@end \n" "@implementation $__lldb_objc_class ($__lldb_category) \n" @@ -152,9 +189,6 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi " %s; \n" "} \n" "@end \n", - g_expression_prefix, - target_specific_defines, - m_prefix.c_str(), m_name.c_str(), m_name.c_str(), m_body.c_str()); diff --git a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp index e7cb728..59c7fb6 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp @@ -11,6 +11,8 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/raw_ostream.h" + #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Debugger.h" @@ -18,9 +20,11 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" +#include "lldb/Target/ObjCLanguageRuntime.h" using namespace lldb_private; @@ -199,28 +203,8 @@ IRExecutionUnit::DisassembleFunction (Stream &stream, disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false); InstructionList &instruction_list = disassembler_sp->GetInstructionList(); - const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); - const char *disassemble_format = "${addr-file-or-load}: "; - if (exe_ctx.HasTargetScope()) - { - disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat(); - } - - for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize(); - instruction_index < num_instructions; - ++instruction_index) - { - Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get(); - instruction->Dump (&stream, - max_opcode_byte_size, - true, - true, - &exe_ctx, - NULL, - NULL, - disassemble_format); - stream.PutChar('\n'); - } + instruction_list.Dump(&stream, true, true, &exe_ctx); + // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. // I'll fix that but for now, just clear the list and it will go away nicely. disassembler_sp->GetInstructionList().Clear(); @@ -239,6 +223,12 @@ static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Con } void +IRExecutionUnit::ReportSymbolLookupError(const ConstString &name) +{ + m_failed_lookups.push_back(name); +} + +void IRExecutionUnit::GetRunnableInfo(Error &error, lldb::addr_t &func_addr, lldb::addr_t &func_end) @@ -369,6 +359,33 @@ IRExecutionUnit::GetRunnableInfo(Error &error, ReportAllocations(*m_execution_engine_ap); WriteData(process_sp); + if (m_failed_lookups.size()) + { + StreamString ss; + + ss.PutCString("Couldn't lookup symbols:\n"); + + bool emitNewLine = false; + + for (const ConstString &failed_lookup : m_failed_lookups) + { + if (emitNewLine) + ss.PutCString("\n"); + emitNewLine = true; + ss.PutCString(" "); + ss.PutCString(Mangled(failed_lookup).GetDemangledName(lldb::eLanguageTypeObjC_plus_plus).AsCString()); + } + + m_failed_lookups.clear(); + + error.SetErrorString(ss.GetData()); + + return; + } + + m_function_load_addr = LLDB_INVALID_ADDRESS; + m_function_end_load_addr = LLDB_INVALID_ADDRESS; + for (JittedFunction &jitted_function : m_jitted_functions) { jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr); @@ -571,7 +588,7 @@ IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size, if (log) { log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p", - (uint64_t)Size, Alignment, SectionID, return_value); + (uint64_t)Size, Alignment, SectionID, (void *)return_value); } return return_value; @@ -588,8 +605,11 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size, uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly); + uint32_t permissions = lldb::ePermissionsReadable; + if (!IsReadOnly) + permissions |= lldb::ePermissionsWritable; m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value, - lldb::ePermissionsReadable | (IsReadOnly ? 0 : lldb::ePermissionsWritable), + permissions, GetSectionTypeFromSectionName (SectionName, AllocationKind::Data), Size, Alignment, @@ -598,12 +618,110 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size, if (log) { log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p", - (uint64_t)Size, Alignment, SectionID, return_value); + (uint64_t)Size, Alignment, SectionID, (void *)return_value); } return return_value; } +uint64_t +IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + SymbolContextList sc_list; + + ExecutionContextScope *exe_scope = m_parent.GetBestExecutionContextScope(); + + lldb::TargetSP target_sp = exe_scope->CalculateTarget(); + + const char *name = Name.c_str(); + + ConstString bare_name_cs(name); + ConstString name_cs; + + if (name[0] == '_') + name_cs = ConstString(name + 1); + + if (!target_sp) + { + if (log) + log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <no target>", + Name.c_str()); + + m_parent.ReportSymbolLookupError(name_cs); + + return 0xbad0bad0; + } + + uint32_t num_matches = 0; + lldb::ProcessSP process_sp = exe_scope->CalculateProcess(); + + if (!name_cs.IsEmpty()) + { + target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list); + num_matches = sc_list.GetSize(); + } + + if (!num_matches) + { + target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list); + num_matches = sc_list.GetSize(); + } + + lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; + + for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++) + { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(i, sym_ctx); + + symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp); + + if (symbol_load_addr == LLDB_INVALID_ADDRESS) + symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get()); + } + + if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs) + { + // Try the Objective-C language runtime. + + ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime(); + + if (runtime) + symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs); + } + + if (symbol_load_addr == LLDB_INVALID_ADDRESS) + { + if (log) + log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>", + name); + + m_parent.ReportSymbolLookupError(bare_name_cs); + + return 0xbad0bad0; + } + + if (log) + log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64, + name, + symbol_load_addr); + + if (symbol_load_addr == 0) + return 0xbad00add; + + return symbol_load_addr; +} + +void * +IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure) { + assert (sizeof(void *) == 8); + + return (void*)getSymbolAddress(Name); +} + lldb::addr_t IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address) { diff --git a/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp b/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp index 8e75c32..cf2a93b 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp @@ -16,7 +16,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" -#include "llvm/PassManager.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/Transforms/IPO.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueSymbolTable.h" @@ -35,6 +35,7 @@ #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTType.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include <map> @@ -59,7 +60,8 @@ IRForTarget::FunctionValueCache::~FunctionValueCache() { } -llvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) +llvm::Value * +IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) { if (!m_values.count(function)) { @@ -70,7 +72,8 @@ llvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) return m_values[function]; } -lldb::addr_t IRForTarget::StaticDataAllocator::Allocate() +lldb::addr_t +IRForTarget::StaticDataAllocator::Allocate() { lldb_private::Error err; @@ -85,7 +88,14 @@ lldb::addr_t IRForTarget::StaticDataAllocator::Allocate() return m_allocation; } -static llvm::Value *FindEntryInstruction (llvm::Function *function) +lldb::TargetSP +IRForTarget::StaticDataAllocator::GetTarget() +{ + return m_execution_unit.GetTarget(); +} + +static llvm::Value * +FindEntryInstruction (llvm::Function *function) { if (function->empty()) return NULL; @@ -217,50 +227,51 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, { if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr)) { - lldb_private::ConstString altnernate_name; + std::vector<lldb_private::ConstString> alternates; bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr); if (!found_it) { - // Check for an alternate mangling for "std::basic_string<char>" - // that is part of the itanium C++ name mangling scheme - const char *name_cstr = name.GetCString(); - if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0) + if (log) + log->Printf("Address of function \"%s\" not found.\n", name.GetCString()); + // Check for an alternate mangling for names from the standard library. + // For example, "std::basic_string<...>" has an alternate mangling scheme per + // the Itanium C++ ABI. + lldb::ProcessSP process_sp = m_data_allocator.GetTarget()->GetProcessSP(); + if (process_sp) { - std::string alternate_mangling("_ZNKSs"); - alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE")); - altnernate_name.SetCString(alternate_mangling.c_str()); - found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr); + lldb_private::CPPLanguageRuntime *cpp_runtime = process_sp->GetCPPLanguageRuntime(); + if (cpp_runtime && cpp_runtime->GetAlternateManglings(name, alternates)) + { + for (size_t i = 0; i < alternates.size(); ++i) + { + const lldb_private::ConstString &alternate_name = alternates[i]; + if (log) + log->Printf("Looking up address of function \"%s\" with alternate name \"%s\"", + name.GetCString(), alternate_name.GetCString()); + if ((found_it = m_decl_map->GetFunctionAddress (alternate_name, fun_addr))) + { + if (log) + log->Printf("Found address of function \"%s\" with alternate name \"%s\"", + name.GetCString(), alternate_name.GetCString()); + break; + } + } + } } } if (!found_it) { lldb_private::Mangled mangled_name(name); - lldb_private::Mangled alt_mangled_name(altnernate_name); - if (log) - { - if (alt_mangled_name) - log->Printf("Function \"%s\" (alternate name \"%s\") has no address", - mangled_name.GetName().GetCString(), - alt_mangled_name.GetName().GetCString()); - else - log->Printf("Function \"%s\" had no address", - mangled_name.GetName().GetCString()); - } - if (m_error_stream) { - if (alt_mangled_name) - m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n", - mangled_name.GetName().GetCString(), - alt_mangled_name.GetName().GetCString()); - else if (mangled_name.GetMangledName()) + if (mangled_name.GetMangledName()) m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n", - mangled_name.GetName().GetCString(), + mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString(), mangled_name.GetMangledName().GetCString()); else m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n", - mangled_name.GetName().GetCString()); + mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString()); } return LookupResult::Fail; } @@ -590,7 +601,10 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) &result_decl->getASTContext()); } - if (m_result_type.GetBitSize() == 0) + + lldb::TargetSP target_sp (m_data_allocator.GetTarget()); + lldb_private::ExecutionContext exe_ctx (target_sp, true); + if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); @@ -617,7 +631,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) if (log) log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, m_result_name.GetCString(), - m_result_type.GetByteSize()); + m_result_type.GetByteSize(nullptr)); // Construct a new result global and set up its metadata @@ -1345,7 +1359,7 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer) lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); if (log && log->GetVerbose()) - log->Printf(" MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str()); + log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, PrintValue(initializer).c_str()); Type *initializer_type = initializer->getType(); @@ -1501,7 +1515,7 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) if (name[0] == '$') { - // The $__lldb_expr_result name indicates the the return value has allocated as + // The $__lldb_expr_result name indicates the return value has allocated as // a static variable. Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, // accesses to this static variable need to be redirected to the result of dereferencing // a pointer that is passed in as one of the arguments. @@ -1518,7 +1532,7 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) value_type = global_variable->getType(); } - const uint64_t value_size = clang_type.GetByteSize(); + const uint64_t value_size = clang_type.GetByteSize(nullptr); lldb::offset_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull; if (log) @@ -2194,7 +2208,7 @@ IRForTarget::UnfoldConstant(Constant *old_constant, ArrayRef <Value*> indices(index_vector); - return GetElementPtrInst::Create(ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); + return GetElementPtrInst::Create(nullptr, ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); }); if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder)) @@ -2381,7 +2395,8 @@ IRForTarget::ReplaceVariables (Function &llvm_function) llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)); ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true)); - GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, + GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(nullptr, + argument, offset_int, "", entry_instruction); @@ -2441,11 +2456,14 @@ IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset) offset_array[0] = offset_int; llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1); + llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext()); + llvm::Type *char_pointer_type = char_type->getPointerTo(); - llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(m_reloc_placeholder, offsets); - llvm::Constant *reloc_getbitcast = ConstantExpr::getBitCast(reloc_getelementptr, type); + llvm::Constant *reloc_placeholder_bitcast = ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type); + llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(char_type, reloc_placeholder_bitcast, offsets); + llvm::Constant *reloc_bitcast = ConstantExpr::getBitCast(reloc_getelementptr, type); - return reloc_getbitcast; + return reloc_bitcast; } bool diff --git a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp index d11bdc1..926d1f2 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp @@ -10,17 +10,28 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Module.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Expression/IRInterpreter.h" #include "lldb/Host/Endian.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" + #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/raw_ostream.h" @@ -455,7 +466,8 @@ static const char *infinite_loop_error = "Interpreter ran for too m bool IRInterpreter::CanInterpret (llvm::Module &module, llvm::Function &function, - lldb_private::Error &error) + lldb_private::Error &error, + const bool support_function_calls) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -507,7 +519,7 @@ IRInterpreter::CanInterpret (llvm::Module &module, return false; } - if (!CanIgnoreCall(call_inst)) + if (!CanIgnoreCall(call_inst) && !support_function_calls) { if (log) log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str()); @@ -611,7 +623,8 @@ IRInterpreter::Interpret (llvm::Module &module, lldb_private::IRMemoryMap &memory_map, lldb_private::Error &error, lldb::addr_t stack_frame_bottom, - lldb::addr_t stack_frame_top) + lldb::addr_t stack_frame_top, + lldb_private::ExecutionContext &exe_ctx) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -668,29 +681,7 @@ IRInterpreter::Interpret (llvm::Module &module, { default: break; - case Instruction::Call: - { - const CallInst *call_inst = dyn_cast<CallInst>(inst); - - if (!call_inst) - { - if (log) - log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } - if (!CanIgnoreCall(call_inst)) - { - if (log) - log->Printf("The interpreter shouldn't have accepted %s", PrintValue(call_inst).c_str()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } - } - break; case Instruction::Add: case Instruction::Sub: case Instruction::Mul: @@ -1476,6 +1467,242 @@ IRInterpreter::Interpret (llvm::Module &module, } } break; + case Instruction::Call: + { + const CallInst *call_inst = dyn_cast<CallInst>(inst); + + if (!call_inst) + { + if (log) + log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName()); + error.SetErrorToGenericError(); + error.SetErrorString(interpreter_internal_error); + return false; + } + + if (CanIgnoreCall(call_inst)) + break; + + // Get the return type + llvm::Type *returnType = call_inst->getType(); + if (returnType == nullptr) + { + error.SetErrorToGenericError(); + error.SetErrorString("unable to access return type"); + return false; + } + + // Work with void, integer and pointer return types + if (!returnType->isVoidTy() && + !returnType->isIntegerTy() && + !returnType->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorString("return type is not supported"); + return false; + } + + // Check we can actually get a thread + if (exe_ctx.GetThreadPtr() == nullptr) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to acquire thread"); + return false; + } + + // Make sure we have a valid process + if (!exe_ctx.GetProcessPtr()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to get the process"); + return false; + } + + // Find the address of the callee function + lldb_private::Scalar I; + const llvm::Value *val = call_inst->getCalledValue(); + + if (!frame.EvaluateValue(I, val, module)) + { + error.SetErrorToGenericError(); + error.SetErrorString("unable to get address of function"); + return false; + } + lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS)); + + lldb_private::StreamString error_stream; + lldb_private::EvaluateExpressionOptions options; + + // We generally receive a function pointer which we must dereference + llvm::Type* prototype = val->getType(); + if (!prototype->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorString("call need function pointer"); + return false; + } + + // Dereference the function pointer + prototype = prototype->getPointerElementType(); + if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg())) + { + error.SetErrorToGenericError(); + error.SetErrorString("call need function pointer"); + return false; + } + + // Find number of arguments + const int numArgs = call_inst->getNumArgOperands(); + + // We work with a fixed array of 16 arguments which is our upper limit + static lldb_private::ABI::CallArgument rawArgs[16]; + if (numArgs >= 16) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("function takes too many arguments"); + return false; + } + + // Push all function arguments to the argument list that will + // be passed to the call function thread plan + for (int i = 0; i < numArgs; i++) + { + // Get details of this argument + llvm::Value *arg_op = call_inst->getArgOperand(i); + llvm::Type *arg_ty = arg_op->getType(); + + // Ensure that this argument is an supported type + if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("argument %d must be integer type", i); + return false; + } + + // Extract the arguments value + lldb_private::Scalar tmp_op = 0; + if (!frame.EvaluateValue(tmp_op, arg_op, module)) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to evaluate argument %d", i); + return false; + } + + // Check if this is a string literal or constant string pointer + if (arg_ty->isPointerTy()) + { + // Pointer to just one type + assert(arg_ty->getNumContainedTypes() == 1); + + lldb::addr_t addr = tmp_op.ULongLong(); + size_t dataSize = 0; + + if (memory_map.GetAllocSize(addr, dataSize)) + { + // Create the required buffer + rawArgs[i].size = dataSize; + rawArgs[i].data_ap.reset(new uint8_t[dataSize + 1]); + + // Read string from host memory + memory_map.ReadMemory(rawArgs[i].data_ap.get(), addr, dataSize, error); + if (error.Fail()) + { + assert(!"we have failed to read the string from memory"); + return false; + } + // Add null terminator + rawArgs[i].data_ap[dataSize] = '\0'; + rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer; + } + else + { + assert(!"unable to locate host data for transfer to device"); + return false; + } + } + else /* if ( arg_ty->isPointerTy() ) */ + { + rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue; + // Get argument size in bytes + rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8; + // Push value into argument list for thread plan + rawArgs[i].value = tmp_op.ULongLong(); + } + + } + + // Pack the arguments into an llvm::array + llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs); + + // Setup a thread plan to call the target function + lldb::ThreadPlanSP call_plan_sp + ( + new lldb_private::ThreadPlanCallFunctionUsingABI + ( + exe_ctx.GetThreadRef(), + funcAddr, + *prototype, + *returnType, + args, + options + ) + ); + + // Check if the plan is valid + if (!call_plan_sp || !call_plan_sp->ValidatePlan(&error_stream)) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to make ThreadPlanCallFunctionUsingABI for 0x%llx", I.ULongLong()); + return false; + } + + exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); + + // Execute the actual function call thread plan + lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, error_stream); + + // Check that the thread plan completed successfully + if (res != lldb::ExpressionResults::eExpressionCompleted) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed"); + return false; + } + + exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); + + // Void return type + if (returnType->isVoidTy()) + { + // Cant assign to void types, so we leave the frame untouched + } + else + // Integer or pointer return type + if (returnType->isIntegerTy() || returnType->isPointerTy()) + { + // Get the encapsulated return value + lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject(); + + lldb_private::Scalar returnVal = -1; + lldb_private::ValueObject *vobj = retVal.get(); + + // Check if the return value is valid + if (vobj == nullptr || retVal.empty()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to get the return value"); + return false; + } + + // Extract the return value as a integer + lldb_private::Value & value = vobj->GetValue(); + returnVal = value.GetScalar(); + + // Push the return value as the result + frame.AssignValue(inst, returnVal, module); + } + } + break; } ++frame.m_ii; diff --git a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp index a4fe7a9..4733b16 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp @@ -418,6 +418,32 @@ IRMemoryMap::Free (lldb::addr_t process_address, Error &error) m_allocations.erase(iter); } +bool +IRMemoryMap::GetAllocSize(lldb::addr_t address, size_t &size) +{ + AllocationMap::iterator iter = FindAllocation(address, size); + if (iter == m_allocations.end()) + return false; + + Allocation &al = iter->second; + + if (address > (al.m_process_start + al.m_size)) + { + size = 0; + return false; + } + + if (address > al.m_process_start) + { + int dif = address - al.m_process_start; + size = al.m_size - dif; + return true; + } + + size = al.m_size; + return true; +} + void IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error) { diff --git a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp index b119216..ef01fee 100644 --- a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/Materializer.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" @@ -49,7 +50,7 @@ Materializer::AddStructMember (Entity &entity) void Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type) { - m_size = type.GetByteSize(); + m_size = type.GetByteSize(nullptr); uint32_t bit_alignment = type.GetTypeBitAlign(); @@ -780,7 +781,7 @@ public: const lldb::addr_t load_addr = process_address + m_offset; - size_t byte_size = m_type.GetByteSize(); + size_t byte_size = m_type.GetByteSize(nullptr); size_t bit_align = m_type.GetTypeBitAlign(); size_t byte_align = (bit_align + 7) / 8; @@ -1051,7 +1052,7 @@ public: m_symbol.GetName().AsCString()); } - Address &sym_address = m_symbol.GetAddress(); + const Address sym_address = m_symbol.GetAddress(); ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); |