Aiur

zellux 的博客

Flux OSKit中trap_state的存放位置

Permalink

写fork函数的时候发现实际传给trap handler的ts地址和用 ((struct trap_state *) (KSTACK_TOP(old))) - 1 计算出来的结果不一样,后者比前者小0x10。另外ts的实际地址加上ts的大小(92个字节)后就超出了内核栈的范围。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * 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,也就解释了为什么计算出来的地址和实际的地址有偏差。

评论