Introduce a trait/derive macro for constructing Binja types out of Rust types #4545
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This work is not yet finished, but I'm opening a draft to get discussion going about design decisions. This PR introduces a trait
BinaryNinjaType
with the following definition:Implementing this trait on a Rust type allows it to be converted into a Binja
Type
to be sent to a BinaryView. Accompanying the trait is a derive macro that allows automatic implementation of this trait for any Rust type, as long as it satisfies the following restrictions:repr(C)
. This is just a design decision aimed at making the trait's semantics more obvious. Unit structs and Tuple structs (with unnamed fields) are unsupported.repr(C)
, and must instead be marked with a primitive type, e.g.repr(u8)
orrepr(u32)
. They must also be fieldless (all variants must not contain extra data), in other words C-style. Additionally, all variants must be assigned an explicit discriminant value.u128
,i128
,usize
andisize
.Currently, several features are missing which I hope to implement, but they are non-trivial and therefore require a bit of discussion around design:
Type::pointer
constructor requires an architecture and no others do.repr(C)
on Enums - The underlying representation (width) is ABI-dependant, which basically means arch-dependant in Binja terms. So, in order for the semantics to make sense, this needs to rely on an architecture, the same as pointers.#[name = "..."]
. However, actually resolving this requires querying a BinaryView.The following features are also currently missing but are more straightforward to implement:
repr(transparent)
on Structs and Enums - This is valid if there is only a single non-zero-sized field/variant. However, the complication is that any number of additional zero-sized fields can live alongside it (such asPhantomData
), and determining which of the fields is the one with non-zero size seems tricky.repr(align)
andrepr(packed)
- This would be nice to add, such that alignment and padding could be specified in Rust, but requires me reading up a bit more about how exactly these attributes work.I would appreciate feedback and thoughts on addressing what's missing.