1

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

  1. IMAGE_SYM_CLASS_EXTERNAL 的存储类
  2. 和0的节号(IMAGE_SYM_UNDEFINED)

它是“指示大小”的“值”字段(在符号表中)。

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

通常, CL(visual C++) 使用IMAGE_SYM_CLASS_EXTERNALandIMAGE_SYM_UNDEFINED来表示 externs。

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

我查看了一些由 CL 编译的简单示例 extern,Value 字段似乎总是为零。所以,它显然没有被用来编码字段的大小。

有谁知道规范指的是什么“尺寸”?他们是否有任何视觉工作室链接器可能使用该字段的场景,或者规范中的宣传只是胡说八道?我有限的大脑无法想到任何这样的场景。

更新:

请注意,它并不(至少不总是)看起来是符号的大小。在我观察到VALUE IS ALWAYS 0的情况下,这就是问题所在。

4

4 回答 4

4

Wisniewski 先生,我相信我找到了答案。我是一名学生,我尝试编写自己的链接器。它的第一个版本可以链接OBJ文件并将它们转储为我自己的二进制格式。但很快我就意识到,如果没有LIBCMT.LIB ,许多C++语言特性是不受支持的。所以起初我编写了 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 编译器发出没有节 (0) 的符号并标记为外部,并且如果它的value 字段为零,则在其他任何地方声明它,但如果value 字段不为 null,这意味着给定的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部分。

祝你好运,对不起我的英语不好。

于 2010-12-13T20:42:48.677 回答
1

声明大小的数组的外部声明怎么样:

一个.cpp:

 extern int example[42];

b.cpp:

 int example[13];

链接器没有捕捉到这种不匹配的事实表明没有使用 Value。我没有简单的方法看到这一点。

于 2010-05-19T10:08:49.207 回答
0

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

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

于 2010-05-17T22:41:30.550 回答
0

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

基本上,如果符号未定义,则链接器无法找到数据结构的大小,因此需要提前知道它在实例化时有多大,以便在链接期间处理这些问题。

于 2010-05-17T15:16:03.333 回答