assemblystructoffsetabistat

how to determine field offset in stat struct calling from assembly?


In order to get struct stat describing file one would call *stat family of functions that will fill memory that is pointed to by passed pointer with struct values.

In C we can call POSIX.1-2008 offsetof macro, but it is a macro, not available in assembly.

How to determine size of struct from assembly and how to determine offsets of fields, so that one could extract necessary fields like st_size, st_mode and so on?


Solution

  • The ABI for the platform determines the rules for C struct padding. For example, x86-64 Linux uses the x86-64 System V ABI.

    Hard way: read the ABI and work it out yourself. Links in the tag wiki. (It's not actually that hard, the rules for alignment / padding within structs are quite simple for the x86-64 System V ABI: every member goes in order of declaration, and is naturally aligned. This can require padding. Windows x64 has its own struct-layout rules that don't always produce the same layout.)

    Easy way: let the compiler calculate the offsets for you by writing a function that stores into the struct, and look at the asm. e.g.

    #include <sys/stat.h>
    void foo(struct stat *st) {
        st->st_size = 1;
        st->st_mode = 2;  // different numbers so you know which field is which in the output
    }
    
        mov     QWORD PTR [rdi+48], 1
        mov     DWORD PTR [rdi+24], 2
        ret
    

    (from the Godbolt compiler explorer)


    Having the compiler output constants for use in separate .asm / .S

    See some other Q&As with answers geared towards automating the process of generating definitions like #define or .equ, or NASM equ: