How to determine values saved on the stack?

匆匆过客 提交于 2019-12-04 06:35:26

No need for inline assembly. The saved state that entry_32.S pushes onto the stack for a syscall is laid out as a struct pt_regs, and you can get a pointer to it like this (you'll need to include <asm/ptrace.h> and/or <asm/processor.h> either directly or indirectly):

struct pt_regs *regs = task_pt_regs(current);

Inline assembly is trickier than it seems. Trying to shortly cover the concerns for GCC:

  1. If it modifies processor registers, it's necessary to put these registers on the clobber list. It's important to note that the clobber list must contain ALL registers that you changed directly (read explicitly) or indirectly (read implicitly);
  2. To reinforce (1), conditional and mathematical operations also change registers, more known as status flags (zero, carry, overflow, etc), so you have to inform it by adding "cc" to the clobber list;
  3. Add "memory" if it modifies different (read random) memory positions;
  4. Add the volatile keyword if it modifies memory that isn't mentioned on the input/output arguments;

Then, your code becomes:

asm("movl 0x1C(%%esp), %0;"
    : "=r" (value)
    : /* no inputs :) */
    /* no modified registers */
);

The output argument isn't required to be on the clobber list because GCC already knows it will be changed.

Alternatively, since all you want is the value of ESP register, you can avoid all the pain doing this:

register int esp asm("esp");
esp += 0x1C;

It might not solve your problem, but it's the way to go. For reference, check this, this and this.

Keep in mind that x86_64 code will often pass values in registers (since it has so many) so nothing will be on the stack. Check the gcc intermediate output (-S IIRC) and look for push in the assembly.

I'm not familiar with debugging kernel code, but gdb is definitely nicer to examine the stack interactively.

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