1351290Sdim//===-- IRDynamicChecks.h ---------------------------------------*- C++ -*-===//
2351290Sdim//
3351290Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4351290Sdim// See https://llvm.org/LICENSE.txt for license information.
5351290Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6351290Sdim//
7351290Sdim//===----------------------------------------------------------------------===//
8351290Sdim
9351290Sdim#ifndef liblldb_IRDynamicChecks_h_
10351290Sdim#define liblldb_IRDynamicChecks_h_
11351290Sdim
12351290Sdim#include "lldb/Expression/DynamicCheckerFunctions.h"
13351290Sdim#include "lldb/lldb-types.h"
14351290Sdim#include "llvm/Pass.h"
15351290Sdim
16351290Sdimnamespace llvm {
17351290Sdimclass BasicBlock;
18351290Sdimclass Module;
19351290Sdim}
20351290Sdim
21351290Sdimnamespace lldb_private {
22351290Sdim
23351290Sdimclass ExecutionContext;
24351290Sdimclass Stream;
25351290Sdim
26351290Sdimclass ClangDynamicCheckerFunctions
27351290Sdim    : public lldb_private::DynamicCheckerFunctions {
28351290Sdimpublic:
29351290Sdim  /// Constructor
30351290Sdim  ClangDynamicCheckerFunctions();
31351290Sdim
32351290Sdim  /// Destructor
33351290Sdim  virtual ~ClangDynamicCheckerFunctions();
34351290Sdim
35351290Sdim  static bool classof(const DynamicCheckerFunctions *checker_funcs) {
36351290Sdim    return checker_funcs->GetKind() == DCF_Clang;
37351290Sdim  }
38351290Sdim
39351290Sdim  /// Install the utility functions into a process.  This binds the instance
40351290Sdim  /// of DynamicCheckerFunctions to that process.
41351290Sdim  ///
42351290Sdim  /// \param[in] diagnostic_manager
43351290Sdim  ///     A diagnostic manager to report errors to.
44351290Sdim  ///
45351290Sdim  /// \param[in] exe_ctx
46351290Sdim  ///     The execution context to install the functions into.
47351290Sdim  ///
48351290Sdim  /// \return
49351290Sdim  ///     True on success; false on failure, or if the functions have
50351290Sdim  ///     already been installed.
51351290Sdim  bool Install(DiagnosticManager &diagnostic_manager,
52351290Sdim               ExecutionContext &exe_ctx) override;
53351290Sdim
54351290Sdim  bool DoCheckersExplainStop(lldb::addr_t addr, Stream &message) override;
55351290Sdim
56351290Sdim  std::shared_ptr<UtilityFunction> m_valid_pointer_check;
57351290Sdim  std::shared_ptr<UtilityFunction> m_objc_object_check;
58351290Sdim};
59351290Sdim
60351290Sdim/// \class IRDynamicChecks IRDynamicChecks.h
61351290Sdim/// "lldb/Expression/IRDynamicChecks.h" Adds dynamic checks to a user-entered
62351290Sdim/// expression to reduce its likelihood of crashing
63351290Sdim///
64351290Sdim/// When an IR function is executed in the target process, it may cause
65351290Sdim/// crashes or hangs by dereferencing NULL pointers, trying to call
66351290Sdim/// Objective-C methods on objects that do not respond to them, and so forth.
67351290Sdim///
68351290Sdim/// IRDynamicChecks adds calls to the functions in DynamicCheckerFunctions to
69351290Sdim/// appropriate locations in an expression's IR.
70351290Sdimclass IRDynamicChecks : public llvm::ModulePass {
71351290Sdimpublic:
72351290Sdim  /// Constructor
73351290Sdim  ///
74351290Sdim  /// \param[in] checker_functions
75351290Sdim  ///     The checker functions for the target process.
76351290Sdim  ///
77351290Sdim  /// \param[in] func_name
78351290Sdim  ///     The name of the function to prepare for execution in the target.
79351290Sdim  IRDynamicChecks(ClangDynamicCheckerFunctions &checker_functions,
80351290Sdim                  const char *func_name = "$__lldb_expr");
81351290Sdim
82351290Sdim  /// Destructor
83351290Sdim  ~IRDynamicChecks() override;
84351290Sdim
85351290Sdim  /// Run this IR transformer on a single module
86351290Sdim  ///
87351290Sdim  /// \param[in] M
88351290Sdim  ///     The module to run on.  This module is searched for the function
89351290Sdim  ///     $__lldb_expr, and that function is passed to the passes one by
90351290Sdim  ///     one.
91351290Sdim  ///
92351290Sdim  /// \return
93351290Sdim  ///     True on success; false otherwise
94351290Sdim  bool runOnModule(llvm::Module &M) override;
95351290Sdim
96351290Sdim  /// Interface stub
97351290Sdim  void assignPassManager(
98351290Sdim      llvm::PMStack &PMS,
99351290Sdim      llvm::PassManagerType T = llvm::PMT_ModulePassManager) override;
100351290Sdim
101351290Sdim  /// Returns PMT_ModulePassManager
102351290Sdim  llvm::PassManagerType getPotentialPassManagerType() const override;
103351290Sdim
104351290Sdimprivate:
105351290Sdim  /// A basic block-level pass to find all pointer dereferences and
106351290Sdim  /// validate them before use.
107351290Sdim
108351290Sdim  /// The top-level pass implementation
109351290Sdim  ///
110351290Sdim  /// \param[in] M
111351290Sdim  ///     The module currently being processed.
112351290Sdim  ///
113351290Sdim  /// \param[in] BB
114351290Sdim  ///     The basic block currently being processed.
115351290Sdim  ///
116351290Sdim  /// \return
117351290Sdim  ///     True on success; false otherwise
118351290Sdim  bool FindDataLoads(llvm::Module &M, llvm::BasicBlock &BB);
119351290Sdim
120351290Sdim  std::string m_func_name; ///< The name of the function to add checks to
121351290Sdim  ClangDynamicCheckerFunctions
122351290Sdim      &m_checker_functions; ///< The checker functions for the process
123351290Sdim};
124351290Sdim
125351290Sdim} // namespace lldb_private
126351290Sdim
127351290Sdim#endif // liblldb_IRDynamicChecks_h_
128