[第一篇_献给AIX][关于库加载以及符号文件的问题]

来源:互联网 发布:yii源码分析 编辑:程序博客网 时间:2024/05/17 01:48

 

 

【问题出现】

在APUE的Figure11.2时,cc fig11.2.c后,出现下面错误信息:

ld:0711-317 ERROR:Undefined symbol: .pthread_create

ld:0711-317 ERROR:Undefined symbol: .pthread_self

【尝试1】

根据提示信息,写cc fig11.2.c -bloadmap:Check.out

在Check.out有如下信息

 

The following symbols are in error:
 Symbol                    Inpndx  TY CL Source-File(Object-File) OR Import-File{Shared-object}
                              RLD: Address  Section  Rld-type Referencing Symbol
 ---------------------------------------------------------------------------------------------- 
.pthread_self                  [42]   ER PR fig11.2.c(fig11.2.o)
                                   00000024 .text  R_RBR    [12]  .printids

.pthread_create         [46]   ER PR fig11.2.c(fig11.2.o) 
                                   000000a4 .text    R_RBR  [14]   .main
说明还是c文件中定义的一些符号找不到。是连接时候出现的问题,不是编译时,说明头文件(pthread.h)加入没有问题。

 

尝试自己写SymbolScript:

#!

.pthread_self

.pthread_create

然后运行:

ld fig11.2.o /usr/lib/crt0.o -lc -bI:SymbolScript

(注:

cc自动加入/usr/lib/crt0.o,与线程初始化有关,定义__start 符号,__start is default entry point of executable file.

在ld需要显式加入;

另,-lc 标明load libc.a,在cc中为默认)

连接通过,

但是运行时出现segmentation fault,尝试失败

 

【尝试2】

//感谢Prayer同志

进入/usr/lib

#ls|grep pthread

看到第一个libpthread.a

(事实上/usr/lib/libpthread.a->/usr/lib/libpthreads.a->/usr/ccs/lib/libpthreads.a)

#nm libpthread.a|grep .pthread_create

看到第一行

.pthread_create T 54680

(注:

T 表示Global text symbol

A: Global absolute symbol

a: Local absolute symbol

B: Global bss symbol

b: local bss symbol

D: Global data symbol

d: Local data symbol

f: source file name symbol

L: global thread-local symbol

l: Static thread-local symbol

t: Local text symbol

U: undefined symbol)

找到了该符号

回到家目录

#cc fig11.2.o /usr/lib/libpthread.a

连接成功,

运行成功。

 

【问题】

export LIBPATH=/usr/lib:/usr/ccs/lib:/lib 后,

系统仍然找不到.pthread_create符号,明明该库就是放在LIBPATH的路径里的啊

【摘录】

1. PowerPC上ELF可执行文件的符号解析

http://www.ibm.com/developerworks/cn/linux/l-elfpw/index1.html

符号解析是Linux系统导入二进制可执行文件的重要过程,它完成的工作包括将一个符号定位到实际的内存地址,并且要保证可以正确引用这些符号。按解析对象的不同它可以分为变量符号解析和函数符号解析;按解析方式的不同可以分为静态解析和动态解析。

 

对于静态解析的符号,它们的地址在文件生成时就由link editor(在Linux下通常是ld)已经确定下来了;对于动态解析的符号,他们的地址在程序运行时才由dynamic linker(动态链接器,32位Linux平台下通常是/lib/ld.so.1)确定下来。我们可以这么认为,如果一个符号在共享库中定义,那么当其他可执行文件或共享库引用这个符号时,就需要对它作动态解析。

 

变量符号的动态解析过程比较简单,系统在载入程序过程中将变量symbol地址存入到GOT(Global Offset Table)中,引用变量symbol时首先计算出GOT表的实际地址,然后以它作为基址加上(变量symbol在GOT表中的偏移量)就可以从GOT表中取得该symbol的实际地址。 

 

【参考】

ld manual

http://www.blogjava.net/davidgw/archive/2009/01/21/252230.html

http://www.cppblog.com/prayer/archive/2008/12/31/70847.html

 

 

 

原创粉丝点击