aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Expression/IRExecutionUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Expression/IRExecutionUnit.cpp')
-rw-r--r--lldb/source/Expression/IRExecutionUnit.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp
index 6f812b9..5e40df2 100644
--- a/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/lldb/source/Expression/IRExecutionUnit.cpp
@@ -13,6 +13,7 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
@@ -20,6 +21,7 @@
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
+#include "lldb/Expression/Expression.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/ObjectFileJIT.h"
#include "lldb/Host/HostInfo.h"
@@ -36,6 +38,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
+#include "lldb/lldb-defines.h"
#include <optional>
@@ -771,6 +774,40 @@ private:
lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS;
};
+/// Returns address of the function referred to by the special function call
+/// label \c label.
+static llvm::Expected<lldb::addr_t>
+ResolveFunctionCallLabel(const FunctionCallLabel &label,
+ const lldb_private::SymbolContext &sc,
+ bool &symbol_was_missing_weak) {
+ symbol_was_missing_weak = false;
+
+ if (!sc.target_sp)
+ return llvm::createStringError("target not available.");
+
+ auto module_sp = sc.target_sp->GetImages().FindModule(label.module_id);
+ if (!module_sp)
+ return llvm::createStringError(
+ llvm::formatv("failed to find module by UID {0}", label.module_id));
+
+ auto *symbol_file = module_sp->GetSymbolFile();
+ if (!symbol_file)
+ return llvm::createStringError(
+ llvm::formatv("no SymbolFile found on module {0:x}.", module_sp.get()));
+
+ auto sc_or_err = symbol_file->ResolveFunctionCallLabel(label);
+ if (!sc_or_err)
+ return llvm::joinErrors(
+ llvm::createStringError("failed to resolve function by UID"),
+ sc_or_err.takeError());
+
+ SymbolContextList sc_list;
+ sc_list.Append(*sc_or_err);
+
+ LoadAddressResolver resolver(*sc.target_sp, symbol_was_missing_weak);
+ return resolver.Resolve(sc_list).value_or(LLDB_INVALID_ADDRESS);
+}
+
lldb::addr_t
IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names,
const lldb_private::SymbolContext &sc,
@@ -906,6 +943,34 @@ lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols(
lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name,
bool &missing_weak) {
+ if (name.GetStringRef().starts_with(FunctionCallLabelPrefix)) {
+ auto label_or_err = FunctionCallLabel::fromString(name);
+ if (!label_or_err) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), label_or_err.takeError(),
+ "failed to create FunctionCallLabel from '{1}': {0}",
+ name.GetStringRef());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ if (auto addr_or_err =
+ ResolveFunctionCallLabel(*label_or_err, m_sym_ctx, missing_weak)) {
+ return *addr_or_err;
+ } else {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), addr_or_err.takeError(),
+ "Failed to resolve function call label '{1}': {0}",
+ name.GetStringRef());
+
+ // Fall back to lookup by name despite error in resolving the label.
+ // May happen in practice if the definition of a function lives in
+ // a different lldb_private::Module than it's declaration. Meaning
+ // we couldn't pin-point it using the information encoded in the label.
+ name.SetString(label_or_err->lookup_name);
+ }
+ }
+
+ // TODO: now with function call labels, do we still need to
+ // generate alternate manglings?
+
std::vector<ConstString> candidate_C_names;
std::vector<ConstString> candidate_CPlusPlus_names;