You can write a script that is invoked as a build step to create the file offsets.h.
The biggest difficulty with this is extracting the structure names and member names from the header files. The example below uses a very simple header file and a very simple awk script to get the names, just to show the idea. A real implementation of this would be dependent on how complex the header files are and how robust your parser needs to be. If the struct definitions in your header files have a very consistent layout, then it might not be much more complex than this example.
This is a complete and fully tested example.
Makefile
a.out: main.o asm.o
cc main.o asm.o
demo_offsets.h: demo.h
sh make_offsets.sh $<
main.o : demo.h
asm.o: demo_offsets.h
make_offsets.sh
set -e
tmp=make_tmp$$
cat << EOF > $tmp.c
#include <stdio.h>
#include <stddef.h>
#include "$1"
int main()
{
`awk -f awkfile $1`
}
EOF
cc -o $tmp $tmp.c
$tmp > $(basename ${1} .h)_offsets.h
rm $tmp.c $tmp
awkfile
/struct/ { s=$2 }
/[A-Za-z_];/ { m=gensub(".*([A-Za-z_]*);", "\\1", 1); printf "printf(\"#define %s_%s_offset %%lu\\n\", offsetof(struct %s, %s));\n", s, m, s, m; }
demo.h
struct demo {
int x;
int y;
};
main.c
#include "demo.h"
extern int f(const struct demo *);
int main()
{
struct demo s = { 1, 2 };
return f(&s);
}
asm.S
#include "demo_offsets.h"
.global f
f:
mov demo_x_offset(%rdi), %eax
add demo_y_offset(%rdi), %eax
ret