sdbbs
sdbbs

Reputation: 5478

Generating annotated text description of structs with size/offset of fields for a given architecture during compilation?

Basically, I would like to obtain the information about packing of structs on a given architecture during the compilation process, formatted as a text file with the struct description (code stripped of original comments), with added comments containing the size and offset of a given field.

Let me give an example - consider the following trivial code, test_struct.c:

#include <stdint.h>
#include <stdio.h>

struct MyStruct {
  uint8_t first;    // this is the first field
  uint16_t second;  // second field
  uint32_t third;   // third field is also important
  uint64_t fourth;  // do not forget fourth field
};
typedef struct MyStruct MyStruct_t;

MyStruct_t my_object = {
  .first  = 10,
  .second = 20,
  .third  = 30,
  .fourth = 40,
};

int main(void) {
  printf("Start: %d\n", my_object.first);
  while ( 1 ) {
    ;
  }
}

I can compile this for PC (say Linux) with:

gcc -Wall -g -o test_struct.exe test_struct.c

... and I can compile for ARM with:

arm-none-eabi-gcc --specs=nosys.specs -Wall -g -o test_struct.elf test_struct.c

Now, for outputting the struct info, I've found Extract detailed symbol information (struct members) from elf file compiled with ARM-GCC :

is pahole what you need? it can dump variable structure with size and offset.

... and indeed, on Linux I can do:

$ pahole -C MyStruct test_struct.exe
struct MyStruct {
    uint8_t                    first;                /*     0     1 */

    /* XXX 1 byte hole, try to pack */

    uint16_t                   second;               /*     2     2 */
    uint32_t                   third;                /*     4     4 */
    uint64_t                   fourth;               /*     8     8 */

    /* size: 16, cachelines: 1, members: 4 */
    /* sum members: 15, holes: 1, sum holes: 1 */
    /* last cacheline: 16 bytes */
};

... and that is the output that I want - compilable text description of the struct, with the original comments stripped, and comments with size and offset of fields added.

However, that "try to pack" worries me - I would like a description of the struct exactly as-is in code; and ultimately, I'd like to compare the default packing of the struct between architectures (in this example, Linux and ARM).

So, I was thinking - since it is generally "the same compiler" (GCC) being used in both cases, would it be possible to instruct the compiler (maybe through a custom script?) to generate such descriptions for selected structs in code? Such that it would be the "same" gcc command in a Cmake/Makefile that executes, regardless of which architecture the code is being built for - and it generates the information for that architecture?

If not, I guess I'd be forced to extract this information in a post-build step; in that case, is pahole my only option, or are there other tools that can generate this kind of information? pahole on Linux seems able to parse the ARM .elf file (pahole -C MyStruct test_struct.exe) - but is does that give accurate architecture-specific information? How do I ensure that I get a description of a struct as-is in memory for a given architecture build, without any attempts for packing by such tools?

( and in either of these cases, are there options to control the text formatting? For instance, I'd rather get an output like this, compared to the above pahole example:

struct MyStruct {
    uint8_t  first;  // 0 1
    uint16_t second; // 2 2
    uint32_t third;  // 4 4
    uint64_t fourth; // 8 8
};

)

Upvotes: 0

Views: 406

Answers (0)

Related Questions