7

这似乎是每个人都在谈论但没有人定义的事情之一……我似乎找不到关于这个话题的任何信息。什么是符号解析?这是我发现的最好的东西:http: //docs.oracle.com/cd/E23824_01/html/819-0690/chapter2-90421.html#chapter2-93321

它与您的程序的编译方式有关吗?

4

3 回答 3

10

好吧,既然您提到了 Unix 的 nm,我可以确定符号分辨率。

可执行文件可以引用未在其内部定义的实体。例如,共享库上的变量或过程。这些实体由外部符号标识。可执行文件也可能具有可以被外部文件引用的内部符号——当然库也是如此。

在这种情况下,符号解析是,一旦程序被加载到内存中,就为它所引用的所有外部实体分配适当的地址。这意味着更改加载程序中引用外部符号的每个位置。

这些地址将取决于在内存中加载外部符号的代码的位置。

在 Unix 中,程序的默认编译模式是使用系统共享库,而不是预先链接可执行文件中所需的所有内容。gcc例如,在使用 编译程序时,-static如果希望静态编译,则传递标志,而不是具有未解析的符号引用。

查找“共享库”以获取更多信息。

于 2009-07-24T02:33:07.107 回答
2

如前所述,它可以指运行时或链接时符号解析。但是,您不应该忘记编译时符号解析

这是语言用来将符号映射到“事物”的规则。符号几乎是任何看起来像名称的东西(本地、成员和全局变量、函数、方法、类型等),而“事物”是编译器对名称所指含义的理解。

执行此操作的规则可以相当简单(例如,C 中的 IIRC,它只不过是要查看的有序列表)或复杂(C++ 有各种情况,包括重载、模板等等)。通常,这些规则与程序的语义交互,有时它们甚至会导致(潜在的)歧义:

C++:

int First(int i) { return i; }
float First(float f) { return f; }

void Second(int (*fn)(int)) { printf("int"); }
void Second(float (*fn)(float); { printf("float"); }

...

Second(&First); // What will be printed?
于 2009-07-24T15:44:18.710 回答
1

我不确定您在什么上下文中表示符号解析。但它让我想起了 dlopen(3) 和 dlsym(3) 用于共享库中的运行时符号解析。

于 2009-07-24T02:34:31.190 回答