0

我得到了一个用 GCC 编译的库,用于编译为静态库的 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_fnjmpbuf. 显然,它是用另一个大小为 a 的假设编译的jmp_buf

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

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

4

1 回答 1

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()

于 2013-07-10T13:31:59.330 回答