diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 9795627a3f4c..5d8a1c8332f0 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -88,6 +88,8 @@ public: off_t &offset, uint32_t index); + uint64_t GetFunctionAddress (const clang::NamedDecl *decl); + // Interface for DwarfExpression Value *GetValueForIndex (uint32_t index); diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h index 938349fa0ae5..5d10e90fafc2 100644 --- a/lldb/include/lldb/Expression/IRForTarget.h +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -14,6 +14,7 @@ namespace llvm { class BasicBlock; + class CallInst; class Function; class Module; class TargetData; @@ -37,15 +38,18 @@ public: llvm::PassManagerType getPotentialPassManagerType() const; private: bool MaybeHandleVariable(llvm::Module &M, - lldb_private::ClangExpressionDeclMap *DM, llvm::Value *V, bool Store); + bool MaybeHandleCall(llvm::Module &M, + llvm::CallInst *C); bool runOnBasicBlock(llvm::Module &M, llvm::BasicBlock &BB); bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); bool replaceVariables(llvm::Module &M, llvm::Function *F); + bool replaceFunctions(llvm::Module &M, + llvm::Function *F); lldb_private::ClangExpressionDeclMap *m_decl_map; const llvm::TargetData *m_target_data; diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index d5d381d64a26..c26b77d75e6d 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -182,6 +182,24 @@ ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl, return true; } +uint64_t +ClangExpressionDeclMap::GetFunctionAddress (const clang::NamedDecl *decl) +{ + TupleIterator iter; + + for (iter = m_tuples.begin(); + iter != m_tuples.end(); + ++iter) + { + if (decl == iter->m_decl) + { + return iter->m_value->GetScalar().ULongLong(); + } + } + + return 0; +} + // Interface for DwarfExpression lldb_private::Value *ClangExpressionDeclMap::GetValueForIndex (uint32_t index) diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index ce28a8f362c3..4f5d44c70a18 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -82,7 +82,6 @@ DeclForGlobalValue(llvm::Module &module, bool IRForTarget::MaybeHandleVariable(Module &M, - lldb_private::ClangExpressionDeclMap *DM, llvm::Value *V, bool Store) { @@ -110,19 +109,54 @@ IRForTarget::MaybeHandleVariable(Module &M, size_t value_size = m_target_data->getTypeStoreSize(value_type); off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type); - if (named_decl && !DM->AddValueToStruct(V, - named_decl, - name, - qual_type, - ast_context, - value_size, - value_alignment)) + if (named_decl && !m_decl_map->AddValueToStruct(V, + named_decl, + name, + qual_type, + ast_context, + value_size, + value_alignment)) return false; } return true; } +bool +IRForTarget::MaybeHandleCall(Module &M, + CallInst *C) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + llvm::Function *fun = C->getCalledFunction(); + + if (fun == NULL) + return true; + + clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun); + + if (!fun_decl) + { + if (log) + log->Printf("Function %s wasn't in the metadata", fun->getName().str().c_str()); + return false; + } + + uint64_t fun_addr = m_decl_map->GetFunctionAddress(fun_decl); + + if (fun_addr == 0) + { + if (log) + log->Printf("Function %s had no address", fun_decl->getNameAsCString()); + return false; + } + + if (log) + log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr); + + return true; +} + bool IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB) { @@ -139,11 +173,15 @@ IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB) Instruction &inst = *ii; if (LoadInst *load = dyn_cast(&inst)) - if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false)) + if (!MaybeHandleVariable(M, load->getPointerOperand(), false)) return false; if (StoreInst *store = dyn_cast(&inst)) - if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false)) + if (!MaybeHandleVariable(M, store->getPointerOperand(), true)) + return false; + + if (CallInst *call = dyn_cast(&inst)) + if (!MaybeHandleCall(M, call)) return false; }