Solaris学习笔记(4)

Solaris学习笔记(4)

作者: Badcoffee
Email:
blog.oliver@gmail.com
Blog: http://blog.csdn.net/yayong
2007年2月

很久没有写blog了,工作越来越忙,生活中琐事也不少,一天中的时间所剩无几了。当初很想写出精品的技术文章来,到后来才发现,要写一篇精品真的很难。从基础理论到实际案例,想深入潜出又要有一定水准,真的是太难了,这中间得花费写作者的多少心智?现在才能体会到成为一名出色的技术作家,需要的不仅仅是技术功底而已。所以,还是先做好工程师这份没有前途的职业再说吧:)

关键词:RISC/CISC/SPARC/ABI/MDB/KMDB/Solaris/OpenSolaris

本文介绍Solaris SPARC系统上Crashdump分析所需的基础知识:寄存器窗口,ABI等;Solaris的内核调试工具已经可以很好地读取出函数的入口参数,但是,在一些情况下,仍旧需要通过读取线程栈的内容来确定函数参数的值。再次说明,本文仅用于学习交流目的,错误再所难免,如果有勘误或疑问请与作者联系。

RISC 与 CISC

关于RISC与CISC的争论由来以久,相关文章到处都是,不明白可以Google一下。似乎两者已经互相借鉴,互相融合了,如果有时间,应该深入了解一下CPU和体系结构方面的知识。

SPARC体系结构的文档,可以从下面的网站得到,本文只涉及到crash dump分析的基础。

http://www.sparc.org/

SPARC的特点

1. 精简指令集;

2. 指令和操作基于寄存器,内存访问需要专门的load/store操作;

3. 有很多寄存器(几百个),通过寄存器窗口来访问;

4. 函数参数传递也通过寄存器,而不是通过栈;

5. 指令编码定长;

6. 地址对齐,不对齐的地址会引发bad trap;例如,各种数据类型必须与其自然边界对齐;

7. 字节序缺省是大端的(也可支持小端,需要页表项的特殊设置);

SPARC寄存器

Processor Status Register (PSR):用来指示kernel/user mode, condition codes, CPU priority level等。

Program Counter (PC): 当前正在执行的指令地址;

next Program Counter (nPC):下条要执行指令的地址;

General-purpose registers:通用寄存器,实际上SPARC有数百个寄存器,但对每个程序仅可见32个,这是通过寄存器窗口实现的。

寄存器窗口中的通用寄存器分类

General-purpose registers %r0 … %r31

1. 全局寄存器(8个) - 对所有程序可见

General-purpose global registers %g0 … %g7 Same as %r0 … %r7

2. 输出寄存器(8个) -函数返回值,输出寄存器是下一个窗口的输入寄存器

General-purpose out registers %o0 … %o7 Same as %r8 … %r15

3. 局部寄存器(8个) - 仅本函数可见

General-purpose local registers %l0 … %l7 Same as %r16 … %r23

4. 输入寄存器(8个) -本函数的输入参数,来自于上一窗口的输出寄存器

General-purpose in registers %i0 … %i7 Same as %r24 … %r31

寄存器窗口

SPARCv9寄存器窗口的数量范围从 2 到 32,具体取决于处理器实现。每个寄存器窗口对应一个函数,当每个函数被调用时,函数开始会调用save指令分配相应的栈空间;

函数的调用必然引起一次窗口的切换和一次栈空间的预先分配,但寄存器在下列情况时才被保存在栈上,

    1. 寄存器窗口用尽时

    2. 上下文切换

    3. flushw指令

这时会引发一个硬件的溢出trap,将寄存器窗口中的16个寄存器(8个局部寄存器和8个输入寄存器)保存到栈上;

寄存器窗口还有underflow trap,可以把保存在栈里的值恢复;restore指令用于切回上级调用的寄存器窗口,并取释放栈空间;

 

相关的指令

1. 函数调用:

call address

或者

jmpl address, %o7

2. 函数入场:

save %sp, -0x78, %sp

3. 函数返回:

jmpl %i7+8, %g0
restore

或者

ret
restore

SPARC的ABI

函数的调用者传递参数到本窗口的o寄存器,被掉函数从本窗口的i寄存器读到;

%o0到%o5 - 用于函数返回值或者传递给下一个函数参数,第一个参数是%o0 ,参数多于6个还会用栈传递;

%o6 - %sp栈顶指针;

