x86_64 calling conventions and stack frames

无人久伴 提交于 2019-12-03 05:35:06
Adrian Ratnapala

I think the difference is that omitting the frame pointer is simply more encouraged in amd64. A footnote on page 16 of the abi says

The conventional use of %rbp as a frame pointer for the stack frame may be avoided by using %rsp (the stack pointer) to index into the stack frame. This technique saves two instructions in the prologue and epilogue and makes one additional general-purpose register (%rbp) available.

I don't know what GDB does. I assume that when compiled with -g, objects have magic debugging information that allows GDB to reconstruct what it needs. I don't think I've tried GDB on a 64-bit machine without debugging info.

Ted Mielczarek

GDB uses the DWARF CFI for unwinding. For unstripped binaries compiled with -g, this will be in the .debug_info section. For stripped x86-64 binaries, there's unwind info in the .eh_frame section. This is defined in the x86-64 ABI, section 3.7, page 56. Handling this info yourself is pretty hard, since parsing DWARF is very involved, but I believe libunwind contains support for it.

If the address of argv is what you want, why not just save a pointer to it in main?
Trying to unwind the stack would be highly unportable, even if you get it to work.
Even if you do manage to go back over the stack, it isn't obvious that the first function's frame pointer would be NULL. The first function on the stack doesn't return, but calls a system call to exit, and therefore its frame pointer is never used. There's no good reason why it would be initialized to NULL.

Assuming that I am linking with glibc (which I am doing), it looks as if I can solve this problem for practical purposes with the glibc global symbol __libc_stack_end:

extern void * __libc_stack_end;

void myfunction(void) {
  /* ... */
  off_t stack_hi = (off_t)__libc_stack_end;
  /* ... */
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!