关于共享库

上一篇 / 下一篇  2008-01-22 11:24:11 / 个人分类:Linux下C语言

x7Ul_U0共享库的工作方式分为三步:Linux宝库"c;BGD Q3L

_8NH8xtF@Y$`jy0

 link时,linker搜索整个库以找到用于解决那些未定义的外部符号模块
 linker标记模块来自的库名,在可执行体中放一个库的列表
 load时,启动代码找到这些库,并在程序开始前把它们映射到程序地址空间
Linux宝库t:?+F?;a[ ]` T

Linux宝库z?!z^&s2w

启动代码可以放在:1、OS中  2、可执行体中   3、动态链接器中

1E{m%b*@K K$Z0Linux宝库Cu}+?.Ic6s

在第二步中,库列表的建立如下表所示:

4S$|3^!_/d#V(^ e'p#@_0Linux宝库g nz4k9uY s

 COFFlinker在该文件中创建了一个以库名命名的段 
Linux宝库'iaV9v:B)m$\"~'O

 LINUX

m N6ok0F3d j0Linux宝库LV;w:|7S`

LINKER

hs^k \3_1AKmO0

q AX'|N3L9Y1I2TC0 通过设置向量(它向一个全局符号)

a)S4^,^6[ N ``v0

x'\/S\5{0?3~.O)q+w0每个共享库定义一个设置向量符号(一般由库名、版本、加载地址组成)Linux宝库(eM%@-CUm~;g3q/rH

bk1ySK#] V C0linker创建一个指向每个这种数据结构指针的数组让启动代码用Linux宝库$y$vDn'Q'kmG!P)M

 BSD/OS使用shell脚本完成 
Linux宝库Q\-os^

Linux宝库2{2|+m`$W6|"yI

而在第三步的映射中,每个系统的处理也不同:Linux宝库^i}n9o*Al&I

Linux宝库(}Z)mT9k"}

 LINUX增加了一个uselib()系统调用(它完成获取一个库的名字和地址,并将其映射到程序地址空间)。而启动代码(例程)搜索库列表,并对每一项执行uselib() 
 BSD/OS使用mmap()系统调用将一个文件的多个页映射进地址空间。启动例程会遍历库列表,打开每个对应文件,并将文件的第一页映射到加载地址,然后再调用各自的自举例程。自举例程映射余下的文本段、数据段、bss段。 

!s'bnz&j5]O7},}0

j(sC:Cr a |c0共享库的结构一般如下:

\9{e1oa6dt0Linux宝库PNev}$| jE$L

 文件头:a.out/coff/elf头
 (初始化代码,不总是存在)
 调转表
 代码
全局数据
 私有数据
Linux宝库5uxB:GMP [6xP+]

Linux宝库7JNj?S,u

跳转指令表:作为一个中间层,它搜集了库中所有例程的地址,便于管理。

9k kq^9W*y.Y0Linux宝库P)]k LSz&S

这样在符号替换成地址的时候,将调转表的地址作为例程的相应地址,而不是例程的实际地址。因为调转指令大小相同,调转表的地址也就容易计算。

(\2jWO#X&x0Linux宝库F j'YB Jf

库代码的升级一般只修改代码段,而数据段一般不修改,这样的中间层就够就能保证原有代码不用改动,之用修改这个表即可。

+T n^@E0

C&{&^Jg f5aKZ)q0针对库例程代码有这么一个中间层,但针对数据就没有,所能做的是把固定数据长度,结构的数据搜集到数据段的开头(匿名数据前面),比如 FILE数据结构、errno、tzname。

c7Dn1f4M:_9F[6[0Linux宝库g,]N!nuP ?qba5]8s

注:在ELF头有一个nterp段,其中包含一个运行该文件时所需使用的解释器程序名字。比如BSD使用C库作为解释器,那么程序启动前内核会将共享C库先映射进来Linux宝库+^~L5hz(X7e

,^r7v*_]$E0空占位库:绑定到应用程序,用于库之间的引用???

*mv(ap6o"g+b"m(@0
  • 它从共享库中提取需要的符号,针对输入库的符号调整这些符号
  • 库中的每一例程<--->空占位库中包含一个同时定义了输出和输入的全局符号的对应项
  • 空占位库只包含符号的定义(绝对数而非相对数),即:
  •  跳转表中每一项地址每个文本全局变量 
     共享库中的实际地址每个数据或bss全局变量 
     未定义没有定义的全局变量 

)llZ.B}2e0那么启动一个共享库一般分为三个步骤:

Z9f/?Q1Bf-Y&am0
  1. 加载可执行代码
  2. 映射库
  3. 执行库特定初始化代码

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

数据统计

  • 访问量: 19962
  • 日志数: 31
  • 建立时间: 2007-10-21
  • 更新时间: 2008-02-19

RSS订阅

Open Toolbar