Home > Mobile >  Is there any way to get offset of structure member to assembly code?
Is there any way to get offset of structure member to assembly code?

Time:12-15

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),            
  • Related