32位和64位架构中的结构成员对齐混淆

时间:2017-09-08 09:29:52

标签: c linux gcc linux-kernel

在64位Linux内核中运行32位应用程序(用C语言编写)时,我遇到了一些问题。在32位内核中运行相同的应用程序没有任何问题。

花了很多时间进行调试后,图片变得更加清晰。在用户空间应用程序和内核模块之间共享一种结构。从用户空间传递到内核空间时,结构变量中成员的值会被破坏。

这是结构的辩护

struct entry
{
    unsigned active:1;
    unsigned strict:1;
    unsigned AB_is_ipv6:1;
    unsigned XY_is_ipv6:1;
    unsigned srtp_sideA_en:2;
    unsigned srtp_sideB_en:2;
    unsigned srtp_mki_sideA_en:2;
    unsigned srtp_mki_sideB_en:2;
    unsigned cnt_fdnat, cnt_fsnat, cnt_rdnat, cnt_rsnat;
    unsigned short Apt, Bpt, Xpt, Ypt;
    unsigned int err[2];
};

两个位字段srtp_mki_sideA_en和srtp_mki_sideB_en的值经常被破坏。

当里面有比特字段成员时,共享结构有什么问题吗?

32位和64位架构中的成员对齐是否存在差异,这可能导致共享数据结构时内存损坏?

在64位内核和32位应用程序之间共享数据结构时是否还有其他已知问题?

1 个答案:

答案 0 :(得分:2)

我根本不相信该结构的内存布局。它没有被声明为打包,它有intshort个部分,几乎每个建筑都有不同的大小。此外,位域还具有编译器相关的捕获量(我过去使用的一个编译器只允许8位长的位域)。

我会完全重新组织结构。首先,按大小排序内容(最大的第一个)。使用打包,使用stdint.h中声明的类型。例如,int32_t保证在每个架构上都有32位。

如果您无法控制结构并且无法更改结构,请对调试使用的内存布局进行反向工程,然后在应用程序中创建类似于给定结构的结构。