用于汇编程序员的Linux / x86-64系统调用中的结构布局?

时间:2022-04-20 13:57:04

A number of linux/x86-64 syscalls accept pointers to structs as arguments.

许多linux / x86-64系统调用接受指向结构的指针作为参数。

For example the second parameter of stat(2) is struct stat*...

例如,stat(2)的第二个参数是struct stat * ...

   struct stat {
       dev_t     st_dev;     /* ID of device containing file */
       ino_t     st_ino;     /* inode number */
       mode_t    st_mode;    /* protection */
       nlink_t   st_nlink;   /* number of hard links */
       uid_t     st_uid;     /* user ID of owner */
       gid_t     st_gid;     /* group ID of owner */
       dev_t     st_rdev;    /* device ID (if special file) */
       off_t     st_size;    /* total size, in bytes */
       blksize_t st_blksize; /* blocksize for file system I/O */
       blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
       time_t    st_atime;   /* time of last access */
       time_t    st_mtime;   /* time of last modification */
       time_t    st_ctime;   /* time of last status change */
   };

This means that if you want to call the syscall from pure assembly than you have to know the rules about how big each type is, and whether there is any padding in between members for alignment purposes, and so on.

这意味着如果要从纯汇编中调用系统调用,则必须知道每种类型有多大的规则,以及成员之间是否存在任何填充以进行对齐,等等。

Does the C standard leave this open to be (compiler) implementation defined or can it be determined from the standard (assuming the primitive type sizes are known)?

C标准是否允许(编译器)实现定义,或者可以从标准确定(假设原始类型大小已知)?

If it is left open, does the kernel or the x86-64 architecture define it in anyway? Or is it just a matter of which compiler the kernel happened to be compiled with?

如果它保持打开状态,内核或x86-64架构是否仍然定义它?或者只是内核碰巧编译的编译器问题?

(That is given some member of the struct I need to calculate the starting offset of that member relative to the address of the struct)

(这是结构的一些成员我需要计算该成员相对于struct的地址的起始偏移量)

2 个解决方案

#1


14  

The layout of structs is not defined in the C standard, but in the ABI definition, in your case the System V AMD64 ABI. That is, in general the layout is OS dependent, and all compilers targeting that OS must conform to the ABI (though most will have options to generate different layout if you know what you are doing). The ABI also defines how parameters are passed to functions, how values are returned, which registers must be preserved across calls, and so on.

结构的布局未在C标准中定义,但在ABI定义中,在您的情况下是System V AMD64 ABI。也就是说,通常布局是依赖于操作系统的,并且所有针对该操作系统的编译器必须符合ABI(尽管如果您知道自己在做什么,大多数编译器都会选择生成不同的布局)。 ABI还定义了如何将参数传递给函数,如何返回值,哪些寄存器必须在调用之间保留,等等。

The ABI definition you need should be available on http://www.x86-64.org/ (seems to be down)

您需要的ABI定义应该可以在http://www.x86-64.org/上找到(似乎已经关闭)

#2


0  

Under Linux/x86-64:

在Linux / x86-64下:

A byte is 8 bits. Sizes and memory addresses are in 1 byte units.

一个字节是8位。大小和内存地址以1个字节为单位。

Primitive Types

Primitive Types have an alignment equal to their size:

原始类型的对齐方式与其大小相同:

The primitive type sizes (and alignments) are:

原始类型大小(和对齐)是:

bool 1
char 1
short 2
int 4
long 8
long long 8
__int128 16
void* 8
float 4
double 8
long double 16
__float128 16
__m64 8
__m128 16

Structs, Unions and Arrays

  • Structs (and unions) alignment is that of the maximum alignment of any of their components.

    结构(和联合)对齐是其任何组件的最大对齐。

  • Each struct member is assigned to the lowest available offset with the appropriate alignment.

    每个结构成员都被分配到具有适当对齐的最低可用偏移量。

  • The size of a struct is rounded up to the nearest multiple of its alignment.

    结构的大小向上舍入到其最接近的对齐倍数。

  • Structure and union objects can require padding to meet size and alignment constraints. The contents of any padding is undefined.

    结构和联合对象可能需要填充以满足大小和对齐约束。任何填充的内容都是未定义的。

  • An array of less than 16 bytes has the alignment of its element type.

    小于16个字节的数组具有其元素类型的对齐方式。

  • An array of 16 bytes or longer has alignment of the higher of (a) 16; and (b) the alignment of its element type.

    16字节或更长的数组具有(a)16中较高的对齐; (b)其元素类型的对齐。

#1


14  

The layout of structs is not defined in the C standard, but in the ABI definition, in your case the System V AMD64 ABI. That is, in general the layout is OS dependent, and all compilers targeting that OS must conform to the ABI (though most will have options to generate different layout if you know what you are doing). The ABI also defines how parameters are passed to functions, how values are returned, which registers must be preserved across calls, and so on.

结构的布局未在C标准中定义,但在ABI定义中,在您的情况下是System V AMD64 ABI。也就是说,通常布局是依赖于操作系统的,并且所有针对该操作系统的编译器必须符合ABI(尽管如果您知道自己在做什么,大多数编译器都会选择生成不同的布局)。 ABI还定义了如何将参数传递给函数,如何返回值,哪些寄存器必须在调用之间保留,等等。

The ABI definition you need should be available on http://www.x86-64.org/ (seems to be down)

您需要的ABI定义应该可以在http://www.x86-64.org/上找到(似乎已经关闭)

#2


0  

Under Linux/x86-64:

在Linux / x86-64下:

A byte is 8 bits. Sizes and memory addresses are in 1 byte units.

一个字节是8位。大小和内存地址以1个字节为单位。

Primitive Types

Primitive Types have an alignment equal to their size:

原始类型的对齐方式与其大小相同:

The primitive type sizes (and alignments) are:

原始类型大小(和对齐)是:

bool 1
char 1
short 2
int 4
long 8
long long 8
__int128 16
void* 8
float 4
double 8
long double 16
__float128 16
__m64 8
__m128 16

Structs, Unions and Arrays

  • Structs (and unions) alignment is that of the maximum alignment of any of their components.

    结构(和联合)对齐是其任何组件的最大对齐。

  • Each struct member is assigned to the lowest available offset with the appropriate alignment.

    每个结构成员都被分配到具有适当对齐的最低可用偏移量。

  • The size of a struct is rounded up to the nearest multiple of its alignment.

    结构的大小向上舍入到其最接近的对齐倍数。

  • Structure and union objects can require padding to meet size and alignment constraints. The contents of any padding is undefined.

    结构和联合对象可能需要填充以满足大小和对齐约束。任何填充的内容都是未定义的。

  • An array of less than 16 bytes has the alignment of its element type.

    小于16个字节的数组具有其元素类型的对齐方式。

  • An array of 16 bytes or longer has alignment of the higher of (a) 16; and (b) the alignment of its element type.

    16字节或更长的数组具有(a)16中较高的对齐; (b)其元素类型的对齐。