@@ -666,6 +666,108 @@ const std::map<ArchAndAddr, std::map<BNBranchType, BranchOverride>>& FunctionLif
666666}
667667
668668
669+ PreparedLiftedBranchOverride::PreparedLiftedBranchOverride (BNPreparedLiftedBranchOverride* object) : m_object(object)
670+ {}
671+
672+
673+ PreparedLiftedBranchOverride::~PreparedLiftedBranchOverride ()
674+ {
675+ BNFreePreparedLiftedBranchOverride (m_object);
676+ }
677+
678+
679+ bool PreparedLiftedBranchOverride::SuppressesInstruction () const
680+ {
681+ return BNPreparedLiftedBranchOverrideSuppressesInstruction (m_object);
682+ }
683+
684+
685+ Ref<LowLevelILFunction> PreparedLiftedBranchOverride::GetSource ()
686+ {
687+ if (!m_source)
688+ m_source = new LowLevelILFunction (BNGetPreparedLiftedBranchOverrideSource (m_object));
689+ return m_source;
690+ }
691+
692+
693+ bool PreparedLiftedBranchOverride::Apply (uint64_t continuationAddress)
694+ {
695+ return BNApplyPreparedLiftedBranchOverride (m_object, continuationAddress);
696+ }
697+
698+
699+ struct FunctionLifterContext ::LiftedBranchOverrideInputs
700+ {
701+ vector<BNOverridableBranchInfo> branches;
702+ vector<BNBranchOverride> overrides;
703+ vector<BNArchitectureAndAddress> indirectTargets;
704+ BNLiftedBranchOverrideInfo info{};
705+ };
706+
707+
708+ FunctionLifterContext::LiftedBranchOverrideInputs FunctionLifterContext::GetLiftedBranchOverrideInputs (
709+ const ArchAndAddr& location, const vector<OverridableBranchInfo>& branches) const
710+ {
711+ LiftedBranchOverrideInputs result;
712+ auto & rawBranches = result.branches ;
713+ auto & rawOverrides = result.overrides ;
714+ auto & indirectTargets = result.indirectTargets ;
715+ auto it = m_branchOverrides.find (location);
716+ if (!location.arch || (it == m_branchOverrides.end ()))
717+ return result;
718+
719+ rawBranches.reserve (branches.size ());
720+ for (const auto & branch : branches)
721+ rawBranches.push_back ({branch.type , branch.target , branch.arch ? branch.arch ->GetObject () : nullptr });
722+
723+ rawOverrides.reserve (it->second .size ());
724+ for (const auto & [originalType, value] : it->second )
725+ {
726+ rawOverrides.push_back ({location.arch ->GetObject (), location.address , originalType, value.type ,
727+ value.target .has_value (), value.targetArch ? value.targetArch ->GetObject () : nullptr ,
728+ value.target .value_or (0 )});
729+ }
730+
731+ const set<ArchAndAddr>* targets = nullptr ;
732+ if (auto user = m_userIndirectBranches.find (location); user != m_userIndirectBranches.end ())
733+ targets = &user->second ;
734+ else if (auto automatic = m_autoIndirectBranches.find (location); automatic != m_autoIndirectBranches.end ())
735+ targets = &automatic->second ;
736+ if (targets)
737+ {
738+ indirectTargets.reserve (targets->size ());
739+ for (const auto & target : *targets)
740+ indirectTargets.push_back ({target.arch ->GetObject (), target.address });
741+ }
742+
743+ result.info = {location.arch ->GetObject (), location.address , 0 ,
744+ rawBranches.data (), rawBranches.size (), rawOverrides.data (), rawOverrides.size (),
745+ m_noReturnCalls.count (location) != 0 , indirectTargets.data (), indirectTargets.size ()};
746+ return result;
747+ }
748+
749+
750+ unique_ptr<PreparedLiftedBranchOverride> FunctionLifterContext::PrepareLiftedBranchOverrides (
751+ LowLevelILFunction& dest, BasicBlock* block, const ArchAndAddr& location,
752+ const vector<OverridableBranchInfo>& branches) const
753+ {
754+ auto inputs = GetLiftedBranchOverrideInputs (location, branches);
755+ if (!inputs.info .arch )
756+ return nullptr ;
757+ auto result = BNPrepareLiftedBranchOverrides (dest.GetObject (), block ? block->GetObject () : nullptr , &inputs.info );
758+ return result ? make_unique<PreparedLiftedBranchOverride>(result) : nullptr ;
759+ }
760+
761+
762+ bool FunctionLifterContext::ApplyLiftedBranchOverrides (LowLevelILFunction& dest, LowLevelILFunction& source,
763+ const ArchAndAddr& location, uint64_t continuationAddress, const vector<OverridableBranchInfo>& branches) const
764+ {
765+ auto inputs = GetLiftedBranchOverrideInputs (location, branches);
766+ inputs.info .continuationAddress = continuationAddress;
767+ return inputs.info .arch && BNApplyLiftedBranchOverrides (dest.GetObject (), source.GetObject (), &inputs.info );
768+ }
769+
770+
669771Ref<Logger>& FunctionLifterContext::GetLogger ()
670772{
671773 return m_logger;
0 commit comments