c - 使用 objdump 或类似工具显示每个函数的调用约定

标签 c calling-convention objdump

我有一个 GCC 从 C 源文件生成的可执行文件(或 .o)。 如何使用 objdump 显示文件中包含的每个函数的调用约定?或类似的工具?

原因

看反汇编的时候好像有个函数A()调用另一个函数 B(x, y)通过推送 yx在堆栈上,但是 B(x, y)在寄存器中查找其参数。

我没有看到任何 __cdecl , __stdcallB(x, y) 的 C 源代码上的类似注释,并且没有看到任何 C/C++ 不兼容问题,所以我想从实际的 .o 中查询它使用的约定或可执行文件,而不是随机猜测。

最佳答案

A colleague found the problem: somewhere in the (rather long) file there was a #pragma which changed the GCC optimization level (from O2 to O0 I think). So, B was defined with O2 active, and A was defined with O0 active. This shouldn't be a problem, but it seems that GCC version chokes on it, and within A it calls B as if B was O0 too, but O0 and O2 have different calling conventions.

……有趣,很好的观察。

I think that information is contained in the .o, because when calling a function in a separate .o, GCC knows the convention and generates the right code.

这个推理是错误的。在您的情况下,B 必须已定义为 static;从寄存器加载参数的优化没有在具有外部链接的函数中完成。这也解释了为什么 在单独的 .o 中调用函数时,GCC … 生成正确的代码 - 它只是不执行优化;因此,GCC 没有必要从某些 信息中了解约定 ......包含在 .o 中——它不存在。

关于c - 使用 objdump 或类似工具显示每个函数的调用约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20347840/

相关文章:

elf - 如何从ELF文件中获取静态初始化的全局变量的值?

c - 这段代码实际上是如何工作的?

c - 在 POSIX C 中将 stdout 重定向到 stdin

c++ - 使用 MFC 时由于 "__cdecl"和 "__thiscall"调用约定不匹配导致的链接器错误?

linux - ARM 在 WinCE 和 Linux 上的调用约定?

c - 为什么 GCC 以不同方式存储全局和静态 int?

c - objdump 产生错误的分支操作码解释

c - 如何将结构作为参数传递给函数以在 C 中进行错误检查?

c - 服务器绑定(bind)导致错误 "Cannot assign requested address"?

GCC MIPS-32 调用约定/堆栈帧定义