windowsvisual-c++linkerportable-executablecomdat-folding

COMDAT section name


I'm writing a linker for Windows binaries, and currently working on implementing COMDAT. I think I understand most of the specification, except that of the three records for a COMDAT section (the section header, section symbols and auxiliary symbol), the specification doesn't seem to mention the common name being stored in any of them.

In other words, when I run dumpbin on such an object, it gives output like:

SECTION HEADER #8
.text$mn name
       0 physical address
       0 virtual address
       5 size of raw data
    2358 file pointer to raw data (00002358 to 0000235C)
    235D file pointer to relocation table
       0 file pointer to line numbers
       1 number of relocations
       0 number of line numbers
60301020 flags
         Code
         COMDAT; sym= cosl

Where does that last item sym= cosl come from? Or if it's just a regular symbol that points to the section, what happens if there are several different such symbols pointing to it?


Solution

  • According to the Microsoft PE and COFF Specification, section 4.5.6 (which I'm sure you have read closely if you're writing a linker), the sym= value is the COMDAT symbol, which is used by the linker in conjunction with the Selection value to determine which copy of the COMDAT section to keep in the final image. There are two entries in the symbol table for each COMDAT section. The first has the section name and an auxiliary record with the Selection info. The COMDAT symbol value comes from the second entry in the symbol table for the COMDAT section. It's either the symbol's ShortName value or the value of the string table entry it points to.

    The COMDAT symbol value should be identical for all copies of the same COMDAT in the various object files to be linked. There should only be two symbol table entries with the matching SectionNumber for a particular COMDAT section in any one object file, if I understand the spec correctly. You shouldn't see multiple COMDAT symbol strings with different values as symbol table entries for a single COMDAT.