Microsoft PE / COFF SPEC(v8,第5.4.4节)说当符号有:
“值”字段(在符号表中)“表示大小”。
这让我很困惑。特别是,我想知道“表明什么的大小?”。
通常,CL(visual C ++)使用IMAGE_SYM_CLASS_EXTERNAL
和IMAGE_SYM_UNDEFINED
来表示外部。
为什么链接器需要知道或关心符号的大小?它不仅需要知道一个名称,它是一个extern,并且设置了适当的重定位项吗?这些都不取决于尺寸。现在,诚然,编译器需要知道这一点,但它会从头文件中获取信息,而不是从目标文件中获取。
我已经看了一些由CL编译的简单示例externs,并且Value字段似乎总是为零。因此,显然没有用它来编码场的大小。
有没有人知道规范指的是什么“大小”?他们的视觉工作室链接器可能使用该字段的任何场景,还是规范中的模糊只是废话?我有限的大脑无法想到任何这样的场景。
更新
请注意,它不会,至少不总是,似乎是符号的大小。在我观察到 VALUE总是0 的情况下,因此问题。
答案 0 :(得分:2)
#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的地方?