| 30 | unordered_map<void*, unordered_map<uint64_t, set<uint64_t>>> g_callSiteInlines; |
| 31 | |
| 32 | void FunctionInliner(Ref<AnalysisContext> analysisContext) |
| 33 | { |
| 34 | std::unique_lock<std::mutex> lock(g_mutex); |
| 35 | |
| 36 | Ref<Function> function = analysisContext->GetFunction(); |
| 37 | Ref<BinaryView> data = function->GetView(); |
| 38 | auto gItr = g_callSiteInlines.find(data->GetObject()); |
| 39 | if (gItr == g_callSiteInlines.end()) |
| 40 | return; |
| 41 | |
| 42 | auto itr = gItr->second.find(function->GetStart()); |
| 43 | if (itr == gItr->second.end()) |
| 44 | return; |
| 45 | |
| 46 | auto& callSiteInlines = itr->second; |
| 47 | lock.unlock(); |
| 48 | |
| 49 | bool updated = false; |
| 50 | uint8_t opcode[BN_MAX_INSTRUCTION_LENGTH]; |
| 51 | InstructionInfo iInfo; |
| 52 | Ref<LowLevelILFunction> llilFunc = analysisContext->GetLowLevelILFunction(); |
| 53 | for (const auto inlineAddr : callSiteInlines) |
| 54 | { |
| 55 | // if (m_owner->IsAborted()) |
| 56 | // return; |
| 57 | |
| 58 | for (auto& i : llilFunc->GetBasicBlocks()) |
| 59 | { |
| 60 | Ref<Architecture> arch = i->GetArchitecture(); |
| 61 | for (size_t instrIndex = i->GetStart(); instrIndex < i->GetEnd(); instrIndex++) |
| 62 | { |
| 63 | LowLevelILInstruction instr = llilFunc->GetInstruction(instrIndex); |
| 64 | |
| 65 | if (instr.address != inlineAddr) |
| 66 | continue; |
| 67 | |
| 68 | if (instr.operation != LLIL_CALL) |
| 69 | { |
| 70 | LogWarn( |
| 71 | "Failed to inline function at: 0x%" PRIx64 ". Mapping to LLIL_CALL Failed!", instr.address); |
| 72 | continue; |
| 73 | } |
| 74 | |
| 75 | uint64_t platformAddr; |
| 76 | LowLevelILInstruction destExpr = instr.GetDestExpr<LLIL_CALL>(); |
| 77 | RegisterValue target = destExpr.GetValue(); |
| 78 | if (target.IsConstant()) |
| 79 | platformAddr = target.value; |
| 80 | else |
| 81 | { |
| 82 | LogWarn( |
| 83 | "Failed to inline function at: 0x%" PRIx64 ". Destination not Constant!", instr.address); |
| 84 | continue; |
| 85 | } |
| 86 | |
| 87 | size_t opLen = data->Read(opcode, instr.address, arch->GetMaxInstructionLength()); |
| 88 | if (!opLen || !arch->GetInstructionInfo(opcode, instr.address, opLen, iInfo)) |
| 89 | continue; |
nothing calls this directly
no test coverage detected