summaryrefslogtreecommitdiff
path: root/include/lldb/Expression
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Expression')
-rw-r--r--include/lldb/Expression/DWARFExpression.h15
-rw-r--r--include/lldb/Expression/DiagnosticManager.h212
-rw-r--r--include/lldb/Expression/ExpressionParser.h23
-rw-r--r--include/lldb/Expression/ExpressionSourceCode.h9
-rw-r--r--include/lldb/Expression/ExpressionVariable.h13
-rw-r--r--include/lldb/Expression/FunctionCaller.h84
-rw-r--r--include/lldb/Expression/IRDynamicChecks.h15
-rw-r--r--include/lldb/Expression/IRExecutionUnit.h170
-rw-r--r--include/lldb/Expression/IRInterpreter.h2
-rw-r--r--include/lldb/Expression/IRMemoryMap.h2
-rw-r--r--include/lldb/Expression/LLVMUserExpression.h60
-rw-r--r--include/lldb/Expression/UserExpression.h54
-rw-r--r--include/lldb/Expression/UtilityFunction.h12
13 files changed, 517 insertions, 154 deletions
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
index 3527c3b4b153c..d984a419c5c92 100644
--- a/include/lldb/Expression/DWARFExpression.h
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -10,11 +10,12 @@
#ifndef liblldb_DWARFExpression_h_
#define liblldb_DWARFExpression_h_
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/lldb-private.h"
+#include <functional>
class DWARFCompileUnit;
@@ -166,7 +167,14 @@ public:
bool
Update_DW_OP_addr (lldb::addr_t file_addr);
-
+
+ bool
+ ContainsThreadLocalStorage() const;
+
+ bool
+ LinkThreadLocalStorage(lldb::ModuleSP new_module_sp,
+ std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback);
+
//------------------------------------------------------------------
/// Make the expression parser read its location information from a
/// given data source. Does not change the offset and length
@@ -282,6 +290,7 @@ public:
ClangExpressionDeclMap *decl_map,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr) const;
@@ -296,6 +305,7 @@ public:
RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr) const;
@@ -370,6 +380,7 @@ public:
const lldb::offset_t length,
const lldb::RegisterKind reg_set,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr);
diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h
new file mode 100644
index 0000000000000..c294bdecf2b24
--- /dev/null
+++ b/include/lldb/Expression/DiagnosticManager.h
@@ -0,0 +1,212 @@
+//===-- DiagnosticManager.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_DiagnosticManager_h
+#define lldb_DiagnosticManager_h
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+#include <string>
+#include <vector>
+
+namespace lldb_private
+{
+
+enum DiagnosticOrigin
+{
+ eDiagnosticOriginUnknown = 0,
+ eDiagnosticOriginLLDB,
+ eDiagnosticOriginClang,
+ eDiagnosticOriginGo,
+ eDiagnosticOriginSwift,
+ eDiagnosticOriginLLVM
+};
+
+enum DiagnosticSeverity
+{
+ eDiagnosticSeverityError,
+ eDiagnosticSeverityWarning,
+ eDiagnosticSeverityRemark
+};
+
+const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX;
+
+class Diagnostic
+{
+friend class DiagnosticManager;
+
+public:
+ DiagnosticOrigin getKind() const { return m_origin; }
+
+ static bool classof(const Diagnostic *diag)
+ {
+ DiagnosticOrigin kind = diag->getKind();
+ switch (kind)
+ {
+ case eDiagnosticOriginUnknown:
+ case eDiagnosticOriginLLDB:
+ case eDiagnosticOriginGo:
+ case eDiagnosticOriginLLVM:
+ return true;
+ case eDiagnosticOriginClang:
+ case eDiagnosticOriginSwift:
+ return false;
+ }
+ }
+
+ Diagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id) :
+ m_message(message),
+ m_severity(severity),
+ m_origin(origin),
+ m_compiler_id(compiler_id)
+ {
+ }
+
+ Diagnostic(const Diagnostic &rhs) :
+ m_message(rhs.m_message),
+ m_severity(rhs.m_severity),
+ m_origin(rhs.m_origin),
+ m_compiler_id(rhs.m_compiler_id)
+ {
+ }
+
+ virtual ~Diagnostic() = default;
+
+ virtual bool HasFixIts () const { return false; }
+
+ DiagnosticSeverity
+ GetSeverity() const
+ {
+ return m_severity;
+ }
+
+ uint32_t
+ GetCompilerID() const
+ {
+ return m_compiler_id;
+ }
+
+ const char *
+ GetMessage() const
+ {
+ return m_message.c_str();
+ }
+
+ void AppendMessage(const char *message, bool precede_with_newline = true)
+ {
+ if (precede_with_newline)
+ m_message.push_back('\n');
+ m_message.append(message);
+ }
+
+protected:
+ std::string m_message;
+ DiagnosticSeverity m_severity;
+ DiagnosticOrigin m_origin;
+ uint32_t m_compiler_id; // Compiler-specific diagnostic ID
+};
+
+typedef std::vector<Diagnostic *> DiagnosticList;
+
+class DiagnosticManager
+{
+public:
+ void
+ Clear()
+ {
+ m_diagnostics.clear();
+ m_fixed_expression.clear();
+ }
+
+ // The diagnostic manager holds a list of diagnostics, which are owned by the manager.
+ const DiagnosticList &
+ Diagnostics()
+ {
+ return m_diagnostics;
+ }
+
+ ~DiagnosticManager()
+ {
+ for (Diagnostic *diag : m_diagnostics)
+ {
+ delete diag;
+ }
+ }
+
+ bool
+ HasFixIts()
+ {
+ for (Diagnostic *diag : m_diagnostics)
+ {
+ if (diag->HasFixIts())
+ return true;
+ }
+ return false;
+ }
+
+ void
+ AddDiagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin,
+ uint32_t compiler_id = LLDB_INVALID_COMPILER_ID)
+ {
+ m_diagnostics.push_back(new Diagnostic(message, severity, origin, compiler_id));
+ }
+
+ void
+ AddDiagnostic(Diagnostic *diagnostic)
+ {
+ m_diagnostics.push_back(diagnostic);
+ }
+
+ size_t
+ Printf(DiagnosticSeverity severity, const char *format, ...) __attribute__((format(printf, 3, 4)));
+ size_t
+ PutCString(DiagnosticSeverity severity, const char *cstr);
+
+ void
+ AppendMessageToDiagnostic(const char *cstr)
+ {
+ if (m_diagnostics.size())
+ {
+ m_diagnostics.back()->AppendMessage(cstr);
+ }
+ }
+
+ // Returns a string containing errors in this format:
+ //
+ // "error: error text\n
+ // warning: warning text\n
+ // remark text\n"
+ std::string
+ GetString(char separator = '\n');
+
+ void
+ Dump(Log *log);
+
+ const std::string &
+ GetFixedExpression()
+ {
+ return m_fixed_expression;
+ }
+
+ // Moves fixed_expression to the internal storage.
+ void
+ SetFixedExpression(std::string fixed_expression)
+ {
+ m_fixed_expression = std::move(fixed_expression);
+ fixed_expression.clear();
+ }
+
+protected:
+ DiagnosticList m_diagnostics;
+ std::string m_fixed_expression;
+};
+}
+
+#endif /* lldb_DiagnosticManager_h */
diff --git a/include/lldb/Expression/ExpressionParser.h b/include/lldb/Expression/ExpressionParser.h
index 49333e79bf5ec..323e515e3bba1 100644
--- a/include/lldb/Expression/ExpressionParser.h
+++ b/include/lldb/Expression/ExpressionParser.h
@@ -57,17 +57,34 @@ public:
/// Parse a single expression and convert it to IR using Clang. Don't
/// wrap the expression in anything at all.
///
- /// @param[in] stream
- /// The stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager in which to store the errors and warnings.
///
/// @return
/// The number of errors encountered during parsing. 0 means
/// success.
//------------------------------------------------------------------
virtual unsigned
- Parse (Stream &stream) = 0;
+ Parse(DiagnosticManager &diagnostic_manager) = 0;
//------------------------------------------------------------------
+ /// Try to use the FixIts in the diagnostic_manager to rewrite the
+ /// expression. If successful, the rewritten expression is stored
+ /// in the diagnostic_manager, get it out with GetFixedExpression.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager containing fixit's to apply.
+ ///
+ /// @return
+ /// \b true if the rewrite was successful, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ RewriteExpression(DiagnosticManager &diagnostic_manager)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
/// Ready an already-parsed expression for execution, possibly
/// evaluating it statically.
///
diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h
index 2dd09378fcd2f..33ceade455582 100644
--- a/include/lldb/Expression/ExpressionSourceCode.h
+++ b/include/lldb/Expression/ExpressionSourceCode.h
@@ -54,10 +54,17 @@ public:
bool GetText (std::string &text,
lldb::LanguageType wrapping_language,
- bool const_object,
bool static_method,
ExecutionContext &exe_ctx) const;
+ // Given a string returned by GetText, find the beginning and end of the body passed to CreateWrapped.
+ // Return true if the bounds could be found. This will also work on text with FixItHints applied.
+ static bool
+ GetOriginalBodyBounds(std::string transformed_text,
+ lldb::LanguageType wrapping_language,
+ size_t &start_loc,
+ size_t &end_loc);
+
private:
ExpressionSourceCode (const char *name,
const char *prefix,
diff --git a/include/lldb/Expression/ExpressionVariable.h b/include/lldb/Expression/ExpressionVariable.h
index d8030ba1c2579..451acb685bb7e 100644
--- a/include/lldb/Expression/ExpressionVariable.h
+++ b/include/lldb/Expression/ExpressionVariable.h
@@ -16,6 +16,8 @@
#include <vector>
// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
@@ -309,10 +311,19 @@ public:
RemovePersistentVariable (lldb::ExpressionVariableSP variable) = 0;
virtual lldb::addr_t
- LookupSymbol (const ConstString &name) = 0;
+ LookupSymbol (const ConstString &name);
+
+ void
+ RegisterExecutionUnit (lldb::IRExecutionUnitSP &execution_unit_sp);
private:
LLVMCastKind m_kind;
+
+ typedef std::set<lldb::IRExecutionUnitSP> ExecutionUnitSet;
+ ExecutionUnitSet m_execution_units; ///< The execution units that contain valuable symbols.
+
+ typedef llvm::DenseMap<const char *, lldb::addr_t> SymbolMap;
+ SymbolMap m_symbol_map; ///< The addresses of the symbols in m_execution_units.
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/FunctionCaller.h b/include/lldb/Expression/FunctionCaller.h
index c9a45811670fe..3848073c654f4 100644
--- a/include/lldb/Expression/FunctionCaller.h
+++ b/include/lldb/Expression/FunctionCaller.h
@@ -99,17 +99,23 @@ public:
//------------------------------------------------------------------
/// Compile the wrapper function
///
- /// @param[in] errors
- /// The stream to print parser errors to.
+ /// @param[in] thread_to_use_sp
+ /// Compilation might end up calling functions. Pass in the thread you
+ /// want the compilation to use. If you pass in an empty ThreadSP it will
+ /// use the currently selected thread.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report parser errors to.
///
/// @return
/// The number of errors.
//------------------------------------------------------------------
virtual unsigned
- CompileFunction (Stream &errors) = 0;
-
+ CompileFunction (lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) = 0;
+
//------------------------------------------------------------------
- /// Insert the default function wrapper and its default argument struct
+ /// Insert the default function wrapper and its default argument struct
///
/// @param[in] exe_ctx
/// The execution context to insert the function and its arguments
@@ -120,16 +126,14 @@ public:
/// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
/// and args_addr_ref is pointed to it.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
bool
- InsertFunction (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors);
+ InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager);
//------------------------------------------------------------------
/// Insert the default function wrapper (using the JIT)
@@ -138,17 +142,17 @@ public:
/// The execution context to insert the function and its arguments
/// into.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionWrapper (ExecutionContext &exe_ctx,
- Stream &errors);
-
+ bool
+ WriteFunctionWrapper(ExecutionContext &exe_ctx, DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
- /// Insert the default function argument struct
+ /// Insert the default function argument struct
///
/// @param[in] exe_ctx
/// The execution context to insert the function and its arguments
@@ -159,16 +163,16 @@ public:
/// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
/// and args_addr_ref is pointed to it.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionArguments (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors);
-
+ bool
+ WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
+ DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
/// Insert an argument struct with a non-default function address and
/// non-default argument values
@@ -185,16 +189,15 @@ public:
/// @param[in] arg_values
/// The values of the function's arguments.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionArguments (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- ValueList &arg_values,
- Stream &errors);
+ bool
+ WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, ValueList &arg_values,
+ DiagnosticManager &diagnostic_manager);
//------------------------------------------------------------------
/// Run the function this FunctionCaller was created with.
@@ -211,8 +214,8 @@ public:
/// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS,
/// this should point to an already allocated structure with the values already written.
///
- /// @param[in] errors
- /// Errors will be written here if there are any.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @param[in] options
/// The options for this expression execution.
@@ -224,12 +227,9 @@ public:
/// Returns one of the ExpressionResults enum indicating function call status.
//------------------------------------------------------------------
lldb::ExpressionResults
- ExecuteFunction(ExecutionContext &exe_ctx,
- lldb::addr_t *args_addr_ptr,
- const EvaluateExpressionOptions &options,
- Stream &errors,
- Value &results);
-
+ ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options,
+ DiagnosticManager &diagnostic_manager, Value &results);
+
//------------------------------------------------------------------
/// Get a thread plan to run the function this FunctionCaller was created with.
///
@@ -243,8 +243,8 @@ public:
/// @param[in] args_addr
/// The address of the argument struct.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @param[in] stop_others
/// True if other threads should pause during execution.
@@ -256,11 +256,9 @@ public:
/// A ThreadPlan shared pointer for executing the function.
//------------------------------------------------------------------
lldb::ThreadPlanSP
- GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t args_addr,
- const EvaluateExpressionOptions &options,
- Stream &errors);
-
+ GetThreadPlanToCallFunction(ExecutionContext &exe_ctx, lldb::addr_t args_addr,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
/// Get the result of the function from its struct
///
diff --git a/include/lldb/Expression/IRDynamicChecks.h b/include/lldb/Expression/IRDynamicChecks.h
index ef77d55f4b340..9f31a6eb01d63 100644
--- a/include/lldb/Expression/IRDynamicChecks.h
+++ b/include/lldb/Expression/IRDynamicChecks.h
@@ -61,8 +61,8 @@ public:
/// Install the utility functions into a process. This binds the
/// instance of DynamicCheckerFunctions to that process.
///
- /// @param[in] error_stream
- /// A stream to print errors on.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to install the functions into.
@@ -71,11 +71,12 @@ public:
/// True on success; false on failure, or if the functions have
/// already been installed.
//------------------------------------------------------------------
- bool Install (Stream &error_stream,
- ExecutionContext &exe_ctx);
-
- bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message);
-
+ bool
+ Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx);
+
+ bool
+ DoCheckersExplainStop(lldb::addr_t addr, Stream &message);
+
std::unique_ptr<UtilityFunction> m_valid_pointer_check;
std::unique_ptr<UtilityFunction> m_objc_object_check;
};
diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h
index 86744b7b9726e..d557a35d0b065 100644
--- a/include/lldb/Expression/IRExecutionUnit.h
+++ b/include/lldb/Expression/IRExecutionUnit.h
@@ -26,8 +26,8 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Expression/IRMemoryMap.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
namespace llvm {
@@ -71,13 +71,19 @@ public:
std::unique_ptr<llvm::Module> &module_ap,
ConstString &name,
const lldb::TargetSP &target_sp,
+ const SymbolContext &sym_ctx,
std::vector<std::string> &cpu_features);
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
~IRExecutionUnit() override;
-
+
+ ConstString GetFunctionName()
+ {
+ return m_name;
+ }
+
llvm::Module *
GetModule()
{
@@ -131,7 +137,83 @@ public:
lldb::ModuleSP
GetJITModule ();
+
+ lldb::addr_t
+ FindSymbol(const ConstString &name);
+ void
+ GetStaticInitializers(std::vector <lldb::addr_t> &static_initializers);
+
+ //----------------------------------------------------------------------
+ /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+ /// @brief Encapsulates a single function that has been generated by the JIT.
+ ///
+ /// Functions that have been generated by the JIT are first resident in the
+ /// local process, and then placed in the target process. JittedFunction
+ /// represents a function possibly resident in both.
+ //----------------------------------------------------------------------
+ struct JittedEntity {
+ ConstString m_name; ///< The function's name
+ lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
+ lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[in] local_addr
+ /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
+ /// it is not present in LLDB's memory.
+ ///
+ /// @param[in] remote_addr
+ /// The address of the function in the target, or LLDB_INVALID_ADDRESS
+ /// if it is not present in the target's memory.
+ //------------------------------------------------------------------
+ JittedEntity (const char *name,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ m_name (name),
+ m_local_addr (local_addr),
+ m_remote_addr (remote_addr)
+ {
+ }
+ };
+
+ struct JittedFunction : JittedEntity
+ {
+ bool m_external;
+ JittedFunction (const char *name,
+ bool external,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ JittedEntity (name, local_addr, remote_addr),
+ m_external(external)
+ {}
+ };
+
+ struct JittedGlobalVariable : JittedEntity
+ {
+ JittedGlobalVariable (const char *name,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ JittedEntity (name, local_addr, remote_addr)
+ {}
+ };
+
+ const std::vector<JittedFunction> &GetJittedFunctions()
+ {
+ return m_jitted_functions;
+ }
+
+ const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables()
+ {
+ return m_jitted_global_variables;
+ }
+
private:
//------------------------------------------------------------------
/// Look up the object in m_address_map that contains a given address,
@@ -201,6 +283,33 @@ private:
DisassembleFunction (Stream &stream,
lldb::ProcessSP &process_sp);
+ struct SearchSpec;
+
+ void
+ CollectCandidateCNames(std::vector<SearchSpec> &C_specs,
+ const ConstString &name);
+
+ void
+ CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs,
+ const std::vector<SearchSpec> &C_specs,
+ const SymbolContext &sc);
+
+ void
+ CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
+ const std::vector<SearchSpec> &C_specs);
+
+ lldb::addr_t
+ FindInSymbols(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
+ lldb::addr_t
+ FindInRuntimes(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
+ lldb::addr_t
+ FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
void
ReportSymbolLookupError(const ConstString &name);
@@ -275,9 +384,6 @@ private:
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
}
- //------------------------------------------------------------------
- /// Passthrough interface stub
- //------------------------------------------------------------------
uint64_t getSymbolAddress(const std::string &Name) override;
void *getPointerToNamedFunction(const std::string &Name,
@@ -288,45 +394,6 @@ private:
IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
};
- //----------------------------------------------------------------------
- /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
- /// @brief Encapsulates a single function that has been generated by the JIT.
- ///
- /// Functions that have been generated by the JIT are first resident in the
- /// local process, and then placed in the target process. JittedFunction
- /// represents a function possibly resident in both.
- //----------------------------------------------------------------------
- struct JittedFunction {
- std::string m_name; ///< The function's name
- lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
- lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] name
- /// The name of the function.
- ///
- /// @param[in] local_addr
- /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
- /// it is not present in LLDB's memory.
- ///
- /// @param[in] remote_addr
- /// The address of the function in the target, or LLDB_INVALID_ADDRESS
- /// if it is not present in the target's memory.
- //------------------------------------------------------------------
- JittedFunction (const char *name,
- lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
- lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
- m_name (name),
- m_local_addr (local_addr),
- m_remote_addr (remote_addr)
- {
- }
- };
-
static const unsigned eSectionIDInvalid = (unsigned)-1;
//----------------------------------------------------------------------
@@ -377,6 +444,9 @@ private:
void dump (Log *log);
};
+ bool
+ CommitOneAllocation (lldb::ProcessSP &process_sp, Error &error, AllocationRecord &record);
+
typedef std::vector<AllocationRecord> RecordVector;
RecordVector m_records;
@@ -385,14 +455,24 @@ private:
std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off
llvm::Module *m_module; ///< Owned by the execution engine
std::vector<std::string> m_cpu_features;
- llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
+ std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
+ std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of all functions that have been JITted into machine code
const ConstString m_name;
+ SymbolContext m_sym_ctx; ///< Used for symbol lookups
std::vector<ConstString> m_failed_lookups;
std::atomic<bool> m_did_jit;
lldb::addr_t m_function_load_addr;
lldb::addr_t m_function_end_load_addr;
+
+ bool m_strip_underscore; ///< True for platforms where global symbols have a _ prefix
+ bool m_reported_allocations; ///< True after allocations have been reported. It is possible that
+ ///< sections will be allocated when this is true, in which case they weren't
+ ///< depended on by any function. (Top-level code defining a variable, but
+ ///< defining no functions using that variable, would do this.) If this
+ ///< is true, any allocations need to be committed immediately -- no
+ ///< opportunity for relocation.
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h
index 4eb81bc68d19d..14c145b91c264 100644
--- a/include/lldb/Expression/IRInterpreter.h
+++ b/include/lldb/Expression/IRInterpreter.h
@@ -50,7 +50,7 @@ public:
Interpret (llvm::Module &module,
llvm::Function &function,
llvm::ArrayRef<lldb::addr_t> args,
- lldb_private::IRMemoryMap &memory_map,
+ lldb_private::IRExecutionUnit &execution_unit,
lldb_private::Error &error,
lldb::addr_t stack_frame_bottom,
lldb::addr_t stack_frame_top,
diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h
index 6fb718a341f7c..36631d25a742d 100644
--- a/include/lldb/Expression/IRMemoryMap.h
+++ b/include/lldb/Expression/IRMemoryMap.h
@@ -129,7 +129,7 @@ private:
typedef std::map<lldb::addr_t, Allocation> AllocationMap;
AllocationMap m_allocations;
- lldb::addr_t FindSpace (size_t size, bool zero_memory = false);
+ lldb::addr_t FindSpace (size_t size);
bool ContainsHostOnlyAllocations ();
AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size);
diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h
index e3d17986f4b38..3762fa11ddbd7 100644
--- a/include/lldb/Expression/LLVMUserExpression.h
+++ b/include/lldb/Expression/LLVMUserExpression.h
@@ -16,6 +16,9 @@
#include <map>
#include <vector>
+// Other libraries and framework includes
+#include "llvm/IR/LegacyPassManager.h"
+
// Project includes
#include "lldb/Expression/UserExpression.h"
@@ -34,26 +37,28 @@ namespace lldb_private
//----------------------------------------------------------------------
class LLVMUserExpression : public UserExpression
{
- public:
- LLVMUserExpression(ExecutionContextScope &exe_scope,
- const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type,
+public:
+ // The IRPasses struct is filled in by a runtime after an expression is compiled and can be used to to run
+ // fixups/analysis passes as required. EarlyPasses are run on the generated module before lldb runs its own IR
+ // fixups and inserts instrumentation code/pointer checks. LatePasses are run after the module has been processed by
+ // llvm, before the module is assembled and run in the ThreadPlan.
+ struct IRPasses
+ {
+ IRPasses() : EarlyPasses(nullptr), LatePasses(nullptr){};
+ std::shared_ptr<llvm::legacy::PassManager> EarlyPasses;
+ std::shared_ptr<llvm::legacy::PassManager> LatePasses;
+ };
+
+ LLVMUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
+ lldb::LanguageType language, ResultType desired_type,
const EvaluateExpressionOptions &options);
~LLVMUserExpression() override;
- lldb::ExpressionResults Execute(Stream &error_stream,
- ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) override;
-
- bool FinalizeJITExecution(Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override;
+ bool
+ FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override;
bool
CanInterpret() override
@@ -73,17 +78,22 @@ class LLVMUserExpression : public UserExpression
lldb::ModuleSP GetJITModule() override;
- protected:
- virtual void ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0;
+protected:
+ lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) override;
- bool PrepareToExecuteJITExpression(Stream &error_stream, ExecutionContext &exe_ctx, lldb::addr_t &struct_address);
+ virtual void
+ ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0;
- virtual bool
- AddArguments (ExecutionContext &exe_ctx,
- std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address,
- Stream &error_stream) = 0;
+ bool
+ PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::addr_t &struct_address);
+ virtual bool
+ AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) = 0;
lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame.
lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.
diff --git a/include/lldb/Expression/UserExpression.h b/include/lldb/Expression/UserExpression.h
index 517dfcd1dc474..2b685dc046c79 100644
--- a/include/lldb/Expression/UserExpression.h
+++ b/include/lldb/Expression/UserExpression.h
@@ -79,8 +79,8 @@ public:
//------------------------------------------------------------------
/// Parse the expression
///
- /// @param[in] error_stream
- /// A stream to print parse errors and warnings to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report parse errors and warnings to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -98,11 +98,8 @@ public:
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
virtual bool
- Parse (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info) = 0;
+ Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) = 0;
virtual bool CanInterpret() = 0;
@@ -110,10 +107,11 @@ public:
MatchesContext (ExecutionContext &exe_ctx);
//------------------------------------------------------------------
- /// Execute the parsed expression
+ /// Execute the parsed expression by callinng the derived class's
+ /// DoExecute method.
///
- /// @param[in] error_stream
- /// A stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -136,16 +134,15 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- virtual lldb::ExpressionResults Execute(Stream &error_stream, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) = 0;
+ lldb::ExpressionResults
+ Execute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result);
//------------------------------------------------------------------
/// Apply the side effects of the function to program state.
///
- /// @param[in] error_stream
- /// A stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -164,10 +161,10 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- virtual bool FinalizeJITExecution(Stream &error_stream, ExecutionContext &exe_ctx,
- lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) = 0;
+ virtual bool
+ FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) = 0;
//------------------------------------------------------------------
/// Return the string that the parser should parse.
@@ -285,6 +282,9 @@ public:
/// @param[in] line_offset
/// The offset of the first line of the expression from the "beginning" of a virtual source file used for error reporting and debug info.
///
+ /// @param[out] fixed_expression
+ /// If non-nullptr, the fixed expression is copied into the provided string.
+ ///
/// @param[out] jit_module_sp_ptr
/// If non-nullptr, used to persist the generated IR module.
///
@@ -299,11 +299,24 @@ public:
lldb::ValueObjectSP &result_valobj_sp,
Error &error,
uint32_t line_offset = 0,
+ std::string *fixed_expression = nullptr,
lldb::ModuleSP *jit_module_sp_ptr = nullptr);
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
+
+ const char *
+ GetFixedText()
+ {
+ if (m_fixed_text.empty())
+ return nullptr;
+ return m_fixed_text.c_str();
+ }
protected:
+ virtual lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result) = 0;
+
static lldb::addr_t
GetObjectPointer (lldb::StackFrameSP frame_sp,
ConstString &object_name,
@@ -325,6 +338,7 @@ protected:
Address m_address; ///< The address the process is stopped in.
std::string m_expr_text; ///< The text of the expression, as typed by the user
std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user
+ std::string m_fixed_text; ///< The text of the expression with fix-its applied - this won't be set if the fixed text doesn't parse.
lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
EvaluateExpressionOptions m_options; ///< Additional options provided by the user.
diff --git a/include/lldb/Expression/UtilityFunction.h b/include/lldb/Expression/UtilityFunction.h
index bee83d8111e41..a78972082c52d 100644
--- a/include/lldb/Expression/UtilityFunction.h
+++ b/include/lldb/Expression/UtilityFunction.h
@@ -54,8 +54,8 @@ public:
//------------------------------------------------------------------
/// Install the utility function into a process
///
- /// @param[in] error_stream
- /// A stream to print parse errors and warnings to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to print parse errors and warnings to.
///
/// @param[in] exe_ctx
/// The execution context to install the utility function to.
@@ -64,8 +64,8 @@ public:
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
virtual bool
- Install (Stream &error_stream, ExecutionContext &exe_ctx) = 0;
-
+ Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) = 0;
+
//------------------------------------------------------------------
/// Check whether the given PC is inside the function
///
@@ -139,8 +139,10 @@ public:
}
// This makes the function caller function.
+ // Pass in the ThreadSP if you have one available, compilation can end up calling code (e.g. to look up indirect
+ // functions) and we don't want this to wander onto another thread.
FunctionCaller *
- MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error);
+ MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP compilation_thread, Error &error);
// This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr
FunctionCaller *