Skip to content

Commit 7064468

Browse files
committed
Add fmt formatters for IL instructions
1 parent 9879389 commit 7064468

6 files changed

+203
-0
lines changed

highlevelilinstruction.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,3 +3262,55 @@ ExprId HighLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId
32623262
{
32633263
return AddExprWithLocation(HLIL_FCMP_UO, loc, size, a, b);
32643264
}
3265+
3266+
3267+
fmt::format_context::iterator fmt::formatter<HighLevelILInstruction>::format(const HighLevelILInstruction& obj, format_context& ctx) const
3268+
{
3269+
if (!obj.function)
3270+
return fmt::format_to(ctx.out(), "<uninit>");
3271+
3272+
vector<InstructionTextToken> tokens;
3273+
Ref<DisassemblySettings> settings = new DisassemblySettings();
3274+
vector<DisassemblyTextLine> lines = obj.function->GetExprText(obj, settings);
3275+
if (!lines.empty())
3276+
{
3277+
if (presentation == '?')
3278+
{
3279+
fmt::format_to(ctx.out(), "{} ", obj.operation);
3280+
fmt::format_to(ctx.out(), "@ {:#x} ", obj.address);
3281+
if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0)
3282+
{
3283+
fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex);
3284+
}
3285+
if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0)
3286+
{
3287+
fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex);
3288+
}
3289+
Ref<Type> type = obj.GetType();
3290+
if (type)
3291+
{
3292+
fmt::format_to(ctx.out(), "[type: {}] ", type->GetString());
3293+
}
3294+
}
3295+
3296+
bool first = true;
3297+
for (auto& line: lines)
3298+
{
3299+
if (!first)
3300+
{
3301+
fmt::format_to(ctx.out(), " ; ");
3302+
}
3303+
first = false;
3304+
3305+
for (auto& token: line.tokens)
3306+
{
3307+
fmt::format_to(ctx.out(), "{}", token.text);
3308+
}
3309+
}
3310+
}
3311+
else
3312+
{
3313+
fmt::format_to(ctx.out(), "???");
3314+
}
3315+
return ctx.out();
3316+
}

highlevelilinstruction.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "binaryninjaapi.h"
3030
#endif
3131
#include "mediumlevelilinstruction.h"
32+
#include <fmt/core.h>
3233

3334
#ifdef BINARYNINJACORE_LIBRARY
3435
namespace BinaryNinjaCore
@@ -1419,3 +1420,24 @@ namespace BinaryNinja
14191420
#undef _STD_SET
14201421
#undef _STD_UNORDERED_MAP
14211422
} // namespace BinaryNinjaCore
1423+
1424+
#ifdef BINARYNINJACORE_LIBRARY
1425+
#define IL_INS_NS BinaryNinjaCore
1426+
#else
1427+
#define IL_INS_NS BinaryNinja
1428+
#endif
1429+
template<> struct fmt::formatter<IL_INS_NS::HighLevelILInstruction>
1430+
{
1431+
// <empty> -> normal, ? -> debug
1432+
char presentation = ' ';
1433+
format_context::iterator format(const IL_INS_NS::HighLevelILInstruction& obj, format_context& ctx) const;
1434+
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
1435+
{
1436+
auto it = ctx.begin(), end = ctx.end();
1437+
if (it != end && *it == '?')
1438+
presentation = *it++;
1439+
if (it != end && *it != '}') detail::throw_format_error("invalid format");
1440+
return it;
1441+
}
1442+
};
1443+
#undef IL_INS_NS

lowlevelilinstruction.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,3 +3690,44 @@ ExprId LowLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId b
36903690
{
36913691
return AddExprWithLocation(LLIL_FCMP_UO, loc, size, 0, a, b);
36923692
}
3693+
3694+
3695+
fmt::format_context::iterator fmt::formatter<LowLevelILInstruction>::format(const LowLevelILInstruction& obj, format_context& ctx) const
3696+
{
3697+
if (!obj.function)
3698+
return fmt::format_to(ctx.out(), "<uninit>");
3699+
3700+
vector<InstructionTextToken> tokens;
3701+
#ifdef BINARYNINJACORE_LIBRARY
3702+
bool success = obj.function->GetExprText(obj.function->GetFunction(), obj.function->GetArchitecture(), obj, tokens);
3703+
#else
3704+
bool success = obj.function->GetExprText(obj.function->GetArchitecture(), obj.exprIndex, tokens);
3705+
#endif
3706+
if (success)
3707+
{
3708+
string text;
3709+
if (presentation == '?')
3710+
{
3711+
fmt::format_to(ctx.out(), "{} ", obj.operation);
3712+
fmt::format_to(ctx.out(), "@ {:#x} ", obj.address);
3713+
if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0)
3714+
{
3715+
fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex);
3716+
}
3717+
if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0)
3718+
{
3719+
fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex);
3720+
}
3721+
}
3722+
3723+
for (auto& token: tokens)
3724+
{
3725+
fmt::format_to(ctx.out(), token.text);
3726+
}
3727+
}
3728+
else
3729+
{
3730+
fmt::format_to(ctx.out(), "???");
3731+
}
3732+
return ctx.out();
3733+
}

