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
);
98 s
.resize(s
.length() - 1);
102 /// \class Instrumenter IRDynamicChecks.cpp
103 /// Finds and instruments individual LLVM IR instructions
105 /// When instrumenting LLVM IR, it is frequently desirable to first search for
106 /// instructions, and then later modify them. This way iterators remain
107 /// intact, and multiple passes can look at the same code base without
108 /// treading on each other's toes.
110 /// The Instrumenter class implements this functionality. A client first
111 /// calls Inspect on a function, which populates a list of instructions to be
112 /// instrumented. Then, later, when all passes' Inspect functions have been
113 /// called, the client calls Instrument, which adds the desired
116 /// A subclass of Instrumenter must override InstrumentInstruction, which
117 /// is responsible for adding whatever instrumentation is necessary.
119 /// A subclass of Instrumenter may override:
121 /// - InspectInstruction [default: does nothing]
123 /// - InspectBasicBlock [default: iterates through the instructions in a
124 /// basic block calling InspectInstruction]
126 /// - InspectFunction [default: iterates through the basic blocks in a
127 /// function calling InspectBasicBlock]
132 /// \param[in] module
133 /// The module being instrumented.
134 Instrumenter(llvm::Module
&module
,
135 std::shared_ptr
<UtilityFunction
> checker_function
)
136 : m_module(module
), m_checker_function(checker_function
) {}
138 virtual ~Instrumenter() = default;
140 /// Inspect a function to find instructions to instrument
142 /// \param[in] function
143 /// The function to inspect.
146 /// True on success; false on error.
147 bool Inspect(llvm::Function
&function
) { return InspectFunction(function
); }
149 /// Instrument all the instructions found by Inspect()
152 /// True on success; false on error.
154 for (InstIterator ii
= m_to_instrument
.begin(),
155 last_ii
= m_to_instrument
.end();
156 ii
!= last_ii
; ++ii
) {
157 if (!InstrumentInstruction(*ii
))
165 /// Add instrumentation to a single instruction
168 /// The instruction to be instrumented.
171 /// True on success; false otherwise.
172 virtual bool InstrumentInstruction(llvm::Instruction
*inst
) = 0;
174 /// Register a single instruction to be instrumented
177 /// The instruction to be instrumented.
178 void RegisterInstruction(llvm::Instruction
&inst
) {
179 m_to_instrument
.push_back(&inst
);
182 /// Determine whether a single instruction is interesting to instrument,
183 /// and, if so, call RegisterInstruction
186 /// The instruction to be inspected.
189 /// False if there was an error scanning; true otherwise.
190 virtual bool InspectInstruction(llvm::Instruction
&i
) { return true; }
192 /// Scan a basic block to see if any instructions are interesting
195 /// The basic block to be inspected.
198 /// False if there was an error scanning; true otherwise.
199 virtual bool InspectBasicBlock(llvm::BasicBlock
&bb
) {
200 for (llvm::BasicBlock::iterator ii
= bb
.begin(), last_ii
= bb
.end();
201 ii
!= last_ii
; ++ii
) {
202 if (!InspectInstruction(*ii
))
209 /// Scan a function to see if any instructions are interesting
212 /// The function to be inspected.
215 /// False if there was an error scanning; true otherwise.
216 virtual bool InspectFunction(llvm::Function
&f
) {
217 for (llvm::Function::iterator bbi
= f
.begin(), last_bbi
= f
.end();
218 bbi
!= last_bbi
; ++bbi
) {
219 if (!InspectBasicBlock(*bbi
))
226 /// Build a function pointer for a function with signature void
227 /// (*)(uint8_t*) with a given address
229 /// \param[in] start_address
230 /// The address of the function.
233 /// The function pointer, for use in a CallInst.
234 llvm::FunctionCallee
BuildPointerValidatorFunc(lldb::addr_t start_address
) {
235 llvm::Type
*param_array
[1];
237 param_array
[0] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
239 ArrayRef
<llvm::Type
*> params(param_array
, 1);
241 FunctionType
*fun_ty
= FunctionType::get(
242 llvm::Type::getVoidTy(m_module
.getContext()), params
, true);
243 PointerType
*fun_ptr_ty
= PointerType::getUnqual(fun_ty
);
244 Constant
*fun_addr_int
=
245 ConstantInt::get(GetIntptrTy(), start_address
, false);
246 return {fun_ty
, ConstantExpr::getIntToPtr(fun_addr_int
, fun_ptr_ty
)};
249 /// Build a function pointer for a function with signature void
250 /// (*)(uint8_t*, uint8_t*) with a given address
252 /// \param[in] start_address
253 /// The address of the function.
256 /// The function pointer, for use in a CallInst.
257 llvm::FunctionCallee
BuildObjectCheckerFunc(lldb::addr_t start_address
) {
258 llvm::Type
*param_array
[2];
260 param_array
[0] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
261 param_array
[1] = const_cast<llvm::PointerType
*>(GetI8PtrTy());
263 ArrayRef
<llvm::Type
*> params(param_array
, 2);
265 FunctionType
*fun_ty
= FunctionType::get(
266 llvm::Type::getVoidTy(m_module
.getContext()), params
, true);
267 PointerType
*fun_ptr_ty
= PointerType::getUnqual(fun_ty
);
268 Constant
*fun_addr_int
=
269 ConstantInt::get(GetIntptrTy(), start_address
, false);
270 return {fun_ty
, ConstantExpr::getIntToPtr(fun_addr_int
, fun_ptr_ty
)};
273 PointerType
*GetI8PtrTy() {
275 m_i8ptr_ty
= llvm::PointerType::getUnqual(m_module
.getContext());
280 IntegerType
*GetIntptrTy() {
282 m_intptr_ty
= llvm::Type::getIntNTy(
283 m_module
.getContext(),
284 m_module
.getDataLayout().getPointerSizeInBits());
290 typedef std::vector
<llvm::Instruction
*> InstVector
;
291 typedef InstVector::iterator InstIterator
;
293 InstVector m_to_instrument
; ///< List of instructions the inspector found
294 llvm::Module
&m_module
; ///< The module which is being instrumented
295 std::shared_ptr
<UtilityFunction
>
296 m_checker_function
; ///< The dynamic checker function for the process
299 PointerType
*m_i8ptr_ty
= nullptr;
300 IntegerType
*m_intptr_ty
= nullptr;
303 class ValidPointerChecker
: public Instrumenter
{
305 ValidPointerChecker(llvm::Module
&module
,
306 std::shared_ptr
<UtilityFunction
> checker_function
)
307 : Instrumenter(module
, checker_function
),
308 m_valid_pointer_check_func(nullptr) {}
310 ~ValidPointerChecker() override
= default;
313 bool InstrumentInstruction(llvm::Instruction
*inst
) override
{
314 Log
*log
= GetLog(LLDBLog::Expressions
);
316 LLDB_LOGF(log
, "Instrumenting load/store instruction: %s\n",
317 PrintValue(inst
).c_str());
319 if (!m_valid_pointer_check_func
)
320 m_valid_pointer_check_func
=
321 BuildPointerValidatorFunc(m_checker_function
->StartAddress());
323 llvm::Value
*dereferenced_ptr
= nullptr;
325 if (llvm::LoadInst
*li
= dyn_cast
<llvm::LoadInst
>(inst
))
326 dereferenced_ptr
= li
->getPointerOperand();
327 else if (llvm::StoreInst
*si
= dyn_cast
<llvm::StoreInst
>(inst
))
328 dereferenced_ptr
= si
->getPointerOperand();
332 // Insert an instruction to call the helper with the result
333 CallInst::Create(m_valid_pointer_check_func
, dereferenced_ptr
, "",
334 inst
->getIterator());
339 bool InspectInstruction(llvm::Instruction
&i
) override
{
340 if (isa
<llvm::LoadInst
>(&i
) || isa
<llvm::StoreInst
>(&i
))
341 RegisterInstruction(i
);
347 llvm::FunctionCallee m_valid_pointer_check_func
;
350 class ObjcObjectChecker
: public Instrumenter
{
352 ObjcObjectChecker(llvm::Module
&module
,
353 std::shared_ptr
<UtilityFunction
> checker_function
)
354 : Instrumenter(module
, checker_function
),
355 m_objc_object_check_func(nullptr) {}
357 ~ObjcObjectChecker() override
= default;
367 std::map
<llvm::Instruction
*, msgSend_type
> msgSend_types
;
370 bool InstrumentInstruction(llvm::Instruction
*inst
) override
{
371 CallInst
*call_inst
= dyn_cast
<CallInst
>(inst
);
374 return false; // call_inst really shouldn't be nullptr, because otherwise
375 // InspectInstruction wouldn't have registered it
377 if (!m_objc_object_check_func
)
378 m_objc_object_check_func
=
379 BuildObjectCheckerFunc(m_checker_function
->StartAddress());
381 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
383 llvm::Value
*target_object
;
384 llvm::Value
*selector
;
386 switch (msgSend_types
[inst
]) {
389 // On arm64, clang uses objc_msgSend for scalar and struct return
390 // calls. The call instruction will record which was used.
391 if (call_inst
->hasStructRetAttr()) {
392 target_object
= call_inst
->getArgOperand(1);
393 selector
= call_inst
->getArgOperand(2);
395 target_object
= call_inst
->getArgOperand(0);
396 selector
= call_inst
->getArgOperand(1);
400 target_object
= call_inst
->getArgOperand(1);
401 selector
= call_inst
->getArgOperand(2);
404 case eMsgSendSuper_stret
:
408 // These objects should always be valid according to Sean Calannan
409 assert(target_object
);
412 // Insert an instruction to call the helper with the result
414 llvm::Value
*arg_array
[2];
416 arg_array
[0] = target_object
;
417 arg_array
[1] = selector
;
419 ArrayRef
<llvm::Value
*> args(arg_array
, 2);
421 CallInst::Create(m_objc_object_check_func
, args
, "", inst
->getIterator());
426 static llvm::Function
*GetFunction(llvm::Value
*value
) {
427 if (llvm::Function
*function
= llvm::dyn_cast
<llvm::Function
>(value
)) {
431 if (llvm::ConstantExpr
*const_expr
=
432 llvm::dyn_cast
<llvm::ConstantExpr
>(value
)) {
433 switch (const_expr
->getOpcode()) {
436 case llvm::Instruction::BitCast
:
437 return GetFunction(const_expr
->getOperand(0));
444 static llvm::Function
*GetCalledFunction(llvm::CallInst
*inst
) {
445 return GetFunction(inst
->getCalledOperand());
448 bool InspectInstruction(llvm::Instruction
&i
) override
{
449 Log
*log
= GetLog(LLDBLog::Expressions
);
451 CallInst
*call_inst
= dyn_cast
<CallInst
>(&i
);
454 const llvm::Function
*called_function
= GetCalledFunction(call_inst
);
456 if (!called_function
)
459 std::string name_str
= called_function
->getName().str();
460 const char *name_cstr
= name_str
.c_str();
462 LLDB_LOGF(log
, "Found call to %s: %s\n", name_cstr
,
463 PrintValue(call_inst
).c_str());
465 if (name_str
.find("objc_msgSend") == std::string::npos
)
468 if (!strcmp(name_cstr
, "objc_msgSend")) {
469 RegisterInstruction(i
);
470 msgSend_types
[&i
] = eMsgSend
;
474 if (!strcmp(name_cstr
, "objc_msgSend_stret")) {
475 RegisterInstruction(i
);
476 msgSend_types
[&i
] = eMsgSend_stret
;
480 if (!strcmp(name_cstr
, "objc_msgSend_fpret")) {
481 RegisterInstruction(i
);
482 msgSend_types
[&i
] = eMsgSend_fpret
;
486 if (!strcmp(name_cstr
, "objc_msgSendSuper")) {
487 RegisterInstruction(i
);
488 msgSend_types
[&i
] = eMsgSendSuper
;
492 if (!strcmp(name_cstr
, "objc_msgSendSuper_stret")) {
493 RegisterInstruction(i
);
494 msgSend_types
[&i
] = eMsgSendSuper_stret
;
499 "Function name '%s' contains 'objc_msgSend' but is not handled",
509 llvm::FunctionCallee m_objc_object_check_func
;
512 IRDynamicChecks::IRDynamicChecks(
513 ClangDynamicCheckerFunctions
&checker_functions
, const char *func_name
)
514 : ModulePass(ID
), m_func_name(func_name
),
515 m_checker_functions(checker_functions
) {}
517 IRDynamicChecks::~IRDynamicChecks() = default;
519 bool IRDynamicChecks::runOnModule(llvm::Module
&M
) {
520 Log
*log
= GetLog(LLDBLog::Expressions
);
522 llvm::Function
*function
= M
.getFunction(StringRef(m_func_name
));
525 LLDB_LOGF(log
, "Couldn't find %s() in the module", m_func_name
.c_str());
530 if (m_checker_functions
.m_valid_pointer_check
) {
531 ValidPointerChecker
vpc(M
, m_checker_functions
.m_valid_pointer_check
);
533 if (!vpc
.Inspect(*function
))
536 if (!vpc
.Instrument())
540 if (m_checker_functions
.m_objc_object_check
) {
541 ObjcObjectChecker
ooc(M
, m_checker_functions
.m_objc_object_check
);
543 if (!ooc
.Inspect(*function
))
546 if (!ooc
.Instrument())
550 if (log
&& log
->GetVerbose()) {
552 raw_string_ostream
oss(s
);
554 M
.print(oss
, nullptr);
556 LLDB_LOGF(log
, "Module after dynamic checks: \n%s", s
.c_str());
562 void IRDynamicChecks::assignPassManager(PMStack
&PMS
, PassManagerType T
) {}
564 PassManagerType
IRDynamicChecks::getPotentialPassManagerType() const {
565 return PMT_ModulePassManager
;