diff options
5 files changed, 89 insertions, 1013 deletions
diff --git a/lldb/source/Expression/IRDynamicChecks.cpp b/lldb/source/Expression/IRDynamicChecks.cpp index 64fdb08157a..c2195de4d44 100644 --- a/lldb/source/Expression/IRDynamicChecks.cpp +++ b/lldb/source/Expression/IRDynamicChecks.cpp @@ -506,6 +506,32 @@ protected: return true; } + + static llvm::Function *GetFunction(llvm::Value *value) + { + if (llvm::Function *function = llvm::dyn_cast<llvm::Function>(value)) + { + return function; + } + + if (llvm::ConstantExpr *const_expr = llvm::dyn_cast<llvm::ConstantExpr>(value)) + { + switch (const_expr->getOpcode()) + { + default: + return nullptr; + case llvm::Instruction::BitCast: + return GetFunction(const_expr->getOperand(0)); + } + } + + return nullptr; + } + + static llvm::Function *GetCalledFunction(llvm::CallInst *inst) + { + return GetFunction(inst->getCalledValue()); + } bool InspectInstruction(llvm::Instruction &i) override { @@ -515,35 +541,12 @@ protected: if (call_inst) { - // This metadata is set by IRForTarget::MaybeHandleCall(). - - MDNode *metadata = call_inst->getMetadata("lldb.call.realName"); - - if (!metadata) + const llvm::Function *called_function = GetCalledFunction(call_inst); + + if (!called_function) return true; - - if (metadata->getNumOperands() != 1) - { - if (log) - log->Printf("Function call metadata has %d operands for [%p] %s", - metadata->getNumOperands(), - static_cast<void*>(call_inst), - PrintValue(call_inst).c_str()); - return false; - } - - MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0)); - - if (!real_name) - { - if (log) - log->Printf("Function call metadata is not an MDString for [%p] %s", - static_cast<void*>(call_inst), - PrintValue(call_inst).c_str()); - return false; - } - - std::string name_str = real_name->getString(); + + std::string name_str = called_function->getName().str(); const char* name_cstr = name_str.c_str(); if (log) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 6092efa484f..eab62aed6cb 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -515,248 +515,6 @@ ClangExpressionDeclMap::GetFunctionInfo return true; } -static void -FindCodeSymbolInContext -( - const ConstString &name, - SymbolContext &sym_ctx, - uint32_t name_type_mask, - SymbolContextList &sc_list -) -{ - sc_list.Clear(); - SymbolContextList temp_sc_list; - if (sym_ctx.module_sp) - sym_ctx.module_sp->FindFunctions(name, - NULL, - name_type_mask, - 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, - name_type_mask, - 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 sc; - temp_sc_list.GetContextAtIndex(i, sc); - if (sc.function) - { - sc_list.Append(sc); - } - else if (sc.symbol) - { - if (sc.symbol->IsExternal()) - { - 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; - } -} - -ConstString -FindBestAlternateMangledName -( - const ConstString &demangled, - const LanguageType &lang_type, - SymbolContext &sym_ctx -) -{ - CPlusPlusLanguage::MethodName cpp_name(demangled); - std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); - - if (!scope_qualified_name.size()) - return ConstString(); - - if (!sym_ctx.module_sp) - return ConstString(); - - SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor(); - if (!sym_vendor) - return ConstString(); - - lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile(); - if (!sym_file) - return ConstString(); - - std::vector<ConstString> alternates; - sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); - - std::vector<ConstString> param_and_qual_matches; - std::vector<ConstString> param_matches; - for (size_t i = 0; i < alternates.size(); i++) - { - ConstString alternate_mangled_name = alternates[i]; - Mangled mangled(alternate_mangled_name, true); - ConstString demangled = mangled.GetDemangledName(lang_type); - - CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); - if (!cpp_name.IsValid()) - continue; - - if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) - { - if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers()) - param_and_qual_matches.push_back(alternate_mangled_name); - else - param_matches.push_back(alternate_mangled_name); - } - } - - if (param_and_qual_matches.size()) - return param_and_qual_matches[0]; // It is assumed that there will be only one! - else if (param_matches.size()) - return param_matches[0]; // Return one of them as a best match - else - return ConstString(); -} - -bool -ClangExpressionDeclMap::GetFunctionAddress -( - const ConstString &name, - uint64_t &func_addr -) -{ - assert (m_parser_vars.get()); - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; - Target *target = exe_ctx.GetTargetPtr(); - // Back out in all cases where we're not fully initialized - if (target == NULL) - return false; - if (!m_parser_vars->m_sym_ctx.target_sp) - return false; - - SymbolContextList sc_list; - - FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); - - uint32_t sc_list_size = sc_list.GetSize(); - - if (sc_list_size == 0) - { - SymbolContext &sc = m_parser_vars->m_sym_ctx; - if (sc.comp_unit) - { - LanguageType lang_type = sc.comp_unit->GetLanguage(); - if (Language::LanguageIsCPlusPlus(lang_type) && - CPlusPlusLanguage::IsCPPMangledName(name.AsCString())) - { - Mangled mangled(name, true); - ConstString demangled = mangled.GetDemangledName(lang_type); - - if (demangled) - { - ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lang_type, sc); - if (best_alternate_mangled_name) - { - FindCodeSymbolInContext( - best_alternate_mangled_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); - sc_list_size = sc_list.GetSize(); - } - - if (sc_list_size == 0) - { - FindCodeSymbolInContext( - demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list); - sc_list_size = sc_list.GetSize(); - } - } - } - } - } - - if (sc_list_size == 0) - { - // We occasionally get debug information in which a const function is reported - // as non-const, so the mangled name is wrong. This is a hack to compensate. - - if (!strncmp(name.GetCString(), "_ZN", 3) && - strncmp(name.GetCString(), "_ZNK", 4)) - { - std::string fixed_scratch("_ZNK"); - fixed_scratch.append(name.GetCString() + 3); - ConstString fixed_name(fixed_scratch.c_str()); - - if (log) - log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString()); - - FindCodeSymbolInContext( - fixed_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, 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) - { - const Address func_so_addr = sym_ctx.function->GetAddressRange().GetBaseAddress(); - if (func_so_addr.IsValid()) - { - callable_load_addr = func_so_addr.GetCallableLoadAddress(target, false); - } - } - else if (sym_ctx.symbol) - { - 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) - { - func_addr = callable_load_addr; - 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; -} - addr_t ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, @@ -2268,6 +2026,54 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, if (function) { Type *function_type = function->GetType(); + + const lldb::LanguageType comp_unit_language = function->GetCompileUnit()->GetLanguage(); + const bool extern_c = Language::LanguageIsC(comp_unit_language) || + (Language::LanguageIsObjC(comp_unit_language) && + !Language::LanguageIsCPlusPlus(comp_unit_language)); + + if (!extern_c) + { + TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); + if (ClangASTContext *src_ast = llvm::dyn_cast<ClangASTContext>(type_system)) + { + clang::DeclContext *src_decl_context = (clang::DeclContext*)function->GetDeclContext().GetOpaqueDeclContext(); + clang::FunctionDecl *src_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context); + + if (src_function_decl) + { + if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, src_ast->getASTContext(), src_function_decl))) + { + if (log) + { + ASTDumper ast_dumper((clang::Decl*)copied_function_decl); + + StreamString ss; + + function->DumpSymbolContext(&ss); + + log->Printf(" CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s", + current_id, + copied_function_decl->getName().str().c_str(), + ss.GetData(), + ast_dumper.GetCString()); + + } + + context.AddNamedDecl(copied_function_decl); + return; + } + else + { + if (log) + { + log->Printf (" Failed to import the function decl for '%s'", + src_function_decl->getName().str().c_str()); + } + } + } + } + } if (!function_type) { @@ -2290,7 +2096,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, CompilerType copied_function_type = GuardedCopyType(function_clang_type); if (copied_function_type) { - function_decl = context.AddFunDecl(copied_function_type); + function_decl = context.AddFunDecl(copied_function_type, extern_c); if (!function_decl) { diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 35833e87558..537db71cfeb 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -265,25 +265,6 @@ public: uint64_t &ptr); //------------------------------------------------------------------ - /// [Used by IRForTarget] Get the address of a function given nothing - /// but its name. Some functions are needed but didn't get Decls made - /// during parsing -- specifically, sel_registerName is never called - /// in the generated IR but we need to call it nonetheless. - /// - /// @param[in] name - /// The name of the function. - /// - /// @param[out] ptr - /// The absolute address of the function in the target. - /// - /// @return - /// True if the address could be retrieved; false otherwise. - //------------------------------------------------------------------ - bool - GetFunctionAddress (const ConstString &name, - uint64_t &ptr); - - //------------------------------------------------------------------ /// [Used by IRForTarget] Get the address of a symbol given nothing /// but its name. /// diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 509c594280a..0c293ee585c 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -43,13 +43,6 @@ using namespace llvm; static char ID; -IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) : - m_execution_unit(execution_unit), - m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()), - m_allocation(LLDB_INVALID_ADDRESS) -{ -} - IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) : m_maker(maker), m_values() @@ -72,28 +65,6 @@ IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) return m_values[function]; } -lldb::addr_t -IRForTarget::StaticDataAllocator::Allocate() -{ - lldb_private::Error err; - - if (m_allocation != LLDB_INVALID_ADDRESS) - { - m_execution_unit.FreeNow(m_allocation); - m_allocation = LLDB_INVALID_ADDRESS; - } - - m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err); - - return m_allocation; -} - -lldb::TargetSP -IRForTarget::StaticDataAllocator::GetTarget() -{ - return m_execution_unit.GetTarget(); -} - static llvm::Value * FindEntryInstruction (llvm::Function *function) { @@ -113,7 +84,6 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, m_func_name(func_name), m_module(NULL), m_decl_map(decl_map), - m_data_allocator(execution_unit), m_CFStringCreateWithBytes(NULL), m_sel_registerName(NULL), m_intptr_ty(NULL), @@ -121,6 +91,7 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, m_result_store(NULL), m_result_is_pointer(false), m_reloc_placeholder(NULL), + m_execution_unit(execution_unit), m_entry_instruction_finder (FindEntryInstruction) { } @@ -168,208 +139,6 @@ IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) return true; } -IRForTarget::LookupResult -IRForTarget::GetFunctionAddress (llvm::Function *fun, - uint64_t &fun_addr, - lldb_private::ConstString &name, - Constant **&value_ptr) -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - fun_addr = LLDB_INVALID_ADDRESS; - name.Clear(); - value_ptr = NULL; - - if (fun->isIntrinsic()) - { - Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID(); - - switch (intrinsic_id) - { - default: - if (log) - log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str()); - - if (m_error_stream) - m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str()); - - return LookupResult::Fail; - case Intrinsic::memcpy: - { - static lldb_private::ConstString g_memcpy_str ("memcpy"); - name = g_memcpy_str; - } - break; - case Intrinsic::memset: - { - static lldb_private::ConstString g_memset_str ("memset"); - name = g_memset_str; - } - break; - case Intrinsic::dbg_declare: - case Intrinsic::dbg_value: - return LookupResult::Ignore; - } - - if (log && name) - log->Printf("Resolved intrinsic name \"%s\"", name.GetCString()); - } - else - { - name.SetCStringWithLength (fun->getName().data(), fun->getName().size()); - } - - // Find the address of the function. - - clang::NamedDecl *fun_decl = DeclForGlobal (fun); - - if (fun_decl) - { - if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr)) - { - std::vector<lldb_private::ConstString> alternates; - bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr); - - if (!found_it) - { - lldb_private::Mangled mangled_name(name); - if (m_error_stream) - { - 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(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(lldb::eLanguageTypeObjC_plus_plus).GetCString()); - } - return LookupResult::Fail; - } - } - } - else - { - if (!m_decl_map->GetFunctionAddress (name, fun_addr)) - { - if (log) - log->Printf ("Metadataless function \"%s\" had no address", name.GetCString()); - - if (m_error_stream) - m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString()); - - return LookupResult::Fail; - } - } - - if (log) - log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr); - - return LookupResult::Success; -} - -llvm::Constant * -IRForTarget::BuildFunctionPointer (llvm::Type *type, - uint64_t ptr) -{ - PointerType *fun_ptr_ty = PointerType::getUnqual(type); - Constant *fun_addr_int = ConstantInt::get(m_intptr_ty, ptr, false); - return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); -} - -void -IRForTarget::RegisterFunctionMetadata(LLVMContext &context, - llvm::Value *function_ptr, - const char *name) -{ - for (llvm::User *user : function_ptr->users()) - { - if (Instruction *user_inst = dyn_cast<Instruction>(user)) - { - MDString* md_name = MDString::get(context, StringRef(name)); - - MDNode *metadata = MDNode::get(context, md_name); - - user_inst->setMetadata("lldb.call.realName", metadata); - } - else - { - RegisterFunctionMetadata (context, user, name); - } - } -} - -bool -IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module) -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - for (llvm::Module::iterator fi = llvm_module.begin(); - fi != llvm_module.end(); - ++fi) - { - Function *fun = &*fi; - - bool is_decl = fun->isDeclaration(); - - if (log) - log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str()); - - if (!is_decl) - continue; - - if (fun->use_empty()) - continue; // ignore - - uint64_t addr = LLDB_INVALID_ADDRESS; - lldb_private::ConstString name; - Constant **value_ptr = NULL; - - LookupResult result = GetFunctionAddress(fun, - addr, - name, - value_ptr); - - switch (result) - { - case LookupResult::Fail: - return false; // GetFunctionAddress reports its own errors - - case LookupResult::Ignore: - break; // Nothing to do - - case LookupResult::Success: - { - Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr); - - RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString()); - - if (value_ptr) - *value_ptr = value; - - // If we are replacing a function with the nobuiltin attribute, it may - // be called with the builtin attribute on call sites. Remove any such - // attributes since it's illegal to have a builtin call to something - // other than a nobuiltin function. - if (fun->hasFnAttribute(llvm::Attribute::NoBuiltin)) { - llvm::Attribute builtin = llvm::Attribute::get(fun->getContext(), llvm::Attribute::Builtin); - - for (auto u : fun->users()) { - if (auto call = dyn_cast<CallInst>(u)) { - call->removeAttribute(AttributeSet::FunctionIndex, builtin); - } - } - } - - fun->replaceAllUsesWith(value); - } - break; - } - } - - return true; -} - - clang::NamedDecl * IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module) { @@ -572,7 +341,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) } - lldb::TargetSP target_sp (m_data_allocator.GetTarget()); + lldb::TargetSP target_sp (m_execution_unit.GetTarget()); lldb_private::ExecutionContext exe_ctx (target_sp, true); if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) { @@ -704,7 +473,8 @@ IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str, static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes"); - if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr)) + CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str); + if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) { if (log) log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); @@ -1093,7 +863,8 @@ IRForTarget::RewriteObjCSelector (Instruction* selector_load) lldb::addr_t sel_registerName_addr; static lldb_private::ConstString g_sel_registerName_str ("sel_registerName"); - if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr)) + sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str); + if (sel_registerName_addr == LLDB_INVALID_ADDRESS) return false; if (log) @@ -1388,48 +1159,6 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer) return false; } -bool -IRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable) -{ - if (GlobalVariable::isExternalLinkage(global_variable->getLinkage())) - return false; - - if (global_variable == m_reloc_placeholder) - return true; - - uint64_t offset = m_data_allocator.GetStream().GetSize(); - - llvm::Type *variable_type = global_variable->getType(); - - Constant *initializer = global_variable->getInitializer(); - - llvm::Type *initializer_type = initializer->getType(); - - size_t size = m_target_data->getTypeAllocSize(initializer_type); - size_t align = m_target_data->getPrefTypeAlignment(initializer_type); - - const size_t mask = (align - 1); - uint64_t aligned_offset = (offset + mask) & ~mask; - m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0); - offset = aligned_offset; - - lldb_private::DataBufferHeap data(size, '\0'); - - if (initializer) - if (!MaterializeInitializer(data.GetBytes(), initializer)) - return false; - - m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize()); - - Constant *new_pointer = BuildRelocation(variable_type, offset); - - global_variable->replaceAllUsesWith(new_pointer); - - global_variable->eraseFromParent(); - - return true; -} - // This function does not report errors; its callers are responsible. bool IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) @@ -1455,7 +1184,7 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr)) { if (!GlobalValue::isExternalLinkage(global_variable->getLinkage())) - return MaterializeInternalVariable(global_variable); + return true; clang::NamedDecl *named_decl = DeclForGlobal(global_variable); @@ -1524,10 +1253,8 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) { if (!global_variable->hasExternalLinkage()) return true; - else if (HandleSymbol (global_variable)) - return true; else - return false; + return true; } } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) @@ -1783,231 +1510,6 @@ IRForTarget::ResolveExternals (Function &llvm_function) return true; } -bool -IRForTarget::ReplaceStrings () -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - typedef std::map <GlobalVariable *, size_t> OffsetsTy; - - OffsetsTy offsets; - - for (GlobalVariable &gv : m_module->globals()) - { - if (!gv.hasInitializer()) - continue; - - Constant *gc = gv.getInitializer(); - - std::string str; - - if (gc->isNullValue()) - { - Type *gc_type = gc->getType(); - - ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type); - - if (!gc_array_type) - continue; - - Type *gc_element_type = gc_array_type->getElementType(); - - IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type); - - if (gc_integer_type->getBitWidth() != 8) - continue; - - str = ""; - } - else - { - ConstantDataArray *gc_array = dyn_cast<ConstantDataArray>(gc); - - if (!gc_array) - continue; - - if (!gc_array->isCString()) - continue; - - if (log) - log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str()); - - str = gc_array->getAsString(); - } - - offsets[&gv] = m_data_allocator.GetStream().GetSize(); - - m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1); - } - - Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext()); - - for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end(); - oi != oe; - ++oi) - { - GlobalVariable *gv = oi->first; - size_t offset = oi->second; - - Constant *new_initializer = BuildRelocation(char_ptr_ty, offset); - - if (log) - log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str()); - - for (llvm::User *u : gv->users()) - { - if (log) - log->Printf("Found use %s", PrintValue(u).c_str()); - - ConstantExpr *const_expr = dyn_cast<ConstantExpr>(u); - StoreInst *store_inst = dyn_cast<StoreInst>(u); - - if (const_expr) - { - if (const_expr->getOpcode() != Instruction::GetElementPtr) - { - if (log) - log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str()); - - return false; - } - - Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType()); - Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast); - - const_expr->replaceAllUsesWith(new_gep); - } - else if (store_inst) - { - Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType()); - - store_inst->setOperand(0, bit_cast); - } - else - { - if (log) - log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str()); - - return false; - } - } - - gv->eraseFromParent(); - } - - return true; -} - -bool -IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block) -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - typedef SmallVector <Value*, 2> ConstantList; - typedef SmallVector <llvm::Instruction*, 2> UserList; - typedef ConstantList::iterator ConstantIterator; - typedef UserList::iterator UserIterator; - - ConstantList static_constants; - UserList static_users; - - for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end(); - ii != ie; - ++ii) - { - llvm::Instruction &inst = *ii; - - for (Value *operand_val : inst.operand_values()) - { - ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val); - - if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/) - { - static_constants.push_back(operand_val); - static_users.push_back(&*ii); - } - } - } - - ConstantIterator constant_iter; - UserIterator user_iter; - - for (constant_iter = static_constants.begin(), user_iter = static_users.begin(); - constant_iter != static_constants.end(); - ++constant_iter, ++user_iter) - { - Value *operand_val = *constant_iter; - llvm::Instruction *inst = *user_iter; - - ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val); - - if (operand_constant_fp) - { - Type *operand_type = operand_constant_fp->getType(); - - APFloat operand_apfloat = operand_constant_fp->getValueAPF(); - APInt operand_apint = operand_apfloat.bitcastToAPInt(); - - const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData(); - size_t operand_data_size = operand_apint.getBitWidth() / 8; - - if (log) - { - std::string s; - raw_string_ostream ss(s); - for (size_t index = 0; - index < operand_data_size; - ++index) - { - ss << (uint32_t)operand_raw_data[index]; - ss << " "; - } - ss.flush(); - - log->Printf("Found ConstantFP with size %" PRIu64 " and raw data %s", (uint64_t)operand_data_size, s.c_str()); - } - - lldb_private::DataBufferHeap data(operand_data_size, 0); - - if (lldb_private::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder()) - { - uint8_t *data_bytes = data.GetBytes(); - - for (size_t index = 0; - index < operand_data_size; - ++index) - { - data_bytes[index] = operand_raw_data[operand_data_size - (1 + index)]; - } - } - else - { - memcpy(data.GetBytes(), operand_raw_data, operand_data_size); - } - - uint64_t offset = m_data_allocator.GetStream().GetSize(); - - size_t align = m_target_data->getPrefTypeAlignment(operand_type); - - const size_t mask = (align - 1); - uint64_t aligned_offset = (offset + mask) & ~mask; - m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0); - - m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size); - - llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo(); - - Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset); - - llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst); - - operand_constant_fp->replaceAllUsesWith(fp_load); - } - } - - return true; -} - static bool isGuardVariableRef(Value *V) { Constant *Old = NULL; @@ -2437,79 +1939,6 @@ IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset) } bool -IRForTarget::CompleteDataAllocation () -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (!m_data_allocator.GetStream().GetSize()) - return true; - - lldb::addr_t allocation = m_data_allocator.Allocate(); - - if (log) - { - if (allocation) - log->Printf("Allocated static data at 0x%llx", (unsigned long long)allocation); - else - log->Printf("Failed to allocate static data"); - } - - if (!allocation || allocation == LLDB_INVALID_ADDRESS) - return false; - - Constant *relocated_addr = ConstantInt::get(m_intptr_ty, (uint64_t)allocation); - Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext())); - - m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast); - - m_reloc_placeholder->eraseFromParent(); - - return true; -} - -bool -IRForTarget::StripAllGVs (Module &llvm_module) -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - std::vector<GlobalVariable *> global_vars; - std::set<GlobalVariable *>erased_vars; - - bool erased = true; - - while (erased) - { - erased = false; - - for (GlobalVariable &global_var : llvm_module.globals()) - { - global_var.removeDeadConstantUsers(); - - if (global_var.use_empty()) - { - if (log) - log->Printf("Did remove %s", - PrintValue(&global_var).c_str()); - global_var.eraseFromParent(); - erased = true; - break; - } - } - } - - for (GlobalVariable &global_var : llvm_module.globals()) - { - GlobalValue::user_iterator ui = global_var.user_begin(); - - if (log) - log->Printf("Couldn't remove %s because of %s", - PrintValue(&global_var).c_str(), - PrintValue(*ui).c_str()); - } - - return true; -} - -bool IRForTarget::runOnModule (Module &llvm_module) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -2650,20 +2079,6 @@ IRForTarget::runOnModule (Module &llvm_module) return false; } - /////////////////////////////// - // Resolve function pointers - // - - if (!ResolveFunctionPointers(llvm_module)) - { - if (log) - log->Printf("ResolveFunctionPointers() failed"); - - // ResolveFunctionPointers() reports its own errors, so we don't do so here - - return false; - } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; ++fi) @@ -2705,14 +2120,6 @@ IRForTarget::runOnModule (Module &llvm_module) return false; } - - if (!ReplaceStaticLiterals(*bbi)) - { - if (log) - log->Printf("ReplaceStaticLiterals() failed"); - - return false; - } } } @@ -2740,28 +2147,6 @@ IRForTarget::runOnModule (Module &llvm_module) return false; } - if (!ReplaceStrings()) - { - if (log) - log->Printf("ReplaceStrings() failed"); - - return false; - } - - if (!CompleteDataAllocation()) - { - if (log) - log->Printf("CompleteDataAllocation() failed"); - - return false; - } - - if (!StripAllGVs(llvm_module)) - { - if (log) - log->Printf("StripAllGVs() failed"); - } - if (log && log->GetVerbose()) { std::string s; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h index fb4abcc103d..52208590a72 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -214,40 +214,6 @@ private: llvm::Constant **&value_ptr); //------------------------------------------------------------------ - /// Build a function pointer given a type and a raw pointer. - /// - /// @param[in] type - /// The type of the function pointer to be built. - /// - /// @param[in] ptr - /// The value of the pointer. - /// - /// @return - /// The pointer. - //------------------------------------------------------------------ - llvm::Constant * - BuildFunctionPointer (llvm::Type *type, - uint64_t ptr); - - void - RegisterFunctionMetadata (llvm::LLVMContext &context, - llvm::Value *function_ptr, - const char *name); - - //------------------------------------------------------------------ - /// The top-level pass implementation - /// - /// @param[in] llvm_function - /// The function currently being processed. - /// - /// @return - /// True if the function has side effects (or if this cannot - /// be determined); false otherwise. - //------------------------------------------------------------------ - bool - ResolveFunctionPointers (llvm::Module &llvm_module); - - //------------------------------------------------------------------ /// A function-level pass to take the generated global value /// $__lldb_expr_result and make it into a persistent variable. /// Also see ASTResultSynthesizer. @@ -565,38 +531,6 @@ private: RemoveGuards (llvm::BasicBlock &basic_block); //------------------------------------------------------------------ - /// A module-level pass to allocate all string literals in a separate - /// allocation and redirect references to them. - //------------------------------------------------------------------ - - //------------------------------------------------------------------ - /// The top-level pass implementation - /// - /// @return - /// True on success; false otherwise - //------------------------------------------------------------------ - bool - ReplaceStrings (); - - //------------------------------------------------------------------ - /// A basic block-level pass to find all literals that will be - /// allocated as statics by the JIT (in contrast to the Strings, - /// which already are statics) and synthesize loads for them. - //------------------------------------------------------------------ - - //------------------------------------------------------------------ - /// The top-level pass implementation - /// - /// @param[in] basic_block - /// The basic block currently being processed. - /// - /// @return - /// True on success; false otherwise - //------------------------------------------------------------------ - bool - ReplaceStaticLiterals (llvm::BasicBlock &basic_block); - - //------------------------------------------------------------------ /// A function-level pass to make all external variable references /// point at the correct offsets from the void* passed into the /// function. ClangExpressionDeclMap::DoStructLayout() must be called @@ -615,39 +549,6 @@ private: bool ReplaceVariables (llvm::Function &llvm_function); - //------------------------------------------------------------------ - /// A module-level pass to remove all global variables from the - /// module since it no longer should export or import any symbols. - //------------------------------------------------------------------ - - //------------------------------------------------------------------ - /// The top-level pass implementation - /// - /// @param[in] llvm_module - /// The module currently being processed. - /// - /// @return - /// True on success; false otherwise - //------------------------------------------------------------------ - bool - StripAllGVs (llvm::Module &llvm_module); - - class StaticDataAllocator { - public: - StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit); - lldb_private::StreamString &GetStream() - { - return m_stream_string; - } - lldb::addr_t Allocate(); - - lldb::TargetSP - GetTarget(); - private: - lldb_private::IRExecutionUnit &m_execution_unit; - lldb_private::StreamString m_stream_string; - lldb::addr_t m_allocation; - }; /// Flags bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved @@ -657,11 +558,11 @@ private: llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet. std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the module being processed, or NULL if there is no module. lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls - StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer. lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed + lldb_private::IRExecutionUnit &m_execution_unit; ///< The execution unit containing the IR being created. llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL. bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::SynthesizeBodyResult) |