首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >除了eax之外,为什么还要提供orig_eax?

除了eax之外,为什么还要提供orig_eax?
EN

Stack Overflow用户
提问于 2011-06-24 22:02:57
回答 1查看 7.3K关注 0票数 19

为什么sys/user.hstruct user_regs_struct中包含orig_eax成员

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-24 22:16:13

因为它是在struct pt_regs,这是....http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/arch/x86/include/asm/user_32.h#L77

代码语言:javascript
复制
 73  * is still the layout used by user mode (the new
 74  * pt_regs doesn't have all registers as the kernel
 75  * doesn't use the extra segment registers)

因此,许多用户空间实用程序都希望这里有一个orig_eax字段,所以它也包含在user_regs_struct中(以便与较旧的调试器和ptracers兼容)。

下一个问题是“为什么struct pt_regs中包含orig_eax成员?”

它是在Linux0.95 http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44中添加的。我建议这是在其他unix使用pt_regs结构之后完成的。0.95中的评论说

代码语言:javascript
复制
  29 * this struct defines the way the registers are stored on the 
  30 * stack during a system call.

因此,orig_eax的位置由syscall接口定义。这就是http://lxr.linux.no/#linux-old+v0.95/kernel/sys_call.s

代码语言:javascript
复制
  17 * Stack layout in 'ret_from_system_call':
  18 *      ptrace needs to have all regs on the stack.
  19 *      if the order here is changed, it needs to be 
  20 *      updated in fork.c:copy_process, signal.c:do_signal,
  21 *      ptrace.c ptrace.h
  22 *
  23 *       0(%esp) - %ebx
 ...
  29 *      18(%esp) - %eax
 ...
  34 *      2C(%esp) - orig_eax

为什么我们需要保存两次旧的eax?因为syscall的返回值将使用eax (下面的文件相同):

代码语言:javascript
复制
  96_system_call:
  97        cld
  98        pushl %eax              # save orig_eax
  99        push %gs
...
 102        push %ds
 103        pushl %eax              # save eax.  The return value will be put here.
 104        pushl %ebp
...
 117        call _sys_call_table(,%eax,4)

Ptrace需要能够读取syscall之前的所有寄存器状态和syscall的返回值;但返回值是写入%eax的。然后,在系统调用之前使用的原始eax将丢失。为了保存它,有一个orig_eax字段。

更新:多亏了R。很棒的LXR,我在Linux0.95中全面搜索了orig_eax

它不仅在ptrace中使用,在重启syscall时也会在do_signal中使用(如果有syscall,以ERESTARTSYS结尾)

代码语言:javascript
复制
 158                        *(&eax) = orig_eax;

UPDATE2: Linus said一些有趣的事情:

必须将ORIG_EAX设置为无效的系统调用编号,这样系统调用重启逻辑(请参阅信号处理代码)才不会触发。

UPDATE3:ptracer应用程序(调试器)可以更改orig_eax以更改要调用的系统调用号:http://lkml.org/lkml/1999/10/30/82 (在某些版本的内核中,在ptrace和ORIG_EAX中更改的是was EIO )

票数 43
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6468896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档