1 //===-- IRDynamicChecks.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Constants.h"
10 #include "llvm/IR/DataLayout.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/IR/Value.h"
15 #include "llvm/Support/raw_ostream.h"
17 #include "IRDynamicChecks.h"
19 #include "lldb/Expression/UtilityFunction.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/ConstString.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/Utility/Log.h"
28 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
31 using namespace lldb_private
;
35 #define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check"
36 #define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
38 static const char g_valid_pointer_check_text
[] =
40 "_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
42 " unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
45 ClangDynamicCheckerFunctions::ClangDynamicCheckerFunctions()
46 : DynamicCheckerFunctions(DCF_Clang
) {}
48 ClangDynamicCheckerFunctions::~ClangDynamicCheckerFunctions() = default;
50 llvm::Error
ClangDynamicCheckerFunctions::Install(
51 DiagnosticManager
&diagnostic_manager
, ExecutionContext
&exe_ctx
) {
52 Expected
<std::unique_ptr
<UtilityFunction
>> utility_fn
=
53 exe_ctx
.GetTargetRef().CreateUtilityFunction(
54 g_valid_pointer_check_text
, VALID_POINTER_CHECK_NAME
,
55 lldb::eLanguageTypeC
, exe_ctx
);
57 return utility_fn
.takeError();
58 m_valid_pointer_check
= std::move(*utility_fn
);
60 if (Process
*process
= exe_ctx
.GetProcessPtr()) {
61 ObjCLanguageRuntime
*objc_language_runtime
=
62 ObjCLanguageRuntime::Get(*process
);
64 if (objc_language_runtime
) {
65 Expected
<std::unique_ptr
<UtilityFunction
>> checker_fn
=
66 objc_language_runtime
->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME
, exe_ctx
);
68 return checker_fn
.takeError();
69 m_objc_object_check
= std::move(*checker_fn
);
73 return Error::success();
76 bool ClangDynamicCheckerFunctions::DoCheckersExplainStop(lldb::addr_t addr
,
78 // FIXME: We have to get the checkers to know why they scotched the call in
80 // so we can print a better message here.
81 if (m_valid_pointer_check
&& m_valid_pointer_check
->ContainsAddress(addr
)) {
82 message
.Printf("Attempted to dereference an invalid pointer.");
84 } else if (m_objc_object_check
&&
85 m_objc_object_check
->ContainsAddress(addr
)) {
86 message
.Printf("Attempted to dereference an invalid ObjC Object or send it "
87 "an unrecognized selector");
93 static std::string
PrintValue(llvm::Value
*V
, bool truncate
= false) {
95 raw_string_ostream
rso(s
);
99 s
.resize(s
.length() - 1);
103 /// \class Instrumenter IRDynamicChecks.cpp
104 /// Finds and instruments individual LLVM IR instructions
106 /// When instrumenting LLVM IR, it is frequently desirable to first search for
107 /// instructions, and then later modify them. This way iterators remain
108 /// intact, and multiple passes can look at the same code base without
109 /// treading on each other's toes.
111 /// The Instrumenter class implements this functionality. A client first
112 /// calls Inspect on a function, which populates a list of instructions to be
113 /// instrumented. Then, later, when all passes' Inspect functions have been
114 /// called, the client calls Instrument, which adds the desired
117 /// A subclass of Instrumenter must override InstrumentInstruction, which
118 /// is responsible for adding whatever instrumentation is necessary.
120 /// A subclass of Instrumenter may override:
122 /// - InspectInstruction [default: does nothing]
124 /// - InspectBasicBlock [default: iterates through the instructions in a
125 /// basic block calling InspectInstruction]
127 /// - InspectFunction [default: iterates through the basic blocks in a
128 /// function calling InspectBasicBlock]
133 /// \param[in] module
134 /// The module being instrumented.
135 Instrumenter(llvm::Module
&module
,
136 std::shared_ptr
<UtilityFunction
> checker_function
)
137 : m_module(module
), m_checker_function(checker_function
) {}
139 virtual ~Instrumenter() = default;
141 /// Inspect a function to find instructions to instrument
143 /// \param[in] function
144 /// The function to inspect.
147 /// True on success; false on error.
148 bool Inspect(llvm::Function
&function
) { return InspectFunction(function
); }
150 /// Instrument all the instructions found by Inspect()
153 /// True on success; false on error.
155 for (InstIterator ii
= m_to_instrument
.begin(),
156 last_ii
= m_to_instrument
.end();
157 ii
!= last_ii
; ++ii
) {
158 if (!InstrumentInstruction(*ii
))
166 /// Add instrumentation to a single instruction
169 /// The instruction to be instrumented.
172 /// True on success; false otherwise.
173 virtual bool InstrumentInstruction(llvm::Instruction
*inst
) = 0;
175 /// Register a single instruction to be instrumented
178 /// The instruction to be instrumented.
179 void RegisterInstruction(llvm::Instruction
&inst
) {
180 m_to_instrument
.push_back(&inst
);
183 /// Determine whether a single instruction is interesting to instrument,
184 /// and, if so, call RegisterInstruction
187 /// The instruction to be inspected.
190 /// False if there was an error scanning; true otherwise.
191 virtual bool InspectInstruction(llvm::Instruction
&i
) { return true; }
193 /// Scan a basic block to see if any instructions are interesting
196 /// The basic block to be inspected.
199 /// False if there was an error scanning; true otherwise.
200 virtual bool InspectBasicBlock(llvm::BasicBlock
&bb
) {
201 for (llvm::BasicBlock::iterator ii
= bb
.begin(), last_ii
= bb
.end();
202 ii
!= last_ii
; ++ii
) {
203 if (!InspectInstruction(*ii
))
210 /// Scan a function to see if any instructions are interesting
213 /// The function to be inspected.
216 /// False if there was an error scanning; true otherwise.
217 virtual bool InspectFunction(llvm::Function
&f
) {
218 for (llvm::Function::iterator bbi
= f
.begin(), last_bbi
= f
.end();
219 bbi
!= last_bbi
; ++bbi
) {
220 if (!InspectBasicBlock(*bbi
))
227 /// Build a function pointer for a function with signature void
228 /// (*)(uint8_t*) with a given address
230 /// \param[in] start_address
231 /// The address of the function.
234 /// The function pointer, for use in a CallInst.
235 llvm::FunctionCallee
BuildPointerValidatorFunc(lldb::addr_t start_address
) {
236 llvm::Type
*param_array
[1];
238 param_array
[0] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
240 ArrayRef
<llvm::Type
*> params(param_array
, 1);
242 FunctionType
*fun_ty
= FunctionType::get(
243 llvm::Type::getVoidTy(m_module
.getContext()), params
, true);
244 PointerType
*fun_ptr_ty
= PointerType::getUnqual(fun_ty
);
245 Constant
*fun_addr_int
=
246 ConstantInt::get(GetIntptrTy(), start_address
, false);
247 return {fun_ty
, ConstantExpr::getIntToPtr(fun_addr_int
, fun_ptr_ty
)};
250 /// Build a function pointer for a function with signature void
251 /// (*)(uint8_t*, uint8_t*) with a given address
253 /// \param[in] start_address
254 /// The address of the function.
257 /// The function pointer, for use in a CallInst.
258 llvm::FunctionCallee
BuildObjectCheckerFunc(lldb::addr_t start_address
) {
259 llvm::Type
*param_array
[2];
261 param_array
[0] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
262 param_array
[1] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
264 ArrayRef
<llvm::Type
*> params(param_array
, 2);
266 FunctionType
*fun_ty
= FunctionType::get(
267 llvm::Type::getVoidTy(m_module
.getContext()), params
, true);
268 PointerType
*fun_ptr_ty
= PointerType::getUnqual(fun_ty
);
269 Constant
*fun_addr_int
=
270 ConstantInt::get(GetIntptrTy(), start_address
, false);
271 return {fun_ty
, ConstantExpr::getIntToPtr(fun_addr_int
, fun_ptr_ty
)};
274 PointerType
*GetI8PtrTy() {
276 m_i8ptr_ty
= llvm::Type::getInt8PtrTy(m_module
.getContext());
281 IntegerType
*GetIntptrTy() {
283 llvm::DataLayout
data_layout(&m_module
);
285 m_intptr_ty
= llvm::Type::getIntNTy(m_module
.getContext(),
286 data_layout
.getPointerSizeInBits());
292 typedef std::vector
<llvm::Instruction
*> InstVector
;
293 typedef InstVector::iterator InstIterator
;
295 InstVector m_to_instrument
; ///< List of instructions the inspector found
296 llvm::Module
&m_module
; ///< The module which is being instrumented
297 std::shared_ptr
<UtilityFunction
>
298 m_checker_function
; ///< The dynamic checker function for the process
301 PointerType
*m_i8ptr_ty
= nullptr;
302 IntegerType
*m_intptr_ty
= nullptr;
305 class ValidPointerChecker
: public Instrumenter
{
307 ValidPointerChecker(llvm::Module
&module
,
308 std::shared_ptr
<UtilityFunction
> checker_function
)
309 : Instrumenter(module
, checker_function
),
310 m_valid_pointer_check_func(nullptr) {}
312 ~ValidPointerChecker() override
= default;
315 bool InstrumentInstruction(llvm::Instruction
*inst
) override
{
316 Log
*log
= GetLog(LLDBLog::Expressions
);
318 LLDB_LOGF(log
, "Instrumenting load/store instruction: %s\n",
319 PrintValue(inst
).c_str());
321 if (!m_valid_pointer_check_func
)
322 m_valid_pointer_check_func
=
323 BuildPointerValidatorFunc(m_checker_function
->StartAddress());
325 llvm::Value
*dereferenced_ptr
= nullptr;
327 if (llvm::LoadInst
*li
= dyn_cast
<llvm::LoadInst
>(inst
))
328 dereferenced_ptr
= li
->getPointerOperand();
329 else if (llvm::StoreInst
*si
= dyn_cast
<llvm::StoreInst
>(inst
))
330 dereferenced_ptr
= si
->getPointerOperand();
334 // Insert an instruction to call the helper with the result
335 CallInst::Create(m_valid_pointer_check_func
, dereferenced_ptr
, "", inst
);
340 bool InspectInstruction(llvm::Instruction
&i
) override
{
341 if (isa
<llvm::LoadInst
>(&i
) || isa
<llvm::StoreInst
>(&i
))
342 RegisterInstruction(i
);
348 llvm::FunctionCallee m_valid_pointer_check_func
;
351 class ObjcObjectChecker
: public Instrumenter
{
353 ObjcObjectChecker(llvm::Module
&module
,
354 std::shared_ptr
<UtilityFunction
> checker_function
)
355 : Instrumenter(module
, checker_function
),
356 m_objc_object_check_func(nullptr) {}
358 ~ObjcObjectChecker() override
= default;
368 std::map
<llvm::Instruction
*, msgSend_type
> msgSend_types
;
371 bool InstrumentInstruction(llvm::Instruction
*inst
) override
{
372 CallInst
*call_inst
= dyn_cast
<CallInst
>(inst
);
375 return false; // call_inst really shouldn't be nullptr, because otherwise
376 // InspectInstruction wouldn't have registered it
378 if (!m_objc_object_check_func
)
379 m_objc_object_check_func
=
380 BuildObjectCheckerFunc(m_checker_function
->StartAddress());
382 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
384 llvm::Value
*target_object
;
385 llvm::Value
*selector
;
387 switch (msgSend_types
[inst
]) {
390 // On arm64, clang uses objc_msgSend for scalar and struct return
391 // calls. The call instruction will record which was used.
392 if (call_inst
->hasStructRetAttr()) {
393 target_object
= call_inst
->getArgOperand(1);
394 selector
= call_inst
->getArgOperand(2);
396 target_object
= call_inst
->getArgOperand(0);
397 selector
= call_inst
->getArgOperand(1);
401 target_object
= call_inst
->getArgOperand(1);
402 selector
= call_inst
->getArgOperand(2);
405 case eMsgSendSuper_stret
:
409 // These objects should always be valid according to Sean Calannan
410 assert(target_object
);
413 // Insert an instruction to call the helper with the result
415 llvm::Value
*arg_array
[2];
417 arg_array
[0] = target_object
;
418 arg_array
[1] = selector
;
420 ArrayRef
<llvm::Value
*> args(arg_array
, 2);
422 CallInst::Create(m_objc_object_check_func
, args
, "", inst
);
427 static llvm::Function
*GetFunction(llvm::Value
*value
) {
428 if (llvm::Function
*function
= llvm::dyn_cast
<llvm::Function
>(value
)) {
432 if (llvm::ConstantExpr
*const_expr
=
433 llvm::dyn_cast
<llvm::ConstantExpr
>(value
)) {
434 switch (const_expr
->getOpcode()) {
437 case llvm::Instruction::BitCast
:
438 return GetFunction(const_expr
->getOperand(0));
445 static llvm::Function
*GetCalledFunction(llvm::CallInst
*inst
) {
446 return GetFunction(inst
->getCalledOperand());
449 bool InspectInstruction(llvm::Instruction
&i
) override
{
450 Log
*log
= GetLog(LLDBLog::Expressions
);
452 CallInst
*call_inst
= dyn_cast
<CallInst
>(&i
);
455 const llvm::Function
*called_function
= GetCalledFunction(call_inst
);
457 if (!called_function
)
460 std::string name_str
= called_function
->getName().str();
461 const char *name_cstr
= name_str
.c_str();
463 LLDB_LOGF(log
, "Found call to %s: %s\n", name_cstr
,
464 PrintValue(call_inst
).c_str());
466 if (name_str
.find("objc_msgSend") == std::string::npos
)
469 if (!strcmp(name_cstr
, "objc_msgSend")) {
470 RegisterInstruction(i
);
471 msgSend_types
[&i
] = eMsgSend
;
475 if (!strcmp(name_cstr
, "objc_msgSend_stret")) {
476 RegisterInstruction(i
);
477 msgSend_types
[&i
] = eMsgSend_stret
;
481 if (!strcmp(name_cstr
, "objc_msgSend_fpret")) {
482 RegisterInstruction(i
);
483 msgSend_types
[&i
] = eMsgSend_fpret
;
487 if (!strcmp(name_cstr
, "objc_msgSendSuper")) {
488 RegisterInstruction(i
);
489 msgSend_types
[&i
] = eMsgSendSuper
;
493 if (!strcmp(name_cstr
, "objc_msgSendSuper_stret")) {
494 RegisterInstruction(i
);
495 msgSend_types
[&i
] = eMsgSendSuper_stret
;
500 "Function name '%s' contains 'objc_msgSend' but is not handled",
510 llvm::FunctionCallee m_objc_object_check_func
;
513 IRDynamicChecks::IRDynamicChecks(
514 ClangDynamicCheckerFunctions
&checker_functions
, const char *func_name
)
515 : ModulePass(ID
), m_func_name(func_name
),
516 m_checker_functions(checker_functions
) {}
518 IRDynamicChecks::~IRDynamicChecks() = default;
520 bool IRDynamicChecks::runOnModule(llvm::Module
&M
) {
521 Log
*log
= GetLog(LLDBLog::Expressions
);
523 llvm::Function
*function
= M
.getFunction(StringRef(m_func_name
));
526 LLDB_LOGF(log
, "Couldn't find %s() in the module", m_func_name
.c_str());
531 if (m_checker_functions
.m_valid_pointer_check
) {
532 ValidPointerChecker
vpc(M
, m_checker_functions
.m_valid_pointer_check
);
534 if (!vpc
.Inspect(*function
))
537 if (!vpc
.Instrument())
541 if (m_checker_functions
.m_objc_object_check
) {
542 ObjcObjectChecker
ooc(M
, m_checker_functions
.m_objc_object_check
);
544 if (!ooc
.Inspect(*function
))
547 if (!ooc
.Instrument())
551 if (log
&& log
->GetVerbose()) {
553 raw_string_ostream
oss(s
);
555 M
.print(oss
, nullptr);
559 LLDB_LOGF(log
, "Module after dynamic checks: \n%s", s
.c_str());
565 void IRDynamicChecks::assignPassManager(PMStack
&PMS
, PassManagerType T
) {}
567 PassManagerType
IRDynamicChecks::getPotentialPassManagerType() const {
568 return PMT_ModulePassManager
;