程序编译链接运行时对库关系的探讨Word文件下载.docx
- 文档编号:17509944
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:6
- 大小:18.62KB
程序编译链接运行时对库关系的探讨Word文件下载.docx
《程序编译链接运行时对库关系的探讨Word文件下载.docx》由会员分享,可在线阅读,更多相关《程序编译链接运行时对库关系的探讨Word文件下载.docx(6页珍藏版)》请在冰豆网上搜索。
至于生成的可执行文件test用哪个ld-linux.so.2由gcc的spec规定,存在于test程序头的PT_INTERP类型的段(segment)中,与ld无关。
第三步,主角是ld-linux.so.2,test要载入内存来运行,需由这个ld-linux.so.2载入必须的共享库,而它搜索库的路径跟上面ld的搜索路径相关的地方就是gcctest.c./say.so-otest中say.so前面的./会硬编码进test中的动态节(.dynamicsection)的DT_NEEDED类型入口中,然而当ld在其他路径信息找到了say.so,却不会把路径信息硬编码进DT_NEED入口。
然后就是ld-linux.so.2搜索库的顺序
1DT_NEED入口中包含的路径
2DT_RPATH入口给出的路径(存在的话)
3环境变量LD_LIBRARY_PATH路径(setuid类的程序排除)
4LD_RUNPATH入口给出的路径(存在的话)
5.库高速缓存文件ld.so.conf中给出的路径
6./lib,/usr/lib
7当前目录
补充:
2test中的DT_RPATH由什么传递进来,我不清楚。
3对于setuid类程序,忽略;
链接时有—library-pathPATH选项时会被override
4同2,这两处路径,当有链接选项--ignore-rpathLIST时会把LIST中的RPATH和RUNPATH信息忽略掉。
5中ld-linux.so.2找的ld.so.conf则在生成glibc库时的--prefix/etc目录下,ld-linux.so.2其实是找搜索ld.so.cache,由ldconfig生成。
6当链接时加入了-znodeflib选项,此处路径信息被忽略
第二步中ld找到了say.so,而ld-linux.so.2却找不到时,仅能得到test,却不能生成进程映象。
实验一:
Gcc&
fPIC&
sharedsay.c&
osay.so
Gcctest.c./say.so&
otest
Readelf&
dtest|less(这里的./到了NEEDED里面)
Mkdir1
Cpsay.so1/libsay.so
Rmtest
L/root/1&
lsaytest.c&
otest(能通过,ld找到了libsay.so)
Lddtest(libsay.so找不到)(ld-linux.so.2找不到libsay.so)
d|less(这里NEEDED里就是libsay.so,-L路径没有包括进来
LD_LIBRARY_PATH=/root/1lddtest(这样就找到了)
LIB_PATH=/root/1gcctest.clibsay.so&
otest(不能成功,找不到libsay.so)
ExportLIB_PATH=/root/1
Gcctest.clibsay.so&
otest(还是不能成功,因此似乎LIB_PATH只在编译ld时有用?
实验二:
Echo&
#8216;
voidmain(){}&
#8217;
&
hello.c
vhello.c(出现/usr/lib/gcc/i486-linux-gnu/4.0.4/collect2--eh-frame-hdr-melf_i386-dynamic-linker/lib/ld-linux.so.2/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crt1.o/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crti.o/usr/lib/gcc/i486-linux-gnu/4.0.4/crtbegin.o-L/usr/lib/gcc/i486-linux-gnu/4.0.4-L/usr/lib/gcc/i486-linux-gnu/4.0.4-L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib-L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../..-L/lib/../lib-L/usr/lib/../lib/tmp/ccoNhv8l.o-lgcc--as-needed-lgcc_s--no-as-needed-lc-lgcc--as-needed-lgcc_s--no-as-needed/usr/lib/gcc/i486-linux-gnu/4.0.4/crtend.o/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crtn.oPerl&
pi&
e&
s@/lib/ld-linux.so.2@/lib/ld-linux.so.bak@g&
$(gcc&
print-filespecs)(把gcc的spec中的linux-ld.so.2改名)
vhello.c(编译仍然能够通过,就是上面信息中ld-linux.so.2变成ld-linux.so.2.bak)
./a.out (这是提出ld-linux.so.2.bak不存在,不是合法的程序解释器了)
Rma.out
v&
statichello.c(编译通过,)
./a.out(也能运行,哈哈)
至此能证实ld-linux.so.2在通常的默认的gcc编译时,是动态链接的,上面-v输出的信息中,其实ld并没有真正调用ld-linux.so.2,只是把gcc的spec中规定的动态连接器名称放入elf文件头中而已,真正调用ld-linux.so.2,要到程序载入阶段)确实如论坛上VirusCamp所言,这里应该就是仅仅写入路径信息到elf文件头中)现在可以确定了ld-linux.so.2在编译成可执行文件时,是不需要存在的,
现在的问题是ld搜索库的路径和顺序了,在manld中找到了这么一段
Thelinkerusesthefollowingsearchpathstolocaterequired
sharedlibraries.
1.Anydirectoriesspecifiedby-rpath-linkoptions.2.Anydirectoriesspecifiedby-rpathoptions.Thedifference
between-rpathand-rpath-linkisthatdirectoriesspecifiedby-rpathoptionsareincludedintheexecutableandusedatrun-time,whereasthe-rpath-linkoptionisonlyeffectiveatlinktime.Itisforthenativelinkeronly.3.OnanELFsystem,ifthe-rpathand"
rpath-link"
optionswere
notused,searchthecontentsoftheenvironmentvariable"
LD_RUN_PATH"
.Itisforthenativelinkeronly.4.OnSunOS,ifthe-rpathoptionwasnotused,searchanydirectoriesspecifiedusing-Loptions.
5.Foranativelinker,thecontentsoftheenvironmentvariable"
LD_LIBRARY_PATH"
.6.ForanativeELFlinker,thedirectoriesin"
DT_RUNPATH"
or
"
DT_RPATH"
ofasharedlibraryaresearchedforsharedlibrariesneededbyit.The"
entriesareignoredif"
entriesexist.7.Thedefaultdirectories,normally/liband/usr/lib.8.ForanativelinkeronanELFsystem,ifthefile/etc/ld.so.confexists,thelistofdirectoriesfoundinthatfile.Iftherequiredsharedlibraryisnotfound,thelinkerwillissueawarningandcontinuewiththelink.
另外还有:
-Rfilename
--just-symbols=filename
Readsymbolnamesandtheiraddressesfromfilename,butdonotrelocateitorincludeitintheoutput.Thisallowsyouroutputfiletorefersymbolicallytoabsolutelocationsofmemorydefinedinotherprograms.Youmayusethisoptionmorethanonce.
ForcompatibilitywithotherELFlinkers,ifthe-Roptionisfollowedbyadirectoryname,ratherthanafilename,itistreatedasthe&
rpathoption.
关于-LDIR,我以前的理解有很多错误的地方,看:
-Lsearchdir
--library-path=searchdir
Addpathsearchdirtothelistofpathsthatldwillsearchfor
archivelibrariesandldcontrolscripts.Youmayusethisoptionanynumberoftimes.Thedirectoriesaresearchedintheorderinwhichtheyarespecifiedonthecommandline.Directoriesspecifiedonthecommandlinearesearchedbeforethedefaultdirectories.All-Loptionsapplytoall-loptions,regardlessoftheorderinwhichtheoptionsappear.Ifsearchdirbeginswith"
="
thenthe"
willbereplacedbythesysrootprefix,apathspecifiedwhenthelinkerisconfigured.Thedefaultsetofpathssearched(withoutbeingspecifiedwith-L)dependsonwhichemulationmodeldisusing,andinsomecasesalsoonhowitwasconfigured.Thepathscanalsobespecifiedinalinkscriptwiththe"
SEARCH_DIR"
command.Directoriesspecifiedthiswayaresearched
atthepointinwhichthelinkerscriptappearsinthecommand
line.
这里才明白这个-LDIR对ld的真正作用
在google搜索了ldLIB_PATH,别人的讨论中,有这么段话,
FromtheREADME:
Ifyouwanttomakeacross-linker,youmaywanttospecify
adifferentsearchpathof-lfoolibrariesthanthedefault.
YoucandothisbysettingtheLIB_PATHvariablein./Makefile.Tobuildjustthelinker,makethetargetall-ldfromthetoplevel
directory(onedirectoryabovethisone).
那么意思好像是只有当要建立一个交叉编译的ld时,才在建立ld的Makefile中设置变量LIB_PATH,它不是一个环境变量,仅仅是能够设在Makefile或
那么还有configure的&
with-lib-path参数,在构建binutils时仅仅告诉configure脚本在这个路径下找库,那么也就是说跟在生成的Makefile中定义变量LIB_PATH意义一样?
Gcc用的哪个ld?
,可以gcc&
printf-prog-name=ld但怎么指定gcc用哪个ld了?
Good2xaut开的帖子,讨论说了,先用gcc本身体系中的的ld,然后在到环境变量PATH中找到http:
//gcc.gnu.org,下面gcc.pdf
-BprefixThisoptionspecifieswheretofindtheexecutables,libraries,includefiles,and
datafilesofthecompileritself.
Gcc相当于是个司机,驱使其他子程序完成任务,cpp,&
cpp&
&
cc1&
&
as&
and&
ld&
,在要运行的每个子程序前加上prefix,带上或者不带上/machine/version,对每个子程序,先试-Bprefix,没找到,或没有B选项,就用标准前缀&
/usr/lib/gcc/&
/usr/local/lib/gcc/&
.
还没找到,就在环境变量PATH下面找
转化成-L选项传给linker,-isystem选项给预处理器preprocessor加上include(搜索头文件的目录)
运行时库libgcc.a,也通过这个选项,还有上面两个标准路径下找
另一种跟B选项相似作用的的方法为,环境变量GCC_EXEC_PREFIX,默认的&
prefix/lib/gcc/,prefix为configure脚本传递过来的,-B选项的prefix优先
--sysroot=dir
在前面搜索头文件和库的路径前都加上dir
COMPILER_PATH,跟PATH类似的,在GCC_EXEC_PREFIX下找不到子程序时在这个list下面找
LIBRARY_PATH对于本地编译器,用来找一些特别的连接器文件,在gccint.pdf中有:
Theprogramcollect2isinstalledasldinthedirectorywherethepassesofthecompiler
areinstalled.Whencollect2needstofindtherealld,ittriesthefollowingfilenames:
&
#8226;
real-ld&
inthedirectorieslistedinthecompiler&
ssearchdirectories.
inthedirectorieslistedintheenvironmentvariablePATH.
ThefilespecifiedintheREAL_LD_FILE_NAMEconfigurationmacro,ifspecified.
inthecompiler&
ssearchdirectories,exceptthatcollect2willnotexecuteitself
recursively.
inPATH
#8220;
Thecompiler&
ssearchdirectories&
#8221;
meansallthedirectorieswheregccsearchesforpasses
ofthecompiler.Thisincludesdirectoriesthatyouspecifywith&
-B&
Cross-compilerssearchalittledifferently:
target-real-ld&
inPATH.
target-ld&
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序 编译 链接 运行 关系 探讨