lowlevelilinstruction.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,3 +2010,24 @@ namespace BinaryNinja
20102010
#undef _STD_UNORDERED_MAP
20112011
#undef _STD_MAP
20122012
} // namespace BinaryNinjaCore
2013+
2014+
#ifdef BINARYNINJACORE_LIBRARY
2015+
#define IL_INS_NS BinaryNinjaCore
2016+
#else
2017+
#define IL_INS_NS BinaryNinja
2018+
#endif
2019+
template<> struct fmt::formatter<IL_INS_NS::LowLevelILInstruction>
2020+
{
2021+
// <empty> -> normal, ? -> debug
2022+
char presentation = ' ';
2023+
format_context::iterator format(const IL_INS_NS::LowLevelILInstruction& obj, format_context& ctx) const;
2024+
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
2025+
{
2026+
auto it = ctx.begin(), end = ctx.end();
2027+
if (it != end && *it == '?')
2028+
presentation = *it++;
2029+
if (it != end && *it != '}') detail::throw_format_error("invalid format");
2030+
return it;
2031+
}
2032+
};
2033+
#undef IL_INS_NS

mediumlevelilinstruction.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,3 +3125,49 @@ ExprId MediumLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprI
31253125
{
31263126
return AddExprWithLocation(MLIL_FCMP_UO, loc, size, a, b);
31273127
}
3128+
3129+
3130+
fmt::format_context::iterator fmt::formatter<MediumLevelILInstruction>::format(const MediumLevelILInstruction& obj, format_context& ctx) const
3131+
{
3132+
if (!obj.function)
3133+
return fmt::format_to(ctx.out(), "<uninit>");
3134+
3135+
vector<InstructionTextToken> tokens;
3136+
#ifdef BINARYNINJACORE_LIBRARY
3137+
bool success = obj.function->GetExprText(obj.function->GetFunction(), obj.function->GetArchitecture(), obj, tokens, new DisassemblySettings());
3138+
#else
3139+
bool success = obj.function->GetExprText(obj.function->GetArchitecture(), obj.exprIndex, tokens);
3140+
#endif
3141+
if (success)
3142+
{
3143+
string text;
3144+
if (presentation == '?')
3145+
{
3146+
fmt::format_to(ctx.out(), "{} ", obj.operation);
3147+
fmt::format_to(ctx.out(), "@ {:#x} ", obj.address);
3148+
if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0)
3149+
{
3150+
fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex);
3151+
}
3152+
if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0)
3153+
{
3154+
fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex);
3155+
}
3156+
Ref<Type> type = obj.GetType();
3157+
if (type)
3158+
{
3159+
fmt::format_to(ctx.out(), "[type: {}] ", type->GetString());
3160+
}
3161+
}
3162+
3163+
for (auto& token: tokens)
3164+
{
3165+
fmt::format_to(ctx.out(), token.text);
3166+
}
3167+
}
3168+
else
3169+
{
3170+
fmt::format_to(ctx.out(), "???");
3171+
}
3172+
return ctx.out();
3173+
}

mediumlevelilinstruction.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,3 +1713,24 @@ namespace BinaryNinja
17131713
#undef _STD_UNORDERED_MAP
17141714
#undef _STD_MAP
17151715
} // namespace BinaryNinjaCore
1716+
1717+
#ifdef BINARYNINJACORE_LIBRARY
1718+
#define IL_INS_NS BinaryNinjaCore
1719+
#else
1720+
#define IL_INS_NS BinaryNinja
1721+
#endif
1722+
template<> struct fmt::formatter<IL_INS_NS::MediumLevelILInstruction>
1723+
{
1724+
// <empty> -> normal, ? -> debug
1725+
char presentation = ' ';
1726+
format_context::iterator format(const IL_INS_NS::MediumLevelILInstruction& obj, format_context& ctx) const;
1727+
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
1728+
{
1729+
auto it = ctx.begin(), end = ctx.end();
1730+
if (it != end && *it == '?')
1731+
presentation = *it++;
1732+
if (it != end && *it != '}') detail::throw_format_error("invalid format");
1733+
return it;
1734+
}
1735+
};
1736+
#undef IL_INS_NS

0 commit comments

Comments
 (0)