Как определить основную версию компилятора из файлов.obj, скомпилированных с /GL?

Я пытаюсь определить версию Visual Studio (2002/2003, 2005, 2008, 2010, 2012, 2013, 2015) из .obj файл, созданный с помощью опции генерации временного кода ссылки.

Файл, созданный мной с помощью MSVC2012, имеет следующее содержимое заголовка COFF:

                File Header
+0  00 00       Machine - Unknown Machine
+2  FF FF       NumberOfSections
+4  01 00 4C 01 TimeDateStamp
+8  70 94 F9 55 PointerToSymbolTable
+12 38 FE B3 0C NumberOfSymbols
+16 A5 D9       SizeOfOptionalHeader
+18 AB 4D       Characteristics
                Optional Header
+20 AC 9B       Magic
+22 D6 B6       Linker Version Major/Minor

Кажется, что начальные 4 байта, являющиеся 00,00,FF,FF помечают его как объект LTCG, а то, что следует, является частным. Ни один из обычных членов заголовка файла не имеет смысла (возможно, отметка времени в порядке, я не проверял).

Кто-нибудь знает, если какая-то часть этого заголовка зависит от компилятора? Все, что мне нужно определить, это основная версия MSVC, используемая для компиляции объекта...

Похоже, что есть версия, закодированная как <MAJOR:16:LE> 0x80 <MINOR:16:LE>хранится вскоре после заголовка. Например:

17.00.61030 -> 0x11.0xEE66 -> 11 00 80 66 EE
19.00.23026 -> 0x13.0x59F2 -> 13 00 80 F2 59

Нужно выяснить, как надежно добраться до него, смещением предыдущих данных.

Это связанный вопрос, без разрешения...

1 ответ

TL,DR:
Вы не можете получить версию компилятора с этим форматом файла, я думаю...

Полный ответ:

Это выглядит как некий вариант "анонимного формата файла", описанного в "winnth.h" различными ANON_OBJECT_HEADER_XXX структуры (заменить XXX от V2 или же BIGOBJ). Вот копия ANON_OBJECT_HEADER_BIGOBJ найдено в winnt.h:

typedef struct ANON_OBJECT_HEADER_BIGOBJ {
    /* same as ANON_OBJECT_HEADER_V2 */
    WORD    Sig1;            // Must be IMAGE_FILE_MACHINE_UNKNOWN
    WORD    Sig2;            // Must be 0xffff
    WORD    Version;         // >= 2 (implies the Flags field is present)
    WORD    Machine;         // Actual machine - IMAGE_FILE_MACHINE_xxx
    DWORD   TimeDateStamp;
    CLSID   ClassID;         // CLSID is a 16 bytes struct  (not original comment)
    DWORD   SizeOfData;      // Size of data that follows the header
    DWORD   Flags;           // 0x1 -> contains metadata
    DWORD   MetaDataSize;    // Size of CLR metadata
    DWORD   MetaDataOffset;  // Offset of CLR metadata
    /* bigobj specifics */
    DWORD   NumberOfSections; // extended from WORD
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
} ANON_OBJECT_HEADER_BIGOBJ;</code>

Описание соответствия:

Sig1 :    00 00
Sig2 :    FF FF
Version : >=2
Machine : 0x14c`

Другие структуры заголовка (т.е. ANON_OBJECT_HEADER а также ANON_OBJECT_HEADER_V2) в основном то же самое, но с меньшим количеством полей.
Для Version поле, я нашел некоторую информацию здесь: http://www.geoffchappell.com/studies/msvc/link/dump/infiles/obj.htm

Выглядит как Version поле равно "1" для анонимных файлов, и похоже, что анонимные файлы и так называемые "файлы импорта" имеют одинаковые характеристики, только Version = 0 для импорта файлов формата (я не очень знаю, что это за общепризнанно).

Но да, просто глядя на заголовок, кажется, что у нас нет информации о том, какая версия компилятора использовалась. И даже тогда, при просмотре файлов.obj, сгенерированных с помощью ключа /GL, они не совсем соответствуют этому формату, и я не нашел много информации о них. Я буду рад, что кто-то докажет, что я неправ.

Другие вопросы по тегам