想知道COFF Externs

时间:2010-05-12 22:37:39

标签: visual-studio linker portable-executable coff

Microsoft PE / COFF SPEC(v8,第5.4.4节)说当符号有:

  1. 存储类IMAGE_SYM_CLASS_EXTERNAL
  2. 节号为0(IMAGE_SYM_UNDEFINED)
  3. “值”字段(在符号表中)“表示大小”。

    这让我很困惑。特别是,我想知道“表明什么的大小?”。

    通常,CL(visual C ++)使用IMAGE_SYM_CLASS_EXTERNALIMAGE_SYM_UNDEFINED来表示外部。

    为什么链接器需要知道或关心符号的大小?它不仅需要知道一个名称,它是一个extern,并且设置了适当的重定位项吗?这些都不取决于尺寸。现在,诚然,编译器需要知道这一点,但它会从头文件中获取信息,而不是从目标文件中获取。

    我已经看了一些由CL编译的简单示例externs,并且Value字段似乎总是为零。因此,显然没有用它来编码场的大小。

    有没有人知道规范指的是什么“大小”?他们的视觉工作室链接器可能使用该字段的任何场景,还是规范中的模糊只是废话?我有限的大脑无法想到任何这样的场景。

    更新

    请注意,它不会,至少不总是,似乎是符号的大小。在我观察到 VALUE总是0 的情况下,因此问题。

4 个答案:

答案 0 :(得分:2)

威斯涅夫斯基先生,我相信我找到了答案。 我是学生,我试图编写自己的链接器。 它的第一个版本可以链接 OBJ 文件并转储它们 到我自己的二进制格式。但很快我就意识到许多 C ++ 语言 如果没有 LIBCMT.LIB ,则不支持这些功能。 所以起初我编写了lib解析器...并且在尝试链接 CRT 时卡住了。 在文件的第二个链接器成员中指定了 LIBCMT.LIB 目标文件 crt0.obj (在 libcmt 内)包含符号 __ acmdln (全局指针指向 命令行)...但我无法在那里找到它!我真的很沮丧...... 符号有IMAGE_SYM_CLASS_EXTERNAL和部分IMAGE_SYM_UNDEFINED,但为什么? 在源文件 crt0.c 中有一个声明:

#ifdef WPRFLAG
wchar_t *_wcmdln;           /* points to wide command line */
#else  /* WPRFLAG */
char *_acmdln;              /* points to command line */
#endif  /* WPRFLAG */

我的调查时间很长,结果如此:

C ++编译器将未经过身体处理的数据放入 .bss 部分,并使用IMAGE_SCN_CNT_UNINITIALIZED_DATA对其进行标记,但是 纯C编译器的行为方式不同( libcmt 是用C语言编写的)。

链接器有责任将未初始化的数据放入段中。 如果C编译器发出没有section(0)的符号并标记为external和if 它的值字段为零,然后在其他任何地方声明,但如果值字段不为空,那 意味着给定 OBJ 文件确实包含该符号但它未初始化。 因此,链接器应保留在 .bss 部分中的位置。 '价值'大小的地方。 当你将这些行更改为:

#ifdef WPRFLAG
wchar_t *_wcmdln = 0xCCCCCCCC; /* points to wide command line */
#else  /* WPRFLAG */
char *_acmdln = 0xCCCCCCCC; /* points to command line */
#endif  /* WPRFLAG */

将会有零值字段,并且它们都将放在 .data 部分中。

祝你好运,抱歉我的英语不好。

答案 1 :(得分:1)

声明大小的数组的extern声明怎么样:

a.cpp:

 extern int example[42];

b.cpp:

 int example[13];

链接器未捕获此不匹配的事实表明不使用Value。我没有简单的方法可以看到它。

答案 2 :(得分:0)

它是符号引用的数据结构的大小。

基本上,如果符号未定义,则链接器无法以其他方式查找数据结构的大小,因此需要事先知道实例化时的大小,以便在链接期间处理这些问题。

答案 3 :(得分:0)

你有一个非常奇特但有趣的问题。它是正确的,在COFF内部生成符号表的唯一可能性是使用/ Zd编译器开关,直到Visual C ++ 6.0并使用旧的链接器开关/ debugtype:coff(参见http://www.debuginfo.com/articles/gendebuginfo.html#gendebuginfovc6)?是否有可能至少使用Visual Studio 2008在COFF内部生成符号表?

我的想法是尝试使用存储类IMAGE_SYM_CLASS_EXTERNAL的符号表和关于链接器开关/ FORCE(/ FORCE:UNRESOLVED或/ FORCE:MULTIPLE)的段号0(IMAGE_SYM_UNDEFINED)以及未解析的符号生成PE by / INCLUDE:dummySymbol或/ NODEFAULTLIB。我的问题是在COFF内部生成符号表并不容易。你收到测试PE的地方?