summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp6
-rw-r--r--lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp13
-rw-r--r--lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h3
-rw-r--r--lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp69
-rw-r--r--lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h2
5 files changed, 93 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 2cee5c01da9..42bfefe8d62 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -784,6 +784,12 @@ ParseSymbols(Symtab *symtab,
// STB_LOCAL symbols for the file, if it is present.
symbol_type = eSymbolTypeObjectFile;
break;
+
+ case STT_GNU_IFUNC:
+ // The symbol is associated with an indirect function. The actual
+ // function will be resolved if it is referenced.
+ symbol_type = eSymbolTypeResolver;
+ break;
}
}
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index c65f95c883d..0a741bca1de 100644
--- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -483,6 +483,19 @@ ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
return error;
}
+addr_t
+ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
+{
+ addr_t function_addr = LLDB_INVALID_ADDRESS;
+ if (address == NULL) {
+ error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
+ } else if (!InferiorCall(this, address, function_addr)) {
+ function_addr = LLDB_INVALID_ADDRESS;
+ error.SetErrorStringWithFormat("unable to determine direct function call for indirect function with address %x", address);
+ }
+ return function_addr;
+}
+
size_t
ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
{
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
index d12e063c312..068686df99f 100644
--- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
@@ -96,6 +96,9 @@ public:
virtual lldb_private::Error
DoDeallocateMemory(lldb::addr_t ptr);
+ virtual lldb::addr_t
+ ResolveIndirectFunction(const lldb_private::Address *address, lldb_private::Error &error);
+
virtual size_t
GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 905ab251446..ba1d3b6eb95 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "InferiorCallPOSIX.h"
+#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -119,6 +120,11 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
if (allocated_addr == UINT32_MAX)
return false;
}
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (allocated_addr == UINT64_MAX)
+ return false;
+ }
return true;
}
}
@@ -203,3 +209,66 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
return false;
}
+
+bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
+ Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ if (thread == NULL || address == NULL)
+ return false;
+
+ const bool stop_other_threads = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
+ const bool try_all_threads = true;
+ const uint32_t timeout_usec = 500000;
+
+ ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
+ lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ThreadPlanCallFunction *call_function_thread_plan
+ = new ThreadPlanCallFunction (*thread,
+ *address,
+ ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+ stop_other_threads,
+ unwind_on_error,
+ ignore_breakpoints);
+ lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
+ if (call_plan_sp)
+ {
+ StreamFile error_strm;
+ // This plan is a utility plan, so set it to discard itself when done.
+ call_plan_sp->SetIsMasterPlan (true);
+ call_plan_sp->SetOkayToDiscard(true);
+
+ StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ if (frame)
+ {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext (exe_ctx);
+ ExecutionResults result = process->RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ stop_other_threads,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ timeout_usec,
+ error_strm);
+ if (result == eExecutionCompleted)
+ {
+ returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+ if (process->GetAddressByteSize() == 4)
+ {
+ if (returned_func == UINT32_MAX)
+ return false;
+ }
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (returned_func == UINT64_MAX)
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index a85db72ec03..d8b6d0ed57f 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -36,6 +36,8 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr,
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
+bool InferiorCall(Process *proc, const Address *address, lldb::addr_t &returned_func);
+
} // namespace lldb_private
#endif // lldb_InferiorCallPOSIX_h_
OpenPOWER on IntegriCloud