%o7 -函数返回地址;

%i6 -%fp栈框架指针(SFP)

%i0到%i5 -入口参数,第一个参数是%i0,来自于上一窗口的输出参数;

%g0永远是0,特殊用途;

SPARC V9的 stack bias:

%o6 is still referred to as the stack pointer register %sp, and %i6 is the frame pointer register %fp. However, the %sp and %fp registers are offset by a constant, known as the stack bias, from the actual memory location of the stack. The size of the stack bias is 2047 bytes.

栈框架的定义

Solaris中,stack frame的格式定义在体系结构相关的头文件中:

http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sparc/sys/frame.h#36

 

 /*

 * Definition of the sparc stack frame (when it is pushed on the stack).

 
*/

struct frame {

long fr_local[8]; /* saved locals */

long fr_arg[6]; /* saved arguments [0 - 5] */

struct frame *fr_savfp; /* saved frame pointer */

long fr_savpc; /* saved program counter */

#if !defined(__sparcv9)

char *fr_stret; /* struct return addr */

#endif /* __sparcv9 */

long fr_argd[6]; /* arg dump area */

long fr_argx[1]; /* array of args past the sixth */

};


实际验证

在console上激活kmdb,用$<systemdump产生一个crashdump。可以根据上面的

头文件验证栈内寄存器窗口值的保存是与上面定义一致的。之所以产生一个crash dump来验证,

是为防止寄存器窗口还没有保存在栈里。

# mdb 0
> ::stackregs
000002a100347111 abort_seq_softintr
+0x94(1814400, 18cc800, 300077d4000, 3f70, 11870400)
  
%l0-%l3:          1821d40    22d3188da0893                0                0
  
%l4-%l7:                0          18cc800          191bc00          1010184
  intr_thread
+0x2c0:       jmpl      %o5, %o7

000002a1003472d1 intr_thread
+0x2c0(0, 1859ff8, 180c000, 1b, 10b5fd8, 1817c00)
  
%l0-%l3:          1008468                a       4414001602              80a
  
%l4-%l7:                0                0                0      2a10030f980
mdb: failed to read instruction at 
0: no mapping for address

000002a10030f221 
0(1817c00, 0, 300077d4000, ffffffffffffffff, 21816800)
  
%l0-%l3:      60000128fe8               1b                0 ffffffffffffffff
  
%l4-%l7:      60000128fe8 ffffffffffffffff          1859ff8          106b174
  thread_start
+4:          jmpl      %i7, %o7

000002a10030f2d1 thread_start
+4(000000)
  
%l0-%l3:                0                0                0                0
  
%l4-%l7:                0                0                0                0

> ::regs
%g0 = 0x0000000000000000                 %l0 = 0x000006000013c200 
%g1 = 0x0000000000000000                 %l1 = 0x0000000000000001 
%g2 = 0x0000000000000000                 %l2 = 0x0000000000000001 
%g3 = 0x0000000001853400 cpunodes+0x1140 %l3 = 0x00000600002b4a10 
%g4 = 0x0000000000000000                 %l4 = 0x000000000191c040 
pci_intr_dma_sync
%g5 = 0x000000000109a800                 %l5 = 0x0000000000000001 
%g6 = 0x0000000000000010                 %l6 = 0x0000000000000002 
%g7 = 0x000002a100347cc0                 %l7 = 0x0000000000000001 

%o0 = 0x0000000000000000                 %i0 = 0x0000000000000000 
%o1 = 0x0000000000020040                 %i1 = 0x000000000000000a 
%o2 = 0x0000000001851000 lgrp_stats+0x12f8 %i2 = 0x000000000000000a 
%o3 = 0x0000000000000001                 %i3 = 0x0000000001814400 
%o4 = 0x00000000013446a4 kmdbmod`kaif_enter %i4 = 0x0000000000000000 
%o5 = 0x00000000018ea2b8 kmdbmod`kaif_dvec %i5 = 0x0000000001853400 
cpunodes
+0x1140
%o6 = 0x000002a100347041                 %i6 = 0x000002a100347111 
%o7 = 0x000000000101028c debug_enter+0x108 %i7 = 0x000000000100ff38 
abort_seq_softintr
+0x94

 
%ccr = 0x00 xcc=nzvc icc=nzvc
%fprs = 0x00 fef=0 du=0 dl=0
 
%asi = 0x00                          
   
%= 0x0000000000000000
  
