【问题标题】:What is Symbol Resolution?什么是符号解析?
【发布时间】:2009-07-24 02:20:39
【问题描述】:

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

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

【问题讨论】:

    标签: compiler-construction symbols


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 有道理,非常感谢。我也会查找“共享库”。你有什么书可以推荐来了解更多这方面的知识吗?
    • 我所知道的关于这个主题的最好的书是Linkers and Loaders by John R. Levine
    【解决方案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?
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我的意思是在 unix 上与 nm 命令一起使用它的上下文中。这有帮助吗?我也不确定 dlopen 是什么,所以我不能说你是否接近。
      猜你喜欢
      • 1970-01-01
      • 2012-12-01
      • 2021-08-26
      相关资源
      最近更新 更多