For example, I have the following structure,
struct thread {
char *pName;
... // number of members between may be different for different configurations
int member;
...
};
For different configurations, there may be different members between pName
and member
, so member
's offset is not the same for different configurations.
And I want to use member
's offset in assembly code, but don't want to hard-code it according to different configurations. I have tried to define the following C style macro, but GCC assembler doesn't recognize it,
#define OFFSET (&(((struct thread*)0)->member))
Is there any other way to do that?
CodePudding user response:
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),