深入理解计算机系统 学习笔记(6)

Hello world,hello blog!

Posted by 吴柚 on April 28, 2019

链接

  1. 符号解析:

原则是:编译器只允许每个模块中每个本地符号只有一个定义。而且对全局的符号的解析很棘手,因为多个目标文件可能会定义相同的符号。C++和Java使用mangling手段来支持重载。

  1. 根据Unix连接器使用下面的规则来处理多重定义的符号:
  • 规则1:不允许有多个强符号。

  • 规则2:如果有一个强符号和多个弱符号,那么选择强符号

  • 规则3:如果有多个弱符号,那么从这些弱符号中任意选择一个

  1. 静态库

事先写好的一些可重定位的目标文件打包成一个单独的文件,它可以用作连接器的输入。当连接器构造一个输出的可执行文件时,它只拷贝静态库里被应用程序引用的目标模块

在Unix系统中,静态库以一种成为存档(archive)的特殊文件格式存放在磁盘中。存档文件是一组连接起来的可重定位目标文件的集合。有一个头部用来描述每个成员目标文件的大小和位置。存档文件的后缀是.a标识。是否可以这么理解.a文件的结构呢?

下面用展示一个静态库连接的过程:

  1. 从应用程序中加载和链接共享库

应用程序还可能从应用程序中加载和链接任意共享库,而无需编译时链接那些库到应用中

Windows中的更新大部分是这个技术。另外还有构建高性能web服务器。

Linux为动态链接器提供了一系列简单的接口:

#include <dlfcn.h>
void *dlopen(const char *filename, int flag);//加载共享库
void *dlsym(void *handle, char *symbol);    //指向一个共享库的句柄和一个符号名字。
int dlclose(void *handle);  //下载共享库
const char *dlerror(void);  //容错