diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index 34a86d413..8bbbca1af 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -416,6 +416,25 @@ map BinaryNinja::GetMemoryUsageInfo() } +map BinaryNinja::GetStatHistograms() +{ + size_t count; + BNStatHistogram* info = BNGetStatHistograms(&count); + + map result; + for (size_t i = 0; i < count; i++) + { + StatHistogram h; + h.total = info[i].total; + for (size_t k = 0; k < 65; k++) + h.buckets[k] = info[i].buckets[k]; + result[info[i].name] = h; + } + BNFreeStatHistograms(info, count); + return result; +} + + bool BinaryNinja::DefaultProgressFunction(size_t, size_t) { return true; diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 9d18c3838..64c85c147 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -2820,6 +2821,16 @@ namespace BinaryNinja { std::map GetMemoryUsageInfo(); + // Per-tag bit-length histograms from the StatCollector sampling facility. + // buckets[k] counts samples whose value has bit_width == k (k in 0..64); total is + // the sum of sampled values. Empty unless a StatCollector was instantiated somewhere. + struct StatHistogram + { + uint64_t total = 0; + std::array buckets {}; + }; + std::map GetStatHistograms(); + void SetThreadName(const std::string& name); /*! diff --git a/binaryninjacore.h b/binaryninjacore.h index 203a9ed88..d6d08fa0a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,7 +37,7 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 180 +#define BN_CURRENT_CORE_ABI_VERSION 181 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and @@ -3615,6 +3615,16 @@ extern "C" double seconds; } BNPerformanceInfo; + // Per-tag bit-length histogram produced by the StatCollector sampling facility. + // Bucket k counts samples whose value has bit width k, for k in 0..64; total is the + // sum of the sampled values (the sample count is recoverable as the sum of buckets). + typedef struct BNStatHistogram + { + char* name; + uint64_t total; + uint64_t buckets[65]; + } BNStatHistogram; + typedef struct BNMemoryUsageInfo { char* name; @@ -8690,6 +8700,9 @@ extern "C" BINARYNINJACOREAPI BNMemoryUsageInfo* BNGetMemoryUsageInfo(size_t* count); BINARYNINJACOREAPI void BNFreeMemoryUsageInfo(BNMemoryUsageInfo* info, size_t count); + BINARYNINJACOREAPI BNStatHistogram* BNGetStatHistograms(size_t* count); + BINARYNINJACOREAPI void BNFreeStatHistograms(BNStatHistogram* stats, size_t count); + BINARYNINJACOREAPI uint32_t BNGetAddressRenderedWidth(uint64_t addr); BINARYNINJACOREAPI BNDebugInfoParser* BNRegisterDebugInfoParser(const char* name, diff --git a/python/__init__.py b/python/__init__.py index 0f6a76911..fac92e06d 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -412,6 +412,30 @@ def get_memory_usage_info() -> Mapping[str, int]: return result +def get_stat_histograms() -> Mapping[str, dict]: + """ + Get per-tag bit-length histograms gathered by StatCollector instrumentation. + + Each entry maps a tag name to ``{"total": int, "buckets": [int; 65]}`` where + ``buckets[k]`` counts samples whose value has ``bit_width == k`` (k in 0..64) and + ``total`` is the sum of the sampled values. Empty unless a ``StatCollector`` was + instantiated somewhere in the core during analysis. + + :return: Dictionary of {tag name: {"total": int, "buckets": list[int]}} + """ + count = ctypes.c_ulonglong() + info = core.BNGetStatHistograms(count) + assert info is not None, "core.BNGetStatHistograms returned None" + result = {} + for i in range(0, count.value): + result[info[i].name] = { + "total": info[i].total, + "buckets": list(info[i].buckets), + } + core.BNFreeStatHistograms(info, count.value) + return result + + def load(*args, **kwargs) -> BinaryView: """ Opens a BinaryView object.