Flux OSKit 中 trap_state 的存放位置
写fork函数的时候发现实际传给trap handler的ts地址和用(struct trap_state *) (KSTACK_TOP(old))) - 1
计算出来的结果不一样,后者比前者小0x10。另外ts的实际地址加上ts的大小(92个字节)后就超出了内核栈的范围。
/*
* This structure corresponds to the state of user registers
* as saved upon kernel trap/interrupt entry.
* As always, it is only a default implementation;
* a well-optimized kernel will probably want to override it
* with something that allows better optimization.
*/
struct trap_state
{
/* Saved segment registers */
unsigned int gs;
unsigned int fs;
unsigned int es;
unsigned int ds;
/* PUSHA register state frame */
unsigned int edi;
unsigned int esi;
unsigned int ebp;
unsigned int cr2; /* we save cr2 over esp for page faults */
unsigned int ebx;
unsigned int edx;
unsigned int ecx;
unsigned int eax;
/* Processor trap number, 0-31. */
unsigned int trapno;
/* Error code pushed by the processor, 0 if none. */
unsigned int err;
/* Processor state frame */
unsigned int eip;
unsigned int cs;
unsigned int eflags;
unsigned int esp;
unsigned int ss;
/* Virtual 8086 segment registers */
unsigned int v86_es;
unsigned int v86_ds;
unsigned int v86_fs;
unsigned int v86_gs;
};
可以看到在trap发生时硬件自动push的eip cs eflags esp ss后还有四个v86的数据,而通常的trap过程中这些数据是不会被push到内核栈的,而这四个数据的长度正好是0x10,也就解释了为什么计算出来的地址和实际的地址有偏差。
本作品采用知识共享署名-非商业性使用 3.0 版本许可协议进行许可,欢迎转载,演绎,但是必须保留本文的署名 zellux(包含链接),且不得用于商业目的。