diff options
author | Greg Clayton <gclayton@apple.com> | 2014-03-24 23:10:19 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2014-03-24 23:10:19 +0000 |
commit | 23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0 (patch) | |
tree | 3e56f285be57acf15b3fb73195567727a329aca9 /lldb/source/Expression/IRForTarget.cpp | |
parent | 2256d0dcedf887593ebfb35db860827e8682807e (diff) | |
download | bcm5719-llvm-23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0.tar.gz bcm5719-llvm-23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0.zip |
JITed functions can now have debug info and be debugged with debug and source info:
(lldb) b puts
(lldb) expr -g -i0 -- (int)puts("hello")
First we will stop at the entry point of the expression before it runs, then we can step over a few times and hit the breakpoint in "puts", then we can continue and finishing stepping and fininsh the expression.
Main features:
- New ObjectFileJIT class that can be easily created for JIT functions
- debug info can now be enabled when parsing expressions
- source for any function that is run throught the JIT is now saved in LLDB process specific temp directory and cleaned up on exit
- "expr -g --" allows you to single step through your expression function with source code
<rdar://problem/16382881>
llvm-svn: 204682
Diffstat (limited to 'lldb/source/Expression/IRForTarget.cpp')
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 0ec3525a50e..a1fa6538e04 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -157,7 +157,7 @@ IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) return true; } -bool +IRForTarget::LookupResult IRForTarget::GetFunctionAddress (llvm::Function *fun, uint64_t &fun_addr, lldb_private::ConstString &name, @@ -182,7 +182,7 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, 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 false; + return LookupResult::Fail; case Intrinsic::memcpy: { static lldb_private::ConstString g_memcpy_str ("memcpy"); @@ -195,6 +195,8 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, name = g_memset_str; } break; + case Intrinsic::dbg_declare: + return LookupResult::Ignore; } if (log && name) @@ -258,7 +260,7 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n", mangled_name.GetName().GetCString()); } - return false; + return LookupResult::Fail; } } } @@ -272,14 +274,14 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, 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 false; + return LookupResult::Fail; } } if (log) log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr); - return true; + return LookupResult::Success; } llvm::Constant * @@ -339,34 +341,46 @@ IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module) lldb_private::ConstString name; Constant **value_ptr = NULL; - if (!GetFunctionAddress(fun, - addr, - name, - value_ptr)) - return false; // GetFunctionAddress reports its own errors + LookupResult result = GetFunctionAddress(fun, + addr, + name, + value_ptr); - 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); + 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; } - - fun->replaceAllUsesWith(value); } return true; |