我有一个用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版本的尺寸在太大的时候会发生变化呢?
修改 该库是使用另一个库编译的,我无法重新编译,因为源代码不可用。这个其他库使用此接口。所以我无法改变界面的结构。
答案 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 建议将无效。即,我假设库正在使用这些函数,调用者分配空间。