2011-06-24 9 views

Respuesta

29

porque estaba en struct pt_regs, que es .... http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/arch/x86/include/asm/user_32.h#L77

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) 

Por lo tanto, una gran cantidad de utilidades de espacio de usuario esperan un campo orig_eax aquí, por lo que se incluye en user_regs_struct también (para que sea compatible con depuradores anteriores y ptrace rs)

La siguiente pregunta es "¿Por qué el miembro orig_eax está incluido en struct pt_regs?".

Fue agregado en linux 0.95 http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44. Sugiero que esto se hizo después de algún otro unix con pt_regs struct. Comentario en 0,95 dice

29 * this struct defines the way the registers are stored on the 
    30 * stack during a system call. 

Por lo tanto, el lugar de orig_eax está definido por la interfaz de llamada al sistema. Aquí es http://lxr.linux.no/#linux-old+v0.95/kernel/sys_call.s

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 

¿Por qué necesitamos para salvar edad eax dos veces? Debido eax se utilizará para el valor de retorno de la llamada al sistema (mismo archivo, un poco más adelante):

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 tiene que ser capaz de leer en todos los registros de estado antes llamada al sistema y el valor de retorno de la llamada al sistema; pero el valor de retorno se escribe en %eax. Entonces original eax, utilizado antes de syscall se perderá. Para guardarlo, hay un campo orig_eax.

ACTUALIZACIÓN: Gracias a R .. y gran LXR, hice una búsqueda completa de orig_eax en linux 0.95.

Se utiliza no sólo en ptrace, sino también en do_signal al reiniciar una llamada al sistema (si hay una llamada al sistema, terminó con ERESTARTSYS)

158      *(&eax) = orig_eax; 

Update2: Linus said algo interesante al respecto:

Es importante que ORIG_EAX se establezca en un valor que sea no a número de llamada del sistema válido, de modo que la lógica de reinicio de llamada del sistema (consulte código de manejo de señal) no se dispara.

Update3: ptrace r aplicación (depurador) puede cambiar orig_eax para cambiar el número de llamada del sistema a ser llamado: http://lkml.org/lkml/1999/10/30/82 (en algunas versiones de kernel, se fue EIO para cambiar en ptrace un ORIG_EAX)

+2

agrietamiento respuesta a una (aparentemente) endeble pregunta! – sehe

+2

Pensé que estaba relacionado con syscalls (y posiblemente reiniciar syscall). +1 para rastrear los detalles! –

+0

tenga en cuenta que los núcleos recientes renombraron el campo a orig_ax - si desea hacer una búsqueda LXR, haga ambos orig_eax y orig_ax. – osgx

Cuestiones relacionadas