欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

关于静态链接,动态链接,共享库,ABI的一些记录(os学习)

程序员文章站 2024-02-03 09:48:52
static linking 在ld时,如果找到了obj文件中存在的reference,就会到libary中去把这个reference的binary code 添加到你的程序中去...

static linking
在ld时,如果找到了obj文件中存在的reference,就会到libary中去把这个reference的binary code 添加到你的程序中去。
经过了静态链接的程序,是一个真正完整的可运行的程序,运行的时候不需要其它的东东,只需要os的kernel调用这个code就行了
静态链接中,最重要的一点:把libary中的binary 程序 添加到我们调用库函数的程序中去了。

dynamic linking
动态链接时,在ld时,如果我们写的code中调用了库中的代码,这里不会把库中的binary code直接添加我们的code中去,而是保留这个reference,在程序加载运行时,注意是在我们的code运行时,程序中保留的那个reference就会被链接程序链接到到libary中执行。动态链接的好处就是可以使on disk 程序非常的小,节约和了memory,动态链接的结果就是(shared libray),动态链接的程序是要依赖于包含reference的libary。在os中如果没有包含这个reference的库文件,我们写的程序就不能run了


shared libraries
共享的库
把很多可以独自运行的文件打包成一libary,这意味着我们不需要把libary里的binary文件添加到executable文件中,在executable中的reference在运行时来调整,这样所有execuable程序都可以到same memory中去找到libary binary。
这需要一些技巧,libary中的binary程序不能有任何的static变量,也不能有global变量,如果有static变量或是global变量,这个binary程序就要为每个调用他的程序提供一个单独的变量空间。这种技巧通常用在多线程的程序中,一个程序可能有多个控制流。

通过 库文件的位置在virtual memory中,也可能不是一定的,也就是说库文件的位置可能经常会变化,这就要求动态库文件在任何的位置都可以运行,就是生成的代码是与运行位置无关的。(这样的代码可以通过在gcc编译时,添加-pic(position independent code)选项得到)。这种位置无关的代码需要elf文件格式的支持,位置无关的代码的运行效率可能要低一点(这是需要付出的代价)

 abi - application binary interface
应用程序与二进制程序中调用的标准:
abi定义了 libary 中的函数是如何被调用,还有syscall是如何调用的。这个调用标准 包含了,参数保存在stack中还是 保存在register中,在libary中函数的入口点是放在哪里,还有其它的一些内容。
当用static linkage时,生成的可运行的程序 与kenel调用应用程序时 用的abi标准要一样。
当用dynamic linkage时,生成的可运行的程序,与libary 中使用的abi标准要保持一样。

unresolved symbols
 没有解决的符号(就是用dynamic linkage时程序中存在的reference,或是static linkage时找不到符号)

linker会运行的加入一些你不知道的reference .
如(   $(v)$(ld) -o $@ $(kern_ldflags) $(kern_objfiles) $(gcc_lib) -b binary $(kern_binfiles)   )
这些reference包含了alloca(),memset(),memcpy()还有其它的一些函数(在libgcc.a中)。
经常我们会由于没有正常的使用tool chain或是command line配置的有问题,而无法正常的编译出自己的os kernel。或是我们调用的一些函数在libary中没实现。在我们ld时没有用libgcc这个库文件时(包含memcpy memmove,memset,memcmp),通过会出错。


其它的一些symbols,如做除法,_up,求余_umode等。也是可以在libgcc库文件中找到的。如果你在ld时,missing such symbols,记住在ld时,link with libgcc.