Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Handle/BNType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ public ulong Width
}
}

/// <summary>
/// Whether this integer-like type is signed (wraps BNIsTypeSigned).
/// </summary>
public BoolWithConfidence Signed
{
get
{
return BoolWithConfidence.FromNative(NativeMethods.BNIsTypeSigned(this.handle));
}
}


public ulong Alignment
{
get
Expand Down
67 changes: 67 additions & 0 deletions Type/EnumerationType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,72 @@ public EnumerationMember[] Members
return this.Enumeration.Members;
}
}

/// <summary>
/// The member values reinterpreted per this enumeration's signedness and width, mirroring
/// Python's <c>EnumerationType.members</c> (which applies
/// <c>binaryninja.types.convert_integer</c> to each raw u64). A signed enumeration reports
/// -1 for <c>0xFFFFFFFFFFFFFFFF</c>; <see cref="EnumerationMember.Value"/> alone returns the
/// raw unsigned value, so signed enumerations previously appeared as huge unsigned numbers.
/// </summary>
/// <remarks>
/// For an unsigned enumeration whose value exceeds <see cref="long.MaxValue"/>, the
/// authoritative value is <see cref="EnumerationMember.Value"/> (ulong); the long returned
/// here wraps. Signed enumerations — the case this method exists for — are exact.
/// </remarks>
public long[] GetMemberSignedValues()
{
EnumerationMember[] members = this.Members;
BoolWithConfidence signed = this.Signed;
ulong width = this.Width;

long[] result = new long[members.Length];

for (int i = 0; i < members.Length; i++)
{
result[i] = ConvertInteger(members[i].Value, signed.Value, width);
}

return result;
}

// Reinterpret a raw 64-bit value as a signed or unsigned integer of the given byte width,
// mirroring Python binaryninja.types.convert_integer (types.py:68). Mask to the width first,
// then sign-extend when signed.
private static long ConvertInteger(ulong value, bool signed, ulong width)
{
ulong masked;

switch (width)
{
case 1:
masked = value & 0xFFUL;
if (signed)
{
return (long)(sbyte)masked;
}
return (long)(byte)masked;

case 2:
masked = value & 0xFFFFUL;
if (signed)
{
return (long)(short)masked;
}
return (long)(ushort)masked;

case 4:
masked = value & 0xFFFFFFFFUL;
if (signed)
{
return (long)(int)masked;
}
return (long)(uint)masked;

default:
// Width 8 (and any other value): the full 64 bits.
return (long)value;
}
}
}
}
Loading