Skip to content

Commit 23f619a

Browse files
committed
Sort switch blocks in graph view by case number
1 parent 06611c1 commit 23f619a

7 files changed

Lines changed: 50 additions & 0 deletions

File tree

basicblock.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,12 @@ vector<vector<InstructionTextToken>> BasicBlock::GetAnnotations()
593593
}
594594

595595

596+
std::optional<int64_t> BasicBlock::GetSortHint()
597+
{
598+
return GetFunction()->GetBlockSortHint(GetArchitecture(), GetStart());
599+
}
600+
601+
596602
vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings* settings)
597603
{
598604
size_t count;

binaryninjaapi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12641,6 +12641,11 @@ namespace BinaryNinja {
1264112641
\return List of automatic annotations for the start of this block
1264212642
*/
1264312643
std::vector<std::vector<InstructionTextToken>> GetAnnotations();
12644+
/*! Hint for sorting this block in graph layouts
12645+
12646+
\return Integer for sorting this block, if defined
12647+
*/
12648+
std::optional<int64_t> GetSortHint();
1264412649

1264512650
/*! property which returns a list of DisassemblyTextLine objects for the current basic block.
1264612651

@@ -13432,6 +13437,7 @@ namespace BinaryNinja {
1343213437
bool IsCallInstruction(Architecture* arch, uint64_t addr);
1343313438

1343413439
std::vector<std::vector<InstructionTextToken>> GetBlockAnnotations(Architecture* arch, uint64_t addr);
13440+
std::optional<int64_t> GetBlockSortHint(Architecture* arch, uint64_t addr);
1343513441

1343613442
BNIntegerDisplayType GetIntegerConstantDisplayType(
1343713443
Architecture* arch, uint64_t instrAddr, uint64_t value, size_t operand);

binaryninjacore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5653,6 +5653,8 @@ extern "C"
56535653

56545654
BINARYNINJACOREAPI BNInstructionTextLine* BNGetFunctionBlockAnnotations(
56555655
BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count);
5656+
BINARYNINJACOREAPI bool BNGetFunctionBlockSortHint(
5657+
BNFunction* func, BNArchitecture* arch, uint64_t addr, int64_t* result);
56565658

56575659
BINARYNINJACOREAPI BNIntegerDisplayType BNGetIntegerConstantDisplayType(
56585660
BNFunction* func, BNArchitecture* arch, uint64_t instrAddr, uint64_t value, size_t operand);

function.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,18 @@ vector<vector<InstructionTextToken>> Function::GetBlockAnnotations(Architecture*
17981798
}
17991799

18001800

1801+
std::optional<int64_t> Function::GetBlockSortHint(Architecture* arch, uint64_t addr)
1802+
{
1803+
int64_t result;
1804+
if (!BNGetFunctionBlockSortHint(m_object, arch->GetObject(), addr, &result))
1805+
{
1806+
return std::nullopt;
1807+
}
1808+
1809+
return result;
1810+
}
1811+
1812+
18011813
BNIntegerDisplayType Function::GetIntegerConstantDisplayType(
18021814
Architecture* arch, uint64_t instrAddr, uint64_t value, size_t operand)
18031815
{

python/basicblock.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,14 @@ def annotations(self) -> List[List['_function.InstructionTextToken']]:
704704

705705
return self.function.get_block_annotations(self.start, self.arch)
706706

707+
@property
708+
def sort_hint(self) -> Optional[int]:
709+
"""Graph edge sorting hint for this block (read-only)"""
710+
if self.function is None:
711+
raise ValueError("Attempting to call BasicBlock.sort_hint when Function is None")
712+
713+
return self.function.get_block_sort_hint(self.start, self.arch)
714+
707715
@property
708716
def disassembly_text(self) -> List['_function.DisassemblyTextLine']:
709717
"""

python/function.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,6 +2437,14 @@ def get_block_annotations(self, addr: int,
24372437
finally:
24382438
core.BNFreeInstructionTextLines(lines, count.value)
24392439

2440+
def get_block_sort_hint(self, addr: int, arch: Optional['architecture.Architecture'] = None) -> Optional[int]:
2441+
if arch is None:
2442+
arch = self.arch
2443+
result = ctypes.c_int64()
2444+
if not core.BNGetFunctionBlockSortHint(self.handle, arch.handle, addr, ctypes.byref(result)):
2445+
return None
2446+
return result.value
2447+
24402448
def set_auto_type(self, value: StringOrType) -> None:
24412449
if isinstance(value, str):
24422450
(value, _) = self.view.parse_type_string(value)

rust/src/function.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,14 @@ impl Function {
510510
unsafe { Array::new(lines, count, ()) }
511511
}
512512

513+
pub fn block_sort_hint(&self, addr: u64, arch: Option<CoreArchitecture>) -> Option<i64> {
514+
let arch = arch.unwrap_or_else(|| self.arch());
515+
let mut result = 0;
516+
unsafe {
517+
BNGetFunctionBlockSortHint(self.handle, arch.handle, addr, &mut result).then_some(result)
518+
}
519+
}
520+
513521
pub fn variable_name(&self, var: &Variable) -> String {
514522
unsafe {
515523
let raw_var = BNVariable::from(var);

0 commit comments

Comments
 (0)