2.2 Export Control
When creating a DSO from a collection of object files the dynamic symbol table will by default contain all the symbols which are globally visible in the object files. In most cases this set is far too large. Only the symbols which are actually part of the ABI should be exported. Failing to restrict the set of exported symbols are numerous drawbacks:
当链接器链接多个文件生成一个DSO的时候会默认包含所有的全局变量语法内容。大多数情况下会很大。只有实际的ABI需要导出。没有限制导出语法内容的大小是一个缺点:
• Users of the DSO could use interfaces which they are not supposed to. This is problematic in revisions of the DSO which are meant to be binary compatible. The correct assumption of the DSO developer is that interfaces, which are not part of the ABI, can be changed arbitrarily. But there are always users who claim to know better or do not care about rules.
用户会使用不支持的接口。这在升级版本保持兼容时是一个很大的问题。一般假设开发者使用接口,不是ABI的可能会改变。但是总是有用户不关注或者想了解更多,活着不关心这些使用规则。
• According to the ELF lookup rules all symbols in the dynamic symbol table can be interposed (un- less the visibility of the symbol is restricted). I.e., definitions from other objects can be used. This means that local references cannot be bound at link time. If it is known or intended that the local defi- nition should always be used the symbol in the ref- erence must not be exported or the visibility must be restricted.
根据ELF查找规则所有其他对象定义的动态语法都会插入到表格。这意味着本地引用是没有边界的。如果知道或者倾向于使用本地定义导出符号或者可见性必须有限制。
• The dynamic symbol table and its string table are available at run-time and therefore must be loaded. This can require a significant amount of memory, even though it is read-only. One might think that the size is not much of an issue but if one examines the length of the mangled names of C++ variables or functions, it becomes obvious that this is not the case. In addition we have the run-time costs of larger symbol tables which we discussed in the previous section.
动态语法表和字符表运行时可用必须加载。这要求很大的内存空间,即使是只读内容。可能认为这个不会占用很多,但是如果检查一次c++内容会发现明显很大。运行时查找大表耗时。
We will now present a number of possible solutions for the problem of exported interfaces. Some of them solve the same problem in slightly different ways. We will say which method should be preferred. The programmer has to make sure that whatever is used is available on the tar- get system.
下面提供几种方法处理这个问题。一些处理相同的问题只有少许不同。会分析那种更好。开发者决定使用那种方式结果该问题。
In the discussions of the various methods we will use one example:
讨论中使用变量和方法如下:
int last;
int next (void) {
return ++last;
}
int index (int scale) {
return next () << scale;
}
Compiled on a IA-32 Linux machine a DSO with only this code (plus startup code etc) contains seven reloca- tions, two of which are relative, and four PLT entries (use the relinfo script). We will see how we can improve on this. Four of the normal and both relative relocations as well as three PLT entries are introduced by the additional code used by the linker to create the DSO. The actual ex- ample code creates only one normal relocation for last and one PLT entry for next. To increment and read the variable last in next the compiler generates code like
编译IA-32系统DSO只有7个重定位,两个重定位,4个PLT。我们会分析如何提高。4个普通和两个重定位、3个PLT有介绍如下。(待完善)。实际代码创建一个普通重定位和一个PLT用于next。next中增加和读取last编译结果如下:
movl last@GOT(%ebx), %edx
movl (%edx), %eax
incl %eax
movl %eax, (%edx)
and the call of next is compiled to
调用如下:
call next@PLT
These code fragments were explained in section 1.5.5.
代码在1.5.5展开。