@@ -204,6 +204,235 @@ vector<InstructionTextToken> InstructionTextToken::ConvertInstructionTextTokenLi
204204 return result;
205205}
206206
207+ BasicBlockAnalysisContext::BasicBlockAnalysisContext (BNBasicBlockAnalysisContext* context)
208+ {
209+ m_context = context;
210+ }
211+
212+ const std::map<ArchAndAddr, std::set<ArchAndAddr>> BasicBlockAnalysisContext::GetIndirectBranches ()
213+ {
214+ if (!m_indirectBranches)
215+ {
216+ auto & indirectBranches = m_indirectBranches.emplace ();
217+
218+ for (size_t i = 0 ; i < m_context->indirectBranchesCount ; i++)
219+ {
220+ ArchAndAddr src (new CoreArchitecture (m_context->indirectBranches [i].sourceArch ), m_context->indirectBranches [i].sourceAddr );
221+ ArchAndAddr dst (new CoreArchitecture (m_context->indirectBranches [i].destArch ), m_context->indirectBranches [i].destAddr );
222+
223+ indirectBranches[src].insert (dst);
224+ }
225+ }
226+
227+ return *m_indirectBranches;
228+ }
229+
230+
231+ const std::set<ArchAndAddr>& BasicBlockAnalysisContext::GetIndirectNoReturnCalls ()
232+ {
233+ if (!m_indirectNoReturnCalls)
234+ {
235+ auto & indirectNoReturnCalls = m_indirectNoReturnCalls.emplace ();
236+
237+ for (size_t i = 0 ; i < m_context->indirectNoReturnCallsCount ; i++)
238+ {
239+ ArchAndAddr addr (new CoreArchitecture (m_context->indirectNoReturnCalls [i].arch ), m_context->indirectNoReturnCalls [i].address );
240+ indirectNoReturnCalls.insert (addr);
241+ }
242+ }
243+
244+ return *m_indirectNoReturnCalls;
245+ }
246+
247+
248+ std::map<ArchAndAddr, bool >& BasicBlockAnalysisContext::GetContextualReturns ()
249+ {
250+ if (!m_contextualReturns)
251+ {
252+ auto & contextualReturns = m_contextualReturns.emplace ();
253+
254+ for (size_t i = 0 ; i < m_context->contextualFunctionReturnCount ; i++)
255+ {
256+ ArchAndAddr addr (new CoreArchitecture (m_context->contextualFunctionReturnLocations [i].arch ), m_context->contextualFunctionReturnLocations [i].address );
257+ contextualReturns[addr] = m_context->contextualFunctionReturnValues [i];
258+ }
259+ }
260+
261+ return *m_contextualReturns;
262+ }
263+
264+
265+ std::map<uint64_t , std::set<ArchAndAddr>>& BasicBlockAnalysisContext::GetDirectCodeReferences ()
266+ {
267+ if (!m_directCodeReferences)
268+ {
269+ auto & directCodeReferences = m_directCodeReferences.emplace ();
270+
271+ for (size_t i = 0 ; i < m_context->directRefCount ; i++)
272+ {
273+ ArchAndAddr src (new CoreArchitecture (m_context->directRefSources [i].arch ), m_context->directRefSources [i].address );
274+
275+ directCodeReferences[m_context->directRefTargets [i]].insert (src);
276+ }
277+ }
278+
279+ return *m_directCodeReferences;
280+ }
281+
282+
283+ std::set<ArchAndAddr>& BasicBlockAnalysisContext::GetDirectNoReturnCalls ()
284+ {
285+ if (!m_directNoReturnCalls)
286+ m_directNoReturnCalls.emplace ();
287+
288+ return *m_directNoReturnCalls;
289+ }
290+
291+
292+ std::set<ArchAndAddr>& BasicBlockAnalysisContext::GetHaltedDisassemblyAddresses ()
293+ {
294+ if (!m_haltedDisassemblyAddresses)
295+ m_haltedDisassemblyAddresses.emplace ();
296+
297+ return *m_haltedDisassemblyAddresses;
298+ }
299+
300+
301+ void BasicBlockAnalysisContext::AddTempOutgoingReference (Function* targetFunc)
302+ {
303+ BNAnalyzeBasicBlocksContextAddTempReference (m_context, targetFunc->m_object );
304+ }
305+
306+
307+ Ref<BasicBlock> BasicBlockAnalysisContext::CreateBasicBlock (Architecture* arch, uint64_t start)
308+ {
309+ BNBasicBlock* block = BNAnalyzeBasicBlocksContextCreateBasicBlock (m_context, arch->GetObject (), start);
310+ if (!block)
311+ return nullptr ;
312+ return new BasicBlock (block);
313+ }
314+
315+
316+ void BasicBlockAnalysisContext::AddFunctionBasicBlock (BasicBlock* block)
317+ {
318+ BNAnalyzeBasicBlocksContextAddBasicBlockToFunction (m_context, block->GetObject ());
319+ }
320+
321+
322+ void BasicBlockAnalysisContext::Finalize ()
323+ {
324+ if (m_directCodeReferences)
325+ {
326+ auto & directRefs = *m_directCodeReferences;
327+
328+ size_t total = 0 ;
329+ for (auto & pair : directRefs)
330+ total += pair.second .size ();
331+
332+ BNArchitectureAndAddress* sources = new BNArchitectureAndAddress[total];
333+ uint64_t * targets = new uint64_t [total];
334+
335+ size_t i = 0 ;
336+ for (auto & pair : directRefs)
337+ {
338+ for (auto & src : pair.second )
339+ {
340+ sources[i].arch = src.arch ->GetObject ();
341+ sources[i].address = src.address ;
342+ targets[i] = pair.first ;
343+ i++;
344+ }
345+ }
346+
347+ BNAnalyzeBasicBlocksContextSetDirectCodeReferences (m_context, sources, targets, total);
348+
349+ delete[] sources;
350+ delete[] targets;
351+ }
352+
353+ if (m_directNoReturnCalls)
354+ {
355+ auto & directNoReturnCalls = *m_directNoReturnCalls;
356+
357+ BNArchitectureAndAddress* noRets = new BNArchitectureAndAddress[directNoReturnCalls.size ()];
358+
359+ size_t i = 0 ;
360+ for (auto & addr : directNoReturnCalls)
361+ {
362+ noRets[i].arch = addr.arch ->GetObject ();
363+ noRets[i].address = addr.address ;
364+ i++;
365+ }
366+
367+ BNAnalyzeBasicBlocksContextSetDirectNoReturnCalls (m_context, noRets, directNoReturnCalls.size ());
368+ delete[] noRets;
369+ }
370+
371+ if (m_haltedDisassemblyAddresses)
372+ {
373+ auto & haltedDisassemblyAddresses = *m_haltedDisassemblyAddresses;
374+
375+ BNArchitectureAndAddress* haltedAddresses = new BNArchitectureAndAddress[haltedDisassemblyAddresses.size ()];
376+
377+ size_t i = 0 ;
378+ for (auto & addr : haltedDisassemblyAddresses)
379+ {
380+ haltedAddresses[i].arch = addr.arch ->GetObject ();
381+ haltedAddresses[i].address = addr.address ;
382+ i++;
383+ }
384+
385+ BNAnalyzeBasicBlocksContextSetHaltedDisassemblyAddresses (m_context, haltedAddresses, haltedDisassemblyAddresses.size ());
386+ delete[] haltedAddresses;
387+ }
388+
389+ if (m_contextualReturns)
390+ {
391+ auto & contextualReturns = *m_contextualReturns;
392+
393+ bool dirty = contextualReturns.size () != m_context->contextualFunctionReturnCount ;
394+
395+ if (!dirty)
396+ {
397+ size_t i = 0 ;
398+ for (auto & pair : contextualReturns)
399+ {
400+ if (pair.first .arch ->GetObject () != m_context->contextualFunctionReturnLocations [i].arch
401+ || pair.first .address != m_context->contextualFunctionReturnLocations [i].address
402+ || pair.second != m_context->contextualFunctionReturnValues [i])
403+ {
404+ dirty = true ;
405+ break ;
406+ }
407+
408+ i++;
409+ }
410+ }
411+
412+ if (dirty)
413+ {
414+ BNArchitectureAndAddress* returns = new BNArchitectureAndAddress[contextualReturns.size ()];
415+ bool * values = new bool [contextualReturns.size ()];
416+
417+ size_t i = 0 ;
418+ for (auto & pair : contextualReturns)
419+ {
420+ returns[i].arch = pair.first .arch ->GetObject ();
421+ returns[i].address = pair.first .address ;
422+ values[i] = pair.second ;
423+ i++;
424+ }
425+
426+ BNAnalyzeBasicBlocksContextSetContextualFunctionReturns (m_context, returns, values, contextualReturns.size ());
427+
428+ delete[] returns;
429+ delete[] values;
430+ }
431+ }
432+
433+ BNAnalyzeBasicBlocksContextFinalize (m_context);
434+ }
435+
207436
208437Architecture::Architecture (BNArchitecture* arch)
209438{
@@ -332,8 +561,10 @@ void Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
332561 BNBasicBlockAnalysisContext* context)
333562{
334563 CallbackRef<Architecture> arch (ctxt);
564+ BasicBlockAnalysisContext abbc (context);
335565 Ref<Function> func (new Function (BNNewFunctionReference (function)));
336- arch->AnalyzeBasicBlocks (*func, *context);
566+
567+ arch->AnalyzeBasicBlocks (func, abbc);
337568}
338569
339570
@@ -956,7 +1187,7 @@ bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, L
9561187}
9571188
9581189
959- void Architecture::AnalyzeBasicBlocks (Function& function, BasicBlockAnalysisContext& context)
1190+ void Architecture::AnalyzeBasicBlocks (Function* function, BasicBlockAnalysisContext& context)
9601191{
9611192 DefaultAnalyzeBasicBlocks (function, context);
9621193}
@@ -1522,9 +1753,9 @@ bool CoreArchitecture::GetInstructionLowLevelIL(const uint8_t* data, uint64_t ad
15221753}
15231754
15241755
1525- void CoreArchitecture::AnalyzeBasicBlocks (Function& function, BasicBlockAnalysisContext& context)
1756+ void CoreArchitecture::AnalyzeBasicBlocks (Function* function, BasicBlockAnalysisContext& context)
15261757{
1527- BNArchitectureAnalyzeBasicBlocks (m_object, function. GetObject (), & context);
1758+ BNArchitectureAnalyzeBasicBlocks (m_object, function-> GetObject (), context. m_context );
15281759}
15291760
15301761
0 commit comments