Chapter 7 Linker -- How Linkers Resolve Multiply-Defined Global Symbols

来源:互联网 发布:修复软件下载 编辑:程序博客网 时间:2024/05/22 04:38

At compile time, the compiler exports each global symbol to the assembler as either strong or weak, and the
assembler encodes this information implicitly in the symbol table of the relocatable object file.

编译的时候,symbol会被划分成 strong 和 weak两种。

Functions and initialized global variables get strong symbols.

Uninitialized global variables get weak symbols.

For the example program in Figure 7.1, buf, bufp0, main, and swap are strong symbols; bufp1 is a weak
symbol.

symbol resolution的规则。
Given this notion of strong and weak symbols, Unix linkers use the following rules for dealing withmultiplydefined
symbols:
 Rule 1: Multiple strong symbols are not allowed.
 Rule 2: Given a strong symbol and multiple weak symbols, choose the strong symbol.
 Rule 3: Given multiple weak symbols, choose any of the weak symbols.

 

一个比较小的,但严重的错误

 

The application of Rules 2 and 3 can introduce some insidious run-time bugs that are incomprehensible to
the unwary programmer, especially if the duplicate symbol definitions have different types. Consider the
following example, where x is defined as an int in one module and a double in another:
1 /* foo5.c */
2 #include <stdio.h>
3 void f(void);
4
5 int x = 15213;
6 int y = 15212;
7
8 int main()
9 {
10 f();
11 printf("x = 0x%x y = 0x%x /n",
12 x, y);
13 return 0;
14 }

 

1 /* bar5.c */
2 double x;
3
4 void f()
5 {
6 x = -0.0;
7 }
On an IA32/Linux machine, doubles are 8 bytes and ints are 4 bytes. Thus, the assignment x = -0.0
in line 5 of bar5.c will overwrite the memory locations for x and y (lines 5 and 6 in foo5.c) with the
double-precision floating-point representation of negative one!

linux> gcc -o foobar5 foo5.c bar5.c
linux> ./foobar5
x = 0x0 y = 0x80000000

 

用gcc的选项来 提示多出定义。

When in doubt, invoke
the linker with a flag such as the GCC -warn-common flag, which instructs it to print a warning message
when it resolves multiply-defined global symbol definitions.