关于静态链接,动态链接,共享库,ABI的一些记录(os学习)
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 Inte易做图ce
应用程序与二进制程序中调用的标准:
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,如做除法,_udiv,求余_umode等。也是可以在libgcc库文件中找到的。如果你在ld时,missing such symbols,记住在ld时,link with libgcc.
补充:移动开发 , IOS ,