%pc = 0x0000000000000000 
 
%npc = 0x0000000000000004 
  
%sp = 0x000002a100347041 unbiased=0x000002a100347840
  
%fp = 0x000002a100347111

  
%tick = 0x000006b00af1f9fe
   
%tba = 0x0000000000000000
    
%tt = 0x9
    
%tl = 0x0
   
%pil = 0xc
%pstate = 0x016 cle=0 tle=0 mm=TSO red=0 pef=1 am=0 priv=1 ie=1 ag=0

       
%cwp = 0x05  %cansave = 0x00
%canrestore = 0x00 %otherwin = 0x00
    
%wstate = 0x00 %cleanwin = 0x00
> 0x000002a100347111+0t2047,24/naJ
0x2a100347910:  
0x2a100347910:  1821d40         
0x2a100347918:  22d3188da0893   
0x2a100347920:  0               
0x2a100347928:  0               
0x2a100347930:  0               
0x2a100347938:  18cc800         
0x2a100347940:  191bc00         
0x2a100347948:  1010184         
0x2a100347950:  1814400         
0x2a100347958:  18cc800         
0x2a100347960:  300077d4000     
0x2a100347968:  3f70            
0x2a100347970:  1               
0x2a100347978:  1870400         
0x2a100347980:  2a1003472d1     
0x2a100347988:  100c714         
0x2a100347990:  3000793e0b8     
0x2a100347998:  0               
0x2a1003479a0:  0               
0x2a1003479a8:  0               
0x2a1003479b0:  3000793e028     
0x2a1003479b8:  3000793e030     
0x2a1003479c0:  1fafdd                
0x2a1003479c8:  3000793e030     
0x2a1003479d0:  0               
0x2a1003479d8:  6000003b6e0     
0x2a1003479e0:  300347221       
0x2a1003479e8:  1fafdd          
0x2a1003479f0:  1297538         
0x2a1003479f8:  413             
0x2a100347a00:  1297518         
0x2a100347a08:  6000003b6e0     
0x2a100347a10:  13c200          
0x2a100347a18:  0               
0x2a100347a20:  0               
0x2a100347a28:  600002b4a10     
> 2a1003472d1+0t2047,24/naJ
0x2a100347ad0:  
0x2a100347ad0:  1008468         
0x2a100347ad8:  a               
0x2a100347ae0:  4414001602      
0x2a100347ae8:  80a             
0x2a100347af0:  0               
0x2a100347af8:  0               
0x2a100347b00:  0               
0x2a100347b08:  2a10030f980     
0x2a100347b10:  0               
0x2a100347b18:  1859ff8         
0x2a100347b20:  180c000         
0x2a100347b28:  1b              
0x2a100347b30:  10b5fd8         
0x2a100347b38:  1817c00         
0x2a100347b40:  2a10030f221     
0x2a100347b48:  0               
0x2a100347b50:  baddcafebaddcafe 
0x2a100347b58:  baddcafebaddcafe 
0x2a100347b60:  baddcafebaddcafe 
0x2a100347b68:  baddcafebaddcafe 
0x2a100347b70:  baddcafebaddcafe 
0x2a100347b78:  baddcafebaddcafe 
0x2a100347b80:  baddcafebaddcafe      
0x2a100347b88:  baddcafebaddcafe 
0x2a100347b90:  baddcafebaddcafe 
0x2a100347b98:  baddcafebaddcafe 
0x2a100347ba0:  baddcafebaddcafe 
0x2a100347ba8:  baddcafebaddcafe 
0x2a100347bb0:  baddcafebaddcafe 
0x2a100347bb8:  baddcafebaddcafe 
0x2a100347bc0:  baddcafebaddcafe 
0x2a100347bc8:  baddcafebaddcafe 
0x2a100347bd0:  baddcafebaddcafe 
0x2a100347bd8:  baddcafebaddcafe 
0x2a100347be0:  baddcafebaddcafe 
0x2a100347be8:  baddcafebaddcafe 

相关文档:

Solaris学习笔记(3)
Solaris学习笔记(2)
Solaris学习笔记(1)
X86汇编语言学习手记(3)

X86汇编语言学习手记(2)
X86汇编语言学习手记(1)


 

Technorati Tag: OpenSolaris
Technorati Tag: Solaris

posted on 2007-02-23 19:25  爱你一万年123  阅读(147)  评论(0编辑  收藏  举报

导航