<?xml version="1.0" encoding="gbk"?> <rss version="2.0"><channel> <title>定阅帖子更新</title> <link>http://www.broadkey.com.cn/XML.ASP</link><description>TEAM Board - 意得法电子</description> <copyright>TEAM 2.0.5 Release</copyright><generator>TEAM Board by TEAM5.Cn Studio</generator> <ttl>30</ttl><item><link>http://www.broadkey.com.cn/Thread.asp?tid=49 </link><title>PowerPC&amp;nbsp;下动态链接库机制</title><author>east</author><pubDate>2009-11-25 23:33:57</pubDate><description><![CDATA[考虑以下简单的程序：<br />
<br />
<font color="#009900">int</font> main()<br />
{<br />
&nbsp;&nbsp;&nbsp; printf(<font color="#ff0000">&quot;f[0] = </font><font color="#ff00ff">%d\n</font><font color="#ff0000">&quot;</font>, 0x0);&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; printf(<font color="#ff0000">&quot;f[0] =<font color="#ff00ff"> </font></font><font color="#ff00ff">%d\n</font><font color="#ff0000">&quot;</font>, 0x8);&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <font color="#ff9900">return</font> 0;<br />
}<br />
<br />
root@comcat:/root&gt; gdb ./test <br />
(gdb) <strong>disass main</strong><br />
Dump of assembler code for function main:<br />
0x1000044c &lt;main+0&gt;:&nbsp;&nbsp;&nbsp; stwu&nbsp;&nbsp;&nbsp; r1,-16(r1)<br />
0x10000450 &lt;main+4&gt;:&nbsp;&nbsp;&nbsp; mflr&nbsp;&nbsp;&nbsp; r0<br />
0x10000454 &lt;main+8&gt;:&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r0,20(r1)<br />
0x10000458 &lt;main+12&gt;:&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r31,12(r1)<br />
0x1000045c &lt;main+16&gt;:&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r31,r1<br />
0x10000460 &lt;main+20&gt;:&nbsp;&nbsp;&nbsp; lis&nbsp;&nbsp;&nbsp;&nbsp; r9,4096<br />
0x10000464 &lt;main+24&gt;:&nbsp;&nbsp;&nbsp; addi&nbsp;&nbsp;&nbsp; r3,r9,2056<br />
0x10000468 &lt;main+28&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r4,0<br />
0x1000046c &lt;main+32&gt;:&nbsp;&nbsp;&nbsp; crclr&nbsp;&nbsp; 4*cr1+eq<br />
0x10000470 &lt;main+36&gt;:&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000"><strong>0x100109c0</strong></font> &lt;printf@plt&gt;<br />
0x10000474 &lt;main+40&gt;:&nbsp;&nbsp;&nbsp; lis&nbsp;&nbsp;&nbsp;&nbsp; r9,4096<br />
0x10000478 &lt;main+44&gt;:&nbsp;&nbsp;&nbsp; addi&nbsp;&nbsp;&nbsp; r3,r9,2056<br />
0x1000047c &lt;main+48&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r4,8<br />
0x10000480 &lt;main+52&gt;:&nbsp;&nbsp;&nbsp; crclr&nbsp;&nbsp; 4*cr1+eq<br />
0x10000484 &lt;main+56&gt;:&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000"><strong>0x100109c0</strong></font> &lt;printf@plt&gt;<br />
0x10000488 &lt;main+60&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r0,0<br />
0x1000048c &lt;main+64&gt;:&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,r0<br />
0x10000490 &lt;main+68&gt;:&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r11,0(r1)<br />
0x10000494 &lt;main+72&gt;:&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r0,4(r11)<br />
0x10000498 &lt;main+76&gt;:&nbsp;&nbsp;&nbsp; mtlr&nbsp;&nbsp;&nbsp; r0<br />
0x1000049c &lt;main+80&gt;:&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r31,-4(r11)<br />
0x100004a0 &lt;main+84&gt;:&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r1,r11<br />
0x100004a4 &lt;main+88&gt;:&nbsp;&nbsp;&nbsp; blr<br />
End of assembler dump.<br />
(gdb) <strong>b *0x10000468</strong><br />
Breakpoint 1 at 0x10000468: file enum.c, line 13.<br />
(gdb) <strong>r</strong><br />
Starting program: /root/test <br />
<br />
Breakpoint 1, 0x10000468 in main () at test.c:13<br />
13&nbsp;&nbsp;&nbsp; test.c: No such file or directory.<br />
&nbsp;&nbsp;&nbsp; in test.c<br />
(gdb) <strong>x /6i 0x100109c0</strong><br />
<font color="#ff0000"><strong>0x100109c0</strong></font> &lt;printf@plt&gt;:&nbsp;&nbsp;&nbsp;<font color="#00ccff"> <font color="#3366ff">li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r11,8</font></font><br />
0x100109c4 &lt;printf@plt+4&gt;:&nbsp;&nbsp;&nbsp; b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10010988 &lt;_GLOBAL_OFFSET_TABLE_+44&gt;<br />
0x100109c8 &lt;printf@plt+8&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109cc &lt;printf@plt+12&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109d0 &lt;printf@plt+16&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109d4 &lt;completed.6562&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
(gdb) <strong>x /10i 0x10010988</strong><br />
0x10010988 &lt;_GLOBAL_OFFSET_TABLE_+44&gt;:&nbsp;&nbsp;&nbsp; rlwinm r12,r11,1,0,30<br />
0x1001098c &lt;_GLOBAL_OFFSET_TABLE_+48&gt;:&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r11,r12,r11<br />
0x10010990 &lt;_GLOBAL_OFFSET_TABLE_+52&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r12,14468<br />
0x10010994 &lt;_GLOBAL_OFFSET_TABLE_+56&gt;:&nbsp;&nbsp;&nbsp; addis&nbsp;&nbsp; r12,r12,4093<br />
0x10010998 &lt;_GLOBAL_OFFSET_TABLE_+60&gt;:&nbsp;&nbsp;&nbsp; mtctr&nbsp;&nbsp; r12<br />
0x1001099c &lt;_GLOBAL_OFFSET_TABLE_+64&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r12,0<br />
0x100109a0 &lt;_GLOBAL_OFFSET_TABLE_+68&gt;:&nbsp;&nbsp;&nbsp; addis&nbsp;&nbsp; r12,r12,12288<br />
0x100109a4 &lt;_GLOBAL_OFFSET_TABLE_+72&gt;:&nbsp;&nbsp;&nbsp; bctr<br />
0x100109a8 &lt;_GLOBAL_OFFSET_TABLE_+76&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109ac &lt;_GLOBAL_OFFSET_TABLE_+80&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
(gdb) si<br />
0x1000046c&nbsp;&nbsp;&nbsp; 13&nbsp;&nbsp;&nbsp; in enum.c<br />
(gdb) si<br />
0x10000470&nbsp;&nbsp;&nbsp; 13&nbsp;&nbsp;&nbsp; in enum.c<br />
(gdb) <br />
0x100109c0 in printf@plt ()<br />
(gdb) <br />
0x100109c4 in printf@plt ()<br />
(gdb) <br />
0x10010988 in ?? ()<br />
(gdb) <br />
0x1001098c in ?? ()<br />
(gdb) <br />
0x10010990 in ?? ()<br />
(gdb) <br />
0x10010994 in ?? ()<br />
(gdb) <br />
0x10010998 in ?? ()<br />
(gdb) <br />
0x1001099c in ?? ()<br />
(gdb) <br />
0x100109a0 in ?? ()<br />
(gdb) <br />
0x100109a4 in ?? ()<br />
(gdb) <br />
0x0ffd3884 in ?? () from /lib/ld.so.1&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ----&gt; 动态链接器解析 printf 符号，获得其函数实体地址，然后重写 0x100109c0 处的指令<br />
(gdb)<strong> b *0x1000047c</strong><br />
Breakpoint 2 at 0x1000047c: file test.c, line 14.<br />
(gdb) c<br />
Continuing.<br />
f[0] = 0<br />
<br />
Breakpoint 2, 0x1000047c in main () at test.c:14<br />
14&nbsp;&nbsp;&nbsp; in test.c<br />
(gdb) <strong>x /6i 0x100109c0</strong><br />
<font color="#ff0000"><strong>0x100109c0</strong></font> &lt;printf@plt&gt;:&nbsp;&nbsp;&nbsp; <font color="#99cc00">b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xfeba210 &lt;printf&gt;&nbsp;&nbsp;&nbsp; <font color="#009900">----&gt; 第一次调用 printf 后，此处即被动态链接器 ld.so.1 重填</font></font><br />
0x100109c4 &lt;printf@plt+4&gt;:&nbsp;&nbsp;&nbsp; b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10010988 &lt;_GLOBAL_OFFSET_TABLE_+44&gt;<br />
0x100109c8 &lt;printf@plt+8&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109cc &lt;printf@plt+12&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109d0 &lt;printf@plt+16&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109d4 &lt;completed.6562&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
(gdb) <strong>x /10i 0x10010988</strong><br />
0x10010988 &lt;_GLOBAL_OFFSET_TABLE_+44&gt;:&nbsp;&nbsp;&nbsp; rlwinm r12,r11,1,0,30<br />
0x1001098c &lt;_GLOBAL_OFFSET_TABLE_+48&gt;:&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r11,r12,r11<br />
0x10010990 &lt;_GLOBAL_OFFSET_TABLE_+52&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r12,14468<br />
0x10010994 &lt;_GLOBAL_OFFSET_TABLE_+56&gt;:&nbsp;&nbsp;&nbsp; addis&nbsp;&nbsp; r12,r12,4093<br />
0x10010998 &lt;_GLOBAL_OFFSET_TABLE_+60&gt;:&nbsp;&nbsp;&nbsp; mtctr&nbsp;&nbsp; r12<br />
0x1001099c &lt;_GLOBAL_OFFSET_TABLE_+64&gt;:&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r12,0<br />
0x100109a0 &lt;_GLOBAL_OFFSET_TABLE_+68&gt;:&nbsp;&nbsp;&nbsp; addis&nbsp;&nbsp; r12,r12,12288<br />
0x100109a4 &lt;_GLOBAL_OFFSET_TABLE_+72&gt;:&nbsp;&nbsp;&nbsp; bctr<br />
0x100109a8 &lt;_GLOBAL_OFFSET_TABLE_+76&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
0x100109ac &lt;_GLOBAL_OFFSET_TABLE_+80&gt;:&nbsp;&nbsp;&nbsp; .long 0x0<br />
<br />
PowerPC 下，动态链接的机制与 x86 不同之处在于：<br />
<br />
PowerPC 上的 GOT 里是一些指令，第一次调用后，PLT 会被重填为新的指令。<br />
<br />
而 x86 上 GOT 只是存放函数地址，起初是 PLT 里的下一条指令，第一次调用后会被修改为 printf 的地址，PLT 的内容不会被修改。]]></description></item></channel></rss>