Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top