ImHex icon indicating copy to clipboard operation
ImHex copied to clipboard

[Feature] Bitfields in structs without the need to specify an extra type

Open JanFeld opened this issue 1 year ago • 4 comments

What feature would you like to see?

I'd like to have the possibility to add bitfields directly in structs.

I'm working with some code-base and binary files i know some structures from and would like to represent them using ImHex patterns.

Some of these structs are declared combining PODs, bitfields and arrays. This representation is more complex in ImHex than in plain c declarations.

For Example:

typedef struct
{
    uint8_t a;

    uint8_t b:2;
    uint8_t reserved:6;

} example_t;

typedef struct
{
    int32_t a;
    uint8_t b:4;
    uint8_t c:4;

    example_t ex[2];
} example_ext_t;

The ImHex pattern would look similar to this (but isn't possible):

bitfield example_t
{
    u8 a;
    b : 2;
    padding : 6;
};

struct example_ext_t
{
    s32 a;
    b : 4; // -> error, no bitfields in structs allowed
    c : 4; // -> error, no bitfields in structs allowed
    example_t ex[2];
};

I tried to use bitfield for the whole definition like the following:

bitfield example_ext_t
{
    s32 a;
    b : 4;
    c : 4;
    example_t ex[2]; // -> error, no arrays in bitfields allowed
};

To represent this i have to add helper types like this:

bitfield example_ext_helper_t
{
    b : 4;
    c : 4;
};

struct example_ext_t
{
    s32 a;
    example_ext_helper_t [[inline]]; // -> inline due to flattened representation in tree-view
    example_t ex[2];
};

How will this feature be useful to you and others?

To allow bitfields and arrays in struct declarations would help to match some C-Struct declarations better. This can help in analysis of binary files representing these structs if the structs are known due to the similarity in C-Structs to the pattern files.

Currently it's more complicated to build patterns for structs declared like above.

Additionally this could help automating creating patterns from C-Structs because you wouldn't have to split bitfields from structs or arrays from bitfields.

Then one could write tools for example using libclang or libtooling to parse C-Struct definitions and create imhex-patterns from them.

Request Type

  • [ ] I can provide a PoC for this feature or am willing to work on it myself and submit a PR

Additional context?

No response

JanFeld avatar Jun 29 '23 10:06 JanFeld

I am not sure about arrays in bit-fields but it use to be possible to mix variables and bit-fields in structures up until bit-fields were overhauled to improve their feature set. I don't know all the tech details but one thing that comes to mind is the full control of endianess of each bit in the bit-field that makes them incompatible with other data types and impossible to declare inside a struct along with non-bit-field variables.

If my suspicion is correct and more bit-field savvy people should confirm/deny it then that would make it impossible to obtain the desired feature unless we extend the bit-field endianess to the rest of the pattern language data types. Even if this assertion is shown to be false there may be other characteristics of bit-fields that prevent their mixing.

I believe that the current implementation is the result of carefully considering possible implementations and active exchanges about their design by the creators of the implementation so there may be little room left to further revisions of the bit-field type. This is only my opinion that i have gathered by witnessing mentioned exchanges in discord.

paxcut avatar Jun 29 '23 13:06 paxcut

I don't have implementation details present but i see your point. The endianess of structures and bitfields is something platform dependent and should be fully configurable for interpretation to decode binary data. I get that it's maybe much more complicated than i thought in the first place.

Then that could be the reason it's not possible to allow (anonymous) 'inline/nested' declarations like this. Correct me if i'm wrong.

struct example_t 
{
    bitfield 
    {
        a : 2;
        padding : 6;
    } [[inline]];

    struct b
    {
        u8 a;
        u8 b;
    };

    u8 c;
};

Are you aware of any other way than helper-structures?

JanFeld avatar Jun 29 '23 14:06 JanFeld

I am afraid I am not confident enough about my knowledge of the subject to assert an answer one way or the other. In general it is not allowed to define user types inside other user types.It is possible to define anonymous members and forward declare types that must be defined later, but considering some of the concepts that the pattern language borrows from c++, in particular templates and inheritance could create literal monsters that parsers may be unable to unravel. By forcing instantiation at each step with filly defined variables with names you not only have a better chance at parsing, but the code becomes more legible to humans too and this can't be stressed enough.

But I think you understood exactly the message I was trying to convey. because bits maybe read left to right and right to left within bit-fields but not for integers which only allow little/big endianness I cannot imagine how to fully define each part without the use of helper types. The use of helper types together with the added abilities to bit-fields also gives you more control over the definitions that what can be afforded from the native definitions alone. That is the best argument I can make about my opinion of incompatibility. Such would be the price paid for the extra flexibility.

I apologize for the length of my answer in advance but allow me to answer your last question. From my current experience creating patterns I find the creation of helper types to be something that i tend to maximize. The flexibility of the pl really shines when the helper types are engineered just so and combined in particular ways that are not possible to describe in such concise and elegant manner. It took me a bit of time to start to internalize the strategies and tactics I currently use for pattern creation but I know now that I will never go back to my old ways.

If you decide to move forward with imhex keep a bit of an open mind and dont be afraid to experiment. Much like the language itself I find the community pretty amazing too in their willingness to help.

paxcut avatar Jun 29 '23 15:06 paxcut

No need to apologize for the length and detail of your answers. I appreciate detailed explanations. Usually they help forming a better mental model of things.

I'll stick to the helper-method for now. I don't want to close the issue though. Maybe one will think of a way to solve it somehow.

Nevertheless i get the point. If one of the maintainers will close the issue due to it's not in scope of the project or it's simply not possible it's fine too.

Thanks for your answers!

JanFeld avatar Jun 30 '23 10:06 JanFeld

This issue is marked stale as it has been open for 11 months without activity. Please try the latest ImHex version. (Avaiable here: https://imhex.download/ for release and https://imhex.download/#nightly for development version) If the issue persists on the latest version, please make a comment on this issue again

Without response, this issue will be closed in one month.

github-actions[bot] avatar Aug 03 '24 16:08 github-actions[bot]