想了解 COFF Externs

发布于 2024-09-01 04:05:56 字数 688 浏览 3 评论 0原文

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

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

时,它的“值”字段(在符号表中)“指示尺寸”。

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

一般来说,CL(Visual C++)使用IMAGE_SYM_CLASS_EXTERNALIMAGE_SYM_UNDEFINED来表示外部变量。

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

我看过一些由 CL 编译的简单示例 extern,并且 Value 字段似乎总是为零。因此,它显然没有用于对字段的大小进行编码。

有谁知道规格所指的“尺寸”是什么?视觉工作室链接器是否有可能使用该字段的场景,或者规范中的简介只是无意义的?我有限的大脑无法想象这样的场景。

更新:

请注意,它并不(至少不总是)显示为符号的大小。在我观察到的情况下,值始终为 0,因此出现了问题。

The Microsoft PE/COFF SPEC (v8, section 5.4.4) says that when a symbol has:

  1. A storage class of IMAGE_SYM_CLASS_EXTERNAL
  2. And a section number of 0 (IMAGE_SYM_UNDEFINED)

It's "value" field (in the symbol table) which "indicates the size".

This confuses me. In particular, I'm wondering "indicates the size of what?".

Generally, IMAGE_SYM_CLASS_EXTERNAL and IMAGE_SYM_UNDEFINED are used by CL(visual C++) to represent externs.

Why would the linker need to know, or care, about the symbol's size? Doesn't it just need to know a name, that it's an extern, and have the appropriate relocation entries set? None of this should depend on size. Now, admittedly, the compiler needs to know this, but it would get that information from a header file, not from an object file.

I've looked at some simple example externs compiled by CL, and the Value field always seems to be zero. So, it's clearly not being used to encode the size of the field.

Does anyone know what "size" the spec is referring to? Are their any scenarios where the visual studio linker might use that field, or is that blurb in the spec just nonsense? My limited brain is unable to think of any such scenarios.

Update:

Please note that it does not, at least not always, appear to be the size of the symbol. In the cases I've observed the VALUE IS ALWAYS 0, hence the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橪书 2024-09-08 04:05:56

Wisniewski先生,我相信我找到了答案。
我是一名学生,我尝试编写自己的链接器。
它的第一个版本可以链接 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 编译器发出没有节 (0) 的符号并标记为外部并且如果
它的值字段为零,然后在其他任何地方声明它,但如果值字段不为空,则
意味着给定的 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 部分中。

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

Mr.Wisniewski, I believe I found the answer.
I'm a student and I've tried to write my own linker.
The very first version of it can link OBJ files and dump them
to my own binary format. But soon I've realized that many C++ language
features are unsupported without LIBCMT.LIB.
So at first I've coded lib parser... and stuck while trying to link CRT.
In the second linker member of the file LIBCMT.LIB was specified that
object file crt0.obj (inside libcmt) contains symbol __acmdln (global pointer to the
command line)... but I couldn't manage to find it there! I was really frustrated...
Symbol had IMAGE_SYM_CLASS_EXTERNAL and section IMAGE_SYM_UNDEFINED, but why?
In the source file crt0.c there is a declaration:

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

My investigation was rather long and the result is so:

C++ compiler places uninitilized data into the .bss section and marks it with IMAGE_SCN_CNT_UNINITIALIZED_DATA, but
pure C compiler behaves in a different way (libcmt was written in C).

It is linker's duty to place uninitialized data into sections.
If C compiler emits symbol without section (0) and marked as external and if
it's value field is zero, then it is declared anywhere else, but if value field is not null, that
means that given OBJ file really contains that symbol but it is not initialized.
So linker should reserve place in .bss section for it. THE PLACE OF 'VALUE' SIZE.
And when you change those lines to:

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

There will be zero value field and both of them will be placed in .data section.

Good luck, and sorry for my bad English.

相对绾红妆 2024-09-08 04:05:56

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

a.cpp:

 extern int example[42];

b.cpp:

 int example[13];

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

How about an extern declaration for an array that declares the size:

a.cpp:

 extern int example[42];

b.cpp:

 int example[13];

The fact that the linker doesn't catch this mismatch suggests however that Value isn't used. I have no easy way to see that.

弃爱 2024-09-08 04:05:56

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

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

It's the size of the data structure referred to by the symbol.

Basically, if the symbol is undefined, the linker can't otherwise find the size of the data structure, and therefore needs to know in advance how big it is when it's instantiated so it can deal with those issues during linkage.

罪歌 2024-09-08 04:05:56

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

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

You have a very exotic, but interesting question. It it correct that the only possibility to produce symbol table inside of COFF is usage of /Zd compiler switch which are supported till Visual C++ 6.0 and use the old linker switch /debugtype:coff (see http://www.debuginfo.com/articles/gendebuginfo.html#gendebuginfovc6)? Is there any possibility to produce symbol table inside of COFF with at least Visual Studio 2008?

My idea is try to produce a PE with a symbol table of storage class IMAGE_SYM_CLASS_EXTERNAL and the section number 0 (IMAGE_SYM_UNDEFINED) with respect of linker switch /FORCE (/FORCE:UNRESOLVED or /FORCE:MULTIPLE) and an unresolved symbol either by /INCLUDE:dummySymbol or by /NODEFAULTLIB. My problem is that it's not easy to produce symbol table inside of COFF. Where you receive the test PEs?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文