|
13 | 13 | #include "llvm/IR/DiagnosticInfo.h" |
14 | 14 | #include "llvm/IR/LLVMContext.h" |
15 | 15 | #include "llvm/IR/Module.h" |
| 16 | +#include "llvm/Support/Error.h" |
16 | 17 | #include "llvm/Support/SourceMgr.h" |
17 | 18 | #include "llvm/Support/raw_ostream.h" |
18 | 19 |
|
19 | 20 | #include "lldb/Core/Debugger.h" |
20 | 21 | #include "lldb/Core/Disassembler.h" |
21 | 22 | #include "lldb/Core/Module.h" |
22 | 23 | #include "lldb/Core/Section.h" |
| 24 | +#include "lldb/Expression/Expression.h" |
23 | 25 | #include "lldb/Expression/IRExecutionUnit.h" |
24 | 26 | #include "lldb/Expression/ObjectFileJIT.h" |
25 | 27 | #include "lldb/Host/HostInfo.h" |
|
36 | 38 | #include "lldb/Utility/LLDBAssert.h" |
37 | 39 | #include "lldb/Utility/LLDBLog.h" |
38 | 40 | #include "lldb/Utility/Log.h" |
| 41 | +#include "lldb/lldb-defines.h" |
39 | 42 |
|
40 | 43 | #include <optional> |
41 | 44 |
|
@@ -771,6 +774,40 @@ class LoadAddressResolver { |
771 | 774 | lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS; |
772 | 775 | }; |
773 | 776 |
|
| 777 | +/// Returns address of the function referred to by the special function call |
| 778 | +/// label \c label. |
| 779 | +static llvm::Expected<lldb::addr_t> |
| 780 | +ResolveFunctionCallLabel(const FunctionCallLabel &label, |
| 781 | + const lldb_private::SymbolContext &sc, |
| 782 | + bool &symbol_was_missing_weak) { |
| 783 | + symbol_was_missing_weak = false; |
| 784 | + |
| 785 | + if (!sc.target_sp) |
| 786 | + return llvm::createStringError("target not available."); |
| 787 | + |
| 788 | + auto module_sp = sc.target_sp->GetImages().FindModule(label.module_id); |
| 789 | + if (!module_sp) |
| 790 | + return llvm::createStringError( |
| 791 | + llvm::formatv("failed to find module by UID {0}", label.module_id)); |
| 792 | + |
| 793 | + auto *symbol_file = module_sp->GetSymbolFile(); |
| 794 | + if (!symbol_file) |
| 795 | + return llvm::createStringError( |
| 796 | + llvm::formatv("no SymbolFile found on module {0:x}.", module_sp.get())); |
| 797 | + |
| 798 | + auto sc_or_err = symbol_file->ResolveFunctionCallLabel(label); |
| 799 | + if (!sc_or_err) |
| 800 | + return llvm::joinErrors( |
| 801 | + llvm::createStringError("failed to resolve function by UID"), |
| 802 | + sc_or_err.takeError()); |
| 803 | + |
| 804 | + SymbolContextList sc_list; |
| 805 | + sc_list.Append(*sc_or_err); |
| 806 | + |
| 807 | + LoadAddressResolver resolver(*sc.target_sp, symbol_was_missing_weak); |
| 808 | + return resolver.Resolve(sc_list).value_or(LLDB_INVALID_ADDRESS); |
| 809 | +} |
| 810 | + |
774 | 811 | lldb::addr_t |
775 | 812 | IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, |
776 | 813 | const lldb_private::SymbolContext &sc, |
@@ -906,6 +943,34 @@ lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols( |
906 | 943 |
|
907 | 944 | lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name, |
908 | 945 | bool &missing_weak) { |
| 946 | + if (name.GetStringRef().starts_with(FunctionCallLabelPrefix)) { |
| 947 | + auto label_or_err = FunctionCallLabel::fromString(name); |
| 948 | + if (!label_or_err) { |
| 949 | + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), label_or_err.takeError(), |
| 950 | + "failed to create FunctionCallLabel from '{1}': {0}", |
| 951 | + name.GetStringRef()); |
| 952 | + return LLDB_INVALID_ADDRESS; |
| 953 | + } |
| 954 | + |
| 955 | + if (auto addr_or_err = |
| 956 | + ResolveFunctionCallLabel(*label_or_err, m_sym_ctx, missing_weak)) { |
| 957 | + return *addr_or_err; |
| 958 | + } else { |
| 959 | + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), addr_or_err.takeError(), |
| 960 | + "Failed to resolve function call label '{1}': {0}", |
| 961 | + name.GetStringRef()); |
| 962 | + |
| 963 | + // Fall back to lookup by name despite error in resolving the label. |
| 964 | + // May happen in practice if the definition of a function lives in |
| 965 | + // a different lldb_private::Module than it's declaration. Meaning |
| 966 | + // we couldn't pin-point it using the information encoded in the label. |
| 967 | + name.SetString(label_or_err->lookup_name); |
| 968 | + } |
| 969 | + } |
| 970 | + |
| 971 | + // TODO: now with function call labels, do we still need to |
| 972 | + // generate alternate manglings? |
| 973 | + |
909 | 974 | std::vector<ConstString> candidate_C_names; |
910 | 975 | std::vector<ConstString> candidate_CPlusPlus_names; |
911 | 976 |
|
|
0 commit comments