diff options
author | Sean Callanan <scallanan@apple.com> | 2013-03-19 01:45:02 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2013-03-19 01:45:02 +0000 |
commit | 9be9d172bfe5987afa6a9727fbe91d10469e6861 (patch) | |
tree | 88278c0c9bb2083b653fc361e383676eb4840947 | |
parent | d67186337afba5a0ff1059b9c9efc1cce575f92d (diff) | |
download | bcm5719-llvm-9be9d172bfe5987afa6a9727fbe91d10469e6861.tar.gz bcm5719-llvm-9be9d172bfe5987afa6a9727fbe91d10469e6861.zip |
Fixed handling of function pointers in the IR
interpreter. They now have correct values, even
when the process is not running.
llvm-svn: 177372
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 32 | ||||
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 22 |
2 files changed, 42 insertions, 12 deletions
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 3dab8339390..c6517e5b0e7 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1066,6 +1066,21 @@ ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl, ClangExpressionVaria ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl, GetParserID())); ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID())); + if (isa<FunctionDecl>(decl)) + { + ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl, GetParserID())); + + if (!entity_sp) + return Value(); + + // We know m_parser_vars is valid since we searched for the variable by + // its NamedDecl + + ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID()); + + return *parser_vars->m_lldb_value; + } + if (expr_var_sp) { flags = expr_var_sp->m_flags; @@ -3690,8 +3705,21 @@ 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); - fun_location->SetValueType(Value::eValueTypeLoadAddress); - fun_location->GetScalar() = load_addr; + + if (load_addr != LLDB_INVALID_ADDRESS) + { + fun_location->SetValueType(Value::eValueTypeLoadAddress); + fun_location->GetScalar() = load_addr; + } + else + { + // We have to try finding a file address. + + lldb::addr_t file_addr = fun_address->GetFileAddress(); + + fun_location->SetValueType(Value::eValueTypeFileAddress); + fun_location->GetScalar() = file_addr; + } ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), m_parser_vars->m_target_info.byte_order, diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 18a92188a70..3c7c76653fb 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -624,6 +624,11 @@ public: // "this", "self", and "_cmd" are direct. bool variable_is_this = false; + // If the variable is a function pointer, we do not need to + // build an extra layer of indirection for it because it is + // accessed directly. + bool variable_is_function_address = false; + // Attempt to resolve the value using the program's data. // If it is, the values to be created are: // @@ -647,12 +652,7 @@ public: break; if (isa<clang::FunctionDecl>(decl)) - { - if (log) - log->Printf("The interpreter does not handle function pointers at the moment"); - - return Memory::Region(); - } + variable_is_function_address = true; resolved_value = m_decl_map.LookupDecl(decl, flags); } @@ -786,17 +786,19 @@ public: } else { + bool no_extra_redirect = (variable_is_this || variable_is_function_address); + Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value); Memory::Region ref_region = m_memory.Malloc(value->getType()); Memory::Region pointer_region; - if (!variable_is_this) + if (!no_extra_redirect) pointer_region = m_memory.Malloc(value->getType()); if (ref_region.IsInvalid()) return Memory::Region(); - if (pointer_region.IsInvalid() && !variable_is_this) + if (pointer_region.IsInvalid() && !no_extra_redirect) return Memory::Region(); DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region); @@ -804,7 +806,7 @@ public: if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX) return Memory::Region(); - if (!variable_is_this) + if (!no_extra_redirect) { DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region); @@ -824,7 +826,7 @@ public: log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base); } - if (variable_is_this) + if (no_extra_redirect) return ref_region; else return pointer_region; |