From 8f713c17ca74b4615fe49e081565aec526a478fa Mon Sep 17 00:00:00 2001 From: Yu Hao Date: Wed, 5 Jul 2023 20:51:40 -0700 Subject: [PATCH] format the code and fix some minor bugs --- .../{knowledge.json => knowledge-v5.12.json} | 0 lib/AnalysisLib/T_function.cpp | 838 +++--- lib/AnalysisLib/T_function.h | 147 +- lib/AnalysisLib/T_module.cpp | 1638 ++++++------ lib/AnalysisLib/T_module.h | 174 +- lib/AnalysisLib/entry_function.cpp | 294 +-- lib/AnalysisLib/entry_function.h | 104 +- lib/AnalysisLib/ioctl_cmd_type.cpp | 1301 +++++----- lib/AnalysisLib/ioctl_cmd_type.h | 120 +- lib/KnowledgeLib/checker.cpp | 837 +++--- lib/KnowledgeLib/checker.h | 265 +- lib/KnowledgeLib/device_driver.cpp | 372 ++- lib/KnowledgeLib/device_driver.h | 124 +- lib/KnowledgeLib/knowledge.cpp | 953 +++---- lib/KnowledgeLib/knowledge.h | 258 +- lib/KnowledgeLib/syzlang.cpp | 882 +++---- lib/KnowledgeLib/syzlang.h | 107 +- lib/KnowledgeLib/task.cpp | 90 +- lib/KnowledgeLib/task.h | 39 +- lib/MLTA/CallGraph.cc | 27 +- lib/MLTA/TypeInitializer.cc | 2 +- lib/ManagerLib/Manager.cpp | 2258 +++++++++-------- lib/ManagerLib/Manager.h | 163 +- lib/ToolLib/basic.h | 40 +- lib/ToolLib/llvm_related.cpp | 650 +++-- lib/ToolLib/llvm_related.h | 46 +- lib/ToolLib/log.h | 129 +- tools/SyzDescribe/SyzDescribe.cpp | 23 +- 28 files changed, 6048 insertions(+), 5833 deletions(-) rename config/{knowledge.json => knowledge-v5.12.json} (100%) diff --git a/config/knowledge.json b/config/knowledge-v5.12.json similarity index 100% rename from config/knowledge.json rename to config/knowledge-v5.12.json diff --git a/lib/AnalysisLib/T_function.cpp b/lib/AnalysisLib/T_function.cpp index b46ef52..60b4737 100644 --- a/lib/AnalysisLib/T_function.cpp +++ b/lib/AnalysisLib/T_function.cpp @@ -3,498 +3,520 @@ // #include "T_function.h" -#include "../ToolLib/log.h" + #include "../ToolLib/llvm_related.h" +#include "../ToolLib/log.h" #include "T_module.h" #define DEBUG_FUNCTION_POINTER -1 sd::T_function::T_function(llvm::Function *f) : llvm_function(f) { - num_checkers_check_callee = -1; - num_checkers_check_caller = 0; + num_checkers_check_callee = -1; + num_checkers_check_caller = 0; } sd::T_function::~T_function() = default; void sd::T_function::check() { - int64_t debug = DEBUG_CHECKER; - std::string str; - yhao_log(debug, "****check_device_driver start*****************"); - yhao_log(debug, "check(): " + this->llvm_function->getName().str()); - - for (auto &b: *this->llvm_function) { - for (auto &i: b) { - switch (i.getOpcode()) { - case llvm::Instruction::Call : { - auto &ci = llvm::cast(i); - - // e.g., @llvm.dbg.declare - if (ci.isDebugOrPseudoInst()) { break; } - // e.g., @llvm.lifetime.start.p0i8 - if (ci.isLifetimeStartOrEnd()) { break; } - if (ci.isInlineAsm()) { break; } - - yhao_dump(-1, i.print, str) - if (ci.isIndirectCall()) { - yhao_log(debug, "ci.isIndirectCall() in " + inst_to_strID(&i)); - add_callee(&i, callee_type::callee_indirect); - break; - } - - auto tf = get_target_function(ci.getCalledOperand()); - if (tf == nullptr) { - yhao_log(2, "ci.getCalledOperand() == nullptr"); - break; - } - std::string function_name = get_real_function_name(tf); - if (function_name == "llvm") { - break; - } - - auto t_f = this->t_module->find_t_function(tf); - if (t_f == nullptr) { - break; - } - - - if (tf->isDeclaration()) { - yhao_log(debug, "tf->isDeclaration(): " + function_name); - add_callee(&i, callee_type::callee_isDeclaration, t_f); - } else { - add_callee(&i, callee_type::callee_not_isDeclaration, t_f); - t_f->caller_not_isDeclaration.insert(this); - } - break; - } - default: { - - } - } - check_function_pointer(&i); + int64_t debug = DEBUG_CHECKER; + std::string str; + yhao_log(debug, "****check_device_driver start*****************"); + yhao_log(debug, "check(): " + this->llvm_function->getName().str()); + + for (auto &b : *this->llvm_function) { + for (auto &i : b) { + switch (i.getOpcode()) { + case llvm::Instruction::Call: { + auto &ci = llvm::cast(i); + + // e.g., @llvm.dbg.declare + if (ci.isDebugOrPseudoInst()) { + break; + } + // e.g., @llvm.lifetime.start.p0i8 + if (ci.isLifetimeStartOrEnd()) { + break; + } + if (ci.isInlineAsm()) { + break; + } + + yhao_dump(-1, i.print, str) if (ci.isIndirectCall()) { + yhao_log(debug, "ci.isIndirectCall() in " + inst_to_strID(&i)); + add_callee(&i, callee_type::callee_indirect); + break; + } + + auto tf = get_target_function(ci.getCalledOperand()); + if (tf == nullptr) { + yhao_log(2, "ci.getCalledOperand() == nullptr"); + break; + } + std::string function_name = get_real_function_name(tf); + if (function_name == "llvm") { + break; + } + + auto t_f = this->t_module->find_t_function(tf); + if (t_f == nullptr) { + break; + } + + if (tf->isDeclaration()) { + yhao_log(debug, "tf->isDeclaration(): " + function_name); + add_callee(&i, callee_type::callee_isDeclaration, t_f); + } else { + add_callee(&i, callee_type::callee_not_isDeclaration, t_f); + t_f->caller_not_isDeclaration.insert(this); + } + break; + } + default: { } + } + check_function_pointer(&i); } + } - - yhao_log(debug, "****check_device_driver end*******************"); + yhao_log(debug, "****check_device_driver end*******************"); } void sd::T_function::check(sd::knowledge *k) { - std::string str; - int64_t debug = DEBUG_CHECKER; - yhao_log(debug, "****check_device_driver start*****************"); - yhao_log(debug, "check(sd::k *k): " + this->llvm_function->getName().str()); - - for (auto &b: *this->llvm_function) { - for (auto &i: b) { - yhao_dump(-1, i.print, str) - switch (i.getOpcode()) { - case llvm::Instruction::Call : { - if (all_callee_map.find(&i) == all_callee_map.end()) { - break; - } - auto ce = all_callee_map[&i]; - - if (ce->ct != callee_type::callee_not_isDeclaration && - ce->ct != callee_type::callee_isDeclaration) { - break; - } - auto tf = ce->tf; - yhao_log(debug, "check: call:" + tf->get_name()); - - auto &ci = llvm::cast(i); - std::string function_name = get_real_function_name(tf->llvm_function); - - bool ret = false; - if (k->inst_call.find(function_name) != k->inst_call.end()) { - yhao_log(debug, "find in inst_call:" + tf->get_name()); - for (auto c: *(k->inst_call[function_name])) { - if (check_call(c, &ci)) { - add_checker_result(c, &i); - ret = true; - } - } - } + std::string str; + int64_t debug = DEBUG_CHECKER; + yhao_log(debug, "****check_device_driver start*****************"); + yhao_log(debug, "check(sd::k *k): " + this->llvm_function->getName().str()); + + for (auto &b : *this->llvm_function) { + for (auto &i : b) { + yhao_dump(-1, i.print, str) switch (i.getOpcode()) { + case llvm::Instruction::Call: { + if (all_callee_map.find(&i) == all_callee_map.end()) { + break; + } + auto ce = all_callee_map[&i]; + + if (ce->ct != callee_type::callee_not_isDeclaration && + ce->ct != callee_type::callee_isDeclaration) { + break; + } + auto tf = ce->tf; + yhao_log(debug, "check: call:" + tf->get_name()); + + auto &ci = llvm::cast(i); + std::string function_name = get_real_function_name(tf->llvm_function); + + bool ret = false; + if (k->inst_call.find(function_name) != k->inst_call.end()) { + yhao_log(debug, "find in inst_call:" + tf->get_name()); + for (auto c : *(k->inst_call[function_name])) { + if (check_call(c, &ci)) { + add_checker_result(c, &i); + ret = true; + } + } + } - // not check the function again even for callee - if (ret) { - ce->checked = true; - } + // not check the function again even for callee + if (ret) { + ce->checked = true; + } + break; + } + case llvm::Instruction::Store: { + auto a1 = i.getOperand(1); + if (auto *inst = llvm::dyn_cast(a1)) { + if (inst->getOpcode() == llvm::Instruction::GetElementPtr) { + auto *gep = llvm::dyn_cast(inst); + if (gep->isInBounds()) { + auto se_ty = gep->getSourceElementType(); + if (se_ty->isStructTy()) { + std::string struct_name = se_ty->getStructName().str(); + if (struct_name.empty()) { break; - } - case llvm::Instruction::Store : { - auto a1 = i.getOperand(1); - if (auto *inst = llvm::dyn_cast(a1)) { - if (inst->getOpcode() == llvm::Instruction::GetElementPtr) { - auto *gep = llvm::dyn_cast(inst); - if (gep->isInBounds()) { - auto se_ty = gep->getSourceElementType(); - if (se_ty->isStructTy()) { - std::string struct_name = se_ty->getStructName().str(); - if (struct_name.empty()) { - break; - } - struct_name = get_real_structure_name(se_ty->getStructName().str()); - if (k->inst_store.find(struct_name) == k->inst_store.end()) { - break; - } - yhao_log(debug, "struct_name: " + struct_name); - if (auto c1 = llvm::cast(gep->getOperand(2))) { - uint64_t offset = c1->getZExtValue(); - for (auto c: *(k->inst_store[struct_name])) { - if (offset == c->offset) { - add_checker_result(c, &i); - } - } - } - } - } else { - // TODO: fix or handle it - yhao_log(debug, "check: !gep->isInBounds()"); - } - } - } + } + struct_name = + get_real_structure_name(se_ty->getStructName().str()); + if (k->inst_store.find(struct_name) == k->inst_store.end()) { break; + } + yhao_log(debug, "struct_name: " + struct_name); + if (auto c1 = + llvm::cast(gep->getOperand(2))) { + uint64_t offset = c1->getZExtValue(); + for (auto c : *(k->inst_store[struct_name])) { + if (offset == c->offset) { + add_checker_result(c, &i); + } + } + } } - default: { - - } + } else { + // TODO: fix or handle it + yhao_log(debug, "check: !gep->isInBounds()"); + } } + } + break; + } + default: { } + } } + } - yhao_log(debug, "****check_device_driver end*******************"); + yhao_log(debug, "****check_device_driver end*******************"); } bool sd::T_function::check_call(sd::checker *c, llvm::CallInst *cs) { - int64_t debug = DEBUG_CHECKER; - if (!c->field) { - return true; - } - - auto arg = cs->getOperand(c->object); - if (auto *inst = llvm::dyn_cast(arg)) { - if (auto *gep = llvm::dyn_cast(inst)) { - auto se_ty = gep->getSourceElementType(); - if (se_ty->isStructTy()) { - std::string struct_name = get_real_structure_name(se_ty->getStructName().str()); - if (struct_name == c->structure) { - yhao_log(debug, "check_call_cmd: struct_name: " + struct_name); - if (auto c1 = llvm::cast(gep->getOperand(2))) { - uint64_t offset = c1->getZExtValue(); - if (offset == c->offset) { - return true; - } - } - } - } else if (se_ty->isArrayTy()) { - auto arg2 = gep->getOperand(0); - if (auto gep2 = llvm::dyn_cast(arg2)) { - auto se_ty2 = gep2->getSourceElementType(); - if (se_ty2->isStructTy()) { - std::string struct_name = get_real_structure_name(se_ty2->getStructName().str()); - if (struct_name == c->structure) { - yhao_log(debug, "check_call_cmd: array struct_name: " + struct_name); - if (auto c1 = llvm::cast(gep2->getOperand(2))) { - uint64_t offset = c1->getZExtValue(); - if (offset == c->offset) { - return true; - } - } - } - } + int64_t debug = DEBUG_CHECKER; + if (!c->field) { + return true; + } + + auto arg = cs->getOperand(c->object); + if (auto *inst = llvm::dyn_cast(arg)) { + if (auto *gep = llvm::dyn_cast(inst)) { + auto se_ty = gep->getSourceElementType(); + if (se_ty->isStructTy()) { + std::string struct_name = + get_real_structure_name(se_ty->getStructName().str()); + if (struct_name == c->structure) { + yhao_log(debug, "check_call_cmd: struct_name: " + struct_name); + if (auto c1 = llvm::cast(gep->getOperand(2))) { + uint64_t offset = c1->getZExtValue(); + if (offset == c->offset) { + return true; + } + } + } + } else if (se_ty->isArrayTy()) { + auto arg2 = gep->getOperand(0); + if (auto gep2 = llvm::dyn_cast(arg2)) { + auto se_ty2 = gep2->getSourceElementType(); + if (se_ty2->isStructTy()) { + std::string struct_name = + get_real_structure_name(se_ty2->getStructName().str()); + if (struct_name == c->structure) { + yhao_log(debug, + "check_call_cmd: array struct_name: " + struct_name); + if (auto c1 = + llvm::cast(gep2->getOperand(2))) { + uint64_t offset = c1->getZExtValue(); + if (offset == c->offset) { + return true; } - + } } + } } + } } + } - return false; + return false; } void sd::T_function::check_function_pointer(llvm::Instruction *i) { - std::string str; - - yhao_log(DEBUG_FUNCTION_POINTER, "check_function_pointer: " + inst_to_strID(i)); - - uint64_t num = i->getNumOperands(); - // not check function call here - if (i->getOpcode() == llvm::Instruction::Call) { - num--; - } - - for (int index = 0; index < num; index++) { - auto arg = i->getOperand(index); - llvm::SmallPtrSet Visited; - check_function_pointer(arg, Visited); - } - - - add_callee(i, callee_type::function_pointer, current_function_pointer); - for (auto temp: current_function_pointer) { - temp->caller_pointer.insert(this); - } - current_function_pointer.clear(); + std::string str; + + yhao_log(DEBUG_FUNCTION_POINTER, + "check_function_pointer: " + inst_to_strID(i)); + + uint64_t num = i->getNumOperands(); + // not check function call here + if (i->getOpcode() == llvm::Instruction::Call) { + num--; + } + + for (int index = 0; index < num; index++) { + auto arg = i->getOperand(index); + llvm::SmallPtrSet Visited; + check_function_pointer(arg, Visited); + } + + add_callee(i, callee_type::function_pointer, current_function_pointer); + for (auto temp : current_function_pointer) { + temp->caller_pointer.insert(this); + } + current_function_pointer.clear(); } -void -sd::T_function::check_function_pointer(llvm::Value *v, llvm::SmallPtrSet &visited) { - std::string str; - - auto *c = llvm::dyn_cast(v); - if (!c) { - return; - } +void sd::T_function::check_function_pointer( + llvm::Value *v, llvm::SmallPtrSet &visited) { + std::string str; - while (true) { - if (auto *gv = llvm::dyn_cast(c)) { - if (!visited.insert(gv).second) { - return; - } - if (auto *f = llvm::dyn_cast(gv)) { - yhao_log(DEBUG_FUNCTION_POINTER, "find function pointer: " + f->getName().str()); + auto *c = llvm::dyn_cast(v); + if (!c) { + return; + } - auto t_f = this->t_module->find_t_function(f); - if (t_f == nullptr) { - return; - } - current_function_pointer.insert(t_f); - return; - } else if (auto *ga = llvm::dyn_cast(gv)) { - c = ga->getAliasee(); - } else if (auto gvv = llvm::dyn_cast(gv)) { - yhao_log(DEBUG_FUNCTION_POINTER, "GlobalVariable: " + gvv->getName().str()); - if (gvv->hasInitializer()) { - auto gvvi = gvv->getInitializer(); - if (const llvm::ConstantVector *cp = llvm::dyn_cast(gvvi)) { - for (unsigned ii = 0, e = cp->getNumOperands(); ii != e; ++ii) { - check_function_pointer(cp->getOperand(ii), visited); - } - } else if (const llvm::ConstantArray *ca = llvm::dyn_cast(gvvi)) { - for (unsigned ii = 0, e = ca->getNumOperands(); ii != e; ++ii) { - check_function_pointer(ca->getOperand(ii), visited); - } - } else if (const llvm::ConstantStruct *cs = llvm::dyn_cast(gvvi)) { - for (unsigned ii = 0, e = cs->getNumOperands(); ii != e; ++ii) { - check_function_pointer(cs->getOperand(ii), visited); - } - } else if (const llvm::ConstantDataSequential *cds = llvm::dyn_cast( - gvvi)) { - for (unsigned ii = 0, e = cds->getNumElements(); ii != e; ++ii) { - check_function_pointer(cds->getElementAsConstant(ii), visited); - } - } - } - } else { - yhao_log(2, "check_function_pointer: not handle else case!"); - return; - } - } else if (auto *ce = llvm::dyn_cast(c)) { - if (ce->getOpcode() == llvm::Instruction::BitCast) { - c = ce->getOperand(0); - } else if (ce->getOpcode() == llvm::Instruction::GetElementPtr) { - c = ce->getOperand(0); - } else { - yhao_log(DEBUG_FUNCTION_POINTER, "check_function_pointer: ConstantExpr: else"); - yhao_dump(DEBUG_FUNCTION_POINTER, ce->print, str) - return; - } - } else if (const llvm::ConstantVector *cp = llvm::dyn_cast(c)) { + while (true) { + if (auto *gv = llvm::dyn_cast(c)) { + if (!visited.insert(gv).second) { + return; + } + if (auto *f = llvm::dyn_cast(gv)) { + yhao_log(DEBUG_FUNCTION_POINTER, + "find function pointer: " + f->getName().str()); + + auto t_f = this->t_module->find_t_function(f); + if (t_f == nullptr) { + return; + } + current_function_pointer.insert(t_f); + return; + } else if (auto *ga = llvm::dyn_cast(gv)) { + c = ga->getAliasee(); + } else if (auto gvv = llvm::dyn_cast(gv)) { + yhao_log(DEBUG_FUNCTION_POINTER, + "GlobalVariable: " + gvv->getName().str()); + if (gvv->hasInitializer()) { + auto gvvi = gvv->getInitializer(); + if (const llvm::ConstantVector *cp = + llvm::dyn_cast(gvvi)) { for (unsigned ii = 0, e = cp->getNumOperands(); ii != e; ++ii) { - check_function_pointer(cp->getOperand(ii), visited); + check_function_pointer(cp->getOperand(ii), visited); } - return; - } else if (const llvm::ConstantArray *ca = llvm::dyn_cast(c)) { + } else if (const llvm::ConstantArray *ca = + llvm::dyn_cast(gvvi)) { for (unsigned ii = 0, e = ca->getNumOperands(); ii != e; ++ii) { - check_function_pointer(ca->getOperand(ii), visited); + check_function_pointer(ca->getOperand(ii), visited); } - return; - } else if (const llvm::ConstantStruct *cs = llvm::dyn_cast(c)) { + } else if (const llvm::ConstantStruct *cs = + llvm::dyn_cast(gvvi)) { for (unsigned ii = 0, e = cs->getNumOperands(); ii != e; ++ii) { - check_function_pointer(cs->getOperand(ii), visited); + check_function_pointer(cs->getOperand(ii), visited); } - return; - } else if (const llvm::ConstantDataSequential *cds = llvm::dyn_cast(c)) { + } else if (const llvm::ConstantDataSequential *cds = + llvm::dyn_cast(gvvi)) { for (unsigned ii = 0, e = cds->getNumElements(); ii != e; ++ii) { - check_function_pointer(cds->getElementAsConstant(ii), visited); + check_function_pointer(cds->getElementAsConstant(ii), visited); } - return; - } else { - yhao_log(DEBUG_FUNCTION_POINTER, "check_function_pointer: else"); - yhao_dump(DEBUG_FUNCTION_POINTER, c->print, str) - return; + } } + } else { + yhao_log(2, "check_function_pointer: not handle else case!"); + return; + } + } else if (auto *ce = llvm::dyn_cast(c)) { + if (ce->getOpcode() == llvm::Instruction::BitCast) { + c = ce->getOperand(0); + } else if (ce->getOpcode() == llvm::Instruction::GetElementPtr) { + c = ce->getOperand(0); + } else { + yhao_log(DEBUG_FUNCTION_POINTER, + "check_function_pointer: ConstantExpr: else"); + yhao_dump(DEBUG_FUNCTION_POINTER, ce->print, str) return; + } + } else if (const llvm::ConstantVector *cp = + llvm::dyn_cast(c)) { + for (unsigned ii = 0, e = cp->getNumOperands(); ii != e; ++ii) { + check_function_pointer(cp->getOperand(ii), visited); + } + return; + } else if (const llvm::ConstantArray *ca = + llvm::dyn_cast(c)) { + for (unsigned ii = 0, e = ca->getNumOperands(); ii != e; ++ii) { + check_function_pointer(ca->getOperand(ii), visited); + } + return; + } else if (const llvm::ConstantStruct *cs = + llvm::dyn_cast(c)) { + for (unsigned ii = 0, e = cs->getNumOperands(); ii != e; ++ii) { + check_function_pointer(cs->getOperand(ii), visited); + } + return; + } else if (const llvm::ConstantDataSequential *cds = + llvm::dyn_cast(c)) { + for (unsigned ii = 0, e = cds->getNumElements(); ii != e; ++ii) { + check_function_pointer(cds->getElementAsConstant(ii), visited); + } + return; + } else { + yhao_log(DEBUG_FUNCTION_POINTER, "check_function_pointer: else"); + yhao_dump(DEBUG_FUNCTION_POINTER, c->print, str) return; } + } } -sd::callee *sd::T_function::add_callee(llvm::Instruction *i, sd::callee_type ct, T_function *tf) { - auto temp_c = new callee(); - temp_c->i = i; - temp_c->ct = ct; - if (tf == nullptr) { - temp_c->tf_set = new std::set; - } else { - temp_c->tf = tf; - } - this->all_callee.push_back(temp_c); - this->all_callee_map[i] = temp_c; - return temp_c; +sd::callee *sd::T_function::add_callee(llvm::Instruction *i, sd::callee_type ct, + T_function *tf) { + auto temp_c = new callee(); + temp_c->i = i; + temp_c->ct = ct; + if (tf == nullptr) { + temp_c->tf_set = new std::set; + } else { + temp_c->tf = tf; + } + this->all_callee.push_back(temp_c); + this->all_callee_map[i] = temp_c; + return temp_c; } // only for function pointer -sd::callee *sd::T_function::add_callee(llvm::Instruction *i, sd::callee_type ct, std::set &tf) { - if (tf.empty()) { - return nullptr; - } - auto temp_c = new callee(); - temp_c->i = i; - temp_c->ct = ct; - temp_c->tf_set = new std::set; - for (auto temp: tf) { - temp_c->tf_set->insert(temp); - } - this->all_callee.push_back(temp_c); - return temp_c; +sd::callee *sd::T_function::add_callee(llvm::Instruction *i, sd::callee_type ct, + std::set &tf) { + if (tf.empty()) { + return nullptr; + } + auto temp_c = new callee(); + temp_c->i = i; + temp_c->ct = ct; + temp_c->tf_set = new std::set; + for (auto temp : tf) { + temp_c->tf_set->insert(temp); + } + this->all_callee.push_back(temp_c); + return temp_c; } void sd::T_function::add_checker_result(sd::checker *c, llvm::Instruction *i) { - int64_t debug = DEBUG_CHECKER; - checker_result *cr1 = make_checker(c->ct); - cr1->checker::copy(c); - cr1->setInst(i); + int64_t debug = DEBUG_CHECKER; + checker_result *cr1 = make_checker(c->ct); + cr1->checker::copy(c); + cr1->setInst(i); - this->checker_results.push_back(cr1); + this->checker_results.push_back(cr1); - yhao_log(debug, "function: " + this->llvm_function->getName().str()); - yhao_log(debug, "checker: " + std::to_string(cr1->ct) + " :" + checker_type_name[cr1->ct]); - yhao_log(debug, inst_to_strID(i)); + yhao_log(debug, "function: " + this->llvm_function->getName().str()); + yhao_log(debug, "checker: " + std::to_string(cr1->ct) + " :" + + checker_type_name[cr1->ct]); + yhao_log(debug, inst_to_strID(i)); } void sd::T_function::reset() { - // reset for check k - for (auto ce: all_callee) { - ce->checked = false; - } - for (auto cr: this->checker_results) { - delete cr; - } - this->checker_results.clear(); - -// // reset for check callee -// this->num_checkers_check_callee = -1; -// for (auto s: all_callee_checker_results) { -// delete s.second; -// } -// this->all_callee_checker_results.clear(); - - // reset for check caller - this->num_checkers_check_caller = 0; + // reset for check k + for (auto ce : all_callee) { + ce->checked = false; + } + for (auto cr : this->checker_results) { + delete cr; + } + this->checker_results.clear(); + + // // reset for check callee + // this->num_checkers_check_callee = -1; + // for (auto s: all_callee_checker_results) { + // delete s.second; + // } + // this->all_callee_checker_results.clear(); + + // reset for check caller + this->num_checkers_check_caller = 0; } -uint64_t sd::T_function::calculate_path(llvm::BasicBlock *start_node, llvm::BasicBlock *end_node, +uint64_t sd::T_function::calculate_path(llvm::BasicBlock *start_node, + llvm::BasicBlock *end_node, std::vector *path) { - // TODO: later: more effective path? - path->push_back(end_node); - return 0; + // TODO: later: more effective path? + path->push_back(end_node); + return 0; } -uint64_t sd::T_function::calculate_path(llvm::BasicBlock *start_node, std::set *end_node, +uint64_t sd::T_function::calculate_path(llvm::BasicBlock *start_node, + std::set *end_node, std::vector *path) { - - uint64_t ret = 0; - uint64_t size = end_node->size(); - if (size == 0) { - yhao_log(3, "end_node->size() == 0"); - ret = 1; - } - // 1 indirect function call or 1 pair device & driver or ... - else if (size == 1) { - calculate_path(start_node, *(end_node->begin()), path); - } - // m pairs device & driver - // get an order based on reachable relationship - else { - yhao_log(2, "end_node->size() >= 1"); - auto *pass_node = new std::vector; - for (auto temp_b1: *end_node) { - for (auto it = pass_node->begin(); it != pass_node->end(); it++) { - if (llvm::isPotentiallyReachable(&temp_b1->front(), &(*it)->front(), nullptr, this->dominator_tree)) { - pass_node->insert(it, temp_b1); - break; - } else if (llvm::isPotentiallyReachable(&(*it)->front(), &temp_b1->front(), nullptr, - this->dominator_tree)) { - continue; - } else { - ret = 1; - yhao_log(3, "llvm::isPotentiallyReachable(): not reachable"); - } - } - } - - auto temp_b1 = start_node; - path->push_back(start_node); - for (auto temp_b2: *pass_node) { - calculate_path(temp_b1, temp_b2, path); - temp_b1 = temp_b2; + uint64_t ret = 0; + uint64_t size = end_node->size(); + if (size == 0) { + yhao_log(3, "end_node->size() == 0"); + ret = 1; + } + // 1 indirect function call or 1 pair device & driver or ... + else if (size == 1) { + calculate_path(start_node, *(end_node->begin()), path); + } + // m pairs device & driver + // get an order based on reachable relationship + else { + yhao_log(2, "end_node->size() >= 1"); + auto *pass_node = new std::vector; + for (auto temp_b1 : *end_node) { + for (auto it = pass_node->begin(); it != pass_node->end(); it++) { + if (llvm::isPotentiallyReachable(&temp_b1->front(), &(*it)->front(), + nullptr, this->dominator_tree)) { + pass_node->insert(it, temp_b1); + break; + } else if (llvm::isPotentiallyReachable(&(*it)->front(), + &temp_b1->front(), nullptr, + this->dominator_tree)) { + continue; + } else { + ret = 1; + yhao_log(3, "llvm::isPotentiallyReachable(): not reachable"); } + } } - return ret; -} - -uint64_t -sd::T_function::calculate_path(std::set *pass_node_i, - std::vector *path) { - if (this->dominator_tree == nullptr) { - this->dominator_tree = new llvm::DominatorTree(*this->llvm_function); + auto temp_b1 = start_node; + path->push_back(start_node); + for (auto temp_b2 : *pass_node) { + calculate_path(temp_b1, temp_b2, path); + temp_b1 = temp_b2; } + } + return ret; +} - // filter the basic block by dominate relationship, only keep the dominated basic block - auto *pass_node_b = new std::set; - for (auto i: *pass_node_i) { - auto temp_b = i->getParent(); - if (pass_node_b->find(temp_b) == pass_node_b->end()) { - for (auto b: *pass_node_b) { - // only insert dominated basic block, so all those basic blocks would be reached - if (this->dominator_tree->dominates(b, temp_b)) { - pass_node_b->insert(temp_b); - pass_node_b->erase(b); - } else if (this->dominator_tree->dominates(temp_b, b)) { - - } - // no dominate relationship, insert the temp_b - else { - pass_node_b->insert(temp_b); - } - } +uint64_t sd::T_function::calculate_path( + std::set *pass_node_i, + std::vector *path) { + if (this->dominator_tree == nullptr) { + this->dominator_tree = new llvm::DominatorTree(*this->llvm_function); + } + + // filter the basic block by dominate relationship, only keep the dominated + // basic block + auto *pass_node_b = new std::set; + for (auto i : *pass_node_i) { + auto temp_b = i->getParent(); + if (pass_node_b->find(temp_b) == pass_node_b->end()) { + for (auto b : *pass_node_b) { + // only insert dominated basic block, so all those basic blocks would be + // reached + if (this->dominator_tree->dominates(b, temp_b)) { + pass_node_b->insert(temp_b); + pass_node_b->erase(b); + } else if (this->dominator_tree->dominates(temp_b, b)) { + } + // no dominate relationship, insert the temp_b + else { + pass_node_b->insert(temp_b); } + } } + } - uint64_t ret = calculate_path(&(this->llvm_function->getEntryBlock()), pass_node_b, path); - return ret; + uint64_t ret = calculate_path(&(this->llvm_function->getEntryBlock()), + pass_node_b, path); + return ret; } -uint64_t sd::T_function::calculate_path(std::set *pass_node_i, std::vector *path) { - - auto *basic_bloc_path = new std::vector; - uint64_t ret = calculate_path(pass_node_i, basic_bloc_path); +uint64_t sd::T_function::calculate_path( + std::set *pass_node_i, std::vector *path) { + auto *basic_bloc_path = new std::vector; + uint64_t ret = calculate_path(pass_node_i, basic_bloc_path); - // TODO: later: basic_bloc_path --> path - yhao_log(3, "TODO: basic_bloc_path --> path"); + // TODO: later: basic_bloc_path --> path + yhao_log(3, "TODO: basic_bloc_path --> path"); - return ret; + return ret; } std::string sd::T_function::get_name() const { - return this->llvm_function->getName().str(); + return this->llvm_function->getName().str(); } -void sd::T_function::add_callee_checker_results(llvm::Instruction *i, sd::T_function *t_f) { - std::set *temp; - if (all_callee_checker_results.find(i) == all_callee_checker_results.end()) { - temp = new std::set; - all_callee_checker_results[i] = temp; - } else { - temp = all_callee_checker_results[i]; - } - temp->insert(t_f); +void sd::T_function::add_callee_checker_results(llvm::Instruction *i, + sd::T_function *t_f) { + std::set *temp; + if (all_callee_checker_results.find(i) == all_callee_checker_results.end()) { + temp = new std::set; + all_callee_checker_results[i] = temp; + } else { + temp = all_callee_checker_results[i]; + } + temp->insert(t_f); } diff --git a/lib/AnalysisLib/T_function.h b/lib/AnalysisLib/T_function.h index 4e847fd..b70c484 100644 --- a/lib/AnalysisLib/T_function.h +++ b/lib/AnalysisLib/T_function.h @@ -5,104 +5,109 @@ #ifndef INC_2021_TEMPLATE_T_FUNCTION_H #define INC_2021_TEMPLATE_T_FUNCTION_H -#include "../ToolLib/basic.h" #include "../KnowledgeLib/knowledge.h" +#include "../ToolLib/basic.h" namespace sd { - class T_module; - - // init and exit T_function number - enum callee_type { - callee_baisc = 0, - callee_not_isDeclaration, - callee_isDeclaration, - callee_indirect, - function_pointer, - }; +class T_module; - class T_function; +// init and exit T_function number +enum callee_type { + callee_baisc = 0, + callee_not_isDeclaration, + callee_isDeclaration, + callee_indirect, + function_pointer, +}; - class callee { - public: - llvm::Instruction *i{}; - callee_type ct = callee_type::callee_baisc; - // for callee_not_isDeclaration and callee_isDeclaration - T_function *tf{}; - // for callee_indirect and function_pointer - std::set *tf_set{}; - // whether this callee is checked by k function - bool checked = false; - }; +class T_function; - class T_function { - public: - explicit T_function(llvm::Function *f); +class callee { + public: + llvm::Instruction *i{}; + callee_type ct = callee_type::callee_baisc; + // for callee_not_isDeclaration and callee_isDeclaration + T_function *tf{}; + // for callee_indirect and function_pointer + std::set *tf_set{}; + // whether this callee is checked by k function + bool checked = false; +}; - virtual ~T_function(); +class T_function { + public: + explicit T_function(llvm::Function *f); - [[nodiscard]] std::string get_name() const; + virtual ~T_function(); - void check(); + [[nodiscard]] std::string get_name() const; - void check(knowledge *k); + void check(); - bool check_call(checker *c, llvm::CallInst *cs); + void check(knowledge *k); - void check_function_pointer(llvm::Instruction *i); + bool check_call(checker *c, llvm::CallInst *cs); - void check_function_pointer(llvm::Value *v, llvm::SmallPtrSet &visited); + void check_function_pointer(llvm::Instruction *i); - callee *add_callee(llvm::Instruction *i, callee_type ct, T_function *tf = nullptr); + void check_function_pointer( + llvm::Value *v, llvm::SmallPtrSet &visited); - callee *add_callee(llvm::Instruction *i, callee_type ct, std::set &tf); + callee *add_callee(llvm::Instruction *i, callee_type ct, + T_function *tf = nullptr); - void add_checker_result(checker *c, llvm::Instruction *i); + callee *add_callee(llvm::Instruction *i, callee_type ct, + std::set &tf); - void add_callee_checker_results(llvm::Instruction *i, T_function *t_f); + void add_checker_result(checker *c, llvm::Instruction *i); - void reset(); + void add_callee_checker_results(llvm::Instruction *i, T_function *t_f); - // calculate path - llvm::DominatorTree *dominator_tree{}; + void reset(); - uint64_t calculate_path(llvm::BasicBlock *start_node, llvm::BasicBlock *end_node, - std::vector *path); + // calculate path + llvm::DominatorTree *dominator_tree{}; - uint64_t calculate_path(llvm::BasicBlock *start_node, std::set *end_node, - std::vector *path); + uint64_t calculate_path(llvm::BasicBlock *start_node, + llvm::BasicBlock *end_node, + std::vector *path); - uint64_t calculate_path(std::set *pass_node_i, - std::vector *path); + uint64_t calculate_path(llvm::BasicBlock *start_node, + std::set *end_node, + std::vector *path); - uint64_t calculate_path(std::set *pass_node_i, - std::vector *path); + uint64_t calculate_path(std::set *pass_node_i, + std::vector *path); - public: - // for itself - llvm::Function *llvm_function; - T_module *t_module{}; + uint64_t calculate_path(std::set *pass_node_i, + std::vector *path); - std::vector all_callee; - // not include function pointers - std::map all_callee_map; - // used for finding function pointers - std::set current_function_pointer; + public: + // for itself + llvm::Function *llvm_function; + T_module *t_module{}; - // for caller - std::set caller_not_isDeclaration; - std::set caller_indirect; - std::set caller_pointer; + std::vector all_callee; + // not include function pointers + std::map all_callee_map; + // used for finding function pointers + std::set current_function_pointer; - // checker results in current function - std::vector checker_results; + // for caller + std::set caller_not_isDeclaration; + std::set caller_indirect; + std::set caller_pointer; - // number of checker, could be used for recursive check_callee analysis - int64_t num_checkers_check_callee; - int64_t num_checkers_check_caller; - // order is from caller to callee - std::map *> all_callee_checker_results; - }; -} + // checker results in current function + std::vector checker_results; + // number of checker, could be used for recursive check_callee analysis + int64_t num_checkers_check_callee; + int64_t num_checkers_check_caller; + // order is from caller to callee + std::map *> + all_callee_checker_results; +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_T_FUNCTION_H +#endif // INC_2021_TEMPLATE_T_FUNCTION_H diff --git a/lib/AnalysisLib/T_module.cpp b/lib/AnalysisLib/T_module.cpp index 3ea442c..156202c 100644 --- a/lib/AnalysisLib/T_module.cpp +++ b/lib/AnalysisLib/T_module.cpp @@ -3,909 +3,943 @@ // #include "T_module.h" -#include "../ToolLib/log.h" -#include "../ToolLib/llvm_related.h" #include "../MLTA/Analyzer.hh" #include "../MLTA/CallGraph.hh" #include "../MLTA/TypeInitializer.hh" +#include "../ToolLib/llvm_related.h" +#include "../ToolLib/log.h" #define DEBUG_CHECK -1 sd::T_module::T_module() { - uint64_t order = 0; - for (const auto &temp: module_init_name) { - auto temp_1 = new module_init_order(); - temp_1->order = order++; - temp_1->name = "module_init_function_" + temp; - temp_1->f = new std::set(); - module_init_function[temp] = temp_1; - } - + uint64_t order = 0; + for (const auto &temp : module_init_name) { auto temp_1 = new module_init_order(); temp_1->order = order++; - temp_1->name = "module_init_function_" + module_name; + temp_1->name = "module_init_function_" + temp; temp_1->f = new std::set(); - module_init_function[module_name] = temp_1; + module_init_function[temp] = temp_1; + } + + auto temp_1 = new module_init_order(); + temp_1->order = order++; + temp_1->name = "module_init_function_" + module_name; + temp_1->f = new std::set(); + module_init_function[module_name] = temp_1; } sd::T_module::~T_module() = default; void sd::T_module::read_bitcode(const std::string &BitcodeFileName) { - yhao_log(1, "*************************************************"); - yhao_log(1, "****************ReadIR***************************"); - - this->bitcode = BitcodeFileName; - llvm::LLVMContext *cxts; - llvm::SMDiagnostic Err; - cxts = new llvm::LLVMContext[1]; - llvm_module = llvm::parseIRFile(BitcodeFileName, Err, cxts[0]); - - if (!llvm_module) { - yhao_log(3, "load T_module: " + BitcodeFileName + " failed"); - exit(0); - } else { - - } - - cg = new llvm::CallGraph(*llvm_module); - - for (auto &f: *this->llvm_module) { - auto ff = new class T_function(&f); - ff->t_module = this; - this->t_functions[&f] = ff; - } - - yhao_log(1, "****************check all function start*********"); - for (auto ff: this->t_functions) { - ff.second->check(); - } - yhao_log(1, "****************check all function end***********"); - - yhao_log(1, "****************indirect functions start*********"); - MLTA_indirect_functions(); - //type_based_indirect_functions(); - yhao_log(1, "****************indirect functions end***********"); + yhao_log(1, "*************************************************"); + yhao_log(1, "****************ReadIR***************************"); + + this->bitcode = BitcodeFileName; + llvm::LLVMContext *cxts; + llvm::SMDiagnostic Err; + cxts = new llvm::LLVMContext[1]; + llvm_module = llvm::parseIRFile(BitcodeFileName, Err, cxts[0]); + + if (!llvm_module) { + yhao_log(3, "load T_module: " + BitcodeFileName + " failed"); + exit(0); + } else { + } + + cg = new llvm::CallGraph(*llvm_module); + + for (auto &f : *this->llvm_module) { + auto ff = new class T_function(&f); + ff->t_module = this; + this->t_functions[&f] = ff; + } + + yhao_log(1, "****************check all function start*********"); + for (auto ff : this->t_functions) { + ff.second->check(); + } + yhao_log(1, "****************check all function end***********"); + + yhao_log(1, "****************indirect functions start*********"); + MLTA_indirect_functions(); + // type_based_indirect_functions(); + yhao_log(1, "****************indirect functions end***********"); } void sd::T_module::analysis_functions() { - yhao_log(1, "****************analysis functions start*********"); - for (auto ff: this->t_functions) { - analysis_functions(ff.second); - } - for (auto ff: this->t_functions) { - check_caller(ff.second); - } - yhao_log(1, "****************analysis functions end***********"); + yhao_log(1, "****************analysis functions start*********"); + for (auto ff : this->t_functions) { + analysis_functions(ff.second); + } + for (auto ff : this->t_functions) { + check_caller(ff.second); + } + yhao_log(1, "****************analysis functions end***********"); } -void sd::T_module::analysis_functions(T_function *f) { - f->check(this->k); -} +void sd::T_module::analysis_functions(T_function *f) { f->check(this->k); } void sd::T_module::update_function() { - for (auto &tf: this->t_functions) { - tf.second->reset(); - } - analysis_functions(); + for (auto &tf : this->t_functions) { + tf.second->reset(); + } + analysis_functions(); } void sd::T_module::update_fp_in_init() { - // add function pointer from all init function - for (auto temp_init_f: init_function) { - auto temp_init_t_f = this->find_t_function(temp_init_f); - if (temp_init_f == nullptr) { - continue; - } - for (auto ce: temp_init_t_f->all_callee) { - if (ce->ct == callee_type::function_pointer) { - for (auto temp_fp: *ce->tf_set) { - fp_in_init.insert(temp_fp->llvm_function); - } - } + // add function pointer from all init function + for (auto temp_init_f : init_function) { + auto temp_init_t_f = this->find_t_function(temp_init_f); + if (temp_init_f == nullptr) { + continue; + } + for (auto ce : temp_init_t_f->all_callee) { + if (ce->ct == callee_type::function_pointer) { + for (auto temp_fp : *ce->tf_set) { + fp_in_init.insert(temp_fp->llvm_function); } + } } + } } void sd::T_module::type_based_indirect_functions() { - std::string str; - + std::string str; + + // number based indirect call + for (auto temp_f : this->t_functions) { + auto f = temp_f.second->llvm_function; + if (f->hasAddressTaken()) { + auto *ft = f->getFunctionType(); + if (this->map_function_type.find(ft) == this->map_function_type.end()) { + auto set_function = new std::set; + set_function->insert(temp_f.second); + this->map_function_type[ft] = set_function; + } else { + this->map_function_type[ft]->insert(temp_f.second); + } + } + } + for (auto ff : this->t_functions) { // number based indirect call - for (auto temp_f: this->t_functions) { - auto f = temp_f.second->llvm_function; - if (f->hasAddressTaken()) { - auto *ft = f->getFunctionType(); - if (this->map_function_type.find(ft) == this->map_function_type.end()) { - auto set_function = new std::set; - set_function->insert(temp_f.second); - this->map_function_type[ft] = set_function; - } else { - this->map_function_type[ft]->insert(temp_f.second); - } - } - } - for (auto ff: this->t_functions) { - // number based indirect call - for (auto ce: ff.second->all_callee) { - if (ce->ct != callee_type::callee_indirect) { - continue; - } - if (!ce->tf_set->empty()) { - continue; - } - auto ci = llvm::cast(ce->i); - llvm::Type *t = ci->getCalledOperand()->getType(); - auto *ft = llvm::cast( - llvm::cast(t)->getNonOpaquePointerElementType()); - std::set *set_function; - if (this->map_function_type.find(ft) == this->map_function_type.end()) { - set_function = new std::set; - this->map_function_type[ft] = set_function; - yhao_log(2, "wrong function number:"); - yhao_dump(2, ci->print, str) - yhao_log(2, inst_to_strID(ce->i)); - } else { - set_function = this->map_function_type[ft]; - } - for (auto &temp_f: *set_function) { - ce->tf_set->insert(temp_f); - temp_f->caller_indirect.insert(ff.second); - } - } - } + for (auto ce : ff.second->all_callee) { + if (ce->ct != callee_type::callee_indirect) { + continue; + } + if (!ce->tf_set->empty()) { + continue; + } + auto ci = llvm::cast(ce->i); + llvm::Type *t = ci->getCalledOperand()->getType(); + auto *ft = llvm::cast( + llvm::cast(t)->getNonOpaquePointerElementType()); + std::set *set_function; + if (this->map_function_type.find(ft) == this->map_function_type.end()) { + set_function = new std::set; + this->map_function_type[ft] = set_function; + yhao_log(2, "wrong function number:"); + yhao_dump(2, ci->print, str) yhao_log(2, inst_to_strID(ce->i)); + } else { + set_function = this->map_function_type[ft]; + } + for (auto &temp_f : *set_function) { + ce->tf_set->insert(temp_f); + temp_f->caller_indirect.insert(ff.second); + } + } + } } void sd::T_module::MLTA_indirect_functions() { - std::string str; - int64_t debug = -1; - - GlobalContext GlobalCtx; - auto MName = StringRef(bitcode); - GlobalCtx.Modules.push_back(make_pair(llvm_module.get(), MName)); - GlobalCtx.ModuleMaps[llvm_module.get()] = bitcode; - - // Initialize global number map - TypeInitializerPass TIPass(&GlobalCtx); - TIPass.run(GlobalCtx.Modules); - TIPass.BuildTypeStructMap(); - - // Build global call graph. - CallGraphPass CGPass(&GlobalCtx); - CGPass.run(GlobalCtx.Modules); - - for (auto ff: t_functions) { - for (auto ce: ff.second->all_callee) { - if (ce->ct != callee_type::callee_indirect) { - continue; - } - - yhao_print(debug, ce->i->print, str) - yhao_log(debug, "mlta ce->i: " + str); - auto *ci = llvm::cast(ce->i); - auto callee = GlobalCtx.Callees[ci]; - for (auto temp_f: callee) { - yhao_log(-1, "callee: " + temp_f->getName().str()); - auto temp_ff = t_functions[temp_f]; - if (temp_ff == nullptr) { - yhao_log(2, "function but no t_function: " + temp_f->getName().str()); - continue; - } - ce->tf_set->insert(temp_ff); - temp_ff->caller_indirect.insert(ff.second); - } - } - } + std::string str; + int64_t debug = -1; + + GlobalContext GlobalCtx; + auto MName = StringRef(bitcode); + GlobalCtx.Modules.push_back(make_pair(llvm_module.get(), MName)); + GlobalCtx.ModuleMaps[llvm_module.get()] = bitcode; + + // Initialize global number map + TypeInitializerPass TIPass(&GlobalCtx); + TIPass.run(GlobalCtx.Modules); + TIPass.BuildTypeStructMap(); + + // Build global call graph. + CallGraphPass CGPass(&GlobalCtx); + CGPass.run(GlobalCtx.Modules); + + for (auto ff : t_functions) { + for (auto ce : ff.second->all_callee) { + if (ce->ct != callee_type::callee_indirect) { + continue; + } + + yhao_print(debug, ce->i->print, str) + yhao_log(debug, "mlta ce->i: " + str); + auto *ci = llvm::cast(ce->i); + auto callee = GlobalCtx.Callees[ci]; + for (auto temp_f : callee) { + yhao_log(-1, "callee: " + temp_f->getName().str()); + auto temp_ff = t_functions[temp_f]; + if (temp_ff == nullptr) { + yhao_log(2, "function but no t_function: " + temp_f->getName().str()); + continue; + } + ce->tf_set->insert(temp_ff); + temp_ff->caller_indirect.insert(ff.second); + } + } + } } // for all indirect function call, remove module init functions from targets // because it is impossible to call module init functions from them void sd::T_module::remove_init_from_indirect() { - for (const auto &temp: module_init_function) { - for (auto temp1: *temp.second->f) { - if (t_functions.find(temp1) == t_functions.end()) { - yhao_log(3, "never possible"); - } - auto t_f = t_functions[temp1]; - for (auto temp2: t_f->caller_indirect) { - for (auto temp3: temp2->all_callee) { - if (temp3->ct == callee_type::callee_indirect) { - if (temp3->tf_set->find(t_f) != temp3->tf_set->end()) { - temp3->tf_set->erase(t_f); - goto next; - } - } - } - next: - continue; - } - t_f->caller_indirect.clear(); - } - } + for (const auto &temp : module_init_function) { + for (auto temp1 : *temp.second->f) { + if (t_functions.find(temp1) == t_functions.end()) { + yhao_log(3, "never possible"); + } + auto t_f = t_functions[temp1]; + for (auto temp2 : t_f->caller_indirect) { + for (auto temp3 : temp2->all_callee) { + if (temp3->ct == callee_type::callee_indirect) { + if (temp3->tf_set->find(t_f) != temp3->tf_set->end()) { + temp3->tf_set->erase(t_f); + goto next; + } + } + } + next: + continue; + } + t_f->caller_indirect.clear(); + } + } } // use MLTA to find targets function -int64_t sd::T_module::get_callee(llvm::Instruction *inst, std::set *targets) { - std::string str; - if (targets == nullptr) { - yhao_log(2, "get_callee: targets == nullptr"); - return -1; - } - - auto bb = inst->getParent(); - auto f = bb->getParent(); - - if (this->t_functions.find(f) == this->t_functions.end()) { - yhao_log(2, "get_callee: this->t_functions.find(f) == this->t_functions.end()"); - return -1; - } - auto t_f = this->t_functions[f]; - if (t_f->all_callee_map.find(inst) == t_f->all_callee_map.end()) { - yhao_dump(-1, inst->print, str) - yhao_log(-1, "get_callee: t_f->all_callee_map.find(inst) == t_f->all_callee_map.end()"); - return -1; - } - auto ce = t_f->all_callee_map[inst]; - if (ce->ct == callee_type::callee_not_isDeclaration || - ce->ct == callee_type::callee_isDeclaration) { - if (ce->tf == nullptr) { - yhao_log(3, "get_callee: ce->tf == nullptr"); - return -1; - } else { - targets->insert(ce->tf); - } - } else if (ce->ct == callee_type::callee_indirect) { - if (ce->tf_set == nullptr) { - yhao_log(3, "get_callee: ce->tf_set == nullptr"); - return -1; - } else { - for (auto ff: *ce->tf_set) { - targets->insert(ff); - } - } +int64_t sd::T_module::get_callee(llvm::Instruction *inst, + std::set *targets) { + std::string str; + if (targets == nullptr) { + yhao_log(2, "get_callee: targets == nullptr"); + return -1; + } + + auto bb = inst->getParent(); + auto f = bb->getParent(); + + if (this->t_functions.find(f) == this->t_functions.end()) { + yhao_log( + 2, "get_callee: this->t_functions.find(f) == this->t_functions.end()"); + return -1; + } + auto t_f = this->t_functions[f]; + if (t_f->all_callee_map.find(inst) == t_f->all_callee_map.end()) { + yhao_dump(-1, inst->print, str) + yhao_log(-1, + "get_callee: t_f->all_callee_map.find(inst) == " + "t_f->all_callee_map.end()"); + return -1; + } + auto ce = t_f->all_callee_map[inst]; + if (ce->ct == callee_type::callee_not_isDeclaration || + ce->ct == callee_type::callee_isDeclaration) { + if (ce->tf == nullptr) { + yhao_log(3, "get_callee: ce->tf == nullptr"); + return -1; } else { - yhao_log(2, "get_callee: !ce->ct == callee_type::callee_indirect"); - return -1; + targets->insert(ce->tf); } - return 0; + } else if (ce->ct == callee_type::callee_indirect) { + if (ce->tf_set == nullptr) { + yhao_log(3, "get_callee: ce->tf_set == nullptr"); + return -1; + } else { + for (auto ff : *ce->tf_set) { + targets->insert(ff); + } + } + } else { + yhao_log(2, "get_callee: !ce->ct == callee_type::callee_indirect"); + return -1; + } + return 0; } - // use MLTA to find targets function and filter it by given fd set -int64_t sd::T_module::get_callee(llvm::Instruction *inst, std::set *targets, +int64_t sd::T_module::get_callee(llvm::Instruction *inst, + std::set *targets, std::set *fp) { - if (targets == nullptr) { - yhao_log(2, "get_callee: targets == nullptr"); - return 1; - } - - std::set temp; - int64_t ret; - ret = get_callee(inst, &temp); - if (ret == 0) { - for (auto f: temp) { - targets->insert(f->llvm_function); - } - } - - if (fp != nullptr && !fp->empty()) { - std::set temp_1; - for (auto f: *targets) { - if (fp->find(f) == fp->end()) { - continue; - } else { - temp_1.insert(f); - } - } - // if (temp_1.empty()) { - // } else { - targets->clear(); - targets->insert(temp_1.begin(), temp_1.end()); - // } - } - - return ret; + if (targets == nullptr) { + yhao_log(2, "get_callee: targets == nullptr"); + return 1; + } + + std::set temp; + int64_t ret; + ret = get_callee(inst, &temp); + if (ret == 0) { + for (auto f : temp) { + targets->insert(f->llvm_function); + } + } + + if (fp != nullptr && !fp->empty()) { + std::set temp_1; + for (auto f : *targets) { + if (fp->find(f) == fp->end()) { + continue; + } else { + temp_1.insert(f); + } + } + // if (temp_1.empty()) { + // } else { + targets->clear(); + targets->insert(temp_1.begin(), temp_1.end()); + // } + } + + return ret; } -int64_t sd::T_module::get_callee(llvm::Instruction *inst, std::set *targets, +int64_t sd::T_module::get_callee(llvm::Instruction *inst, + std::set *targets, std::set *fp) { - std::set temp; - if (fp != nullptr && !fp->empty()) { - for (auto temp_t_f: *fp) { - temp.insert(temp_t_f->llvm_function); - } + std::set temp; + if (fp != nullptr && !fp->empty()) { + for (auto temp_t_f : *fp) { + temp.insert(temp_t_f->llvm_function); } - return get_callee(inst, targets, &temp); + } + return get_callee(inst, targets, &temp); } -int64_t sd::T_module::find_ops_structure(const std::string &ops_structure, const std::string &name, +int64_t sd::T_module::find_ops_structure(const std::string &ops_structure, + const std::string &name, llvm::GlobalVariable **ops) const { - std::string str; - if (name.empty()) { - return 1; - } - *ops = this->llvm_module->getNamedGlobal(name); - if (*ops == nullptr) { - yhao_log(3, "not find ops_structure:" + ops_structure); - yhao_log(3, "not find name:" + name); - return 1; - } - yhao_dump(-1, (*ops)->print, str) - return 0; + std::string str; + if (name.empty()) { + return 1; + } + *ops = this->llvm_module->getNamedGlobal(name); + if (*ops == nullptr) { + yhao_log(3, "not find ops_structure:" + ops_structure); + yhao_log(3, "not find name:" + name); + return 1; + } + yhao_dump(-1, (*ops)->print, str) return 0; } void sd::T_module::find_module_init_function() { - int64_t debug = -1; - std::string module_init_start = "__initcall_"; - std::string module_init_next = "\n"; - uint64_t pos_start = 0; - uint64_t pos_end = 0; - uint64_t pos_next; - uint64_t size_m = module_init_start.size(); - std::string info; - std::string module_asm = llvm_module->getModuleInlineAsm(); - - std::ofstream temp_of(this->work_dir + "module_inline_asm.s", std::ios_base::out); - temp_of << module_asm << std::endl; - temp_of.close(); - - auto get_function = [&, this]() { - uint64_t get_function_size; - uint64_t get_function_pos_start; - get_function_size = pos_end - pos_start - size_m; - std::string init_asm = module_asm.substr(pos_start + size_m, pos_end - pos_start - size_m); - get_function_pos_start = init_asm.find("__"); - get_function_pos_start = init_asm.find('_', get_function_pos_start + 2); - get_function_pos_start = init_asm.find('_', get_function_pos_start + 1); - std::string function_name = init_asm.substr(get_function_pos_start + 1, - get_function_size - get_function_pos_start - 1); - yhao_log(debug, info + "function_name: " + function_name); - llvm::Function *f = llvm_module->getFunction(function_name); + int64_t debug = -1; + std::string module_init_start = "__initcall_"; + std::string module_init_next = "\n"; + uint64_t pos_start = 0; + uint64_t pos_end = 0; + uint64_t pos_next; + uint64_t size_m = module_init_start.size(); + std::string info; + std::string module_asm = llvm_module->getModuleInlineAsm(); + + std::ofstream temp_of(this->work_dir + "module_inline_asm.s", + std::ios_base::out); + temp_of << module_asm << std::endl; + temp_of.close(); + + auto get_function = [&, this]() { + uint64_t get_function_size; + uint64_t get_function_pos_start; + get_function_size = pos_end - pos_start - size_m; + std::string init_asm = + module_asm.substr(pos_start + size_m, pos_end - pos_start - size_m); + get_function_pos_start = init_asm.find("__"); + get_function_pos_start = init_asm.find('_', get_function_pos_start + 2); + get_function_pos_start = init_asm.find('_', get_function_pos_start + 1); + std::string function_name = + init_asm.substr(get_function_pos_start + 1, + get_function_size - get_function_pos_start - 1); + yhao_log(debug, info + "function_name: " + function_name); + llvm::Function *f = llvm_module->getFunction(function_name); + if (!f) { + yhao_log( + 2, + "find_module_init_function : can not find module_init T_function :" + + function_name); + } else { + yhao_log(debug, + "find_module_init_function : find module_init T_function :" + + f->getName().str()); + } + return f; + }; + + pos_start = module_asm.find(module_init_start, 0); + while (pos_start != std::string::npos) { + pos_next = module_asm.find(module_init_next, pos_start + 1); + + for (const auto &temp : module_init_name) { + std::string name = temp + ":"; + pos_end = module_asm.find(name, pos_start + 1); + if (pos_end != std::string::npos && pos_end < pos_next) { + info = "find_module_init_function_" + temp + ": "; + auto f = get_function(); if (!f) { - yhao_log(2, "find_module_init_function : can not find module_init T_function :" + function_name); - } else { - yhao_log(debug, "find_module_init_function : find module_init T_function :" + f->getName().str()); - } - return f; - }; - - pos_start = module_asm.find(module_init_start, 0); - while (pos_start != std::string::npos) { - pos_next = module_asm.find(module_init_next, pos_start + 1); - - for (const auto &temp: module_init_name) { - std::string name = temp + ":"; - pos_end = module_asm.find(name, pos_start + 1); - if (pos_end != std::string::npos && pos_end < pos_next) { - info = "find_module_init_function_" + temp + ": "; - auto f = get_function(); - if (!f) { - continue; - } - auto fv = module_init_function[temp]->f; - auto it = init_function.begin(), ie = init_function.end(); - while (it != ie && fv->find(f) != fv->end()) { - if (get_real_function_name(*it) == get_real_function_name(f)) { - f = *it; - } - it++; - } - yhao_log(debug, info + "real function_name: " + f->getName().str()); - fv->insert(f); - goto find; - } - } - if (pos_next < module_asm.size()) { - yhao_log(1, "find_module_init_function : can not find module_init T_function: " + - module_asm.substr(pos_start, pos_next - pos_start)); - } - find: - pos_start = module_asm.find(module_init_start, pos_start + 1); - } - - for (auto &gv: this->llvm_module->getGlobalList()) { - auto sec = gv.getSection().str(); - for (const auto &temp: module_init_name) { - auto name = ".initcall" + temp + ".init"; - if (sec.find(name) != std::string::npos) { - auto func = llvm::cast(gv.getOperand(0));; - auto fv = module_init_function[temp]->f; - auto it = init_function.begin(), ie = init_function.end(); - while (it != ie && fv->find(func) != fv->end()) { - if (get_real_function_name(*it) == get_real_function_name(func)) { - func = *it; - } - it++; - } - yhao_log(debug, info + "real function_name: " + func->getName().str()); - fv->insert(func); - } - } - } - - std::string str; - auto ga = this->llvm_module->getNamedAlias(module_name); - if (ga == nullptr) { - return; - } - auto func = llvm::cast(ga->getAliasee()); - if (func == nullptr) { - return; - } - auto fv = module_init_function[module_name]->f; - auto it = init_function.begin(), ie = init_function.end(); - while (it != ie && fv->find(func) != fv->end()) { - if (get_real_function_name(*it) == get_real_function_name(func)) { + continue; + } + auto fv = module_init_function[temp]->f; + auto it = init_function.begin(), ie = init_function.end(); + while (it != ie && fv->find(f) != fv->end()) { + if (get_real_function_name(*it) == get_real_function_name(f)) { + f = *it; + } + it++; + } + yhao_log(debug, info + "real function_name: " + f->getName().str()); + fv->insert(f); + goto find; + } + } + if (pos_next < module_asm.size()) { + yhao_log( + 1, + "find_module_init_function : can not find module_init T_function: " + + module_asm.substr(pos_start, pos_next - pos_start)); + } + find: + pos_start = module_asm.find(module_init_start, pos_start + 1); + } + + for (auto &gv : this->llvm_module->getGlobalList()) { + auto sec = gv.getSection().str(); + for (const auto &temp : module_init_name) { + auto name = ".initcall" + temp + ".init"; + if (sec.find(name) != std::string::npos) { + auto func = llvm::cast(gv.getOperand(0)); + ; + auto fv = module_init_function[temp]->f; + auto it = init_function.begin(), ie = init_function.end(); + while (it != ie && fv->find(func) != fv->end()) { + if (get_real_function_name(*it) == get_real_function_name(func)) { func = *it; - } - it++; - } - yhao_log(debug, info + "real function_name: " + func->getName().str()); - fv->insert(func); + } + it++; + } + yhao_log(debug, info + "real function_name: " + func->getName().str()); + fv->insert(func); + } + } + } + + std::string str; + auto ga = this->llvm_module->getNamedAlias(module_name); + if (ga == nullptr) { + return; + } + auto func = llvm::cast(ga->getAliasee()); + if (func == nullptr) { + return; + } + auto fv = module_init_function[module_name]->f; + auto it = init_function.begin(), ie = init_function.end(); + while (it != ie && fv->find(func) != fv->end()) { + if (get_real_function_name(*it) == get_real_function_name(func)) { + func = *it; + } + it++; + } + yhao_log(debug, info + "real function_name: " + func->getName().str()); + fv->insert(func); } void sd::T_module::find_init_and_exit_function() { - std::string section_init = ".init.text"; - std::string section_exit = ".exit.text"; - - for (auto &f: llvm_module->getFunctionList()) { - if (f.getSection().find(section_init) != std::string::npos) { - yhao_log(-1, "find_init_and_exit_function : section_init function_name : " + f.getName().str()); - init_function.push_back(&f); - } else if (f.getSection().find(section_exit) != std::string::npos) { - exit_function.push_back(&f); - } else { - - } + std::string section_init = ".init.text"; + std::string section_exit = ".exit.text"; + + for (auto &f : llvm_module->getFunctionList()) { + if (f.getSection().find(section_init) != std::string::npos) { + yhao_log(-1, + "find_init_and_exit_function : section_init function_name : " + + f.getName().str()); + init_function.push_back(&f); + } else if (f.getSection().find(section_exit) != std::string::npos) { + exit_function.push_back(&f); + } else { } + } - this->update_fp_in_init(); - + this->update_fp_in_init(); } int64_t sd::T_module::check_callee(T_function *t_f) { - int64_t debug = DEBUG_CHECK; - // loop all function once for all entry function - // if there is caller1 and caller2, skip analysis of caller2 - // but save results of caller2 - if (t_f->num_checkers_check_callee > 0) { - // copy all checker_results to caller if existing - yhao_log(debug, "t_f->num_checkers_check_callee > 0: " + t_f->get_name()); - return t_f->num_checkers_check_callee; - } - // if has been analyzed before and no checkers, directly return - // somehow, it would be a bug if the case is a loop when finally the num_checkers_check_callee > 0 - else if (t_f->num_checkers_check_callee == 0) { - yhao_log(debug, "t_f->num_checkers_check_callee == 0: " + t_f->get_name()); - return 0; - } - // set the num_checkers_check_callee to 0 - // so that if it would be analyzed in callee, directly return - else if (t_f->num_checkers_check_callee == -1) { - t_f->num_checkers_check_callee = 0; - } - - yhao_log(debug, "check_callee start: " + t_f->get_name()); - t_f->num_checkers_check_callee += (int64_t) t_f->checker_results.size(); - - for (auto ce: t_f->all_callee) { - if (ce->ct == callee_type::callee_not_isDeclaration) { - // skip the callee function because it has been checked by k - if (ce->checked) { - continue; - } - auto temp_f = ce->tf; - yhao_log(debug, "callee_not_isDeclaration: " + temp_f->get_name()); - auto temp_ret = check_callee(temp_f); - if (temp_ret > 0) { - t_f->num_checkers_check_callee += temp_ret; - t_f->add_callee_checker_results(ce->i, temp_f); - } - } else if (ce->ct == callee_type::callee_indirect) { - // check all possible indirect call, hope there is no FN - for (auto temp_f: *ce->tf_set) { - yhao_log(debug, "callee_indirect: " + temp_f->get_name()); - auto temp_ret = check_callee(temp_f); - if (temp_ret > 0) { - t_f->num_checkers_check_callee += temp_ret; - t_f->add_callee_checker_results(ce->i, temp_f); - } - } - } else if (ce->ct == callee_type::function_pointer) { - // a heuristic way to handle register and probe function - for (auto temp_f: *ce->tf_set) { - if (temp_f->get_name().find("probe") != std::string::npos) { - yhao_log(debug, "function pointer: " + temp_f->get_name()); - auto temp_ret = check_callee(temp_f); - if (temp_ret > 0) { - t_f->num_checkers_check_callee += temp_ret; - t_f->add_callee_checker_results(ce->i, temp_f); - } - } - } - } - } - yhao_log(debug, "check_callee end: " + t_f->get_name()); - - int64_t ret = t_f->num_checkers_check_callee; - return ret; + int64_t debug = DEBUG_CHECK; + // loop all function once for all entry function + // if there is caller1 and caller2, skip analysis of caller2 + // but save results of caller2 + if (t_f->num_checkers_check_callee > 0) { + // copy all checker_results to caller if existing + yhao_log(debug, "t_f->num_checkers_check_callee > 0: " + t_f->get_name()); + return t_f->num_checkers_check_callee; + } + // if has been analyzed before and no checkers, directly return + // somehow, it would be a bug if the case is a loop when finally the + // num_checkers_check_callee > 0 + else if (t_f->num_checkers_check_callee == 0) { + yhao_log(debug, "t_f->num_checkers_check_callee == 0: " + t_f->get_name()); + return 0; + } + // set the num_checkers_check_callee to 0 + // so that if it would be analyzed in callee, directly return + else if (t_f->num_checkers_check_callee == -1) { + t_f->num_checkers_check_callee = 0; + } + + yhao_log(debug, "check_callee start: " + t_f->get_name()); + t_f->num_checkers_check_callee += (int64_t)t_f->checker_results.size(); + + for (auto ce : t_f->all_callee) { + if (ce->ct == callee_type::callee_not_isDeclaration) { + // skip the callee function because it has been checked by k + if (ce->checked) { + continue; + } + auto temp_f = ce->tf; + yhao_log(debug, "callee_not_isDeclaration: " + temp_f->get_name()); + auto temp_ret = check_callee(temp_f); + if (temp_ret > 0) { + t_f->num_checkers_check_callee += temp_ret; + t_f->add_callee_checker_results(ce->i, temp_f); + } + } else if (ce->ct == callee_type::callee_indirect) { + // check all possible indirect call, hope there is no FN + for (auto temp_f : *ce->tf_set) { + yhao_log(debug, "callee_indirect: " + temp_f->get_name()); + auto temp_ret = check_callee(temp_f); + if (temp_ret > 0) { + t_f->num_checkers_check_callee += temp_ret; + t_f->add_callee_checker_results(ce->i, temp_f); + } + } + } else if (ce->ct == callee_type::function_pointer) { + // a heuristic way to handle register and probe function + for (auto temp_f : *ce->tf_set) { + if (temp_f->get_name().find("probe") != std::string::npos) { + yhao_log(debug, "function pointer: " + temp_f->get_name()); + auto temp_ret = check_callee(temp_f); + if (temp_ret > 0) { + t_f->num_checkers_check_callee += temp_ret; + t_f->add_callee_checker_results(ce->i, temp_f); + } + } + } + } + } + yhao_log(debug, "check_callee end: " + t_f->get_name()); + + int64_t ret = t_f->num_checkers_check_callee; + return ret; } int64_t sd::T_module::check_caller(T_function *t_f) { - int64_t debug = DEBUG_CHECK; - std::string str; - yhao_log(debug, "check_caller: " + t_f->get_name()); - int64_t ret = t_f->num_checkers_check_caller + (int64_t) t_f->checker_results.size(); - if (ret > 0) { - for (auto caller: t_f->caller_not_isDeclaration) { - yhao_log(debug, "check_caller caller_not_isDeclaration: " + caller->get_name() + ": " + t_f->get_name()); - for (auto temp1: caller->all_callee_checker_results) { - for (auto temp2: *temp1.second) { - if (t_f == temp2) { - // find in caller, goto next - yhao_log(debug, "check_caller find in all_callee_checker_results"); - goto next1; - } - } - } - // not find in caller, add it - for (auto temp1: caller->all_callee_map) { - if (temp1.second->ct == callee_type::callee_not_isDeclaration) { - if (temp1.second->tf == t_f) { - // if checked by k skip - if (temp1.second->checked) { - yhao_log(debug, "temp1.second->checked"); - goto next1; - } - caller->add_callee_checker_results(temp1.first, t_f); - // if new caller, check it recursive - if (caller->num_checkers_check_caller == 0) { - caller->num_checkers_check_caller += ret; - check_caller(caller); - } else { - yhao_log(debug, "not caller->num_checkers_check_caller == 0"); - caller->num_checkers_check_caller += ret; - } - goto next1; - } - } - } - yhao_log(debug, "check_caller not find in all_callee_map callee_not_isDeclaration"); - next1: - continue; - } - - for (auto caller: t_f->caller_indirect) { - yhao_log(debug, "check_caller caller_indirect: " + caller->get_name() + ": " + t_f->get_name()); - for (auto temp1: caller->all_callee_checker_results) { - for (auto temp2: *temp1.second) { - if (t_f == temp2) { - // find in caller, goto next - yhao_log(debug, "check_caller find in all_callee_checker_results"); - goto next2; - } - } - } - // not find in caller, add it - for (auto temp1: caller->all_callee_map) { - if (temp1.second->ct == callee_type::callee_indirect) { - for (auto temp2: *temp1.second->tf_set) { - if (temp2 == t_f) { - caller->add_callee_checker_results(temp1.first, t_f); - // if new caller, check it recursive - if (caller->num_checkers_check_caller == 0) { - caller->num_checkers_check_caller += ret; - check_caller(caller); - } else { - yhao_log(debug, "not caller->num_checkers_check_caller == 0"); - caller->num_checkers_check_caller += ret; - } - goto next2; - } - } - } - } - yhao_log(debug, "check_caller not find in all_callee_map callee_indirect"); - next2: - continue; - } - - for (auto caller: t_f->caller_pointer) { - yhao_log(debug, "check_caller caller_pointer: " + caller->get_name() + ": " + t_f->get_name()); - for (auto temp1: caller->all_callee_checker_results) { - for (auto temp2: *temp1.second) { - if (t_f == temp2) { - // find in caller, goto next - yhao_log(debug, "check_caller find in all_callee_checker_results"); - goto next3; - } - } - } - // not find in caller, add it - for (auto temp1: caller->all_callee) { - if (temp1->ct == callee_type::function_pointer) { - for (auto temp2: *temp1->tf_set) { - if (temp2 == t_f) { - caller->add_callee_checker_results(temp1->i, t_f); - // if new caller, check it recursive - if (caller->num_checkers_check_caller == 0) { - caller->num_checkers_check_caller += ret; - check_caller(caller); - } else { - yhao_log(debug, "not caller->num_checkers_check_caller == 0"); - caller->num_checkers_check_caller += ret; - } - goto next3; - } - } - } - } - yhao_log(debug, "check_caller not find in all_callee_map function_pointer"); - next3: - continue; - } - yhao_log(debug, "check_caller end: " + t_f->get_name()); - return 0; - } else { - yhao_log(debug, "ret: " + std::to_string(ret)); - return 0; - } + int64_t debug = DEBUG_CHECK; + std::string str; + yhao_log(debug, "check_caller: " + t_f->get_name()); + int64_t ret = + t_f->num_checkers_check_caller + (int64_t)t_f->checker_results.size(); + if (ret > 0) { + for (auto caller : t_f->caller_not_isDeclaration) { + yhao_log(debug, "check_caller caller_not_isDeclaration: " + + caller->get_name() + ": " + t_f->get_name()); + for (auto temp1 : caller->all_callee_checker_results) { + for (auto temp2 : *temp1.second) { + if (t_f == temp2) { + // find in caller, goto next + yhao_log(debug, "check_caller find in all_callee_checker_results"); + goto next1; + } + } + } + // not find in caller, add it + for (auto temp1 : caller->all_callee_map) { + if (temp1.second->ct == callee_type::callee_not_isDeclaration) { + if (temp1.second->tf == t_f) { + // if checked by k skip + if (temp1.second->checked) { + yhao_log(debug, "temp1.second->checked"); + goto next1; + } + caller->add_callee_checker_results(temp1.first, t_f); + // if new caller, check it recursive + if (caller->num_checkers_check_caller == 0) { + caller->num_checkers_check_caller += ret; + check_caller(caller); + } else { + yhao_log(debug, "not caller->num_checkers_check_caller == 0"); + caller->num_checkers_check_caller += ret; + } + goto next1; + } + } + } + yhao_log( + debug, + "check_caller not find in all_callee_map callee_not_isDeclaration"); + next1: + continue; + } + + for (auto caller : t_f->caller_indirect) { + yhao_log(debug, "check_caller caller_indirect: " + caller->get_name() + + ": " + t_f->get_name()); + for (auto temp1 : caller->all_callee_checker_results) { + for (auto temp2 : *temp1.second) { + if (t_f == temp2) { + // find in caller, goto next + yhao_log(debug, "check_caller find in all_callee_checker_results"); + goto next2; + } + } + } + // not find in caller, add it + for (auto temp1 : caller->all_callee_map) { + if (temp1.second->ct == callee_type::callee_indirect) { + for (auto temp2 : *temp1.second->tf_set) { + if (temp2 == t_f) { + caller->add_callee_checker_results(temp1.first, t_f); + // if new caller, check it recursive + if (caller->num_checkers_check_caller == 0) { + caller->num_checkers_check_caller += ret; + check_caller(caller); + } else { + yhao_log(debug, "not caller->num_checkers_check_caller == 0"); + caller->num_checkers_check_caller += ret; + } + goto next2; + } + } + } + } + yhao_log(debug, + "check_caller not find in all_callee_map callee_indirect"); + next2: + continue; + } + + for (auto caller : t_f->caller_pointer) { + yhao_log(debug, "check_caller caller_pointer: " + caller->get_name() + + ": " + t_f->get_name()); + for (auto temp1 : caller->all_callee_checker_results) { + for (auto temp2 : *temp1.second) { + if (t_f == temp2) { + // find in caller, goto next + yhao_log(debug, "check_caller find in all_callee_checker_results"); + goto next3; + } + } + } + // not find in caller, add it + for (auto temp1 : caller->all_callee) { + if (temp1->ct == callee_type::function_pointer) { + for (auto temp2 : *temp1->tf_set) { + if (temp2 == t_f) { + caller->add_callee_checker_results(temp1->i, t_f); + // if new caller, check it recursive + if (caller->num_checkers_check_caller == 0) { + caller->num_checkers_check_caller += ret; + check_caller(caller); + } else { + yhao_log(debug, "not caller->num_checkers_check_caller == 0"); + caller->num_checkers_check_caller += ret; + } + goto next3; + } + } + } + } + yhao_log(debug, + "check_caller not find in all_callee_map function_pointer"); + next3: + continue; + } + yhao_log(debug, "check_caller end: " + t_f->get_name()); + return 0; + } else { + yhao_log(debug, "ret: " + std::to_string(ret)); + return 0; + } } -int64_t sd::T_module::check_open(llvm::Function *f, std::vector *crs) { - if (this->t_functions.find(f) == this->t_functions.end()) { - return 1; - } - auto t_f = this->t_functions[f]; - uint64_t size = 0; - callee *ce; - for (auto temp_ce: t_f->all_callee) { - if (temp_ce->ct == callee_type::callee_indirect) { - size++; - ce = temp_ce; - } - } - if (size == 0) { - yhao_log(3, "check_open: " + f->getName().str() + ": no indirect"); - return 1; - } else if (size == 1) { - auto cr = new checker_result(); - cr->ct = checker_type::open_indirect; - cr->setInst(ce->i); - crs->push_back(cr); - } else if (size > 1) { - yhao_log(3, "check_open: " + f->getName().str() + ": more than one indirect"); - return 1; - } - return 0; +int64_t sd::T_module::check_open(llvm::Function *f, + std::vector *crs) { + if (this->t_functions.find(f) == this->t_functions.end()) { + return 1; + } + auto t_f = this->t_functions[f]; + uint64_t size = 0; + callee *ce; + for (auto temp_ce : t_f->all_callee) { + if (temp_ce->ct == callee_type::callee_indirect) { + size++; + ce = temp_ce; + } + } + if (size == 0) { + yhao_log(3, "check_open: " + f->getName().str() + ": no indirect"); + return 1; + } else if (size == 1) { + auto cr = new checker_result(); + cr->ct = checker_type::open_indirect; + cr->setInst(ce->i); + crs->push_back(cr); + } else if (size > 1) { + yhao_log(3, + "check_open: " + f->getName().str() + ": more than one indirect"); + return 1; + } + return 0; } int64_t sd::T_module::check_function_pointer(sd::entry_function *init_f) { - if (init_f->count_function_pointer == 0) { - //collect all function pointers - // do not consider order now, so there would be some FP - if (init_f->parent != nullptr && init_f->parent->parent != nullptr) { - auto parent = init_f->parent->parent; - for (auto fp: parent->function_pointers) { - init_f->function_pointers.insert(fp); - } - } - check_function_pointer(init_f, init_f->t_function); - } - - return 0; + if (init_f->count_function_pointer == 0) { + // collect all function pointers + // do not consider order now, so there would be some FP + if (init_f->parent != nullptr && init_f->parent->parent != nullptr) { + auto parent = init_f->parent->parent; + for (auto fp : parent->function_pointers) { + init_f->function_pointers.insert(fp); + } + } + check_function_pointer(init_f, init_f->t_function); + } + + return 0; } -int64_t sd::T_module::check_function_pointer(sd::entry_function *init_f, T_function *t_f) { - int64_t debug = -1; - - //if (init_f->checked_function.find(t_f) != init_f->checked_function.end()) { - // return 0; - //} else { - // init_f->checked_function.insert(t_f); - //} - - // skip if call chain is too long - // possible only for kvm - if (current_call_chain.size() > MAX_FUNC_DEPTH) { - return 0; - } - - if (init_f->count_function_pointer > MAX_CALLEE_COUNT) { - return 0; - } else { - init_f->count_function_pointer++; - } - - auto path = get_file_name(t_f->llvm_function); - if (path.empty()) { - return 0; - } - for (const auto &temp: skip_path) { - if (path.find(temp) == 0) { - return 0; - } - } - - if (debug > -1) { - yhao_log(debug, "current_call_chain: "); - for (auto temp: current_call_chain) { - yhao_log(debug, temp->get_name()); - } - } +int64_t sd::T_module::check_function_pointer(sd::entry_function *init_f, + T_function *t_f) { + int64_t debug = -1; - current_call_chain.push_back(t_f); + // if (init_f->checked_function.find(t_f) != init_f->checked_function.end()) { + // return 0; + // } else { + // init_f->checked_function.insert(t_f); + // } - for (auto ce: t_f->all_callee) { - if (ce->ct == callee_type::function_pointer) { - for (auto fp: *ce->tf_set) { - init_f->function_pointers.insert(fp); - } - } else if (ce->ct == callee_type::callee_not_isDeclaration) { - if (!ce->checked) { - check_function_pointer(init_f, ce->tf); - } - } else if (ce->ct == callee_type::callee_indirect) { - // statistic - // indirect call - init_f->number_indirect_call++; - //yhao_log(1, "indirect call: " + init_f->get_entry_function_name()); - //yhao_log(1, "indirect call: " + dump_inst(ce->i)); - for (auto callee: *ce->tf_set) { - init_f->number_indirect_call_target_before++; - if (init_f->function_pointers.find(callee) == init_f->function_pointers.end()) { - continue; - } - init_f->number_indirect_call_target_after++; - //yhao_log(1, "indirect call target: " + callee->get_name()); - check_function_pointer(init_f, callee); - } - } - } + // skip if call chain is too long + // possible only for kvm + if (current_call_chain.size() > MAX_FUNC_DEPTH) { + return 0; + } - for (auto ce: t_f->all_callee) { - if (ce->ct == callee_type::function_pointer) { - // current, not handle order of function pointer in callee set - for (auto callee: *ce->tf_set) { - for (const auto &name: possible_name) { - if (callee->llvm_function->getName().contains(name)) { - check_function_pointer(init_f, callee); - } - } - } - } - } + if (init_f->count_function_pointer > MAX_CALLEE_COUNT) { + return 0; + } else { + init_f->count_function_pointer++; + } - current_call_chain.pop_back(); + auto path = get_file_name(t_f->llvm_function); + if (path.empty()) { return 0; + } + for (const auto &temp : skip_path) { + if (path.find(temp) == 0) { + return 0; + } + } + + if (debug > -1) { + yhao_log(debug, "current_call_chain: "); + for (auto temp : current_call_chain) { + yhao_log(debug, temp->get_name()); + } + } + + current_call_chain.push_back(t_f); + + for (auto ce : t_f->all_callee) { + if (ce->ct == callee_type::function_pointer) { + for (auto fp : *ce->tf_set) { + init_f->function_pointers.insert(fp); + } + } else if (ce->ct == callee_type::callee_not_isDeclaration) { + if (!ce->checked) { + check_function_pointer(init_f, ce->tf); + } + } else if (ce->ct == callee_type::callee_indirect) { + // statistic + // indirect call + init_f->number_indirect_call++; + // yhao_log(1, "indirect call: " + init_f->get_entry_function_name()); + // yhao_log(1, "indirect call: " + dump_inst(ce->i)); + for (auto callee : *ce->tf_set) { + init_f->number_indirect_call_target_before++; + if (init_f->function_pointers.find(callee) == + init_f->function_pointers.end()) { + continue; + } + init_f->number_indirect_call_target_after++; + // yhao_log(1, "indirect call target: " + callee->get_name()); + check_function_pointer(init_f, callee); + } + } + } + + for (auto ce : t_f->all_callee) { + if (ce->ct == callee_type::function_pointer) { + // current, not handle order of function pointer in callee set + for (auto callee : *ce->tf_set) { + for (const auto &name : possible_name) { + if (callee->llvm_function->getName().contains(name)) { + check_function_pointer(init_f, callee); + } + } + } + } + } + + current_call_chain.pop_back(); + return 0; } void sd::T_module::set_function_flag(llvm::Function *f, sd::init_flag flag) { - // reduce repeat work - if ((function_flag.find(f) != function_flag.end()) && (function_flag[f] & flag)) { - - } else { - function_flag[f] = flag; - if (!f->isDeclaration()) { - for (auto &cf: *(*this->cg)[f]) { - if (cf.second->getFunction() != nullptr) { - set_function_flag(cf.second->getFunction(), flag); - } - } - } - } + // reduce repeat work + if ((function_flag.find(f) != function_flag.end()) && + (function_flag[f] & flag)) { + } else { + function_flag[f] = flag; + if (!f->isDeclaration()) { + for (auto &cf : *(*this->cg)[f]) { + if (cf.second->getFunction() != nullptr) { + set_function_flag(cf.second->getFunction(), flag); + } + } + } + } } [[maybe_unused]] void sd::T_module::get_init_and_exit_function_number() { - uint64_t total_basic_block_number = 0; - std::cout << "this->llvm_module->size() : " << this->llvm_module->size() << std::endl; - for (auto &f: this->llvm_module->functions()) { - total_basic_block_number += f.size(); - } - std::cout << "total_basic_block_number : " << total_basic_block_number << std::endl; - - uint64_t total_init_basic_block_number = 0; - std::cout << "this->T_function.size() : " << this->init_function.size() << std::endl; - for (auto f: this->init_function) { - total_init_basic_block_number += f->size(); - } - std::cout << "total_init_basic_block_number : " << total_init_basic_block_number << std::endl; - - uint64_t total_exit_basic_block_number = 0; - std::cout << "this->exit_function.size() : " << this->exit_function.size() << std::endl; - for (auto f: this->exit_function) { - total_exit_basic_block_number += f->size(); - } - std::cout << "total_exit_basic_block_number : " << total_exit_basic_block_number << std::endl; - - for (auto f: this->init_function) { - set_function_flag(f, init_flag::INIT_FLAG_INIT_EXIT); - } - for (auto f: this->exit_function) { - set_function_flag(f, init_flag::INIT_FLAG_INIT_EXIT); + uint64_t total_basic_block_number = 0; + std::cout << "this->llvm_module->size() : " << this->llvm_module->size() + << std::endl; + for (auto &f : this->llvm_module->functions()) { + total_basic_block_number += f.size(); + } + std::cout << "total_basic_block_number : " << total_basic_block_number + << std::endl; + + uint64_t total_init_basic_block_number = 0; + std::cout << "this->T_function.size() : " << this->init_function.size() + << std::endl; + for (auto f : this->init_function) { + total_init_basic_block_number += f->size(); + } + std::cout << "total_init_basic_block_number : " + << total_init_basic_block_number << std::endl; + + uint64_t total_exit_basic_block_number = 0; + std::cout << "this->exit_function.size() : " << this->exit_function.size() + << std::endl; + for (auto f : this->exit_function) { + total_exit_basic_block_number += f->size(); + } + std::cout << "total_exit_basic_block_number : " + << total_exit_basic_block_number << std::endl; + + for (auto f : this->init_function) { + set_function_flag(f, init_flag::INIT_FLAG_INIT_EXIT); + } + for (auto f : this->exit_function) { + set_function_flag(f, init_flag::INIT_FLAG_INIT_EXIT); + } + for (auto &f : this->llvm_module->functions()) { + // do not set init T_function + if ((function_flag.find(&f) != function_flag.end()) && + (function_flag[&f] & init_flag::INIT_FLAG_INIT_EXIT)) { + } else { + set_function_flag(&f, init_flag::INIT_FLAG_OTHER); } - for (auto &f: this->llvm_module->functions()) { - // do not set init T_function - if ((function_flag.find(&f) != function_flag.end()) && - (function_flag[&f] & init_flag::INIT_FLAG_INIT_EXIT)) { + } - } else { - set_function_flag(&f, init_flag::INIT_FLAG_OTHER); - } + uint64_t total_init_exit_callee_basic_block_number = 0; + for (auto f : this->function_flag) { + if (f.second == init_flag::INIT_FLAG_INIT_EXIT) { + total_init_exit_callee_basic_block_number += f.first->size(); } - - uint64_t total_init_exit_callee_basic_block_number = 0; - for (auto f: this->function_flag) { - if (f.second == init_flag::INIT_FLAG_INIT_EXIT) { - total_init_exit_callee_basic_block_number += f.first->size(); - } - } - std::cout << "total_init_exit_callee_basic_block_number : " << total_init_exit_callee_basic_block_number - << std::endl; - + } + std::cout << "total_init_exit_callee_basic_block_number : " + << total_init_exit_callee_basic_block_number << std::endl; } // return the number of paths in the T_function, inter-procedural, -void sd::T_module::get_path_number(llvm::Function *f, std::set *call, uint64_t *path_number, - uint64_t *b_number) { - - if (f == nullptr || f->isDeclaration()) { - return; - } - - for (auto &b: *f) { - if (b.getTerminator()->getNumSuccessors() > 1) { - *b_number += 1; - } - } - get_path_number(&(f->getEntryBlock()), new std::set, path_number); - - for (auto &cf: *(*this->cg)[f]) { - if (cf.second->getFunction() != nullptr && !cf.second->getFunction()->isDeclaration()) { - if (call->find(cf.second->getFunction()) == call->end()) { - call->insert(cf.second->getFunction()); - - std::string name = cf.second->getFunction()->getName().str(); - if (no_path_functions.find(name) == no_path_functions.end()) { - get_path_number(cf.second->getFunction(), call, path_number, b_number); - } - } - } - } +void sd::T_module::get_path_number(llvm::Function *f, + std::set *call, + uint64_t *path_number, uint64_t *b_number) { + if (f == nullptr || f->isDeclaration()) { + return; + } + + for (auto &b : *f) { + if (b.getTerminator()->getNumSuccessors() > 1) { + *b_number += 1; + } + } + get_path_number(&(f->getEntryBlock()), new std::set, + path_number); + + for (auto &cf : *(*this->cg)[f]) { + if (cf.second->getFunction() != nullptr && + !cf.second->getFunction()->isDeclaration()) { + if (call->find(cf.second->getFunction()) == call->end()) { + call->insert(cf.second->getFunction()); + + std::string name = cf.second->getFunction()->getName().str(); + if (no_path_functions.find(name) == no_path_functions.end()) { + get_path_number(cf.second->getFunction(), call, path_number, + b_number); + } + } + } + } } -void -sd::T_module::get_path_number(llvm::BasicBlock *b, std::set *path, - uint64_t *path_number) { - if (b->getTerminator()->getNumSuccessors() == 0) { - path->clear(); - } else if (b->getTerminator()->getNumSuccessors() == 1) { - path->insert(b->getSingleSuccessor()); - get_path_number(b->getSingleSuccessor(), path, path_number); - } else if (b->getTerminator()->getNumSuccessors() == 2) { - if (path->find(b) == path->end() || path->find(b->getTerminator()->getSuccessor(0)) == path->end()) { - *path_number += 1; - auto *new_path = new std::set; - for (auto p: *path) { - new_path->insert(p); - } - path->insert(b->getTerminator()->getSuccessor(0)); - new_path->insert(b->getTerminator()->getSuccessor(1)); - get_path_number(b->getTerminator()->getSuccessor(0), path, path_number); - get_path_number(b->getTerminator()->getSuccessor(1), new_path, path_number); - } else { - // loop - path->insert(b->getTerminator()->getSuccessor(1)); - get_path_number(b->getTerminator()->getSuccessor(1), path, path_number); - } +void sd::T_module::get_path_number(llvm::BasicBlock *b, + std::set *path, + uint64_t *path_number) { + if (b->getTerminator()->getNumSuccessors() == 0) { + path->clear(); + } else if (b->getTerminator()->getNumSuccessors() == 1) { + path->insert(b->getSingleSuccessor()); + get_path_number(b->getSingleSuccessor(), path, path_number); + } else if (b->getTerminator()->getNumSuccessors() == 2) { + if (path->find(b) == path->end() || + path->find(b->getTerminator()->getSuccessor(0)) == path->end()) { + *path_number += 1; + auto *new_path = new std::set; + for (auto p : *path) { + new_path->insert(p); + } + path->insert(b->getTerminator()->getSuccessor(0)); + new_path->insert(b->getTerminator()->getSuccessor(1)); + get_path_number(b->getTerminator()->getSuccessor(0), path, path_number); + get_path_number(b->getTerminator()->getSuccessor(1), new_path, + path_number); } else { - *path_number += 1; + // loop + path->insert(b->getTerminator()->getSuccessor(1)); + get_path_number(b->getTerminator()->getSuccessor(1), path, path_number); } + } else { + *path_number += 1; + } } sd::T_function *sd::T_module::find_t_function(llvm::Function *f) { - if (this->t_functions.find(f) == this->t_functions.end()) { - yhao_log(3, "can not find function: " + f->getName().str()); - return nullptr; - } - return this->t_functions[f]; + if (this->t_functions.find(f) == this->t_functions.end()) { + yhao_log(3, "can not find function: " + f->getName().str()); + return nullptr; + } + return this->t_functions[f]; } diff --git a/lib/AnalysisLib/T_module.h b/lib/AnalysisLib/T_module.h index b0797a2..774180b 100644 --- a/lib/AnalysisLib/T_module.h +++ b/lib/AnalysisLib/T_module.h @@ -5,139 +5,125 @@ #ifndef INC_2021_TEMPLATE_T_MODULE_H #define INC_2021_TEMPLATE_T_MODULE_H +#include "../KnowledgeLib/device_driver.h" #include "../ToolLib/basic.h" #include "T_function.h" #include "entry_function.h" -#include "../KnowledgeLib/device_driver.h" namespace sd { - // init and exit T_function number - enum init_flag { - INIT_FLAG_INIT_EXIT = 1 << 1, - INIT_FLAG_OTHER = 1 << 2, - }; - - const static std::string module_init_name[]{ - "0", - "1", - "1s", - "2", - "2s", - "3", - "3s", - "4", - "4s", - "5", - "5s", - "6", - "6s", - "7", - "7s", - }; - static std::string module_name = "init_module"; - - class module_init_order { - public: - uint64_t order; - std::string name; - std::set *f; - }; - - // things at LLVM T_module level - class T_module { - public: - T_module(); - - virtual ~T_module(); - - void read_bitcode(const std::string &BitcodeFileName); - - std::string bitcode; - std::unique_ptr llvm_module; - llvm::CallGraph *cg{}; - std::string work_dir; - - knowledge *k{}; - // T_module: - std::map t_functions; - std::map module_init_function; - std::vector init_function; - std::vector exit_function; - std::set fp_in_init; +// init and exit T_function number +enum init_flag { + INIT_FLAG_INIT_EXIT = 1 << 1, + INIT_FLAG_OTHER = 1 << 2, +}; - T_function *find_t_function(llvm::Function *f); +const static std::string module_init_name[]{ + "0", "1", "1s", "2", "2s", "3", "3s", "4", + "4s", "5", "5s", "6", "6s", "7", "7s", +}; +static std::string module_name = "init_module"; - // check drivers and device in all functions - void analysis_functions(); +class module_init_order { + public: + uint64_t order; + std::string name; + std::set *f; +}; - void analysis_functions(T_function *f); +// things at LLVM T_module level +class T_module { + public: + T_module(); - void update_function(); + virtual ~T_module(); - void update_fp_in_init(); + void read_bitcode(const std::string &BitcodeFileName); + std::string bitcode; + std::unique_ptr llvm_module; + llvm::CallGraph *cg{}; + std::string work_dir; - // functions for indirect function call: - // number based indirect function call - std::unordered_map *> map_function_type; + knowledge *k{}; + // T_module: + std::map t_functions; + std::map module_init_function; + std::vector init_function; + std::vector exit_function; + std::set fp_in_init; - void type_based_indirect_functions(); + T_function *find_t_function(llvm::Function *f); - void MLTA_indirect_functions(); + // check drivers and device in all functions + void analysis_functions(); - void remove_init_from_indirect(); + void analysis_functions(T_function *f); - int64_t get_callee(llvm::Instruction *inst, std::set *targets); + void update_function(); - int64_t get_callee(llvm::Instruction *inst, std::set *targets, - std::set *fp = nullptr); + void update_fp_in_init(); - int64_t get_callee(llvm::Instruction *inst, std::set *targets, - std::set *fp = nullptr); + // functions for indirect function call: + // number based indirect function call + std::unordered_map *> + map_function_type; + void type_based_indirect_functions(); - int64_t find_ops_structure(const std::string &ops_structure, const std::string &ops_name, - llvm::GlobalVariable **ops) const; + void MLTA_indirect_functions(); - // analysis init&exit functions: - void find_module_init_function(); + void remove_init_from_indirect(); - void find_init_and_exit_function(); + int64_t get_callee(llvm::Instruction *inst, std::set *targets); - int64_t check_callee(T_function *t_f); + int64_t get_callee(llvm::Instruction *inst, + std::set *targets, + std::set *fp = nullptr); - int64_t check_caller(T_function *t_f); + int64_t get_callee(llvm::Instruction *inst, + std::set *targets, + std::set *fp = nullptr); - int64_t check_open(llvm::Function *f, std::vector *crs); + int64_t find_ops_structure(const std::string &ops_structure, + const std::string &ops_name, + llvm::GlobalVariable **ops) const; - std::vector current_call_chain; + // analysis init&exit functions: + void find_module_init_function(); - int64_t check_function_pointer(entry_function *init_f); + void find_init_and_exit_function(); - int64_t check_function_pointer(entry_function *init_f, T_function *t_f); + int64_t check_callee(T_function *t_f); - // init and exit T_function number - std::map function_flag; + int64_t check_caller(T_function *t_f); - void set_function_flag(llvm::Function *f, init_flag flag); + int64_t check_open(llvm::Function *f, std::vector *crs); - [[maybe_unused]] void get_init_and_exit_function_number(); + std::vector current_call_chain; + int64_t check_function_pointer(entry_function *init_f); - // get path number : - const std::set no_path_functions = {"vsnprintf", "format_decode"}; + int64_t check_function_pointer(entry_function *init_f, T_function *t_f); - void get_path_number(llvm::Function *f, std::set *call, uint64_t *path_number, - uint64_t *b_number); + // init and exit T_function number + std::map function_flag; - void get_path_number(llvm::BasicBlock *b, std::set *path, uint64_t *path_number); + void set_function_flag(llvm::Function *f, init_flag flag); + [[maybe_unused]] void get_init_and_exit_function_number(); - }; + // get path number : + const std::set no_path_functions = {"vsnprintf", + "format_decode"}; + void get_path_number(llvm::Function *f, std::set *call, + uint64_t *path_number, uint64_t *b_number); -} + void get_path_number(llvm::BasicBlock *b, std::set *path, + uint64_t *path_number); +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_T_MODULE_H +#endif // INC_2021_TEMPLATE_T_MODULE_H diff --git a/lib/AnalysisLib/entry_function.cpp b/lib/AnalysisLib/entry_function.cpp index f0a2c31..3d28e01 100644 --- a/lib/AnalysisLib/entry_function.cpp +++ b/lib/AnalysisLib/entry_function.cpp @@ -3,184 +3,192 @@ // #include "entry_function.h" -#include "../ToolLib/log.h" + #include "../ToolLib/llvm_related.h" +#include "../ToolLib/log.h" sd::entry_function::entry_function() = default; sd::entry_function::entry_function(sd::T_function *t_function) { - this->t_function = t_function; + this->t_function = t_function; } void sd::entry_function::reset() { - for (auto c: this->all_checker_results) { - delete c; - } - this->all_checker_results.clear(); - for (auto v: this->checker_results) { - delete v.second; - } - this->checker_results.clear(); - count_update_checker = 0; + for (auto c : this->all_checker_results) { + delete c; + } + this->all_checker_results.clear(); + for (auto v : this->checker_results) { + delete v.second; + } + this->checker_results.clear(); + count_update_checker = 0; } // only update checker from callee void sd::entry_function::update_checker_results() { - int64_t debug = 0; - reset(); - yhao_log(debug, "****update_checker_results(t_function); start*****************"); - update_checker_results(t_function); - yhao_log(debug, "****update_checker_results(t_function); end*******************"); - for (auto cr: all_checker_results) { - cr->compute_hash(); - } + int64_t debug = 0; + reset(); + yhao_log(debug, + "****update_checker_results(t_function); start*****************"); + update_checker_results(t_function); + yhao_log(debug, + "****update_checker_results(t_function); end*******************"); + for (auto cr : all_checker_results) { + cr->compute_hash(); + } } void sd::entry_function::update_checker_results(T_function *t_f) { - int64_t debug = -1; - - // skip if call chain is too long - // possible only for kvm - if (current_call_chain.size() > MAX_FUNC_DEPTH) { - return; - } - if (count_update_checker > MAX_CALLEE_COUNT) { - return; - } else { - count_update_checker++; + int64_t debug = -1; + + // skip if call chain is too long + // possible only for kvm + if (current_call_chain.size() > MAX_FUNC_DEPTH) { + return; + } + if (count_update_checker > MAX_CALLEE_COUNT) { + return; + } else { + count_update_checker++; + } + + auto path = get_file_name(t_f->llvm_function); + if (path.empty()) { + return; + } + for (const auto &temp : skip_path) { + if (path.find(temp) == 0) { + return; } + } - auto path = get_file_name(t_f->llvm_function); - if (path.empty()) { - return; + std::string real_name = get_real_function_name(t_f->llvm_function); + for (auto temp : current_call_chain) { + if (get_real_function_name(temp->getFunction()) == real_name) { + yhao_log(debug, "update_checker_results checked: " + t_f->get_name()); + return; } - for(const auto& temp : skip_path) { - if (path.find(temp) == 0) { - return; - } + } + + yhao_log(debug, "update_checker_results start: " + t_f->get_name()); + yhao_log(debug, "checker_results: " + std::to_string(checker_results.size())); + for (auto cr : t_f->checker_results) { + auto cr1 = cr->copy(); + for (auto i : current_call_chain) { + cr1->push_call_chain(i); } - - std::string real_name = get_real_function_name(t_f->llvm_function); - for (auto temp: current_call_chain) { - if (get_real_function_name(temp->getFunction()) == real_name) { - yhao_log(debug, "update_checker_results checked: " + t_f->get_name()); - return; - } + cr1->has_function_pointer = in_function_pointer; + cr1->push_call_chain(cr1->inst); + this->all_checker_results.push_back(cr1); + if (this->checker_results.find(cr1->ct) == this->checker_results.end()) { + this->checker_results[cr1->ct] = new std::vector; } - - yhao_log(debug, "update_checker_results start: " + t_f->get_name()); - yhao_log(debug, "checker_results: " + std::to_string(checker_results.size())); - for (auto cr: t_f->checker_results) { - auto cr1 = cr->copy(); - for (auto i: current_call_chain) { - cr1->push_call_chain(i); + checker_results[cr1->ct]->push_back(cr1); + } + + yhao_log(debug, "all_callee_checker_results: " + + std::to_string(t_f->all_callee_checker_results.size())); + for (auto t_f_set : t_f->all_callee_checker_results) { + current_call_chain.push_back(t_f_set.first); + for (auto callee_t_f : *t_f_set.second) { + yhao_log(debug, + "callee: " + t_f->get_name() + ": " + callee_t_f->get_name()); + bool is_pointer = false; + // try to find callee + if (t_f->all_callee_map.find(t_f_set.first) == + t_f->all_callee_map.end()) { + // callee_type::function_pointer + is_pointer = true; + } else { + // other callee + auto ce = t_f->all_callee_map[t_f_set.first]; + if (ce->ct == callee_type::callee_not_isDeclaration) { + if (ce->tf != callee_t_f) { + // callee_type::function_pointer + is_pointer = true; + } + } else if (ce->ct == callee_type::callee_isDeclaration) { + if (ce->tf != callee_t_f) { + // callee_type::function_pointer + is_pointer = true; + } + } else if (ce->ct == callee_type::callee_indirect) { + if (ce->tf_set->find(callee_t_f) == ce->tf_set->end()) { + // callee_type::function_pointer + is_pointer = true; + } else { + if (this->function_pointers.find(callee_t_f) == + this->function_pointers.end()) { + continue; + } + } + } else if (ce->ct == callee_type::function_pointer) { + if (ce->tf_set->find(callee_t_f) != ce->tf_set->end()) { + // callee_type::function_pointer + is_pointer = true; + } } - cr1->has_function_pointer = in_function_pointer; - cr1->push_call_chain(cr1->inst); - this->all_checker_results.push_back(cr1); - if (this->checker_results.find(cr1->ct) == this->checker_results.end()) { - this->checker_results[cr1->ct] = new std::vector; + } + if (is_pointer) { + // callee_type::function_pointer + bool check = false; + for (const auto &name : possible_name) { + if (callee_t_f->llvm_function->getName().contains(name)) { + check = true; + } } - checker_results[cr1->ct]->push_back(cr1); - } - - yhao_log(debug, "all_callee_checker_results: " + std::to_string(t_f->all_callee_checker_results.size())); - for (auto t_f_set: t_f->all_callee_checker_results) { - current_call_chain.push_back(t_f_set.first); - for (auto callee_t_f: *t_f_set.second) { - yhao_log(debug, "callee: " + t_f->get_name() + ": " + callee_t_f->get_name()); - bool is_pointer = false; - // try to find callee - if (t_f->all_callee_map.find(t_f_set.first) == t_f->all_callee_map.end()) { - // callee_type::function_pointer - is_pointer = true; - } else { - // other callee - auto ce = t_f->all_callee_map[t_f_set.first]; - if (ce->ct == callee_type::callee_not_isDeclaration) { - if (ce->tf != callee_t_f) { - // callee_type::function_pointer - is_pointer = true; - } - } else if (ce->ct == callee_type::callee_isDeclaration) { - if (ce->tf != callee_t_f) { - // callee_type::function_pointer - is_pointer = true; - } - } else if (ce->ct == callee_type::callee_indirect) { - if (ce->tf_set->find(callee_t_f) == ce->tf_set->end()) { - // callee_type::function_pointer - is_pointer = true; - } else { - if (this->function_pointers.find(callee_t_f) == this->function_pointers.end()) { - continue; - } - } - } else if (ce->ct == callee_type::function_pointer) { - if (ce->tf_set->find(callee_t_f) != ce->tf_set->end()) { - // callee_type::function_pointer - is_pointer = true; - } - } - } - if (is_pointer) { - // callee_type::function_pointer - bool check = false; - for(const auto& name : possible_name) { - if (callee_t_f->llvm_function->getName().contains(name)) { - check = true; - } - } - if (!check) { - continue; - } - } else { - - } + if (!check) { + continue; + } + } else { + } - // statistic - bool old_in_function_pointer = in_function_pointer; - if (is_pointer) { - in_function_pointer = true; - } + // statistic + bool old_in_function_pointer = in_function_pointer; + if (is_pointer) { + in_function_pointer = true; + } - update_checker_results(callee_t_f); + update_checker_results(callee_t_f); - if (is_pointer) { - in_function_pointer = old_in_function_pointer; - } - } - current_call_chain.pop_back(); + if (is_pointer) { + in_function_pointer = old_in_function_pointer; + } } - yhao_log(debug, "update_checker_results end: " + t_f->get_name()); + current_call_chain.pop_back(); + } + yhao_log(debug, "update_checker_results end: " + t_f->get_name()); } -int64_t sd::entry_function::get_checker_results(sd::checker_type ct, std::vector *crs) { - if (this->checker_results.find(ct) == this->checker_results.end()) { - return 1; - } - for (auto cr: *(this->checker_results[ct])) { - crs->push_back(cr); - } - return 0; +int64_t sd::entry_function::get_checker_results( + sd::checker_type ct, std::vector *crs) { + if (this->checker_results.find(ct) == this->checker_results.end()) { + return 1; + } + for (auto cr : *(this->checker_results[ct])) { + crs->push_back(cr); + } + return 0; } int64_t sd::entry_function::get_device_driver_kind() { - yhao_log(1, "all checker result start: " + this->get_entry_function_name()); - yhao_log(1, "all checker size: " + std::to_string(this->all_checker_results.size())); - int64_t ret = 0; - for (auto cr: this->all_checker_results) { - yhao_log(1, "checker result: \n" + cr->print()); - ret |= 1 << cr->ct; - } - yhao_log(1, "all checker result end: " + this->get_entry_function_name()); - return ret; + yhao_log(1, "all checker result start: " + this->get_entry_function_name()); + yhao_log(1, "all checker size: " + + std::to_string(this->all_checker_results.size())); + int64_t ret = 0; + for (auto cr : this->all_checker_results) { + yhao_log(1, "checker result: \n" + cr->print()); + ret |= 1 << cr->ct; + } + yhao_log(1, "all checker result end: " + this->get_entry_function_name()); + return ret; } llvm::Function *sd::entry_function::get_entry_function() const { - return this->t_function->llvm_function; + return this->t_function->llvm_function; } std::string sd::entry_function::get_entry_function_name() const { - return this->get_entry_function()->getName().str(); + return this->get_entry_function()->getName().str(); } diff --git a/lib/AnalysisLib/entry_function.h b/lib/AnalysisLib/entry_function.h index d55974a..e0e5fd5 100644 --- a/lib/AnalysisLib/entry_function.h +++ b/lib/AnalysisLib/entry_function.h @@ -8,76 +8,70 @@ #include "T_function.h" namespace sd { - class device_driver; +class device_driver; - const static std::string possible_name[] = { - "probe", - "init", - "register", - "connect", - "notifier", - "client", - "add", - }; +const static std::string possible_name[] = { + "probe", "init", "register", "connect", "notifier", "client", "add", +}; - const static std::string skip_path[] = { - "./include", - "./arch/x86/include", - "./arch/x86/boot", - "./arch/x86/kernel/../include", - "arch/x86/boot", - "arch/x86/event", - "lib/", - "kernel/", - "./security", - }; +const static std::string skip_path[] = { + "./include", + "./arch/x86/include", + "./arch/x86/boot", + "./arch/x86/kernel/../include", + "arch/x86/boot", + "arch/x86/event", + "lib/", + "kernel/", + "./security", +}; - class entry_function { - public: - entry_function(); +class entry_function { + public: + entry_function(); - explicit entry_function(T_function *t_function); + explicit entry_function(T_function *t_function); - // analysis - public: - T_function *t_function{}; - std::vector all_checker_results; - // real checker number, e.g. checker_result_number - std::map *> checker_results; + // analysis + public: + T_function *t_function{}; + std::vector all_checker_results; + // real checker number, e.g. checker_result_number + std::map *> checker_results; - device_driver *parent = nullptr; - bool is_init = true; + device_driver *parent = nullptr; + bool is_init = true; - std::vector current_call_chain; - std::set function_pointers; - std::set checked_function; + std::vector current_call_chain; + std::set function_pointers; + std::set checked_function; - // statistic - // indirect call - uint64_t number_indirect_call = 0; - uint64_t number_indirect_call_target_before = 0; - uint64_t number_indirect_call_target_after = 0; + // statistic + // indirect call + uint64_t number_indirect_call = 0; + uint64_t number_indirect_call_target_before = 0; + uint64_t number_indirect_call_target_after = 0; - bool in_function_pointer = false; + bool in_function_pointer = false; + uint64_t count_update_checker = 0; + uint64_t count_function_pointer = 0; - uint64_t count_update_checker = 0; - uint64_t count_function_pointer = 0; + void reset(); - void reset(); + void update_checker_results(); - void update_checker_results(); + void update_checker_results(T_function *t_f); - void update_checker_results(T_function *t_f); + int64_t get_device_driver_kind(); - int64_t get_device_driver_kind(); + int64_t get_checker_results(checker_type ct, + std::vector *crs); - int64_t get_checker_results(checker_type ct, std::vector *crs); + [[nodiscard]] llvm::Function *get_entry_function() const; - [[nodiscard]] llvm::Function *get_entry_function() const; + [[nodiscard]] std::string get_entry_function_name() const; +}; +} // namespace sd - [[nodiscard]] std::string get_entry_function_name() const; - }; -} - -#endif //INC_2021_TEMPLATE_ENTRY_FUNCTION_H +#endif // INC_2021_TEMPLATE_ENTRY_FUNCTION_H diff --git a/lib/AnalysisLib/ioctl_cmd_type.cpp b/lib/AnalysisLib/ioctl_cmd_type.cpp index 4130223..300a99e 100644 --- a/lib/AnalysisLib/ioctl_cmd_type.cpp +++ b/lib/AnalysisLib/ioctl_cmd_type.cpp @@ -4,738 +4,739 @@ #include "ioctl_cmd_type.h" -#include "../ToolLib/log.h" #include "../ToolLib/llvm_related.h" +#include "../ToolLib/log.h" -sd::ioctl_cmd_type::ioctl_cmd_type(llvm::Function *tf, - std::set cmd, - std::set type, - device_driver *dd, +sd::ioctl_cmd_type::ioctl_cmd_type(llvm::Function *tf, std::set cmd, + std::set type, device_driver *dd, T_module *tm, std::set *fps) { - this->target_function = tf; - this->DT = new llvm::DominatorTree(*target_function); - uint64_t function_arg_index = 0; - for (auto &function_arg: target_function->args()) { - if (cmd.find(function_arg_index) != cmd.end()) { - all_cmd_inst.insert(&function_arg); - } - if (type.find(function_arg_index) != type.end()) { - all_type_inst.insert(&function_arg); - } - function_arg_index++; + this->target_function = tf; + this->DT = new llvm::DominatorTree(*target_function); + uint64_t function_arg_index = 0; + for (auto &function_arg : target_function->args()) { + if (cmd.find(function_arg_index) != cmd.end()) { + all_cmd_inst.insert(&function_arg); + } + if (type.find(function_arg_index) != type.end()) { + all_type_inst.insert(&function_arg); } - update_cmd_and_type(); + function_arg_index++; + } + update_cmd_and_type(); - this->tm = tm; - this->fps = fps; - this->dd = dd; + this->tm = tm; + this->fps = fps; + this->dd = dd; } -sd::ioctl_cmd_type::ioctl_cmd_type(llvm::Function *tf, - std::set cmd, - std::set type, - sd::ioctl_cmd_type *caller, - std::map caller_arguments) { - for (auto ci: caller->call_stack) { - this->call_stack.push_back(ci); +sd::ioctl_cmd_type::ioctl_cmd_type( + llvm::Function *tf, std::set cmd, std::set type, + sd::ioctl_cmd_type *caller, + std::map caller_arguments) { + for (auto ci : caller->call_stack) { + this->call_stack.push_back(ci); + } + this->target_function = tf; + this->DT = new llvm::DominatorTree(*target_function); + uint64_t function_arg_index = 0; + for (auto &function_arg : target_function->args()) { + if (cmd.find(function_arg_index) != cmd.end()) { + all_cmd_inst.insert(&function_arg); } - this->target_function = tf; - this->DT = new llvm::DominatorTree(*target_function); - uint64_t function_arg_index = 0; - for (auto &function_arg: target_function->args()) { - if (cmd.find(function_arg_index) != cmd.end()) { - all_cmd_inst.insert(&function_arg); - } - if (type.find(function_arg_index) != type.end()) { - all_type_inst.insert(&function_arg); - } - if (caller_arguments.find(function_arg_index) != caller_arguments.end()) { - this->caller_args[&function_arg] = caller_arguments[function_arg_index]; - } - function_arg_index++; + if (type.find(function_arg_index) != type.end()) { + all_type_inst.insert(&function_arg); } - update_cmd_and_type(); - - assert(caller != nullptr); - this->tm = caller->tm; - this->fps = caller->fps; - this->dd = caller->dd; - this->current_cmd = caller->current_cmd; - this->only_type = caller->only_type; - this->curr_func_depth = caller->curr_func_depth + 1; - this->caller = caller; + if (caller_arguments.find(function_arg_index) != caller_arguments.end()) { + this->caller_args[&function_arg] = caller_arguments[function_arg_index]; + } + function_arg_index++; + } + update_cmd_and_type(); + + assert(caller != nullptr); + this->tm = caller->tm; + this->fps = caller->fps; + this->dd = caller->dd; + this->current_cmd = caller->current_cmd; + this->only_type = caller->only_type; + this->curr_func_depth = caller->curr_func_depth + 1; + this->caller = caller; } sd::ioctl_cmd_type::~ioctl_cmd_type() = default; -void sd::ioctl_cmd_type::set_only_type_module() { - this->only_type = true; -} +void sd::ioctl_cmd_type::set_only_type_module() { this->only_type = true; } -void sd::ioctl_cmd_type::unset_only_type_module() { - this->only_type = false; -} +void sd::ioctl_cmd_type::unset_only_type_module() { this->only_type = false; } void sd::ioctl_cmd_type::run_cmd() { - int64_t debug = -1; - std::string str; - - std::set < llvm::BasicBlock * > all_bb; - for (auto &bb: *target_function) { - all_bb.insert(&bb); - } - while (!all_bb.empty()) { - auto bb = *all_bb.begin(); - all_bb.erase(bb); - for (auto &i: *bb) { - switch (i.getOpcode()) { - case llvm::Instruction::Call: { - auto ci = llvm::dyn_cast(&i); - yhao_log(debug, "llvm::Instruction::Call"); - yhao_dump(debug, i.print, str) - check_call_cmd(ci); - break; - } - case llvm::Instruction::Switch: { - yhao_dump(debug, i.print, str) - auto si = llvm::dyn_cast(&i); - auto targetSwitchCond = si->getCondition(); - std::set < llvm::BasicBlock * > visited_in_switch; - if (!this->is_cmd_affected(targetSwitchCond)) { - yhao_log(debug, "is_cmd_affected: false"); - break; - } - for (auto cis = si->case_begin(), cie = si->case_end(); cis != cie; cis++) { - auto cmd_val = cis->getCaseValue(); - auto sb = cis->getCaseSuccessor(); - std::set < llvm::BasicBlock * > visited_in_cmd; - auto cmd_value = cmd_val->getValue().getZExtValue(); - yhao_log(debug, "Found Cmd:" + std::to_string(cmd_value) + ":START"); - if (this->dd->cmd.find(cmd_value) != this->dd->cmd.end()) { - - } else { - auto temp = new class cmd_info(); - temp->i = si; - temp->value = cmd_value; - temp->b = sb; - temp->in_entry_function = (this->caller == nullptr); - temp->in_indirect_call = this->in_indirect_call; - this->dd->cmd[cmd_value] = temp; - } - this->current_cmd = this->dd->cmd[cmd_value]; - run_type(sb); - yhao_log(debug, "Found Cmd:" + std::to_string(cmd_value) + ":END"); - uint64_t num = 0; - for (auto p: predecessors(sb)) { - num++; - } - if (num == 1) { - std::set < llvm::BasicBlock * > temp; - temp.insert(sb); - get_dom_bb(sb, &temp); - for (auto temp_b: temp) { - if (all_bb.find(temp_b) != all_bb.end()) { - all_bb.erase(temp_b); - } - } - } - } - break; - } - case llvm::Instruction::ICmp: { - auto icmp = llvm::dyn_cast(&i); - if (icmp->isEquality()) { - auto *op1 = icmp->getOperand(0); - auto *op2 = icmp->getOperand(1); - llvm::Value *icmp_value = nullptr; - if (this->is_cmd_affected(op1)) { - icmp_value = op2; - } else if (this->is_cmd_affected(op2)) { - icmp_value = op1; - } - if (icmp_value != nullptr) { - this->curr_cmd = icmp_value; - } - } - break; - } - case llvm::Instruction::Br: { - if (this->curr_cmd == nullptr) { - break; - } - auto *c_int = llvm::dyn_cast(this->curr_cmd); - this->curr_cmd = nullptr; - if (c_int == nullptr) { - break; - } - yhao_log(debug, "Found Cmd:" + std::to_string(c_int->getZExtValue()) + " (BR): START"); - auto cmd_value = c_int->getZExtValue(); - auto bi = llvm::dyn_cast(&i); - auto sb = bi->getSuccessor(0); - if (this->dd->cmd.find(cmd_value) != this->dd->cmd.end()) { - - } else { - auto temp = new class cmd_info(); - temp->i = bi; - temp->value = cmd_value; - temp->b = sb; - temp->in_entry_function = (this->caller == nullptr); - temp->in_indirect_call = this->in_indirect_call; - this->dd->cmd[cmd_value] = temp; - } - this->current_cmd = this->dd->cmd[cmd_value]; - run_type(sb); - yhao_log(debug, "Found Cmd:" + std::to_string(c_int->getZExtValue()) + " (BR): END"); - - uint64_t num = 0; - for ([[maybe_unused]] auto p: predecessors(sb)) { - num++; - } - if (num == 1) { - std::set < llvm::BasicBlock * > temp; - temp.insert(sb); - get_dom_bb(sb, &temp); - for (auto temp_b: temp) { - if (all_bb.find(temp_b) != all_bb.end()) { - all_bb.erase(temp_b); - } - } - } - break; - } - default: { - + int64_t debug = -1; + std::string str; + + std::set all_bb; + for (auto &bb : *target_function) { + all_bb.insert(&bb); + } + while (!all_bb.empty()) { + auto bb = *all_bb.begin(); + all_bb.erase(bb); + for (auto &i : *bb) { + switch (i.getOpcode()) { + case llvm::Instruction::Call: { + auto ci = llvm::dyn_cast(&i); + yhao_log(debug, "llvm::Instruction::Call"); + yhao_dump(debug, i.print, str) check_call_cmd(ci); + break; + } + case llvm::Instruction::Switch: { + yhao_dump(debug, i.print, str) auto si = + llvm::dyn_cast(&i); + auto targetSwitchCond = si->getCondition(); + std::set visited_in_switch; + if (!this->is_cmd_affected(targetSwitchCond)) { + yhao_log(debug, "is_cmd_affected: false"); + break; + } + for (auto cis = si->case_begin(), cie = si->case_end(); cis != cie; + cis++) { + auto cmd_val = cis->getCaseValue(); + auto sb = cis->getCaseSuccessor(); + std::set visited_in_cmd; + auto cmd_value = cmd_val->getValue().getZExtValue(); + yhao_log(debug, + "Found Cmd:" + std::to_string(cmd_value) + ":START"); + if (this->dd->cmd.find(cmd_value) != this->dd->cmd.end()) { + } else { + auto temp = new class cmd_info(); + temp->i = si; + temp->value = cmd_value; + temp->b = sb; + temp->in_entry_function = (this->caller == nullptr); + temp->in_indirect_call = this->in_indirect_call; + this->dd->cmd[cmd_value] = temp; + } + this->current_cmd = this->dd->cmd[cmd_value]; + run_type(sb); + yhao_log(debug, "Found Cmd:" + std::to_string(cmd_value) + ":END"); + uint64_t num = 0; + for (auto p : predecessors(sb)) { + num++; + } + if (num == 1) { + std::set temp; + temp.insert(sb); + get_dom_bb(sb, &temp); + for (auto temp_b : temp) { + if (all_bb.find(temp_b) != all_bb.end()) { + all_bb.erase(temp_b); } + } + } + } + break; + } + case llvm::Instruction::ICmp: { + auto icmp = llvm::dyn_cast(&i); + if (icmp->isEquality()) { + auto *op1 = icmp->getOperand(0); + auto *op2 = icmp->getOperand(1); + llvm::Value *icmp_value = nullptr; + if (this->is_cmd_affected(op1)) { + icmp_value = op2; + } else if (this->is_cmd_affected(op2)) { + icmp_value = op1; + } + if (icmp_value != nullptr) { + this->curr_cmd = icmp_value; + } + } + break; + } + case llvm::Instruction::Br: { + if (this->curr_cmd == nullptr) { + break; + } + auto *c_int = llvm::dyn_cast(this->curr_cmd); + this->curr_cmd = nullptr; + if (c_int == nullptr) { + break; + } + yhao_log(debug, "Found Cmd:" + std::to_string(c_int->getZExtValue()) + + " (BR): START"); + auto cmd_value = c_int->getZExtValue(); + auto bi = llvm::dyn_cast(&i); + auto sb = bi->getSuccessor(0); + if (this->dd->cmd.find(cmd_value) != this->dd->cmd.end()) { + } else { + auto temp = new class cmd_info(); + temp->i = bi; + temp->value = cmd_value; + temp->b = sb; + temp->in_entry_function = (this->caller == nullptr); + temp->in_indirect_call = this->in_indirect_call; + this->dd->cmd[cmd_value] = temp; + } + this->current_cmd = this->dd->cmd[cmd_value]; + run_type(sb); + yhao_log(debug, "Found Cmd:" + std::to_string(c_int->getZExtValue()) + + " (BR): END"); + + uint64_t num = 0; + for ([[maybe_unused]] auto p : predecessors(sb)) { + num++; + } + if (num == 1) { + std::set temp; + temp.insert(sb); + get_dom_bb(sb, &temp); + for (auto temp_b : temp) { + if (all_bb.find(temp_b) != all_bb.end()) { + all_bb.erase(temp_b); + } } + } + break; } + default: { + } + } } + } } void sd::ioctl_cmd_type::run_type(llvm::BasicBlock *start_bb) { - std::set < llvm::BasicBlock * > all_bb; - if (start_bb == &target_function->getEntryBlock()) { - for (auto &bb: *target_function) { - all_bb.insert(&bb); - } - } else { - for (auto &bb: *target_function) { - if (llvm::isPotentiallyReachable(start_bb, &bb, nullptr, this->DT)) { - all_bb.insert(&bb); - } - } + std::set all_bb; + if (start_bb == &target_function->getEntryBlock()) { + for (auto &bb : *target_function) { + all_bb.insert(&bb); } + } else { + for (auto &bb : *target_function) { + if (llvm::isPotentiallyReachable(start_bb, &bb, nullptr, this->DT)) { + all_bb.insert(&bb); + } + } + } - while (!all_bb.empty()) { - auto bb = *all_bb.begin(); - all_bb.erase(bb); - for (auto &i: *bb) { - switch (i.getOpcode()) { - case llvm::Instruction::Call: { - auto ci = llvm::dyn_cast(&i); - check_call_type(ci); - break; - } - default: { - - } - } + while (!all_bb.empty()) { + auto bb = *all_bb.begin(); + all_bb.erase(bb); + for (auto &i : *bb) { + switch (i.getOpcode()) { + case llvm::Instruction::Call: { + auto ci = llvm::dyn_cast(&i); + check_call_type(ci); + break; + } + default: { } + } } + } } bool sd::ioctl_cmd_type::is_cmd_affected(llvm::Value *targetValue) { - if (all_cmd_inst.find(targetValue) == all_cmd_inst.end()) { - return all_cmd_inst.find(targetValue->stripPointerCasts()) != all_cmd_inst.end(); - } - return true; + if (all_cmd_inst.find(targetValue) == all_cmd_inst.end()) { + return all_cmd_inst.find(targetValue->stripPointerCasts()) != + all_cmd_inst.end(); + } + return true; } bool sd::ioctl_cmd_type::is_type_affected(llvm::Value *targetValue) { - if (all_type_inst.find(targetValue) == all_type_inst.end()) { - return all_type_inst.find(targetValue->stripPointerCasts()) != all_type_inst.end(); - } - return true; + if (all_type_inst.find(targetValue) == all_type_inst.end()) { + return all_type_inst.find(targetValue->stripPointerCasts()) != + all_type_inst.end(); + } + return true; } void sd::ioctl_cmd_type::update_cmd_and_type() { - for (auto &bb: *target_function) { - for (auto &i: bb) { - if (i.getOpcode() == llvm::Instruction::Call) { - continue; + for (auto &bb : *target_function) { + for (auto &i : bb) { + if (i.getOpcode() == llvm::Instruction::Call) { + continue; + } + llvm::Value *storePtrArg = nullptr; + if (i.getOpcode() == llvm::Instruction::Store) { + storePtrArg = llvm::dyn_cast(&i) + ->getPointerOperand() + ->stripPointerCasts(); + } + for (auto index = 0; index < i.getNumOperands(); index++) { + auto *currValue = i.getOperand(index); + if (currValue != nullptr) { + auto *strippedValue = currValue->stripPointerCasts(); + if (all_cmd_inst.find(currValue) != all_cmd_inst.end() || + all_cmd_inst.find(strippedValue) != all_cmd_inst.end()) { + if (all_cmd_inst.find(&i) == all_cmd_inst.end()) { + all_cmd_inst.insert(&i); } - llvm::Value *storePtrArg = nullptr; - if (i.getOpcode() == llvm::Instruction::Store) { - storePtrArg = llvm::dyn_cast(&i)->getPointerOperand()->stripPointerCasts(); + if (storePtrArg != nullptr) { + if (all_cmd_inst.find(storePtrArg) == all_cmd_inst.end()) { + all_cmd_inst.insert(storePtrArg); + } + } + } + if (all_type_inst.find(currValue) != all_type_inst.end() || + all_type_inst.find(strippedValue) != all_type_inst.end()) { + if (all_type_inst.find(&i) == all_type_inst.end()) { + all_type_inst.insert(&i); } - for (auto index = 0; index < i.getNumOperands(); index++) { - auto *currValue = i.getOperand(index); - if (currValue != nullptr) { - auto *strippedValue = currValue->stripPointerCasts(); - if (all_cmd_inst.find(currValue) != all_cmd_inst.end() || - all_cmd_inst.find(strippedValue) != all_cmd_inst.end()) { - if (all_cmd_inst.find(&i) == all_cmd_inst.end()) { - all_cmd_inst.insert(&i); - - } - if (storePtrArg != nullptr) { - if (all_cmd_inst.find(storePtrArg) == all_cmd_inst.end()) { - all_cmd_inst.insert(storePtrArg); - } - } - } - if (all_type_inst.find(currValue) != all_type_inst.end() || - all_type_inst.find(strippedValue) != all_type_inst.end()) { - if (all_type_inst.find(&i) == all_type_inst.end()) { - all_type_inst.insert(&i); - } - - if (storePtrArg != nullptr) { - if (all_type_inst.find(storePtrArg) == all_type_inst.end()) { - all_type_inst.insert(storePtrArg); - } - } - } - - } + if (storePtrArg != nullptr) { + if (all_type_inst.find(storePtrArg) == all_type_inst.end()) { + all_type_inst.insert(storePtrArg); + } } + } } + } } + } } void sd::ioctl_cmd_type::check_call_cmd(llvm::CallInst *ci) { - int64_t debug = -1; - std::string str; - yhao_print(debug, ci->print, str) - yhao_log(debug, "check_call_cmd: " + str); - - std::set < llvm::Function * > targets; - - if (ci->isInlineAsm()) { - return; - } - if (this->tm == nullptr) { - return; - } - - if (ci->isIndirectCall()) { - this->tm->get_callee(ci, &targets, this->fps); + int64_t debug = -1; + std::string str; + yhao_print(debug, ci->print, str) yhao_log(debug, "check_call_cmd: " + str); + + std::set targets; + + if (ci->isInlineAsm()) { + return; + } + if (this->tm == nullptr) { + return; + } + + if (ci->isIndirectCall()) { + this->tm->get_callee(ci, &targets, this->fps); + } else { + targets.insert(get_target_function(ci->getCalledOperand())); + } + + for (auto target : targets) { + if (target->isDeclaration()) { } else { - targets.insert(get_target_function(ci->getCalledOperand())); - } - - for (auto target: targets) { - if (target->isDeclaration()) { - - } else { - check_callee(ci, target); - } + check_callee(ci, target); } + } } void sd::ioctl_cmd_type::check_callee(llvm::CallInst *ci, llvm::Function *tf) { - std::string str; - int64_t debug = -1; - yhao_print(debug, ci->print, str) - yhao_log(debug, "check_callee: " + std::to_string(this->only_type) + ": " + str); - yhao_log(debug, tf->getName().str()); - - if (this->count_callee > MAX_CALLEE_COUNT) { - return; - } else { - this->count_callee++; - } - if (this->curr_func_depth > MAX_FUNC_DEPTH) { - return; - } - // we need to follow the called function, only if this is not recursive. - if (std::find(this->call_stack.begin(), this->call_stack.end(), ci) == this->call_stack.end()) { - std::vector < llvm::CallInst * > new_call_stack; - new_call_stack.insert(new_call_stack.end(), this->call_stack.begin(), this->call_stack.end()); - new_call_stack.insert(new_call_stack.end(), ci); - std::set cmd; - std::set type; - std::map < uint64_t, llvm::Value * > new_caller_args; - // get propagation info - this->get_arg_propagation(ci, cmd, type, new_caller_args); - - // handle bit cast in function call - if (false && this->only_type && !type.empty()) { - yhao_log(debug, "only_type: check function call:"); - yhao_dump(debug, ci->print, str) - for (auto index: type) { - yhao_log(debug, "index: " + std::to_string(index)); - auto targetOperand = tf->getArg(index); - if (targetOperand != nullptr) { - yhao_dump(debug, targetOperand->print, str) - - llvm::Type *temp_t; - temp_t = targetOperand->getType(); - if (temp_t->isPointerTy() && temp_t->getNumContainedTypes()) { - temp_t = temp_t->getNonOpaquePointerElementType(); - } - - yhao_print(-1, temp_t->print, str) - if (str == "i1" || str == "i8" || str == "i16" || str == "i32" || str == "i64") { - continue; - } - if (current_cmd == nullptr) { - continue; - } - current_cmd->in_types[ci] = temp_t; - } - } - } + std::string str; + int64_t debug = -1; + yhao_print(debug, ci->print, str) yhao_log( + debug, "check_callee: " + std::to_string(this->only_type) + ": " + str); + yhao_log(debug, tf->getName().str()); + + if (this->count_callee > MAX_CALLEE_COUNT) { + return; + } else { + this->count_callee++; + } + if (this->curr_func_depth > MAX_FUNC_DEPTH) { + return; + } + // we need to follow the called function, only if this is not recursive. + if (std::find(this->call_stack.begin(), this->call_stack.end(), ci) == + this->call_stack.end()) { + std::vector new_call_stack; + new_call_stack.insert(new_call_stack.end(), this->call_stack.begin(), + this->call_stack.end()); + new_call_stack.insert(new_call_stack.end(), ci); + std::set cmd; + std::set type; + std::map new_caller_args; + // get propagation info + this->get_arg_propagation(ci, cmd, type, new_caller_args); + + // handle bit cast in function call + if (false && this->only_type && !type.empty()) { + yhao_log(debug, "only_type: check function call:"); + yhao_dump(debug, ci->print, str) for (auto index : type) { + yhao_log(debug, "index: " + std::to_string(index)); + auto targetOperand = tf->getArg(index); + if (targetOperand != nullptr) { + yhao_dump(debug, targetOperand->print, str) - // analyze only if one of the argument is a command or argument - if (!cmd.empty() || !type.empty()) { - this->call_stack.push_back(ci); - auto *child = new ioctl_cmd_type(tf, cmd, type, this, - new_caller_args); - child->in_indirect_call = this->in_indirect_call; - if (ci->isIndirectCall()) { - child->in_indirect_call = true; - } - if (child->only_type) { - child->run_type(&child->target_function->getEntryBlock()); - } else { - child->run_cmd(); - } - this->call_stack.pop_back(); + llvm::Type *temp_t; + temp_t = targetOperand->getType(); + if (temp_t->isPointerTy() && temp_t->getNumContainedTypes()) { + temp_t = temp_t->getNonOpaquePointerElementType(); + } + + yhao_print(3, temp_t->print, str) if (str == "i1" || str == "i8" || + str == "i16" || str == "i32" || + str == "i64") { + continue; + } + if (current_cmd == nullptr) { + continue; + } + current_cmd->in_types[ci] = temp_t; } + } + } + + // analyze only if one of the argument is a command or argument + if (!cmd.empty() || !type.empty()) { + this->call_stack.push_back(ci); + auto *child = new ioctl_cmd_type(tf, cmd, type, this, new_caller_args); + child->in_indirect_call = this->in_indirect_call; + if (ci->isIndirectCall()) { + child->in_indirect_call = true; + } + if (child->only_type) { + child->run_type(&child->target_function->getEntryBlock()); + } else { + child->run_cmd(); + } + this->call_stack.pop_back(); } + } } void sd::ioctl_cmd_type::check_call_type(llvm::CallInst *ci) { - int64_t debug = -1; - std::string str; - yhao_print(debug, ci->print, str) - yhao_log(debug, "visitCallInst: " + str); - - std::set < llvm::Function * > targets; - - if (ci->isInlineAsm()) { - return; + int64_t debug = -1; + std::string str; + yhao_print(debug, ci->print, str) yhao_log(debug, "visitCallInst: " + str); + + std::set targets; + + if (ci->isInlineAsm()) { + return; + } + if (this->tm == nullptr) { + return; + } + + if (ci->isIndirectCall()) { + this->tm->get_callee(ci, &targets, this->fps); + } else { + targets.insert(get_target_function(ci->getCalledOperand())); + } + + for (auto target : targets) { + if (!target->hasName()) { + continue; } - if (this->tm == nullptr) { - return; - } - - if (ci->isIndirectCall()) { - this->tm->get_callee(ci, &targets, this->fps); + auto function_name = target->getName().str(); + llvm::Value *targetOperand = nullptr; + llvm::Value *srcOperand = nullptr; + bool in_out = true; + if (function_name.find("copy_from_user") != std::string::npos) { + yhao_print(debug, ci->print, str) + yhao_log(debug, "copy_from_user: " + str); + if (ci->getNumOperands() >= 2) { + targetOperand = ci->getArgOperand(0); + } + if (ci->getNumOperands() >= 3) { + srcOperand = ci->getArgOperand(1); + } + } else if (function_name.find("copy_to_user") != std::string::npos) { + if (ci->getNumOperands() >= 3) { + targetOperand = ci->getArgOperand(1); + } + if (ci->getNumOperands() >= 2) { + srcOperand = ci->getArgOperand(0); + } + in_out = false; + } else if (function_name.find("memdup_user") != std::string::npos) { + srcOperand = ci->getArgOperand(0); + targetOperand = ci->getReturnedArgOperand(); } else { - targets.insert(get_target_function(ci->getCalledOperand())); + if (target->isDeclaration()) { + } else { + this->only_type = true; + check_callee(ci, target); + this->only_type = false; + } } - - for (auto target: targets) { - if (!target->hasName()) { - continue; - } - auto function_name = target->getName().str(); - llvm::Value *targetOperand = nullptr; - llvm::Value *srcOperand = nullptr; - bool in_out = true; - if (function_name.find("copy_from_user") != std::string::npos) { - yhao_print(debug, ci->print, str) - yhao_log(debug, "copy_from_user: " + str); - if (ci->getNumOperands() >= 2) { - targetOperand = ci->getArgOperand(0); - } - if (ci->getNumOperands() >= 3) { - srcOperand = ci->getArgOperand(1); - } - } else if (function_name.find("copy_to_user") != std::string::npos) { - if (ci->getNumOperands() >= 3) { - targetOperand = ci->getArgOperand(1); - } - if (ci->getNumOperands() >= 2) { - srcOperand = ci->getArgOperand(0); - } - in_out = false; - } else if (function_name.find("memdup_user") != std::string::npos) { - srcOperand = ci->getArgOperand(0); - targetOperand = ci->getReturnedArgOperand(); + if (srcOperand != nullptr) { + if (!this->is_type_affected(srcOperand)) { + yhao_log(0, "Found a copy from user from non-user argument"); + yhao_dump(-1, ci->print, str) + } + } + if (targetOperand != nullptr) { + // yu_hao: fix3: handle copy_from_user before cmd + if (current_cmd == nullptr) { + this->current_cmd = dd->no_cmd; + if (in_out) { + this->current_cmd->in_types[targetOperand] = + typeOutputHandler(targetOperand, this); } else { - if (target->isDeclaration()) { - } else { - this->only_type = true; - check_callee(ci, target); - this->only_type = false; - } - } - if (srcOperand != nullptr) { - if (!this->is_type_affected(srcOperand)) { - yhao_log(0, "Found a copy from user from non-user argument"); - yhao_dump(-1, ci->print, str) - } + this->current_cmd->out_types[targetOperand] = + typeOutputHandler(targetOperand, this); } - if (targetOperand != nullptr) { - // yu_hao: fix3: handle copy_from_user before cmd - if (current_cmd == nullptr) { - this->current_cmd = dd->no_cmd; - if (in_out) { - this->current_cmd->in_types[targetOperand] = typeOutputHandler(targetOperand, this); - } else { - this->current_cmd->out_types[targetOperand] = typeOutputHandler(targetOperand, this); - } - } else { - if (in_out) { - this->current_cmd->in_types[targetOperand] = typeOutputHandler(targetOperand, this); - } else { - this->current_cmd->out_types[targetOperand] = typeOutputHandler(targetOperand, this); - } - } + } else { + if (in_out) { + this->current_cmd->in_types[targetOperand] = + typeOutputHandler(targetOperand, this); + } else { + this->current_cmd->out_types[targetOperand] = + typeOutputHandler(targetOperand, this); } + } } + } } -void sd::ioctl_cmd_type::get_dom_bb(llvm::BasicBlock *bb, std::set *temp) { - for (auto *c: DT->getNode(bb)->children()) { - temp->insert(c->getBlock()); - get_dom_bb(c->getBlock(), temp); - } +void sd::ioctl_cmd_type::get_dom_bb(llvm::BasicBlock *bb, + std::set *temp) { + for (auto *c : DT->getNode(bb)->children()) { + temp->insert(c->getBlock()); + get_dom_bb(c->getBlock(), temp); + } } -void sd::ioctl_cmd_type::get_arg_propagation(llvm::CallInst *ci, std::set &cmd, - std::set &type, - std::map &caller_arg) { - int curr_arg_index = 0; - for (auto &arg: ci->args()) { - if (this->is_cmd_affected(arg.get())) { - cmd.insert(curr_arg_index); - } - if (this->is_type_affected(arg.get())) { - type.insert(curr_arg_index); - } - caller_arg[curr_arg_index] = arg.get(); - curr_arg_index++; +void sd::ioctl_cmd_type::get_arg_propagation( + llvm::CallInst *ci, std::set &cmd, std::set &type, + std::map &caller_arg) { + int curr_arg_index = 0; + for (auto &arg : ci->args()) { + if (this->is_cmd_affected(arg.get())) { + cmd.insert(curr_arg_index); + } + if (this->is_type_affected(arg.get())) { + type.insert(curr_arg_index); } + caller_arg[curr_arg_index] = arg.get(); + curr_arg_index++; + } } - namespace sd { - using namespace llvm; - using namespace std; - - Type *get_source_type(Instruction *inst) { - if (auto *bci = dyn_cast(inst)) { - return bci->getSrcTy(); - } else if (auto *gepInst = dyn_cast(inst)) { - return gepInst->getSourceElementType(); - } - return nullptr; - } - - Type *get_val_type(llvm::Value *val, ioctl_cmd_type *currFunction) { - val = val->stripPointerCasts(); - std::set < Value * > all_uses; - all_uses.clear(); - for (auto us = val->use_begin(), ue = val->use_end(); us != ue; us++) { - all_uses.insert((*us).get()); - } - if (all_uses.size() > 1) { - yhao_log(1, "More than one use :"); - } - for (auto sd: all_uses) { - auto *gv = dyn_cast(sd); - if (gv) { - return gv->getType(); - } - } +using namespace llvm; +using namespace std; + +Type *get_source_type(Instruction *inst) { + if (auto *bci = dyn_cast(inst)) { + return bci->getSrcTy(); + } else if (auto *gepInst = dyn_cast(inst)) { + return gepInst->getSourceElementType(); + } + return nullptr; +} - if (currFunction) { - if (currFunction->caller_args.find(val) != currFunction->caller_args.end()) { - Value *callerArg = currFunction->caller_args[val]; - Type *retVal = ioctl_cmd_type::typeOutputHandler(callerArg, currFunction->caller); - return retVal; - } - } - return nullptr; +Type *get_val_type(llvm::Value *val, ioctl_cmd_type *currFunction) { + val = val->stripPointerCasts(); + std::set all_uses; + all_uses.clear(); + for (auto us = val->use_begin(), ue = val->use_end(); us != ue; us++) { + all_uses.insert((*us).get()); + } + if (all_uses.size() > 1) { + yhao_log(1, "More than one use :"); + } + for (auto sd : all_uses) { + auto *gv = dyn_cast(sd); + if (gv) { + return gv->getType(); + } + } + + if (currFunction) { + if (currFunction->caller_args.find(val) != + currFunction->caller_args.end()) { + Value *callerArg = currFunction->caller_args[val]; + Type *retVal = + ioctl_cmd_type::typeOutputHandler(callerArg, currFunction->caller); + return retVal; } + } + return nullptr; +} - llvm::Type *ioctl_cmd_type::typeOutputHandler(llvm::Value *val, ioctl_cmd_type *currFunc) { - int64_t debug = -1; - std::string str = "typeOutputHandler: "; +llvm::Type *ioctl_cmd_type::typeOutputHandler(llvm::Value *val, + ioctl_cmd_type *currFunc) { + int64_t debug = -1; + std::string str = "typeOutputHandler: "; + yhao_add_dump(debug, val->print, str) + + Type *retType = nullptr; + if (!dyn_cast(val)) { + Type *targetType = get_val_type(val, currFunc); + if (targetType == nullptr) { + if (dyn_cast(val)) { + std::set visitedInstr; + visitedInstr.clear(); + targetType = ioctl_cmd_type::get_type_recursive(val, visitedInstr); + if (targetType == nullptr) { + str = " !targetType != nullptr: "; + yhao_add_dump(debug, val->print, str) + } + } else { + str = " !dyn_cast(val): "; yhao_add_dump(debug, val->print, str) + } + } + retType = targetType; + } else { + yhao_dump(debug, val->print, str) - Type *retType = nullptr; - if (!dyn_cast(val)) { - Type *targetType = get_val_type(val, currFunc); - if (targetType == nullptr) { - if (dyn_cast(val)) { - std::set < Instruction * > visitedInstr; - visitedInstr.clear(); - targetType = ioctl_cmd_type::get_type_recursive(val, visitedInstr); - if (targetType == nullptr) { - str = " !targetType != nullptr: "; - yhao_add_dump(debug, val->print, str) - } - } else { - str = " !dyn_cast(val): "; - yhao_add_dump(debug, val->print, str) - } - } - retType = targetType; - } else { - yhao_dump(debug, val->print, str) - - Type *targetType = get_source_type(dyn_cast(val)); - if (targetType == nullptr) { - targetType = get_val_type(val, currFunc); - } - // yu_hao: fix2: data flow like store i8* %to, i8** %to.addr, align 8 - if (targetType == nullptr) { - std::set < Instruction * > visitedInstr; - visitedInstr.clear(); - auto temp = get_inst_recursive(val, visitedInstr); - if (temp != nullptr) { - val = temp; - targetType = get_val_type(val, currFunc); - } else { - - } - } + Type *targetType = get_source_type(dyn_cast(val)); + if (targetType == nullptr) { + targetType = get_val_type(val, currFunc); + } + // yu_hao: fix2: data flow like store i8* %to, i8** %to.addr, align 8 + if (targetType == nullptr) { + std::set visitedInstr; + visitedInstr.clear(); + auto temp = get_inst_recursive(val, visitedInstr); + if (temp != nullptr) { + val = temp; + targetType = get_val_type(val, currFunc); + } else { + } + } - if (targetType == nullptr) { - if (val == nullptr) { - - } else { - if (dyn_cast(val)) { - std::set < Instruction * > visitedInstr; - visitedInstr.clear(); - targetType = ioctl_cmd_type::get_type_recursive(val, visitedInstr); - if (targetType == nullptr) { - str = " ! !targetType != nullptr: "; - yhao_add_dump(debug, val->print, str) - } - } else { - str = " ! !dyn_cast(val): "; - yhao_add_dump(debug, val->print, str) - } - } - } - retType = targetType; + if (targetType == nullptr) { + if (val == nullptr) { + } else { + if (dyn_cast(val)) { + std::set visitedInstr; + visitedInstr.clear(); + targetType = ioctl_cmd_type::get_type_recursive(val, visitedInstr); + if (targetType == nullptr) { + str = " ! !targetType != nullptr: "; + yhao_add_dump(debug, val->print, str) + } + } else { + str = " ! !dyn_cast(val): "; + yhao_add_dump(debug, val->print, str) } - - return retType; + } } + retType = targetType; + } - Type *ioctl_cmd_type::get_type_recursive(Value *val, std::set &visited) { - int64_t debug = -1; - std::string str = "get_type_recursive"; - yhao_add_dump(debug, val->print, str) - auto *inst = llvm::dyn_cast(val); - if (inst == nullptr) { - return nullptr; - } - if (visited.find(inst) != visited.end()) { - return nullptr; - } + return retType; +} - visited.insert(inst); - if (llvm::dyn_cast(inst)) { - auto *currLI = llvm::dyn_cast(inst); - llvm::Value *point_val = currLI->getPointerOperand()->stripPointerCasts(); - for (auto u: point_val->users()) { - auto *tmpVal = llvm::dyn_cast(u); - if (llvm::dyn_cast(tmpVal)) { - llvm::Type *currChType = ioctl_cmd_type::get_type_recursive(tmpVal, visited); - if (currChType) { - return currChType; - } - } - } - } - if (llvm::dyn_cast(inst)) { - auto *currSI = llvm::dyn_cast(inst); - llvm::Value *valueOp = currSI->getValueOperand(); - if (llvm::dyn_cast(valueOp)) { - llvm::Type *currChType = ioctl_cmd_type::get_type_recursive(valueOp, visited); - if (currChType) { - return currChType; - } - } - } - if (llvm::dyn_cast(inst)) { - auto *currBCI = llvm::dyn_cast(inst); - return currBCI->getSrcTy(); - } - if (llvm::dyn_cast(inst)) { - auto *currPN = llvm::dyn_cast(inst); - unsigned i = 0; - while (i < currPN->getNumOperands()) { - llvm::Value *targetOp = currPN->getOperand(i); - llvm::Type *currChType = ioctl_cmd_type::get_type_recursive(targetOp, visited); - if (currChType) { - return currChType; - } - i++; - } - } - if (llvm::dyn_cast(inst)) { - auto *currAI = dyn_cast(inst); - return currAI->getType(); - } - visited.erase(inst); - return nullptr; +Type *ioctl_cmd_type::get_type_recursive(Value *val, + std::set &visited) { + int64_t debug = -1; + std::string str = "get_type_recursive"; + yhao_add_dump(debug, val->print, str) auto *inst = + llvm::dyn_cast(val); + if (inst == nullptr) { + return nullptr; + } + if (visited.find(inst) != visited.end()) { + return nullptr; + } + + visited.insert(inst); + if (llvm::dyn_cast(inst)) { + auto *currLI = llvm::dyn_cast(inst); + llvm::Value *point_val = currLI->getPointerOperand()->stripPointerCasts(); + for (auto u : point_val->users()) { + auto *tmpVal = llvm::dyn_cast(u); + if (llvm::dyn_cast(tmpVal)) { + llvm::Type *currChType = + ioctl_cmd_type::get_type_recursive(tmpVal, visited); + if (currChType) { + return currChType; + } + } } + } + if (llvm::dyn_cast(inst)) { + auto *currSI = llvm::dyn_cast(inst); + llvm::Value *valueOp = currSI->getValueOperand(); + if (llvm::dyn_cast(valueOp)) { + llvm::Type *currChType = + ioctl_cmd_type::get_type_recursive(valueOp, visited); + if (currChType) { + return currChType; + } + } + } + if (llvm::dyn_cast(inst)) { + auto *currBCI = llvm::dyn_cast(inst); + return currBCI->getSrcTy(); + } + if (llvm::dyn_cast(inst)) { + auto *currPN = llvm::dyn_cast(inst); + unsigned i = 0; + while (i < currPN->getNumOperands()) { + llvm::Value *targetOp = currPN->getOperand(i); + llvm::Type *currChType = + ioctl_cmd_type::get_type_recursive(targetOp, visited); + if (currChType) { + return currChType; + } + i++; + } + } + if (llvm::dyn_cast(inst)) { + auto *currAI = dyn_cast(inst); + return currAI->getType(); + } + visited.erase(inst); + return nullptr; +} - Value *ioctl_cmd_type::get_inst_recursive(Value *val, set &visited) { - int64_t debug = -1; - std::string str = "get_inst_recursive"; - yhao_add_dump(debug, val->print, str) - auto inst = llvm::dyn_cast(val); - if (inst == nullptr) { - return nullptr; - } - if (visited.find(inst) != visited.end()) { - return nullptr; - } - - visited.insert(inst); - if (llvm::dyn_cast(inst)) { - auto currLI = llvm::dyn_cast(inst); - llvm::Value *pointerVal = currLI->getPointerOperand()->stripPointerCasts(); - for (auto u: pointerVal->users()) { - auto *tmpVal = llvm::dyn_cast(u); - if (llvm::dyn_cast(tmpVal)) { - auto currInst = ioctl_cmd_type::get_inst_recursive(tmpVal, visited); - if (currInst) { - return currInst; - } - } - } - } else if (llvm::dyn_cast(inst)) { - auto *currSI = llvm::dyn_cast(inst); - llvm::Value *valueOp = currSI->getValueOperand(); - if (llvm::dyn_cast(valueOp)) { - auto currInst = ioctl_cmd_type::get_inst_recursive(valueOp, visited); - if (currInst) { - return currInst; - } - } else { - return valueOp; - } - } else if (llvm::dyn_cast(inst)) { - auto currBCI = llvm::dyn_cast(inst); - return currBCI; - } else if (llvm::dyn_cast(inst)) { - auto currPN = llvm::dyn_cast(inst); - unsigned i = 0; - while (i < currPN->getNumOperands()) { - llvm::Value *targetOp = currPN->getOperand(i); - auto currInst = ioctl_cmd_type::get_inst_recursive(targetOp, visited); - if (currInst) { - return currInst; - } - i++; - } - } else if (llvm::dyn_cast(inst)) { - auto temp_ai = llvm::dyn_cast(inst); - return temp_ai; - } - visited.erase(inst); - return nullptr; +Value *ioctl_cmd_type::get_inst_recursive(Value *val, + set &visited) { + int64_t debug = -1; + std::string str = "get_inst_recursive"; + yhao_add_dump(debug, val->print, str) auto inst = + llvm::dyn_cast(val); + if (inst == nullptr) { + return nullptr; + } + if (visited.find(inst) != visited.end()) { + return nullptr; + } + + visited.insert(inst); + if (llvm::dyn_cast(inst)) { + auto currLI = llvm::dyn_cast(inst); + llvm::Value *pointerVal = currLI->getPointerOperand()->stripPointerCasts(); + for (auto u : pointerVal->users()) { + auto *tmpVal = llvm::dyn_cast(u); + if (llvm::dyn_cast(tmpVal)) { + auto currInst = ioctl_cmd_type::get_inst_recursive(tmpVal, visited); + if (currInst) { + return currInst; + } + } } -} \ No newline at end of file + } else if (llvm::dyn_cast(inst)) { + auto *currSI = llvm::dyn_cast(inst); + llvm::Value *valueOp = currSI->getValueOperand(); + if (llvm::dyn_cast(valueOp)) { + auto currInst = ioctl_cmd_type::get_inst_recursive(valueOp, visited); + if (currInst) { + return currInst; + } + } else { + return valueOp; + } + } else if (llvm::dyn_cast(inst)) { + auto currBCI = llvm::dyn_cast(inst); + return currBCI; + } else if (llvm::dyn_cast(inst)) { + auto currPN = llvm::dyn_cast(inst); + unsigned i = 0; + while (i < currPN->getNumOperands()) { + llvm::Value *targetOp = currPN->getOperand(i); + auto currInst = ioctl_cmd_type::get_inst_recursive(targetOp, visited); + if (currInst) { + return currInst; + } + i++; + } + } else if (llvm::dyn_cast(inst)) { + auto temp_ai = llvm::dyn_cast(inst); + return temp_ai; + } + visited.erase(inst); + return nullptr; +} +} // namespace sd diff --git a/lib/AnalysisLib/ioctl_cmd_type.h b/lib/AnalysisLib/ioctl_cmd_type.h index fad1683..414c285 100644 --- a/lib/AnalysisLib/ioctl_cmd_type.h +++ b/lib/AnalysisLib/ioctl_cmd_type.h @@ -5,90 +5,88 @@ #ifndef INC_2021_TEMPLATE_IOCTL_CMD_TYPE_H #define INC_2021_TEMPLATE_IOCTL_CMD_TYPE_H -#include "T_module.h" #include "../KnowledgeLib/device_driver.h" +#include "T_module.h" namespace sd { - class ioctl_cmd_type { - public: - T_module *tm = nullptr; - std::set *fps{}; - - device_driver *dd; - cmd_info *current_cmd; - - llvm::Function *target_function; - llvm::DominatorTree *DT = nullptr; - std::vector call_stack; - bool only_type = false; - llvm::Value *curr_cmd = nullptr; - uint64_t curr_func_depth = 0; - uint64_t count_callee = 0; - ioctl_cmd_type *caller = nullptr; +class ioctl_cmd_type { + public: + T_module *tm = nullptr; + std::set *fps{}; - // All instructions whose result depend on the value - // which is derived from cmd and number arg value. - std::set all_cmd_inst; - std::set all_type_inst; - std::set visit_BBs; - // map that stores the actual values passed by the caller, - // callee <-> caller - // this is useful in determining the number of argument. - std::map caller_args; + device_driver *dd; + cmd_info *current_cmd; - // statistic - bool in_indirect_call = false; + llvm::Function *target_function; + llvm::DominatorTree *DT = nullptr; + std::vector call_stack; + bool only_type = false; + llvm::Value *curr_cmd = nullptr; + uint64_t curr_func_depth = 0; + uint64_t count_callee = 0; + ioctl_cmd_type *caller = nullptr; - public: - ioctl_cmd_type(llvm::Function *tf, - std::set cmd, - std::set type, - device_driver *dd, - T_module *tm = nullptr, - std::set *fps = nullptr); + // All instructions whose result depend on the value + // which is derived from cmd and number arg value. + std::set all_cmd_inst; + std::set all_type_inst; + std::set visit_BBs; + // map that stores the actual values passed by the caller, + // callee <-> caller + // this is useful in determining the number of argument. + std::map caller_args; - ioctl_cmd_type(llvm::Function *tf, - std::set cmd, - std::set type, - sd::ioctl_cmd_type *caller, - std::map caller_arguments); + // statistic + bool in_indirect_call = false; - virtual ~ioctl_cmd_type(); + public: + ioctl_cmd_type(llvm::Function *tf, std::set cmd, + std::set type, device_driver *dd, + T_module *tm = nullptr, + std::set *fps = nullptr); - void set_only_type_module(); + ioctl_cmd_type(llvm::Function *tf, std::set cmd, + std::set type, sd::ioctl_cmd_type *caller, + std::map caller_arguments); - void unset_only_type_module(); + virtual ~ioctl_cmd_type(); - void run_cmd(); + void set_only_type_module(); - void run_type(llvm::BasicBlock *start_bb); + void unset_only_type_module(); - bool is_cmd_affected(llvm::Value *targetValue); + void run_cmd(); - bool is_type_affected(llvm::Value *targetValue); + void run_type(llvm::BasicBlock *start_bb); - void update_cmd_and_type(); + bool is_cmd_affected(llvm::Value *targetValue); - void check_call_cmd(llvm::CallInst *ci); + bool is_type_affected(llvm::Value *targetValue); - void check_callee(llvm::CallInst *ci, llvm::Function *tf); + void update_cmd_and_type(); - // for number - void check_call_type(llvm::CallInst *ci); + void check_call_cmd(llvm::CallInst *ci); - void get_dom_bb(llvm::BasicBlock *bb, std::set *temp); + void check_callee(llvm::CallInst *ci, llvm::Function *tf); - void get_arg_propagation(llvm::CallInst *ci, std::set &cmd, std::set &type, - std::map &caller_arg); + // for number + void check_call_type(llvm::CallInst *ci); - static llvm::Type *typeOutputHandler(llvm::Value *val, ioctl_cmd_type *currFunc); + void get_dom_bb(llvm::BasicBlock *bb, std::set *temp); - static llvm::Type *get_type_recursive(llvm::Value *val, std::set &visited); + void get_arg_propagation(llvm::CallInst *ci, std::set &cmd, + std::set &type, + std::map &caller_arg); - static llvm::Value *get_inst_recursive(llvm::Value *val, std::set &visited); + static llvm::Type *typeOutputHandler(llvm::Value *val, + ioctl_cmd_type *currFunc); - }; -} + static llvm::Type *get_type_recursive(llvm::Value *val, + std::set &visited); + static llvm::Value *get_inst_recursive( + llvm::Value *val, std::set &visited); +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_IOCTL_CMD_TYPE_H +#endif // INC_2021_TEMPLATE_IOCTL_CMD_TYPE_H diff --git a/lib/KnowledgeLib/checker.cpp b/lib/KnowledgeLib/checker.cpp index e44a2c5..70cb1a6 100644 --- a/lib/KnowledgeLib/checker.cpp +++ b/lib/KnowledgeLib/checker.cpp @@ -3,555 +3,556 @@ // #include "checker.h" + +#include + #include "../ToolLib/llvm_related.h" #include "../ToolLib/log.h" -#include sd::checker *sd::checker::copy() { - auto c = new checker(); - c->copy(this); - return c; + auto c = new checker(); + c->copy(this); + return c; } void sd::checker::copy(sd::checker *c) { - this->ct = c->ct; - this->id = c->id; - this->name = c->name; + this->ct = c->ct; + this->id = c->id; + this->name = c->name; - this->structure = c->structure; - this->offset = c->offset; + this->structure = c->structure; + this->offset = c->offset; - this->function = c->function; - this->object = c->object; - this->value = c->value; - this->value_offset = c->value_offset; - this->field = c->field; + this->function = c->function; + this->object = c->object; + this->value = c->value; + this->value_offset = c->value_offset; + this->field = c->field; } nlohmann::json *sd::checker::to_json() { - auto j = new nlohmann::json(); - (*j)["1_checker_type"] = this->ct; - (*j)["1_id"] = this->id; - (*j)["2_structure"] = this->structure; - (*j)["3_offset"] = this->offset; - (*j)["4_function"] = this->function; - (*j)["4_1_object"] = this->object; - (*j)["4_2_value"] = this->value; - (*j)["4_3_offset"] = this->value_offset; - (*j)["4_4_field"] = this->field; - return j; + auto j = new nlohmann::json(); + (*j)["1_checker_type"] = this->ct; + (*j)["1_id"] = this->id; + (*j)["2_structure"] = this->structure; + (*j)["3_offset"] = this->offset; + (*j)["4_function"] = this->function; + (*j)["4_1_object"] = this->object; + (*j)["4_2_value"] = this->value; + (*j)["4_3_offset"] = this->value_offset; + (*j)["4_4_field"] = this->field; + return j; } void sd::checker::from_json(nlohmann::json j) { - if (j.contains("1_checker_type") && j["1_checker_type"].is_number_integer()) { - this->ct = j["1_checker_type"].get(); - } - if (j.contains("1_id") && j["1_id"].is_number_integer()) { - this->id = j["1_id"].get(); - } - if (j.contains("2_structure") && j["2_structure"].is_string()) { - this->structure = j["2_structure"].get(); - } - if (j.contains("3_offset") && j["3_offset"].is_number_integer()) { - this->offset = j["3_offset"].get(); - } - if (j.contains("4_function") && j["4_function"].is_string()) { - this->function = j["4_function"].get(); - } - if (j.contains("4_1_object") && j["4_1_object"].is_number_integer()) { - this->object = j["4_1_object"].get(); - } - if (j.contains("4_2_value") && j["4_2_value"].is_number_integer()) { - this->value = j["4_2_value"].get(); - } - if (j.contains("4_3_offset") && j["4_3_offset"].is_number_integer()) { - this->value_offset = j["4_3_offset"].get(); - } - if (j.contains("4_4_field") && j["4_4_field"].is_boolean()) { - this->field = j["4_4_field"].get(); - } + if (j.contains("1_checker_type") && j["1_checker_type"].is_number_integer()) { + this->ct = j["1_checker_type"].get(); + } + if (j.contains("1_id") && j["1_id"].is_number_integer()) { + this->id = j["1_id"].get(); + } + if (j.contains("2_structure") && j["2_structure"].is_string()) { + this->structure = j["2_structure"].get(); + } + if (j.contains("3_offset") && j["3_offset"].is_number_integer()) { + this->offset = j["3_offset"].get(); + } + if (j.contains("4_function") && j["4_function"].is_string()) { + this->function = j["4_function"].get(); + } + if (j.contains("4_1_object") && j["4_1_object"].is_number_integer()) { + this->object = j["4_1_object"].get(); + } + if (j.contains("4_2_value") && j["4_2_value"].is_number_integer()) { + this->value = j["4_2_value"].get(); + } + if (j.contains("4_3_offset") && j["4_3_offset"].is_number_integer()) { + this->value_offset = j["4_3_offset"].get(); + } + if (j.contains("4_4_field") && j["4_4_field"].is_boolean()) { + this->field = j["4_4_field"].get(); + } } std::string sd::checker::print() { - auto j = this->to_json(); - std::string s = j->dump(2); - delete j; - return s; + auto j = this->to_json(); + std::string s = j->dump(2); + delete j; + return s; } sd::checker::~checker() = default; nlohmann::json sd::offset_chain_offset::to_json() { - auto *j = new nlohmann::json(); - (*j)["0_offset"] = this->offset; - (*j)["1_type"] = this->type_str; - if (this->next != nullptr) { - (*j)["2_next"] = this->next->to_json(); - } - return *j; + auto *j = new nlohmann::json(); + (*j)["0_offset"] = this->offset; + (*j)["1_type"] = this->type_str; + if (this->next != nullptr) { + (*j)["2_next"] = this->next->to_json(); + } + return *j; } sd::offset_chain_offset::offset_chain_offset() { - offset_chain_offset::offset = -2; - offset_chain_offset::type_str = ""; - offset_chain_offset::type = nullptr; - offset_chain_offset::next = nullptr; + offset_chain_offset::offset = -2; + offset_chain_offset::type_str = ""; + offset_chain_offset::type = nullptr; + offset_chain_offset::next = nullptr; } -sd::offset_chain_offset::~offset_chain_offset() { - delete this->next; -} +sd::offset_chain_offset::~offset_chain_offset() { delete this->next; } void sd::offset_chain_offset::copy(sd::offset_chain_offset *oc) { - this->offset = oc->offset; - this->type_str = oc->type_str; - this->type = oc->type; - if (oc->next == nullptr) { - this->next = nullptr; - } else { - this->next = new offset_chain_offset(); - this->next->copy(oc->next); - } + this->offset = oc->offset; + this->type_str = oc->type_str; + this->type = oc->type; + if (oc->next == nullptr) { + this->next = nullptr; + } else { + this->next = new offset_chain_offset(); + this->next->copy(oc->next); + } } void sd::offset_chain_offset::read_value_from_json(nlohmann::json j) { - if (j.contains("0_offset") && j["0_offset"].is_number_integer()) { - this->offset = j["0_offset"].get(); - } - if (j.contains("1_type") && j["1_type"].is_string()) { - this->type_str = j["1_type"].get(); - } - if (j.contains("2_next") && j["2_next"].is_object()) { - if (this->next == nullptr) { - this->next = new offset_chain_offset(); - } - this->next->read_value_from_json(j["2_next"]); + if (j.contains("0_offset") && j["0_offset"].is_number_integer()) { + this->offset = j["0_offset"].get(); + } + if (j.contains("1_type") && j["1_type"].is_string()) { + this->type_str = j["1_type"].get(); + } + if (j.contains("2_next") && j["2_next"].is_object()) { + if (this->next == nullptr) { + this->next = new offset_chain_offset(); } + this->next->read_value_from_json(j["2_next"]); + } } sd::offset_chain_base::offset_chain_base() { - offset_chain_base::base = ""; - offset_chain_base::type_str = ""; - offset_chain_base::type = nullptr; - offset_chain_base::next = nullptr; + offset_chain_base::base = ""; + offset_chain_base::type_str = ""; + offset_chain_base::type = nullptr; + offset_chain_base::next = nullptr; } -sd::offset_chain_base::~offset_chain_base() { - delete this->next; -} +sd::offset_chain_base::~offset_chain_base() { delete this->next; } nlohmann::json sd::offset_chain_base::to_json() { - auto *j = new nlohmann::json(); - (*j)["0_base"] = this->base; - (*j)["1_type"] = this->type_str; - if (this->next != nullptr) { - (*j)["2_next"] = this->next->to_json(); - } - return *j; + auto *j = new nlohmann::json(); + (*j)["0_base"] = this->base; + (*j)["1_type"] = this->type_str; + if (this->next != nullptr) { + (*j)["2_next"] = this->next->to_json(); + } + return *j; } void sd::offset_chain_base::copy(sd::offset_chain_base *oc) { - this->base = oc->base; - this->type_str = oc->type_str; - this->type = oc->type; - if (oc->next == nullptr) { - this->next = nullptr; - } else { - this->next = new offset_chain_offset(); - this->next->copy(oc->next); - } - + this->base = oc->base; + this->type_str = oc->type_str; + this->type = oc->type; + if (oc->next == nullptr) { + this->next = nullptr; + } else { + this->next = new offset_chain_offset(); + this->next->copy(oc->next); + } } void sd::offset_chain_base::read_value_from_json(nlohmann::json j) { - if (j.contains("0_base") && j["0_base"].is_string()) { - this->base = j["0_base"].get(); - } - if (j.contains("1_type") && j["1_type"].is_string()) { - this->type_str = j["1_type"].get(); - } - if (j.contains("2_next") && j["2_next"].is_object()) { - if (this->next == nullptr) { - this->next = new offset_chain_offset(); - } - this->next->read_value_from_json(j["2_next"]); + if (j.contains("0_base") && j["0_base"].is_string()) { + this->base = j["0_base"].get(); + } + if (j.contains("1_type") && j["1_type"].is_string()) { + this->type_str = j["1_type"].get(); + } + if (j.contains("2_next") && j["2_next"].is_object()) { + if (this->next == nullptr) { + this->next = new offset_chain_offset(); } + this->next->read_value_from_json(j["2_next"]); + } } -sd::checker_result::~checker_result() { - delete this->offset_chain; -} +sd::checker_result::~checker_result() { delete this->offset_chain; } void sd::checker_result::setInst(llvm::Instruction *i) { - checker_result::inst = i; - yhao_print(-1, checker_result::inst->print, checker_result::inst_str) - checker_result::inst_strID = inst_to_strID(checker_result::inst); + checker_result::inst = i; + yhao_print(-1, checker_result::inst->print, checker_result::inst_str) + checker_result::inst_strID = inst_to_strID(checker_result::inst); } void sd::checker_result::setInst(llvm::Module *m) { - int64_t debug = -1; - yhao_log(1, this->inst_strID); - auto i = strID_to_inst(m, this->inst_strID); - if (i != nullptr) { + int64_t debug = -1; + yhao_log(1, this->inst_strID); + auto i = strID_to_inst(m, this->inst_strID); + if (i != nullptr) { + std::string i_str; + yhao_print(debug, i->print, + i_str) if (real_inst_str(i_str) == + real_inst_str(checker_result::inst_str)) { + checker_result::inst = i; + return; + } + goto search_bb; + } + +search_bb: + auto b = strID_to_basicblock(m, checker_result::inst_strID); + if (b != nullptr) { + for (auto &ii : *b) { + std::string i_str; + yhao_print(debug, ii.print, + i_str) if (real_inst_str(i_str) == + real_inst_str(checker_result::inst_str)) { + checker_result::inst = ⅈ + return; + } + } + goto search_f; + } + +search_f: + auto f = strID_to_function(m, checker_result::inst_strID); + if (f != nullptr) { + for (auto &bb : *f) { + for (auto &ii : bb) { std::string i_str; - yhao_print(debug, i->print, i_str) - if (real_inst_str(i_str) == real_inst_str(checker_result::inst_str)) { - checker_result::inst = i; - return; - } - goto search_bb; - } - - search_bb: - auto b = strID_to_basicblock(m, checker_result::inst_strID); - if (b != nullptr) { - for (auto &ii: *b) { - std::string i_str; - yhao_print(debug, ii.print, i_str) - if (real_inst_str(i_str) == real_inst_str(checker_result::inst_str)) { - checker_result::inst = ⅈ - return; - } - } - goto search_f; - } - - search_f: - auto f = strID_to_function(m, checker_result::inst_strID); - if (f != nullptr) { - for (auto &bb: *f) { - for (auto &ii: bb) { - std::string i_str; - yhao_print(debug, ii.print, i_str) - if (real_inst_str(i_str) == real_inst_str(checker_result::inst_str)) { - checker_result::inst = ⅈ - return; - } - } + yhao_print(debug, ii.print, + i_str) if (real_inst_str(i_str) == + real_inst_str(checker_result::inst_str)) { + checker_result::inst = ⅈ + return; } - goto error; + } } + goto error; + } - error: - yhao_log(3, "not find inst"); +error: + yhao_log(3, "not find inst"); } void sd::checker_result::push_call_chain(llvm::Instruction *i) { - this->call_chain.push_back(i); + this->call_chain.push_back(i); } -void sd::checker_result::pop_call_chain() { - this->call_chain.pop_back(); -} +void sd::checker_result::pop_call_chain() { this->call_chain.pop_back(); } void sd::checker_result::compute_hash() { - std::string hash_str; - hash_str += std::to_string(this->ct); - hash_str += checker_result::structure; - hash_str += std::to_string(this->offset); - hash_str += checker_result::inst_strID; - for (auto i: this->call_chain) { - hash_str += inst_to_strID(i); - } - this->hash = std::hash{}(hash_str); + std::string hash_str; + hash_str += std::to_string(this->ct); + hash_str += checker_result::structure; + hash_str += std::to_string(this->offset); + hash_str += checker_result::inst_strID; + for (auto i : this->call_chain) { + hash_str += inst_to_strID(i); + } + this->hash = std::hash{}(hash_str); } sd::checker_result *sd::checker_result::copy() { - auto c = new checker_result(); - c->checker_result::copy(this); - return c; + auto c = new checker_result(); + c->checker_result::copy(this); + return c; } void sd::checker_result::copy(sd::checker_result *c) { - checker::copy(c); - this->inst = c->inst; - this->inst_str = c->inst_str; - this->inst_strID = c->inst_strID; - if (c->offset_chain == nullptr) { - this->offset_chain = nullptr; - } else { - this->offset_chain = new offset_chain_base(); - this->offset_chain->copy(c->offset_chain); - } - for (auto i: c->call_chain) { - this->call_chain.push_back(i); - } - this->hash = c->hash; + checker::copy(c); + this->inst = c->inst; + this->inst_str = c->inst_str; + this->inst_strID = c->inst_strID; + if (c->offset_chain == nullptr) { + this->offset_chain = nullptr; + } else { + this->offset_chain = new offset_chain_base(); + this->offset_chain->copy(c->offset_chain); + } + for (auto i : c->call_chain) { + this->call_chain.push_back(i); + } + this->hash = c->hash; } nlohmann::json *sd::checker_result::to_json() { - auto j = checker::to_json(); - (*j)["0_hash"] = this->hash; - (*j)["0_inst_strID"] = this->inst_strID; - (*j)["0_inst_str"] = this->inst_str; - if (this->offset_chain != nullptr) { - (*j)["a_offset_chain"] = this->offset_chain->to_json(); - } - int64_t No; - No = 0; - for (auto i: this->call_chain) { - std::stringstream ss; - ss << std::setw(2) << std::setfill('0') << No++; - std::string s = ss.str(); - (*j)["b_call_chain"][s] = inst_to_strID(i); - } - return j; + auto j = checker::to_json(); + (*j)["0_hash"] = this->hash; + (*j)["0_inst_strID"] = this->inst_strID; + (*j)["0_inst_str"] = this->inst_str; + if (this->offset_chain != nullptr) { + (*j)["a_offset_chain"] = this->offset_chain->to_json(); + } + int64_t No; + No = 0; + for (auto i : this->call_chain) { + std::stringstream ss; + ss << std::setw(2) << std::setfill('0') << No++; + std::string s = ss.str(); + (*j)["b_call_chain"][s] = inst_to_strID(i); + } + return j; } void sd::checker_result::from_json(nlohmann::json j) { - checker::from_json(j); - if (j.contains("0_hash") && j["0_hash"].is_number_integer()) { - this->hash = j["0_hash"].get(); - } - if (j.contains("0_inst_strID") && j["0_inst_strID"].is_string()) { - this->inst_strID = j["0_inst_strID"].get(); - } - if (j.contains("0_inst_str") && j["0_inst_str"].is_string()) { - this->inst_str = j["0_inst_str"].get(); - } - if (j.contains("a_offset_chain") && j["a_offset_chain"].is_object()) { - if (this->offset_chain == nullptr) { - this->offset_chain = new offset_chain_base(); - } - this->offset_chain->read_value_from_json(j["a_offset_chain"]); - } -} - -std::string sd::checker_result::get_call_chain(const std::string &linux_kernel_version) { - std::string ret; - int64_t No; - No = 0; - for (auto i: this->call_chain) { - std::stringstream ss; - ss << std::setw(2) << std::setfill('0') << No++; - std::string s = ss.str(); - if (linux_kernel_version.empty()) { - ret += Annotation_Symbol + s + ": " + dump_inst(i) + "\n"; - } else { - ret += Annotation_Symbol + s + ": " + dump_inst_booltin(i, linux_kernel_version) + "\n"; - } + checker::from_json(j); + if (j.contains("0_hash") && j["0_hash"].is_number_integer()) { + this->hash = j["0_hash"].get(); + } + if (j.contains("0_inst_strID") && j["0_inst_strID"].is_string()) { + this->inst_strID = j["0_inst_strID"].get(); + } + if (j.contains("0_inst_str") && j["0_inst_str"].is_string()) { + this->inst_str = j["0_inst_str"].get(); + } + if (j.contains("a_offset_chain") && j["a_offset_chain"].is_object()) { + if (this->offset_chain == nullptr) { + this->offset_chain = new offset_chain_base(); + } + this->offset_chain->read_value_from_json(j["a_offset_chain"]); + } +} + +std::string sd::checker_result::get_call_chain( + const std::string &linux_kernel_version) { + std::string ret; + int64_t No; + No = 0; + for (auto i : this->call_chain) { + std::stringstream ss; + ss << std::setw(2) << std::setfill('0') << No++; + std::string s = ss.str(); + if (linux_kernel_version.empty()) { + ret += Annotation_Symbol + s + ": " + dump_inst(i) + "\n"; + } else { + ret += Annotation_Symbol + s + ": " + + dump_inst_booltin(i, linux_kernel_version) + "\n"; } - return ret; + } + return ret; } sd::checker_result_number *sd::checker_result_number::copy() { - auto c = new checker_result_number(); - c->checker_result_number::copy(this); - return c; + auto c = new checker_result_number(); + c->checker_result_number::copy(this); + return c; } void sd::checker_result_number::copy(sd::checker_result_number *c) { - checker_result::copy(c); - this->number = c->number; + checker_result::copy(c); + this->number = c->number; } nlohmann::json *sd::checker_result_number::to_json() { - auto *j = checker_result::to_json(); - (*j)["b_type"] = this->number; - return j; + auto *j = checker_result::to_json(); + (*j)["b_type"] = this->number; + return j; } void sd::checker_result_number::from_json(nlohmann::json j) { - checker_result::from_json(j); - if (j.contains("b_type") && j["b_type"].is_object()) { - if (j["b_type"].get() < 0) { - yhao_log(3, "b_type: bad value"); - } else { - this->number = j["b_type"].get(); - } + checker_result::from_json(j); + if (j.contains("b_type") && j["b_type"].is_object()) { + if (j["b_type"].get() < 0) { + yhao_log(3, "b_type: bad value"); } else { - yhao_log(3, "b_type: no value"); + this->number = j["b_type"].get(); } + } else { + yhao_log(3, "b_type: no value"); + } } sd::checker_result_string *sd::checker_result_string::copy() { - auto c = new checker_result_string(); - c->checker_result_string::copy(this); - return c; + auto c = new checker_result_string(); + c->checker_result_string::copy(this); + return c; } void sd::checker_result_string::copy(sd::checker_result_string *c) { - checker_result::copy(c); - this->fmt = c->fmt; - for (auto v: va1) { - this->va1.push_back(v); - } - for (const auto &v: va2) { - this->va2.push_back(v); - } + checker_result::copy(c); + this->fmt = c->fmt; + for (auto v : va1) { + this->va1.push_back(v); + } + for (const auto &v : va2) { + this->va2.push_back(v); + } } nlohmann::json *sd::checker_result_string::to_json() { - auto j = checker_result::to_json(); - (*j)["c_fmt"] = this->fmt; - int64_t No; - No = 0; - for (auto v: va1) { - (*j)["c_val1"][std::to_string(No++)] = v; - } - No = 0; - for (const auto &v: va2) { - (*j)["c_val2"][std::to_string(No++)] = v; - } - (*j)["d_match"] = this->match; - return j; + auto j = checker_result::to_json(); + (*j)["c_fmt"] = this->fmt; + int64_t No; + No = 0; + for (auto v : va1) { + (*j)["c_val1"][std::to_string(No++)] = v; + } + No = 0; + for (const auto &v : va2) { + (*j)["c_val2"][std::to_string(No++)] = v; + } + (*j)["d_match"] = this->match; + return j; } void sd::checker_result_string::from_json(nlohmann::json j) { - checker_result::from_json(j); - if (j.contains("c_fmt") && j["c_fmt"].is_string()) { - this->fmt = j["c_fmt"].get(); - } else { - yhao_log(3, "c_fmt: no value"); - } - int64_t No; - if (j.contains("c_val1") && j["c_val1"].is_object()) { - No = 0; - auto key = std::to_string(No); - auto j_val1 = j["c_val1"]; - while (j_val1.contains(key) && j_val1[key].is_number_integer()) { - this->va1.push_back(j_val1[key].get()); - No++; - key = std::to_string(No); - } - } else { - yhao_log(3, "c_val1: no value"); - } - if (j.contains("c_val2") && j["c_val2"].is_object()) { - No = 0; - auto key = std::to_string(No); - auto j_val2 = j["c_val2"]; - while (j_val2.contains(key) && j_val2[key].is_string()) { - this->va2.push_back(j_val2[key].get()); - No++; - key = std::to_string(No); - } - } else { - yhao_log(3, "c_val2: no value"); + checker_result::from_json(j); + if (j.contains("c_fmt") && j["c_fmt"].is_string()) { + this->fmt = j["c_fmt"].get(); + } else { + yhao_log(3, "c_fmt: no value"); + } + int64_t No; + if (j.contains("c_val1") && j["c_val1"].is_object()) { + No = 0; + auto key = std::to_string(No); + auto j_val1 = j["c_val1"]; + while (j_val1.contains(key) && j_val1[key].is_number_integer()) { + this->va1.push_back(j_val1[key].get()); + No++; + key = std::to_string(No); + } + } else { + yhao_log(3, "c_val1: no value"); + } + if (j.contains("c_val2") && j["c_val2"].is_object()) { + No = 0; + auto key = std::to_string(No); + auto j_val2 = j["c_val2"]; + while (j_val2.contains(key) && j_val2[key].is_string()) { + this->va2.push_back(j_val2[key].get()); + No++; + key = std::to_string(No); } + } else { + yhao_log(3, "c_val2: no value"); + } } std::string sd::checker_result_string::to_string() { - std::string name; - bool fmt_model = false; - int64_t va1_index = 0, va2_index = 0; - for (auto temp: this->fmt) { - if (temp == '%') { - fmt_model = true; - } else if (fmt_model) { - fmt_model = false; - if (temp == 's') { - if (va2_index >= this->va2.size()) { - name += "%s"; - continue; - } - auto temp_va = va2.at(va2_index); - if (temp_va.empty()) { - name += "%s"; - continue; - } - name += temp_va; - va2_index++; - } else if (temp == 'u' || temp == 'd' || temp == 'i') { - if (va1_index >= this->va1.size()) { - //name += "%"; - //name += temp; - name += "#"; - continue; - } - auto temp_va = va1.at(va1_index); - name += std::to_string(temp_va); - va1_index++; - } else if (temp == 'l') { - fmt_model = true; - } - } else { - name += temp; + std::string name; + bool fmt_model = false; + int64_t va1_index = 0, va2_index = 0; + for (auto temp : this->fmt) { + if (temp == '%') { + fmt_model = true; + } else if (fmt_model) { + fmt_model = false; + if (temp == 's') { + if (va2_index >= this->va2.size()) { + name += "%s"; + continue; } + auto temp_va = va2.at(va2_index); + if (temp_va.empty()) { + name += "%s"; + continue; + } + name += temp_va; + va2_index++; + } else if (temp == 'u' || temp == 'd' || temp == 'i') { + if (va1_index >= this->va1.size()) { + // name += "%"; + // name += temp; + name += "#"; + continue; + } + auto temp_va = va1.at(va1_index); + name += std::to_string(temp_va); + va1_index++; + } else if (temp == 'l') { + fmt_model = true; + } + } else { + name += temp; } - return name; + } + return name; } sd::checker_result_string::~checker_result_string() { - this->va1.clear(); - this->va2.clear(); + this->va1.clear(); + this->va2.clear(); } sd::checker_result_ops *sd::checker_result_ops::copy() { - auto c = new checker_result_ops(); - c->checker_result_ops::copy(this); - return c; + auto c = new checker_result_ops(); + c->checker_result_ops::copy(this); + return c; } void sd::checker_result_ops::copy(sd::checker_result_ops *c) { - checker_result::copy(c); - this->ops_structure = c->ops_structure; - this->ops_name = c->ops_name; + checker_result::copy(c); + this->ops_structure = c->ops_structure; + this->ops_name = c->ops_name; } nlohmann::json *sd::checker_result_ops::to_json() { - auto j = checker_result::to_json(); - (*j)["d_ops_structure"] = this->ops_structure; - (*j)["d_ops_name"] = this->ops_name; - return j; + auto j = checker_result::to_json(); + (*j)["d_ops_structure"] = this->ops_structure; + (*j)["d_ops_name"] = this->ops_name; + return j; } void sd::checker_result_ops::from_json(nlohmann::json j) { - checker_result::from_json(j); - if (j.contains("d_ops_structure") && j["d_ops_structure"].is_string() && - j["d_ops_structure"].get().empty()) { - this->ops_structure = j["d_ops_structure"].get(); - } else { - yhao_log(3, "d_ops_structure: no value"); - } - if (j.contains("d_ops_name") && j["d_ops_name"].is_string() && !j["d_ops_name"].get().empty()) { - this->ops_name = j["d_ops_name"].get(); - } else { - yhao_log(3, "d_ops_name: no value"); - } + checker_result::from_json(j); + if (j.contains("d_ops_structure") && j["d_ops_structure"].is_string() && + j["d_ops_structure"].get().empty()) { + this->ops_structure = j["d_ops_structure"].get(); + } else { + yhao_log(3, "d_ops_structure: no value"); + } + if (j.contains("d_ops_name") && j["d_ops_name"].is_string() && + !j["d_ops_name"].get().empty()) { + this->ops_name = j["d_ops_name"].get(); + } else { + yhao_log(3, "d_ops_name: no value"); + } } sd::checker_result *sd::make_checker(sd::checker_type ct) { - checker_result *cr; - switch (ct) { - case checker_type::dev_type: - case checker_type::dri_type: - case checker_type::dri_major: - case checker_type::dri_minor: - case checker_type::file_fd: { - cr = new checker_result_number(); - break; - } - case checker_type::dev_name: - case checker_type::dri_name: { - cr = new checker_result_string(); - break; - } - case checker_type::dri_ops: - case checker_type::file_ops: { - cr = new checker_result_ops(); - break; - } - case checker_type::file_install: { - cr = new checker_result(); - break; - } - default: { - cr = new checker_result(); - yhao_log(3, "bad ct"); - } - } - return cr; + checker_result *cr; + switch (ct) { + case checker_type::dev_type: + case checker_type::dri_type: + case checker_type::dri_major: + case checker_type::dri_minor: + case checker_type::file_fd: { + cr = new checker_result_number(); + break; + } + case checker_type::dev_name: + case checker_type::dri_name: { + cr = new checker_result_string(); + break; + } + case checker_type::dri_ops: + case checker_type::file_ops: { + cr = new checker_result_ops(); + break; + } + case checker_type::file_install: { + cr = new checker_result(); + break; + } + default: { + cr = new checker_result(); + yhao_log(3, "bad ct"); + } + } + return cr; } int64_t sd::match_call_chain(sd::checker_result *a, sd::checker_result *b) { - int64_t ret = 0; - if (a == nullptr || b == nullptr) { - return ret; - } - int64_t size = a->call_chain.size() > b->call_chain.size() ? b->call_chain.size() : a->call_chain.size(); - while (ret < size && (a->call_chain.at(ret) == b->call_chain.at(ret))) { - ret++; - } + int64_t ret = 0; + if (a == nullptr || b == nullptr) { return ret; + } + int64_t size = a->call_chain.size() > b->call_chain.size() + ? b->call_chain.size() + : a->call_chain.size(); + while (ret < size && (a->call_chain.at(ret) == b->call_chain.at(ret))) { + ret++; + } + return ret; } diff --git a/lib/KnowledgeLib/checker.h b/lib/KnowledgeLib/checker.h index a65e178..b475179 100644 --- a/lib/KnowledgeLib/checker.h +++ b/lib/KnowledgeLib/checker.h @@ -13,197 +13,188 @@ #define MAX_CALLEE_COUNT 100000000 namespace sd { - enum checker_type { - dev_name = 0, - dev_type, - dri_ops, - dri_type, - dri_major, - dri_minor, - dri_name, - // for open - open_indirect, - // for file of non-open fd - file_fd, - file_ops, - file_install, - }; - - const static std::string checker_type_name[] = { - "dev_name", - "dev_type", - "dri_ops", - "dri_type", - "dri_major", - "dri_minor", - "dri_name", - "open_indirect", - "file_fd", - "file_ops", - "file_install", - }; +enum checker_type { + dev_name = 0, + dev_type, + dri_ops, + dri_type, + dri_major, + dri_minor, + dri_name, + // for open + open_indirect, + // for file of non-open fd + file_fd, + file_ops, + file_install, +}; - const static std::string syscall_name[]{ - "4-open", - "4-read", - "4-write", - "4-ioctl", - }; +const static std::string checker_type_name[] = { + "dev_name", "dev_type", "dri_ops", "dri_type", + "dri_major", "dri_minor", "dri_name", "open_indirect", + "file_fd", "file_ops", "file_install", +}; - class checker { - public: - checker_type ct; - uint64_t id; - std::string name; +const static std::string syscall_name[]{ + "4-open", + "4-read", + "4-write", + "4-ioctl", +}; - std::string structure; - int64_t offset; +class checker { + public: + checker_type ct; + uint64_t id; + std::string name; - std::string function; - int64_t object; - int64_t value; - int64_t value_offset; - bool field; + std::string structure; + int64_t offset; - virtual ~checker(); + std::string function; + int64_t object; + int64_t value; + int64_t value_offset; + bool field; - virtual checker *copy(); + virtual ~checker(); - void copy(checker *c); + virtual checker *copy(); - virtual nlohmann::json *to_json(); + void copy(checker *c); - virtual void from_json(nlohmann::json j); + virtual nlohmann::json *to_json(); - virtual std::string print(); - }; + virtual void from_json(nlohmann::json j); - class offset_chain_offset { - public: - int64_t offset; - // TODO: later: support symbolic offset - std::string type_str; - // TODO: later: try to support llvm number instead of string - // TODO: later: this->llvm_module->getIdentifiedStructTypes() - llvm::Type *type; - offset_chain_offset *next; + virtual std::string print(); +}; - offset_chain_offset(); +class offset_chain_offset { + public: + int64_t offset; + // TODO: later: support symbolic offset + std::string type_str; + // TODO: later: try to support llvm number instead of string + // TODO: later: this->llvm_module->getIdentifiedStructTypes() + llvm::Type *type; + offset_chain_offset *next; - virtual ~offset_chain_offset(); + offset_chain_offset(); - void copy(offset_chain_offset *oc); + virtual ~offset_chain_offset(); - nlohmann::json to_json(); + void copy(offset_chain_offset *oc); - void read_value_from_json(nlohmann::json j); - }; + nlohmann::json to_json(); - class offset_chain_base { - public: - std::string base; - std::string type_str; - llvm::Type *type; - offset_chain_offset *next; + void read_value_from_json(nlohmann::json j); +}; - offset_chain_base(); +class offset_chain_base { + public: + std::string base; + std::string type_str; + llvm::Type *type; + offset_chain_offset *next; - virtual ~offset_chain_base(); + offset_chain_base(); - void copy(offset_chain_base *oc); + virtual ~offset_chain_base(); - nlohmann::json to_json(); + void copy(offset_chain_base *oc); - void read_value_from_json(nlohmann::json j); - }; + nlohmann::json to_json(); - class checker_result : public checker { - public: - uint64_t hash; - llvm::Instruction *inst{}; - std::string inst_strID; - std::string inst_str; - int64_t match; + void read_value_from_json(nlohmann::json j); +}; - void setInst(llvm::Instruction *i); +class checker_result : public checker { + public: + uint64_t hash; + llvm::Instruction *inst{}; + std::string inst_strID; + std::string inst_str; + int64_t match; - void setInst(llvm::Module *m); + void setInst(llvm::Instruction *i); - offset_chain_base *offset_chain{}; - std::vector call_chain; + void setInst(llvm::Module *m); - // statistic - bool has_function_pointer = false; + offset_chain_base *offset_chain{}; + std::vector call_chain; - void push_call_chain(llvm::Instruction *i); + // statistic + bool has_function_pointer = false; - void pop_call_chain(); + void push_call_chain(llvm::Instruction *i); - void compute_hash(); + void pop_call_chain(); - ~checker_result() override; + void compute_hash(); - checker_result *copy() override; + ~checker_result() override; - void copy(checker_result *c); + checker_result *copy() override; - nlohmann::json *to_json() override; + void copy(checker_result *c); - void from_json(nlohmann::json j) override; + nlohmann::json *to_json() override; - std::string get_call_chain(const std::string& linux_kernel_version = ""); - }; + void from_json(nlohmann::json j) override; - class checker_result_number : public checker_result { - public: - int64_t number; + std::string get_call_chain(const std::string &linux_kernel_version = ""); +}; - checker_result_number *copy() override; +class checker_result_number : public checker_result { + public: + int64_t number; - void copy(checker_result_number *c); + checker_result_number *copy() override; - nlohmann::json *to_json() override; + void copy(checker_result_number *c); - void from_json(nlohmann::json j) override; - }; + nlohmann::json *to_json() override; - class checker_result_string : public checker_result { - public: - std::string fmt; - std::vector va1; - std::vector va2; + void from_json(nlohmann::json j) override; +}; - checker_result_string *copy() override; +class checker_result_string : public checker_result { + public: + std::string fmt; + std::vector va1; + std::vector va2; - void copy(checker_result_string *c); + checker_result_string *copy() override; - nlohmann::json *to_json() override; + void copy(checker_result_string *c); - void from_json(nlohmann::json j) override; + nlohmann::json *to_json() override; - std::string to_string(); + void from_json(nlohmann::json j) override; - ~checker_result_string() override; - }; + std::string to_string(); - class checker_result_ops : public checker_result { - public: - std::string ops_structure; - std::string ops_name; + ~checker_result_string() override; +}; - checker_result_ops *copy() override; +class checker_result_ops : public checker_result { + public: + std::string ops_structure; + std::string ops_name; - void copy(checker_result_ops *c); + checker_result_ops *copy() override; - nlohmann::json *to_json() override; + void copy(checker_result_ops *c); - void from_json(nlohmann::json j) override; - }; + nlohmann::json *to_json() override; - checker_result *make_checker(checker_type ct); + void from_json(nlohmann::json j) override; +}; - int64_t match_call_chain(checker_result *a, checker_result *b); -} +checker_result *make_checker(checker_type ct); +int64_t match_call_chain(checker_result *a, checker_result *b); +} // namespace sd -#endif //INC_2021_TEMPLATE_CHECKER_H +#endif // INC_2021_TEMPLATE_CHECKER_H diff --git a/lib/KnowledgeLib/device_driver.cpp b/lib/KnowledgeLib/device_driver.cpp index 831d1b3..2dc98aa 100644 --- a/lib/KnowledgeLib/device_driver.cpp +++ b/lib/KnowledgeLib/device_driver.cpp @@ -3,240 +3,238 @@ // #include "device_driver.h" + #include "../AnalysisLib/entry_function.h" #include "../ToolLib/llvm_related.h" void sd::device_driver::set_kind() { - this->kind |= 1 << ops->ct; - for (auto cr: this->name) { - kind |= 1 << cr->ct; - } - for (auto cr: this->number) { - kind |= 1 << cr->ct; - } - for (auto cr: this->file_install) { - kind |= 1 << cr->ct; - } - for (auto cr: this->file_fd) { - kind |= 1 << cr->ct; - } + this->kind |= 1 << ops->ct; + for (auto cr : this->name) { + kind |= 1 << cr->ct; + } + for (auto cr : this->number) { + kind |= 1 << cr->ct; + } + for (auto cr : this->file_install) { + kind |= 1 << cr->ct; + } + for (auto cr : this->file_fd) { + kind |= 1 << cr->ct; + } } -bool sd::device_driver::is_only_driver() const { - return this->name.empty(); -} +bool sd::device_driver::is_only_driver() const { return this->name.empty(); } void sd::device_driver::update_structure_type() { - for (auto temp: this->cmd) { - for (auto temp_1: temp.second->in_types) { - auto ty = get_real_type(temp_1.second); - if (ty == nullptr) { - continue; - } - auto st = llvm::dyn_cast(ty); - if (st == nullptr) { - continue; - } - this->structures.insert(st); - } - for (auto temp_1: temp.second->out_types) { - auto ty = get_real_type(temp_1.second); - if (ty == nullptr) { - continue; - } - auto st = llvm::dyn_cast(ty); - if (st == nullptr) { - continue; - } - this->structures.insert(st); + for (auto temp : this->cmd) { + for (auto temp_1 : temp.second->in_types) { + auto ty = get_real_type(temp_1.second); + if (ty == nullptr) { + continue; + } + auto st = llvm::dyn_cast(ty); + if (st == nullptr) { + continue; + } + this->structures.insert(st); + } + for (auto temp_1 : temp.second->out_types) { + auto ty = get_real_type(temp_1.second); + if (ty == nullptr) { + continue; + } + auto st = llvm::dyn_cast(ty); + if (st == nullptr) { + continue; + } + this->structures.insert(st); + } + } + std::set new_type_set(this->structures); + while (!new_type_set.empty()) { + std::set temp_type_set; + for (auto temp : new_type_set) { + for (auto et : temp->elements()) { + et = get_real_type(et); + auto st = llvm::dyn_cast(et); + if (st == nullptr) { + continue; } - } - std::set new_type_set(this->structures); - while (!new_type_set.empty()) { - std::set temp_type_set; - for (auto temp: new_type_set) { - for (auto et: temp->elements()) { - et = get_real_type(et); - auto st = llvm::dyn_cast(et); - if (st == nullptr) { - continue; - } - if (this->structures.find(st) != this->structures.end()) { - continue; - } else { - this->structures.insert(st); - } - temp_type_set.insert(st); - } + if (this->structures.find(st) != this->structures.end()) { + continue; + } else { + this->structures.insert(st); } - new_type_set.clear(); - new_type_set.insert(temp_type_set.begin(), temp_type_set.end()); + temp_type_set.insert(st); + } } + new_type_set.clear(); + new_type_set.insert(temp_type_set.begin(), temp_type_set.end()); + } } std::string sd::device_driver::print() { - std::string str; - std::string ret; - int64_t debug = 1; - update_structure_type(); - get_resource(); - ret += "*************************************************\n"; - ret += "ops_name json: \n" + ops->to_json()->dump(2) + "\n"; - ret += "ops_name: " + ops->ops_name + "\n"; - ret += "parent: " + parent->get_entry_function_name() + "\n"; - if (non_open_parent != nullptr) { - ret += "non_open_parent: " + std::to_string(non_open_parent->value) + "\n"; - } - for (auto temp: name) { - ret += "device name json: \n" + temp->to_json()->dump(2) + "\n"; - ret += "device name string: " + temp->to_string() + "\n"; - } - if (debug >= DEBUG_LEVEL) { - for (auto temp: cmd) { - ret += " cmd: " + std::to_string(temp.first) + "\n"; - for (auto temp_1: temp.second->in_types) { - yhao_print(debug, temp_1.first->print, str) - ret += " in val: " + str + "\n"; - if (temp_1.second == nullptr) { - - } else { - yhao_print(debug, temp_1.second->print, str) - ret += " in type: " + str + "\n"; - } - } - for (auto temp_1: temp.second->out_types) { - yhao_print(debug, temp_1.first->print, str) - ret += " out val: " + str + "\n"; - if (temp_1.second == nullptr) { - - } else { - yhao_print(debug, temp_1.second->print, str) - ret += " out type: " + str + "\n"; - } - } + std::string str; + std::string ret; + int64_t debug = 1; + update_structure_type(); + get_resource(); + ret += "*************************************************\n"; + ret += "ops_name json: \n" + ops->to_json()->dump(2) + "\n"; + ret += "ops_name: " + ops->ops_name + "\n"; + ret += "parent: " + parent->get_entry_function_name() + "\n"; + if (non_open_parent != nullptr) { + ret += "non_open_parent: " + std::to_string(non_open_parent->value) + "\n"; + } + for (auto temp : name) { + ret += "device name json: \n" + temp->to_json()->dump(2) + "\n"; + ret += "device name string: " + temp->to_string() + "\n"; + } + if (debug >= DEBUG_LEVEL) { + for (auto temp : cmd) { + ret += " cmd: " + std::to_string(temp.first) + "\n"; + for (auto temp_1 : temp.second->in_types) { + yhao_print(debug, temp_1.first->print, str) ret += + " in val: " + str + "\n"; + if (temp_1.second == nullptr) { + } else { + yhao_print(debug, temp_1.second->print, str) ret += + " in type: " + str + "\n"; } - for (auto temp: this->structures) { - yhao_print(debug, temp->print, str) - ret += "all type: " + str + "\n"; + } + for (auto temp_1 : temp.second->out_types) { + yhao_print(debug, temp_1.first->print, str) ret += + " out val: " + str + "\n"; + if (temp_1.second == nullptr) { + } else { + yhao_print(debug, temp_1.second->print, str) ret += + " out type: " + str + "\n"; } + } + } + for (auto temp : this->structures) { + yhao_print(debug, temp->print, str) ret += "all type: " + str + "\n"; } - ret += "=================================================\n"; - return ret; + } + ret += "=================================================\n"; + return ret; } std::string sd::device_driver::get_id() { - if (this->id.empty()) { - if (this->parent->parent == nullptr) { - } else { - this->id += Annotation_Symbol"parent id hash: " + this->parent->parent->get_id_hash() + "\n"; - } - this->id += Annotation_Symbol"call chain: \n"; - this->id += ops->get_call_chain(this->linux_kernel_version); - } - return this->id; + if (this->id.empty()) { + if (this->parent->parent == nullptr) { + } else { + this->id += Annotation_Symbol "parent id hash: " + + this->parent->parent->get_id_hash() + "\n"; + } + this->id += Annotation_Symbol "call chain: \n"; + this->id += ops->get_call_chain(this->linux_kernel_version); + } + return this->id; } std::string sd::device_driver::get_id_hash() { - if (this->id_hash.empty()) { - std::hash str_hash; - this->id_hash = std::to_string(str_hash(this->get_id())); - yhao_log(1, "id: " + this->get_id()); - yhao_log(1, "id hash: "); - } - return this->id_hash; + if (this->id_hash.empty()) { + std::hash str_hash; + this->id_hash = std::to_string(str_hash(this->get_id())); + yhao_log(1, "id: " + this->get_id()); + yhao_log(1, "id hash: "); + } + return this->id_hash; } std::string sd::device_driver::get_id_real_hash() { - if (this->id_real_hash.empty()) { - std::string temp; + if (this->id_real_hash.empty()) { + std::string temp; - if (this->parent->parent != nullptr) { - temp += get_id_hash(); - } + if (this->parent->parent != nullptr) { + temp += get_id_hash(); + } - temp += this->ops->ops_name; + temp += this->ops->ops_name; - entry_function *temp_parent; - if (this->syscalls.find(syscall_name[3]) == this->syscalls.end()) { - temp_parent = nullptr; - } else { - temp_parent = this->syscalls[syscall_name[3]]; - } - std::set fps; - while (temp_parent != nullptr && temp_parent->parent != nullptr) { - for (auto temp_1: temp_parent->function_pointers) { - fps.insert(temp_1->llvm_function); - } - temp_parent = temp_parent->parent->parent; - } - for (auto temp_func: fps) { - temp += temp_func->getName().str(); - } - - std::hash str_hash; - this->id_real_hash = std::to_string(str_hash(temp)); + entry_function *temp_parent; + if (this->syscalls.find(syscall_name[3]) == this->syscalls.end()) { + temp_parent = nullptr; + } else { + temp_parent = this->syscalls[syscall_name[3]]; + } + std::set fps; + while (temp_parent != nullptr && temp_parent->parent != nullptr) { + for (auto temp_1 : temp_parent->function_pointers) { + fps.insert(temp_1->llvm_function); + } + temp_parent = temp_parent->parent->parent; + } + for (auto temp_func : fps) { + temp += temp_func->getName().str(); } - return this->id_real_hash; + + std::hash str_hash; + this->id_real_hash = std::to_string(str_hash(temp)); + } + return this->id_real_hash; } std::string sd::device_driver::get_resource() { - if (this->resource.empty()) { - if (ops->ct == checker_type::dri_ops) { - this->resource = "fd_" + this->get_id_hash() + "_fd"; - } else if (ops->ct == checker_type::file_ops) { - if (this->parent->parent == nullptr) { - this->resource = "fd_" + this->get_id_hash() + "_fd"; - } else if (this->non_open_parent == nullptr) { - this->resource = "not_find_non_open_parent"; - yhao_log(3, "this->non_open_parent == nullptr"); - yhao_log(2, this->get_id()); - } else { - this->resource = this->non_open_parent->generate_resource_name(); - } - } else { - yhao_log(3, "ops->ct"); - } - } - return this->resource; + if (this->resource.empty()) { + if (ops->ct == checker_type::dri_ops) { + this->resource = "fd_" + this->get_id_hash() + "_fd"; + } else if (ops->ct == checker_type::file_ops) { + if (this->parent->parent == nullptr) { + this->resource = "fd_" + this->get_id_hash() + "_fd"; + } else if (this->non_open_parent == nullptr) { + this->resource = "not_find_non_open_parent"; + yhao_log(3, "this->non_open_parent == nullptr"); + yhao_log(2, this->get_id()); + } else { + this->resource = this->non_open_parent->generate_resource_name(); + } + } else { + yhao_log(3, "ops->ct"); + } + } + return this->resource; } bool sd::device_driver::operator<(const sd::device_driver &rhs) const { - int64_t index_1 = 0, index_2 = 0; - auto temp = this; - while (temp != nullptr && temp->parent != nullptr) { - temp = temp->parent->parent; - index_1++; - } - temp = &rhs; - while (temp != nullptr && temp->parent != nullptr) { - temp = temp->parent->parent; - index_2++; - } - if (index_1 == index_2) { - if (this->name.size() < rhs.name.size()) { - return true; - } - return false; - } else if (index_1 < index_2) { - return true; - } else if (index_1 > index_2) { - return false; - } + int64_t index_1 = 0, index_2 = 0; + auto temp = this; + while (temp != nullptr && temp->parent != nullptr) { + temp = temp->parent->parent; + index_1++; + } + temp = &rhs; + while (temp != nullptr && temp->parent != nullptr) { + temp = temp->parent->parent; + index_2++; + } + if (index_1 == index_2) { + if (this->name.size() < rhs.name.size()) { + return true; + } + return false; + } else if (index_1 < index_2) { return true; + } else if (index_1 > index_2) { + return false; + } + return true; } bool sd::device_driver::operator>(const sd::device_driver &rhs) const { - return rhs < *this; + return rhs < *this; } bool sd::device_driver::operator<=(const sd::device_driver &rhs) const { - return !(rhs < *this); + return !(rhs < *this); } bool sd::device_driver::operator>=(const sd::device_driver &rhs) const { - return !(*this < rhs); + return !(*this < rhs); } std::string sd::cmd_info::generate_resource_name() { - return "fd_" + dd->get_id_hash() + "_cmd_" + std::to_string(this->value) + "_fd"; + return "fd_" + dd->get_id_hash() + "_cmd_" + std::to_string(this->value) + + "_fd"; } diff --git a/lib/KnowledgeLib/device_driver.h b/lib/KnowledgeLib/device_driver.h index 7e35ce0..7491001 100644 --- a/lib/KnowledgeLib/device_driver.h +++ b/lib/KnowledgeLib/device_driver.h @@ -10,92 +10,90 @@ #include "checker.h" namespace sd { - class entry_function; - class device_driver; +class entry_function; - class cmd_info { - public: - llvm::Instruction *i{}; - uint64_t value{}; - llvm::BasicBlock *b{}; - std::map in_types; - std::map out_types; - bool non_open = false; - device_driver *dd{}; +class device_driver; - std::string generate_resource_name(); +class cmd_info { + public: + llvm::Instruction *i{}; + uint64_t value{}; + llvm::BasicBlock *b{}; + std::map in_types; + std::map out_types; + bool non_open = false; + device_driver *dd{}; - // statistic - bool in_entry_function = false; - bool in_indirect_call = false; - }; + std::string generate_resource_name(); - class device_driver { - public: - device_driver() { - no_cmd = new cmd_info(); - }; + // statistic + bool in_entry_function = false; + bool in_indirect_call = false; +}; - void set_kind(); +class device_driver { + public: + device_driver() { no_cmd = new cmd_info(); }; - [[nodiscard]] bool is_only_driver() const; + void set_kind(); - void update_structure_type(); + [[nodiscard]] bool is_only_driver() const; - std::string print(); + void update_structure_type(); - // the id for each driver - std::string get_id(); + std::string print(); - std::string get_id_hash(); + // the id for each driver + std::string get_id(); - // whether the two device driver are the similar - std::string get_id_real_hash(); + std::string get_id_hash(); - std::string get_resource(); + // whether the two device driver are the similar + std::string get_id_real_hash(); - bool operator<(const device_driver &rhs) const; + std::string get_resource(); - bool operator>(const device_driver &rhs) const; + bool operator<(const device_driver &rhs) const; - bool operator<=(const device_driver &rhs) const; + bool operator>(const device_driver &rhs) const; - bool operator>=(const device_driver &rhs) const; + bool operator<=(const device_driver &rhs) const; - public: - std::string linux_kernel_version; - int64_t kind = 0; + bool operator>=(const device_driver &rhs) const; - checker_result_ops *ops{}; - std::vector name; - std::vector number; - std::vector file_install; - std::vector file_fd; + public: + std::string linux_kernel_version; + int64_t kind = 0; - // cmd and arg - std::map cmd; - cmd_info *no_cmd{}; - std::set structures; - std::map structure_name; + checker_result_ops *ops{}; + std::vector name; + std::vector number; + std::vector file_install; + std::vector file_fd; - entry_function *parent = nullptr; - cmd_info *non_open_parent = nullptr; + // cmd and arg + std::map cmd; + cmd_info *no_cmd{}; + std::set structures; + std::map structure_name; - // id based on parent and call chain - // different device driver in source code - std::string id; - std::string id_hash; + entry_function *parent = nullptr; + cmd_info *non_open_parent = nullptr; - // id based on the ops and whether they have different function pointers - // different device driver in template - std::string id_real_hash; + // id based on parent and call chain + // different device driver in source code + std::string id; + std::string id_hash; - std::string resource; + // id based on the ops and whether they have different function pointers + // different device driver in template + std::string id_real_hash; - std::map syscalls; - std::set entries; - }; -} + std::string resource; + std::map syscalls; + std::set entries; +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_DEVICE_DRIVER_H +#endif // INC_2021_TEMPLATE_DEVICE_DRIVER_H diff --git a/lib/KnowledgeLib/knowledge.cpp b/lib/KnowledgeLib/knowledge.cpp index b370dae..9812662 100644 --- a/lib/KnowledgeLib/knowledge.cpp +++ b/lib/KnowledgeLib/knowledge.cpp @@ -3,590 +3,595 @@ // #include "knowledge.h" + #include "../ToolLib/log.h" sd::K_function::K_function() = default; sd::K_function::K_function(const nlohmann::json &j) { - if (j.contains("1-file") && j["1-file"].is_string()) { - this->file = j["1-file"].get(); - } else { - yhao_log(0, "1-file"); - } - if (j.contains("2-name") && j["2-name"].is_string()) { - this->name = j["2-name"].get(); - } else { - yhao_log(3, "2-name"); - } - - if (j.contains("4-object") && j["4-object"].is_number_integer()) { - this->object = j["4-object"].get(); - } else { - this->object = -2; - yhao_log(0, "4-object"); - } - if (j.contains("5-field") && j["5-field"].is_boolean()) { - this->field = j["5-field"].get(); - } else { - yhao_log(0, "K_function: 5-field"); - } - - if (j.contains("6-value") && j["6-value"].is_number_integer()) { - this->value = j["6-value"].get(); - } else { - this->value = -2; - yhao_log(3, "6-value"); - } - if (j.contains("7-offset") && j["7-offset"].is_number_integer()) { - this->offset = j["7-offset"].get(); - } else { - this->offset = -2; - yhao_log(0, "K_function: 7-offset"); - } - if (j.contains("8-fmt") && j["8-fmt"].is_boolean()) { - this->fmt = j["8-fmt"].get(); - } else { - yhao_log(0, "K_function: 8-fmt"); - } + if (j.contains("1-file") && j["1-file"].is_string()) { + this->file = j["1-file"].get(); + } else { + yhao_log(0, "1-file"); + } + if (j.contains("2-name") && j["2-name"].is_string()) { + this->name = j["2-name"].get(); + } else { + yhao_log(3, "2-name"); + } + + if (j.contains("4-object") && j["4-object"].is_number_integer()) { + this->object = j["4-object"].get(); + } else { + this->object = -2; + yhao_log(0, "4-object"); + } + if (j.contains("5-field") && j["5-field"].is_boolean()) { + this->field = j["5-field"].get(); + } else { + yhao_log(0, "K_function: 5-field"); + } + + if (j.contains("6-value") && j["6-value"].is_number_integer()) { + this->value = j["6-value"].get(); + } else { + this->value = -2; + yhao_log(3, "6-value"); + } + if (j.contains("7-offset") && j["7-offset"].is_number_integer()) { + this->offset = j["7-offset"].get(); + } else { + this->offset = -2; + yhao_log(0, "K_function: 7-offset"); + } + if (j.contains("8-fmt") && j["8-fmt"].is_boolean()) { + this->fmt = j["8-fmt"].get(); + } else { + yhao_log(0, "K_function: 8-fmt"); + } } nlohmann::json sd::K_function::to_json() { - auto *j = new nlohmann::json(); - (*j)["1-file"] = this->file; - (*j)["2-name"] = this->name; + auto *j = new nlohmann::json(); + (*j)["1-file"] = this->file; + (*j)["2-name"] = this->name; - (*j)["4-object"] = this->object; - (*j)["5-field"] = this->field; + (*j)["4-object"] = this->object; + (*j)["5-field"] = this->field; - (*j)["6-value"] = this->value; - (*j)["7-offset"] = this->offset; - (*j)["8-fmt"] = this->fmt; - return *j; + (*j)["6-value"] = this->value; + (*j)["7-offset"] = this->offset; + (*j)["8-fmt"] = this->fmt; + return *j; } sd::K_variable::K_variable() = default; sd::K_variable::K_variable(const nlohmann::json &j) { - std::string str; - - if (j.contains("1-offset") && j["1-offset"].is_number_integer()) { - this->offset = j["1-offset"].get(); + std::string str; + + if (j.contains("1-offset") && j["1-offset"].is_number_integer()) { + this->offset = j["1-offset"].get(); + } else { + this->offset = -2; + yhao_log(0, "1-offset"); + } + if (j.contains("2-function")) { + if (j["2-function"].is_array()) { + for (const auto &f : j["2-function"]) { + this->function.push_back(new K_function(f)); + } } else { - this->offset = -2; - yhao_log(0, "1-offset"); - } - if (j.contains("2-function")) { - if (j["2-function"].is_array()) { - for (const auto &f: j["2-function"]) { - this->function.push_back(new K_function(f)); - } - } else { - yhao_log(0, "2-function: \n" + j.dump(2)); - } + yhao_log(0, "2-function: \n" + j.dump(2)); } + } - if (j.contains("3-structure") && j["3-structure"].is_string()) { - this->structure = j["3-structure"].get(); - } else { - yhao_log(0, "K_variable: 3-structure"); - } + if (j.contains("3-structure") && j["3-structure"].is_string()) { + this->structure = j["3-structure"].get(); + } else { + yhao_log(0, "K_variable: 3-structure"); + } - for (auto temp: syscall_name) { - if (j.contains(temp) && j[temp].is_number_integer()) { - this->functions_index[temp] = j[temp].get(); - } else { - this->functions_index[temp] = -2; - yhao_log(0, "not find K_variable: " + str); - } + for (auto temp : syscall_name) { + if (j.contains(temp) && j[temp].is_number_integer()) { + this->functions_index[temp] = j[temp].get(); + } else { + this->functions_index[temp] = -2; + yhao_log(0, "not find K_variable: " + str); } + } } nlohmann::json sd::K_variable::to_json() { - auto *j = new nlohmann::json(); - (*j)["1-offset"] = this->offset; - for (auto f: this->function) { - (*j)["2-function"].push_back(f->to_json()); - } - (*j)["3-structure"] = this->structure; - for (const auto &temp: syscall_name) { - (*j)[temp] = this->functions_index[temp]; - } - return *j; + auto *j = new nlohmann::json(); + (*j)["1-offset"] = this->offset; + for (auto f : this->function) { + (*j)["2-function"].push_back(f->to_json()); + } + (*j)["3-structure"] = this->structure; + for (const auto &temp : syscall_name) { + (*j)[temp] = this->functions_index[temp]; + } + return *j; } sd::K_variable::~K_variable() { - for (auto temp: function) { - delete temp; - } + for (auto temp : function) { + delete temp; + } }; -int64_t sd::K_base::find_k_variable(const std::string &structure1, int64_t offset, sd::K_variable **k) { - if (structure1 == this->structure) { - for (const auto &v: variable) { - if (v.second != nullptr && offset == v.second->offset) { - *k = v.second; - return 0; - } - } +int64_t sd::K_base::find_k_variable(const std::string &structure1, + int64_t offset, sd::K_variable **k) { + if (structure1 == this->structure) { + for (const auto &v : variable) { + if (v.second != nullptr && offset == v.second->offset) { + *k = v.second; + return 0; + } } - return 1; + } + return 1; } sd::K_base::K_base() = default; void sd::K_base::read(const nlohmann::json &json) { - std::string key; - - key = "1-name"; - if (json.contains(key) && json[key].is_string()) { - this->name = json[key].get(); - } else { - yhao_log(0, key); - } - - key = "2-structure"; - if (json.contains(key) && json[key].is_string()) { - this->structure = json[key].get(); - } else { - yhao_log(3, key); - } + std::string key; + + key = "1-name"; + if (json.contains(key) && json[key].is_string()) { + this->name = json[key].get(); + } else { + yhao_log(0, key); + } + + key = "2-structure"; + if (json.contains(key) && json[key].is_string()) { + this->structure = json[key].get(); + } else { + yhao_log(3, key); + } } sd::K_base::~K_base() { - for (const auto &temp: variable) { - delete temp.second; - } + for (const auto &temp : variable) { + delete temp.second; + } } nlohmann::json sd::K_base::to_json() { - j.clear(); - j["1-name"] = this->name; - j["2-structure"] = this->structure; - for (auto v: variable) { - if (v.second != nullptr) { - (j)[v.first] = v.second->to_json(); - } - } - return this->j; + j.clear(); + j["1-name"] = this->name; + j["2-structure"] = this->structure; + for (auto v : variable) { + if (v.second != nullptr) { + (j)[v.first] = v.second->to_json(); + } + } + return this->j; } sd::K_device::K_device() = default; sd::K_device::K_device(const nlohmann::json &json) { - K_base::read(json); - std::string key; - - key = "3-dev_name"; - if (json.contains(key) && json[key].is_object()) { - this->dev_name = new K_variable(json[key]); - this->variable[key] = this->dev_name; - } else { - yhao_log(3, key); - } - - key = "4-dev_type"; - if (json.contains(key) && json[key].is_object()) { - this->dev_type = new K_variable(json[key]); - this->variable[key] = this->dev_type; - } else { - yhao_log(3, key); - } + K_base::read(json); + std::string key; + + key = "3-dev_name"; + if (json.contains(key) && json[key].is_object()) { + this->dev_name = new K_variable(json[key]); + this->variable[key] = this->dev_name; + } else { + yhao_log(3, key); + } + + key = "4-dev_type"; + if (json.contains(key) && json[key].is_object()) { + this->dev_type = new K_variable(json[key]); + this->variable[key] = this->dev_type; + } else { + yhao_log(3, key); + } } nlohmann::json sd::K_device::to_json() { - K_base::to_json(); - return j; + K_base::to_json(); + return j; } sd::K_driver::K_driver() = default; sd::K_driver::K_driver(const nlohmann::json &json) { - K_base::read(json); - std::string key; - - key = "0-major_value"; - if (json.contains(key) && json[key].is_number_integer()) { - this->major_value = json[key].get(); + K_base::read(json); + std::string key; + + key = "0-major_value"; + if (json.contains(key) && json[key].is_number_integer()) { + this->major_value = json[key].get(); + } else { + this->major_value = -2; + yhao_log(0, key); + } + + key = "3-dri_ops"; + if (json.contains(key) && json[key].is_object()) { + this->dri_ops = new K_variable(json[key]); + this->variable[key] = this->dri_ops; + } else { + yhao_log(3, key + ": \n" + json.dump(2)); + } + + key = "4-dri_type"; + if (json.contains(key)) { + if (json[key].is_object()) { + this->dri_type = new K_variable(json[key]); + this->variable[key] = this->dri_type; } else { - this->major_value = -2; - yhao_log(0, key); + yhao_log(0, key); } + } - key = "3-dri_ops"; - if (json.contains(key) && json[key].is_object()) { - this->dri_ops = new K_variable(json[key]); - this->variable[key] = this->dri_ops; + key = "5-dri_major"; + if (json.contains(key)) { + if (json[key].is_object()) { + this->dri_major = new K_variable(json[key]); + this->variable[key] = this->dri_major; } else { - yhao_log(3, key + ": \n" + json.dump(2)); - } - - key = "4-dri_type"; - if (json.contains(key)) { - if (json[key].is_object()) { - this->dri_type = new K_variable(json[key]); - this->variable[key] = this->dri_type; - } else { - yhao_log(0, key); - } + yhao_log(0, key); } + } - key = "5-dri_major"; - if (json.contains(key)) { - if (json[key].is_object()) { - this->dri_major = new K_variable(json[key]); - this->variable[key] = this->dri_major; - } else { - yhao_log(0, key); - } - } - - key = "6-dri_minor"; - if (json.contains(key)) { - if (json[key].is_object()) { - this->dri_minor = new K_variable(json[key]); - this->variable[key] = this->dri_minor; - } else { - yhao_log(0, key); - } + key = "6-dri_minor"; + if (json.contains(key)) { + if (json[key].is_object()) { + this->dri_minor = new K_variable(json[key]); + this->variable[key] = this->dri_minor; + } else { + yhao_log(0, key); } + } - key = "7-dri_name"; - if (json.contains(key)) { - if (json[key].is_object()) { - this->dri_name = new K_variable(json[key]); - this->variable[key] = this->dri_name; - } else { - yhao_log(0, key); - } + key = "7-dri_name"; + if (json.contains(key)) { + if (json[key].is_object()) { + this->dri_name = new K_variable(json[key]); + this->variable[key] = this->dri_name; + } else { + yhao_log(0, key); } + } - key = "8-key_dereference_obj"; - if (json.contains(key) && json[key].is_object()) { - auto k = json[key]; - std::string temp; - temp = "1-name"; - if (k.contains(temp) && k[temp].is_string()) { - this->key_dereference_obj_name = k[temp].get(); - } else { - yhao_log(3, temp); - } - temp = "2-open"; - if (k.contains(temp) && k[temp].is_number_integer()) { - this->key_dereference_obj_open = k[temp].get(); - } else { - yhao_log(3, k.dump()); - yhao_log(3, temp); - } + key = "8-key_dereference_obj"; + if (json.contains(key) && json[key].is_object()) { + auto k = json[key]; + std::string temp; + temp = "1-name"; + if (k.contains(temp) && k[temp].is_string()) { + this->key_dereference_obj_name = k[temp].get(); } else { - yhao_log(3, key); + yhao_log(3, temp); } - - key = "9-sub"; - if (json.contains(key)) { - if (json[key].is_array()) { - for (const auto &f: json[key]) { - auto s = new K_driver(f); - s->parent = this; - this->sub.push_back(s); - } - } else { - yhao_log(0, key + ": \n" + json.dump(2)); - } + temp = "2-open"; + if (k.contains(temp) && k[temp].is_number_integer()) { + this->key_dereference_obj_open = k[temp].get(); + } else { + yhao_log(3, k.dump()); + yhao_log(3, temp); + } + } else { + yhao_log(3, key); + } + + key = "9-sub"; + if (json.contains(key)) { + if (json[key].is_array()) { + for (const auto &f : json[key]) { + auto s = new K_driver(f); + s->parent = this; + this->sub.push_back(s); + } + } else { + yhao_log(0, key + ": \n" + json.dump(2)); } + } } nlohmann::json sd::K_driver::to_json() { - K_base::to_json(); - j["0-major_value"] = this->major_value; - j["8-key_dereference_obj"]["1-name"] = this->key_dereference_obj_name; - j["8-key_dereference_obj"]["2-open"] = this->key_dereference_obj_open; - for (auto s: this->sub) { - j["9-sub"].push_back(s->to_json()); - } - return j; + K_base::to_json(); + j["0-major_value"] = this->major_value; + j["8-key_dereference_obj"]["1-name"] = this->key_dereference_obj_name; + j["8-key_dereference_obj"]["2-open"] = this->key_dereference_obj_open; + for (auto s : this->sub) { + j["9-sub"].push_back(s->to_json()); + } + return j; } -int64_t sd::K_driver::find_k_variable(const std::string &structure1, int64_t offset, sd::K_variable **k) { - int64_t ret; - ret = K_base::find_k_variable(structure1, offset, k); +int64_t sd::K_driver::find_k_variable(const std::string &structure1, + int64_t offset, sd::K_variable **k) { + int64_t ret; + ret = K_base::find_k_variable(structure1, offset, k); + if (ret == 0) { + return 0; + } + for (auto sd : this->sub) { + ret = sd->find_k_variable(structure1, offset, k); if (ret == 0) { - return 0; - } - for (auto sd: this->sub) { - ret = sd->find_k_variable(structure1, offset, k); - if (ret == 0) { - return 0; - } + return 0; } - return 1; + } + return 1; } sd::K_driver::~K_driver() { - for (auto sd: sub) { - delete sd; - } + for (auto sd : sub) { + delete sd; + } } sd::K_file::K_file() = default; sd::K_file::K_file(const nlohmann::json &json) { - K_base::read(json); - std::string key; - - key = "3-fd"; - if (json.contains(key) && json[key].is_object()) { - this->file_fd = new K_variable(json[key]); - this->variable[key] = this->file_fd; - } else { - yhao_log(3, key + ": \n" + json.dump(2)); - } - - key = "4-file_ops"; - if (json.contains(key) && json[key].is_object()) { - this->file_ops = new K_variable(json[key]); - this->variable[key] = this->file_ops; - } else { - yhao_log(3, key + ": \n" + json.dump(2)); - } - - key = "5-install"; - if (json.contains(key) && json[key].is_object()) { - this->file_install = new K_variable(json[key]); - this->variable[key] = this->file_install; - } else { - yhao_log(3, key + ": \n" + json.dump(2)); - } + K_base::read(json); + std::string key; + + key = "3-fd"; + if (json.contains(key) && json[key].is_object()) { + this->file_fd = new K_variable(json[key]); + this->variable[key] = this->file_fd; + } else { + yhao_log(3, key + ": \n" + json.dump(2)); + } + + key = "4-file_ops"; + if (json.contains(key) && json[key].is_object()) { + this->file_ops = new K_variable(json[key]); + this->variable[key] = this->file_ops; + } else { + yhao_log(3, key + ": \n" + json.dump(2)); + } + + key = "5-install"; + if (json.contains(key) && json[key].is_object()) { + this->file_install = new K_variable(json[key]); + this->variable[key] = this->file_install; + } else { + yhao_log(3, key + ": \n" + json.dump(2)); + } } nlohmann::json sd::K_file::to_json() { - K_base::to_json(); - return j; + K_base::to_json(); + return j; } sd::knowledge::knowledge() = default; void sd::knowledge::read(const std::string &knowledge) { - std::ifstream json_ifstream(knowledge); - if (json_ifstream.is_open()) { - json_ifstream >> knowledge_json; - json_ifstream.close(); - } else { - yhao_log(3, "open k json file fail: " + knowledge); - exit(0); - } - if (knowledge_json.contains("device") && knowledge_json["device"].is_object()) { - this->device = new K_device(knowledge_json["device"]); - } else { - yhao_log(3, "knowledge_json.contains(device)"); - } - if (knowledge_json.contains("driver") && knowledge_json["driver"].is_array()) { - for (const auto &d: knowledge_json["driver"]) { - this->driver.push_back(new K_driver(d)); - } - } else { - yhao_log(3, "knowledge_json.contains(device)"); - } - if (knowledge_json.contains("file") && knowledge_json["file"].is_object()) { - this->file = new K_file(knowledge_json["file"]); - } else { - yhao_log(3, "knowledge_json.contains(file)"); - } + std::ifstream json_ifstream(knowledge); + if (json_ifstream.is_open()) { + json_ifstream >> knowledge_json; + json_ifstream.close(); + } else { + yhao_log(3, "open k json file fail: " + knowledge); + exit(0); + } + if (knowledge_json.contains("device") && + knowledge_json["device"].is_object()) { + this->device = new K_device(knowledge_json["device"]); + } else { + yhao_log(3, "knowledge_json.contains(device)"); + } + if (knowledge_json.contains("driver") && + knowledge_json["driver"].is_array()) { + for (const auto &d : knowledge_json["driver"]) { + this->driver.push_back(new K_driver(d)); + } + } else { + yhao_log(3, "knowledge_json.contains(device)"); + } + if (knowledge_json.contains("file") && knowledge_json["file"].is_object()) { + this->file = new K_file(knowledge_json["file"]); + } else { + yhao_log(3, "knowledge_json.contains(file)"); + } } void sd::knowledge::print(const std::string &path) { - nlohmann::json j; - if (this->device != nullptr) { - j["device"] = this->device->to_json(); - } - for (auto d: this->driver) { - j["driver"].push_back(d->to_json()); - } - if (this->file != nullptr) { - j["file"] = this->file->to_json(); - } - - std::ofstream json_ofstream(path); - json_ofstream << j.dump(2); - json_ofstream.close(); + nlohmann::json j; + if (this->device != nullptr) { + j["device"] = this->device->to_json(); + } + for (auto d : this->driver) { + j["driver"].push_back(d->to_json()); + } + if (this->file != nullptr) { + j["file"] = this->file->to_json(); + } + + std::ofstream json_ofstream(path); + json_ofstream << j.dump(2); + json_ofstream.close(); } -void sd::knowledge::make_checker(checker_type type, K_base *kb, K_variable *kv, uint64_t id) { - if (kv == nullptr) - return; - - if (kv->offset >= 0) { - auto c = new checker(); - c->ct = type; - c->id = id; - c->name = kb->name; - c->structure = kb->structure; - c->offset = kv->offset; - - this->checkers.push_back(c); - if (this->inst_store.find(kb->structure) == this->inst_store.end()) { - this->inst_store[kb->structure] = new std::set; - } - this->inst_store[kb->structure]->insert(c); - } - for (auto f: kv->function) { - auto c = new checker(); - c->ct = type; - c->id = id; - c->name = kb->name; - c->structure = kb->structure; - c->offset = kv->offset; - - c->function = f->name; - c->object = f->object; - c->value = f->value; - c->value_offset = f->offset; - c->field = f->field; - - this->checkers.push_back(c); - if (this->inst_call.find(f->name) == this->inst_call.end()) { - this->inst_call[f->name] = new std::set; - } - this->inst_call[f->name]->insert(c); - } +void sd::knowledge::make_checker(checker_type type, K_base *kb, K_variable *kv, + uint64_t id) { + if (kv == nullptr) return; + + if (kv->offset >= 0) { + auto c = new checker(); + c->ct = type; + c->id = id; + c->name = kb->name; + c->structure = kb->structure; + c->offset = kv->offset; + + this->checkers.push_back(c); + if (this->inst_store.find(kb->structure) == this->inst_store.end()) { + this->inst_store[kb->structure] = new std::set; + } + this->inst_store[kb->structure]->insert(c); + } + for (auto f : kv->function) { + auto c = new checker(); + c->ct = type; + c->id = id; + c->name = kb->name; + c->structure = kb->structure; + c->offset = kv->offset; + + c->function = f->name; + c->object = f->object; + c->value = f->value; + c->value_offset = f->offset; + c->field = f->field; + + this->checkers.push_back(c); + if (this->inst_call.find(f->name) == this->inst_call.end()) { + this->inst_call[f->name] = new std::set; + } + this->inst_call[f->name]->insert(c); + } } -void sd::knowledge::make_driver_checker(const std::vector &drivers) { - for (auto d: drivers) { - uint64_t id = 0; - if (d->dri_name == nullptr) { - - } else { - std::string str = d->structure; - std::hash str_hash; - id = str_hash(str); - } - make_checker(checker_type::dri_ops, d, d->dri_ops, id); - make_checker(checker_type::dri_type, d, d->dri_type); - make_checker(checker_type::dri_major, d, d->dri_major); - make_checker(checker_type::dri_minor, d, d->dri_minor); - make_checker(checker_type::dri_name, d, d->dri_name, id); - make_driver_checker(d->sub); - } +void sd::knowledge::make_driver_checker( + const std::vector &drivers) { + for (auto d : drivers) { + uint64_t id = 0; + if (d->dri_name == nullptr) { + } else { + std::string str = d->structure; + std::hash str_hash; + id = str_hash(str); + } + make_checker(checker_type::dri_ops, d, d->dri_ops, id); + make_checker(checker_type::dri_type, d, d->dri_type); + make_checker(checker_type::dri_major, d, d->dri_major); + make_checker(checker_type::dri_minor, d, d->dri_minor); + make_checker(checker_type::dri_name, d, d->dri_name, id); + make_driver_checker(d->sub); + } } void sd::knowledge::make_checker() { - // for device - make_checker(checker_type::dev_name, device, device->dev_name); - make_checker(checker_type::dev_type, device, device->dev_type); + // for device + make_checker(checker_type::dev_name, device, device->dev_name); + make_checker(checker_type::dev_type, device, device->dev_type); - // for driver - make_driver_checker(this->driver); + // for driver + make_driver_checker(this->driver); - // for file - make_checker(checker_type::file_fd, file, file->file_fd); - make_checker(checker_type::file_ops, file, file->file_ops); - make_checker(checker_type::file_install, file, file->file_install); - - for (auto temp: checkers) { - yhao_log(DEBUG_CHECKER, "checker: " + temp->print()); - } + // for file + make_checker(checker_type::file_fd, file, file->file_fd); + make_checker(checker_type::file_ops, file, file->file_ops); + make_checker(checker_type::file_install, file, file->file_install); + for (auto temp : checkers) { + yhao_log(DEBUG_CHECKER, "checker: " + temp->print()); + } } -void sd::knowledge::update_checker() { - -} +void sd::knowledge::update_checker() {} -int64_t sd::knowledge::add_knowledge(sd::checker_result *cr, std::string key_dereference_obj_name, +int64_t sd::knowledge::add_knowledge(sd::checker_result *cr, + std::string key_dereference_obj_name, int64_t key_dereference_obj_open) { - if (cr->ct != checker_type::open_indirect) { - return 1; - } - - auto oc = cr->offset_chain; - if (oc == nullptr) { - yhao_log(3, "offset chain bug: " + cr->print()); - return 1; - } - auto temp = oc->next; - if (temp == nullptr || temp->next == nullptr) { - yhao_log(3, "offset chain bug: " + cr->print()); - return 1; - } - std::string structure = oc->type_str; - int64_t offset = temp->offset; - std::string ops_structure = temp->type_str; - int64_t open_offset = temp->next->offset; - - while (temp->next->next != nullptr) { - structure = temp->type_str; - offset = temp->next->offset; - ops_structure = temp->next->type_str; - open_offset = temp->next->next->offset; - temp = temp->next; - } - - auto new_kd = new K_driver(); - new_kd->structure = structure; - auto new_kv = new K_variable(); - new_kv->offset = offset; - new_kv->structure = ops_structure; - new_kv->functions_index["4-open"] = open_offset; - new_kd->dri_ops = new_kv; - new_kd->variable["dri_ops"] = new_kv; - new_kd->key_dereference_obj_name = std::move(key_dereference_obj_name); - new_kd->key_dereference_obj_open = key_dereference_obj_open; - - // not support: sub driver: major_value, dri_minor - - K_driver *kd; - // typically, there is only one layer sub - structure = cr->structure; - for (auto d: this->driver) { - if (d->structure == structure) { - kd = d; - goto next; - } - for (auto sd: d->sub) { - if (sd->structure == structure) { - kd = sd; - goto next; - } - } - } - goto error; - next: - for (auto sub: kd->sub) { - if (sub->structure == new_kd->structure) { - yhao_log(1, "existing k"); - goto out; - } - } - new_kd->parent = kd; - kd->sub.push_back(new_kd); - make_checker(checker_type::dri_ops, new_kd, new_kd->dri_ops); - new_knowledge = true; - yhao_log(1, "add new k"); - return 0; + if (cr->ct != checker_type::open_indirect) { + return 1; + } - error: - yhao_log(3, "not find parent driver: " + structure); - out: - delete new_kd; + auto oc = cr->offset_chain; + if (oc == nullptr) { + yhao_log(3, "offset chain bug: " + cr->print()); return 1; + } + auto temp = oc->next; + if (temp == nullptr || temp->next == nullptr) { + yhao_log(3, "offset chain bug: " + cr->print()); + return 1; + } + std::string structure = oc->type_str; + int64_t offset = temp->offset; + std::string ops_structure = temp->type_str; + int64_t open_offset = temp->next->offset; + + while (temp->next->next != nullptr) { + structure = temp->type_str; + offset = temp->next->offset; + ops_structure = temp->next->type_str; + open_offset = temp->next->next->offset; + temp = temp->next; + } + + auto new_kd = new K_driver(); + new_kd->structure = structure; + auto new_kv = new K_variable(); + new_kv->offset = offset; + new_kv->structure = ops_structure; + new_kv->functions_index["4-open"] = open_offset; + new_kd->dri_ops = new_kv; + new_kd->variable["dri_ops"] = new_kv; + new_kd->key_dereference_obj_name = std::move(key_dereference_obj_name); + new_kd->key_dereference_obj_open = key_dereference_obj_open; + + // not support: sub driver: major_value, dri_minor + + K_driver *kd; + // typically, there is only one layer sub + structure = cr->structure; + for (auto d : this->driver) { + if (d->structure == structure) { + kd = d; + goto next; + } + for (auto sd : d->sub) { + if (sd->structure == structure) { + kd = sd; + goto next; + } + } + } + goto error; +next: + for (auto sub : kd->sub) { + if (sub->structure == new_kd->structure) { + yhao_log(1, "existing k"); + goto out; + } + } + new_kd->parent = kd; + kd->sub.push_back(new_kd); + make_checker(checker_type::dri_ops, new_kd, new_kd->dri_ops); + new_knowledge = true; + yhao_log(1, "add new k"); + return 0; + +error: + yhao_log(3, "not find parent driver: " + structure); +out: + delete new_kd; + return 1; } -int64_t sd::knowledge::find_k_variable(const std::string &structure, int64_t offset, sd::K_variable **k) { - uint64_t ret; - ret = this->device->find_k_variable(structure, offset, k); - if (ret == 0) { - return 0; - } - ret = this->file->find_k_variable(structure, offset, k); +int64_t sd::knowledge::find_k_variable(const std::string &structure, + int64_t offset, sd::K_variable **k) { + uint64_t ret; + ret = this->device->find_k_variable(structure, offset, k); + if (ret == 0) { + return 0; + } + ret = this->file->find_k_variable(structure, offset, k); + if (ret == 0) { + return 0; + } + for (auto d : this->driver) { + ret = d->find_k_variable(structure, offset, k); if (ret == 0) { - return 0; - } - for (auto d: this->driver) { - ret = d->find_k_variable(structure, offset, k); - if (ret == 0) { - return 0; - } + return 0; } - yhao_log(3, "not find K_variable: " + structure + ": " + std::to_string(offset)); - return 1; + } + yhao_log(3, + "not find K_variable: " + structure + ": " + std::to_string(offset)); + return 1; } diff --git a/lib/KnowledgeLib/knowledge.h b/lib/KnowledgeLib/knowledge.h index 9c393b0..3871bda 100644 --- a/lib/KnowledgeLib/knowledge.h +++ b/lib/KnowledgeLib/knowledge.h @@ -11,175 +11,179 @@ namespace sd { - // -2: null - // -1: return value - // 0~N: arguments - - class K_function { - public: - // additional: file of function - std::string file; - // necessary: name of function - std::string name; +// -2: null +// -1: return value +// 0~N: arguments + +class K_function { + public: + // additional: file of function + std::string file; + // necessary: name of function + std::string name; + + // index of the driver or device structure object in argument or return + // value(-1) + int64_t object{}; + // whether object is the field of the driver or device structure + // e.g. func(driver->var) driver is the object + bool field{}; - // index of the driver or device structure object in argument or return value(-1) - int64_t object{}; - // whether object is the field of the driver or device structure - // e.g. func(driver->var) driver is the object - bool field{}; + // index of value in arguments or return value(-1) + int64_t value{}; + // (optical) if the value is a field of the argument, the index is variable + // offset e.g. func(arg): arg->var is the value + int64_t offset{}; + // whether it is printf() + bool fmt{}; - // index of value in arguments or return value(-1) - int64_t value{}; - // (optical) if the value is a field of the argument, the index is variable offset - // e.g. func(arg): arg->var is the value - int64_t offset{}; - // whether it is printf() - bool fmt{}; + K_function(); - K_function(); + explicit K_function(const nlohmann::json &j); - explicit K_function(const nlohmann::json &j); + nlohmann::json to_json(); +}; - nlohmann::json to_json(); - }; +class K_variable { + public: + // necessary: index of the variable in the driver or device structure + int64_t offset{}; + // related function + std::vector function; + // optical: name of ops structure + std::string structure; + // index of the functions + std::map functions_index; - class K_variable { - public: - // necessary: index of the variable in the driver or device structure - int64_t offset{}; - // related function - std::vector function; - // optical: name of ops structure - std::string structure; - // index of the functions - std::map functions_index; + K_variable(); - K_variable(); + explicit K_variable(const nlohmann::json &j); - explicit K_variable(const nlohmann::json &j); + virtual ~K_variable(); - virtual ~K_variable(); + nlohmann::json to_json(); +}; - nlohmann::json to_json(); - }; +class K_base { + public: + // name model + std::string name; + // necessary: the driver or device structure + std::string structure; + // variable inside the driver or device structure + // e.g. major, minor, ops, name + std::map variable; - class K_base { - public: - // name model - std::string name; - // necessary: the driver or device structure - std::string structure; - // variable inside the driver or device structure - // e.g. major, minor, ops, name - std::map variable; + nlohmann::json j; - nlohmann::json j; + K_base(); - K_base(); + virtual ~K_base(); - virtual ~K_base(); + void read(const nlohmann::json &json); - void read(const nlohmann::json &json); + virtual int64_t find_k_variable(const std::string &structure1, int64_t offset, + K_variable **k); - virtual int64_t find_k_variable(const std::string &structure1, int64_t offset, K_variable **k); + virtual nlohmann::json to_json(); +}; - virtual nlohmann::json to_json(); - }; +class K_device : public K_base { + public: + K_variable *dev_name{}; + K_variable *dev_type{}; - class K_device : public K_base { - public: - K_variable *dev_name{}; - K_variable *dev_type{}; + K_device(); - K_device(); + explicit K_device(const nlohmann::json &json); - explicit K_device(const nlohmann::json &json); + nlohmann::json to_json() override; +}; - nlohmann::json to_json() override; - }; +class K_driver : public K_base { + public: + // additional + K_variable *dri_ops{}; + // optical + K_variable *dri_type{}; + K_variable *dri_major{}; + K_variable *dri_minor{}; + K_variable *dri_name{}; - class K_driver : public K_base { - public: - // additional - K_variable *dri_ops{}; - // optical - K_variable *dri_type{}; - K_variable *dri_major{}; - K_variable *dri_minor{}; - K_variable *dri_name{}; + // necessary: the caller of the ops structure + std::string key_dereference_obj_name; + // the index of open function + int64_t key_dereference_obj_open{}; + // optical: children drivers + std::vector sub; - // necessary: the caller of the ops structure - std::string key_dereference_obj_name; - // the index of open function - int64_t key_dereference_obj_open{}; - // optical: children drivers - std::vector sub; + // if it is a child driver, it has the major number and parent + int64_t major_value{}; + K_driver *parent{}; - // if it is a child driver, it has the major number and parent - int64_t major_value{}; - K_driver *parent{}; + K_driver(); - K_driver(); + explicit K_driver(const nlohmann::json &json); - explicit K_driver(const nlohmann::json &json); + ~K_driver() override; - ~K_driver() override; + nlohmann::json to_json() override; - nlohmann::json to_json() override; + int64_t find_k_variable(const std::string &structure1, int64_t offset, + K_variable **k) override; +}; - int64_t find_k_variable(const std::string &structure1, int64_t offset, K_variable **k) override; - }; +class K_file : public K_base { + public: + K_variable *file_fd{}; + K_variable *file_ops{}; + K_variable *file_install{}; - class K_file : public K_base { - public: - K_variable *file_fd{}; - K_variable *file_ops{}; - K_variable *file_install{}; + K_file(); - K_file(); + explicit K_file(const nlohmann::json &json); - explicit K_file(const nlohmann::json &json); + nlohmann::json to_json() override; +}; - nlohmann::json to_json() override; - }; +class knowledge { + public: + nlohmann::json knowledge_json; + // knowledge with structure + K_device *device{}; + std::vector driver; + K_file *file{}; - class knowledge { - public: - nlohmann::json knowledge_json; - // knowledge with structure - K_device *device{}; - std::vector driver; - K_file *file{}; + // knowledge items + std::vector checkers; + std::map *> inst_store; + std::map *> inst_call; + bool new_knowledge{}; - // knowledge items - std::vector checkers; - std::map *> inst_store; - std::map *> inst_call; + public: + knowledge(); - bool new_knowledge{}; + void read(const std::string &knowledge); - public: - knowledge(); + void print(const std::string &path); - void read(const std::string &knowledge); + void make_checker(checker_type type, K_base *kb, K_variable *kv, + uint64_t id = 0); - void print(const std::string &path); + void make_driver_checker(const std::vector &drivers); - void make_checker(checker_type type, K_base *kb, K_variable *kv, uint64_t id = 0); + void make_checker(); - void make_driver_checker(const std::vector &drivers); + void update_checker(); - void make_checker(); + int64_t add_knowledge(sd::checker_result *cr, + std::string key_dereference_obj_name, + int64_t key_dereference_obj_open); - void update_checker(); + int64_t find_k_variable(const std::string &structure, int64_t offset, + K_variable **k); +}; +} // namespace sd - int64_t add_knowledge(sd::checker_result *cr, std::string key_dereference_obj_name, - int64_t key_dereference_obj_open); - - int64_t find_k_variable(const std::string &structure, int64_t offset, K_variable **k); - }; -} - - -#endif //INC_2021_TEMPLATE_KNOWLEDGE_H +#endif // INC_2021_TEMPLATE_KNOWLEDGE_H diff --git a/lib/KnowledgeLib/syzlang.cpp b/lib/KnowledgeLib/syzlang.cpp index 5677d67..631af45 100644 --- a/lib/KnowledgeLib/syzlang.cpp +++ b/lib/KnowledgeLib/syzlang.cpp @@ -3,500 +3,514 @@ // #include "syzlang.h" -#include "../ToolLib/log.h" -#include "../ToolLib/llvm_related.h" -#include "../AnalysisLib/entry_function.h" -std::string sd::syzlang::generate_dd(device_driver *dd, std::set &resources) { - std::string ret; - - yhao_log(0, "generate_dd: " + dd->get_id_real_hash()); +#include "../AnalysisLib/entry_function.h" +#include "../ToolLib/llvm_related.h" +#include "../ToolLib/log.h" - // open and resource - if (dd->non_open_parent == nullptr) { - ret += Annotation_Symbol"driver found at module init function "; - } else { - ret += Annotation_Symbol"driver found at (not module init) function "; +std::string sd::syzlang::generate_dd(device_driver *dd, + std::set &resources) { + std::string ret; + + yhao_log(0, "generate_dd: " + dd->get_id_real_hash()); + + // open and resource + if (dd->non_open_parent == nullptr) { + ret += Annotation_Symbol "driver found at module init function "; + } else { + ret += Annotation_Symbol "driver found at (not module init) function "; + } + ret += dd->parent->get_entry_function_name() + "() in "; + ret += dump_function_booltin(dd->parent->get_entry_function(), + this->linux_kernel_version); + ret += "\n"; + + ret += dd->get_id(); + ret += "\n"; + + ret += Annotation_Symbol "syscalls handler structure in "; + ret += dump_inst_booltin(dd->ops->inst, this->linux_kernel_version); + ret += "\n"; + if (dd->syscalls.empty()) { + ret += Annotation_Symbol "not find any syscall handler in the structure\n"; + } else { + for (auto temp : dd->syscalls) { + ret += Annotation_Symbol "find handler "; + ret += temp.first.substr(2) + ": " + + temp.second->get_entry_function_name() + "\n"; } - ret += dd->parent->get_entry_function_name() + "() in "; - ret += dump_function_booltin(dd->parent->get_entry_function(), this->linux_kernel_version); + } + ret += "\n"; + + bool useful = false; + if ((!dd->syscalls.empty()) && (!dd->cmd.empty())) { + useful = true; + } + + // for open fd, if not have useful syscall handlers, make resource annotation + if (useful) { + } else { + ret += Annotation_Symbol " "; + } + std::string resource = "resource " + dd->get_resource() + "[fd]\n"; + if (resources.find(resource) == resources.end()) { + resources.insert(resource); + ret += resource; ret += "\n"; - - ret += dd->get_id(); - ret += "\n"; - - ret += Annotation_Symbol"syscalls handler structure in "; - ret += dump_inst_booltin(dd->ops->inst, this->linux_kernel_version); - ret += "\n"; - if (dd->syscalls.empty()) { - ret += Annotation_Symbol"not find any syscall handler in the structure\n"; - } else { - for (auto temp: dd->syscalls) { - ret += Annotation_Symbol"find handler "; - ret += temp.first.substr(2) + ": " + temp.second->get_entry_function_name() + "\n"; - } + } + + // for open fd, if not have useful syscall handlers, make open annotation + if (dd->ops->ct == checker_type::dri_ops) { + uint64_t index = 0; + std::map names; + for (auto n : dd->name) { + auto temp_name = n->to_string(); + if (names.find(temp_name) == names.end()) { + names[temp_name] = n; + } } - ret += "\n"; - - bool useful = false; - if ((!dd->syscalls.empty()) && (!dd->cmd.empty())) { - useful = true; + uint64_t open_index = 0; + for (auto n : names) { + std::string str_open; + str_open += Annotation_Symbol "device file name in "; + str_open += dump_inst_booltin(n.second->inst, this->linux_kernel_version); + str_open += "\n"; + + if (n.first.empty() || n.first == "%s") { + str_open += Annotation_Symbol + "not get correct value for this device file name\n"; + } else { + if (useful) { + } else { + str_open += Annotation_Symbol; + } + open_index++; + auto temp_name = n.first; + uint64_t temp_index; + if (temp_name.find('#') == std::string::npos) { + temp_index = 0; + } else { + temp_index = 3; + } + str_open += syscall_open[0 + temp_index]; + str_open += PREFIX; + str_open += dd->get_id_hash() + "_open_" + std::to_string(index++); + str_open += syscall_open[1 + temp_index]; + str_open += temp_name; + str_open += syscall_open[2 + temp_index]; + str_open += dd->get_resource() + "\n"; + } + ret += str_open; } - - // for open fd, if not have useful syscall handlers, make resource annotation - if (useful) { - } else { - ret += Annotation_Symbol" "; + if (names.empty()) { + ret += Annotation_Symbol "not get possible device file name\n"; } - std::string resource = "resource " + dd->get_resource() + "[fd]\n"; - if (resources.find(resource) == resources.end()) { - resources.insert(resource); - ret += resource; - ret += "\n"; + if (open_index == 0 && useful) { + std::string str_open; + str_open += syscall_open[0]; + str_open += PREFIX; + str_open += dd->get_id_hash() + "_open_" + std::to_string(index++); + str_open += syscall_open[1]; + str_open += "incorrect_device_file_name"; + str_open += syscall_open[2]; + str_open += dd->get_resource() + "\n"; + ret += str_open; } - - // for open fd, if not have useful syscall handlers, make open annotation - if (dd->ops->ct == checker_type::dri_ops) { - uint64_t index = 0; - std::map names; - for (auto n: dd->name) { - auto temp_name = n->to_string(); - if (names.find(temp_name) == names.end()) { - names[temp_name] = n; - } + } else { + ret += Annotation_Symbol "non open fd\n"; + } + ret += "\n"; + + // ioctl and cmd + std::string str_ioctl; + std::string str_structure_type; + for (auto cmd : dd->cmd) { + if (cmd.second->in_types.empty() && cmd.second->out_types.empty()) { + str_ioctl += generate_ioctl(dd, cmd.second, nullptr, 0, 0); + } else { + uint64_t index = 0; + std::set temp_in_types; + std::set temp_out_types; + std::set temp_in_out_types; + for (auto type : cmd.second->in_types) { + if (type.second == nullptr) { + } else { + temp_in_types.insert(type.second); } - uint64_t open_index = 0; - for (auto n: names) { - std::string str_open; - str_open += Annotation_Symbol"device file name in "; - str_open += dump_inst_booltin(n.second->inst, this->linux_kernel_version); - str_open += "\n"; - - if (n.first.empty() || n.first == "%s") { - str_open += Annotation_Symbol"not get correct value for this device file name\n"; - } else { - if (useful) { - - } else { - str_open += Annotation_Symbol; - } - open_index++; - auto temp_name = n.first; - uint64_t temp_index; - if (temp_name.find('#') == std::string::npos) { - temp_index = 0; - } else { - temp_index = 3; - } - str_open += syscall_open[0 + temp_index]; - str_open += PREFIX; - str_open += dd->get_id_hash() + "_open_" + std::to_string(index++); - str_open += syscall_open[1 + temp_index]; - str_open += temp_name; - str_open += syscall_open[2 + temp_index]; - str_open += dd->get_resource() + "\n"; - } - ret += str_open; + } + for (auto type : cmd.second->out_types) { + if (type.second == nullptr) { + } else { + temp_out_types.insert(type.second); } - if (names.empty()) { - ret += Annotation_Symbol"not get possible device file name\n"; + } + for (auto type : temp_in_types) { + if (temp_out_types.find(type) == temp_out_types.end()) { + } else { + temp_in_out_types.insert(type); } - if (open_index == 0 && useful) { - std::string str_open; - str_open += syscall_open[0]; - str_open += PREFIX; - str_open += dd->get_id_hash() + "_open_" + std::to_string(index++); - str_open += syscall_open[1]; - str_open += "incorrect_device_file_name"; - str_open += syscall_open[2]; - str_open += dd->get_resource() + "\n"; - ret += str_open; + } + if (temp_in_types.empty() && temp_out_types.empty() && + temp_in_out_types.empty()) { + str_ioctl += generate_ioctl(dd, cmd.second, nullptr, 0, 0); + } else { + for (auto type : temp_in_types) { + if (temp_in_out_types.find(type) == temp_in_out_types.end()) { + str_ioctl += generate_ioctl(dd, cmd.second, type, 0, index++); + } } - } else { - ret += Annotation_Symbol"non open fd\n"; - } - ret += "\n"; - - // ioctl and cmd - std::string str_ioctl; - std::string str_structure_type; - for (auto cmd: dd->cmd) { - if (cmd.second->in_types.empty() && cmd.second->out_types.empty()) { - str_ioctl += generate_ioctl(dd, cmd.second, nullptr, 0, 0); - } else { - uint64_t index = 0; - std::set temp_in_types; - std::set temp_out_types; - std::set temp_in_out_types; - for (auto type: cmd.second->in_types) { - if (type.second == nullptr) { - - } else { - temp_in_types.insert(type.second); - } - } - for (auto type: cmd.second->out_types) { - if (type.second == nullptr) { - - } else { - temp_out_types.insert(type.second); - } - } - for (auto type: temp_in_types) { - if (temp_out_types.find(type) == temp_out_types.end()) { - - } else { - temp_in_out_types.insert(type); - } - } - if (temp_in_types.empty() && temp_out_types.empty() && temp_in_out_types.empty()) { - str_ioctl += generate_ioctl(dd, cmd.second, nullptr, 0, 0); - } else { - for (auto type: temp_in_types) { - if (temp_in_out_types.find(type) == temp_in_out_types.end()) { - str_ioctl += generate_ioctl(dd, cmd.second, type, 0, index++); - } - } - for (auto type: temp_out_types) { - if (temp_in_out_types.find(type) == temp_in_out_types.end()) { - str_ioctl += generate_ioctl(dd, cmd.second, type, 1, index++); - } - } - for (auto type: temp_in_out_types) { - str_ioctl += generate_ioctl(dd, cmd.second, type, 2, index++); - } - } + for (auto type : temp_out_types) { + if (temp_in_out_types.find(type) == temp_in_out_types.end()) { + str_ioctl += generate_ioctl(dd, cmd.second, type, 1, index++); + } } + for (auto type : temp_in_out_types) { + str_ioctl += generate_ioctl(dd, cmd.second, type, 2, index++); + } + } } - ret += str_ioctl; - if (dd->cmd.empty()) { - - } else { - ret += "\n"; - } - + } + ret += str_ioctl; + if (dd->cmd.empty()) { + } else { + ret += "\n"; + } - // type - for (auto st: dd->structures) { - ret += generate_struct(st, dd); - } + // type + for (auto st : dd->structures) { + ret += generate_struct(st, dd); + } - return ret; + return ret; } -std::string -sd::syzlang::generate_ioctl(sd::device_driver *dd, sd::cmd_info *cmd, llvm::Type *t, int64_t in_out, uint64_t index) { - std::string temp_ioctl; - temp_ioctl += syscall_ioctl[0]; - temp_ioctl += PREFIX; - if (t == nullptr) { - temp_ioctl += dd->get_id_hash() + "_" + std::to_string(cmd->value); - } else { - temp_ioctl += dd->get_id_hash() + "_" + std::to_string(cmd->value) + "_" + std::to_string(index); - }; - temp_ioctl += syscall_ioctl[1]; - temp_ioctl += dd->resource; - temp_ioctl += syscall_ioctl[2]; - temp_ioctl += std::to_string(cmd->value); - temp_ioctl += syscall_ioctl[3]; - if (t == nullptr) { - temp_ioctl += "ptr[in, array[int8]]"; - } else if (t->isArrayTy() || t->isStructTy()) { - temp_ioctl += "ptr["; - if (in_out == 0) { - temp_ioctl += "in"; - } else if (in_out == 1) { - temp_ioctl += "out"; - } else if (in_out == 2) { - temp_ioctl += "inout"; - } - temp_ioctl += ", "; - temp_ioctl += generate_type(t, dd); - temp_ioctl += "]"; - } else if (t->isIntegerTy()) { - temp_ioctl += "int64"; - } else { - temp_ioctl += generate_type(t, dd, in_out); +std::string sd::syzlang::generate_ioctl(sd::device_driver *dd, + sd::cmd_info *cmd, llvm::Type *t, + int64_t in_out, uint64_t index) { + std::string temp_ioctl; + temp_ioctl += syscall_ioctl[0]; + temp_ioctl += PREFIX; + if (t == nullptr) { + temp_ioctl += dd->get_id_hash() + "_" + std::to_string(cmd->value); + } else { + temp_ioctl += dd->get_id_hash() + "_" + std::to_string(cmd->value) + "_" + + std::to_string(index); + }; + temp_ioctl += syscall_ioctl[1]; + temp_ioctl += dd->resource; + temp_ioctl += syscall_ioctl[2]; + temp_ioctl += std::to_string(cmd->value); + temp_ioctl += syscall_ioctl[3]; + if (t == nullptr) { + temp_ioctl += "ptr[in, array[int8]]"; + } else if (t->isArrayTy() || t->isStructTy()) { + temp_ioctl += "ptr["; + if (in_out == 0) { + temp_ioctl += "in"; + } else if (in_out == 1) { + temp_ioctl += "out"; + } else if (in_out == 2) { + temp_ioctl += "inout"; } - temp_ioctl += syscall_ioctl[4]; - if (cmd->non_open) { - if ((!cmd->dd->syscalls.empty()) && (!cmd->dd->cmd.empty())) { - temp_ioctl += " " + cmd->generate_resource_name(); - } else { - temp_ioctl += "\n" Annotation_Symbol + temp_ioctl + " " + cmd->generate_resource_name(); - } - //std::string resource = "resource " + cmd->generate_resource_name() + "[fd]\n"; - yhao_log(0, "cmd->non_open: " + cmd->generate_resource_name()); - yhao_log(0, cmd->dd->print()); + temp_ioctl += ", "; + temp_ioctl += generate_type(t, dd); + temp_ioctl += "]"; + } else if (t->isIntegerTy()) { + temp_ioctl += "int64"; + } else { + temp_ioctl += generate_type(t, dd, in_out); + } + temp_ioctl += syscall_ioctl[4]; + if (cmd->non_open) { + if ((!cmd->dd->syscalls.empty()) && (!cmd->dd->cmd.empty())) { + temp_ioctl += " " + cmd->generate_resource_name(); + } else { + temp_ioctl += "\n" Annotation_Symbol + temp_ioctl + " " + + cmd->generate_resource_name(); } - temp_ioctl += "\n"; - return temp_ioctl; + // std::string resource = "resource " + cmd->generate_resource_name() + + // "[fd]\n"; + yhao_log(0, "cmd->non_open: " + cmd->generate_resource_name()); + yhao_log(0, cmd->dd->print()); + } + temp_ioctl += "\n"; + return temp_ioctl; } -std::string sd::syzlang::generate_type(llvm::Type *t, device_driver *dd, int64_t inout, bool opt) { - std::string ret; - std::string str; - switch (t->getTypeID()) { - case llvm::Type::HalfTyID: - case llvm::Type::BFloatTyID: - case llvm::Type::FloatTyID: - case llvm::Type::DoubleTyID: - case llvm::Type::X86_FP80TyID: - case llvm::Type::FP128TyID: - case llvm::Type::PPC_FP128TyID: - yhao_log(3, "case llvm::Type::PPC_FP128TyID:"); - break; - case llvm::Type::VoidTyID: - yhao_log(3, "case llvm::Type::VoidTyID:"); - break; - case llvm::Type::LabelTyID: - case llvm::Type::MetadataTyID: - case llvm::Type::X86_MMXTyID: - case llvm::Type::X86_AMXTyID: - case llvm::Type::TokenTyID: - yhao_log(3, "case llvm::Type::TokenTyID:"); - break; - case llvm::Type::IntegerTyID: - ret += "int" + std::to_string(llvm::dyn_cast(t)->getBitWidth()); - break; - case llvm::Type::FunctionTyID: - yhao_log(3, "case llvm::Type::FunctionTyID:"); - yhao_dump(2, t->print, str) - ret += "intptr"; - break; - case llvm::Type::PointerTyID: - ret += "ptr["; - if (inout == 0) { - ret += "in, "; - } else if (inout == 1) { - ret += "out, "; - } else if (inout == 2) { - ret += "inout, "; - } - if (t->getNumContainedTypes()) { - ret += generate_type(t->getNonOpaquePointerElementType(), dd, inout, false); - } else { - ret += "array[int8]"; - } - if (opt) { - ret += ", opt"; - } - ret += "]"; - break; - case llvm::Type::StructTyID: - ret += generate_struct_name(llvm::dyn_cast(t), dd); - break; - case llvm::Type::ArrayTyID: - ret += "array["; - ret += generate_type(t->getArrayElementType(), dd, inout, opt); - if (t->getArrayNumElements() != 0) { - ret += ", "; - ret += std::to_string(t->getArrayNumElements()); - } - ret += "]"; - break; - case llvm::Type::FixedVectorTyID: - case llvm::Type::ScalableVectorTyID: - yhao_log(3, "case llvm::Type::ScalableVectorTyID:"); - break; - } - return ret; +std::string sd::syzlang::generate_type(llvm::Type *t, device_driver *dd, + int64_t inout, bool opt) { + std::string ret; + std::string str; + switch (t->getTypeID()) { + case llvm::Type::HalfTyID: + case llvm::Type::BFloatTyID: + case llvm::Type::FloatTyID: + case llvm::Type::DoubleTyID: + case llvm::Type::X86_FP80TyID: + case llvm::Type::FP128TyID: + case llvm::Type::PPC_FP128TyID: + yhao_log(3, "case llvm::Type::PPC_FP128TyID:"); + break; + case llvm::Type::VoidTyID: + yhao_log(3, "case llvm::Type::VoidTyID:"); + break; + case llvm::Type::LabelTyID: + case llvm::Type::MetadataTyID: + case llvm::Type::X86_MMXTyID: + case llvm::Type::X86_AMXTyID: + case llvm::Type::TokenTyID: + yhao_log(3, "case llvm::Type::TokenTyID:"); + break; + case llvm::Type::IntegerTyID: + ret += "int" + std::to_string( + llvm::dyn_cast(t)->getBitWidth()); + break; + case llvm::Type::FunctionTyID: + yhao_log(3, "case llvm::Type::FunctionTyID:"); + yhao_dump(2, t->print, str) ret += "intptr"; + break; + case llvm::Type::PointerTyID: + ret += "ptr["; + if (inout == 0) { + ret += "in, "; + } else if (inout == 1) { + ret += "out, "; + } else if (inout == 2) { + ret += "inout, "; + } + if (t->getNumContainedTypes()) { + ret += generate_type(t->getNonOpaquePointerElementType(), dd, inout, + false); + } else { + ret += "array[int8]"; + } + if (opt) { + ret += ", opt"; + } + ret += "]"; + break; + case llvm::Type::StructTyID: + ret += generate_struct_name(llvm::dyn_cast(t), dd); + break; + case llvm::Type::ArrayTyID: + ret += "array["; + ret += generate_type(t->getArrayElementType(), dd, inout, opt); + if (t->getArrayNumElements() != 0) { + ret += ", "; + ret += std::to_string(t->getArrayNumElements()); + } + ret += "]"; + break; + case llvm::Type::FixedVectorTyID: + case llvm::Type::ScalableVectorTyID: + yhao_log(3, "case llvm::Type::ScalableVectorTyID:"); + break; + } + return ret; } -std::string sd::syzlang::generate_struct(llvm::StructType *st, device_driver *dd) { - std::string ret; - auto name = generate_struct_name(st, dd); - uint64_t field_index = 0; - ret += name; - ret += " {\n"; - for (auto i = 0; i < st->getNumElements(); i++) { - ret += " "; - ret += "field_" + std::to_string(field_index++); - ret += " "; - std::set checked; - ret += generate_type(st->getElementType(i), dd, 0, is_opt_pointer(st, checked, st->getElementType(i))); - ret += "\n"; - } - if (st->isPacked()) { - ret += "} [packed]\n"; - } else { - ret += "}\n"; - } - return ret; +std::string sd::syzlang::generate_struct(llvm::StructType *st, + device_driver *dd) { + std::string ret; + auto name = generate_struct_name(st, dd); + uint64_t field_index = 0; + ret += name; + ret += " {\n"; + for (auto i = 0; i < st->getNumElements(); i++) { + ret += " "; + ret += "field_" + std::to_string(field_index++); + ret += " "; + std::set checked; + ret += generate_type(st->getElementType(i), dd, 0, + is_opt_pointer(st, checked, st->getElementType(i))); + ret += "\n"; + } + if (st->isPacked()) { + ret += "} [packed]\n"; + } else { + ret += "}\n"; + } + return ret; } -std::string sd::syzlang::generate_struct_name(llvm::StructType *st, device_driver *dd) { - std::string ret; - if (dd == nullptr) { - if (structure_name.find(st) != structure_name.end()) { - ret = structure_name[st]; +std::string sd::syzlang::generate_struct_name(llvm::StructType *st, + device_driver *dd) { + std::string ret; + if (dd == nullptr) { + if (structure_name.find(st) != structure_name.end()) { + ret = structure_name[st]; + } else { + auto temp_name = st->getStructName().str(); + for (auto temp : temp_name) { + if (temp == '.') { + ret += '_'; } else { - auto temp_name = st->getStructName().str(); - for (auto temp: temp_name) { - if (temp == '.') { - ret += '_'; - } else { - ret += temp; - } - } - structure_name[st] = ret; + ret += temp; } + } + structure_name[st] = ret; + } + } else { + if (dd->structure_name.find(st) != dd->structure_name.end()) { + ret = dd->structure_name[st]; } else { - if (dd->structure_name.find(st) != dd->structure_name.end()) { - ret = dd->structure_name[st]; + auto temp_name = st->getStructName().str(); + for (auto temp : temp_name) { + if (temp == '.') { + ret += '_'; } else { - auto temp_name = st->getStructName().str(); - for (auto temp: temp_name) { - if (temp == '.') { - ret += '_'; - } else { - ret += temp; - } - } - ret += "_" + dd->get_id_hash(); - dd->structure_name[st] = ret; + ret += temp; } + } + ret += "_" + dd->get_id_hash(); + dd->structure_name[st] = ret; } - return ret; + } + return ret; } std::string sd::syzlang::generate_general() const { - std::string ret; - ret += copyright; - ret += "\n"; - ret += kernel_version; - ret += this->linux_kernel_version; - ret += "\n"; - ret += "\n"; - ret += "meta arches[\""; - ret += this->target; - ret += "\"]"; - ret += "\n"; - return ret; + std::string ret; + ret += copyright; + ret += "\n"; + ret += kernel_version; + ret += this->linux_kernel_version; + ret += "\n"; + ret += "\n"; + ret += "meta arches[\""; + ret += this->target; + ret += "\"]"; + ret += "\n"; + return ret; } void sd::syzlang::set_target(const std::string &t) { - for (const auto &arche: arches) { - if (t.find(arche[0] + "-") != std::string::npos) { - this->target = arche[1]; - break; - } + for (const auto &arche : arches) { + if (t.find(arche[0] + "-") != std::string::npos) { + this->target = arche[1]; + break; } + } } std::string sd::syzlang::generate(sd::device_driver *dd) { - std::string ret; - std::vector temp; - temp.push_back(dd); - ret += generate(dd->parent->get_entry_function(), temp); - return ret; + std::string ret; + std::vector temp; + temp.push_back(dd); + ret += generate(dd->parent->get_entry_function(), temp); + return ret; } -std::string sd::syzlang::generate(llvm::Function *func, const std::vector &dds) { - std::string ret; - std::string file_name = generate_file_name(func); - yhao_log(0, "file name: " + file_name); +std::string sd::syzlang::generate(llvm::Function *func, + const std::vector &dds) { + std::string ret; + std::string file_name = generate_file_name(func); + yhao_log(0, "file name: " + file_name); - std::hash str_hash; - this->file_prefix = std::to_string(str_hash(file_name)); - yhao_log(0, "file name hash: " + this->file_prefix); + std::hash str_hash; + this->file_prefix = std::to_string(str_hash(file_name)); + yhao_log(0, "file name hash: " + this->file_prefix); - // add debug info - ret += generate_general(); - ret += "\n"; + // add debug info + ret += generate_general(); + ret += "\n"; - std::set resources; + std::set resources; - // generate for each device driver - for (auto dd: dds) { - ret += generate_dd(dd, resources); - } + // generate for each device driver + for (auto dd : dds) { + ret += generate_dd(dd, resources); + } - std::ofstream syz_of(this->work_dir + file_name); - syz_of << ret; - syz_of.close(); + std::ofstream syz_of(this->work_dir + file_name); + syz_of << ret; + syz_of.close(); - this->file_prefix = ""; + this->file_prefix = ""; - return ret; + return ret; } std::string sd::syzlang::generate_file_name(llvm::Function *func) const { - std::string ret; - ret += PREFIX; - std::string path = get_file_name(func); - for (auto c: path) { - if (c == '/' || c == '.') { - ret += '_'; - } else { - ret += c; - } + std::string ret; + ret += PREFIX; + std::string path = get_file_name(func); + for (auto c : path) { + if (c == '/' || c == '.') { + ret += '_'; + } else { + ret += c; } - ret += "_"; - ret += target; - ret += ".txt"; - return ret; + } + ret += "_"; + ret += target; + ret += ".txt"; + return ret; } -bool sd::syzlang::is_opt_pointer(llvm::StructType *st, std::set &checked, llvm::Type *t) { - if (checked.find(t) == checked.end()) { - checked.insert(t); - } else { - return false; +bool sd::syzlang::is_opt_pointer(llvm::StructType *st, + std::set &checked, + llvm::Type *t) { + if (checked.find(t) == checked.end()) { + checked.insert(t); + } else { + return false; + } + switch (t->getTypeID()) { + case llvm::Type::HalfTyID: + case llvm::Type::BFloatTyID: + case llvm::Type::FloatTyID: + case llvm::Type::DoubleTyID: + case llvm::Type::X86_FP80TyID: + case llvm::Type::FP128TyID: + case llvm::Type::PPC_FP128TyID: + case llvm::Type::VoidTyID: + case llvm::Type::LabelTyID: + case llvm::Type::MetadataTyID: + case llvm::Type::X86_MMXTyID: + case llvm::Type::X86_AMXTyID: + case llvm::Type::TokenTyID: + case llvm::Type::IntegerTyID: + case llvm::Type::FunctionTyID: + // case llvm::Type::DXILPointerTyID: + break; + case llvm::Type::PointerTyID: { + if (t->getNumContainedTypes()) { + return is_opt_pointer(st, checked, t->getNonOpaquePointerElementType()); + } } - switch (t->getTypeID()) { - case llvm::Type::HalfTyID: - case llvm::Type::BFloatTyID: - case llvm::Type::FloatTyID: - case llvm::Type::DoubleTyID: - case llvm::Type::X86_FP80TyID: - case llvm::Type::FP128TyID: - case llvm::Type::PPC_FP128TyID: - case llvm::Type::VoidTyID: - case llvm::Type::LabelTyID: - case llvm::Type::MetadataTyID: - case llvm::Type::X86_MMXTyID: - case llvm::Type::X86_AMXTyID: - case llvm::Type::TokenTyID: - case llvm::Type::IntegerTyID: - case llvm::Type::FunctionTyID: - // case llvm::Type::DXILPointerTyID: - break; - case llvm::Type::PointerTyID: { - if (t->getNumContainedTypes()) { - return is_opt_pointer(st, checked, t->getNonOpaquePointerElementType()); - } + case llvm::Type::StructTyID: { + if (get_real_structure_name(t->getStructName().str()) == + get_real_structure_name(st->getStructName().str())) { + return true; + } + for (int64_t i = 0; i < t->getStructNumElements(); i++) { + if (is_opt_pointer(st, checked, t->getStructElementType(i))) { + return true; } - case llvm::Type::StructTyID: { - if (get_real_structure_name(t->getStructName().str()) == get_real_structure_name(st->getStructName().str())) { - return true; - } - for (int64_t i = 0; i < t->getStructNumElements(); i++) { - if (is_opt_pointer(st, checked, t->getStructElementType(i))) { - return true; - } - } - break; - } - case llvm::Type::ArrayTyID: - return is_opt_pointer(st, checked, t->getArrayElementType()); - case llvm::Type::FixedVectorTyID: - case llvm::Type::ScalableVectorTyID: - break; + } + break; } - return false; + case llvm::Type::ArrayTyID: + return is_opt_pointer(st, checked, t->getArrayElementType()); + case llvm::Type::FixedVectorTyID: + case llvm::Type::ScalableVectorTyID: + break; + } + return false; } -std::string sd::syzlang::print_loc(llvm::Function *func, const std::vector &dds) { - std::string ret; - std::set functions; - uint64_t line = 0; - for (auto dd : dds) { - - } - for (auto f : functions) { - line += get_loc(f); - } - ret = Annotation_Symbol" loc of " + get_file_name(func) + " : " + std::to_string(line); - return ret; +std::string sd::syzlang::print_loc(llvm::Function *func, + const std::vector &dds) { + std::string ret; + std::set functions; + uint64_t line = 0; + for (auto dd : dds) { + } + for (auto f : functions) { + line += get_loc(f); + } + ret = Annotation_Symbol " loc of " + get_file_name(func) + " : " + + std::to_string(line); + return ret; } diff --git a/lib/KnowledgeLib/syzlang.h b/lib/KnowledgeLib/syzlang.h index 9c8cc56..5144165 100644 --- a/lib/KnowledgeLib/syzlang.h +++ b/lib/KnowledgeLib/syzlang.h @@ -8,75 +8,74 @@ #define INC_2021_TEMPLATE_SYZLANG_H namespace sd { - const static std::string syscall_open[]{ - "openat$", - "(fd const[AT_FDCWD], file ptr[in, string[\"/dev/", - "\"]], flags flags[open_flags], mode const[0]) ", - "syz_open_dev$", - "(dev ptr[in, string[\"/dev/", - "\"]], id intptr, flags flags[open_flags]) ", - }; +const static std::string syscall_open[]{ + "openat$", + "(fd const[AT_FDCWD], file ptr[in, string[\"/dev/", + "\"]], flags flags[open_flags], mode const[0]) ", + "syz_open_dev$", + "(dev ptr[in, string[\"/dev/", + "\"]], id intptr, flags flags[open_flags]) ", +}; - const static std::string syscall_ioctl[]{ - "ioctl$", - "(fd ", - ", cmd const[", - "], arg ", - ")", - }; +const static std::string syscall_ioctl[]{ + "ioctl$", "(fd ", ", cmd const[", "], arg ", ")", +}; - const static std::string copyright = - Annotation_Symbol"Copyright 2018 syzkaller project authors. All rights reserved.\n" - Annotation_Symbol"Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.\n"; - const static std::string kernel_version = - Annotation_Symbol"Code generated by SyzDescribe. DO NOT EDIT.\n" - Annotation_Symbol"Code generated from linux "; +const static std::string copyright = Annotation_Symbol + "Copyright 2018 syzkaller project authors. All rights " + "reserved.\n" Annotation_Symbol + "Use of this source code is governed by Apache 2 LICENSE that can be found " + "in the LICENSE file.\n"; +const static std::string kernel_version = Annotation_Symbol + "Code generated by SyzDescribe. DO NOT EDIT.\n" Annotation_Symbol + "Code generated from linux "; - const static std::string arches[][2]{ - "x86", "386", - "x86_64", "amd64", - "aarch64", "arm64", - "mips64le", "mips64le", - "ppc64le", "ppc64le", - "s390x", "s390x", - }; +const static std::string arches[][2]{ + "x86", "386", "x86_64", "amd64", "aarch64", "arm64", + "mips64le", "mips64le", "ppc64le", "ppc64le", "s390x", "s390x", +}; - class syzlang { - public: - std::string linux_kernel_version; - std::string target; - std::string work_dir; +class syzlang { + public: + std::string linux_kernel_version; + std::string target; + std::string work_dir; - std::string file_prefix; - std::map structure_name; + std::string file_prefix; + std::map structure_name; - std::string generate_dd(device_driver *dd, std::set &resources); + std::string generate_dd(device_driver *dd, std::set &resources); - std::string - generate_ioctl(sd::device_driver *dd, sd::cmd_info *cmd, llvm::Type *t, int64_t in_out, uint64_t index); + std::string generate_ioctl(sd::device_driver *dd, sd::cmd_info *cmd, + llvm::Type *t, int64_t in_out, uint64_t index); - // inout: 0 -- in, 1 -- out, 2 -- inout, - std::string generate_type(llvm::Type *t, device_driver *dd = nullptr, int64_t inout = 0, bool opt = false); + // inout: 0 -- in, 1 -- out, 2 -- inout, + std::string generate_type(llvm::Type *t, device_driver *dd = nullptr, + int64_t inout = 0, bool opt = false); - std::string generate_struct(llvm::StructType *st, device_driver *dd = nullptr); + std::string generate_struct(llvm::StructType *st, + device_driver *dd = nullptr); - std::string generate_struct_name(llvm::StructType *st, device_driver *dd = nullptr); + std::string generate_struct_name(llvm::StructType *st, + device_driver *dd = nullptr); - [[nodiscard]] std::string generate_general() const; + [[nodiscard]] std::string generate_general() const; - void set_target(const std::string &t); + void set_target(const std::string &t); - std::string generate(device_driver *dd); + std::string generate(device_driver *dd); - std::string generate(llvm::Function *func, const std::vector &dds); + std::string generate(llvm::Function *func, + const std::vector &dds); - std::string generate_file_name(llvm::Function *func) const; + std::string generate_file_name(llvm::Function *func) const; - bool is_opt_pointer(llvm::StructType *st, std::set &checked, llvm::Type *t); + bool is_opt_pointer(llvm::StructType *st, std::set &checked, + llvm::Type *t); - std::string print_loc(llvm::Function *func, const std::vector &dds); - }; -} + std::string print_loc(llvm::Function *func, + const std::vector &dds); +}; +} // namespace sd - -#endif //INC_2021_TEMPLATE_SYZLANG_H +#endif // INC_2021_TEMPLATE_SYZLANG_H diff --git a/lib/KnowledgeLib/task.cpp b/lib/KnowledgeLib/task.cpp index 69cbefd..7c9854d 100644 --- a/lib/KnowledgeLib/task.cpp +++ b/lib/KnowledgeLib/task.cpp @@ -3,68 +3,64 @@ // #include "task.h" + #include "../ToolLib/log.h" -sd::task::task(nlohmann::json j) { - this->from_json(std::move(j)); -} +sd::task::task(nlohmann::json j) { this->from_json(std::move(j)); } -sd::task::task(const std::string &entryFunction, - sd::checker_result *cr) { - this->entry_function = entryFunction; - this->cr = cr; - compute_hash(); +sd::task::task(const std::string &entryFunction, sd::checker_result *cr) { + this->entry_function = entryFunction; + this->cr = cr; + compute_hash(); } nlohmann::json *sd::task::to_json() { - auto j = new nlohmann::json(); - (*j)["0_hash"] = this->hash; - (*j)["1_task"] = this->task_str; - (*j)["2_bitcode"] = this->bitcode; - (*j)["3_entry_function"] = this->entry_function; - (*j)["4_work_dir"] = this->work_dir; - (*j)["5_checker"] = *(cr->to_json()); - return j; + auto j = new nlohmann::json(); + (*j)["0_hash"] = this->hash; + (*j)["1_task"] = this->task_str; + (*j)["2_bitcode"] = this->bitcode; + (*j)["3_entry_function"] = this->entry_function; + (*j)["4_work_dir"] = this->work_dir; + (*j)["5_checker"] = *(cr->to_json()); + return j; } std::string sd::task::print() { - auto j = this->to_json(); - std::string s = j->dump(2); - delete j; - return s; + auto j = this->to_json(); + std::string s = j->dump(2); + delete j; + return s; } void sd::task::from_json(nlohmann::json j) { - if (j.contains("0_hash") && j["0_hash"].is_number_integer()) { - this->hash = j["0_hash"].get(); - } - if (j.contains("1_task") && j["1_task"].is_string()) { - this->task_str = j["1_task"].get(); - } - if (j.contains("2_bitcode") && j["2_bitcode"].is_string()) { - this->bitcode = j["2_bitcode"].get(); - } - if (j.contains("3_entry_function") && j["3_entry_function"].is_string()) { - this->entry_function = j["3_entry_function"].get(); - } - if (j.contains("4_work_dir") && j["4_work_dir"].is_string()) { - this->work_dir = j["4_work_dir"].get(); - } - if (j.contains("5_checker") && j["5_checker"].is_object()) { - if (this->cr != nullptr) { - this->cr->from_json(j["5_checker"]); - } + if (j.contains("0_hash") && j["0_hash"].is_number_integer()) { + this->hash = j["0_hash"].get(); + } + if (j.contains("1_task") && j["1_task"].is_string()) { + this->task_str = j["1_task"].get(); + } + if (j.contains("2_bitcode") && j["2_bitcode"].is_string()) { + this->bitcode = j["2_bitcode"].get(); + } + if (j.contains("3_entry_function") && j["3_entry_function"].is_string()) { + this->entry_function = j["3_entry_function"].get(); + } + if (j.contains("4_work_dir") && j["4_work_dir"].is_string()) { + this->work_dir = j["4_work_dir"].get(); + } + if (j.contains("5_checker") && j["5_checker"].is_object()) { + if (this->cr != nullptr) { + this->cr->from_json(j["5_checker"]); } + } } void sd::task::compute_hash() { - std::string hash_str; - hash_str += this->entry_function; - hash_str += std::to_string(cr->hash); - this->hash = std::hash{}(hash_str); - this->task_str = std::to_string(this->hash) + ".json"; + std::string hash_str; + hash_str += this->entry_function; + hash_str += std::to_string(cr->hash); + this->hash = std::hash{}(hash_str); + this->task_str = std::to_string(this->hash) + ".json"; } -void sd::task::update_checker_inst(llvm::Module *m) { - this->cr->setInst(m); -} +void sd::task::update_checker_inst(llvm::Module *m) { this->cr->setInst(m); } diff --git a/lib/KnowledgeLib/task.h b/lib/KnowledgeLib/task.h index bfdba5e..0fc4661 100644 --- a/lib/KnowledgeLib/task.h +++ b/lib/KnowledgeLib/task.h @@ -10,31 +10,30 @@ #include "checker.h" namespace sd { - class task { - public: - explicit task(nlohmann::json j); +class task { + public: + explicit task(nlohmann::json j); - task(const std::string &entryFunction, - sd::checker_result *cr); + task(const std::string &entryFunction, sd::checker_result *cr); - public: - uint64_t hash{}; - std::string task_str; - std::string bitcode; - std::string entry_function; - std::string work_dir; - checker_result *cr; + public: + uint64_t hash{}; + std::string task_str; + std::string bitcode; + std::string entry_function; + std::string work_dir; + checker_result *cr; - nlohmann::json *to_json(); + nlohmann::json *to_json(); - std::string print(); + std::string print(); - void from_json(nlohmann::json j); + void from_json(nlohmann::json j); - void compute_hash(); + void compute_hash(); - void update_checker_inst(llvm::Module *m); - }; -} + void update_checker_inst(llvm::Module *m); +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_TASK_H +#endif // INC_2021_TEMPLATE_TASK_H diff --git a/lib/MLTA/CallGraph.cc b/lib/MLTA/CallGraph.cc index a80eb58..2f6ae85 100644 --- a/lib/MLTA/CallGraph.cc +++ b/lib/MLTA/CallGraph.cc @@ -57,7 +57,7 @@ void CallGraphPass::findCalleesWithType(CallInst *CI, FuncSet &S) { // auto &CS = llvm::cast(*CI); - for (Function *F : Ctx->AddressTakenFuncs) { + for (Function *F: Ctx->AddressTakenFuncs) { // VarArg if (F->getFunctionType()->isVarArg()) { @@ -96,12 +96,14 @@ void CallGraphPass::findCalleesWithType(CallInst *CI, FuncSet &S) { // makes the equality evaluation of two types from // two modules very hard, which is actually done // at link time by the linker. - while (DefinedTy->isPointerTy() && ActualTy->isPointerTy() && DefinedTy->getNumContainedTypes() && ActualTy->getNumContainedTypes()) { + while (DefinedTy->isPointerTy() && ActualTy->isPointerTy() && DefinedTy->getNumContainedTypes() && + ActualTy->getNumContainedTypes()) { DefinedTy = DefinedTy->getNonOpaquePointerElementType(); ActualTy = ActualTy->getNonOpaquePointerElementType(); } if (DefinedTy->isStructTy() && ActualTy->isStructTy() && - (get_real_structure_name(DefinedTy->getStructName().str()) == get_real_structure_name(ActualTy->getStructName().str()))) + (get_real_structure_name(DefinedTy->getStructName().str()) == + get_real_structure_name(ActualTy->getStructName().str()))) continue; if (DefinedTy->isIntegerTy() && ActualTy->isIntegerTy() && DefinedTy->getIntegerBitWidth() == ActualTy->getIntegerBitWidth()) @@ -156,14 +158,14 @@ void CallGraphPass::unrollLoops(Function *F) { LP = LPL.front(); LPL.pop_front(); vector SubLPs = LP->getSubLoops(); - for (auto SubLP : SubLPs) { + for (auto SubLP: SubLPs) { LPSet.insert(SubLP); LPL.push_back(SubLP); } } } - for (Loop *LP : LPSet) { + for (Loop *LP: LPSet) { // Get the header,latch block, exiting block of every loop BasicBlock *HeaderB = LP->getHeader(); @@ -173,7 +175,7 @@ void CallGraphPass::unrollLoops(Function *F) { LP->getLoopLatches(LatchBS); - for (BasicBlock *LatchB : LatchBS) { + for (BasicBlock *LatchB: LatchBS) { if (!HeaderB || !LatchB) { OP << "ERROR: Cannot find Header Block or Latch Block\n"; continue; @@ -383,7 +385,8 @@ bool CallGraphPass::typeConfineInCast(CastInst *CastI) { return true; } - if (!FromTy->isPointerTy() || !ToTy->isPointerTy() || !FromTy->getNumContainedTypes() || ! ToTy->getNumContainedTypes()) + if (!FromTy->isPointerTy() || !ToTy->isPointerTy() || !FromTy->getNumContainedTypes() || + !ToTy->getNumContainedTypes()) return false; Type *EToTy = dyn_cast(ToTy)->getNonOpaquePointerElementType(); Type *EFromTy = dyn_cast(FromTy)->getNonOpaquePointerElementType(); @@ -414,7 +417,7 @@ void CallGraphPass::transitType(Type *ToTy, Type *FromTy, void CallGraphPass::funcSetIntersection(FuncSet &FS1, FuncSet &FS2, FuncSet &FS) { FS.clear(); - for (auto F : FS1) { + for (auto F: FS1) { if (FS2.find(F) != FS2.end()) FS.insert(F); } @@ -530,7 +533,7 @@ bool CallGraphPass::findCalleesWithMLTA(CallInst *CI, FuncSet &FS) { unsigned CT = LT.front(); LT.pop_front(); - for (auto H : typeTransitMap[CT]) { + for (auto H: typeTransitMap[CT]) { FS2 = typeFuncsMap[hashIdxHash(H, FieldIdx)]; FST.clear(); funcSetIntersection(FS1, FS2, FST); @@ -591,7 +594,7 @@ bool CallGraphPass::doInitialization(Module *M) { // Iterate functions and instructions - for (Function &F : *M) { + for (Function &F: *M) { //if (F.empty()) // continue; @@ -647,7 +650,7 @@ bool CallGraphPass::doModulePass(Module *M) { #endif // Collect callers and callees - for (auto &i : instructions(F)) { + for (auto &i: instructions(F)) { // Map callsite to possible callees. if (CallInst *CI = dyn_cast(&i)) { @@ -663,7 +666,7 @@ bool CallGraphPass::doModulePass(Module *M) { findCalleesWithType(CI, FS); #endif - for (Function *Callee : FS) + for (Function *Callee: FS) Ctx->Callers[Callee].insert(CI); // Save called values for future uses. diff --git a/lib/MLTA/TypeInitializer.cc b/lib/MLTA/TypeInitializer.cc index fd860ff..e5d3ef1 100644 --- a/lib/MLTA/TypeInitializer.cc +++ b/lib/MLTA/TypeInitializer.cc @@ -85,7 +85,7 @@ bool TypeInitializerPass::doFinalization(Module *M) { void TypeInitializerPass::BuildTypeStructMap() { // build GlobalTypes based on TypeValueMap and VnameToTypenameMap - for (auto const &P1 : TypeValueMap) { + for (auto const &P1: TypeValueMap) { if (VnameToTypenameMap.find(P1.second) != VnameToTypenameMap.end()) { Ctx->GlobalTypes.insert(pair(P1.first, VnameToTypenameMap[P1.second])); //OP<<*P1.first<<"\t"<> config_json; - } else { - yhao_log(3, "open config json file fail: " + config); - } - - if (config_json.contains("4_work_dir") && config_json["4_work_dir"].is_string()) { - this->work_dir = config_json["4_work_dir"].get(); - } - if (this->work_dir.empty()) { - this->work_dir = std::filesystem::current_path(); - } - this->work_dir += "/"; - this->t_module->work_dir = this->work_dir; - - std::ofstream json_ofstream(this->work_dir + "config.json"); - json_ofstream << config_json.dump(2); - json_ofstream.close(); - - if (config_json.contains("bitcode") && config_json["bitcode"].is_string()) { - bitcode = config_json["bitcode"].get(); - yhao_log(1, "bitcode: " + bitcode); - this->t_module->read_bitcode(bitcode); - } else { - yhao_log(3, "no bitcode"); - exit(1); - } - if (config_json.contains("version") && config_json["version"].is_string()) { - this->s->linux_kernel_version = config_json["version"].get(); - } else { - - } - this->s->set_target(this->t_module->llvm_module->getTargetTriple()); - this->s->work_dir = this->work_dir; + std::ifstream json_ifstream(config); + if (json_ifstream.is_open()) { + json_ifstream >> config_json; + } else { + yhao_log(3, "open config json file fail: " + config); + } + + if (config_json.contains("4_work_dir") && + config_json["4_work_dir"].is_string()) { + this->work_dir = config_json["4_work_dir"].get(); + } + if (this->work_dir.empty()) { + this->work_dir = std::filesystem::current_path(); + } + this->work_dir += "/"; + this->t_module->work_dir = this->work_dir; + + std::ofstream json_ofstream(this->work_dir + "config.json"); + json_ofstream << config_json.dump(2); + json_ofstream.close(); + + if (config_json.contains("bitcode") && config_json["bitcode"].is_string()) { + bitcode = config_json["bitcode"].get(); + yhao_log(1, "bitcode: " + bitcode); + this->t_module->read_bitcode(bitcode); + } else { + yhao_log(3, "no bitcode"); + exit(1); + } + if (config_json.contains("version") && config_json["version"].is_string()) { + this->s->linux_kernel_version = config_json["version"].get(); + } else { + } + this->s->set_target(this->t_module->llvm_module->getTargetTriple()); + this->s->work_dir = this->work_dir; } void sd::Manager::analysis() { - yhao_log(1, "********find_init_and_exit_function start********"); - this->t_module->find_init_and_exit_function(); - this->t_module->find_module_init_function(); - t_module->remove_init_from_indirect(); - yhao_log(1, "********find_init_and_exit_function end**********"); - - auto knowledge_file = config_json["knowledge"].get(); - yhao_log(1, "knowledge json file: " + knowledge_file); - this->k->read(knowledge_file); - - // update offset of dev->devt - int64_t offset; - for (auto &st: t_module->llvm_module->getIdentifiedStructTypes()) { - std::string struct_name = get_real_structure_name(st->getName().str()); - if (struct_name == "struct.device") { - offset = 0; - for (auto et: st->elements()) { - if (et->isStructTy()) { - std::string element_name = get_real_structure_name(et->getStructName().str()); - if (element_name == "struct.spinlock") { - offset = offset - 2; - goto update_knowledge; - } - } - offset++; - } - } - } - update_knowledge: - this->k->device->dev_type->offset = offset; - - yhao_log(1, "print knowledge json file: " + this->work_dir + "knowledge.json"); - this->k->print(this->work_dir + "knowledge.json"); - this->k->make_checker(); - this->t_module->k = this->k; - if (config_json.contains("template_analysis") && config_json["template_analysis"].is_string()) { - this->template_klee = config_json["template_analysis"].get(); - } - - yhao_log(1, "start our"); - time(&start); - analysis_ops_and_file_name(); - time(&end); - analysis_time_module_init_function = difftime(end, start); - - time(&start); - for (auto dd: this->all_device_drivers) { - auto id_real_hash = dd->get_id_real_hash(); - if (device_drivers.find(id_real_hash) != device_drivers.end()) { - - } else { - device_drivers[id_real_hash] = dd; + yhao_log(1, "********find_init_and_exit_function start********"); + this->t_module->find_init_and_exit_function(); + this->t_module->find_module_init_function(); + t_module->remove_init_from_indirect(); + yhao_log(1, "********find_init_and_exit_function end**********"); + + auto knowledge_file = config_json["knowledge"].get(); + yhao_log(1, "knowledge json file: " + knowledge_file); + this->k->read(knowledge_file); + + // update offset of dev->devt + int64_t offset; + for (auto &st : t_module->llvm_module->getIdentifiedStructTypes()) { + std::string struct_name = get_real_structure_name(st->getName().str()); + if (struct_name == "struct.device") { + offset = 0; + for (auto et : st->elements()) { + if (et->isStructTy()) { + std::string element_name = + get_real_structure_name(et->getStructName().str()); + if (element_name == "struct.spinlock") { + offset = offset - 2; + goto update_knowledge; + } } + offset++; + } } - - for (const auto &dd: this->device_drivers) { - collect_info(dd.second); + } +update_knowledge: + this->k->device->dev_type->offset = offset; + + yhao_log(1, + "print knowledge json file: " + this->work_dir + "knowledge.json"); + this->k->print(this->work_dir + "knowledge.json"); + this->k->make_checker(); + this->t_module->k = this->k; + if (config_json.contains("template_analysis") && + config_json["template_analysis"].is_string()) { + this->template_klee = config_json["template_analysis"].get(); + } + + yhao_log(1, "start our"); + time(&start); + analysis_ops_and_file_name(); + time(&end); + analysis_time_module_init_function = difftime(end, start); + + time(&start); + for (auto dd : this->all_device_drivers) { + auto id_real_hash = dd->get_id_real_hash(); + if (device_drivers.find(id_real_hash) != device_drivers.end()) { + } else { + device_drivers[id_real_hash] = dd; } - - for (const auto &dd: this->device_drivers) { - collect_cmd_and_type(dd.second); + } + + for (const auto &dd : this->device_drivers) { + collect_info(dd.second); + } + + for (const auto &dd : this->device_drivers) { + collect_cmd_and_type(dd.second); + } + + // collect more entry functions other than module init function, e.g., ioctl + std::set entry_set; + for (const auto &dd : this->device_drivers) { + collect_entry_function(dd.second, entry_set); + } + + // analysis those entry functions, mainly for non-open fd + while (!entry_set.empty()) { + auto init_f = *entry_set.begin(); + entry_set.erase(init_f); + // all_entry_set.insert(init_f); + yhao_log(-1, "analysis entry: " + init_f->get_entry_function_name()); + + this->t_module->check_function_pointer(init_f); + init_f->update_checker_results(); + std::vector results; + this->mapping_checker_results(init_f, results); + execute_init_function(results); + + for (auto dd : results) { + auto id_real_hash = dd->get_id_real_hash(); + if (device_drivers.find(id_real_hash) != device_drivers.end()) { + } else { + device_drivers[id_real_hash] = dd; + } } - // collect more entry functions other than module init function, e.g., ioctl - std::set entry_set; - for (const auto &dd: this->device_drivers) { - collect_entry_function(dd.second, entry_set); + for (auto dd : results) { + collect_info(dd); } - - // analysis those entry functions, mainly for non-open fd - while (!entry_set.empty()) { - auto init_f = *entry_set.begin(); - entry_set.erase(init_f); - //all_entry_set.insert(init_f); - yhao_log(-1, "analysis entry: " + init_f->get_entry_function_name()); - - this->t_module->check_function_pointer(init_f); - init_f->update_checker_results(); - std::vector results; - this->mapping_checker_results(init_f, results); - execute_init_function(results); - - for (auto dd: results) { - auto id_real_hash = dd->get_id_real_hash(); - if (device_drivers.find(id_real_hash) != device_drivers.end()) { - - } else { - device_drivers[id_real_hash] = dd; - } - } - - for (auto dd: results) { - collect_info(dd); - } - for (auto dd: results) { - collect_cmd_and_type(dd); - } - for (auto dd: results) { - collect_entry_function(dd, entry_set); - } + for (auto dd : results) { + collect_cmd_and_type(dd); } - time(&end); - analysis_time_ioctl = difftime(end, start); - yhao_log(1, "end our"); - - // output syscalls description based on source code file - std::map> temp_dds; - for (const auto &dd_pair: this->device_drivers) { - auto dd = dd_pair.second; - entry_function *temp_ef = dd->parent; - while (temp_ef->parent != nullptr && temp_ef->parent->parent != nullptr) { - temp_ef = temp_ef->parent->parent; - } - temp_dds[temp_ef->get_entry_function()].push_back(dd); - yhao_log(1, "\n" + dd->print()); + for (auto dd : results) { + collect_entry_function(dd, entry_set); } - - for (auto &dds: temp_dds) { - std::sort(dds.second.begin(), dds.second.end()); + } + time(&end); + analysis_time_ioctl = difftime(end, start); + yhao_log(1, "end our"); + + // output syscalls description based on source code file + std::map> temp_dds; + for (const auto &dd_pair : this->device_drivers) { + auto dd = dd_pair.second; + entry_function *temp_ef = dd->parent; + while (temp_ef->parent != nullptr && temp_ef->parent->parent != nullptr) { + temp_ef = temp_ef->parent->parent; } - - for (const auto &dds: temp_dds) { - this->s->generate(dds.first, dds.second); + temp_dds[temp_ef->get_entry_function()].push_back(dd); + yhao_log(1, "\n" + dd->print()); + } + + for (auto &dds : temp_dds) { + std::sort(dds.second.begin(), dds.second.end()); + } + + for (const auto &dds : temp_dds) { + this->s->generate(dds.first, dds.second); + } + + // statistic + this->number_module_init_function = this->init_function.size(); + this->number_driver = this->device_drivers.size(); + for (const auto &dd : this->device_drivers) { + if (dd.second->syscalls.find(syscall_name[3]) != + dd.second->syscalls.end()) { + this->number_ioctl++; } - - // statistic - this->number_module_init_function = this->init_function.size(); - this->number_driver = this->device_drivers.size(); - for (const auto &dd: this->device_drivers) { - if (dd.second->syscalls.find(syscall_name[3]) != dd.second->syscalls.end()) { - this->number_ioctl++; - } + } + + for (const auto &init_f : this->init_function) { + // yhao_log(1, "init: " + init_f.second->get_entry_function_name()); + + this->number_function_pointer += init_f.second->function_pointers.size(); + this->number_indirect_call += init_f.second->number_indirect_call; + this->number_indirect_call_target_before += + init_f.second->number_indirect_call_target_before; + this->number_indirect_call_target_after += + init_f.second->number_indirect_call_target_after; + + // for (auto fp : init_f.second->function_pointers) { + // yhao_log(1, "fp: " + fp->get_name()); + // } + } + + for (const auto &init_f : this->all_new_entry_functions) { + // yhao_log(1, "init: " + init_f->get_entry_function_name()); + + this->number_function_pointer += init_f->function_pointers.size(); + this->number_indirect_call += init_f->number_indirect_call; + this->number_indirect_call_target_before += + init_f->number_indirect_call_target_before; + this->number_indirect_call_target_after += + init_f->number_indirect_call_target_after; + + // for (auto fp : init_f->function_pointers) { + // yhao_log(1, "fp: " + fp->get_name()); + // } + } + + std::string output; + std::ofstream statistic(this->work_dir + "statistic.txt"); + statistic << "overall"; + statistic << " " + std::to_string(number_module_init_function); + statistic << " " + std::to_string(number_driver); + statistic << " " + std::to_string(number_ioctl); + statistic << " " + std::to_string(number_function_pointer); + statistic << " " + std::to_string(number_indirect_call); + statistic << " " + std::to_string(number_indirect_call_target_before); + statistic << " " + std::to_string(number_indirect_call_target_after); + statistic << " " + std::to_string(analysis_time_module_init_function); + statistic << " " + std::to_string(analysis_time_ioctl); + statistic << "\n"; + + for (const auto &dd_pair : this->device_drivers) { + auto dd = dd_pair.second; + statistic << "driver"; + statistic << " " + std::to_string(dd->ops->has_function_pointer); + statistic << " " + dd->ops->name; + statistic << " " + dd->ops->ops_name; + statistic << " " + std::to_string(dd->entries.size()); + statistic << " " + std::to_string(dd->syscalls.find(syscall_name[3]) != + dd->syscalls.end()); + + std::set names; + for (auto temp : dd->name) { + auto str = temp->to_string(); + names.insert(str); } + statistic << " " + std::to_string(names.size()); - for (const auto &init_f: this->init_function) { - //yhao_log(1, "init: " + init_f.second->get_entry_function_name()); - - this->number_function_pointer += init_f.second->function_pointers.size(); - this->number_indirect_call += init_f.second->number_indirect_call; - this->number_indirect_call_target_before += init_f.second->number_indirect_call_target_before; - this->number_indirect_call_target_after += init_f.second->number_indirect_call_target_after; - - //for (auto fp : init_f.second->function_pointers) { - // yhao_log(1, "fp: " + fp->get_name()); - //} + uint64_t number = 0; + for (auto temp : names) { + if (temp.find('#') != std::string::npos) { + number++; + } } - - for (const auto &init_f: this->all_new_entry_functions) { - //yhao_log(1, "init: " + init_f->get_entry_function_name()); - - this->number_function_pointer += init_f->function_pointers.size(); - this->number_indirect_call += init_f->number_indirect_call; - this->number_indirect_call_target_before += init_f->number_indirect_call_target_before; - this->number_indirect_call_target_after += init_f->number_indirect_call_target_after; - - //for (auto fp : init_f->function_pointers) { - // yhao_log(1, "fp: " + fp->get_name()); - //} + statistic << " " + std::to_string(number); + + uint64_t number1 = 0; + uint64_t number2 = 0; + uint64_t number3 = 0; + for (auto temp : dd->cmd) { + auto cmd = temp.second; + std::set temp_types; + for (auto type : cmd->in_types) { + temp_types.insert(type.second); + } + for (auto type : cmd->out_types) { + temp_types.insert(type.second); + } + uint64_t temp_size = 1; + if (!temp_types.empty()) { + temp_size = temp_types.size(); + } + number1 += temp_size; + if (cmd->in_entry_function) { + number2 += temp_size; + } + if (cmd->in_indirect_call) { + number3 += temp_size; + } } - - std::string output; - std::ofstream statistic(this->work_dir + "statistic.txt"); - statistic << "overall"; - statistic << " " + std::to_string(number_module_init_function); - statistic << " " + std::to_string(number_driver); - statistic << " " + std::to_string(number_ioctl); - statistic << " " + std::to_string(number_function_pointer); - statistic << " " + std::to_string(number_indirect_call); - statistic << " " + std::to_string(number_indirect_call_target_before); - statistic << " " + std::to_string(number_indirect_call_target_after); - statistic << " " + std::to_string(analysis_time_module_init_function); - statistic << " " + std::to_string(analysis_time_ioctl); + statistic << " " + std::to_string(number1); + statistic << " " + std::to_string(number2); + statistic << " " + std::to_string(number3); statistic << "\n"; + } - for (const auto &dd_pair: this->device_drivers) { - auto dd = dd_pair.second; - statistic << "driver"; - statistic << " " + std::to_string(dd->ops->has_function_pointer); - statistic << " " + dd->ops->name; - statistic << " " + dd->ops->ops_name; - statistic << " " + std::to_string(dd->entries.size()); - statistic << " " + std::to_string(dd->syscalls.find(syscall_name[3]) != dd->syscalls.end()); - - std::set names; - for (auto temp: dd->name) { - auto str = temp->to_string(); - names.insert(str); - } - statistic << " " + std::to_string(names.size()); - - uint64_t number = 0; - for (auto temp: names) { - if (temp.find('#') != std::string::npos) { - number++; - } - } - statistic << " " + std::to_string(number); - - uint64_t number1 = 0; - uint64_t number2 = 0; - uint64_t number3 = 0; - for (auto temp: dd->cmd) { - auto cmd = temp.second; - std::set temp_types; - for (auto type : cmd->in_types) { - temp_types.insert(type.second); - } - for (auto type : cmd->out_types) { - temp_types.insert(type.second); - } - uint64_t temp_size = 1; - if (!temp_types.empty()) { - temp_size = temp_types.size(); - } - number1 += temp_size; - if (cmd->in_entry_function) { - number2 += temp_size; - } - if (cmd->in_indirect_call) { - number3 += temp_size; - } - } - statistic << " " + std::to_string(number1); - statistic << " " + std::to_string(number2); - statistic << " " + std::to_string(number3); - statistic << "\n"; - } - - statistic.close(); + statistic.close(); } void sd::Manager::analysis_ops_and_file_name() { - this->t_module->analysis_functions(); - - analysis_init_function(); - // only get driver - // handle_init_function_with_driver(); - // if new k, recheck all - // handle_init_function_with_device(); - // get results - handle_init_function_with_driver_device(); + this->t_module->analysis_functions(); + + analysis_init_function(); + // only get driver + // handle_init_function_with_driver(); + // if new k, recheck all + // handle_init_function_with_device(); + // get results + handle_init_function_with_driver_device(); } - // collect info about the non-open parent and set up the related syscalls void sd::Manager::collect_info(device_driver *dd) { - int64_t ret; - int64_t debug = 0; - int64_t index; - - yhao_log(0, "collect_info: " + dd->get_id_real_hash()); - - llvm::Function *fp; - // handle parent - // check each device drivers - if (dd->parent != nullptr && dd->parent->parent != nullptr) { - auto parent_dd = dd->parent->parent; - for (auto cmd: parent_dd->cmd) { - auto bb = cmd.second->b; - for (auto inst: dd->ops->call_chain) { - if (inst->getFunction() != bb->getParent()) { - continue; - } - if (!llvm::isPotentiallyReachable(bb, inst->getParent())) { - continue; - } - if (dd->ops->ct == checker_type::file_ops) { - cmd.second->non_open = true; - cmd.second->dd = dd; - } - dd->non_open_parent = cmd.second; - break; - } - if (dd->non_open_parent != nullptr) { - break; - } + int64_t ret; + int64_t debug = 0; + int64_t index; + + yhao_log(0, "collect_info: " + dd->get_id_real_hash()); + + llvm::Function *fp; + // handle parent + // check each device drivers + if (dd->parent != nullptr && dd->parent->parent != nullptr) { + auto parent_dd = dd->parent->parent; + for (auto cmd : parent_dd->cmd) { + auto bb = cmd.second->b; + for (auto inst : dd->ops->call_chain) { + if (inst->getFunction() != bb->getParent()) { + continue; } - } - yhao_log(debug, "ops name: " + dd->ops->ops_name); - yhao_log(debug, "ops name: " + dd->ops->print()); - if (dd->non_open_parent != nullptr) { - yhao_log(debug, "non_open_parent: " + std::to_string(dd->non_open_parent->value)); - } - - T_function *t_f; - entry_function *new_init_f; - for (const auto &temp: syscall_name) { - ret = get_function_by_syscall(dd->ops, temp, &index, &fp); - if (ret) { - continue; + if (!llvm::isPotentiallyReachable(bb, inst->getParent())) { + continue; } - t_f = this->t_module->find_t_function(fp); - if (t_f == nullptr) { - yhao_log(3, "t_f == nullptr"); - continue; + if (dd->ops->ct == checker_type::file_ops) { + cmd.second->non_open = true; + cmd.second->dd = dd; } - new_init_f = new entry_function(t_f); - new_init_f->is_init = false; - new_init_f->parent = dd; - dd->syscalls[temp] = new_init_f; - this->all_new_entry_functions.push_back(new_init_f); - this->t_module->check_function_pointer(new_init_f); + dd->non_open_parent = cmd.second; + break; + } + if (dd->non_open_parent != nullptr) { + break; + } } - collect_entry(dd); -} - -void sd::Manager::collect_cmd_and_type(device_driver *dd) { - int64_t debug = -1; - int64_t ret; - - yhao_log(0, "collect_cmd_and_type: " + dd->get_id_real_hash()); - if (dd->syscalls.find(syscall_name[3]) == dd->syscalls.end()) { - return; - } - entry_function *ioctl = dd->syscalls[syscall_name[3]]; - if (ioctl == nullptr) { - return; + } + yhao_log(debug, "ops name: " + dd->ops->ops_name); + yhao_log(debug, "ops name: " + dd->ops->print()); + if (dd->non_open_parent != nullptr) { + yhao_log(debug, + "non_open_parent: " + std::to_string(dd->non_open_parent->value)); + } + + T_function *t_f; + entry_function *new_init_f; + for (const auto &temp : syscall_name) { + ret = get_function_by_syscall(dd->ops, temp, &index, &fp); + if (ret) { + yhao_log(0, "ret get_function_by_syscall"); + continue; } - - std::set fps; - auto parent = ioctl; - while (parent != nullptr && parent->parent != nullptr) { - for (auto temp_1: parent->function_pointers) { - fps.insert(temp_1->llvm_function); - } - parent = parent->parent->parent; + t_f = this->t_module->find_t_function(fp); + if (t_f == nullptr) { + yhao_log(3, "t_f == nullptr"); + continue; } + new_init_f = new entry_function(t_f); + new_init_f->is_init = false; + new_init_f->parent = dd; + dd->syscalls[temp] = new_init_f; + this->all_new_entry_functions.push_back(new_init_f); + this->t_module->check_function_pointer(new_init_f); + } + collect_entry(dd); +} - auto tf = ioctl->t_function->llvm_function; - std::set cmd; - std::set type; - auto num_arg = tf->getFunctionType()->getNumParams(); - yhao_log(debug, "num_arg: " + std::to_string(num_arg)); - if (num_arg == 4) { - cmd.insert(2); - type.insert(3); - yhao_log(debug, "block: ioctl"); - } - // ioctl in char - else if (num_arg == 3) { - cmd.insert(1); - type.insert(2); - yhao_log(debug, "char: ioctl"); - } else { - assert(0 && "a bad function?"); +void sd::Manager::collect_cmd_and_type(device_driver *dd) { + int64_t debug = -1; + int64_t ret; + + yhao_log(0, "collect_cmd_and_type: " + dd->get_id_real_hash()); + if (dd->syscalls.find(syscall_name[3]) == dd->syscalls.end()) { + return; + } + entry_function *ioctl = dd->syscalls[syscall_name[3]]; + if (ioctl == nullptr) { + return; + } + + std::set fps; + auto parent = ioctl; + while (parent != nullptr && parent->parent != nullptr) { + for (auto temp_1 : parent->function_pointers) { + fps.insert(temp_1->llvm_function); } - ioctl_cmd_type temp1(tf, cmd, type, dd, this->t_module, &fps); - temp1.run_cmd(); + parent = parent->parent->parent; + } + + auto tf = ioctl->t_function->llvm_function; + std::set cmd; + std::set type; + auto num_arg = tf->getFunctionType()->getNumParams(); + yhao_log(debug, "num_arg: " + std::to_string(num_arg)); + if (num_arg == 4) { + cmd.insert(2); + type.insert(3); + yhao_log(debug, "block: ioctl"); + } + // ioctl in char + else if (num_arg == 3) { + cmd.insert(1); + type.insert(2); + yhao_log(debug, "char: ioctl"); + } else { + assert(0 && "a bad function?"); + } + ioctl_cmd_type temp1(tf, cmd, type, dd, this->t_module, &fps); + temp1.run_cmd(); } -void sd::Manager::collect_entry_function(device_driver *dd, std::set &entry_set) { - if (dd->syscalls.find(syscall_name[3]) != dd->syscalls.end() && dd->syscalls[syscall_name[3]] != nullptr) { - // do not insert entry function within loop - std::set temp; - auto temp_parent = dd->syscalls[syscall_name[3]]; - while (temp_parent != nullptr && temp_parent->parent != nullptr) { - if (temp.find(temp_parent->get_entry_function_name()) == temp.end()) { - temp.insert(temp_parent->get_entry_function_name()); - } else { - return; - } - temp_parent = temp_parent->parent->parent; - } - entry_set.insert(dd->syscalls[syscall_name[3]]); +void sd::Manager::collect_entry_function( + device_driver *dd, std::set &entry_set) { + if (dd->syscalls.find(syscall_name[3]) != dd->syscalls.end() && + dd->syscalls[syscall_name[3]] != nullptr) { + // do not insert entry function within loop + std::set temp; + auto temp_parent = dd->syscalls[syscall_name[3]]; + while (temp_parent != nullptr && temp_parent->parent != nullptr) { + if (temp.find(temp_parent->get_entry_function_name()) == temp.end()) { + temp.insert(temp_parent->get_entry_function_name()); + } else { + return; + } + temp_parent = temp_parent->parent->parent; } + entry_set.insert(dd->syscalls[syscall_name[3]]); + } } void sd::Manager::analysis_init_function() { - int64_t debug = 0; - for (const auto &temp: this->t_module->module_init_function) { - auto set_f = temp.second; - yhao_log(1, "****" + set_f->name + " start*****************"); - yhao_log(1, "size: " + std::to_string(set_f->f->size())); - if (set_f->order < 7) { - continue; - } - for (auto f: *set_f->f) { - yhao_log(debug, "****analysis_init_function start*****************"); - if (this->t_module->t_functions.find(f) == this->t_module->t_functions.end()) { - yhao_log(3, "analysis_init_functions can not find function: " + f->getName().str()); + int64_t debug = 0; + for (const auto &temp : this->t_module->module_init_function) { + auto set_f = temp.second; + yhao_log(1, "****" + set_f->name + " start*****************"); + yhao_log(1, "size: " + std::to_string(set_f->f->size())); + if (set_f->order < 7) { + continue; + } + for (auto f : *set_f->f) { + yhao_log(debug, "****analysis_init_function start*****************"); + if (this->t_module->t_functions.find(f) == + this->t_module->t_functions.end()) { + yhao_log(3, "analysis_init_functions can not find function: " + + f->getName().str()); + } else { + yhao_log(1, "analysis_init_function: " + f->getName().str()); + auto init_f = new entry_function(this->t_module->t_functions[f]); + init_function[f->getName().str()] = init_f; + + // now we do not use this and use check_caller instead + // this->t_module->check_callee(init_f->t_function); + yhao_log(debug, "****check_function_pointer start*****************"); + this->t_module->check_function_pointer(init_f); + yhao_log(debug, "****check_function_pointer end*******************"); + + yhao_log(debug, "****update_checker_results start*****************"); + init_f->update_checker_results(); + std::vector results; + this->mapping_checker_results(init_f, results); + yhao_log(debug, "****update_checker_results start*****************"); + + if (results.empty()) { + if (init_f->all_checker_results.empty()) { + } else { + yhao_log(debug, "init_function_with_device: " + f->getName().str()); + init_function_with_device[f->getName().str()] = init_f; + } + } else { + for (auto temp1 : results) { + int64_t kind = temp1->kind; + if (kind & (1 << checker_type::dev_name)) { + yhao_log(debug, "init_function_with_driver_device dev_name: " + + f->getName().str()); + init_function_with_driver_device[f->getName().str()] = init_f; + } else if (kind & (1 << checker_type::dri_name)) { + yhao_log(debug, "init_function_with_driver_device dri_name: " + + f->getName().str()); + init_function_with_driver_device[f->getName().str()] = init_f; } else { - yhao_log(1, "analysis_init_function: " + f->getName().str()); - auto init_f = new entry_function(this->t_module->t_functions[f]); - init_function[f->getName().str()] = init_f; - - // now we do not use this and use check_caller instead - // this->t_module->check_callee(init_f->t_function); - yhao_log(debug, "****check_function_pointer start*****************"); - this->t_module->check_function_pointer(init_f); - yhao_log(debug, "****check_function_pointer end*******************"); - - yhao_log(debug, "****update_checker_results start*****************"); - init_f->update_checker_results(); - std::vector results; - this->mapping_checker_results(init_f, results); - yhao_log(debug, "****update_checker_results start*****************"); - - if (results.empty()) { - if (init_f->all_checker_results.empty()) { - - } else { - yhao_log(debug, "init_function_with_device: " + f->getName().str()); - init_function_with_device[f->getName().str()] = init_f; - } - } else { - for (auto temp1: results) { - int64_t kind = temp1->kind; - if (kind & (1 << checker_type::dev_name)) { - yhao_log(debug, "init_function_with_driver_device dev_name: " + f->getName().str()); - init_function_with_driver_device[f->getName().str()] = init_f; - } else if (kind & (1 << checker_type::dri_name)) { - yhao_log(debug, "init_function_with_driver_device dri_name: " + f->getName().str()); - init_function_with_driver_device[f->getName().str()] = init_f; - } else { - yhao_log(debug, "init_function_with_driver: " + f->getName().str()); - init_function_with_driver[f->getName().str()] = init_f; - } - yhao_log(debug, temp1->ops->print()); - } - } + yhao_log(debug, + "init_function_with_driver: " + f->getName().str()); + init_function_with_driver[f->getName().str()] = init_f; } - yhao_log(debug, "****analysis_init_function end*******************"); + yhao_log(debug, temp1->ops->print()); + } } + } + yhao_log(debug, "****analysis_init_function end*******************"); } - yhao_log(1, "****init function statistic start****************"); - yhao_log(1, "init_function_with_driver: " + std::to_string(init_function_with_driver.size())); - yhao_log(1, "init_function_with_device: " + std::to_string(init_function_with_device.size())); - yhao_log(1, "init_function_with_driver_device: " + std::to_string(init_function_with_driver_device.size())); - yhao_log(1, "****init function statistic end ****************"); + } + yhao_log(1, "****init function statistic start****************"); + yhao_log(1, "init_function_with_driver: " + + std::to_string(init_function_with_driver.size())); + yhao_log(1, "init_function_with_device: " + + std::to_string(init_function_with_device.size())); + yhao_log(1, "init_function_with_driver_device: " + + std::to_string(init_function_with_driver_device.size())); + yhao_log(1, "****init function statistic end ****************"); } int64_t sd::Manager::handle_init_function_with_driver() { - yhao_log(1, "****handle_init_function_with_driver start*******************"); - std::string str; - int64_t ret; - for (auto temp: this->all_device_drivers) { - if (!temp->is_only_driver()) { - continue; - } - - // get driver ops checker - auto init_f = temp->parent; - auto cr_ops = temp->ops; - auto task1 = make_task(init_f->get_entry_function_name(), cr_ops); - execute_task(task1); - yhao_log(-1, "json: \n" + task1->print()); - - // get the open function in ops structure from checker - llvm::Function *fp; - int64_t open_index; - ret = this->get_function_by_syscall(cr_ops, "4-open", &open_index, &fp); - if (ret) { - continue; - } - - // analysis open function and find indirect function call checker - std::vector crs_open; - ret = this->t_module->check_open(fp, &crs_open); - if (ret) { - continue; - } - - // TODO: get offset chain of indirect function call checker cr_open - auto cr_open = crs_open.at(0); - cr_open->structure = cr_ops->structure; - yhao_dump(-1, cr_open->inst->print, str) - auto oc = new offset_chain_base(); - cr_open->offset_chain = oc; - oc->base = ""; - oc->type_str = "struct.snd_minor"; - auto next1 = new offset_chain_offset(); - oc->next = next1; - next1->offset = 3; - next1->type_str = "struct.file_operations"; - auto next2 = new offset_chain_offset(); - next1->next = next2; - next2->offset = 14; - - auto task2 = make_task(fp->getName().str(), cr_open); - execute_task(task2); - yhao_log(-1, "json: \n" + task2->print()); - - ret = this->k->add_knowledge(cr_open, cr_ops->ops_name, open_index); - if (ret) { - continue; - } + yhao_log(1, "****handle_init_function_with_driver start*******************"); + std::string str; + int64_t ret; + for (auto temp : this->all_device_drivers) { + if (!temp->is_only_driver()) { + continue; } - this->k->print(this->work_dir + "knowledge.json"); - yhao_log(1, "****handle_init_function_with_driver end*******************"); - return 0; -} - -int64_t sd::Manager::handle_init_function_with_device() { - yhao_log(1, "****handle_init_function_with_device start*******************"); - std::string str; - int64_t ret = 0; + // get driver ops checker + auto init_f = temp->parent; + auto cr_ops = temp->ops; + auto task1 = make_task(init_f->get_entry_function_name(), cr_ops); + execute_task(task1); + yhao_log(-1, "json: \n" + task1->print()); - - // update analysis if new k - if (!k->new_knowledge) { - yhao_log(1, "****no new k end*************************************"); - return 0; + // get the open function in ops structure from checker + llvm::Function *fp; + int64_t open_index; + ret = this->get_function_by_syscall(cr_ops, "4-open", &open_index, &fp); + if (ret) { + continue; } - this->t_module->update_function(); + // analysis open function and find indirect function call checker + std::vector crs_open; + ret = this->t_module->check_open(fp, &crs_open); + if (ret) { + continue; + } - // update existing init function with device drivers - for (const auto &f: this->init_function_with_driver_device) { - auto init_f = f.second; - init_f->update_checker_results(); - std::vector results; - this->mapping_checker_results(init_f, results); + // TODO: get offset chain of indirect function call checker cr_open + auto cr_open = crs_open.at(0); + cr_open->structure = cr_ops->structure; + yhao_dump(-1, cr_open->inst->print, str) auto oc = new offset_chain_base(); + cr_open->offset_chain = oc; + oc->base = ""; + oc->type_str = "struct.snd_minor"; + auto next1 = new offset_chain_offset(); + oc->next = next1; + next1->offset = 3; + next1->type_str = "struct.file_operations"; + auto next2 = new offset_chain_offset(); + next1->next = next2; + next2->offset = 14; + + auto task2 = make_task(fp->getName().str(), cr_open); + execute_task(task2); + yhao_log(-1, "json: \n" + task2->print()); + + ret = this->k->add_knowledge(cr_open, cr_ops->ops_name, open_index); + if (ret) { + continue; } + } - // update init function with device - std::map temp; - for (const auto &f: this->init_function_with_device) { - auto init_f = f.second; - init_f->update_checker_results(); - std::vector results; - this->mapping_checker_results(init_f, results); + this->k->print(this->work_dir + "knowledge.json"); + yhao_log(1, "****handle_init_function_with_driver end*******************"); + return 0; +} - yhao_log(1, init_f->get_entry_function_name()); +int64_t sd::Manager::handle_init_function_with_device() { + yhao_log(1, "****handle_init_function_with_device start*******************"); + std::string str; + int64_t ret = 0; - if (results.empty()) { - if (init_f->all_checker_results.empty()) { - yhao_log(3, "where is device?"); - ret = 1; - } else { - // the same as before - yhao_log(1, "same as before"); - } + // update analysis if new k + if (!k->new_knowledge) { + yhao_log(1, "****no new k end*************************************"); + return 0; + } + + this->t_module->update_function(); + + // update existing init function with device drivers + for (const auto &f : this->init_function_with_driver_device) { + auto init_f = f.second; + init_f->update_checker_results(); + std::vector results; + this->mapping_checker_results(init_f, results); + } + + // update init function with device + std::map temp; + for (const auto &f : this->init_function_with_device) { + auto init_f = f.second; + init_f->update_checker_results(); + std::vector results; + this->mapping_checker_results(init_f, results); + + yhao_log(1, init_f->get_entry_function_name()); + + if (results.empty()) { + if (init_f->all_checker_results.empty()) { + yhao_log(3, "where is device?"); + ret = 1; + } else { + // the same as before + yhao_log(1, "same as before"); + } + } else { + for (auto temp1 : results) { + int64_t kind = temp1->kind; + if (kind & (1 << checker_type::dev_name)) { + temp[f.first] = f.second; + yhao_log(1, "new init_function_with_driver_device dev_name: " + + init_f->get_entry_function_name()); + init_function_with_driver_device[init_f->get_entry_function_name()] = + init_f; + } else if (kind & (1 << checker_type::dri_name)) { + temp[f.first] = f.second; + yhao_log(1, "new init_function_with_driver_device dri_name: " + + init_f->get_entry_function_name()); + init_function_with_driver_device[init_f->get_entry_function_name()] = + init_f; } else { - for (auto temp1: results) { - int64_t kind = temp1->kind; - if (kind & (1 << checker_type::dev_name)) { - temp[f.first] = f.second; - yhao_log(1, "new init_function_with_driver_device dev_name: " + init_f->get_entry_function_name()); - init_function_with_driver_device[init_f->get_entry_function_name()] = init_f; - } else if (kind & (1 << checker_type::dri_name)) { - temp[f.first] = f.second; - yhao_log(1, "new init_function_with_driver_device dri_name: " + init_f->get_entry_function_name()); - init_function_with_driver_device[init_f->get_entry_function_name()] = init_f; - } else { - yhao_log(3, "find the new driver but where is the device?"); - ret = 1; - } - } + yhao_log(3, "find the new driver but where is the device?"); + ret = 1; } + } } - for (const auto &f: temp) { - init_function_with_device.erase(f.first); - } + } + for (const auto &f : temp) { + init_function_with_device.erase(f.first); + } - yhao_log(1, "****handle_init_function_with_device end*******************"); - return ret; + yhao_log(1, "****handle_init_function_with_device end*******************"); + return ret; } // TODO:handle_init_function_with_driver_device int64_t sd::Manager::handle_init_function_with_driver_device() { - yhao_log(1, "****handle_init_function_with_driver_device start*******************"); - int64_t debug = -1; - std::string str; - int64_t ret = 0; - - execute_init_function(this->all_device_drivers); - for (auto temp_dd: this->all_device_drivers) { - // remove some device name - yhao_log(debug, "remove name start: "); - if (temp_dd->name.size() > 1) { - std::vector temp_name; - for (auto name: temp_dd->name) { - yhao_log(debug, name->print()); - if (name->fmt.find("%s") != std::string::npos && name->va2.empty()) { - continue; - } - temp_name.push_back(name); - } - if (temp_name.empty()) { - continue; - } - temp_dd->name.clear(); - for (auto name: temp_name) { - temp_dd->name.push_back(name); - } - } - yhao_log(debug, "remove name end: "); - - yhao_log(debug, "mapping: "); - yhao_log(debug, "checker ops:"); - yhao_log(debug, temp_dd->ops->print()); - yhao_log(debug, "checker name:"); - for (auto temp_1: temp_dd->name) { - yhao_log(debug, temp_1->print()); - } - yhao_log(debug, "checker number:"); - for (auto temp_1: temp_dd->number) { - yhao_log(debug, temp_1->print()); + yhao_log( + 1, + "****handle_init_function_with_driver_device start*******************"); + int64_t debug = -1; + std::string str; + int64_t ret = 0; + + execute_init_function(this->all_device_drivers); + for (auto temp_dd : this->all_device_drivers) { + // remove some device name + yhao_log(debug, "remove name start: "); + if (temp_dd->name.size() > 1) { + std::vector temp_name; + for (auto name : temp_dd->name) { + yhao_log(debug, name->print()); + if (name->fmt.find("%s") != std::string::npos && name->va2.empty()) { + continue; } + temp_name.push_back(name); + } + if (temp_name.empty()) { + continue; + } + temp_dd->name.clear(); + for (auto name : temp_name) { + temp_dd->name.push_back(name); + } } - yhao_log(1, "****handle_init_function_with_driver_device end*******************"); - return ret; -} - -void sd::Manager::mapping_checker_results(entry_function *ef, std::vector &results) { - int64_t debug = -1; - yhao_log(debug, "****mapping_checker_results(); start*****************"); - std::vector crs; - ef->get_checker_results(checker_type::dri_ops, &crs); - ef->get_checker_results(checker_type::file_ops, &crs); - if (crs.empty()) { - return; + yhao_log(debug, "remove name end: "); + + yhao_log(debug, "mapping: "); + yhao_log(debug, "checker ops:"); + yhao_log(debug, temp_dd->ops->print()); + yhao_log(debug, "checker name:"); + for (auto temp_1 : temp_dd->name) { + yhao_log(debug, temp_1->print()); } - for (auto c: crs) { - yhao_log(debug, "dri_ops or file_ops: " + c->print()); - auto temp = new device_driver(); - temp->linux_kernel_version = this->s->linux_kernel_version; - temp->ops = (checker_result_ops *) (c); - temp->parent = ef; - all_device_drivers.push_back(temp); - results.push_back(temp); + yhao_log(debug, "checker number:"); + for (auto temp_1 : temp_dd->number) { + yhao_log(debug, temp_1->print()); } + } + yhao_log( + 1, "****handle_init_function_with_driver_device end*******************"); + return ret; +} - crs.clear(); - ef->get_checker_results(checker_type::dri_name, &crs); - for (auto c: crs) { - int64_t match = -1, temp_match; - device_driver *temp_dd = nullptr; - bool equal_match = false; - for (auto temp: all_device_drivers) { - if (c->id == temp->ops->id) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match > match) { - match = temp_match; - temp_dd = temp; - equal_match = false; - } else if (temp_match == match) { - equal_match = true; - } - } +void sd::Manager::mapping_checker_results( + entry_function *ef, std::vector &results) { + int64_t debug = -1; + yhao_log(debug, "****mapping_checker_results(); start*****************"); + std::vector crs; + ef->get_checker_results(checker_type::dri_ops, &crs); + ef->get_checker_results(checker_type::file_ops, &crs); + if (crs.empty()) { + return; + } + for (auto c : crs) { + yhao_log(debug, "dri_ops or file_ops: " + c->print()); + auto temp = new device_driver(); + temp->linux_kernel_version = this->s->linux_kernel_version; + temp->ops = (checker_result_ops *)(c); + temp->parent = ef; + all_device_drivers.push_back(temp); + results.push_back(temp); + } + + crs.clear(); + ef->get_checker_results(checker_type::dri_name, &crs); + for (auto c : crs) { + int64_t match = -1, temp_match; + device_driver *temp_dd = nullptr; + bool equal_match = false; + for (auto temp : all_device_drivers) { + if (c->id == temp->ops->id) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match > match) { + match = temp_match; + temp_dd = temp; + equal_match = false; + } else if (temp_match == match) { + equal_match = true; } - c->match = match; - if (equal_match) { - for (auto temp: all_device_drivers) { - if (c->id == temp->ops->id) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match == match) { - temp->name.push_back((checker_result_string *) c); - } - } - } - } else if (temp_dd == nullptr) { - yhao_log(2, "temp_dd == nullptr: " + c->print()); - } else { - temp_dd->name.push_back((checker_result_string *) c); + } + } + c->match = match; + if (equal_match) { + for (auto temp : all_device_drivers) { + if (c->id == temp->ops->id) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match == match) { + temp->name.push_back((checker_result_string *)c); + } } + } + } else if (temp_dd == nullptr) { + yhao_log(2, "temp_dd == nullptr: " + c->print()); + } else { + temp_dd->name.push_back((checker_result_string *)c); } - - crs.clear(); - ef->get_checker_results(checker_type::dev_name, &crs); - for (auto c: crs) { - std::string p1 = get_file_name(c->call_chain.at(0)->getParent()->getParent()); - int64_t index = p1.find('/'); - index = p1.find('/', index + 1); - int64_t temp_match; - for (auto temp: all_device_drivers) { - if (c->id == temp->ops->id) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match > 0) { - c->match = temp_match; - temp->name.push_back((checker_result_string *) c); - } else if (temp_match == 0) { - std::string p2 = get_file_name(temp->ops->call_chain.at(0)->getParent()->getParent()); - if (index < p1.size() && index < p2.size()) { - if (p1.substr(0, index) == p2.substr(0, index)) { - temp->name.push_back((checker_result_string *) c); - } - } - } + } + + crs.clear(); + ef->get_checker_results(checker_type::dev_name, &crs); + for (auto c : crs) { + std::string p1 = + get_file_name(c->call_chain.at(0)->getParent()->getParent()); + int64_t index = p1.find('/'); + index = p1.find('/', index + 1); + int64_t temp_match; + for (auto temp : all_device_drivers) { + if (c->id == temp->ops->id) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match > 0) { + c->match = temp_match; + temp->name.push_back((checker_result_string *)c); + } else if (temp_match == 0) { + std::string p2 = get_file_name( + temp->ops->call_chain.at(0)->getParent()->getParent()); + if (index < p1.size() && index < p2.size()) { + if (p1.substr(0, index) == p2.substr(0, index)) { + temp->name.push_back((checker_result_string *)c); } + } } + } } + } - crs.clear(); - ef->get_checker_results(checker_type::dev_type, &crs); - for (auto c: crs) { - for (auto temp: all_device_drivers) { - temp->number.push_back((checker_result_number *) c); - } + crs.clear(); + ef->get_checker_results(checker_type::dev_type, &crs); + for (auto c : crs) { + for (auto temp : all_device_drivers) { + temp->number.push_back((checker_result_number *)c); } - - crs.clear(); - ef->get_checker_results(checker_type::dri_type, &crs); - ef->get_checker_results(checker_type::dri_major, &crs); - ef->get_checker_results(checker_type::dri_minor, &crs); - for (auto c: crs) { - int64_t match = -1, temp_match; - device_driver *temp_dd; - bool equal_match = false; - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match > match) { - match = temp_match; - temp_dd = temp; - equal_match = false; - } else if (temp_match == match) { - equal_match = true; - } - } - c->match = match; - if (equal_match) { - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match == match) { - temp->number.push_back((checker_result_number *) c); - } - } - } else { - temp_dd->number.push_back((checker_result_number *) c); - } + } + + crs.clear(); + ef->get_checker_results(checker_type::dri_type, &crs); + ef->get_checker_results(checker_type::dri_major, &crs); + ef->get_checker_results(checker_type::dri_minor, &crs); + for (auto c : crs) { + int64_t match = -1, temp_match; + device_driver *temp_dd; + bool equal_match = false; + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match > match) { + match = temp_match; + temp_dd = temp; + equal_match = false; + } else if (temp_match == match) { + equal_match = true; + } } - - crs.clear(); - ef->get_checker_results(checker_type::file_install, &crs); - for (auto c: crs) { - yhao_log(debug, "file_install: " + c->print()); - int64_t match = -1, temp_match; - device_driver *temp_dd; - bool equal_match = false; - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match > match) { - match = temp_match; - temp_dd = temp; - equal_match = false; - } else if (temp_match == match) { - equal_match = true; - } - } - c->match = match; - if (equal_match) { - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match == match) { - temp->file_install.push_back(c); - } - } - } else { - if (temp_dd == nullptr) { - yhao_log(3, "temp_dd == nullptr"); - } - temp_dd->file_install.push_back(c); + c->match = match; + if (equal_match) { + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match == match) { + temp->number.push_back((checker_result_number *)c); } + } + } else { + temp_dd->number.push_back((checker_result_number *)c); } - - crs.clear(); - ef->get_checker_results(checker_type::file_fd, &crs); - for (auto c: crs) { - int64_t match = -1, temp_match; - device_driver *temp_dd; - bool equal_match = false; - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match > match) { - match = temp_match; - temp_dd = temp; - equal_match = false; - } else if (temp_match == match) { - equal_match = true; - } + } + + crs.clear(); + ef->get_checker_results(checker_type::file_install, &crs); + for (auto c : crs) { + yhao_log(debug, "file_install: " + c->print()); + int64_t match = -1, temp_match; + device_driver *temp_dd; + bool equal_match = false; + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match > match) { + match = temp_match; + temp_dd = temp; + equal_match = false; + } else if (temp_match == match) { + equal_match = true; + } + } + c->match = match; + if (equal_match) { + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match == match) { + temp->file_install.push_back(c); } - c->match = match; - if (equal_match) { - for (auto temp: all_device_drivers) { - temp_match = match_call_chain(c, temp->ops); - if (temp_match == match) { - temp->file_fd.push_back((checker_result_number *) c); - } - } - } else { - temp_dd->file_fd.push_back((checker_result_number *) c); + } + } else { + if (temp_dd == nullptr) { + yhao_log(3, "temp_dd == nullptr"); + } + temp_dd->file_install.push_back(c); + } + } + + crs.clear(); + ef->get_checker_results(checker_type::file_fd, &crs); + for (auto c : crs) { + int64_t match = -1, temp_match; + device_driver *temp_dd; + bool equal_match = false; + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match > match) { + match = temp_match; + temp_dd = temp; + equal_match = false; + } else if (temp_match == match) { + equal_match = true; + } + } + c->match = match; + if (equal_match) { + for (auto temp : all_device_drivers) { + temp_match = match_call_chain(c, temp->ops); + if (temp_match == match) { + temp->file_fd.push_back((checker_result_number *)c); } + } + } else { + temp_dd->file_fd.push_back((checker_result_number *)c); } + } - for (auto dd: all_device_drivers) { - dd->set_kind(); + for (auto dd : all_device_drivers) { + dd->set_kind(); + } + yhao_log(debug, "****mapping_checker_results(); end*******************"); +} + +void sd::Manager::check_cmd_and_type(const std::string &function_name, + nlohmann::json *result_json, + std::set *fps) const {} + +int64_t sd::Manager::get_function_by_index(sd::checker_result_ops *cr0, + int64_t index, + llvm::Function **fp) const { + std::string str; + int64_t debug = -1; + int64_t ret; + llvm::GlobalVariable *ops; + ret = this->t_module->find_ops_structure(cr0->ops_structure, cr0->ops_name, + &ops); + if (ret) { + return 1; + } + + if (!ops->hasInitializer()) { + yhao_log(debug, "ops->hasInitializer()"); + return 1; + } + + auto c = ops->getInitializer(); + const llvm::ConstantStruct *cs = llvm::dyn_cast(c); + if (cs == nullptr) { + yhao_log(debug, "llvm::dyn_cast 1"); + yhao_dump(debug, ops->print, str); + return 1; + } + + if (index == -2) { + return 1; + } + + if (cs->getNumOperands() <= 2) { + c = cs->getOperand(0); + cs = llvm::dyn_cast(c); + if (cs == nullptr) { + yhao_log(debug, "llvm::dyn_cast 2"); + yhao_dump(debug, ops->print, str); + return 1; } - yhao_log(debug, "****mapping_checker_results(); end*******************"); + } + + if (index >= cs->getNumOperands() || index < 0) { + yhao_log(2, "cr0->ops_name: " + cr0->ops_name); + yhao_log(2, "get_function_by_index: index >= cs->getNumOperands(): " + + std::to_string(index)); + yhao_dump(2, cs->print, str); + return 1; + } + + llvm::Value *fp1 = cs->getOperand(index); + if (llvm::isa(fp1)) { + fp1 = llvm::dyn_cast(fp1)->getOperand(0); + } + auto *fp2 = llvm::dyn_cast(fp1); + if (fp2 == nullptr) { + yhao_log(debug, "cr0->ops_name: " + cr0->ops_name); + yhao_print(debug, fp1->print, str); + yhao_log(debug, "get_function_by_index: fail: " + std::to_string(index) + + ": " + str); + return 1; + } + *fp = fp2; + return 0; } -void sd::Manager::check_cmd_and_type(const std::string &function_name, nlohmann::json *result_json, - std::set *fps) const { +int64_t sd::Manager::get_function_by_syscall(sd::checker_result_ops *cr0, + std::string syscall, + int64_t *index, + llvm::Function **fp) const { + std::string str; + int64_t ret; + K_variable *v; + ret = this->k->find_k_variable(cr0->structure, cr0->offset, &v); + if (ret) { + return ret; + } + if (v->functions_index.find(syscall) == v->functions_index.end()) { + return 1; + } + *index = v->functions_index[syscall]; + ret = get_function_by_index(cr0, *index, fp); + if (ret) { + return ret; + } + return 0; +} +sd::task *sd::Manager::make_task(const std::string &entry_function, + checker_result *cr, + const std::string &task_bitcode, + const std::string &task_work_dir) const { + auto task = new class task(entry_function, cr); + if (task_bitcode.empty()) { + task->bitcode = this->bitcode; + } else { + task->bitcode = task_bitcode; + } + if (task_work_dir.empty()) { + task->work_dir = this->work_dir; + } else { + task->work_dir = task_work_dir; + } + return task; } -int64_t sd::Manager::get_function_by_index(sd::checker_result_ops *cr0, int64_t index, llvm::Function **fp) const { - std::string str; - int64_t debug = -1; - int64_t ret; - llvm::GlobalVariable *ops; - ret = this->t_module->find_ops_structure(cr0->ops_structure, cr0->ops_name, &ops); - if (ret) { - return 1; +void sd::Manager::execute_init_function( + std::vector &dds) const { + for (auto temp_dd : dds) { + // get driver ops checker + auto cr_ops = temp_dd->ops; + auto task1 = make_task(temp_dd->parent->get_entry_function_name(), cr_ops); + execute_task(task1); + + // get device name checker + for (auto temp_1 : temp_dd->name) { + auto task2 = + make_task(temp_dd->parent->get_entry_function_name(), temp_1); + execute_task(task2); } + } +} - if (!ops->hasInitializer()) { - yhao_log(debug, "ops->hasInitializer()"); - return 1; +// now only consider one task_str with on checker +int64_t sd::Manager::execute_task(sd::task *t) { + std::string str; + int64_t debug = 0; + llvm::Value *debug_v = nullptr; + + auto ct = t->cr->ct; + switch (ct) { + case checker_type::dev_type: + case checker_type::dri_type: + case checker_type::dri_major: + case checker_type::dri_minor: { + // cr = new checker_result_number(); + return 0; } + case checker_type::dev_name: + case checker_type::dri_name: { + auto cr = (checker_result_string *)t->cr; + auto inst = cr->inst; + if (inst->getOpcode() == llvm::Instruction::Call) { + if (cr->value > inst->getNumOperands()) { + yhao_log(3, "inst->getNumOperands() <= cr->value"); + return 1; + } + auto v = inst->getOperand(cr->value); + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); + } + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); + } + if (cr->value_offset != -2) { + auto gv = llvm::dyn_cast(v); + if (gv == nullptr) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "gv == nullptr"); + break; + } + if (!gv->hasInitializer()) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "!gv->hasInitializer()"); + break; + } + auto gvI = gv->getInitializer(); + auto temp_v1 = llvm::dyn_cast(gvI); + if (temp_v1 == nullptr) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "temp_v1 == nullptr"); + break; + } + yhao_dump(debug, temp_v1->print, str); + llvm::Value *temp_v2 = nullptr; + if (!temp_v1->getType()->hasName()) { + temp_v2 = temp_v1->getOperand(0)->getOperand(cr->value_offset); + } else { + temp_v2 = temp_v1->getOperand(cr->value_offset); + } + + if (llvm::isa(temp_v2)) { + temp_v2 = + llvm::dyn_cast(temp_v2)->getOperand(0); + } + + v = temp_v2; + } else { + } - auto c = ops->getInitializer(); - const llvm::ConstantStruct *cs = llvm::dyn_cast(c); - if (cs == nullptr) { - yhao_log(debug, "llvm::dyn_cast"); - yhao_dump(debug, ops->print, str) - return 1; - } + if (auto temp_v1 = llvm::dyn_cast(v)) { + v = temp_v1->getOperand(0); + } - if (index == -2) { - return 1; - } + auto gv = llvm::dyn_cast(v); + if (gv == nullptr || !gv->hasInitializer()) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "gv == nullptr || !gv->hasInitializer()"); + break; + } - if (index >= cs->getNumOperands() || index < 0) { - yhao_log(2, "cr0->ops_name: " + cr0->ops_name); - yhao_log(2, "get_function_by_index: index >= cs->getNumOperands(): " + std::to_string(index)); - return 1; - } + auto gvI = gv->getInitializer(); - auto fp1 = cs->getOperand(index); - auto *fp2 = llvm::dyn_cast(fp1); - if (fp2 == nullptr) { - yhao_log(debug, "cr0->ops_name: " + cr0->ops_name); - yhao_print(debug, fp1->print, str) - yhao_log(debug, "get_function_by_index: fail: " + std::to_string(index) + ": " + str); - return 1; - } - *fp = fp2; - return 0; -} - -int64_t sd::Manager::get_function_by_syscall(sd::checker_result_ops *cr0, std::string syscall, int64_t *index, - llvm::Function **fp) const { - std::string str; - int64_t ret; + if (const llvm::ConstantStruct *c = + llvm::dyn_cast(gvI)) { + gvI = c->getOperand(0); + } - K_variable *v; - ret = this->k->find_k_variable(cr0->structure, cr0->offset, &v); - if (ret) { - return ret; - } - if (v->functions_index.find(syscall) == v->functions_index.end()) { - return 1; - } - *index = v->functions_index[syscall]; - ret = get_function_by_index(cr0, *index, fp); - if (ret) { - return ret; - } - return 0; -} + if (const llvm::ConstantDataArray *currDArray = + llvm::dyn_cast(gvI)) { + cr->fmt = currDArray->getAsCString().str(); + } else { + yhao_print(3, gvI->print, str); + cr->fmt = str; + } -sd::task * -sd::Manager::make_task(const std::string &entry_function, checker_result *cr, - const std::string &task_bitcode, - const std::string &task_work_dir) const { - auto task = new class task(entry_function, cr); - if (task_bitcode.empty()) { - task->bitcode = this->bitcode; - } else { - task->bitcode = task_bitcode; - } - if (task_work_dir.empty()) { - task->work_dir = this->work_dir; - } else { - task->work_dir = task_work_dir; - } - return task; -} + if (cr->value != -2) { + yhao_log(debug, "handle situation: name 1"); + yhao_log(debug, t->print()); + return 0; + } + yhao_dump(debug, inst->print, str); + yhao_log(debug, "operands number of call inst: " + + std::to_string(inst->getNumOperands())); + for (int64_t i = cr->value + 1; i < inst->getNumOperands() - 1; ++i) { + auto temp_v1 = inst->getOperand(i); + if (llvm::isa(temp_v1)) { + auto temp_v2 = llvm::dyn_cast(temp_v1); + temp_v1 = temp_v2->getOperand(0); + auto temp_gv1 = llvm::dyn_cast(temp_v1); + if (temp_gv1 == nullptr || !temp_gv1->hasInitializer()) { + cr->va2.emplace_back(""); + continue; + } + auto temp_gv1I = temp_gv1->getInitializer(); -void sd::Manager::execute_init_function(std::vector &dds) const { - for (auto temp_dd: dds) { - // get driver ops checker - auto cr_ops = temp_dd->ops; - auto task1 = make_task(temp_dd->parent->get_entry_function_name(), cr_ops); - execute_task(task1); - - // get device name checker - for (auto temp_1: temp_dd->name) { - auto task2 = make_task(temp_dd->parent->get_entry_function_name(), temp_1); - execute_task(task2); + if (const llvm::ConstantDataArray *cda = + llvm::dyn_cast(temp_gv1I)) { + cr->va2.push_back(cda->getAsCString().str()); + } else { + yhao_print(3, temp_gv1I->print, str); + cr->va2.push_back(str); + } + } else if (llvm::isa(temp_v1)) { + auto temp_v2 = llvm::dyn_cast(temp_v1); + cr->va1.push_back(temp_v2->getZExtValue()); + } else { + } } + yhao_log(debug, "handle situation: name 2"); + yhao_log(debug, t->print()); + return 0; + } + break; } -} - -// now only consider one task_str with on checker -int64_t sd::Manager::execute_task(sd::task *t) { - std::string str; - int64_t debug = -1; - - auto ct = t->cr->ct; - switch (ct) { - case checker_type::dev_type: - case checker_type::dri_type: - case checker_type::dri_major: - case checker_type::dri_minor: { -// cr = new checker_result_number(); - return 0; + case checker_type::dri_ops: + case checker_type::file_ops: { + auto cr = (checker_result_ops *)t->cr; + auto inst = cr->inst; + if (inst->getOpcode() == llvm::Instruction::Store) { + auto v = inst->getOperand(0); + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); } - case checker_type::dev_name: - case checker_type::dri_name: { - auto cr = (checker_result_string *) t->cr; - auto inst = cr->inst; - if (inst->getOpcode() == llvm::Instruction::Call) { - if (cr->value > inst->getNumOperands()) { - yhao_log(3, "inst->getNumOperands() <= cr->value"); - return 1; - } - auto v = inst->getOperand(cr->value); - if (cr->value_offset != -2) { - auto gv = llvm::dyn_cast(v); - if (gv == nullptr) { - break; - } - if (!gv->hasInitializer()) { - break; - } - auto gvI = gv->getInitializer(); - auto temp_v1 = llvm::dyn_cast(gvI); - if (temp_v1 == nullptr) { - break; - } - v = temp_v1->getOperand(cr->value_offset); - } - if (auto temp_v1 = llvm::dyn_cast(v);temp_v1 == nullptr) { - break; - } else { - v = temp_v1->getOperand(0); - } - auto gv = llvm::dyn_cast(v); - if (gv == nullptr || !gv->hasInitializer()) { - break; - } - auto gvI = gv->getInitializer(); - const llvm::ConstantDataArray *currDArray = llvm::dyn_cast(gvI); - if (currDArray != nullptr) { - cr->fmt = currDArray->getAsCString().str(); - } else { - yhao_print(-1, gvI->print, str) - cr->fmt = str; - } - - if (cr->value_offset != -2) { - return 0; - } - yhao_dump(debug, inst->print, str) - yhao_log(debug, "number of call inst: " + std::to_string(inst->getNumOperands())); - for (int64_t i = cr->value + 1; i < inst->getNumOperands() - 1; ++i) { - auto temp_v1 = inst->getOperand(i); - if (llvm::isa(temp_v1)) { - auto temp_v2 = llvm::dyn_cast(temp_v1); - temp_v1 = temp_v2->getOperand(0); - auto temp_gv1 = llvm::dyn_cast(temp_v1); - if (temp_gv1 == nullptr || !temp_gv1->hasInitializer()) { - cr->va2.emplace_back(""); - break; - } - auto temp_gv1I = temp_gv1->getInitializer(); - const llvm::ConstantDataArray *temp_currDArray = llvm::dyn_cast( - temp_gv1I); - if (temp_currDArray != nullptr) { - cr->va2.push_back(temp_currDArray->getAsCString().str()); - } else { - yhao_print(-1, temp_gv1I->print, str) - cr->va2.push_back(str); - } - } else if (llvm::isa(temp_v1)) { - auto temp_v2 = llvm::dyn_cast(temp_v1); - cr->va1.push_back(temp_v2->getZExtValue()); - } else { - - } - } - return 0; - } - break; + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); + } + auto gv = llvm::dyn_cast(v); + if (gv == nullptr) { + break; } - case checker_type::dri_ops: - case checker_type::file_ops: { - auto cr = (checker_result_ops *) t->cr; - auto inst = cr->inst; - if (inst->getOpcode() == llvm::Instruction::Store) { - auto v = inst->getOperand(0); - auto gv = llvm::dyn_cast(v); - if (gv == nullptr) { - break; - } - if (!gv->hasInitializer()) { - break; - } - auto gvI = gv->getInitializer(); - auto gvt = gvI->getType(); - if (gvt->isStructTy()) { - cr->ops_structure = gvt->getStructName().str(); - } - cr->ops_name = gv->getName().str(); - return 0; - - } else if (inst->getOpcode() == llvm::Instruction::Call) { - auto v = inst->getOperand(cr->value); - auto gv = llvm::dyn_cast(v); - if (gv == nullptr) { - yhao_log(2, "gv == nullptr"); - break; - } - if (!gv->hasInitializer()) { - yhao_log(2, "!gv->hasInitializer()"); - break; - } - auto gvI = gv->getInitializer(); - if (cr->value_offset != -2) { - auto temp_v1 = llvm::dyn_cast(gvI); - if (temp_v1 == nullptr) { - break; - } - auto temp_v2 = temp_v1->getOperand(cr->value_offset); - gv = llvm::dyn_cast(temp_v2); - if (gv == nullptr) { - yhao_log(1, "gv == nullptr"); - break; - } - if (!gv->hasInitializer()) { - yhao_log(1, "!gv->hasInitializer()"); - break; - } - gvI = gv->getInitializer(); - } - auto gvt = gvI->getType(); - if (gvt->isStructTy()) { - cr->ops_structure = gvt->getStructName().str(); - } - cr->ops_name = gv->getName().str(); - return 0; + if (!gv->hasInitializer()) { + break; + } + auto gvI = gv->getInitializer(); + auto gvt = gvI->getType(); + if (gvt->isStructTy()) { + auto temp = llvm::dyn_cast(gvt); + if (temp->hasName()) { + cr->ops_structure = gvt->getStructName().str(); + } else { + if (llvm::isa(gvt->getStructElementType(0))) { + cr->ops_structure = + gvt->getStructElementType(0)->getStructName().str(); } - break; + } + } + cr->ops_name = gv->getName().str(); + yhao_log(debug, "handle situation: ops store"); + yhao_log(debug, t->print()); + return 0; + + } else if (inst->getOpcode() == llvm::Instruction::Call) { + auto v = inst->getOperand(cr->value); + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); } - case checker_type::open_indirect: { -// execute_task_by_klee(t); - return 0; + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); } - case checker_type::file_fd: - case checker_type::file_install: - default: { - yhao_log(3, "not handle now"); - return 0; + auto gv = llvm::dyn_cast(v); + if (gv == nullptr) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "gv == nullptr"); + break; } + if (!gv->hasInitializer()) { + yhao_dump(debug, v->print, str); + yhao_log(debug, "!gv->hasInitializer()"); + break; + } + auto gvI = gv->getInitializer(); + if (cr->value_offset != -2) { + auto temp_v1 = llvm::dyn_cast(gvI); + if (temp_v1 == nullptr) { + yhao_log(debug, "temp_v1 == nullptr"); + debug_v = gvI; + break; + } + + llvm::Value *temp_v2 = nullptr; + if (!temp_v1->getType()->hasName()) { + temp_v2 = temp_v1->getOperand(0)->getOperand(cr->value_offset); + } else { + temp_v2 = temp_v1->getOperand(cr->value_offset); + } + + if (llvm::isa(temp_v2)) { + temp_v2 = llvm::dyn_cast(temp_v2)->getOperand(0); + } + if (llvm::isa(temp_v2)) { + temp_v2 = + llvm::dyn_cast(temp_v2)->getOperand(0); + } + + gv = llvm::dyn_cast(temp_v2); + if (gv == nullptr) { + yhao_dump(debug, temp_v2->print, str); + yhao_log(debug, "cr->value_offset: gv == nullptr"); + break; + } + if (!gv->hasInitializer()) { + yhao_dump(debug, temp_v2->print, str); + yhao_log(debug, "cr->value_offset: !gv->hasInitializer()"); + break; + } + gvI = gv->getInitializer(); + } + auto gvt = gvI->getType(); + if (gvt->isStructTy()) { + auto temp = llvm::dyn_cast(gvt); + if (temp->hasName()) { + cr->ops_structure = gvt->getStructName().str(); + } else { + if (llvm::isa(gvt->getStructElementType(0))) { + cr->ops_structure = + gvt->getStructElementType(0)->getStructName().str(); + } + } + } + cr->ops_name = gv->getName().str(); + yhao_log(debug, "handle situation: ops call"); + yhao_log(debug, t->print()); + return 0; + } + break; } - yhao_log(2, "not handle situation"); - yhao_log(2, t->print()); -// execute_task_by_klee(t); - return 0; + case checker_type::open_indirect: { + // execute_task_by_klee(t); + return 0; + } + case checker_type::file_fd: + case checker_type::file_install: + default: { + yhao_log(3, "not handle now"); + return 0; + } + } + yhao_log(2, "not handle situation"); + if (debug_v != nullptr) { + yhao_dump(2, debug_v->print, str); + } + yhao_log(2, t->print()); + // execute_task_by_klee(t); + return 0; } int64_t sd::Manager::execute_task_by_klee(sd::task *t) const { - auto j = t->to_json(); - std::ofstream json_of_stream(t->task_str); - json_of_stream << j->dump(2); - json_of_stream.close(); - delete j; - - std::string cmd; - cmd = this->template_klee; - cmd.append(" --config_json=" + t->work_dir + t->task_str); - cmd.append("1>>klee_debug.log 2>&1"); - - yhao_log(1, "cmd start: " + cmd); - - FILE *stream; - std::string Result; - const int max_buffer = 1024; - char buffer[max_buffer]; - - stream = popen(cmd.c_str(), "r"); - if (stream) { - while (!feof(stream)) { - if (fgets(buffer, max_buffer, stream) != nullptr) - Result = buffer; - } - pclose(stream); + auto j = t->to_json(); + std::ofstream json_of_stream(t->task_str); + json_of_stream << j->dump(2); + json_of_stream.close(); + delete j; + + std::string cmd; + cmd = this->template_klee; + cmd.append(" --config_json=" + t->work_dir + t->task_str); + cmd.append("1>>klee_debug.log 2>&1"); + + yhao_log(1, "cmd start: " + cmd); + + FILE *stream; + std::string Result; + const int max_buffer = 1024; + char buffer[max_buffer]; + + stream = popen(cmd.c_str(), "r"); + if (stream) { + while (!feof(stream)) { + if (fgets(buffer, max_buffer, stream) != nullptr) Result = buffer; } + pclose(stream); + } - yhao_log(1, "cmd finish: " + cmd); + yhao_log(1, "cmd finish: " + cmd); - std::ifstream json_if_stream(t->task_str); - nlohmann::json new_json; - json_if_stream >> new_json; - t->from_json(new_json); - json_if_stream.close(); - return 0; + std::ifstream json_if_stream(t->task_str); + nlohmann::json new_json; + json_if_stream >> new_json; + t->from_json(new_json); + json_if_stream.close(); + return 0; } void sd::Manager::collect_entry(sd::device_driver *dd) const { - int64_t ret; - llvm::GlobalVariable *ops; - ret = this->t_module->find_ops_structure(dd->ops->ops_structure, dd->ops->ops_name, &ops); - if (ret) { - return; - } - - if (!ops->hasInitializer()) { - return; - } - - auto c = ops->getInitializer(); - const llvm::ConstantStruct *cs = llvm::dyn_cast(c); - if (cs == nullptr) { - return; + int64_t ret; + llvm::GlobalVariable *ops; + ret = this->t_module->find_ops_structure(dd->ops->ops_structure, + dd->ops->ops_name, &ops); + if (ret) { + return; + } + + if (!ops->hasInitializer()) { + return; + } + + auto c = ops->getInitializer(); + const llvm::ConstantStruct *cs = llvm::dyn_cast(c); + if (cs == nullptr) { + return; + } + + for (uint64_t index = 0; index < cs->getNumOperands(); index++) { + auto fp1 = cs->getOperand(index); + auto *fp2 = llvm::dyn_cast(fp1); + if (fp2 == nullptr) { + continue; } + dd->entries.insert(fp2); + } +} - for (uint64_t index = 0; index < cs->getNumOperands(); index++) { - auto fp1 = cs->getOperand(index); - auto *fp2 = llvm::dyn_cast(fp1); - if (fp2 == nullptr) { - continue; - } - dd->entries.insert(fp2); - } +llvm::Value *sd::Manager::get_real_value(llvm::Value *v) { + if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); + return get_real_value(v); + } else if (llvm::isa(v)) { + v = llvm::dyn_cast(v)->getOperand(0); + return get_real_value(v); + } else if (llvm::ConstantStruct *cs = llvm::dyn_cast(v); + cs && !cs->hasName()) { + v = cs->getOperand(0); + return get_real_value(v); + } else { + return v; + } } diff --git a/lib/ManagerLib/Manager.h b/lib/ManagerLib/Manager.h index 3a012b6..c2b850d 100644 --- a/lib/ManagerLib/Manager.h +++ b/lib/ManagerLib/Manager.h @@ -5,118 +5,123 @@ #ifndef INC_2021_TEMPLATE_MANAGER_H #define INC_2021_TEMPLATE_MANAGER_H -#include "../ToolLib/json.hpp" #include "../AnalysisLib/T_module.h" -#include "../KnowledgeLib/knowledge.h" -#include "../KnowledgeLib/task.h" #include "../KnowledgeLib/device_driver.h" +#include "../KnowledgeLib/knowledge.h" #include "../KnowledgeLib/syzlang.h" +#include "../KnowledgeLib/task.h" +#include "../ToolLib/json.hpp" namespace sd { - class Manager { - public: - nlohmann::json config_json; - T_module *t_module; - knowledge *k; - syzlang *s; - - std::string bitcode; - std::string work_dir; - // analysis tool - std::string template_klee; +class Manager { + public: + nlohmann::json config_json; + T_module *t_module; + knowledge *k; + syzlang *s; - // all new entry function - std::vector all_new_entry_functions; + std::string bitcode; + std::string work_dir; + // analysis tool + std::string template_klee; - // module init functions - std::map init_function; + // all new entry function + std::vector all_new_entry_functions; - std::map init_function_with_driver; - std::map init_function_with_device; - std::map init_function_with_driver_device; + // module init functions + std::map init_function; - std::vector all_device_drivers; - std::map device_drivers; + std::map init_function_with_driver; + std::map init_function_with_device; + std::map init_function_with_driver_device; - // statistic - uint64_t number_module_init_function = 0; - uint64_t number_driver = 0; - uint64_t number_ioctl = 0; + std::vector all_device_drivers; + std::map device_drivers; - // vs dynamic + // statistic + uint64_t number_module_init_function = 0; + uint64_t number_driver = 0; + uint64_t number_ioctl = 0; + // vs dynamic - // function pointer - uint64_t number_function_pointer = 0; - uint64_t number_indirect_call = 0; - uint64_t number_indirect_call_target_before = 0; - uint64_t number_indirect_call_target_after = 0; + // function pointer + uint64_t number_function_pointer = 0; + uint64_t number_indirect_call = 0; + uint64_t number_indirect_call_target_before = 0; + uint64_t number_indirect_call_target_after = 0; - // analysis time - time_t start, end; - double analysis_time_module_init_function = 0; - double analysis_time_ioctl = 0; + // analysis time + time_t start, end; + double analysis_time_module_init_function = 0; + double analysis_time_ioctl = 0; - public: - Manager(); + public: + Manager(); - void setup(const std::string &config); + void setup(const std::string &config); - void analysis(); + void analysis(); - void analysis_ops_and_file_name(); + void analysis_ops_and_file_name(); - void collect_info(device_driver *dd); + void collect_info(device_driver *dd); - void collect_entry(device_driver *dd) const; + void collect_entry(device_driver *dd) const; - void collect_cmd_and_type(device_driver *dd); + void collect_cmd_and_type(device_driver *dd); - static void collect_entry_function(device_driver *dd, std::set &entry_set); + static void collect_entry_function(device_driver *dd, + std::set &entry_set); - // 1. use module init function as entry point - // 2. classify the functions based the number of driver and device - void analysis_init_function(); + // 1. use module init function as entry point + // 2. classify the functions based the number of driver and device + void analysis_init_function(); - // 1. get the value - // 2. generate new k - int64_t handle_init_function_with_driver(); + // 1. get the value + // 2. generate new k + int64_t handle_init_function_with_driver(); - // check the function with new k - int64_t handle_init_function_with_device(); + // check the function with new k + int64_t handle_init_function_with_device(); - // 1. get the value - // 2. generate template - int64_t handle_init_function_with_driver_device(); + // 1. get the value + // 2. generate template + int64_t handle_init_function_with_driver_device(); - void mapping_checker_results(entry_function *ef, std::vector &results); + void mapping_checker_results(entry_function *ef, + std::vector &results); - void check_cmd_and_type(const std::string &function_name, nlohmann::json *result_json, - std::set *fps) const; + void check_cmd_and_type(const std::string &function_name, + nlohmann::json *result_json, + std::set *fps) const; - // find ops structure from give sd::checker_result_ops *cr0 - // and find function by int64_t index - // and return function to llvm::Function **fp - int64_t get_function_by_index(sd::checker_result_ops *cr0, int64_t index, llvm::Function **fp) const; + // find ops structure from give sd::checker_result_ops *cr0 + // and find function by int64_t index + // and return function to llvm::Function **fp + int64_t get_function_by_index(sd::checker_result_ops *cr0, int64_t index, + llvm::Function **fp) const; - int64_t get_function_by_syscall(sd::checker_result_ops *cr0, std::string syscall, int64_t *index, - llvm::Function **fp) const; + int64_t get_function_by_syscall(sd::checker_result_ops *cr0, + std::string syscall, int64_t *index, + llvm::Function **fp) const; - // make a task_str based on give information - // use default information from Class Manager - [[nodiscard]] task * - make_task(const std::string &entry_function, checker_result *cr, - const std::string &task_bitcode = "", - const std::string &task_work_dir = "") const; + // make a task_str based on give information + // use default information from Class Manager + [[nodiscard]] task *make_task(const std::string &entry_function, + checker_result *cr, + const std::string &task_bitcode = "", + const std::string &task_work_dir = "") const; - void execute_init_function(std::vector &dds) const; + void execute_init_function(std::vector &dds) const; - // execute the task_str and get the results - static int64_t execute_task(task *t); + // execute the task_str and get the results + static int64_t execute_task(task *t); - int64_t execute_task_by_klee(task *t) const; - }; -} + int64_t execute_task_by_klee(task *t) const; + llvm::Value *get_real_value(llvm::Value *v); +}; +} // namespace sd -#endif //INC_2021_TEMPLATE_MANAGER_H +#endif // INC_2021_TEMPLATE_MANAGER_H diff --git a/lib/ToolLib/basic.h b/lib/ToolLib/basic.h index 8419774..8172342 100644 --- a/lib/ToolLib/basic.h +++ b/lib/ToolLib/basic.h @@ -5,43 +5,43 @@ #ifndef INC_BASIC_H #define INC_BASIC_H -#define DEBUG_LEVEL 1 +#define DEBUG_LEVEL (0) #define ERR 0 #define DELIMITER '$' #define Annotation_Symbol "# " #define PREFIX "syz_describe_" -#include -#include +#include +#include +#include +#include +#include #include #include -#include +#include #include +#include +#include #include -#include -#include -#include +#include #include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include #include -#include -#include +#include +#include +#include +#include +#include #include #include #include -#include -#include #include -#include -#endif //INC_BASIC_H +#endif // INC_BASIC_H diff --git a/lib/ToolLib/llvm_related.cpp b/lib/ToolLib/llvm_related.cpp index f8c9928..e340b88 100644 --- a/lib/ToolLib/llvm_related.cpp +++ b/lib/ToolLib/llvm_related.cpp @@ -3,412 +3,409 @@ // #include "llvm_related.h" + #include "log.h" llvm::BasicBlock *get_real_basic_block(llvm::BasicBlock *b) { - llvm::BasicBlock *rb; - if (b->hasName()) { - rb = b; - } else { - for (auto *Pred: llvm::predecessors(b)) { - rb = get_real_basic_block(Pred); - break; - } + llvm::BasicBlock *rb; + if (b->hasName()) { + rb = b; + } else { + for (auto *Pred : llvm::predecessors(b)) { + rb = get_real_basic_block(Pred); + break; } - return rb; + } + return rb; } llvm::BasicBlock *get_final_basic_block(llvm::BasicBlock *b) { - auto *inst = b->getTerminator(); - for (unsigned int i = 0, end = inst->getNumSuccessors(); i < end; i++) { - std::string name = inst->getSuccessor(i)->getName().str(); - if (inst->getSuccessor(i)->hasName()) { - } else { - return get_final_basic_block(inst->getSuccessor(i)); - } + auto *inst = b->getTerminator(); + for (unsigned int i = 0, end = inst->getNumSuccessors(); i < end; i++) { + std::string name = inst->getSuccessor(i)->getName().str(); + if (inst->getSuccessor(i)->hasName()) { + } else { + return get_final_basic_block(inst->getSuccessor(i)); } - return b; + } + return b; } std::string get_file_name(llvm::Function *f) { - if (f->hasMetadata()) { - llvm::SmallVector, 4> MDs; - f->getAllMetadata(MDs); - for (auto &MD: MDs) { - llvm::MDNode *N = MD.second; - if (N == nullptr) { - continue; - } - auto *SP = llvm::dyn_cast(N); - if (SP == nullptr) { - continue; - } - std::string Path = SP->getFilename().str(); - return Path; - } + if (f->hasMetadata()) { + llvm::SmallVector, 4> MDs; + f->getAllMetadata(MDs); + for (auto &MD : MDs) { + llvm::MDNode *N = MD.second; + if (N == nullptr) { + continue; + } + auto *SP = llvm::dyn_cast(N); + if (SP == nullptr) { + continue; + } + std::string Path = SP->getFilename().str(); + return Path; } - return ""; + } + return ""; } std::string get_real_function_name(llvm::Function *f) { - std::string name = f->getName().str(); - std::string ret; - if (name.find('.') != std::string::npos) { - ret = name.substr(0, name.find('.')); - } else { - ret = name; - } - return ret; + std::string name = f->getName().str(); + std::string ret; + if (name.find('.') != std::string::npos) { + ret = name.substr(0, name.find('.')); + } else { + ret = name; + } + return ret; } std::string get_real_function_type(llvm::FunctionType *ft) { - std::string type; - std::string str; - int64_t debug = 4; - auto ret = ft->getReturnType(); - if (ret->isPointerTy() && ret->getNumContainedTypes() && ret->getNonOpaquePointerElementType()->isStructTy()) { - yhao_print(debug, ret->print, str) - str = str.substr(0, str.size() - 1); - if (str.find("struct") == std::string::npos) { - type += str; - } else { - type += (get_real_structure_name(str) + "*"); - } - } else if (ret->isStructTy()) { - yhao_print(debug, ret->print, str) - if (str.find("struct") == std::string::npos) { - type += str; - } else { - type += get_real_structure_name(str); - } + std::string type; + std::string str; + int64_t debug = 4; + auto ret = ft->getReturnType(); + if (ret->isPointerTy() && ret->getNumContainedTypes() && + ret->getNonOpaquePointerElementType()->isStructTy()) { + yhao_print(debug, ret->print, str) str = str.substr(0, str.size() - 1); + if (str.find("struct") == std::string::npos) { + type += str; } else { - yhao_print(debug, ret->print, str) - type += str; + type += (get_real_structure_name(str) + "*"); } - type += " ("; - for (auto i = 0; i < ft->getNumParams(); i++) { - if (i != 0) { - type += ", "; - } - auto temp = ft->getParamType(i); - if (temp->isPointerTy() && temp->getNumContainedTypes() && temp->getNonOpaquePointerElementType()->isStructTy()) { - yhao_print(debug, temp->print, str) - str = str.substr(0, str.size() - 1); - if (str.find("struct") == std::string::npos) { - type += str; - } else { - type += (get_real_structure_name(str) + "*"); - } - } else if (temp->isStructTy()) { - yhao_print(debug, temp->print, str) - if (str.find("struct") == std::string::npos) { - type += str; - } else { - type += get_real_structure_name(str); - } - } else { - yhao_print(debug, temp->print, str) - type += str; - } + } else if (ret->isStructTy()) { + yhao_print(debug, ret->print, + str) if (str.find("struct") == std::string::npos) { + type += str; } - type += ")"; - return type; + else { + type += get_real_structure_name(str); + } + } else { + yhao_print(debug, ret->print, str) type += str; + } + type += " ("; + for (auto i = 0; i < ft->getNumParams(); i++) { + if (i != 0) { + type += ", "; + } + auto temp = ft->getParamType(i); + if (temp->isPointerTy() && temp->getNumContainedTypes() && + temp->getNonOpaquePointerElementType()->isStructTy()) { + yhao_print(debug, temp->print, str) str = str.substr(0, str.size() - 1); + if (str.find("struct") == std::string::npos) { + type += str; + } else { + type += (get_real_structure_name(str) + "*"); + } + } else if (temp->isStructTy()) { + yhao_print(debug, temp->print, + str) if (str.find("struct") == std::string::npos) { + type += str; + } + else { + type += get_real_structure_name(str); + } + } else { + yhao_print(debug, temp->print, str) type += str; + } + } + type += ")"; + return type; } std::string get_real_structure_name(const std::string &name) { - std::string ret; - uint64_t index_1 = name.find('.'); - if (index_1 != std::string::npos) { - uint64_t index_2 = name.find('.', index_1 + 1); - if (index_2 != std::string::npos) { - ret = name.substr(0, index_2); - } else { - ret = name; - } + std::string ret; + uint64_t index_1 = name.find('.'); + if (index_1 != std::string::npos) { + uint64_t index_2 = name.find('.', index_1 + 1); + if (index_2 != std::string::npos) { + ret = name.substr(0, index_2); } else { - ret = name; - yhao_log(3, "get_structure_name: " + name); + ret = name; } - return ret; + } else { + ret = name; + yhao_log(3, "get_structure_name: " + name); + } + return ret; } llvm::Type *get_real_type(llvm::Type *t) { - if (t == nullptr) { - return nullptr; - } - if (t->isPointerTy() && t->getNumContainedTypes()) { - return get_real_type(t->getNonOpaquePointerElementType()); - } else if (t->isArrayTy()) { - return get_real_type(t->getArrayElementType()); - } else if (t->isVectorTy()) { - return get_real_type(t->getScalarType()); - } - return t; + if (t == nullptr) { + return nullptr; + } + if (t->isPointerTy() && t->getNumContainedTypes()) { + return get_real_type(t->getNonOpaquePointerElementType()); + } else if (t->isArrayTy()) { + return get_real_type(t->getArrayElementType()); + } else if (t->isVectorTy()) { + return get_real_type(t->getScalarType()); + } + return t; } std::string dump_inst(llvm::Instruction *inst) { - std::string ret; - if (inst == nullptr) { - return ret; - } + std::string ret; + if (inst == nullptr) { + return ret; + } - auto b = inst->getParent(); - auto f = b->getParent(); - if (inst->hasMetadata()) { - const llvm::DebugLoc &debugInfo = inst->getDebugLoc(); - if (debugInfo) { - std::string path = debugInfo->getFilename().str(); - ret += "path: " + path; - unsigned int line = debugInfo->getLine(); - unsigned int column = debugInfo->getColumn(); - ret += "; line: " + std::to_string(line); - ret += "; column: " + std::to_string(column); - } - } else { - std::string path = get_file_name(f); - ret += "path: " + path; + auto b = inst->getParent(); + auto f = b->getParent(); + if (inst->hasMetadata()) { + const llvm::DebugLoc &debugInfo = inst->getDebugLoc(); + if (debugInfo) { + std::string path = debugInfo->getFilename().str(); + ret += "path: " + path; + unsigned int line = debugInfo->getLine(); + unsigned int column = debugInfo->getColumn(); + ret += "; line: " + std::to_string(line); + ret += "; column: " + std::to_string(column); } - ret += "; function: " + get_real_function_name(f); - return ret; + } else { + std::string path = get_file_name(f); + ret += "path: " + path; + } + ret += "; function: " + get_real_function_name(f); + return ret; } std::string dump_inst_booltin(llvm::Instruction *inst, std::string version) { - std::string ret; + std::string ret; - if (inst != nullptr) { -// inst->dump(); - } else { - return ret; - } - auto b = inst->getParent(); - auto f = b->getParent(); + if (inst != nullptr) { + // inst->dump(); + } else { + return ret; + } + auto b = inst->getParent(); + auto f = b->getParent(); - unsigned int line = 1; - std::string Path = get_file_name(f); - if (inst->hasMetadata()) { - const llvm::DebugLoc &debugInfo = inst->getDebugLoc(); - if (debugInfo) { - Path = debugInfo->getFilename().str(); - line = debugInfo->getLine(); - } + unsigned int line = 1; + std::string Path = get_file_name(f); + if (inst->hasMetadata()) { + const llvm::DebugLoc &debugInfo = inst->getDebugLoc(); + if (debugInfo) { + Path = debugInfo->getFilename().str(); + line = debugInfo->getLine(); } + } - if (version.empty()) { - ret = ""; - } else { - ret += "https://elixir.bootlin.com/linux/"; - ret += version; - ret += "/source/"; - } - ret += Path + "#L" + std::to_string(line); - return ret; + if (version.empty()) { + ret = ""; + } else { + ret += "https://elixir.bootlin.com/linux/"; + ret += version; + ret += "/source/"; + } + ret += Path + "#L" + std::to_string(line); + return ret; } std::string dump_function_booltin(llvm::Function *func, std::string version) { - std::string ret; + std::string ret; - if (func != nullptr) { -// inst->dump(); - } else { - return ret; - } - - unsigned int line = 1; - std::string path; - - if (func->hasMetadata()) { - llvm::SmallVector, 4> MDs; - func->getAllMetadata(MDs); - for (auto &MD: MDs) { - llvm::MDNode *N = MD.second; - if (N == nullptr) { - continue; - } - auto *sp = llvm::dyn_cast(N); - if (sp == nullptr) { - continue; - } - line = sp->getLine(); - path = sp->getFilename().str(); - break; - } - } + if (func != nullptr) { + // inst->dump(); + } else { + return ret; + } + unsigned int line = 1; + std::string path; - - if (version.empty()) { - ret = ""; - } else { - ret += "https://elixir.bootlin.com/linux/"; - ret += version; - ret += "/source/"; + if (func->hasMetadata()) { + llvm::SmallVector, 4> MDs; + func->getAllMetadata(MDs); + for (auto &MD : MDs) { + llvm::MDNode *N = MD.second; + if (N == nullptr) { + continue; + } + auto *sp = llvm::dyn_cast(N); + if (sp == nullptr) { + continue; + } + line = sp->getLine(); + path = sp->getFilename().str(); + break; } - ret += path + "#L" + std::to_string(line); - return ret; + } + + if (version.empty()) { + ret = ""; + } else { + ret += "https://elixir.bootlin.com/linux/"; + ret += version; + ret += "/source/"; + } + ret += path + "#L" + std::to_string(line); + return ret; } std::string real_inst_str(std::string str) { - auto index = str.find_last_of('#'); - if (index == std::string::npos) { - return str; - } else { - return str.substr(0, index); - } + auto index = str.find_last_of('#'); + if (index == std::string::npos) { + return str; + } else { + return str.substr(0, index); + } } /// Compute the true target of a function call, resolving LLVM aliases /// and bitcasts. llvm::Function *get_target_function(llvm::Value *calledVal) { - llvm::SmallPtrSet Visited; + llvm::SmallPtrSet Visited; - auto *c = llvm::dyn_cast(calledVal); - if (!c) - return nullptr; + auto *c = llvm::dyn_cast(calledVal); + if (!c) return nullptr; - while (true) { - if (auto *gv = llvm::dyn_cast(c)) { - if (!Visited.insert(gv).second) - return nullptr; - - if (auto *f = llvm::dyn_cast(gv)) - return f; - else if (auto *ga = llvm::dyn_cast(gv)) - c = ga->getAliasee(); - else - return nullptr; - } else if (auto *ce = llvm::dyn_cast(c)) { - if (ce->getOpcode() == llvm::Instruction::BitCast) - c = ce->getOperand(0); - else - return nullptr; - } else - return nullptr; - } + while (true) { + if (auto *gv = llvm::dyn_cast(c)) { + if (!Visited.insert(gv).second) return nullptr; + + if (auto *f = llvm::dyn_cast(gv)) + return f; + else if (auto *ga = llvm::dyn_cast(gv)) + c = ga->getAliasee(); + else + return nullptr; + } else if (auto *ce = llvm::dyn_cast(c)) { + if (ce->getOpcode() == llvm::Instruction::BitCast) + c = ce->getOperand(0); + else + return nullptr; + } else + return nullptr; + } } std::string function_to_strID(llvm::Function *f) { - std::string ret; - if (f == nullptr) { - return ret; - } - std::string Path = get_file_name(f); - std::string NameFunction = f->getName().str(); - ret += Path; - ret += DELIMITER; - ret += NameFunction; + std::string ret; + if (f == nullptr) { return ret; + } + std::string Path = get_file_name(f); + std::string NameFunction = f->getName().str(); + ret += Path; + ret += DELIMITER; + ret += NameFunction; + return ret; } std::string basicblock_to_strID(llvm::BasicBlock *b) { - std::string ret; - if (b == nullptr) { - return ret; - } - auto f = b->getParent(); - ret += function_to_strID(f); - int64_t No; - No = 0; - for (auto &bb: *f) { - if (b == &bb) { - break; - } - No++; - } - int64_t NoBB = No; - ret += DELIMITER; - ret += std::to_string(NoBB); + std::string ret; + if (b == nullptr) { return ret; + } + auto f = b->getParent(); + ret += function_to_strID(f); + int64_t No; + No = 0; + for (auto &bb : *f) { + if (b == &bb) { + break; + } + No++; + } + int64_t NoBB = No; + ret += DELIMITER; + ret += std::to_string(NoBB); + return ret; } std::string inst_to_strID(llvm::Instruction *inst) { - std::string ret; - if (inst == nullptr) { - return ret; - } - auto b = inst->getParent(); - ret += basicblock_to_strID(b); - int64_t No; - No = 0; - for (auto &i: *b) { - if (inst == &i) { - break; - } - No++; - } - int64_t NoInst = No; - ret += DELIMITER; - ret += std::to_string(NoInst); + std::string ret; + if (inst == nullptr) { return ret; + } + auto b = inst->getParent(); + ret += basicblock_to_strID(b); + int64_t No; + No = 0; + for (auto &i : *b) { + if (inst == &i) { + break; + } + No++; + } + int64_t NoInst = No; + ret += DELIMITER; + ret += std::to_string(NoInst); + return ret; } llvm::Function *strID_to_function(llvm::Module *m, const std::string &str) { - uint64_t start; - start = str.find(DELIMITER); - if (start == str.size()) { - yhao_log(3, "no function: " + str); - return nullptr; - } - uint64_t end = str.find(DELIMITER, start + 1); - std::string NameFunction = str.substr(start + 1, end - start - 1); - llvm::Function *f = m->getFunction(NameFunction); - if (f == nullptr) { - yhao_log(3, "bad function name str: " + str); - yhao_log(3, "bad function name: " + NameFunction); - } - return f; + uint64_t start; + start = str.find(DELIMITER); + if (start == str.size()) { + yhao_log(3, "no function: " + str); + return nullptr; + } + uint64_t end = str.find(DELIMITER, start + 1); + std::string NameFunction = str.substr(start + 1, end - start - 1); + llvm::Function *f = m->getFunction(NameFunction); + if (f == nullptr) { + yhao_log(3, "bad function name str: " + str); + yhao_log(3, "bad function name: " + NameFunction); + } + return f; } llvm::BasicBlock *strID_to_basicblock(llvm::Module *m, const std::string &str) { - llvm::Function *f = strID_to_function(m, str); - if (f == nullptr) { - return nullptr; - } - uint64_t start; - start = str.find(DELIMITER); - start = str.find(DELIMITER, start + 1); - if (start == str.size()) { - yhao_log(3, "no basicblock: " + str); - return nullptr; - } - uint64_t end = str.find(DELIMITER, start + 1); - std::string NoBB = str.substr(start + 1, end - start - 1); - int64_t No = std::stoi(NoBB); - llvm::BasicBlock *b = nullptr; - for (auto &bb: *f) { - if (No == 0) { - b = &bb; - break; - } - No--; + llvm::Function *f = strID_to_function(m, str); + if (f == nullptr) { + return nullptr; + } + uint64_t start; + start = str.find(DELIMITER); + start = str.find(DELIMITER, start + 1); + if (start == str.size()) { + yhao_log(3, "no basicblock: " + str); + return nullptr; + } + uint64_t end = str.find(DELIMITER, start + 1); + std::string NoBB = str.substr(start + 1, end - start - 1); + int64_t No = std::stoi(NoBB); + llvm::BasicBlock *b = nullptr; + for (auto &bb : *f) { + if (No == 0) { + b = &bb; + break; } - return b; + No--; + } + return b; } llvm::Instruction *strID_to_inst(llvm::Module *m, const std::string &str) { - llvm::BasicBlock *b = strID_to_basicblock(m, str); - if (b == nullptr) { - return nullptr; - } - uint64_t start; - start = str.find(DELIMITER); - start = str.find(DELIMITER, start + 1); - start = str.find(DELIMITER, start + 1); - if (start == str.size()) { - yhao_log(3, "no inst: " + str); - return nullptr; - } - uint64_t end = str.find(DELIMITER, start + 1); - std::string NoInst = str.substr(start + 1, end - start - 1); - int64_t No = std::stoi(NoInst); - llvm::Instruction *i; - for (auto &ii: *b) { - if (No == 0) { - i = ⅈ - break; - } - No--; + llvm::BasicBlock *b = strID_to_basicblock(m, str); + if (b == nullptr) { + return nullptr; + } + uint64_t start; + start = str.find(DELIMITER); + start = str.find(DELIMITER, start + 1); + start = str.find(DELIMITER, start + 1); + if (start == str.size()) { + yhao_log(3, "no inst: " + str); + return nullptr; + } + uint64_t end = str.find(DELIMITER, start + 1); + std::string NoInst = str.substr(start + 1, end - start - 1); + int64_t No = std::stoi(NoInst); + llvm::Instruction *i; + for (auto &ii : *b) { + if (No == 0) { + i = ⅈ + break; } - return i; + No--; + } + return i; } uint64_t get_loc(llvm::Function *func) { @@ -417,7 +414,6 @@ uint64_t get_loc(llvm::Function *func) { std::string file; if (func != nullptr) { - } else { return line; } @@ -455,4 +451,4 @@ uint64_t get_loc(llvm::Function *func) { } line = end - start; return line > 0 ? line : 0; -} \ No newline at end of file +} diff --git a/lib/ToolLib/llvm_related.h b/lib/ToolLib/llvm_related.h index 4e1bb59..6fa9f39 100644 --- a/lib/ToolLib/llvm_related.h +++ b/lib/ToolLib/llvm_related.h @@ -5,10 +5,10 @@ #ifndef INC_LLVM_RELATED_H #define INC_LLVM_RELATED_H +#include + #include "basic.h" #include "log.h" -#include "llvm/IR/Function.h" -#include llvm::BasicBlock *get_real_basic_block(llvm::BasicBlock *b); @@ -20,15 +20,17 @@ std::string get_real_function_name(llvm::Function *f); std::string get_real_function_type(llvm::FunctionType *f); -std::string get_real_structure_name(const std::string& name); +std::string get_real_structure_name(const std::string &name); llvm::Type *get_real_type(llvm::Type *t); std::string dump_inst(llvm::Instruction *inst); -std::string dump_inst_booltin(llvm::Instruction *inst, std::string version = "v5.12"); +std::string dump_inst_booltin(llvm::Instruction *inst, + std::string version = "v5.12"); -std::string dump_function_booltin(llvm::Function *func, std::string version = "v5.12"); +std::string dump_function_booltin(llvm::Function *func, + std::string version = "v5.12"); std::string real_inst_str(std::string str); @@ -36,22 +38,22 @@ std::string real_inst_str(std::string str); /// and bitcasts. llvm::Function *get_target_function(llvm::Value *calledVal); -#define yhao_llvm_print(type, empty, out, print, str) \ - if ((type) >= DEBUG_LEVEL) { \ - if ((empty) == 1) { \ - (str) = ""; \ - } \ - llvm::raw_string_ostream dump(str); \ - print(dump); \ - if ((out) == 1) { \ - yhao_log(type, str); \ - } \ - } - -#define yhao_add(type, print, str) yhao_llvm_print(type, 0, 0, print, str) -#define yhao_print(type, print, str) yhao_llvm_print(type, 1, 0, print, str) -#define yhao_dump(type, print, str) yhao_llvm_print(type, 1, 1, print, str) -#define yhao_add_dump(type, print, str) yhao_llvm_print(type, 0, 1, print, str) +#define yhao_llvm_print(type, empty, out, print, str) \ + if ((type) >= DEBUG_LEVEL) { \ + if ((empty) == 1) { \ + (str) = ""; \ + } \ + llvm::raw_string_ostream dump(str); \ + print(dump); \ + if ((out) == 1) { \ + yhao_log(type, str); \ + } \ + } + +#define yhao_add(type, print, str) yhao_llvm_print(type, 0, 0, print, str) +#define yhao_print(type, print, str) yhao_llvm_print(type, 1, 0, print, str) +#define yhao_dump(type, print, str) yhao_llvm_print(type, 1, 1, print, str) +#define yhao_add_dump(type, print, str) yhao_llvm_print(type, 0, 1, print, str) // strID: Path-NameFunction-NoBB-NoInst std::string function_to_strID(llvm::Function *f); @@ -68,4 +70,4 @@ llvm::Instruction *strID_to_inst(llvm::Module *m, const std::string &str); uint64_t get_loc(llvm::Function *func); -#endif //INC_LLVM_RELATED_H +#endif // INC_LLVM_RELATED_H diff --git a/lib/ToolLib/log.h b/lib/ToolLib/log.h index de15e8d..032d6da 100644 --- a/lib/ToolLib/log.h +++ b/lib/ToolLib/log.h @@ -11,105 +11,104 @@ static std::string file_debug = "debug.log"; [[maybe_unused]] static std::string file_log = "log.log"; static std::string get_time() { - time_t current_time; - current_time = time(nullptr); - std::string time = ctime(¤t_time); - time = time.substr(0, time.size() - 1); - return time; + time_t current_time; + current_time = time(nullptr); + std::string time = ctime(¤t_time); + time = time.substr(0, time.size() - 1); + return time; } static std::string print_stack_trace() { - std::string str; - llvm::raw_string_ostream dump(str); - llvm::sys::PrintStackTrace(dump); - return str; + std::string str; + llvm::raw_string_ostream dump(str); + llvm::sys::PrintStackTrace(dump); + return str; } // number: 0(debug), 1(info), 2(warning), 3(error) static void yhao_log(int64_t type, const std::string &message) { - if (type < DEBUG_LEVEL) { - return; - } - switch (type) { - case -1: { + if (type < DEBUG_LEVEL) { + return; + } + switch (type) { + case -1: { #if ERR - std::cerr << "low debug: " << get_time() << ": " << message << std::endl; + std::cerr << "low debug: " << get_time() << ": " << message << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << "low debug: " << get_time() << ": " << message << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << "low debug: " << get_time() << ": " << message << std::endl; + log.close(); #endif - break; - } - case 0: { + break; + } + case 0: { #if ERR - std::cerr << "debug: " << get_time() << ": " << message << std::endl; + std::cerr << "debug: " << get_time() << ": " << message << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << "debug: " << get_time() << ": " << message << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << "debug: " << get_time() << ": " << message << std::endl; + log.close(); #endif - break; - } - case 1: { + break; + } + case 1: { #if ERR - std::cerr << "info: " << get_time() << " : " << message << std::endl; + std::cerr << "info: " << get_time() << " : " << message << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << "info: " << get_time() << " : " << message << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << "info: " << get_time() << " : " << message << std::endl; + log.close(); #endif - break; - } - case 2: { + break; + } + case 2: { #if ERR - std::cerr << "warning: " << get_time() << " : " << message << std::endl; + std::cerr << "warning: " << get_time() << " : " << message << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << "warning: " << get_time() << " : " << message << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << "warning: " << get_time() << " : " << message << std::endl; + log.close(); #endif - break; - } - case 3: { + break; + } + case 3: { #if ERR - std::cerr << "error: " << get_time() << " : " << message << std::endl; - std::cerr << print_stack_trace() << std::endl; + std::cerr << "error: " << get_time() << " : " << message << std::endl; + std::cerr << print_stack_trace() << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << "error: " << get_time() << " : " << message << std::endl; - log << print_stack_trace() << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << "error: " << get_time() << " : " << message << std::endl; + log << print_stack_trace() << std::endl; + log.close(); #endif - break; - } - default: { + break; + } + default: { #if ERR - std::cerr << get_time() << ": " << message << std::endl; + std::cerr << get_time() << ": " << message << std::endl; #else - std::ofstream log(file_debug, std::ios_base::app); - log << get_time() << ": " << message << std::endl; - log.close(); + std::ofstream log(file_debug, std::ios_base::app); + log << get_time() << ": " << message << std::endl; + log.close(); #endif - } } + } } static void yhao_start_log() { #if ERR - std::cerr << "info: " << get_time() << std::endl; + std::cerr << "info: " << get_time() << std::endl; #else - std::ofstream log(file_debug); - log << "info: " << get_time() << std::endl; - log.close(); + std::ofstream log(file_debug); + log << "info: " << get_time() << std::endl; + log.close(); #endif } -[[maybe_unused]] -static void start_log(char **argv) { - llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - yhao_start_log(); +[[maybe_unused]] static void start_log(char **argv) { + llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); + yhao_start_log(); } -#endif //INC_2021_TEMPLATE_LOG_H +#endif // INC_2021_TEMPLATE_LOG_H diff --git a/tools/SyzDescribe/SyzDescribe.cpp b/tools/SyzDescribe/SyzDescribe.cpp index 3314131..83af9b6 100644 --- a/tools/SyzDescribe/SyzDescribe.cpp +++ b/tools/SyzDescribe/SyzDescribe.cpp @@ -2,22 +2,21 @@ // Created by yhao on 3/3/21. // +#include "../../lib/ManagerLib/Manager.h" #include "../../lib/ToolLib/basic.h" #include "../../lib/ToolLib/log.h" -#include "../../lib/ManagerLib/Manager.h" -llvm::cl::opt config_json("config_json", - llvm::cl::desc("The configuration json file."), - llvm::cl::value_desc("file name"), - llvm::cl::init("./config_json.json")); +llvm::cl::opt config( + "config", llvm::cl::desc("The configuration json file."), + llvm::cl::value_desc("file name"), llvm::cl::init("./config.json")); int main(int argc, char **argv) { - llvm::cl::ParseCommandLineOptions(argc, argv, ""); - start_log(argv); + llvm::cl::ParseCommandLineOptions(argc, argv, ""); + start_log(argv); - auto manager = new sd::Manager(); - manager->setup(config_json); - manager->analysis(); + auto manager = new sd::Manager(); + manager->setup(config); + manager->analysis(); - return 0; -} \ No newline at end of file + return 0; +}