| 496 | } |
| 497 | |
| 498 | virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override |
| 499 | { |
| 500 | Instruction instr, secondInstr; |
| 501 | if (!Disassemble(data, addr, len, instr)) |
| 502 | { |
| 503 | il.AddInstruction(il.Undefined()); |
| 504 | return false; |
| 505 | } |
| 506 | |
| 507 | if (InstructionHasBranchDelay(instr) == 1) |
| 508 | { |
| 509 | if (len < 8) |
| 510 | { |
| 511 | LogWarn("Can not lift instruction with delay slot @ 0x%08" PRIx64, addr); |
| 512 | return false; |
| 513 | } |
| 514 | |
| 515 | if (!Disassemble(data + instr.size, addr + instr.size, len - instr.size, secondInstr)) |
| 516 | { |
| 517 | il.AddInstruction(il.Undefined()); |
| 518 | return false; |
| 519 | } |
| 520 | |
| 521 | bool status = true; |
| 522 | bool isBranchLikely = InstructionIsBranchLikely(instr); |
| 523 | if (isBranchLikely) |
| 524 | { |
| 525 | InstructionInfo instrInfo; |
| 526 | LowLevelILLabel trueCode, falseCode; |
| 527 | SetInstructionInfoForInstruction(addr, instr, instrInfo); |
| 528 | il.AddInstruction(il.If(GetConditionForInstruction(il, instr, GetAddressSize()), trueCode, falseCode)); |
| 529 | il.MarkLabel(trueCode); |
| 530 | il.SetCurrentAddress(this, addr + instr.size); |
| 531 | GetLowLevelILForInstruction(this, addr + instr.size, il, secondInstr, GetAddressSize(), m_decomposeFlags); |
| 532 | for (size_t i = 0; i < instrInfo.branchCount; i++) |
| 533 | { |
| 534 | if (instrInfo.branchType[i] == TrueBranch) |
| 535 | { |
| 536 | BNLowLevelILLabel* trueLabel = il.GetLabelForAddress(this, instrInfo.branchTarget[i]); |
| 537 | if (trueLabel) |
| 538 | il.AddInstruction(il.Goto(*trueLabel)); |
| 539 | else |
| 540 | il.AddInstruction(il.Jump(il.ConstPointer(GetAddressSize(), instrInfo.branchTarget[i]))); |
| 541 | break; |
| 542 | } |
| 543 | } |
| 544 | il.MarkLabel(falseCode); |
| 545 | } |
| 546 | else |
| 547 | { |
| 548 | size_t nop; |
| 549 | |
| 550 | // ensure we have space to preserve one register in case the delay slot |
| 551 | // clobbers a value needed by the branch. this will be eliminated when |
| 552 | // normal LLIL is generated from Lifted IL if we don't need it |
| 553 | il.SetCurrentAddress(this, addr + instr.size); |
| 554 | nop = il.Nop(); |
| 555 | il.AddInstruction(nop); |
nothing calls this directly
no test coverage detected