这似乎是每个人都谈论但没有人定义的事情之一......我似乎无法找到关于这个主题的任何信息。什么是符号分辨率?这是我发现的最好的东西:http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter2-90421.html#chapter2-93321
它与程序的编译方式有关吗?
答案 0 :(得分:5)
好吧,既然你提到了Unix的nm,我可以精确定位符号分辨率。
可执行文件可以引用未在其自身内定义的实体。例如,共享库上的变量或过程。这些实体由外部符号标识。可执行文件也可能具有可由外部文件引用的内部符号 - 当然是库的情况。
在此上下文中,符号解析是,一旦程序被加载到内存中,就为其引用的所有外部实体分配适当的地址。这意味着更改已加载程序中的每个位置,其中引用了外部符号。
这些地址将取决于内存中加载了外部符号的代码的位置。
在Unix中,程序的默认编译模式是使用系统共享库,而不是预先链接可执行文件中所需的所有内容。例如,在使用gcc
编译程序时,如果希望对其进行静态编译,则传递-static
标志,而不是使用未解析的符号引用。
查找“共享库”以获取更多信息。
答案 1 :(得分:1)
我不确定你的意思是什么上下文符号解析。但它让我想起dlopen(3)和dlsym(3)在共享库中的运行时符号解析。
答案 2 :(得分:1)
如上所述,它可以指运行时或链接时符号解析。但是,您不应忘记编译时符号解析。
这是语言用于将符号映射到“事物”的规则。符号几乎是任何看起来像名称的东西(本地,成员和全局变量,函数,方法,类型等)和“事物”是编译器理解名称所指的内容。
执行此操作的规则可以相当简单(例如,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?