程序员的自我修养 ch7 动态链接

1. DSO,Dynamic Shared Objects

[serverate: /local/root/c/ch7 ]
>> cat lib.h
#ifndef LIB_H
#define LIB_H
void foo(int i);
#endif
[serverate: /local/root/c/ch7 ]
>> cat lib.c
#include <stdio.h>

void fun(int i)
{
        printf("printing from lib.so %d\n", i);
        sleep(-1);
}

>> cat p1.c
#include "lib.h"

int main()
{
        fun(1);
        return 0;
}
[serverate: /local/root/c/ch7 ]
>> cat p2.c
#include "lib.h"

int main()
{
        fun(2);
        return 0;
}

test 1:

[serverate: /local/root/c/ch7 ]
>> gcc -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p1 p1.c ./lib.so
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p2 p2.c ./lib.so

>> ./p1 &
[2]     24559
[serverate: /local/root/c/ch7 ]
>> cd /proc/24559
[serverate: /proc/24559 ]
>> cat maps
08048000-08049000 r-xp 00000000 08:06 21915275                           /local/root/c/ch7/p1
08049000-0804a000 rw-p 00000000 08:06 21915275                           /local/root/c/ch7/p1
f7dca000-f7dcb000 rw-p f7dca000 00:00 0
f7dcb000-f7f14000 r-xp 00000000 08:01 504034                             /lib32/libc-2.7.so
f7f14000-f7f15000 r--p 00149000 08:01 504034                             /lib32/libc-2.7.so
f7f15000-f7f17000 rw-p 0014a000 08:01 504034                             /lib32/libc-2.7.so
f7f17000-f7f1a000 rw-p f7f17000 00:00 0
f7f2a000-f7f2b000 rw-p f7f2a000 00:00 0
f7f2b000-f7f2c000 r-xp 00000000 08:06 21915273                           /local/root/c/ch7/lib.so
f7f2c000-f7f2d000 rw-p 00000000 08:06 21915273                           /local/root/c/ch7/lib.so
f7f2d000-f7f30000 rw-p f7f2d000 00:00 0
f7f30000-f7f4d000 r-xp 00000000 08:01 504031                             /lib32/ld-2.7.so
f7f4d000-f7f4f000 rw-p 0001c000 08:01 504031                             /lib32/ld-2.7.so
ffca8000-ffcbd000 rw-p 7ffffffea000 00:00 0                              [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0                                  [vdso]

[serverate: /local/root/c/ch7 ]
>> ./p2 &
[1]     24575

[serverate: /local/root/c/ch7 ]
>> cd /proc/24575
[serverate: /proc/24575 ]
>> cat maps
08048000-08049000 r-xp 00000000 08:06 21915277                           /local/root/c/ch7/p2
08049000-0804a000 rw-p 00000000 08:06 21915277                           /local/root/c/ch7/p2
f7e11000-f7e12000 rw-p f7e11000 00:00 0
f7e12000-f7f5b000 r-xp 00000000 08:01 504034                             /lib32/libc-2.7.so
f7f5b000-f7f5c000 r--p 00149000 08:01 504034                             /lib32/libc-2.7.so
f7f5c000-f7f5e000 rw-p 0014a000 08:01 504034                             /lib32/libc-2.7.so
f7f5e000-f7f61000 rw-p f7f5e000 00:00 0
f7f71000-f7f72000 rw-p f7f71000 00:00 0
f7f72000-f7f73000 r-xp 00000000 08:06 21915273                           /local/root/c/ch7/lib.so
f7f73000-f7f74000 rw-p 00000000 08:06 21915273                           /local/root/c/ch7/lib.so
f7f74000-f7f77000 rw-p f7f74000 00:00 0
f7f77000-f7f94000 r-xp 00000000 08:01 504031                             /lib32/ld-2.7.so
f7f94000-f7f96000 rw-p 0001c000 08:01 504031                             /lib32/ld-2.7.so
ffed1000-ffee6000 rw-p 7ffffffea000 00:00 0                              [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0                                  [vdso]


test 2:
[serverate: /local/root/c/ch7 ]
>> gcc -fPIC -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p1 p1.c ./lib.so
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p2 p2.c ./lib.so
2. PIC

>> cat pic.c
static int a;
extern int b;
extern void ext();

void bar()
{
        a = 1;
        b = 2;
}

void foo()
{
        bar();
        ext();
}

[serverate: /local/root/c/ch7 ]
>> gcc -m32 -fPIC -shared -o pic.so pic.c
[serverate: /local/root/c/ch7 ]
>> objdump -d pic.so

pic.so:     file format elf32-i386

Disassembly of section .init:

000002dc <_init>:
 2dc:   55                      push   %ebp
 2dd:   89 e5                   mov    %esp,%ebp
 2df:   53                      push   %ebx
 2e0:   83 ec 04                sub    $0x4,%esp
 2e3:   e8 00 00 00 00          call   2e8 <_init+0xc>
 2e8:   5b                      pop    %ebx
 2e9:   81 c3 b0 12 00 00       add    $0x12b0,%ebx
 2ef:   8b 93 f0 ff ff ff       mov    -0x10(%ebx),%edx
 2f5:   85 d2                   test   %edx,%edx
 2f7:   74 05                   je     2fe <_init+0x22>
 2f9:   e8 2e 00 00 00          call   32c <__gmon_start__@plt>
 2fe:   e8 cd 00 00 00          call   3d0 <frame_dummy>
 303:   e8 58 01 00 00          call   460 <__do_global_ctors_aux>
 308:   58                      pop    %eax
 309:   5b                      pop    %ebx
 30a:   c9                      leave
 30b:   c3                      ret
Disassembly of section .plt:

0000030c <bar@plt-0x10>:
 30c:   ff b3 04 00 00 00       pushl  0x4(%ebx)
 312:   ff a3 08 00 00 00       jmp    *0x8(%ebx)
 318:   00 00                   add    %al,(%eax)
        ...

0000031c <bar@plt>:
 31c:   ff a3 0c 00 00 00       jmp    *0xc(%ebx)
 322:   68 00 00 00 00          push   $0x0
 327:   e9 e0 ff ff ff          jmp    30c <_init+0x30>

0000032c <__gmon_start__@plt>:
 32c:   ff a3 10 00 00 00       jmp    *0x10(%ebx)
 332:   68 08 00 00 00          push   $0x8
 337:   e9 d0 ff ff ff          jmp    30c <_init+0x30>

0000033c <_Jv_RegisterClasses@plt>:
 33c:   ff a3 14 00 00 00       jmp    *0x14(%ebx)
 342:   68 10 00 00 00          push   $0x10
 347:   e9 c0 ff ff ff          jmp    30c <_init+0x30>

0000034c <ext@plt>:
 34c:   ff a3 18 00 00 00       jmp    *0x18(%ebx)
 352:   68 18 00 00 00          push   $0x18
 357:   e9 b0 ff ff ff          jmp    30c <_init+0x30>

0000035c <__cxa_finalize@plt>:
 35c:   ff a3 1c 00 00 00       jmp    *0x1c(%ebx)
 362:   68 20 00 00 00          push   $0x20
 367:   e9 a0 ff ff ff          jmp    30c <_init+0x30>
Disassembly of section .text:

00000370 <__do_global_dtors_aux>:
 370:   55                      push   %ebp
 371:   89 e5                   mov    %esp,%ebp
 373:   53                      push   %ebx
 374:   e8 91 00 00 00          call   40a <__i686.get_pc_thunk.bx>
 379:   81 c3 1f 12 00 00       add    $0x121f,%ebx
 37f:   83 ec 04                sub    $0x4,%esp
 382:   80 bb 28 00 00 00 00    cmpb   $0x0,0x28(%ebx)
 389:   75 38                   jne    3c3 <__do_global_dtors_aux+0x53>
 38b:   8b 83 fc ff ff ff       mov    -0x4(%ebx),%eax
 391:   85 c0                   test   %eax,%eax
 393:   74 1b                   je     3b0 <__do_global_dtors_aux+0x40>
 395:   8b 83 20 00 00 00       mov    0x20(%ebx),%eax
 39b:   89 04 24                mov    %eax,(%esp)
 39e:   e8 b9 ff ff ff          call   35c <__cxa_finalize@plt>
 3a3:   eb 0b                   jmp    3b0 <__do_global_dtors_aux+0x40>
 3a5:   83 c0 04                add    $0x4,%eax
 3a8:   89 83 24 00 00 00       mov    %eax,0x24(%ebx)
 3ae:   ff d2                   call   *%edx
 3b0:   8b 83 24 00 00 00       mov    0x24(%ebx),%eax
 3b6:   8b 10                   mov    (%eax),%edx
 3b8:   85 d2                   test   %edx,%edx
 3ba:   75 e9                   jne    3a5 <__do_global_dtors_aux+0x35>
 3bc:   c6 83 28 00 00 00 01    movb   $0x1,0x28(%ebx)
 3c3:   83 c4 04                add    $0x4,%esp
 3c6:   5b                      pop    %ebx
 3c7:   c9                      leave
 3c8:   c3                      ret
 3c9:   8d b4 26 00 00 00 00    lea    0x0(%esi),%esi

000003d0 <frame_dummy>:
 3d0:   55                      push   %ebp
 3d1:   89 e5                   mov    %esp,%ebp
 3d3:   53                      push   %ebx
 3d4:   e8 31 00 00 00          call   40a <__i686.get_pc_thunk.bx>
 3d9:   81 c3 bf 11 00 00       add    $0x11bf,%ebx
 3df:   83 ec 04                sub    $0x4,%esp
 3e2:   8b 8b 2c ff ff ff       mov    -0xd4(%ebx),%ecx
 3e8:   85 c9                   test   %ecx,%ecx
 3ea:   74 18                   je     404 <frame_dummy+0x34>
 3ec:   8b 93 f4 ff ff ff       mov    -0xc(%ebx),%edx
 3f2:   85 d2                   test   %edx,%edx
 3f4:   74 0e                   je     404 <frame_dummy+0x34>
 3f6:   8d 83 2c ff ff ff       lea    -0xd4(%ebx),%eax
 3fc:   89 04 24                mov    %eax,(%esp)
 3ff:   e8 38 ff ff ff          call   33c <_Jv_RegisterClasses@plt>
 404:   83 c4 04                add    $0x4,%esp
 407:   5b                      pop    %ebx
 408:   c9                      leave
 409:   c3                      ret

0000040a <__i686.get_pc_thunk.bx>:
 40a:   8b 1c 24                mov    (%esp),%ebx
 40d:   c3                      ret
 40e:   90                      nop
 40f:   90                      nop

00000410 <bar>:
 410:   55                      push   %ebp
 411:   89 e5                   mov    %esp,%ebp
 413:   e8 40 00 00 00          call   458 <__i686.get_pc_thunk.cx>
 418:   81 c1 80 11 00 00       add    $0x1180,%ecx
 41e:   c7 81 2c 00 00 00 01    movl   $0x1,0x2c(%ecx)
 425:   00 00 00
 428:   8b 81 f8 ff ff ff       mov    -0x8(%ecx),%eax
 42e:   c7 00 02 00 00 00       movl   $0x2,(%eax)
 434:   c9                      leave
 435:   c3                      ret

00000436 <foo>:
 436:   55                      push   %ebp
 437:   89 e5                   mov    %esp,%ebp
 439:   53                      push   %ebx
 43a:   83 ec 04                sub    $0x4,%esp
 43d:   e8 c8 ff ff ff          call   40a <__i686.get_pc_thunk.bx>
 442:   81 c3 56 11 00 00       add    $0x1156,%ebx
 448:   e8 cf fe ff ff          call   31c <bar@plt>
 44d:   e8 fa fe ff ff          call   34c <ext@plt>
 452:   83 c4 04                add    $0x4,%esp
 455:   5b                      pop    %ebx
 456:   c9                      leave
 457:   c3                      ret

00000458 <__i686.get_pc_thunk.cx>:
 458:   8b 0c 24                mov    (%esp),%ecx
 45b:   c3                      ret
 45c:   90                      nop
 45d:   90                      nop
 45e:   90                      nop
 45f:   90                      nop

00000460 <__do_global_ctors_aux>:
 460:   55                      push   %ebp
 461:   89 e5                   mov    %esp,%ebp
 463:   56                      push   %esi
 464:   53                      push   %ebx
 465:   e8 a0 ff ff ff          call   40a <__i686.get_pc_thunk.bx>
 46a:   81 c3 2e 11 00 00       add    $0x112e,%ebx
 470:   8d 83 20 ff ff ff       lea    -0xe0(%ebx),%eax
 476:   8d 70 fc                lea    -0x4(%eax),%esi
 479:   8b 40 fc                mov    -0x4(%eax),%eax
 47c:   eb 09                   jmp    487 <__do_global_ctors_aux+0x27>
 47e:   66 90                   xchg   %ax,%ax
 480:   83 ee 04                sub    $0x4,%esi
 483:   ff d0                   call   *%eax
 485:   8b 06                   mov    (%esi),%eax
 487:   83 f8 ff                cmp    $0xffffffff,%eax
 48a:   75 f4                   jne    480 <__do_global_ctors_aux+0x20>
 48c:   5b                      pop    %ebx
 48d:   5e                      pop    %esi
 48e:   c9                      leave
 48f:   90                      nop
 490:   c3                      ret
 491:   90                      nop
 492:   90                      nop
 493:   90                      nop
Disassembly of section .fini:

00000494 <_fini>:
 494:   55                      push   %ebp
 495:   89 e5                   mov    %esp,%ebp
 497:   53                      push   %ebx
 498:   83 ec 04                sub    $0x4,%esp
 49b:   e8 00 00 00 00          call   4a0 <_fini+0xc>
 4a0:   5b                      pop    %ebx
 4a1:   81 c3 f8 10 00 00       add    $0x10f8,%ebx
 4a7:   e8 c4 fe ff ff          call   370 <__do_global_dtors_aux>
 4ac:   59                      pop    %ecx
 4ad:   5b                      pop    %ebx
 4ae:   c9                      leave
 4af:   c3                      ret

2.1 模块内部调用或跳转
call   31c <bar@plt>


2.2 模块内部数据访问
2.3 模块间数据访问
GOT: Global offset table
从下面可以看出,got的位置在00001588。

>> objdump -h pic.so

pic.so:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .hash         00000048  000000b4  000000b4  000000b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .dynsym       000000d0  000000fc  000000fc  000000fc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynstr       0000007b  000001cc  000001cc  000001cc  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.version  0000001a  00000248  00000248  00000248  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.version_r 00000020  00000264  00000264  00000264  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.dyn      00000030  00000284  00000284  00000284  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .rel.plt      00000028  000002b4  000002b4  000002b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .init         00000030  000002dc  000002dc  000002dc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .plt          00000060  0000030c  0000030c  0000030c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .text         00000124  00000370  00000370  00000370  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .fini         0000001c  00000494  00000494  00000494  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .eh_frame     00000004  000004b0  000004b0  000004b0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .ctors        00000008  000014b4  000014b4  000004b4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 13 .dtors        00000008  000014bc  000014bc  000004bc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .jcr          00000004  000014c4  000014c4  000004c4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .dynamic      000000c0  000014c8  000014c8  000004c8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .got          00000010  00001588  00001588  00000588  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .got.plt      00000020  00001598  00001598  00000598  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .data         00000008  000015b8  000015b8  000005b8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .bss          00000008  000015c0  000015c0  000005c0  2**2
                  ALLOC
 20 .comment      000000d2  00000000  00000000  000005c0  2**0
                  CONTENTS, READONLY
 21 .debug_aranges 00000050  00000000  00000000  00000698  2**3
                  CONTENTS, READONLY, DEBUGGING
 22 .debug_info   0000011c  00000000  00000000  000006e8  2**0
                  CONTENTS, READONLY, DEBUGGING
 23 .debug_abbrev 00000024  00000000  00000000  00000804  2**0
                  CONTENTS, READONLY, DEBUGGING
 24 .debug_line   00000104  00000000  00000000  00000828  2**0
                  CONTENTS, READONLY, DEBUGGING
 25 .debug_ranges 00000040  00000000  00000000  00000930  2**3
                  CONTENTS, READONLY, DEBUGGING

>> objdump -R pic.so

pic.so:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
000015b8 R_386_RELATIVE    *ABS*
000015bc R_386_RELATIVE    *ABS*
00001588 R_386_GLOB_DAT    __gmon_start__
0000158c R_386_GLOB_DAT    _Jv_RegisterClasses
00001590 R_386_GLOB_DAT    b
00001594 R_386_GLOB_DAT    __cxa_finalize
000015a4 R_386_JUMP_SLOT   bar
000015a8 R_386_JUMP_SLOT   __gmon_start__
000015ac R_386_JUMP_SLOT   _Jv_RegisterClasses
000015b0 R_386_JUMP_SLOT   ext
000015b4 R_386_JUMP_SLOT   __cxa_finalize

可以看出变量b的偏移是1590。
这和代码是对应的,

 428:   8b 81 f8 ff ff ff       mov    -0x8(%ecx),%eax
 42e:   c7 00 02 00 00 00       movl   $0x2,(%eax)

2.4 模块间调用和跳转
如何区分一个DSO是否为PIC

[serverate: /local/root/c/ch7 ]
>> gcc -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> readelf -d lib.so |grep TEXTREL
 0x00000016 (TEXTREL)                    0x0

有输出,则不是PIC。PIC的DSO不会有代码段重定位表地址。
PIE: Position-Independent Executable -fPIE


3. 共享模块的全局变量问题
Question: 如果一个共享对象lib.so中定义了一个全局变量G,而进程A和B都使用了lib.so,那么当进程A改变这个全局变量G的值的时,进程B中G会受到影响么?
不会,因为当lib.so被两个进程加载时,它的数据段部分在每个进程中都有独立的副本,从这个角度看,共享对象中的全局变量实际上和定义在程序内部的全局变量没什么区别。如果是同一个进程中的2个线程,则会看到对方对全局变量的修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值