|
15 | 15 | #include "llvm/IR/DiagnosticInfo.h" |
16 | 16 | #include "llvm/IR/LLVMContext.h" |
17 | 17 | #include "llvm/IR/Module.h" |
| 18 | +#include "llvm/Support/Error.h" |
18 | 19 | #include "llvm/Support/SourceMgr.h" |
19 | 20 | #include "llvm/Support/raw_ostream.h" |
20 | 21 |
|
|
23 | 24 | #include "lldb/Core/JITSection.h" |
24 | 25 | #include "lldb/Core/Module.h" |
25 | 26 | #include "lldb/Core/Section.h" |
| 27 | +#include "lldb/Expression/Expression.h" |
26 | 28 | #include "lldb/Expression/IRExecutionUnit.h" |
27 | 29 | #include "lldb/Expression/ObjectFileJIT.h" |
28 | 30 | #include "lldb/Host/HostInfo.h" |
|
39 | 41 | #include "lldb/Utility/LLDBAssert.h" |
40 | 42 | #include "lldb/Utility/LLDBLog.h" |
41 | 43 | #include "lldb/Utility/Log.h" |
| 44 | +#include "lldb/lldb-defines.h" |
42 | 45 |
|
43 | 46 | #include <optional> |
44 | 47 |
|
@@ -810,6 +813,40 @@ class LoadAddressResolver { |
810 | 813 | lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS; |
811 | 814 | }; |
812 | 815 |
|
| 816 | +/// Returns address of the function referred to by the special function call |
| 817 | +/// label \c label. |
| 818 | +static llvm::Expected<lldb::addr_t> |
| 819 | +ResolveFunctionCallLabel(const FunctionCallLabel &label, |
| 820 | + const lldb_private::SymbolContext &sc, |
| 821 | + bool &symbol_was_missing_weak) { |
| 822 | + symbol_was_missing_weak = false; |
| 823 | + |
| 824 | + if (!sc.target_sp) |
| 825 | + return llvm::createStringError("target not available."); |
| 826 | + |
| 827 | + auto module_sp = sc.target_sp->GetImages().FindModule(label.module_id); |
| 828 | + if (!module_sp) |
| 829 | + return llvm::createStringError( |
| 830 | + llvm::formatv("failed to find module by UID {0}", label.module_id)); |
| 831 | + |
| 832 | + auto *symbol_file = module_sp->GetSymbolFile(); |
| 833 | + if (!symbol_file) |
| 834 | + return llvm::createStringError( |
| 835 | + llvm::formatv("no SymbolFile found on module {0:x}.", module_sp.get())); |
| 836 | + |
| 837 | + auto sc_or_err = symbol_file->ResolveFunctionCallLabel(label); |
| 838 | + if (!sc_or_err) |
| 839 | + return llvm::joinErrors( |
| 840 | + llvm::createStringError("failed to resolve function by UID"), |
| 841 | + sc_or_err.takeError()); |
| 842 | + |
| 843 | + SymbolContextList sc_list; |
| 844 | + sc_list.Append(*sc_or_err); |
| 845 | + |
| 846 | + LoadAddressResolver resolver(*sc.target_sp, symbol_was_missing_weak); |
| 847 | + return resolver.Resolve(sc_list).value_or(LLDB_INVALID_ADDRESS); |
| 848 | +} |
| 849 | + |
813 | 850 | lldb::addr_t |
814 | 851 | IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, |
815 | 852 | const lldb_private::SymbolContext &sc, |
@@ -954,6 +991,34 @@ lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols( |
954 | 991 |
|
955 | 992 | lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name, |
956 | 993 | bool &missing_weak) { |
| 994 | + if (name.GetStringRef().starts_with(FunctionCallLabelPrefix)) { |
| 995 | + auto label_or_err = FunctionCallLabel::fromString(name); |
| 996 | + if (!label_or_err) { |
| 997 | + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), label_or_err.takeError(), |
| 998 | + "failed to create FunctionCallLabel from '{1}': {0}", |
| 999 | + name.GetStringRef()); |
| 1000 | + return LLDB_INVALID_ADDRESS; |
| 1001 | + } |
| 1002 | + |
| 1003 | + if (auto addr_or_err = |
| 1004 | + ResolveFunctionCallLabel(*label_or_err, m_sym_ctx, missing_weak)) { |
| 1005 | + return *addr_or_err; |
| 1006 | + } else { |
| 1007 | + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), addr_or_err.takeError(), |
| 1008 | + "Failed to resolve function call label '{1}': {0}", |
| 1009 | + name.GetStringRef()); |
| 1010 | + |
| 1011 | + // Fall back to lookup by name despite error in resolving the label. |
| 1012 | + // May happen in practice if the definition of a function lives in |
| 1013 | + // a different lldb_private::Module than it's declaration. Meaning |
| 1014 | + // we couldn't pin-point it using the information encoded in the label. |
| 1015 | + name.SetString(label_or_err->lookup_name); |
| 1016 | + } |
| 1017 | + } |
| 1018 | + |
| 1019 | + // TODO: now with function call labels, do we still need to |
| 1020 | + // generate alternate manglings? |
| 1021 | + |
957 | 1022 | std::vector<ConstString> candidate_C_names; |
958 | 1023 | std::vector<ConstString> candidate_CPlusPlus_names; |
959 | 1024 |
|
|
0 commit comments