什么是正确的jmp_buf大小?

时间:2013-07-10 07:52:59

标签: gcc arm

我有一个用GCC编译的库,用于编译为静态lib的ARM Cortex-M3处理器。该库的接口有一个jmp_buf。

struct png_struct_def {
#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf jmpbuf;
#endif
    png_error_ptr error_fn;
    // a lot more members ...
};
typedef png_struct_def png_struct;

当我将png_struct地址传递给库函数时,它将值存储为error_fn而不是jmpbuf的最后一个字段。显然它已经编译了另一个jmp_buf的大小的假设。

两个编译器版本都是arm-none-eabi-gcc。为什么代码不兼容。什么是“正确的”jmp_buf大小?我可以在反汇编中看到只使用了jmp_buf的前半部分。为什么GCC版本的尺寸在太大的时候会发生变化呢?

修改 该库是使用另一个库编译的,我无法重新编译,因为源代码不可用。这个其他库使用此接口。所以我无法改变界面的结构。

1 个答案:

答案 0 :(得分:0)

您可以简单地重新排序数据声明。我建议如下,

typedef struct if {
    int some_value;
      union
        {
          jmp_buf jmpbuf;
          char pad[511];
        } __attribute__ ((__transparent_union__));
} *ifp;

问题在于,根据 ARM 库,可能会保存不同的寄存器。最多可以保存16个 32位通用寄存器和32个 64位 NEON寄存器。这给出了大约320个字节。如果多次使用struct,则可以进行过度分配。无论你得到jmp_buf的哪个定义,这都应该有用。

如果你不能重新编译库,你可以尝试使用,

typedef struct if {
    char pad[LIB_JMPBUF_SZ];
    int some_value;
} *ifp;

您计算jmp_buf大小的位置。 libc可能更改了版本之间jmp_buf的定义。此外,即使编译器名称匹配,一个可能支持浮点而另一个不匹配,等等。即使版本匹配,也可以设想编译器配置可以提供不同的jmp_buf大小。

这两个建议都是非便携式。如果您的代码调用setjmp()longjmp(),那么2 nd 建议将无效。即,我假设库正在使用这些函数,调用者分配空间。