views:

195

answers:

3

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) "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.

A: 

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.

Randolpho
No! It's not the size of the data structure referred to by the symbol. At least not always. For example, if I create an extern field of a class type, the Value field in the object file ends up being 0, not sizeof(FooBar). Also, the linker doesn't need to know the size from the reference site. It needs to know the size of the section that contains the symbol, and the offset (from the defining object file) and the necessary relocation fixups (from the symbol's usage site), but it doesn't care about the size of the symbol.
Scott Wisniewski
A: 

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?

Oleg
I think you are confusing the Symbol Table with COFF debugging information. You are correct that Visual Studio does not produce COFF Line Number records (debugging info), but it does produce Symbol Tables. The linker couldn't function without them.In any case, the storage class of the symbols in question is external and the section number is 0. The question I have is how should the Value field be interpreted. The spec says "size", except the value is 0, so it's not the size.
Scott Wisniewski
A: 

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.

Hans Passant
Thanks for the suggestion.In that case, the compiler still emits 0 for the Value field.If the compiler sets it to 0, it doesn't mean it's not used though....
Scott Wisniewski
Yeah, I didn't think so. You'd probably have to use some other language, like Fortran, to see it getting used.
Hans Passant
Thanks again. I was hoping I could find information on how the linker interprets the value (more so than a compiler that sets it). It looks like I'm just going to have to test like crazy to figure that out. I wish the PE / COFF docs didn't suck so much... Having to test in order to figure out what it is I need to write so that I can then figure out what it is I need to test is exactly the kind of situation I like to avoid. Sigh.....
Scott Wisniewski